]> jfr.im git - irc/unrealircd/unrealircd.git/commitdiff
beta18
authorstskeeps <redacted>
Tue, 23 Sep 2003 18:42:03 +0000 (18:42 +0000)
committerstskeeps <redacted>
Tue, 23 Sep 2003 18:42:03 +0000 (18:42 +0000)
115 files changed:
.CHANGES.NEW
.RELEASE.NOTES
.bugreport.gdb
Changes
Makefile.in
README [new file with mode: 0644]
Unreal.nfo
autoconf/configure.in
configure
doc/example.conf
doc/unreal32docs.html
help.conf
include/common.h
include/config.h
include/dynconf.h
include/h.h
include/modules.h
include/msg.h
include/numeric.h
include/res.h
include/struct.h
include/sys.h
include/version.h
ircdcron/ircdchk.in [moved from ircdcron/ircdchk with 82% similarity, mode: 0644]
makefile.win32
makefile.win32.ssl
makefile.win32.ssl.ziplink
makefile.win32.ziplink
src/Makefile
src/channel.c
src/events.c
src/extcmodes.c [new file with mode: 0644]
src/fdlist.c
src/ircd.c
src/list.c
src/modules.c
src/modules/m_adminchat.c
src/modules/m_akill.c
src/modules/m_away.c
src/modules/m_chghost.c
src/modules/m_chgident.c
src/modules/m_chgname.c
src/modules/m_chmodetst.c [new file with mode: 0644]
src/modules/m_cycle.c
src/modules/m_dummy.c
src/modules/m_guest.c
src/modules/m_htm.c
src/modules/m_kill.c
src/modules/m_lag.c
src/modules/m_message.c
src/modules/m_mkpasswd.c
src/modules/m_nachat.c
src/modules/m_oper.c
src/modules/m_pingpong.c
src/modules/m_quit.c
src/modules/m_rakill.c
src/modules/m_rping.c
src/modules/m_sdesc.c
src/modules/m_sendumode.c
src/modules/m_sethost.c
src/modules/m_setident.c
src/modules/m_setname.c
src/modules/m_sqline.c
src/modules/m_svsjoin.c
src/modules/m_svslusers.c
src/modules/m_svsmode.c
src/modules/m_svsmotd.c
src/modules/m_svsnick.c
src/modules/m_svsnline.c
src/modules/m_svsnoop.c
src/modules/m_svso.c
src/modules/m_svspart.c
src/modules/m_svssilence.c
src/modules/m_svswatch.c
src/modules/m_swhois.c
src/modules/m_tkl.c
src/modules/m_tsctl.c
src/modules/m_unkline.c
src/modules/m_unsqline.c
src/modules/m_unzline.c
src/modules/m_vhost.c
src/modules/m_who.c
src/modules/m_whois.c
src/packet.c
src/res.c
src/res_comp.c
src/res_init.c
src/res_mkquery.c
src/s_bsd.c
src/s_conf.c
src/s_debug.c
src/s_err.c
src/s_extra.c
src/s_kline.c
src/s_misc.c
src/s_serv.c
src/s_stats.c [new file with mode: 0644]
src/s_svs.c
src/s_user.c
src/send.c
src/socket.c
src/ssl.c
src/umodes.c
src/webtv.c
src/win32/Win32GUI.c
src/win32/Win32GUI.rc
src/win32/gnu_regex.dll [deleted file]
src/win32/gnu_regex.lib [deleted file]
src/win32/resource.h
src/win32/service.c
src/win32/toolbar.bmp
src/win32/tre.dll [new file with mode: 0644]
src/win32/tre.lib [new file with mode: 0644]
src/win32/unrealinst.iss
update

index 7ac007a6105fa5ff8eebdec45dd6a2c1d9dc09b8..cb27b715baab4326b2d04c63d55deb09c6777618 100644 (file)
@@ -7,7 +7,7 @@
  \___/|_| |_|_|  \___|\__,_|_|\___/\_| \_| \____/\__,_|
 
                                Configuration Program
-                                for Unreal3.2-beta17
+                                for Unreal3.2-beta18
                                     
 This program will help you to compile your IRC server, and ask you
 questions regarding the compile-time settings of it during the process. 
index cf94c285eec531022e35369cedfc9667965dc9cb..8bd10a0de1d222ef06245636dfe575c2d5a380d8 100644 (file)
@@ -1,58 +1,80 @@
 
-Unreal3.2-beta17 Release Notes
+Unreal3.2-beta18 Release Notes
 ======================================
 
 ==[ GENERAL INFORMATION ]==
 * If you are upgrading, make sure you run ./Config and make clean before doing make
-* The official UnrealIRCd documentation is doc/unreal32docs.html (also contains a FAQ),
-  read it before asking for help.
+* The official UnrealIRCd documentation is doc/unreal32docs.html
+  online version at: http://www.vulnscan.org/UnrealIrcd/unreal32docs.html
+  FAQ: http://www.vulnscan.org/UnrealIrcd/faq/
+  Read them before asking for help.
 * Report bugs at http://bugs.unrealircd.org/
-* This is a forced release because of a security bug, so not many new features.
-
-==[ REMOVED ]==
-Nothing.
+* This release adds a lot nice new features and fixes most win32 crashes.
 
 == [NEW FEATURES (see unreal32docs.html for more information) ]==
-* Implemented short motds (ircd.smotd). When a user connects ircd.smotd is displayed 
-  (or a tld::shortmotd). This file contains brief text. Alternatively, ircd.motd (or
-  tld::motd) is displayed when a user types /motd. The idea behind this is instead of
-  displaying huge ASCII art, and tons of text to every user when they connect (since
-  most users will ignore it anyway) you only show that stuff to users who specifically
-  request it. If you choose not to use short motds, everything will function as it used to.
-* Added set::ident::connect-timeout (default 10s) and set::ident::read-timeout (default 30s) to
-  give much more control over ident timeouts, this should also fix connection timeout problems
-  during connecting.
-* Added deny channel::redirect, which allows you to forward a client to another channel
-  if the one he/she joined is not allowed. can also be used for channel "aliases" like
-  #operhelp sends people to #help.
-* Added set::options::mkpasswd-for-everyone to let normal users use /mkpasswd.
-* MacOS X support, you need dlcompat package installed in /usr for this to work
-
-==[ UPDATED ]==
-* ban version {} now also checks for SCRIPT replies
-* module updates (module coders should check Changes)
-* Renamed channel mode +a to "channel admin"
-* IPv6: UnrealIRCd can now lookup ip6.arpa addresses too
+* ChannelMode +f has been changed a lot, it's an advanced anti-flood mode now.
+  It can protect against: joinflood, ctcpflood, msgflood, nickflood and knockflood.
+  For example: +f [30j,50m]:15 means max 30 joins and 50 messages are allowed per
+  15 seconds, if the max joins limit is reached the channel is automatically put +i,
+  if the messages limit is reached the channel is put +m.
+  For more info see: http://www.vulnscan.org/UnrealIrcd/unreal32docs.html#feature_antiflood
+  You might want to enable it by default via set::modes-on-join.
+* The /stats system has been recoded, some new features:
+  * extended flags for shun and kline, for example:
+    "/stats G +m *aol.com" will display all glines matching *aol.com.
+  * support for long flags, like: /stats exceptban
+* Finally support for up to 32 new channelmodes, all of which can be done in modules
+  (currently disabled by default). SnoMask module support has been added as well.
+* Added nickflood protection, set::anti-flood::nick-flood, this is
+  enabled by default and set at 3:60 (max 3 nickchanges per 60 seconds).
+* The win32 editor has been improved: better handling of mIRC codes, short motd editting,
+  goto button, find text feature, etc..
+* A new deny channel :: warn option, this will inform opers (with eyes snomask) that the
+  user was trying to join the forbidden channel.
+* official-channels support, these channels are shown in /list even if they have 0 users,
+  you can also a default topic which is shown in /list.
+* Added badwords all { }, you can use this instead of using a badwords channel,
+  badword message and badword quit block for the same word.
+* Added set::channel-command-prefix to allow channel text which starts with specific
+  characters to be sent to +d clients (for in channel commands).
+* You can now set the default bantime for a gline/kline/gzline/.. in set::default-bantime
+  (like for /gline *@*.something.net)
+* A README file has been added.
+* Will now strip/block color codes in quits if the user is in a +S/+c channel.
+
+==[ CHANGED ]==
+* We will now error at too large cloak keys (>2147483646)
+* away-flood configuration now works just like nick-flood,
+  it's also enabled by default at 4 per 120s.
+* badword filtering is now only done at the first server (source),
+  this can reduce CPU usage a lot, especially at hubs.
 
 ==[ MAJOR BUGS FIXED ]==
-* Security fixes, including a bug which allows any user to crash the ircd
-* Several win32 resolver fixes
-* "make install" fixed, was broken in beta16
-* badword::action block with regex (non-fast) badwords could cause a crash
-* misc /whois and webtv fixes
-* /who cleanup & bugfixes
-* /join cleanup: multiple chanmode +L fixes
-* IPv6 resolver
-* SVS* bug which could cause server notices to be sent to random users
-* Solaris/SunOS compile fixes
-* MOTD cleanup: fixes remote MOTD gone after rehash etc
+* The buggy windows resolver has been replaced with the *NIX resolver,
+  the win-resolver was the main cause of unrealircd@windows crashes.
+* services-related crashbug found 24h after beta17 release :(
+* ban version crash
+* UnrealIRCd should now be able to run fine at PowerPC.
+* No security related fixes this release.
+
+==[ MINOR BUGS FIXED ]==
+* oper::swhois wasn't working correctly (/whois from remote servers).
+* /silence with cloaked hosts
+* trafficstats were sometimes incorrect (/stats T and /HTM).
+* multiple channelmode +(m)u fixes, most of them were multiserver related.
+* IPv6: FreeBSD has support for ::ffff:1.2.3.4 alike IPs disabled by default,
+  we will now spit out some information about this if binding to such IPs fails.  
+* Fixed a chroot bug
+* Made /restart work at windows in service mode.
+* A few +b/+e bugfixes
+* Allow o/a/q'd people to nickchange if banned
+* Added some missing info to /stats
+* etc..
 
 ==[ ADDITIONAL INFO ]==
-* There's experimental "+a/+q with symbol" support in this version (you need to enable it
-  in config.h explicitly). Full support will be in next release.
 * See Changelog
 
-============================= (old release notes below) ==============================
+========================= (pretty old release notes below) ==========================
 [this has been editted a bit]
 
 * Unreal3.2 is a lot different than Unreal3.1.1. Forget all you have
index 057f2fe236f92c7988408b41ae923e22401f7180..ee1185bac7286e5f585479d6950a09fc193d84b3 100644 (file)
@@ -74,4 +74,4 @@ echo \n
 echo Modules:\n
 echo ----------------------\n
 dumparray Modules 50
-quit
\ No newline at end of file
+quit
diff --git a/Changes b/Changes
index 7da199b29a66873a4c22059483a831f9fbce6efd..c12cab672d9cba1a81796757225dedcec55f9de0 100644 (file)
--- a/Changes
+++ b/Changes
@@ -2229,3 +2229,215 @@ seen. gmtime warning still there
 - Docs update
 - Temporarily disabled compiling TRE 
 *** Unreal3.2-beta17 release *** (god save us)
+- Modified './update', now points to docs until we have a new update thingy.
+- Fixed bug with /list and '?' wildcard, reported by maGGus.
+- Fixed a few fdlist bugs in SVSMODE/SVS2MODE found by Aither.
+- IPv6: added warning if a ::ffff:a.b.c.d type addr doesn't work since this "feature"
+  is disabled by default at newer *BSD versions. Also improved another warning.
+- Added set::channel-command-prefix to allow channel text which starts with specific characters
+  to be sent to +d clients (for in channel commands).
+- Added a README
+- Added some checking in fdlist add/remove functions.
+- Updated docs a bit (how-to-get-support/FAQ link style).
+- Rewrote the win32 editor handling of mIRC codes. The new system should be more stable,
+  and it supports more features, such as background colors. Just a note, the editor should
+  be able to display any mIRC code without problem, however, some codes may be changed once
+  you save the file. For example, reverse is replaced with ctrl+k0,1 and color code 99 is 
+  treated as a 1 if used for a text color and 0 if used for a bgcolor. This might cause
+  problems when displaying in some clients, however not all clients support color code 99.
+  As for the reverse, if I can come up with a decent way to still keep the original reverse
+  code, I will change it to do that. So in short, if you need the color codes to stay
+  _exactly_ the way they are, then you shouldn't use the editor on that file. Also, color 
+  codes that are 0..9 are translated to 2 digits, ie "2" becomes "02" this is to prevent 
+  problems when a number follows directly after the color code. 
+- Added support for editting short motds in the win32 editor.
+- Added a goto button on the win32 editor toolbar.
+- Made the win32 editor window maximizable.
+- Added a find text feature to the win32 editor.
+- Added HOOKTYPE_LOCAL_OPER (first param = aClient of oper, second param = 1 if the user
+  just became an oper, 0 if they just -o'ed)
+- Added a system to allow modules to create snomasks using functions SnomaskAdd and SnomaskDel
+- Fixed ban version crash and another read-after-free.
+- Fixed problem with make custommodule and multiple EXLIBS arguments (EXLIBS="-la -lb -lc").
+- Fixed a bug with +b and +e involving how trimming should occur when a mask is too long.
+  (#0001103) reported by Troco.
+- Fixed a bug in aliases reported by darko``
+- Updated help.conf and unreal32docs.html (#0001111) reported by SciFi, AngryWolf, and Zerwas.
+- Cleaned up some code for /die under Windows
+- Fixed ircd.c compile error discovered by Ravage
+- Made unreal work with Linux under PPC (#0001105,#0000929) reported by drevlan and Cruiser
+  and thanks to drevlan for donating a linux ppc shell to help track down the problem
+- Fixed a problem where Unreal would sometimes die without outputting information about the
+  crash under Windows
+- Made /restart work under Windows in NT service mode.
+- Fixed a documentation typo (#0001027) reported by Soldier007
+- Fixed a bunch of logging problems reported by LRL (#0001034).
+- Fixed a problem with a fix for +b/+e reported by AngryWolf (#0001117)
+- Fixed a documentation typo reported by Z3l3zT (#0001066)
+- Clarified what ban server {} does, suggested by Joolz (#0001110)
+- Fixed a problem related to crontab reported by LRL (#0001034)
+- Fixed a problem in PPC detection
+- Will now error at too large cloak keys (2147483647 and greater) because it's dangerous
+  and could cause cloak key differences (ex: mixed ia32&ia64 networks).
+- Some minor text/documentation fixes.
+- First big part of modulized extended channelmodes system:
+  - Adds room for at least 32 (new) channel modes.
+  - Supports both paramless and 1-parameter modes.
+  - Modulized: modules can add new channelmodes, but are unloadable (permanent).
+  - Everything is ifdef'd, and EXTCMODE is disabled by default in config.h
+  - It will send CHANMODES= in the PROTOCTL message on server link, this enables
+    servers and services to see which modes are supported and of what type
+    they are (1-parameter, paramless, etc).
+  And now the bad part:
+  - The system has not been fully tested, it will contain bugs (for example I'm
+    aware of some memory leaks).
+  - A few features are missing: warning/error on linking if chanmodes mismatch, unloading
+    of channel modes (not planned soon), 005 broadcasts on change and maybe more..
+  - The function (and maybe variable) names will be changed in the next weeks/months
+  - You should be carefull with parameter modes + services. Things will get desynced
+    if services don't recognize it's a parameter mode. This also applies to clients
+    without 005 CHANMODES= support.
+  - No documentation
+
+  I really suggest module coders to wait a few weeks till the system is ready..
+  In the meantime, don't report bugs or ask for support on this.
+- Fixed bug with SWHOIS: oper::swhois wasn't broadcasted correctly which made it
+  only show up in local (or server) /whois, reported by format (#0001141).
+- minor m_kick tweak.
+- Fixed bug in /silence regarding cloaked hosts, reported by kuwatog (#0001157).
+- Fixed a problem with a Sleep call on win32
+- Rewrote the /stats system. The new system allows for long flags for example
+  /stats gline to list glines rather than just /stats G (old flags are still
+  supported). Additionally, for glines an extended syntax is now supported allowing
+  more refined searches. /stats G +m *@*.aol.com lists only glines that match that 
+  mask. For more info do /stats ?. 
+- Added stats flags for except throttle and ban version blocks
+- stats bugfixes: a null pointer crash and a '/stats k' bug.
+- Fixed a couple of problems in the new stats system
+- Fixed another stats problem, reported by Angrywolf (#0001163)
+- Rewrote the usermode module interface to be more stable and consistent with other
+  module functions. New functions are UmodeAdd and UmodeDel (backwards compatibility
+  is available for the old functions).
+- Fixed a bug in the snomask and umode system dealing with removing flags
+- Added two module functions ModuleGetOptions and ModuleSetOptions to retrieve/toggle
+  module options
+- Fixed a bug effecting +k/+L where you could /mode #chan +k test, /mode #chan +k test
+  and each time it would send a mode change (#0001170) reported by Airnike.
+- A few documentation updates/fixes
+- 005 CHANMODES= set back to original value before extcmode merge
+- made some functions in channel.c non-static so module coders
+  can use them (they are not defined in the header files [yet] however).
+- fixed 2 minor oob write issues
+- Fixed a bug with stats l/L
+- Updated example.conf with a more strict default oper-only-stats.
+- Made '/stats S' and '/stats Z' oper only again (always).
+- Hopefully fixed incoming/outgoing rate in /stats T. Only the stats of the first
+  listener was counted instead of the total. This also explains why on some (many?)
+  ircd configurations it always showed 0.00 kb/s and why HTM (high traffic mode)
+  was never kicking in.
+- A few doc updates (example.conf).
+- Added EOS command (End Of Sync), which is sent between servers after a server has
+  succesfully synced (after introducing of channels, users, etc). This way we can
+  easily distinct between linked servers and a connecting server.
+  This is needed / very helpful for: snomask +F, new +f anti flood system, prolly
+  other things as well. Services don't support this command, but it's not
+  needed atm since +F/+f both ignore U lines.
+- Internal: changed 2 MyMalloc's to MyMallocEx (mem zerofill).. nothing was currently
+  affected by this but it's easy to forget if you add new stuff.
+- Fixed minor /WALLOPS bug reported by Praetorian_ (#0001195).
+- Internal code cleanups: EOS var rename, got rid of old UnknownUser structs, moved
+  anti away flood to new flood struct.
+- Changed away flood configuration to set::anti-flood::away-flood <count>:<period>.
+- Added nickflood protection, can be set in set::anti-flood::nick-flood <count>:<period>
+  to allow max 'count' nickchanges per 'period' seconds. The default is 3 per 60s.
+  As usual, the nickchange limiting does not apply to ircops.
+- Allow o/a/q'd users to nickchange if banned (#0001150).
+- Added badword all { }, this will add the badword to the badword channel, badword message
+  and badword quit lists... could be useful :p.
+- Little config.h cleanup (removed obsolete non-working defines).
+- Allow opers to talk in channel even if +m (#0001109).
+- Implemented the *nix resolver under windows. This should solve 90% of the problems that
+  exist in the Windows version. There may be some problems with the resolver that still
+  need to be worked out, however it should be much more stable than before. Some of this
+  code is based on the ircu Windows NT port by run.
+- Fixed a problem with /quote dns i
+- Rewrote a whole bunch of stuff in the extcmode code
+- Extended the module system to allow better error reporting using ModuleGetError and
+  ModuleGetErrorStr
+- Changed channel mode +f, it's a much more advanced antiflood mode now.
+  It can protect against joinfloods, ctcpfloods, nickfloods and message/notice floods.
+  For example +f [10j]:15 allows 10 joins per 15 seconds, if the limit is reached the
+  channel is set automatically +i (invite only) by the server.
+  You can read more about it in section 3.12 'Anti-Flood features' of unreal32docs.html:
+  http://www.vulnscan.org/UnrealIrcd/unreal32docs.html#feature_antiflood
+  This change can cause desynch problems if both old+f and new+f servers are used on
+  a network. It's (currrently!) possible to use the old +f system if you undef NEWCHFLOODPROT
+  in include/config.h.
+- Fixed ~5 compiler warnings at *NIX and ~20 at windows. Some of them _could_ have caused problems.
+- Moved EOS debugging code to DEBUGMODE.
+- Fixed a channel sync bug reported by thilo&Rocko (#0001218).
+- Fixed minor config parser memleak reported by AngryWolf (#0001214).
+- Fixed bug regarding hidden opers + m_whois cleanup (#0001208).
+- Made SSL users unable to -z themselves, also added 2 flags to /stats S,
+  reported by Joolz (#0001200).
+- Fixed problem with opers having both 'admin' and 'coadmin' causing double-notices (#0001043).
+- +f now also allows you to specify an 'action'. For example +f [30j#R]:15 will set the
+  channel +R (instead of +i) if more than 30 joins in 15 seconds are reached.
+  The following combinations are allowed: c#m, c#M, j#R and m#M. (docs will be updated later)
+- Probably fixed a bug regarding 'setting mode' notice with +f (was sometimes sent to non-chanops).
+- Fixed multiple chmode +u bugs: remote join, netjoin, +mu relay between servers, kick and
+  a part bug. Most of them reported by Lx (#0001097).
+- Fixed a bug in +f + modes-on-join + 't' subfloodtype, reported by Rocko (#0001228).
+- Fixed a crashbug with +f and services, reported by Rocko (#0001227).
+- And another +f + modes-on-join one...
+- Made anti away flood system work just like anti nick flood (#0001205).
+  NO_FLOOD_AWAY is now enabled and away-flood is set to 4 per 120s by default.
+- Fixed a double OperOverride notice bug reported by DukePyrolator (#0001180).
+- Doc fixes/updates reported by Angrywolf (#0001163, #0001176).
+- Fixed a /rehash crash regarding badword all & regex badwords, reported by Angrywolf (#0001230).
+- Fixed an old bug where allow::hostname localhost (or *@localhost) didn't work (#0001115).
+- Fixed a chroot bug, reported by iceblade (#0001112).
+- Badwords filtering is now only done for local clients, previously every server was filtering
+  the message. This will reduce CPU usage, especially at hubs (#0001022).
+- Will now strip/block color codes in quits if any channel the user is in has mode +S/+c.
+- Temporarely added trace code for hunting down negative operator counts (#0001155).
+- Made it so that with +M and user not +r and not voice/halfop/ops/etc the part message isn't
+  shown, just like with +m.
+- Added warn option to deny channel, this will send a notice to the eyes snomask when a user
+  attempts to join. Suggested by Joolz (#0000992).
+- Added clientsonly/serversonly/ssl/java flags to /stats P (#0000992).
+- Added official-channels block. These channels are listed in /list even if they have 0 users.
+- Fixed a crashbug introduced by +mu fixes 3 days ago (#0001237).
+- Fixed a typo where /knock would say the channel is +I if +V is set, reported by Certus
+- Improved SSL error msg sent to junk snomask.
+- Fixed Q:lined nickname msgs during linking and a debug fix.
+- Fixed a SVSMOTD crashbug (removing of motd).
+- Fix-for-fix-for-+mu-fix (it was still crashing)... don't ask.
+- Minor +f code tweaks.
+- Added checks for ipv4 listen lines on ipv6 compile.
+- Finished some of the extcmode code (memleaks).
+- Fixed a problem in the new win32 resolver code
+- Added HOOKTYPE_UNKUSER_QUIT (disconnects of unregistered clients).
+- Fixed a Linux PPC problem (#0001242)
+- Made the win32 version use libtre for regex rather than GNU regex
+  libtre is smaller, faster, and more feature rich.
+- Fixed some issues regarding unsetting of -R/-M when server set that mode due to a flood (+f),
+  it would set the mode back immediately after next msg/join, counters are now reset.
+- Updated documentation
+- Added set::default-bantime. It allows you to set the default time for a gline/kline/gzline/
+  shun/etc when the time is not not specified (like with /gline *@*.stupid.net).
+- Added HOOKTYPE_LOCAL_PASS and HOOKTYPE_REMOTE_CONNECT
+- Added HOOKTYPE_REMOTE_QUIT
+- Added beta18 release notes (might be changed)
+- Added HOOKTYPE_REHASHFLAG (triggered when /rehash is passed a flag)
+- Fix for HOOKTYPE_REMOTE_QUIT (was called for local quits too)
+- Redid the join/kick/topic hooks
+- Added a few macros (MOD_HEADER, MOD_INIT, MOD_TEST, MOD_LOAD, MOD_UNLOAD) to make
+  setting up a module for both static and dynamic linking easier
+- Fixed a win32 resolver lockup bug
+- Fixed hunt_server* bug
+- Very Very small change to doc/example.conf
+- Updated .CHANGES.NEW to read Beta18
+- Minor doc update.
+- Updated all the modules to use the new macros
+- Changed version to 'beta18'
index 6b248cf50301429e70eaf715427e2c2c59a147aa..65a89446d8ea6e3fb802c8e733c7c65af19a4274 100644 (file)
@@ -138,7 +138,7 @@ MAKEARGS =  'CFLAGS=${CFLAGS}' 'CC=${CC}' 'IRCDLIBS=${IRCDLIBS}' \
                'CRYPTOINCLUDES=${CRYPTOINCLUDES}'
 
 custommodule:
-       cd src; ${MAKE} ${MAKEARGS} MODULEFILE=${MODULEFILE} EXLIBS=${EXLIBS} custommodule
+       cd src; ${MAKE} ${MAKEARGS} MODULEFILE=${MODULEFILE} 'EXLIBS=${EXLIBS}' custommodule
 
 server:
 build:
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..d8edfeb
--- /dev/null
+++ b/README
@@ -0,0 +1,24 @@
+==[ COMPILING ]==
+To build the ircd, run:
+./Config
+make
+
+If you specified an alternative location during ./Config you also need
+to run "make install".
+
+==[ MAKING A CONFIG FILE ]==
+If you are new, then you need to create your own configfile:
+
+copy doc/example.conf to your main UnrealIRCd directory and call
+it unrealircd.conf .
+Then open it in an editor and carefully modify it, consult the docs
+(doc/unreal32docs.html, or online: www.unrealircd.com/unreal32docs.html)
+for more information about every block/setting.
+Common problems are explained in the FAQ, which is located at:
+http://www.vulnscan.org/UnrealIrcd/faq/ .
+
+==[ BOOTING YOUR IRCD ]==
+Just type: ./unreal start
+Note that after booting the errors are usually logged to ircd.log,
+so check that file if you have any problems.
+Again, check the FAQ (and docs) if you have any boot problems.
index 7d6d733c9953a1d25efb096de427ffa3568394d0..195858b2ddeb7efb3f2cae60b8021575a4e5bd20 100644 (file)
@@ -1,5 +1,5 @@
 ===============================================
-=            UnrealIRCd v3.2 (beta17)         =
+=            UnrealIRCd v3.2 (beta18)         =
 ===============================================
  Was brought to you by:
 
index 589fd1f20b0ccdaefee5d0b2c1ac03e6cfdaf242..f6e4a994afc2407aa79997e0e7573ba21f472755 100644 (file)
@@ -368,6 +368,7 @@ CFLAGS="$CFLAGS -D_SOLARIS"
 IRCDLIBS="$IRCDLIBS -lresolv "
 ;;
 esac
+
 dnl AC_MSG_RESULT(configuring TRE regex library)
 dnl cur_dir=`pwd`
 dnl cd extras/tre
@@ -377,5 +378,6 @@ dnl make
 dnl AC_MSG_RESULT(installing TRE regex library)
 dnl make install
 dnl cd $cur_dir
-AC_OUTPUT(Makefile src/modules/Makefile unreal)
+AC_OUTPUT(Makefile src/modules/Makefile unreal ircdcron/ircdchk)
 chmod 0700 unreal
+chmod 0700 ircdcron/ircdchk
index 41558cf370b2be2920ee2c7c3b9cae477c358e0c..903e93c1e3305cc8dd42a959636b3456ef73148a 100755 (executable)
--- a/configure
+++ b/configure
@@ -9956,7 +9956,8 @@ CFLAGS="$CFLAGS -D_SOLARIS"
 IRCDLIBS="$IRCDLIBS -lresolv "
 ;;
 esac
-ac_config_files="$ac_config_files Makefile src/modules/Makefile unreal"
+
+ac_config_files="$ac_config_files Makefile src/modules/Makefile unreal ircdcron/ircdchk"
 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
@@ -10430,6 +10431,7 @@ do
   "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
   "src/modules/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/modules/Makefile" ;;
   "unreal" ) CONFIG_FILES="$CONFIG_FILES unreal" ;;
+  "ircdcron/ircdchk" ) CONFIG_FILES="$CONFIG_FILES ircdcron/ircdchk" ;;
   "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;}
@@ -10975,3 +10977,4 @@ if test "$no_create" != yes; then
 fi
 
 chmod 0700 unreal
+chmod 0700 ircdcron/ircdchk
index fe098da60f14270b40d7591fa4cb05603c8ae8e4..38492aad055e2fc5369788150a5b87aa79ecfdd9 100644 (file)
@@ -16,7 +16,7 @@
  * PLEASE READ doc/unreal32docs.html! The online version is also available at:
  * www.vulnscan.org/UnrealIrcd/unreal32docs.html
  * It contains a lot information about the configfile: gives information about
- * every block, variable, etc.
+ * every block, variable, etc..
  */
 
 /* Type of comments */
@@ -541,7 +541,9 @@ ban ip {
 /*
  * NEW: ban server {}
  * OLD: Server Q:Line
- * Disables a server from connecting to you.
+ * Disables a server from connecting to the network.
+ * if the server links to a remote server, local server
+ * will disconnect from the network.
  * Syntax is as follows:
  * ban server {
  *     mask "(server name)";
@@ -680,7 +682,7 @@ set {
        stats-server            "stats.roxnet.org";
        help-channel            "#ROXnet";
        hiddenhost-prefix       "rox";
-       prefix-quit             "no";
+       /* prefix-quit          "no"; */
        cloak-keys {
                9666;
                3333;
@@ -732,21 +734,30 @@ set {
        /* Make the message in static-quit show in all quits - meaning no
            custom quits are allowed on local server */
        /* static-quit "Client quit";   */
-       /* This allows you to make certain stats oper only, use * for all stats or leave this out to allow 
-        * all users to use any stats. */
-       oper-only-stats "okG";
-
-       /* Throttling: this example sets a limit of 3 connections per 60s. */
+       /* This allows you to make certain stats oper only, use * for all stats,
+        * leave it out to allow users to see all stats. Type '/stats' for a full list.
+        * Some admins might want to remove the 'kGs' to allow normal users to list
+        * klines, glines and shuns.
+        */
+       oper-only-stats "okGsMRUEelLCX";
+
+       /* Throttling: this example sets a limit of 3 connections per 60s (per host). */
        throttle {
                connections 3;
                period 60s;
        };
 
+       /* Anti flood protection */
+       anti-flood {
+               nick-flood 3:60;        /* 3 nickchanges per 60 seconds (the default) */
+       };
+
 };
 
 /*
- * Need more help ? 
- * 1) Read the documentation, doc/unreal32docs.html !!
- * 2) Mail unreal-users@lists.sourceforge.net
- * 3) Come to irc.ircsystems.net #Unreal-Support
+ * Problems or need more help?
+ * 1) www.vulnscan.org/UnrealIrcd/unreal32docs.html
+ * 2) www.vulnscan.org/UnrealIrcd/faq/ <- contains 80% of your questions!
+ * 3) If you still have problems you can go irc.ircsystems.net #unreal-support,
+ *    note that we require you to READ THE DOCUMENTATION and FAQ first!
  */
index bb34aa9e64d74cc2764be9446fc87810a8dbbe93..662c51eae8b612dbd97cbef55847adf51aeaef35 100644 (file)
 <div align="center"><b><font size="7">UnrealIRCd</font></b><br>
   <font size="4"><a href="http://www.unrealircd.com">http://www.unrealircd.com</a></font><br>
   <font size="4">Version: 3.2</font><br>
-  <b>Current Version:</b> 3.2 Beta17<br>
-  <b>Last doc update:</b> 2003-06-15 </div>
+  <b>Current Version:</b> 3.2 Beta18<br>
+  <b>Last doc update:</b> 2003-09-22</div>
   <b>Head Coders:</b> Stskeeps / codemastr / Luke / McSkaf / Syzop<br>
   <b>Contributors:</b> Zogg / NiQuiL / assyrian / chasm / DrBin / llthangel / Griever / nighthawk<br>
   <b>Documentation:</b> CKnight^ / Syzop<br>
 <p>Due to the increasing complexity of UnrealIRCd3.2 We have switched to an easier 
   to navigate, more inclusive documentation set. To view this documentation you 
   must have a compatible browser, which are listed below. Up to date docs are 
-  available @ <a href="http://www.vulnscan.org/UnrealIrcd/unreal32docs.html">http://www.vulnscan.org/UnrealIrcd/unreal32docs.html</a></p>
+  available at <a href="http://www.vulnscan.org/UnrealIrcd/unreal32docs.html">http://www.vulnscan.org/UnrealIrcd/unreal32docs.html</a>
+  and a FAQ at <a href="http://www.vulnscan.org/UnrealIrcd/faq/" TARGET="_blank">http://www.vulnscan.org/UnrealIrcd/faq/</a>.
+</p>
 <p><b>Compatible Browsers: </b><br>
 <ul>
 <li>Opera 6.02
@@ -55,7 +57,7 @@
   -- 3.9. <a href="#feature_ipv6">IPv6</a><br>
   -- 3.10. <a href="#feature_ziplinks">Zip links</a><br>
   -- 3.11. <a href="#feature_dyndns">Dynamic DNS/IP linking support</a><br>
-  -- 3.12. <a href="#feature_throttling">Throttling</a><br>
+  -- 3.12. <a href="#feature_antiflood">Anti-flood features</a><br>
   -- 3.13. <a href="#feature_other">Other features</a><br>
   4. <a href="#configuringyourunrealircdconf">Configuring your unrealircd.conf 
   file</a><br>
   ---4.30. <a href="#linkblock">Link Block -=- (C/N/H:Lines)</a><br>
   ---4.31. <a href="#aliasblock">Alias Block</a><br>
   ---4.32. <a href="#helpblock">Help Block</a><br>
-  ---4.33. <a href="#setblock">Set Block -=- (networks/unrealircd.conf)</a><br>
+  ---4.33. <a href="#officialchannels">Official Channels Block</a><br>
+  ---4.34. <a href="#setblock">Set Block -=- (networks/unrealircd.conf)</a><br>
   5. <a href="#addtlfiles">Additional Files</a><br>
   6. <a href="#userchannelmodes">User & Channel Modes</a><br>
   7. <a href="#useropercommands">User & Oper Commands</a><br>
-  8. <a href="#faq">Frequently Asked Questions (FAQ)</a><br> 
+  8. <a href="http://www.vulnscan.org/UnrealIrcd/faq/" target="_blank">Frequently Asked Questions (FAQ)</a><br> 
 </p>
 <p><b><font size="+2">1.0 &#8211;Introduction & Notes <a name="IntroductionNotes"></a></font></b><br>
 </p><div class="desc">
   of the UnrealIRCd Development Team. This document may be copied/printed/reproduced/published 
   as many times as you like, provided it is for use with UnrealIRCd and it is not 
   modified in anyway. &#8211; Copyright UnrealIRCd Development Team 2002-2003</p>
-<p>Please read this manual before asking for help, you may also want to take a look
-   at the <a href="#faq">FAQ</a> for common problems. If that didn't help you can
-   ask for support at <a href="irc://irc.ircsystems.net/unreal-support">irc.ircsystems.net (port 6667) channel #unreal-support</a> (strict UnrealIRCd support, don't
-   ask for help about services!). If you have a real bug (like a crash) then report it at 
+<p>Please read this manual before asking for help, you also REALLY want to take a look at the 
+   <a href="http://www.vulnscan.org/UnrealIrcd/faq/" target="_blank">FAQ</a> since over 80% of your questions/problems are answered in it. If you still
+   need help you can ask for support at irc.ircsystems.net (port 6667) channel #unreal-support (note 
+   that we REQUIRE you to read the docs and faq and we only help with UnrealIRCd, not with services!). 
+   If you have a real bug (like a crash) then report it at 
    <a href="http://bugs.unrealircd.org" TARGET="_blank">http://bugs.unrealircd.org</a>.</p></div>
 
 <p><font size="+2"><b>1.1 &#8211; Notes on upgrading/mixing 3.1.x -&gt; 3.2 </b></font><a name="notesonolder"></a><br>
 Linux:<br>
 <ul>
 <li>Rename your old UnrealIRCd directory (or otherwise you'll overwrite it in the next step)
-<li>Extract the new UnrealIRCd version and run ./Config and make(*NIX).
+<li>Extract the new UnrealIRCd version and run ./Config and make
 <li>Copy your old configuration files to the new directory (unrealircd.conf, motd, rules, server.* [SSL certs], network file, etc)</p></ul>
 Windows:<br>
 <ul>
@@ -134,8 +138,8 @@ Windows:<br>
 <li>Run the installer for the new version of Unreal.
 <li>Copy your old configuration files to the new folder.
 </ul>
-<p>Please also check .RELEASE.NOTES and maybe even Changes to see what has been changed. 
-   If you notice any changes (or bugs) between version, BE SURE TO READ THOSE FILES FIRST before reporting it as a bug!.</p></div>
+<p>Please also check .RELEASE.NOTES to see what has been changed. 
+   If you notice any changes (or bugs) between version, BE SURE TO READ THE RELEASE NOTES FIRST before reporting it as a bug!.</p></div>
 
 <p><font size="+2"><b>2.0 - Installation</b></font><a name="installation" id="installation"></a><br><div class="desc">
   <br>
@@ -197,14 +201,14 @@ Windows:<br>
 <p>This is controlled by usermode +x (like: /mode yournick +x), admins can also force +x to be enabled 
    by default, or make it so users can never do -x.</p>
 <p>The cloaked host is generated by a formula which uses 3 "cloak keys." You are required
-   to set these 3 keys in your config file, they should be 3 random numbers between 10,000 and 4,294,967,295.
+   to set these 3 keys in your config file, they should be 3 random numbers between 10,000 and 2,147,483,646.
    If someone else knows these keys they can decode the cloaked host and discover the real one, that's why you
-   have to keep them secret. The cloak keys must be the same on all servers on the network.</p>
+   have to keep them secret. _The cloak keys must be the same on all servers on the network_.</p>
 </div>
 <p><font size="+2"><b>3.2 - Modules</b></font><a name="feature_modules"></a></p><div class="desc">
 <p>UnrealIRCd supports modules (except under windows) which is nice because:<br>
    - You can load/reload/unload them while the ircd is running (by /rehash). This allows some bugs to be fixed or new features to be added without requiring a restart.<br>
-   - Other people can create modules as well with new commands or usermodes for example.<br>
+   - Other people can create (3rd party) modules with new commands, usermodes and even channelmodes.<br>
    UnrealIRCd only comes with a few modules, take a look at www.unrealircd.com -&gt; modules
    or use google to find 3rd party modules.</p>
 <p>Note that you need to load at least the commands module!</p></div>
@@ -263,7 +267,8 @@ Windows:<br>
 <p>You need to have your IRC server compiled with SSL support. To setup an SSL port you need to set listen::options::ssl.</p>
 <p>You cannot connect normally to a SSL port (so don't make port 6667 ssl!), you need a client or a tunnel
    that understands the SSL protocol.</p>
-<p>Clients that support SSL: <A HREF="http://www.xchat.org/" TARGET="_blank">XChat</a></p>
+<p>Clients that support SSL: <A HREF="http://www.xchat.org/" TARGET="_blank">XChat</a>,
+                             <A HREF="http://www.irssi.org/" TARGET="_blank">irssi</a></p>
 <p>For all other clients which don't support SSL (like mIRC) you can use a tunnel like
    <A HREF="http://www.stunnel.org/" TARGET="_blank">stunnel</A>, here's a stunnel.conf example (for stunnel 4.x):<br>
    <pre>
@@ -278,25 +283,86 @@ Windows:<br>
 <p>If you are really concerned about security/sniffing then you also need to validate certificates on the client end.
    That's however way too off topic to explain here. Learn about SSL, don't ask us, it has nothing to do with UnrealIRCd.</p></div>
 <p><font size="+2"><b>3.9 - IPv6</b></font><a name="feature_ipv6"></a></p><div class="desc">
-<p>UnrealIRCd supports IPv6, since beta15 it seems to work well although there might be some
-   bugs in it. You need to compile with IPv6 support (answer yes to the ./Config question), ofcourse your
-   OS needs to have IPv6 support enabled too.</p>
+<p>UnrealIRCd supports IPv6, since beta15 it seems to be stable.<br> 
+   Your OS needs to have IPv6 support and you need to enable IPv6 support in UnrealIRCd during ./Config as well.<br>
 <p>Although microsoft has an experimental IPv6 implementation for w2k/XP it is not (yet) supported by UnrealIRCd.</p></div>
 
 <p><font size="+2"><b>3.10 - Zip links</b></font><a name="feature_ziplinks"></a></p><div class="desc">
 <p>Zip links can be turned on for server&lt;-&gt;server links, it compresses the data by using zlib.
    It can save 60-80% bandwidth... So it's quite useful for low-bandwidth links or links with
    many users, it can help a lot when you are linking since a lot of data is sent about every user/channel/etc.</p>
-<p>To compile with zip links support, you need to answer Yes to the zlib question in ./Config and set it in link::options::zip</p></div>
+<p>To compile with zip links support, you need to answer Yes to the zlib question in ./Config and set it in link::options::zip 
+   (on both sides)</p></div>
 
 <p><font size="+2"><b>3.11 - Dynamic DNS/IP linking support</b></font><a name="feature_dyndns"></a></p><div class="desc">
 <p>UnrealIRCd has some (new) nice features which helps dynamic IP users using dynamic DNS (like blah.dyndns.org).
    If you are linking two dynamic DNS hosts, then set link::options::nodnscache and link::options::nohostcheck. 
 </p></div>
 
-<p><font size="+2"><b>3.12 - Throttling</b></font><a name="feature_throttling"></a></p><div class="desc">
-<p>Throttling is a method that allows you to limit how fast a user can disconnect and then reconnect to your server. 
-   You can config it in your set::throttle block to allow X connections in YY seconds from the same IP.</p></div>
+<p><font size="+2"><b>3.12 - Anti-Flood features</b></font><a name="feature_antiflood"></a></p><div class="desc">
+<p>
+<b>Throttling</b><br>
+Throttling is a method that allows you to limit how fast a user can disconnect and then reconnect to your server. 
+ You can config it in your set::throttle block to allow X connections in YY seconds from the same IP.<br>
+<b>Channel modes</b><br>
+There are also some channel modes which can be very effective against floods. To name a few:<br>
+<b>K</b> = no /knock, <b>N</b> = no nickchanges, <b>C</b> = no CTCPs, <b>M</b> = only registered users can talk.<br>
+As of beta18 there's also a much more advanced channelmode +f...<br>
+<b>Channel mode f</b><br>
+Instead of using scripts and bots to protect against channel floods it is now build into the ircd.<br>
+This is an example +f mode: <i>*** Blah sets mode: +f [10j]:15</i><br>
+This means 10 joins per 15 seconds are allowed in the channel, if the limit is hit, the channel will be set +i automatically.<br>
+The following floodtypes are available:<br>
+<table border=1 cellpadding=3 cellspacing=1>
+<tr><td>mode:</td><td>name:</td><td>default action:</td><td>other avail. actions:</td><td>comments</td></tr>
+<tr><td>c</td><td>CTCPs</td><td>auto +C</td><td>m, M</td><td>&nbsp;</td></tr>
+<tr><td>j</td><td>joins</td><td>auto +i</td><td>R</td><td>&nbsp;</td></tr>
+<tr><td>k</td><td>knocks</td><td>auto +K</td><td>&nbsp;</td><td><font size=-1>(counted for local clients only)</font></td></tr>
+<tr><td>m</td><td>messages/notices</td><td>auto +m</td><td>M</td><td>&nbsp;</td></tr>
+<tr><td>n</td><td>nickchanges</td><td>auto +N</td><td>&nbsp;</td><td>&nbsp;</td></tr>
+<tr><td>t</td><td>text</td><td>kick</td><td>b</td><td>per-user messages/notices like the old +f. Will kick or ban the user.</td></tr>
+</table>
+<p />&nbsp;
+Example:
+<pre>
+<font color=green>*** ChanOp sets mode: +f [20j,50m,7n]:15</font>
+&lt;ChanOp&gt; lalala
+<font color=green>*** Evil1 (~fdsdsfddf@Clk-17B4D84B.blah.net) has joined #test
+*** Evil2 (~jcvibhcih@Clk-3472A942.xx.someispcom) has joined #test
+*** Evil3 (~toijhlihs@Clk-38D374A3.aol.com) has joined #test
+*** Evil4 (~eihjifihi@Clk-5387B42F.dfdfd.blablalba.be) has joined #test</font>
+-- snip XX lines --
+<font color=green>*** Evil21 (~jiovoihew@Clk-48D826C3.e.something.org) has joined #test</font>
+<font color=brown>-server1.test.net:#test *** Channel joinflood detected (limit is 20 per 15 seconds), putting +i</font>
+<font color=green>*** server1.test.net sets mode: +i</font>
+&lt;Evil2&gt; fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl
+&lt;Evil12&gt; fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl
+&lt;Evil15&gt; fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl
+&lt;Evil10&gt; fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl
+&lt;Evil8&gt; fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl
+-- snip XX lines --
+<font color=brown>-server1.test.net:#test *** Channel msg/noticeflood detected (limit is 50 per 15 seconds), putting +m</font>
+<font color=green>*** server1.test.net sets mode: +m</font>
+<font color=green>*** Evil1 is now known as Hmmm1</font>
+<font color=green>*** Evil2 is now known as Hmmm2</font>
+<font color=green>*** Evil3 is now known as Hmmm3</font>
+<font color=green>*** Evil4 is now known as Hmmm4</font>
+<font color=green>*** Evil5 is now known as Hmmm5</font>
+<font color=green>*** Evil6 is now known as Hmmm6</font>
+<font color=green>*** Evil7 is now known as Hmmm7</font>
+<font color=green>*** Evil8 is now known as Hmmm8</font>
+<font color=brown>-server1.test.net:#test *** Channel nickflood detected (limit is 7 per 15 seconds), putting +N</font>
+<font color=green>*** server1.test.net sets mode: +N</font>
+</pre>
+
+Instead of the default action, you can for some floodtypes specify another one, for example: <i>+f [20j#R,50m#M]:15</i><br>
+This will set the channel +R if the joinlimit is reached (&gt;20 joins in 15 seconds),
+and will set the channel +M if the msg limit is reached (&gt;50 messages in 15 seconds).<br>
+Look at the table above to see more options.<br>
+<br>
+The old +f mode (msgflood per-user) is also still available as 't', +f 10:6 is now called +f [10t]:6 and 
++f *20:10 is now +f [20t#b]:10. Currently the ircd will automatically convert old +f mode types to new ones.<br>
+</p></div>
 
 <p><font size="+2"><b>3.13 - Other features</b></font><a name="feature_other"></a></p><div class="desc">
 <p>UnrealIRCd has a lot of features so not everything is covered here... You'll find that out by yourself.</p></div>
@@ -423,7 +489,7 @@ class &lt;name&gt; {
 <p><b>maxclients</b> specifies the maximum (total) number of clients/servers which can be in this class</p>
 <p><b>sendq</b> specifies the amount of data which can be in the send queue (very high for servers with low bandwith, medium for clients)</p>
 <p><b>recvq</b> specifies the amount of data which can be in the receive queue and is used for flood control 
- (this only applies to normal users, try experimenting with values 3000-8000, >8000 is no difference and 8000 is the default).</p>
+ (this only applies to normal users, try experimenting with values 3000-8000, 8000 is the default).</p>
 <p>Examples:<br>
 <pre>
 class clients {
@@ -526,7 +592,7 @@ listen &lt;ip:port&gt; {
   no options are required, you may specify this without any directives in the 
   form listen &lt;ip:port&gt;;.</p>
 <p><b>ip and port</b><br>
-  ip is usually set at * but you can specify an IP here to only bind to that IP. 
+  You can set ip to * to bind to all available ips, or specify one to only bind to that ip (usually needed at shell providers).
   The port is the port you want to listen on. You can also set the port to a range rather than an individual
   value. For example, 6660-6669 would listen on ports 6660 through 6669 (inclusive). IPv6 users, see below.</p>
 <p><b>Info for IPv6 users</b><br>
@@ -534,7 +600,7 @@ listen &lt;ip:port&gt; {
   Like [::1]:6667 (listen at localhost on port 6667). If you are using IPv6 and you 
   want to listen at a specific IPv4 addr you need to use ::ffff:ipv4ip. For example: 
   [::ffff:203.123.67.1]:6667 which will listen at 203.123.67.1 on port 6667. 
-  Ofcourse you can also just use * with IPv6.</p>
+  Ofcourse you can also just use *.</p>
 <p><b>options block</b> (optional)<br>
   You can specify special options for this port if you want, valid options are:<br>
 <table border="0">
@@ -557,6 +623,7 @@ listen *:6601 {
 </pre></p>
 <p>Or if there are no options:</p>
 <p>listen *:8067;<br>
+  listen 213.12.31.126:6667;<br>
   listen *:6660-6669;</p></div>
 <p><font class="block_section">4.7 - </font><font class="block_name">Oper Block</font>
    <font class="block_recommended">RECOMMENDED</font> <font class="block_old">(Previously known as the O:Line)</font><a name="operblock"></a><div class="desc">
@@ -689,11 +756,6 @@ listen *:6601 {
     <td><div align="center">can_unkline</div></td>
     <td>Can use /kline -u@h</td>
   </tr>
-  <tr> 
-    <td><div align="center">t</div></td>
-    <td><div align="center">can_gkline</div></td>
-    <td>Can use /gline and /shun</td>
-  </tr>
   <tr> 
     <td><div align="center">n</div></td>
     <td><div align="center">can_localnotice</div></td>
@@ -732,7 +794,7 @@ listen *:6601 {
   <tr> 
     <td><div align="center">v</div></td>
     <td><div align="center">can_override</div></td>
-    <td>Can use OperOverride</td>
+    <td>Can use <a href="#operoverride">OperOverride</a></td>
   </tr>
 </table>
 <p>Certin flags give you other flags by default:</p>
@@ -760,10 +822,10 @@ listen *:6601 {
   </tr>
   <tr> 
     <td>can_globops</td>
-    <td>can_glopops</td>
-    <td>can_glopops</td>
-    <td>can_glopops</td>
-    <td>can_glopops</td>
+    <td>can_globops</td>
+    <td>can_globops</td>
+    <td>can_globops</td>
+    <td>can_globops</td>
   </tr>
   <tr> 
     <td>can_wallops</td>
@@ -851,6 +913,11 @@ oper bobsmith {
        snomask frebWqFv;
 };
 </pre></p>
+<a name="operoverride"><b>Some little info about OperOverride:</b><br>
+OperOverride are things like: joining a +ikl channel and going trough bans (you need to /invite yourself first however), 
+op'ing yourself in a channel, etc.<br>
+The can_override operflag was added as an attempt to stop oper abuse.
+No oper is able to override by default, you would have to give them the can_override flag explicitly.
 <p> </p></div>
 <p><font class="block_section">4.8 - </font><font class="block_name">DRpass Block</font>
    <font class="block_recommended">RECOMMENDED</font> <font class="block_old">(Previously known as the X:Line)</font><a name="drpassblock"></a><div class="desc">
@@ -1064,9 +1131,11 @@ ban server {
        mask &lt;server-name&gt;;
        reason &lt;reason-for-ban&gt;;
 };</pre></p>
-<p>This block disables a server's ability to connect to your server. The ban::mask 
-  field specifies a wildcard mask to match against the server attempting to connect's 
-  name, and ban::reason specifies the reason for which this ban has been placed.</p>
+<p>This block disables a server's ability to connect to the network. If the server links 
+  directly to your server, the link is denied. If the server links to a remote server, the 
+  local server will disconnect from the network. The ban::mask field specifies a wildcard
+  mask to match against the server attempting to connect's name, and ban::reason specifies 
+  the reason for which this ban has been placed.</p>
 <p>Example:<br>
 <pre>
 ban server {
@@ -1257,14 +1326,17 @@ deny channel {
        channel "&lt;channel-mask&gt;";
        reason &lt;reason-for-ban&gt;;
        redirect "&lt;channel-name&gt;";
+       warn [on|off];
 };</pre></p>
 <p> </p>
 <p>The deny channel block allows you to disallow users from joining specific channels. 
-  The deny::channel directive specifies a wildcard mask of channels the users 
-  may not join, and the deny::reason specifies the reason why the channel may 
-  not be joined. Additionally, you may specify a deny::redirect. If this is specified,
+  The <b>deny::channel</b> directive specifies a wildcard mask of channels the users 
+  may not join, and the <b>deny::reason</b> specifies the reason why the channel may 
+  not be joined. Additionally, you may specify a <b>deny::redirect</b>. If this is specified,
   when a user tries to join a channel that matches deny::channel, he/she will be redirected
-  to deny::redirect.</p>
+  to deny::redirect. And there's also <b>deny::warn</b> which (if set to on) will send an
+  opernotice (to EYES snomask) if the user tries to join.
+</p>
 <p>Example</p>
 <pre>
 deny channel {
@@ -1272,6 +1344,12 @@ deny channel {
        reason "No it don't!";
 };
 
+deny channel {
+       channel "#*teen*sex*";
+       reason "You == dead";
+       warn on;
+};
+
 deny channel {
        channel "#operhelp";
        reason "Our network help channel is #help, not #operhelp";
@@ -1347,9 +1425,9 @@ badword &lt;type&gt; {
 };</pre></p>
 <p>The badword block allows you to manipulate the list used for user and channel 
   mode +G to strip "badwords". The badword:: specifies the type, valid 
-  types are channel, message, and quit, channel is for the channel +G list, message 
-  is for the user +G list, and quit is for quit message censoring. The badword::word
-  can be a simple word or a regular expression we should search for. The 
+  types are channel, message, quit, and all. channel is for the channel +G list, message 
+  is for the user +G list, quit is for quit message censoring, and all adds it to all three lists. 
+  The badword::word can be a simple word or a regular expression we should search for. The 
   badword::replace is what we should replace this match with. If badword::replace 
   is left out, the word is replaced with &lt;censored&gt;. The badword::action defines
   what action should be taken if this badword is found. If you specify replace, then the
@@ -1554,17 +1632,39 @@ help &lt;name&gt; {
   for the help block are the text that will be displayed to the user when requesting 
   the /helpop.</p>
 <p></p></div>
-<p><font class="block_section">4.33 - </font><font class="block_name">Set Block</font>
+
+<p><font class="block_section">4.33 - </font><font class="block_name">Official Channels Block</font>
+   <font class="block_optional">OPTIONAL</font><a name="officialchannels"></a>
+</p><div class="desc">
+<p>Syntax:<br>
+<pre>
+official-channels {
+       "#channel" { topic "The default topic"; };
+};</pre></p>
+<p>Official channels are shown in /list even if no users are in the channel.
+   The <b>topic</b> is optional and is only shown in /list if it has 0 users.
+</p>
+
+<p>Example:<br>
+<pre>
+official-channels {
+       "#Help" { topic "The official help channel, if nobody is present type /helpop helpme"; };
+       "#Home";
+       "#Main" { topic "The main channel"; };
+};</pre></p>
+</div>
+
+<p><font class="block_section">4.34 - </font><font class="block_name">Set Block</font>
    <font class="block_required">REQUIRED</font> <font class="block_old">(Previously known as unrealircd.conf/networks file)</font><a name="setblock"></a>
 </p><div class="desc">
 <p>The set file is what use to be our networks/unrealircd.conf and our networks 
   file. On single server networks, rather than have 3 files, on single server 
   networks, you can just include the set statements in the unrealircd.conf, on 
   multi-server networks, i recommend still using a networks file.</p>
-<p>Now, if your server is on a network, chances are you will all basically use 
-  the same Set settings. Therefore it makes more sense to have a network file, 
-  which is loaded with a include:: directive. Below you will find all of the set 
-  directives available.</p>
+  <p>Now, if your server is on a network, chances are you will all basically use 
+    the same Set settings. Therefore it makes more sense to have a network file, 
+    which is loaded with a include:: directive. Refer to section <a href="#includedirective">4.9</a>. 
+    Below you will find all of the set directives available.</p>
 <p>In this doc we refer to settings / directives in the &lt;block-name&gt;::&lt;block-directive&gt; 
   format. This format is NOT the format that it can be entered into the configuration 
   file. IT MUST be converted to the format listed below. It is presented in the 
@@ -1644,9 +1744,17 @@ set {
 <p><font class="set">set::oper-only-stats &lt;stats-list&gt;;</font><br>
   Specifies a list of stats flags with no seperators that defines stats flags 
   only opers can use. Leave this value out to allow users to use all flags, or 
-  specify * for users to be able to use no flags.</p>
+  specify * for users to be able to use no flags. Only short operflags may be specifed
+  here.</p>
+<p><font class="set">set::oper-only-stats {&lt;stats-flag&gt;; &lt;stats-flag&gt;;};</font><br>
+  Specifies a list of stats flags that can only be used by opers. This only works with long
+  stats flags.</p>
 <p><font class="set">set::maxchannelsperuser &lt;amount-of-channels&gt;;</font><br>
   Specifies the number of channels a single user may be in at any one time.</p>
+<p><font class="set">set::channel-command-prefix &lt;command-prefixes&gt;;</font><br>
+  Specifies the prefix characters for services "in channel commands". Messages starting with 
+  any of the specified characters will still be sent even if the client is +d. The default 
+  value is "`".</p>
 <p><font class="set">set::allow-userhost-change [never|always|not-on-channels|force-rejoin]</font><br>
   Specifies what happens when the user@host changes (+x/-x/chghost/chgident/setident/vhost/etc).<br>
   <i>never</i> disables all the commands, <i>always</i> does always allow it even when in channels 
@@ -1753,20 +1861,29 @@ set {
  <p><font class="set">set::anti-flood::unknown-flood-amount &lt;amount&gt;;</font><br>
   Specifies the amount of data (in KiloBytes) that the unknown connection must send
   in order for the user to be killed.</p>
- <p><font class="set">set::anti-flood::away-count &lt;amount&gt;;</font><br>
-  Specifies the number of aways a user must execute before flood protection is triggered.
-  This requires NO_FLOOD_AWAY to be defined.</p>
- <p><font class="set">set::anti-flood::away-period &lt;timevalue&gt;;</font><br>
-  Specifies the amount of time in which the set::anti-flood::away-count of /aways must be
-  executed for flood protection to be triggered. This requires NO_FLOOD_AWAY to be defined.</p>
+ <p><font class="set">set::anti-flood::away-flood &lt;count&gt;:&lt;period&gt;</font><br>
+  Away flood protection: limits /away to 'count' changes per 'period' seconds.
+  This requires NO_FLOOD_AWAY to be enabled in config.h. Example: <i>away-flood 5:60s;</i>
+  means max 5 changes per 60 seconds.</p>
+ <p><font class="set">set::anti-flood::nick-flood &lt;count&gt;:&lt;period&gt;</font><br>
+  Nickflood protection: limits nickchanges to 'count' per 'period' seconds.
+  For example <i>nick-flood 4:90</i> means 4 per 90 seconds, the default is 3 per 60.</p>
+ <p><font class="set">set::default-bantime &lt;time&gt;</font><br>
+  Default bantime when doing /kline, /gline, /zline, /shun, etc without time parameter 
+  (like /gline *@some.nasty.isp), the default is permanent (0). Example: <i>default-bantime 90d;</i></p>
 <p></p> </div>
 <p><b><font size="+2">5 &#8211; Additional Files<a name="addtlfiles"></a>
   </font></b></p><div class="desc">
   In addition to the configuration files, Unreal has a few other files, such as MOTD, OperMOTD, 
-  BotMOTD, and Rules. Listed below are the names of these files and their uses.
+  BotMOTD, and Rules. Listed below are the names of these files and their uses.<br>
+  Note that the motd files (all types) and rules files can also be specified in a tld block, 
+  these are just the files used by default (and for remote MOTD/RULES's).<p />&nbsp;
 <table width="83%" border="1">
   <tr>
-    <td>ircd.motd</td><td>Displayed when a /motd is executed and when a user connects</td> 
+    <td>ircd.motd</td><td>Displayed when a /motd is executed and (if ircd.smotd is not present) when a user connects</td> 
+  </tr>
+  <tr>
+    <td>ircd.smotd</td><td>Displayed on connect only (short MOTD)</td>
   </tr>
   <tr>
     <td>ircd.rules</td><td>Displayed when a /rules is executed</td>
@@ -1993,7 +2110,7 @@ set {
   </tr>
   <tr> 
     <td><div align="center">d</div></td>
-    <td>Makes it so you can not receive private messages</td>
+    <td>Makes it so you can not receive channel PRIVMSGs</td>
   </tr>
   <tr> 
     <td><div align="center">k</div></td>
@@ -2023,13 +2140,25 @@ set {
     <td><div align="center">p</div></td>
     <td>Hides the channels you are in in a /whois reply</td>
   </tr>
+  <tr> 
+    <td><div align="center">R</div></td>
+    <td>Allows you to only receive PRIVMSGs/NOTICEs from registered (+r) users</td>
+  </tr>
+  <tr> 
+    <td><div align="center">V</div></td>
+    <td>Marks you as a WebTV user</td>
+  </tr>
+  <tr>
+    <td><div align="center">z</div></td>
+    <td>Indicates that you are an SSL client</td>
+  </tr>
 </table>
 <p></p></div>
 <p><font size="+2"><b>7 &#8211; User & Oper Commands Table<a name="useropercommands" id="useropercommands"></a></b></font></p><div class="desc">
 <p>NOTE: the /helpop documentation is more up to date, use <i>/helpop command</i> (or <i>/helpop ?command</i> if you are oper) 
 to get more information on a command.</p>
 
-<table width="75%" border="1">
+<table width="90%" border="1">
   <tr> 
     <td width="33%"><div align="center"><b>Command</b></div></td>
     <td width="57%"><div align="center"><b>Description</b></div></td>
@@ -2072,9 +2201,9 @@ to get more information on a command.</p>
     <td>All</td>
   </tr>
   <tr> 
-    <td height="39">part &lt;channel1, channel2, ...&gt;</td>
-    <td>Allows you to part (leave) channels. Using the /part #channel1, #channel2, 
-      channel3 will allow you to part more than one channel at a time. </td>
+    <td height="39">cycle &lt;channel1, channel2, ...&gt;</td>
+    <td>Cycles the given channel(s). This command is equivilent
+      to sending a PART then a JOIN command.</td>
     <td>All</td>
   </tr>
   <tr> 
@@ -2248,13 +2377,22 @@ to get more information on a command.</p>
       of a channel.<br></td>
     <td>All</td>
   </tr>
+  <tr> 
+    <td height="39">dns &lt;option&gt;</td>
+    <td>Returns information about the IRC server's DNS cache.
+        Note, since most clients have a builtin DNS command,
+        you will most likely need to use /raw DNS to use this.
+        Opers may specify an l as the first parameter to the command
+        to receive a list of entries in the DNS cache.</td>
+    <td>All</td>
+  </tr>
   <tr> 
     <td height="39">oper &lt;userid&gt; &lt;password&gt;<br></td>
     <td>Command to give a user operator status if they match an Oper Block<br></td>
     <td>IRCop</td>
   </tr>
   <tr> 
-    <td height="39">wallop &lt;message&gt;</td>
+    <td height="39">wallops &lt;message&gt;</td>
     <td>Sends a message to all users with umode +w</td>
     <td>IRCop</td>
   </tr>
@@ -2307,8 +2445,8 @@ to get more information on a command.</p>
   </tr>
   <tr> 
     <td height="39">shun +-&lt;user@host&gt; &lt;time to shun&gt; :&lt;reason&gt;<br></td>
-    <td>Prevents a user from executing ANY commands on the server, and prevents 
-      them from speaking. Time to shun is in seconds, or you can use 1d for 1 days. 
+    <td>Prevents a user from executing ANY commands and prevents them from speaking. 
+      Shuns are global (like glines). Time to shun is in seconds, or you can use 1d for 1 days. 
       To remove a shun, put a &#8211;user@host. Setting time to 0 makes it permanent. 
       <br></td>
     <td>IRCop</td>
@@ -2495,44 +2633,65 @@ to get more information on a command.</p>
   </tr>
   <tr>
     <td height="36">stats &lt;option&gt;<br></td>
-    <td>b - Send the badwords list<br>
-      C - Send the link block list<br>
-      d - Send the deny link (auto) block list<br>
-      D - Send the deny link (all) block list<br>
-      e - Send the except socks block list<br>
-      E - Send the except ban block list<br>
-      F - Send the deny dcc block list<br>
-      G - Report TKL information (G:lines/Shuns)<br>
-      H - Send the link block list<br>
-      I - Send the allow block list<br>
-      K - Send the ban user/ban ip/except ban block list (Includes AKILLs)<br>
-      L - Send Link information<br>
-      m - Send the events list<br>
-      M - Send list of how many times each command was used<br>
-      n - Send the ban realname block list<br>
-      N - Send network configuration list<br>
-      O - Send the oper block list<br>
-      q - Send the SQLINE list<br>
-      Q - Send the ban nick block list<br>
-      r - Send the channel deny/allow block list<br>
-      s - Send the SCache and NS list<br>
-      S - Send the dynamic configuration list<br>
-      t - Send the tld block list<br>
-      T - Send connection information<br>
-      u - Send server uptime and connection count<br>
-      U - Send the ulines block list<br>
-      v - Send the deny version block list<br>
-      V - Send the vhost block list<br>
-      y - Send the class block list<br>
-      Z - Send memory usage information</td>
-    <td>Admin</td>
+       <td>
+       B - banversion - Send the ban version list<br>
+       b - badword - Send the badwords list<br>
+       C - link - Send the link block list<br>
+       d - denylinkauto - Send the deny link (auto) block list<br>
+       D - denylinkall - Send the deny link (all) block list<br>
+       e - excepthrottle - Send the except trottle block list<br>
+       E - exceptban - Send the except ban block list<br>
+       F - denydcc - Send the deny dcc block list<br>
+       G - gline - Send the gline list<br>
+       &nbsp;&nbsp;Extended flags: [+/-mrs] [mask] [reason] [setby]<br>
+       &nbsp;&nbsp;&nbsp;&nbsp;m Return glines matching/not matching the specified mask<br>
+       &nbsp;&nbsp;&nbsp;&nbsp;r Return glines with a reason matching/not matching the specified reason<br>
+       &nbsp;&nbsp;&nbsp;&nbsp;s Return glines set by/not set by clients matching the specified name<br>
+       I - allow - Send the allow block list<br>
+       K - kline - Send the ban user/ban ip/except ban block list<br>
+       l - linkinfo - Send link information<br>
+       L - linkinfoall - Send all link information<br>
+       M - command - Send list of how many times each command was used<br>
+       n - banrealname - Send the ban realname block list<br>
+       O - oper - Send the oper block list<br>
+       S - set - Send the set block list<br>
+       s - shun - Send the shun list<br>
+       &nbsp;&nbsp;Extended flags: [+/-mrs] [mask] [reason] [setby]<br>
+       &nbsp;&nbsp;&nbsp;&nbsp;m Return shuns matching/not matching the specified mask<br>
+       &nbsp;&nbsp;&nbsp;&nbsp;r Return shuns with a reason matching/not matching the specified reason<br>
+       &nbsp;&nbsp;&nbsp;&nbsp;s Return shuns set by/not set by clients matching the specified name<br>
+       P - port - Send information about ports<br>
+       q - sqline - Send the SQLINE list<br>
+       Q - bannick - Send the ban nick block list<br>
+       r - chanrestrict - Send the channel deny/allow block list<br>
+       R - usage - Send usage information<br>
+       t - tld - Send the tld block list<br>
+       T - traffic - Send traffic information<br>
+       u - uptime - Send the server uptime and connection count<br>
+       U - uline - Send the ulines block list<br>
+       v - Send the deny version block list<br>
+       V - Send the vhost block list<br>
+       X - notlink - Send the list of servers that are not current linked<br>
+       Y - class - Send the class block list<br>
+       z - zip - Send compression information about ziplinked servers (if compiled with ziplinks support)<br>
+       Z - mem - Send memory usage information<br>
+       </td>
+    <td>All</td>
   </tr>
   <tr>
     <td height="36">module<br></td>
     <td>
        Lists all loaded modules
+     </td>
     <td>Admin</td>
   </tr>
+  <tr>
+    <td height="36">close<br></td>
+    <td>
+       This command will disconnect all unknown connections from the IRC server.
+    </td>
+    <td>IRCOp</td>
+  </tr>
 </table>
 
 <p></p></div>
index 9a9eff4f531c8f0aca38d9769af292658b03c208..b2aa8504cee3c0dfb4350015d9e54cec89dc417b 100644 (file)
--- a/help.conf
+++ b/help.conf
@@ -35,8 +35,8 @@ help Usercmds {
        " AWAY    LINKS   NOTICE  SILENCE  WHO";
        " CREDITS LIST    PART    STATS    WHOIS";
        " INVITE  LUSERS  PING    TIME     WHOWAS";
-       " ISON    MAP     PONG    TOPIC";
-       " JOIN    MODE    PRIVMSG USERHOST";
+       " ISON    MAP     PONG    TOPIC    CYCLE";
+       " JOIN    MODE    PRIVMSG USERHOST DNS";
        " KICK    MOTD    QUIT    VERSION";
        " KNOCK   NAMES   RULES   VHOST";
        " ==-----------------oOo-----------------==";
@@ -56,7 +56,7 @@ help Opercmds {
        " LAG SETHOST SETIDENT CHGHOST CHGIDENT";
        " CHGNAME SQUIT CONNECT DCCDENY UNDCCDENY";
        " SAJOIN SAPART SAMODE RPING TRACE";
-       " OPERMOTD SDESC MKPASSWD";
+       " OPERMOTD SDESC MKPASSWD CLOSE MODULE";
        " ==----------------oOo---------------==";
 };
 
@@ -104,7 +104,7 @@ help Umodes {
        " B = Marks you as being a Bot";
        " G = Filters out all Bad words in your messages with <censored>";
        " H = Hide IRCop status in /WHO and /WHOIS. (IRC Operators only)";
-       " R = Allows you to only receive PRIVMSGs from registered (+r) users";
+       " R = Allows you to only receive PRIVMSGs/NOTICEs from registered (+r) users";
        " S = For Services only. (Protects them)";
        " V = Marks the client as a WebTV user";
        " W = Lets you see when people do a /WHOIS on you (IRC Operators only)";
@@ -199,11 +199,10 @@ help Oflags {
        " k = Access to do local /KILLs";
        " K = Access to do global /KILLs";
        " b = Oper can /KLINE users from server";
-       " t = Oper can /GLINE users from server";
        " B = Oper can remove Klines";
        " z = Can add Z:Lines";
        " Z = Can add global Z:Lines";
-       " t = Can use /GLINE";
+       " t = Can use /GLINE and /SHUN";
        " v = Can use OperOverride";
        " H = Gets +x on oper up";
        " W = Gets +W on oper up";
@@ -263,6 +262,26 @@ help Whowas {
        " Example: WHOWAS hAtbLaDe";
 };
 
+help Cycle {
+       " Cycles the given channel(s). This command is equivilent";
+       " to sending a PART then a JOIN command.";
+       " -";
+       " Syntax:  CYCLE <chan1>,<chan2>,<chan3>";
+       " Example: CYCLE #help";
+       " Example: CYCLE #main,#chat";
+};
+
+help Dns {
+       " Returns information about the IRC server's DNS cache.";
+       " Note, since most clients have a builtin DNS command,";
+       " you will most likely need to use /raw DNS to use this.";
+       " Opers may specify an l as the first parameter to the command";
+       " to receive a list of entries in the DNS cache.";
+       " -";
+       "Syntax:  DNS";
+       "Syntax:  DNS l (Oper only)";
+};
+
 help Names {
        " Provides a list of users on the specified channel.";
        " -";
@@ -425,9 +444,14 @@ help Kick {
        " Removes a user from a channel. Can only be used by Operators";
        " or Half-Ops. If no reason is specified, your nickname becomes the reason.";
        " -";
+/*
+       ** This doesn't seem to be working **
        " Syntax:  KICK <channel>[,<channel2>..] <user>[,<user2>..] <reason>";
        " Example: KICK #Lobby foobar Lamer..";
        "          KICK #Lobby,#OperHelp Lamer23,Luser12 Lamers!";
+*/
+       " Syntax:  KICK <channel> <user> [reason]";
+       " Example: KICK #Lobby foobar Lamer..";
 };
 
 help Away {
@@ -663,7 +687,7 @@ help Gline {
 
 help Shun {
        " Prevents a user from executing ANY command except ADMIN";
-       " and respond to Server Pings.";
+       " and respond to Server Pings. Shuns are global (like glines).";
        " A time of 0 in the SHUN makes it permanent (Never Expires).";
        " You may also specify the time in the format 1d10h15m30s.";
        " IRC Operator only command.";
@@ -902,6 +926,23 @@ help Mkpasswd {
        " Example: MKPASSWD crypt mpsare";
 };
 
+help Module {
+       " This will give you a list of all modules loaded in the form:";
+       " *** name - version (description) [optional flags here]";
+       " flags can be:";
+       " [PERM]: permanent module (not possible to unload/reload)";
+       " [Unloading]: module is in the process of unloading";
+       " -";
+       " Syntax: MODULE";
+};
+
+help Close {
+       " This command will disconnect all unknown connections from the";
+       " IRC server.";
+       " -";
+       " Syntax:  CLOSE";
+};
+
 help Tsctl {
        " This is a highly advanced command used to Adjust the";
        " Internal IRC clock.";
index dff77b2b8670f0e72feb6a67ce89482d60cb19c1..28ea18062d17a2211e98eab325128df0d29e5310 100644 (file)
@@ -36,7 +36,7 @@
 #include <process.h>
 #include <io.h>
 #endif
-#include "dynconf.h"
+//#include "dynconf.h"
 #include "ircsprintf.h"
 #include "config.h"
 #ifdef PARAMH
@@ -226,6 +226,18 @@ extern struct SLink *find_user_link( /* struct SLink *, struct Client * */ );
 
 /* IRCu/Hybrid/Unreal way now :) -Stskeeps */
 
+#ifdef EXTCMODE
+ #define EXPAR1        extchmstr[0]
+ #define EXPAR2        extchmstr[1]
+ #define EXPAR3        extchmstr[2]
+ #define EXPAR4        extchmstr[3]
+#else
+ #define EXPAR1 ""
+ #define EXPAR2 ""
+ #define EXPAR3 ""
+ #define EXPAR4 ""
+#endif /* EXTCMODE */
+
 #define PROTOCTL_CLIENT_1         \
                "MAP"             \
                " KNOCK"          \
@@ -248,6 +260,18 @@ extern struct SLink *find_user_link( /* struct SLink *, struct Client * */ );
                MAXTARGETS, \
                TOPICLEN
 
+#ifdef PREFIX_AQ
+#define CHPFIX "(qaohv)~&@%+"
+#define CHPAR1 "be"
+#else
+#define CHPFIX "(ohv)@%+"
+#define CHPAR1 "beqa"
+#endif /* PREFIX_AQ */
+
+#define CHPAR2 "kfL"
+#define CHPAR3 "l"
+#define CHPAR4 "psmntirRcOAQKVGCuzNSM"
+
 #define PROTOCTL_CLIENT_2        \
                "WALLCHOPS"       \
                " WATCH=%i"       \
@@ -255,39 +279,27 @@ extern struct SLink *find_user_link( /* struct SLink *, struct Client * */ );
                " MODES=%i"       \
                " CHANTYPES=%s"   \
                " PREFIX=%s"      \
-               " CHANMODES=%s,%s,%s,%s" \
+               " CHANMODES=%s%s,%s%s,%s%s,%s%s" \
                " NETWORK=%s"     \
                " CASEMAPPING=%s" \
                " :are supported by this server"
 
-#ifndef PREFIX_AQ
 #define PROTOCTL_PARAMETERS_2    \
-                MAXWATCH, \
-                 MAXSILES, \
-                 MAXMODEPARAMS, \
-                 "#", \
-                 "(ohv)@%+", \
-                 "beqa", \
-                 "kfL", \
-                "l", \
-                "psmntirRcOAQKVGCuzNSM", \
-                ircnet005, \
-                "ascii"
-#else
-#define PROTOCTL_PARAMETERS_2     \
-                MAXWATCH, \
-                 MAXSILES, \
-                 MAXMODEPARAMS, \
-                 "#", \
-                 "(qaohv)~&@%+", \
-                 "be", \
-                 "kfL", \
-                "l", \
-                "psmntirRcOAQKVGCuzNSM", \
-                ircnet005, \
-                "ascii"
-#endif             
-/* Server-Server PROTOCTL -Stskeeps */
+               MAXWATCH, \
+               MAXSILES, \
+               MAXMODEPARAMS, \
+               "#", \
+               CHPFIX, \
+               CHPAR1, EXPAR1, \
+               CHPAR2, EXPAR2, \
+               CHPAR3, EXPAR3, \
+               "psmntirRcOAQKVGCuzNSM", EXPAR4, \
+               ircnet005, \
+               "ascii"
+
+/* Server-Server PROTOCTL -Stskeeps
+ * Please check send_proto() for more. -- Syzop
+ */
 #define PROTOCTL_SERVER "NOQUIT" \
                         " TOKEN" \
                         " NICKv2" \
index 08737103cdc6891144f72f576d5dd93bd24969fa..9898cc0987c67e148349e75ea7d44d76e2c69726 100644 (file)
 */
 #undef DISABLE_USERMOD
 
-/*
-  Ident checking
-  #define this to disable ident checking
-*/
-#undef NO_IDENT_CHECKING
-
 /*
  * No spoof code
  *
  * HOSTILENAME - Define this if you want the hostile username patch included,
  *              it will strip characters that are not 0-9,a-z,A-Z,_,- or .
  */
-#define HOSTILENAME            /* */
-
-/*
-** Nick flood limit
-** Minimum time between nick changes.
-** (The first two changes are allowed quickly after another however).
-**
-** Define NICK_DELAY if you want this feature.
-*/
-
-#define NICK_DELAY 15          /* recommended value 15 */
+#define HOSTILENAME            /* [DO NOT CHANGE!] */
 
 /*
  * This makes topics include nick!user@host instead of nick in topic whoset, 
 
 #define HOW_MANY_FREELINKS_ALLOWED     200     /* default: 200 */
 
-/*
- * Define this if you wish to output a *file* to a K lined client rather
- * than the K line comment (the comment field is treated as a filename)
- */
-#undef COMMENT_IS_FILE
-
 /*
  * MAXUNKNOWNCONNECTIONSPERIP
 */
  */
 #define        SHOW_INVISIBLE_LUSERS
 
-/* MAXIMUM LINKS
- *
- * This define is useful for leaf nodes and gateways. It keeps you from
- * connecting to too many places. It works by keeping you from
- * connecting to more than "n" nodes which you have C:blah::blah:6667
- * lines for.
- *
- * Note that any number of nodes can still connect to you. This only
- * limits the number that you actively reach out to connect to.
- *
- * Leaf nodes are nodes which are on the edge of the tree. If you want
- * to have a backup link, then sometimes you end up connected to both
- * your primary and backup, routing traffic between them. To prevent
- * this, #define MAXIMUM_LINKS 1 and set up both primary and
- * secondary with C:blah::blah:6667 lines. THEY SHOULD NOT TRY TO
- * CONNECT TO YOU, YOU SHOULD CONNECT TO THEM.
- *
- * Gateways such as the server which connects Australia to the US can
- * do a similar thing. Put the American nodes you want to connect to
- * in with C:blah::blah:6667 lines, and the Australian nodes with
- * C:blah::blah lines. Have the Americans put you in with C:blah::blah
- * lines. Then you will only connect to one of the Americans.
- *
- * This value is only used if you don't have server classes defined, and
- * a server is in class 0 (the default class if none is set).
- *
- */
-
-#define MAXIMUM_LINKS 1
-
 /*
  * NOTE: defining CMDLINE_CONFIG and installing ircd SUID or SGID is a MAJOR
  *       security problem - they can use the "-f" option to read any files
  * NO_FLOOD_AWAY - enables limiting of how frequently a client can set /away
  */
 
-#undef NO_FLOOD_AWAY
+#define NO_FLOOD_AWAY
 
 /*
  * Define your network service names here.
 #define StatServ "StatServ"
 #define InfoServ "InfoServ"
 #define BotServ "BotServ"
-/*
- * How many seconds in between simultaneous nick changes?
- */
-#define NICK_CHANGE_DELAY      30
 
 /*
  * How many open targets can one nick have for messaging nicks and
  */
 #define SIXBONE_HACK
 
+/*
+ * Extended channel modes. This extends the channel modes with yet another
+ * 32 possible modes which can also be used in modules.
+ * This is currently considered experimental however.
+ */
+#undef EXTCMODE
+
+/*
+ * New channelmode +f system which allows flood control for:
+ * msgs, joins, ctcps, nickchanges and /knock.
+ */
+#define NEWCHFLOODPROT
+
 /* ------------------------- END CONFIGURATION SECTION -------------------- */
 #define MOTD MPATH
 #define RULES RPATH
index f22d07af82482a0e2264f3f84705668ee235e1fa..eafc8ceef9c5f6ad0d7bd8055a5eec07e3574410 100644 (file)
@@ -52,11 +52,20 @@ enum UHAllowed { UHALLOW_ALWAYS, UHALLOW_NOCHANS, UHALLOW_REJOIN, UHALLOW_NEVER
 
 struct ChMode {
         long mode;
+#ifdef NEWCHFLOODPROT
+               ChanFloodProt   floodprot;
+#else
         unsigned short  msgs;
         unsigned short  per; 
         unsigned char   kmode;
+#endif
 };
 
+typedef struct _OperStat {
+       struct _OperStat *prev, *next;
+       char *flag;
+} OperStat;
+
 typedef struct zConfiguration aConfiguration;
 struct zConfiguration {
        unsigned som:1;
@@ -86,6 +95,7 @@ struct zConfiguration {
        char *auto_join_chans;
        char *oper_auto_join_chans;
        char *oper_only_stats;
+       OperStat *oper_only_stats_ext;
        int  maxchannelsperuser;
        int  anti_spam_quit_message_time;
        char *egd_path;
@@ -99,6 +109,7 @@ struct zConfiguration {
        enum UHAllowed userhost_allowed;
        char *restrict_usermodes;
        char *restrict_channelmodes;
+       char *channel_command_prefix;
        long unknown_flood_bantime;
        long unknown_flood_amount;
        struct ChMode modes_on_join;
@@ -106,8 +117,11 @@ struct zConfiguration {
        unsigned char away_count;
        long away_period;
 #endif
+       unsigned char nick_count;
+       long nick_period;
        int ident_connect_timeout;
        int ident_read_timeout;
+       long default_bantime;
        aNetwork network;
 };
 
@@ -180,8 +194,13 @@ extern aConfiguration iConf;
 #define AWAY_PERIOD                    iConf.away_period
 #define AWAY_COUNT                     iConf.away_count
 #endif
+#define NICK_PERIOD                    iConf.nick_period
+#define NICK_COUNT                     iConf.nick_count
 
 #define IDENT_CONNECT_TIMEOUT  iConf.ident_connect_timeout
 #define IDENT_READ_TIMEOUT             iConf.ident_read_timeout
 
 #define MKPASSWD_FOR_EVERYONE  iConf.mkpasswd_for_everyone
+#define CHANCMDPFX iConf.channel_command_prefix
+
+#define DEFAULT_BANTIME                        iConf.default_bantime
index 78dc8101580273309d6b572805fb6798b69fbf4f..590a4d565120ef83f9ffab3670c7af6581e14283 100644 (file)
@@ -99,6 +99,7 @@ extern ConfigItem_log         *conf_log;
 extern ConfigItem_alias                *conf_alias;
 extern ConfigItem_include      *conf_include;
 extern ConfigItem_help         *conf_help;
+extern ConfigItem_offchans     *conf_offchans;
 extern int             completed_connection(aClient *);
 extern void clear_unknown();
 extern EVENT(tkl_check_expire);
@@ -110,7 +111,7 @@ extern EVENT(e_clean_out_throttling_buckets);
 extern void  module_loadall(int module_load);
 extern long set_usermode(char *umode);
 extern char *get_modestr(long umodes);
-extern void tkl_stats(aClient *cptr);
+extern void tkl_stats(aClient *cptr, int type, char *para);
 extern void                    config_error(char *format, ...);
 extern int                     config_verbose;
 extern void config_progress(char *format, ...);
@@ -213,10 +214,10 @@ extern int dgets(int, char *, int);
 extern char *inetntoa(char *);
 
 #if !defined(HAVE_SNPRINT) || !defined(HAVE_VSNPRINTF)
-#ifndef _WIN32
+/* #ifndef _WIN32 XXX why was this?? -- Syzop. */
 extern int snprintf (char *str, size_t count, const char *fmt, ...);
 extern int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
-#endif
+/* #endif */
 #endif
 
 #ifdef _WIN32
@@ -371,11 +372,7 @@ extern void add_client_to_list(aClient *);
 extern void checklist();
 extern void remove_client_from_list(aClient *);
 extern void initlists();
-#ifndef _WIN32
 extern struct hostent *get_res(char *);
-#else
-extern struct hostent *get_res(char *, long);
-#endif
 extern struct hostent *gethost_byaddr(char *, Link *);
 extern struct hostent *gethost_byname(char *, Link *);
 extern void flush_cache();
@@ -438,6 +435,18 @@ extern long UMODE_STRIPBADWORDS; /* 0x80000000      */
 extern long UMODE_HIDEWHOIS; /* hides channels in /whois */
 extern long AllUmodes, SendUmodes;
 
+extern long SNO_KILLS;
+extern long SNO_CLIENT;
+extern long SNO_FLOOD;
+extern long SNO_FCLIENT;
+extern long SNO_JUNK;
+extern long SNO_VHOST;
+extern long SNO_EYES;
+extern long SNO_TKL;
+extern long SNO_NICKCHANGE;
+extern long SNO_QLINE;
+extern long SNO_SNOTICE;
+
 #ifndef HAVE_STRLCPY
 size_t strlcpy(char *dst, const char *src, size_t size);
 #endif
@@ -516,6 +525,7 @@ extern long xbase64dec(char *b64);
 extern aClient *find_server_b64_or_real(char *name);
 extern aClient *find_server_by_base64(char *b64);
 extern int is_chanownprotop(aClient *cptr, aChannel *chptr);
+extern int is_skochanop(aClient *cptr, aChannel *chptr);
 extern char *make_virthost(char *curr, char *new, int mode);
 extern int  channel_canjoin(aClient *sptr, char *name);
 extern char *collapse(char *pattern);
@@ -550,7 +560,7 @@ extern void       run_configuration(void);
 extern void rehash_motdrules();
 extern aMotd *read_file(char *filename, aMotd **list);
 extern aMotd *read_file_ex(char *filename, aMotd **list, struct tm *);
-CMD_FUNC(m_server_remote);
+extern CMD_FUNC(m_server_remote);
 extern void send_proto(aClient *, ConfigItem_link *);
 extern char *xbase64enc(long i);
 extern void unload_all_modules(void);
@@ -573,3 +583,34 @@ extern char trouble_info[1024];
 extern void rejoin_doparts(aClient *sptr);
 extern void rejoin_dojoinandmode(aClient *sptr);
 extern void ident_failed(aClient *cptr);
+
+extern char extchmstr[4][64];
+#ifdef EXTCMODE
+extern int extcmode_default_requirechop(aClient *, aChannel *, char *, int, int);
+extern int extcmode_default_requirehalfop(aClient *, aChannel *, char *, int, int);
+extern Cmode_t extcmode_get(Cmode *);
+extern void extcmode_init(void);
+extern CmodeParam *extcmode_get_struct(CmodeParam *, char);
+extern void make_extcmodestr();
+extern CmodeParam *extcmode_duplicate_paramlist(CmodeParam *);
+extern void extcmode_free_paramlist(CmodeParam *);
+#endif
+extern CMD_FUNC(m_eos);
+extern int do_chanflood(ChanFloodProt *, int);
+extern void do_chanflood_action(aChannel *, int, char *);
+extern char *channel_modef_string(ChanFloodProt *);
+extern void chmode_str(struct ChMode, char *, char *);
+extern char *get_cptr_status(aClient *);
+extern char *get_snostr(long);
+#ifdef _WIN32
+extern void InitDebug(void);
+extern int InitwIRCD(int argc, char **);
+extern void SocketLoop(void *);
+#endif
+#ifdef STATIC_LINKING
+extern int l_commands_Init(ModuleInfo *);
+extern int l_commands_Test(ModuleInfo *);
+extern int l_commands_Load(int);
+#endif
+extern void sendto_chmodemucrap(aClient *, aChannel *, char *);
+extern void verify_opercount(aClient *, char *);
index cec58121c8db54cb694c1c83322bb43f867e616e..91619b4102515135a7954d4937e10e86ba386f58 100644 (file)
@@ -23,7 +23,7 @@
 #define MOD_VERSION    "3.2-b5-1"
 #define MOD_WE_SUPPORT  "3.2-b5*"
 #define MAXCUSTOMHOOKS  30
-#define MAXHOOKTYPES   60
+#define MAXHOOKTYPES   70
 typedef void                   (*vFP)();       /* Void function pointer */
 typedef int                    (*iFP)();       /* Integer function pointer */
 typedef char                   (*cFP)();       /* char * function pointer */
@@ -94,6 +94,127 @@ typedef struct {
 #define MOBJ_COMMAND 0x0004
 #define MOBJ_HOOKTYPE 0x0008
 #define MOBJ_VERSIONFLAG 0x0010
+#define MOBJ_SNOMASK 0x0020
+#define MOBJ_UMODE 0x0040
+
+typedef struct {
+        long mode;
+        char flag;
+        int (*allowed)(aClient *sptr);
+        char unloaded;
+        Module *owner;
+} Umode;
+
+typedef struct {
+        long mode;
+        char flag;
+        int (*allowed)(aClient *sptr);
+        char unloaded;
+        Module *owner;
+} Snomask;
+
+#ifdef EXTCMODE
+#define EXCHK_ACCESS           0 /* Check access */
+#define EXCHK_ACCESS_ERR       1 /* Check access and send error if needed */
+#define EXCHK_PARAM                    2 /* Check parameter and send error if needed */
+
+#define EXSJ_SAME                      0 /* Parameters are the same */
+#define EXSJ_WEWON                     1 /* We won! w00t */
+#define EXSJ_THEYWON           2 /* They won :( */
+
+/** Extended channel mode table.
+ * This table contains all extended channelmode info like the flag, mode, their
+ * functions, etc..
+ */
+typedef unsigned long Cmode_t;
+
+#define EXTCM_PAR_HEADER struct _CmodeParam *prev, *next; char flag;
+
+typedef struct _CmodeParam {
+       EXTCM_PAR_HEADER
+       /** other fields are placed after this header in your own paramstruct */
+} CmodeParam;
+
+typedef struct {
+       /** mode character (like 'Z') */
+       char            flag;
+
+       /** unique flag (like 0x10) */
+       Cmode_t         mode;
+
+       /** # of paramters (1 or 0) */
+       int                     paracount;
+
+       /** access and parameter checking.
+        * aClient *: the client
+        * aChannel *: the channel
+        * para *: the parameter (NULL for paramless modes)
+        * int: check type (see EXCHK_*)
+        * int: what (MODE_ADD or MODE_DEL)
+        * return value: 1=ok, 0=bad
+        */
+       int                     (*is_ok)(aClient *,aChannel *, char *para, int, int);
+
+       /** NOTE: The routines below are NULL for paramless modes */
+       
+       /** Store parameter in memory for channel.
+        * aExtCMtableParam *: the list (usually chptr->mode.extmodeparams).
+        * char *: the parameter.
+        * return value: the head of the list, RTFS if you wonder why.
+        * design notes: only alloc a new paramstruct if you need to, search for
+        * any current one first (like in case of mode +y 5 and then +y 6 later without -y).
+        */
+       CmodeParam *            (*put_param)(CmodeParam *, char *);
+
+       /** Get readable string version" of the stored parameter.
+        * aExtCMtableParam *: the list (usually chptr->mode.extmodeparams).
+        * return value: a pointer to the string (temp. storage)
+        */
+       char *          (*get_param)(CmodeParam *);
+
+       /** Convert input parameter to output.
+        * Like +l "1aaa" becomes "1".
+        * char *: the input parameter.
+        * return value: pointer to output string (temp. storage)
+        */
+       char *          (*conv_param)(char *);
+
+       /** free and remove parameter from list.
+        * aExtCMtableParam *: the list (usually chptr->mode.extmodeparams).
+        */
+       void            (*free_param)(CmodeParam *);
+
+       /** duplicate a struct and return a pointer to duplicate.
+        * This is usually just a malloc + memcpy.
+        * aExtCMtableParam *: source struct itself (no list).
+        * return value: pointer to newly allocated struct.
+        */
+       CmodeParam *    (*dup_struct)(CmodeParam *);
+
+       /** Compares 2 parameters and decides who wins the sjoin fight.
+        * When syncing channel modes (m_sjoin) a parameter conflict may occur, things like
+        * +l 5 vs +l 10. This function should determinate who wins the fight, this decision
+        * should of course not be random but the same at every server on the net.
+        * examples of such comparisons are "highest wins" (+l) and a strcmp() check (+k/+L).
+        * aChannel *: channel the fight is about.
+        * aExtCMtableParam *: our parameter
+        * aExtCMtableParam *: their parameter
+        */
+       int                     (*sjoin_check)(aChannel *, CmodeParam *, CmodeParam *);
+} Cmode;
+
+typedef struct {
+       char            flag;
+       int             paracount;
+       int             (*is_ok)(aClient *,aChannel *, char *para, int, int);
+       CmodeParam *    (*put_param)(CmodeParam *, char *);
+       char *          (*get_param)(CmodeParam *);
+       char *          (*conv_param)(char *);
+       void            (*free_param)(CmodeParam *);
+       CmodeParam *    (*dup_struct)(CmodeParam *);
+       int             (*sjoin_check)(aChannel *, CmodeParam *, CmodeParam *);
+} CmodeInfo;
+#endif
 
 typedef struct _command {
        struct _command *prev, *next;
@@ -115,6 +236,8 @@ typedef struct _ModuleObject {
                Command *command;
                Hooktype *hooktype;
                Versionflag *versionflag;
+               Snomask *snomask;
+               Umode *umode;
        } object;
 } ModuleObject;
 
@@ -138,6 +261,16 @@ struct _hooktype {
  * What we use to keep track internally of the modules
 */
 
+#define MODERR_NOERROR 0
+#define MODERR_EXISTS  1
+#define MODERR_NOSPACE 2
+#define MODERR_INVALID 3
+
+unsigned int ModuleGetError(Module *module);
+const char *ModuleGetErrorStr(Module *module);
+unsigned int ModuleGetOptions(Module *module);
+unsigned int ModuleSetOptions(Module *module, unsigned int options);
+
 struct _Module
 {
        struct _Module *prev, *next;
@@ -153,11 +286,15 @@ struct _Module
        ModuleChild *children;
        ModuleObject *objects;
        ModuleInfo modinfo; /* Used to store handle info for module */
+       unsigned char options;
+       unsigned char errorcode;
 };
 /*
  * Symbol table
 */
 
+#define MOD_OPT_PERM 0x0001
+
 struct _mod_symboltable
 {
 #ifndef STATIC_LINKING
@@ -266,6 +403,15 @@ void HooktypeDel(Hooktype *hooktype, Module *module);
   if (retval retchk) return retval; \
  } \
 }
+#define RunHookReturnInt2(hooktype,x,y,retchk) \
+{ \
+ int retval; \
+ for (global_i = Hooks[hooktype]; global_i; global_i = global_i->next) \
+ { \
+  retval = (*(global_i->func.intfunc))(x,y); \
+  if (retval retchk) return retval; \
+ } \
+}
 
 #define RunHookReturnVoid(hooktype,x,ret) for (global_i = Hooks[hooktype]; global_i; global_i = global_i->next) if((*(global_i->func.intfunc))(x) ret) return
 #define RunHook2(hooktype,x,y) for (global_i = Hooks[hooktype]; global_i; global_i = global_i->next) (*(global_i->func.intfunc))(x,y)
@@ -283,6 +429,7 @@ int CommandExists(char *name);
 #define HOOKTYPE_LOCAL_QUIT    1
 #define HOOKTYPE_LOCAL_NICKCHANGE 2
 #define HOOKTYPE_LOCAL_CONNECT 3
+#define HOOKTYPE_REHASHFLAG 4
 #undef HOOKTYPE_SCAN_INFO
 #define HOOKTYPE_CONFIGPOSTTEST 6
 #define HOOKTYPE_REHASH 7
@@ -301,6 +448,15 @@ int CommandExists(char *name);
 #define HOOKTYPE_LOCAL_KICK 20
 #define HOOKTYPE_LOCAL_CHANMODE 21
 #define HOOKTYPE_LOCAL_TOPIC 22
+#define HOOKTYPE_LOCAL_OPER 23
+#define HOOKTYPE_UNKUSER_QUIT 24
+#define HOOKTYPE_LOCAL_PASS 25
+#define HOOKTYPE_REMOTE_CONNECT 26
+#define HOOKTYPE_REMOTE_QUIT 27
+#define HOOKTYPE_PRE_LOCAL_JOIN 28
+#define HOOKTYPE_PRE_LOCAL_KICK 29
+#define HOOKTYPE_PRE_LOCAL_TOPIC 30
+
 /* Module flags */
 #define MODFLAG_NONE   0x0000
 #define MODFLAG_LOADED 0x0001 /* Fully loaded */
@@ -320,4 +476,18 @@ int CommandExists(char *name);
 #define CONFIG_DENY 5
 #define CONFIG_ALLOW 6
 
+#ifdef DYNAMIC_LINKING
+#define MOD_HEADER(name) Mod_Header
+#define MOD_TEST(name) Mod_Test
+#define MOD_INIT(name) Mod_Init
+#define MOD_LOAD(name) Mod_Load
+#define MOD_UNLOAD(name) Mod_Unload
+#else
+#define MOD_HEADER(name) name##_Header
+#define MOD_TEST(name) name##_Test
+#define MOD_INIT(name) name##_Init
+#define MOD_LOAD(name) name##_Load
+#define MOD_UNLOAD(name) name##_Unload
+#endif
+
 #endif
index 3df5838ac9602c20713af333f18a0ad25f4f4aa2..a2a38056b2b6c8a3a45f78020626e49c4c1b6698 100644 (file)
 #define TOK_MODULE     "BQ"
 /* BR and BT are in use */
 
+#define MSG_EOS                "EOS"
+#define TOK_EOS                "ES"
+
 #define MAXPARA        15
 
 extern int m_topic(), m_join(), m_part(), m_mode();
index cd1b0bf3900111a774a8d8c897762eb6a24ab670..4c651732dda9e452b68b59259e3b683fd9ae40f1 100644 (file)
 #define RPL_STATSELINE      225
 #define RPL_STATSNLINE      226
 #define RPL_STATSVLINE      227
+#define RPL_STATSBANVER             228
 #define RPL_SERVICEINFO      231
 #define RPL_RULES            232
 #define        RPL_SERVICE          233
index 9e2db13c470ff07741ae6d551b7bbdc945634456..05359a1c966104478731940c98ecfdb476a94610 100644 (file)
@@ -39,22 +39,13 @@ typedef     struct  reslist {
        char    *name;
        struct  reslist *next;
        Link    cinfo;
-#ifndef _WIN32
        struct  hent he;
-#else
-       struct hostent *he;
-       char locked;
-#endif
        } ResRQ;
 
 typedef        struct  cache {
        time_t  expireat;
        time_t  ttl;
-#ifndef _WIN32
        struct hostent he;
-#else
-       struct hostent *he;
-#endif
        struct  cache   *hname_next, *hnum_next, *list_next;
        } aCache;
 
index c1df9305a93a88cbdd7bf19e09760fdaae923208..0f0e646739f2edb1d59f1f6e737b7102f7cc4662 100644 (file)
@@ -108,6 +108,7 @@ typedef struct _configitem_alias ConfigItem_alias;
 typedef struct _configitem_alias_format ConfigItem_alias_format;
 typedef struct _configitem_include ConfigItem_include;
 typedef struct _configitem_help ConfigItem_help;
+typedef struct _configitem_offchans ConfigItem_offchans;
 typedef struct liststruct ListStruct;
 
 #define CFG_TIME 0x0001
@@ -122,6 +123,7 @@ typedef struct Server aServer;
 typedef struct SLink Link;
 typedef struct SBan Ban;
 typedef struct SMode Mode;
+typedef struct SChanFloodProt ChanFloodProt;
 typedef struct ListOptions LOpts;
 typedef struct FloodOpt aFloodOpt;
 typedef struct MotdItem aMotd;
@@ -307,24 +309,9 @@ typedef unsigned int u_int32_t;    /* XXX Hope this works! */
  * -DuffJ
  */
 
-
-#define SNO_KILLS      0x0001
-#define SNO_CLIENT     0x0002
-#define SNO_FLOOD      0x0004
-#define SNO_FCLIENT    0x0008
-#define SNO_JUNK       0x0010
-#define SNO_VHOST      0x0020
-#define SNO_EYES       0x0040
-#define SNO_TKL        0x0080
-#define SNO_NICKCHANGE 0x0100
-#define SNO_QLINE      0x0200
-#define SNO_SNOTICE    0x0400
-
 #define SNO_DEFOPER "+kscfvGq"
 #define SNO_DEFUSER "+ks"
 
-#define SNO_NONOPERS (SNO_KILLS | SNO_SNOTICE)
-
 #define SEND_UMODES (SendUmodes)
 #define ALL_UMODES (AllUmodes)
 /* SEND_UMODES and ALL_UMODES are now handled by umode_get/umode_lget/umode_gget -- Syzop. */
@@ -376,7 +363,7 @@ typedef unsigned int u_int32_t;     /* XXX Hope this works! */
 #define IsWebTV(x)             ((x)->umodes & UMODE_WEBTV)
 #define        IsPerson(x)             ((x)->user && IsClient(x))
 #define        IsPrivileged(x)         (IsAnOper(x) || IsServer(x))
-#define        SendWallops(x)          (!IsMe(x) && ((x)->umodes & UMODE_WALLOP))
+#define        SendWallops(x)          (!IsMe(x) && IsPerson(x) && ((x)->umodes & UMODE_WALLOP))
 #define        SendServNotice(x)       (((x)->user) && ((x)->user->snomask & SNO_SNOTICE))
 #define        IsListening(x)          ((x)->flags & FLAGS_LISTEN)
 // #define     DoAccess(x)             ((x)->flags & FLAGS_CHKACCESS)
@@ -642,6 +629,7 @@ struct aloopStruct {
        unsigned do_garbage_collect : 1;
        unsigned ircd_booted : 1;
        unsigned do_bancheck : 1;
+       unsigned ircd_rehashing : 1;
        unsigned tainted : 1;
 };
 
@@ -670,10 +658,6 @@ struct User {
        Link *invited;          /* chain of invite pointer blocks */
        Link *silence;          /* chain of silence pointer blocks */
        char *away;             /* pointer to away message */
-#ifdef NO_FLOOD_AWAY
-       time_t last_away;       /* last time the user set away */
-       unsigned char away_count;       /* number of times away has been set */
-#endif
        u_int32_t servicestamp; /* Services' time stamp variable */
        signed char refcnt;     /* Number of times this block is referenced */
        unsigned short joined;          /* number of channels joined */
@@ -688,6 +672,14 @@ struct User {
 #ifdef LIST_DEBUG
        aClient *bcptr;
 #endif
+       struct {
+               time_t nick_t;
+               unsigned char nick_c;
+#ifdef NO_FLOOD_AWAY
+               time_t away_t;                  /* last time the user set away */
+               unsigned char away_c;   /* number of times away has been set */
+#endif
+       } flood;
 };
 
 struct Server {
@@ -702,6 +694,9 @@ struct Server {
 #ifdef LIST_DEBUG
        aClient *bcptr;
 #endif
+       struct {
+               unsigned synced:1;              /* Server linked? (3.2beta18+) */
+       } flags;
 };
 
 #define M_UNREGISTERED 0x0001
@@ -748,15 +743,29 @@ typedef struct ircstatsx {
 
 extern ircstats IRCstats;
 
-typedef struct {
-       long    mode;
-       char    flag;
-       int     (*allowed)(aClient *sptr);
-} aUMtable;
+#include "modules.h"
 
-extern aUMtable *Usermode_Table;
+extern Umode *Usermode_Table;
 extern short    Usermode_highest;
 
+extern Snomask *Snomask_Table;
+extern short Snomask_highest;
+
+#ifdef EXTCMODE
+extern Cmode *Channelmode_Table;
+extern unsigned short Channelmode_highest;
+#endif
+
+extern Umode *UmodeAdd(Module *module, char ch, int options, int (*allowed)(aClient *sptr), long *mode);
+extern void UmodeDel(Umode *umode);
+
+extern Snomask *SnomaskAdd(Module *module, char ch, int (*allowed)(aClient *sptr), long *mode);
+extern void SnomaskDel(Snomask *sno);
+
+#ifdef EXTCMODE
+extern Cmode *CmodeAdd(Module *reserved, CmodeInfo req, Cmode_t *mode);
+extern void CmodeDel(Cmode *cmode);
+#endif
 
 #define LISTENER_NORMAL                0x000001
 #define LISTENER_CLIENTSONLY   0x000002
@@ -1102,6 +1111,7 @@ struct _configitem_deny_channel {
        ConfigItem              *prev, *next;
        ConfigFlag              flag;
        char                    *channel, *reason, *redirect;
+       unsigned char   warn;
 };
 
 struct _configitem_allow_channel {
@@ -1170,6 +1180,12 @@ struct _configitem_help {
        aMotd *text;
 };
 
+struct _configitem_offchans {
+       ConfigItem *prev, *next;
+       char chname[CHANNELLEN+1];
+       char *topic;
+};
+
 #define HM_HOST 1
 #define HM_IPV4 2
 #define HM_IPV6 3
@@ -1225,16 +1241,46 @@ struct ListOptions {
        TS   topictimemax;
 };
 
+#ifdef EXTCMODE
+#define EXTCMODETABLESZ 32
+#endif /* EXTCMODE */
+
+/* this can be like ~60-90 bytes, therefore it's in a seperate struct */
+#define FLD_CTCP       0 /* c */
+#define FLD_JOIN       1 /* j */
+#define FLD_KNOCK      2 /* k */
+#define FLD_MSG                3 /* m */
+#define FLD_NICK       4 /* n */
+#define FLD_TEXT       5 /* t */
+
+#define NUMFLD 6 /* 6 flood types */
+
+struct SChanFloodProt {
+       unsigned short  per; /* setting: per <XX> seconds */
+       time_t                  t[NUMFLD]; /* runtime: timers */
+       unsigned short  c[NUMFLD]; /* runtime: counters */
+       unsigned short  l[NUMFLD]; /* setting: limit */
+       unsigned char   a[NUMFLD]; /* setting: action */
+};
+
 /* mode structure for channels */
 struct SMode {
        long mode;
+#ifdef EXTCMODE
+       Cmode_t extmode;
+       CmodeParam *extmodeparam;
+#endif
        int  limit;
        char key[KEYLEN + 1];
        char link[LINKLEN + 1];
+#ifdef NEWCHFLOODPROT
+       ChanFloodProt *floodprot;
+#else
        /* x:y */
        unsigned short  msgs;           /* x */
        unsigned short  per;            /* y */
        unsigned char    kmode; /* mode  0 = kick  1 = ban */
+#endif
 };
 
 /* Used for notify-hash buckets... -Donwulff */
@@ -1489,7 +1535,6 @@ extern char *gnulicense[];
 #include "ssl.h"
 #endif
 #define EVENT_HASHES EVENT_DRUGS
-#include "modules.h"
 #include "events.h"
 struct Command {
        aCommand                *prev, *next;
@@ -1526,5 +1571,8 @@ int       throttle_can_connect(struct IN_ADDR *in);
 
 #endif
 
+#define VERIFY_OPERCOUNT(clnt,tag) { if (IRCstats.operators < 0) verify_opercount(clnt,tag); } while(0)
+
 #endif /* __struct_include__ */
 
+#include "dynconf.h"
index 51bf6f5890c17e44769b866a8f15c76f3dd44b36..6821ffc963dd088b6a147fed081b5469090a74a3 100644 (file)
@@ -215,7 +215,12 @@ static const struct in6_addr in6addr_any = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 #define P_ECONNABORTED ECONNABORTED
 #define P_ECONNRESET   ECONNRESET
 #define P_ENOTCONN     ENOTCONN
+#define P_EMSGSIZE     EMSGSIZE
 #else
+/* WIN32 */
+
+#define NETDB_INTERNAL  -1  /* see errno */
+#define NETDB_SUCCESS   0   /* no problem */
 
 /* IO and Error portability macros */
 #define READ_SOCK(fd, buf, len) recv((fd), (buf), (len), 0)
@@ -239,6 +244,7 @@ static const struct in6_addr in6addr_any = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 #define P_ECONNABORTED WSAECONNABORTED
 #define P_ECONNRESET   WSAECONNRESET
 #define P_ENOTCONN     WSAENOTCONN
+#define P_EMSGSIZE     WSAEMSGSIZE
 #endif
 
 #endif /* __sys_include__ */
index aa068a54211234bc699f52dad1c00a8014765e18..ccf8373bd2cd9cf1be035661aa2a0aa4de7930f7 100644 (file)
@@ -29,7 +29,7 @@
 #define UnrealProtocol                 2303
 #define PATCH1                 "3"
 #define PATCH2                 ".2"
-#define PATCH3                 "-beta17"
+#define PATCH3                 "-beta18"
 #define PATCH4                 ""
 #define PATCH5                 ""
 #define PATCH6                 ""
old mode 100755 (executable)
new mode 100644 (file)
similarity index 82%
rename from ircdcron/ircdchk
rename to ircdcron/ircdchk.in
index 2e2556b..0889271
 #    0,10,20,30,40,50 * * * *   /home/mydir/ircdchk >/dev/null 2>&1
 #
 # change this to the mail address to mail output to:
-MAIL=me
-# change this to the directory you run your ircd from:
-dir="../src"
+# MAIL=me
 
-# change this to the name of your ircd's file in that directory:
-ircdexe="ircd"
+# These values shouldn't need to be changed
 
-# I wouldn't touch this if I were you.
-ircdname="../ircd.pid"
+# The path to the ircd binary
+ircdexe="@BINDIR@"
 
-########## you probably don't need to change anything below here ##########
+# The path to the ircd pid file
+ircdname="@IRCDDIR@/ircd.pid"
 
-cd $dir
+########## you probably don't need to change anything below here ##########
 if test -r $ircdname; then
   # there is a pid file -- is it current?
   ircdpid=`cat $ircdname`
@@ -46,4 +44,4 @@ fi
 echo ""
 echo "Couldn't find the ircd running.  Reloading it..."
 echo ""
-./$ircdexe
+$ircdexe
index c48b92291ff4efe4497b5bd215a6612d38105e48..7569c89938f34de6a2e480ab96a770a61b06733a 100644 (file)
@@ -31,11 +31,11 @@ OBJ_FILES=SRC/CHANNEL.OBJ SRC/SEND.OBJ SRC/SOCKET.OBJ \
  SRC/S_DEBUG.OBJ  SRC/SUPPORT.OBJ SRC/LIST.OBJ \
  SRC/S_ERR.OBJ SRC/PACKET.OBJ SRC/S_BSD.OBJ \
  SRC/S_SERV.OBJ SRC/S_USER.OBJ SRC/WIN32GUI.OBJ \
- SRC/VERSION.OBJ SRC/RES_INIT.OBJ \
+ SRC/VERSION.OBJ SRC/RES_INIT.OBJ SRC/RES_COMP.OBJ SRC/RES_MKQUERY.OBJ SRC/RES_SKIPNAME.OBJ \
  SRC/S_KLINE.OBJ SRC/S_EXTRA.OBJ SRC/IRCSPRINTF.OBJ SRC/LUSERS.OBJ \
  SRC/SCACHE.OBJ SRC/ALN.OBJ SRC/BADWORDS.OBJ SRC/WEBTV.OBJ SRC/RES.OBJ SRC/MODULES.OBJ \
  SRC/S_SVS.OBJ SRC/EVENTS.OBJ SRC/UMODES.OBJ SRC/AUTH.OBJ SRC/CIDR.OBJ SRC/SSL.OBJ \
- SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ
+ SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ SRC/EXTCMODES.OBJ SRC/S_STATS.OBJ
 
 MOD_FILES=SRC/L_COMMANDS.OBJ SRC/M_CHGHOST.OBJ SRC/M_SDESC.OBJ SRC/M_SETIDENT.OBJ \
  SRC/M_SETNAME.OBJ SRC/M_SETHOST.OBJ SRC/M_CHGIDENT.OBJ SRC/M_SVSMOTD.OBJ \
@@ -70,7 +70,7 @@ CONF:
        
 
 ./WIRCD.EXE: $(OBJ_FILES) $(MOD_FILES) SRC/win32/WIN32.RES
-        $(LINK) $(LFLAGS) $(OBJ_FILES) $(MOD_FILES) SRC/win32/WIN32.RES SRC/WIN32/GNU_REGEX.LIB  /MAPINFO:LINES /MAP
+        $(LINK) $(LFLAGS) $(OBJ_FILES) $(MOD_FILES) SRC/win32/WIN32.RES SRC/WIN32/TRE.LIB /MAPINFO:LINES /MAP
        -@erase src\win32\win32.res
 !IFNDEF DEBUG
  @echo Non Debug version built 
@@ -102,6 +102,9 @@ src/ircsprintf.obj: src/ircsprintf.c $(INCLUDES)
 src/packet.obj: src/packet.c $(INCLUDES)
         $(CC) $(CFLAGS) src/packet.c
 
+src/s_stats.obj: src/s_stats.c $(INCLUDES)
+        $(CC) $(CFLAGS) src/s_stats.c
+
 src/fdlist.obj: src/fdlist.c $(INCLUDES)
         $(CC) $(CFLAGS) src/fdlist.c
 
@@ -139,6 +142,12 @@ src/list.obj: src/list.c $(INCLUDES)
 src/res.obj: src/res.c $(INCLUDES)
         $(CC) $(CFLAGS) src/res.c
 
+src/res_mkquery.obj: src/res_mkquery.c $(INCLUDES)
+        $(CC) $(CFLAGS) src/res_mkquery.c
+
+src/res_skipname.obj: src/res_skipname.c $(INCLUDES)
+        $(CC) $(CFLAGS) src/res_skipname.c
+
 src/s_bsd.obj: src/s_bsd.c $(INCLUDES)
         $(CC) $(CFLAGS) src/s_bsd.c
 
@@ -231,6 +240,9 @@ src/cidr.obj: src/cidr.c $(INCLUDES)
 src/random.obj: src/random.c $(INCLUDES)
        $(CC) $(CFLAGS) src/random.c
 
+src/extcmodes.obj: src/extcmodes.c $(INCLUDES)
+       $(CC) $(CFLAGS) src/extcmodes.c
+
 src/ssl.obj: src/ssl.c $(INCLUDES)
        $(CC) $(CFLAGS) src/ssl.c
 
index 682588e3c0e97c633ad1a0336d7f1bb831e56cfc..3f90524c085970153379c72e488dd6841ea25079 100644 (file)
@@ -34,11 +34,11 @@ OBJ_FILES=SRC/CHANNEL.OBJ SRC/SEND.OBJ SRC/SOCKET.OBJ \
  SRC/S_DEBUG.OBJ  SRC/SUPPORT.OBJ SRC/LIST.OBJ \
  SRC/S_ERR.OBJ SRC/PACKET.OBJ SRC/S_BSD.OBJ \
  SRC/S_SERV.OBJ SRC/S_USER.OBJ SRC/WIN32GUI.OBJ \
- SRC/VERSION.OBJ SRC/RES_INIT.OBJ \
+ SRC/VERSION.OBJ SRC/RES_INIT.OBJ SRC/RES_COMP.OBJ SRC/RES_MKQUERY.OBJ SRC/RES_SKIPNAME.OBJ \
  SRC/S_KLINE.OBJ SRC/S_EXTRA.OBJ SRC/IRCSPRINTF.OBJ SRC/LUSERS.OBJ \
  SRC/SCACHE.OBJ SRC/ALN.OBJ SRC/BADWORDS.OBJ SRC/WEBTV.OBJ SRC/RES.OBJ SRC/MODULES.OBJ \
  SRC/S_SVS.OBJ SRC/EVENTS.OBJ SRC/UMODES.OBJ SRC/AUTH.OBJ SRC/CIDR.OBJ SRC/SSL.OBJ \
- SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ
+ SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ SRC/EXTCMODES.OBJ SRC/S_STATS.OBJ
 
 MOD_FILES=SRC/L_COMMANDS.OBJ SRC/M_CHGHOST.OBJ SRC/M_SDESC.OBJ SRC/M_SETIDENT.OBJ \
  SRC/M_SETNAME.OBJ SRC/M_SETHOST.OBJ SRC/M_CHGIDENT.OBJ SRC/M_SVSMOTD.OBJ \
@@ -73,7 +73,7 @@ CONF:
        
 
 ./WIRCD.EXE: $(OBJ_FILES) $(MOD_FILES) SRC/win32/WIN32.RES
-        $(LINK) $(LFLAGS) $(OBJ_FILES) $(MOD_FILES) SRC/win32/WIN32.RES SRC/WIN32/GNU_REGEX.LIB  /MAPINFO:LINES /MAP
+        $(LINK) $(LFLAGS) $(OBJ_FILES) $(MOD_FILES) SRC/win32/WIN32.RES SRC/WIN32/TRE.LIB /MAPINFO:LINES /MAP
        -@erase src\win32\win32.res
 !IFNDEF DEBUG
  @echo Non Debug version built 
@@ -105,6 +105,9 @@ src/ircsprintf.obj: src/ircsprintf.c $(INCLUDES)
 src/packet.obj: src/packet.c $(INCLUDES)
         $(CC) $(CFLAGS) src/packet.c
 
+src/s_stats.obj: src/s_stats.c $(INCLUDES)
+        $(CC) $(CFLAGS) src/s_stats.c
+
 src/fdlist.obj: src/fdlist.c $(INCLUDES)
         $(CC) $(CFLAGS) src/fdlist.c
 
@@ -142,6 +145,12 @@ src/list.obj: src/list.c $(INCLUDES)
 src/res.obj: src/res.c $(INCLUDES)
         $(CC) $(CFLAGS) src/res.c
 
+src/res_mkquery.obj: src/res_mkquery.c $(INCLUDES)
+        $(CC) $(CFLAGS) src/res_mkquery.c
+
+src/res_skipname.obj: src/res_skipname.c $(INCLUDES)
+        $(CC) $(CFLAGS) src/res_skipname.c
+
 src/s_bsd.obj: src/s_bsd.c $(INCLUDES)
         $(CC) $(CFLAGS) src/s_bsd.c
 
@@ -234,6 +243,9 @@ src/cidr.obj: src/cidr.c $(INCLUDES)
 src/random.obj: src/random.c $(INCLUDES)
        $(CC) $(CFLAGS) src/random.c
 
+src/extcmodes.obj: src/extcmodes.c $(INCLUDES)
+       $(CC) $(CFLAGS) src/extcmodes.c
+
 src/ssl.obj: src/ssl.c $(INCLUDES)
        $(CC) $(CFLAGS) src/ssl.c
 
index 44adb118a2ed4e8664633416dab2518f578cb63a..19d079f1bbcc6f1c9bf86341a2e5b05472281ac8 100644 (file)
@@ -41,11 +41,11 @@ OBJ_FILES=SRC/CHANNEL.OBJ SRC/SEND.OBJ SRC/SOCKET.OBJ \
  SRC/S_DEBUG.OBJ  SRC/SUPPORT.OBJ SRC/LIST.OBJ \
  SRC/S_ERR.OBJ SRC/PACKET.OBJ SRC/S_BSD.OBJ \
  SRC/S_SERV.OBJ SRC/S_USER.OBJ SRC/WIN32GUI.OBJ \
- SRC/VERSION.OBJ SRC/RES_INIT.OBJ \
+ SRC/VERSION.OBJ SRC/RES_INIT.OBJ SRC/RES_COMP.OBJ SRC/RES_MKQUERY.OBJ SRC/RES_SKIPNAME.OBJ \
  SRC/S_KLINE.OBJ SRC/S_EXTRA.OBJ SRC/IRCSPRINTF.OBJ SRC/LUSERS.OBJ \
  SRC/SCACHE.OBJ SRC/ALN.OBJ SRC/BADWORDS.OBJ SRC/WEBTV.OBJ SRC/RES.OBJ SRC/MODULES.OBJ \
  SRC/S_SVS.OBJ SRC/EVENTS.OBJ SRC/UMODES.OBJ SRC/AUTH.OBJ SRC/CIDR.OBJ SRC/SSL.OBJ \
- SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ SRC/ZIP.OBJ
+ SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ SRC/ZIP.OBJ SRC/EXTCMODES.OBJ SRC/S_STATS.OBJ
 
 MOD_FILES=SRC/L_COMMANDS.OBJ SRC/M_CHGHOST.OBJ SRC/M_SDESC.OBJ SRC/M_SETIDENT.OBJ \
  SRC/M_SETNAME.OBJ SRC/M_SETHOST.OBJ SRC/M_CHGIDENT.OBJ SRC/M_SVSMOTD.OBJ \
@@ -80,7 +80,7 @@ CONF:
        
 
 ./WIRCD.EXE: $(OBJ_FILES) $(MOD_FILES) SRC/win32/WIN32.RES
-        $(LINK) $(LFLAGS) $(OBJ_FILES) $(MOD_FILES) SRC/win32/WIN32.RES SRC/WIN32/GNU_REGEX.LIB  /MAPINFO:LINES /MAP
+        $(LINK) $(LFLAGS) $(OBJ_FILES) $(MOD_FILES) SRC/win32/WIN32.RES SRC/WIN32/TRE.LIB /MAPINFO:LINES /MAP
        -@erase src\win32\win32.res
 !IFNDEF DEBUG
  @echo Non Debug version built 
@@ -112,6 +112,9 @@ src/ircsprintf.obj: src/ircsprintf.c $(INCLUDES)
 src/packet.obj: src/packet.c $(INCLUDES)
         $(CC) $(CFLAGS) src/packet.c
 
+src/s_stats.obj: src/s_stats.c $(INCLUDES)
+        $(CC) $(CFLAGS) src/s_stats.c
+
 src/fdlist.obj: src/fdlist.c $(INCLUDES)
         $(CC) $(CFLAGS) src/fdlist.c
 
@@ -149,6 +152,12 @@ src/list.obj: src/list.c $(INCLUDES)
 src/res.obj: src/res.c $(INCLUDES)
         $(CC) $(CFLAGS) src/res.c
 
+src/res_mkquery.obj: src/res_mkquery.c $(INCLUDES)
+        $(CC) $(CFLAGS) src/res_mkquery.c
+
+src/res_skipname.obj: src/res_skipname.c $(INCLUDES)
+        $(CC) $(CFLAGS) src/res_skipname.c
+
 src/s_bsd.obj: src/s_bsd.c $(INCLUDES)
         $(CC) $(CFLAGS) src/s_bsd.c
 
@@ -241,6 +250,9 @@ src/cidr.obj: src/cidr.c $(INCLUDES)
 src/random.obj: src/random.c $(INCLUDES)
        $(CC) $(CFLAGS) src/random.c
 
+src/extcmodes.obj: src/extcmodes.c $(INCLUDES)
+       $(CC) $(CFLAGS) src/extcmodes.c
+
 src/zip.obj: src/zip.c $(INCLUDES)
        $(CC) $(CFLAGS) src/zip.c
 
index 94ad67f578d36a3659490eab12cabb7a7d208207..f3f2a9bdffd4f0c5e495feceb1b9a53ca89a05b0 100644 (file)
@@ -36,11 +36,11 @@ OBJ_FILES=SRC/CHANNEL.OBJ SRC/SEND.OBJ SRC/SOCKET.OBJ \
  SRC/S_DEBUG.OBJ  SRC/SUPPORT.OBJ SRC/LIST.OBJ \
  SRC/S_ERR.OBJ SRC/PACKET.OBJ SRC/S_BSD.OBJ \
  SRC/S_SERV.OBJ SRC/S_USER.OBJ SRC/WIN32GUI.OBJ \
- SRC/VERSION.OBJ SRC/RES_INIT.OBJ \
+ SRC/VERSION.OBJ SRC/RES_INIT.OBJ SRC/RES_COMP.OBJ SRC/RES_MKQUERY.OBJ SRC/RES_SKIPNAME.OBJ \
  SRC/S_KLINE.OBJ SRC/S_EXTRA.OBJ SRC/IRCSPRINTF.OBJ SRC/LUSERS.OBJ \
  SRC/SCACHE.OBJ SRC/ALN.OBJ SRC/BADWORDS.OBJ SRC/WEBTV.OBJ SRC/RES.OBJ SRC/MODULES.OBJ \
  SRC/S_SVS.OBJ SRC/EVENTS.OBJ SRC/UMODES.OBJ SRC/AUTH.OBJ SRC/CIDR.OBJ SRC/SSL.OBJ \
- SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ SRC/ZIP.OBJ
+ SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ SRC/ZIP.OBJ SRC/EXTCMODES.OBJ SRC/S_STATS.OBJ
 
 MOD_FILES=SRC/L_COMMANDS.OBJ SRC/M_CHGHOST.OBJ SRC/M_SDESC.OBJ SRC/M_SETIDENT.OBJ \
  SRC/M_SETNAME.OBJ SRC/M_SETHOST.OBJ SRC/M_CHGIDENT.OBJ SRC/M_SVSMOTD.OBJ \
@@ -75,7 +75,7 @@ CONF:
        
 
 ./WIRCD.EXE: $(OBJ_FILES) $(MOD_FILES) SRC/win32/WIN32.RES
-        $(LINK) $(LFLAGS) $(OBJ_FILES) $(MOD_FILES) SRC/win32/WIN32.RES SRC/WIN32/GNU_REGEX.LIB  /MAPINFO:LINES /MAP
+        $(LINK) $(LFLAGS) $(OBJ_FILES) $(MOD_FILES) SRC/win32/WIN32.RES SRC/WIN32/TRE.LIB /MAPINFO:LINES /MAP
        -@erase src\win32\win32.res
 !IFNDEF DEBUG
  @echo Non Debug version built 
@@ -107,6 +107,9 @@ src/ircsprintf.obj: src/ircsprintf.c $(INCLUDES)
 src/packet.obj: src/packet.c $(INCLUDES)
         $(CC) $(CFLAGS) src/packet.c
 
+src/s_stats.obj: src/s_stats.c $(INCLUDES)
+        $(CC) $(CFLAGS) src/s_stats.c
+
 src/fdlist.obj: src/fdlist.c $(INCLUDES)
         $(CC) $(CFLAGS) src/fdlist.c
 
@@ -144,6 +147,12 @@ src/list.obj: src/list.c $(INCLUDES)
 src/res.obj: src/res.c $(INCLUDES)
         $(CC) $(CFLAGS) src/res.c
 
+src/res_mkquery.obj: src/res_mkquery.c $(INCLUDES)
+        $(CC) $(CFLAGS) src/res_mkquery.c
+
+src/res_skipname.obj: src/res_skipname.c $(INCLUDES)
+        $(CC) $(CFLAGS) src/res_skipname.c
+
 src/s_bsd.obj: src/s_bsd.c $(INCLUDES)
         $(CC) $(CFLAGS) src/s_bsd.c
 
@@ -236,6 +245,9 @@ src/cidr.obj: src/cidr.c $(INCLUDES)
 src/random.obj: src/random.c $(INCLUDES)
        $(CC) $(CFLAGS) src/random.c
 
+src/extcmodes.obj: src/extcmodes.c $(INCLUDES)
+       $(CC) $(CFLAGS) src/extcmodes.c
+
 src/zip.obj: src/zip.c $(INCLUDES)
        $(CC) $(CFLAGS) src/zip.c
 
index d1f19a1099fd874ba8c8575b5a09bb245dc88f0b..35aff7a2da7d93f0a30b6bf9e1bc0bd7f53c0212 100644 (file)
@@ -27,8 +27,8 @@ OBJS=auth.o aln.o badwords.o channel.o cloak.o crule.o dbuf.o \
        res_init.o res_comp.o res_mkquery.o res_skipname.o s_auth.o \
        s_bsd.o s_conf.o s_debug.o s_err.o s_extra.o s_kline.o \
        s_misc.o s_numeric.o s_serv.o s_svs.o $(STRTOUL) socket.o \
-       ssl.o s_user.o scache.o send.o support.o umodes.o \
-       version.o webtv.o whowas.o zip.o cidr.o random.o
+       ssl.o s_user.o scache.o send.o support.o umodes.o s_stats.o \
+       version.o webtv.o whowas.o zip.o cidr.o random.o extcmodes.o 
 
 SRC=$(OBJS:%.o=%.c)
 
@@ -53,7 +53,7 @@ all: build
 build: ircd mods
 
 custommodule:
-       cd modules; $(MAKE) MODULEFILE=$(MODULEFILE) EXLIBS=$(EXLIBS) custommodule
+       cd modules; $(MAKE) MODULEFILE=$(MODULEFILE) 'EXLIBS=$(EXLIBS)' custommodule
 
 ircd: $(OBJS)
        $(CC) $(CFLAGS) $(CRYPTOLIB) -o ircd $(OBJS) $(LDFLAGS) $(IRCDLIBS) $(CRYPTOLIB)
@@ -98,6 +98,9 @@ dbuf.o: dbuf.c $(INCLUDES) ../include/dbuf.h
 packet.o: packet.c $(INCLUDES)
        $(CC) $(CFLAGS) -c packet.c
 
+s_stats.o: s_stats.c $(INCLUDES)
+       $(CC) $(CFLAGS) -c s_stats.c
+
 badwords.o: badwords.c $(INCLUDES)
        $(CC) $(CFLAGS) -c badwords.c
 
@@ -240,5 +243,8 @@ cidr.o: cidr.c $(INCLUDES)
 random.o: random.c $(INCLUDES)
        $(CC) $(CFLAGS) -c random.c
 
+extcmodes.o: extcmodes.c $(INCLUDES)
+       $(CC) $(CFLAGS) -c extcmodes.c
+
 # DO NOT DELETE THIS LINE -- make depend depends on it.
 
index 86e686d34cb700ddf1f45ea8a48a1d6b35d86106..69156070baea49a09757277cee5889db433f8a76 100644 (file)
@@ -72,26 +72,33 @@ extern int lifesux;
 
 /* Some forward declarations */
 CMD_FUNC(do_join);
-static void add_invite(aClient *, aChannel *);
-static int add_banid(aClient *, aChannel *, char *);
-static int can_join(aClient *, aClient *, aChannel *, char *, char *,
+void add_invite(aClient *, aChannel *);
+char *clean_ban_mask(char *);
+int add_banid(aClient *, aChannel *, char *);
+int can_join(aClient *, aClient *, aChannel *, char *, char *,
     char **);
-static int channel_link(aClient *, aClient *, int, char **);
 void channel_modes(aClient *, char *, char *, aChannel *);
-static int check_channelmask(aClient *, aClient *, char *);
+int check_channelmask(aClient *, aClient *, char *);
 int del_banid(aChannel *, char *);
-static void set_mode(aChannel *, aClient *, int, char **, u_int *,
+void set_mode(aChannel *, aClient *, int, char **, u_int *,
     char[MAXMODEPARAMS][MODEBUFLEN + 3], int);
-static void make_mode_str(aChannel *, long, long, int,
+
+#ifdef EXTCMODE
+void make_mode_str(aChannel *, long, Cmode_t, long, int,
+    char[MAXMODEPARAMS][MODEBUFLEN + 3], char *, char *, char);
+#else
+void make_mode_str(aChannel *, long, long, int,
     char[MAXMODEPARAMS][MODEBUFLEN + 3], char *, char *, char);
-static int do_mode_char(aChannel *, long, char, char *,
+#endif
+
+int do_mode_char(aChannel *, long, char, char *,
        u_int, aClient *,
     u_int *, char[MAXMODEPARAMS][MODEBUFLEN + 3], char);
-static void do_mode(aChannel *, aClient *, aClient *, int, char **, int,
+void do_mode(aChannel *, aClient *, aClient *, int, char **, int,
     int);
-static void bounce_mode(aChannel *, aClient *, int, char **);
+void bounce_mode(aChannel *, aClient *, int, char **);
 
-static void sub1_from_channel(aChannel *);
+void sub1_from_channel(aChannel *);
 
 void clean_channelname(char *);
 void del_invite(aClient *, aChannel *);
@@ -167,13 +174,20 @@ void make_cmodestr(void)
 {
        char *p = &cmodestring[0];
        aCtab *tab = &cFlagTab[0];
-
+#ifdef EXTCMODE
+       int i;
+#endif
        while (tab->mode != 0x0)
        {
                *p = tab->flag;
                p++;
                tab++;
        }
+#ifdef EXTCMODE
+       for (i=0; i <= Channelmode_highest; i++)
+               if (Channelmode_Table[i].flag)
+                       *p++ = Channelmode_Table[i].flag;
+#endif
        *p = '\0';
 }
 
@@ -345,7 +359,7 @@ void        free_membership(Membership *lp, int local)
 **     message (NO SUCH NICK) is generated. If the client was found
 **     through the history, chasing will be 1 and otherwise 0.
 */
-static aClient *find_chasing(aClient *sptr, char *user, int *chasing)
+aClient *find_chasing(aClient *sptr, char *user, int *chasing)
 {
        aClient *who = find_client(user, (aClient *)NULL);
 
@@ -377,7 +391,7 @@ static aClient *find_chasing(aClient *sptr, char *user, int *chasing)
 
 /* add_exbanid - add an id to be excepted to the channel bans  (belongs to cptr) */
 
-static int add_exbanid(aClient *cptr, aChannel *chptr, char *banid)
+int add_exbanid(aClient *cptr, aChannel *chptr, char *banid)
 {
        Ban *ban;
        int  cnt = 0, len = 0;
@@ -450,7 +464,7 @@ int del_exbanid(aChannel *chptr, char *banid)
  */
 /* add_banid - add an id to be banned to the channel  (belongs to cptr) */
 
-static int add_banid(aClient *cptr, aChannel *chptr, char *banid)
+int add_banid(aClient *cptr, aChannel *chptr, char *banid)
 {
        Ban *ban;
        int  cnt = 0, len = 0;
@@ -603,7 +617,7 @@ static int is_irc_banned(aChannel *chptr)
  * adds a user to a channel by adding another link to the channels member
  * chain.
  */
-static void add_user_to_channel(aChannel *chptr, aClient *who, int flags)
+void add_user_to_channel(aChannel *chptr, aClient *who, int flags)
 {
        Member *ptr;
        Membership *ptr2;
@@ -741,6 +755,18 @@ int is_chanownprotop(aClient *cptr, aChannel *chptr) {
        return 0;
 }
 
+int is_skochanop(aClient *cptr, aChannel *chptr) {
+       Membership *lp;
+               
+       if (IsServer(cptr))
+               return 1;
+       if (chptr)
+               if ((lp = find_membership_link(cptr->user->channel, chptr)))
+                       if (lp->flags & (CHFL_CHANOWNER|CHFL_CHANPROT|CHFL_CHANOP|CHFL_HALFOP))
+                               return 1;
+       return 0;
+}
+
 int  is_chanprot(aClient *cptr, aChannel *chptr)
 {
        Membership *lp;
@@ -768,7 +794,24 @@ int  can_send(aClient *cptr, aChannel *chptr, char *msgtext)
        */
        
        if (!MyClient(cptr))
+       {
+               if (IsClient(cptr))
+               {
+                       /* channelmode +mu is a special case.. sux!. -- Syzop */                
+
+                       lp = find_membership_link(cptr->user->channel, chptr);
+                       if ((chptr->mode.mode & MODE_MODERATED) && (chptr->mode.mode & MODE_AUDITORIUM) &&
+                           !IsOper(cptr) &&
+                       (!lp || !(lp->flags & (CHFL_CHANOP|CHFL_VOICE|CHFL_CHANOWNER|CHFL_HALFOP|CHFL_CHANPROT))) &&
+                       !is_irc_banned(chptr))
+                   {
+                               sendto_chanops_butone(cptr, chptr, ":IRC PRIVMSG %s :%s: %s",
+                                       chptr->chname, cptr->name, msgtext);
+                               return (CANNOT_SEND_MODERATED);
+                       }
+               }
                return 0;
+       }
 
        if (chptr->mode.mode & MODE_NOCOLOR)
                if (strchr((char *)msgtext, 3) || strchr((char *)msgtext, 27))
@@ -784,21 +827,14 @@ int  can_send(aClient *cptr, aChannel *chptr, char *msgtext)
            || !(lp->flags & (CHFL_CHANOP | CHFL_VOICE | CHFL_CHANOWNER |
            CHFL_HALFOP | CHFL_CHANPROT))))
                return CANNOT_SEND_MODREG;
-       if (chptr->mode.mode & MODE_MODERATED &&
+       if (chptr->mode.mode & MODE_MODERATED && !IsOper(cptr) &&
            (!lp
            || !(lp->flags & (CHFL_CHANOP | CHFL_VOICE | CHFL_CHANOWNER |
            CHFL_HALFOP | CHFL_CHANPROT))))
            {
-               if (!(chptr->mode.mode & MODE_AUDITORIUM))
-               {
+                       if ((chptr->mode.mode & MODE_AUDITORIUM) && !is_irc_banned(chptr))
+                               sendto_chmodemucrap(cptr, chptr, msgtext);
                        return (CANNOT_SEND_MODERATED);
-               } 
-               {
-                       if (!is_irc_banned(chptr))
-                               sendto_chanops_butone(cptr, chptr, ":IRC PRIVMSG %s :%s: %s",
-                                               chptr->chname, cptr->name, msgtext);
-                       return (CANNOT_SEND_MODERATED);
-               }
            }
 
        if (chptr->mode.mode & MODE_NOCTCP &&
@@ -820,6 +856,50 @@ int  can_send(aClient *cptr, aChannel *chptr, char *msgtext)
        return 0;
 }
 
+/* [just a helper for channel_modef_string()] */
+static inline char *chmodefstrhelper(char *buf, char t, char tdef, unsigned short l, unsigned char a)
+{
+char *p;
+       ircsprintf(buf, "%hd", l);
+       p = buf + strlen(buf);
+       *p++ = t;
+       if (a && (a != tdef))
+       {
+               *p++ = '#';
+               *p++ = a;
+       }
+       *p++ = ',';
+       return p;
+}
+
+/** returns the channelmode +f string (ie: '[5k,40j]:10') */
+char *channel_modef_string(ChanFloodProt *x)
+{
+static char retbuf[512]; /* overkill :p */
+char *p = retbuf;
+       *p++ = '[';
+
+       /* (alphabetized) */
+       if (x->l[FLD_CTCP])
+               p = chmodefstrhelper(p, 'c', 'C', x->l[FLD_CTCP], x->a[FLD_CTCP]);
+       if (x->l[FLD_JOIN])
+               p = chmodefstrhelper(p, 'j', 'i', x->l[FLD_JOIN], x->a[FLD_JOIN]);
+       if (x->l[FLD_KNOCK])
+               p = chmodefstrhelper(p, 'k', 'K', x->l[FLD_KNOCK], x->a[FLD_KNOCK]);
+       if (x->l[FLD_MSG])
+               p = chmodefstrhelper(p, 'm', 'm', x->l[FLD_MSG], x->a[FLD_MSG]);
+       if (x->l[FLD_NICK])
+               p = chmodefstrhelper(p, 'n', 'N', x->l[FLD_NICK], x->a[FLD_NICK]);
+       if (x->l[FLD_TEXT])
+               p = chmodefstrhelper(p, 't', '\0', x->l[FLD_TEXT], x->a[FLD_TEXT]);
+
+       if (*(p - 1) == ',')
+               p--;
+       *p++ = ']';
+       ircsprintf(p, ":%hd", x->per);
+       return retbuf;
+}
+
 /*
  * write the "simple" list of channel modes for channel chptr onto buffer mbuf
  * with the parameters in pbuf.
@@ -828,8 +908,12 @@ void channel_modes(aClient *cptr, char *mbuf, char *pbuf, aChannel *chptr)
 {
        aCtab *tab = &cFlagTab[0];
        char bcbuf[1024];
+#ifdef EXTCMODE
+       int i;
+#endif
 
        *mbuf++ = '+';
+       /* Paramless first */
        while (tab->mode != 0x0)
        {
                if ((chptr->mode.mode & tab->mode))
@@ -837,6 +921,14 @@ void channel_modes(aClient *cptr, char *mbuf, char *pbuf, aChannel *chptr)
                                *mbuf++ = tab->flag;
                tab++;
        }
+#ifdef EXTCMODE
+       for (i=0; i <= Channelmode_highest; i++)
+       {
+               if (Channelmode_Table[i].flag && !Channelmode_Table[i].paracount &&
+                   (chptr->mode.extmode & Channelmode_Table[i].mode))
+                       *mbuf++ = Channelmode_Table[i].flag;
+       }
+#endif
        if (chptr->mode.limit)
        {
                *mbuf++ = 'l';
@@ -867,22 +959,40 @@ void channel_modes(aClient *cptr, char *mbuf, char *pbuf, aChannel *chptr)
                }
        }
        /* if we add more parameter modes, add a space to the strings here --Stskeeps */
+#ifdef NEWCHFLOODPROT
+       if (chptr->mode.floodprot)
+#else
        if (chptr->mode.per)
+#endif
        {
                *mbuf++ = 'f';
                if (IsMember(cptr, chptr) || IsServer(cptr)
                    || IsULine(cptr))
                {
+#ifdef NEWCHFLOODPROT
+                       ircsprintf(bcbuf, "%s ", channel_modef_string(chptr->mode.floodprot));
+#else
                        if (chptr->mode.kmode == 1)
-                               ircsprintf(bcbuf, "*%i:%i ", chptr->mode.msgs,
-                                   chptr->mode.per);
+                               ircsprintf(bcbuf, "*%i:%i ", chptr->mode.msgs, chptr->mode.per);
                        else
-                               ircsprintf(bcbuf, "%i:%i ", chptr->mode.msgs,
-                                   chptr->mode.per);
+                               ircsprintf(bcbuf, "%i:%i ", chptr->mode.msgs, chptr->mode.per);
+#endif
                        (void)strcat(pbuf, bcbuf);
                }
+       }
 
+#ifdef EXTCMODE
+       for (i=0; i <= Channelmode_highest; i++)
+       {
+               if (Channelmode_Table[i].flag && Channelmode_Table[i].paracount &&
+                   (chptr->mode.extmode & Channelmode_Table[i].mode))
+               {
+                       *mbuf++ = Channelmode_Table[i].flag;
+                       strcat(pbuf, Channelmode_Table[i].get_param(extcmode_get_struct(chptr->mode.extmodeparam, Channelmode_Table[i].flag)));
+                       strcat(pbuf, " ");
+               }
        }
+#endif
 
        *mbuf++ = '\0';
        return;
@@ -1318,10 +1428,7 @@ void bounce_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[])
 {
        char pvar[MAXMODEPARAMS][MODEBUFLEN + 3];
        int  pcount;
-       long oldm, oldl;
 
-       oldm = chptr->mode.mode;
-       oldl = chptr->mode.limit;
        set_mode(chptr, cptr, parc, parv, &pcount, pvar, 1);
 
        if (chptr->creationtime)
@@ -1342,13 +1449,10 @@ void do_mode(aChannel *chptr, aClient *cptr, aClient *sptr, int parc, char *parv
 {
        char pvar[MAXMODEPARAMS][MODEBUFLEN + 3];
        int  pcount;
-       long oldm, oldl;
        char tschange = 0, isbounce = 0;        /* fwd'ing bounce */
 
        if (**parv == '&')
                isbounce = 1;
-       oldm = chptr->mode.mode;
-       oldl = chptr->mode.limit;
 
        set_mode(chptr, sptr, parc, parv, &pcount, pvar, 0);
 
@@ -1454,14 +1558,22 @@ void do_mode(aChannel *chptr, aClient *cptr, aClient *sptr, int parc, char *parv
  *  contain the +x-y stuff, and the parabuf will contain the parameters.
  *  If bounce is set to 1, it will make the string it needs for a bounce.
  */
+#ifdef EXTCMODE
+void make_mode_str(aChannel *chptr, long oldm, Cmode_t oldem, long oldl, int pcount, 
+       char pvar[MAXMODEPARAMS][MODEBUFLEN + 3], char *mode_buf, char *para_buf, char bounce)
+#else
 void make_mode_str(aChannel *chptr, long oldm, long oldl, int pcount, 
        char pvar[MAXMODEPARAMS][MODEBUFLEN + 3], char *mode_buf, char *para_buf, char bounce)
+#endif
 {
 
        char tmpbuf[MODEBUFLEN+3], *tmpstr;
        aCtab *tab = &cFlagTab[0];
        char *x = mode_buf;
        int  what, cnt, z;
+#ifdef EXTCMODE
+       int i;
+#endif
        char *m;
        what = 0;
 
@@ -1487,6 +1599,25 @@ void make_mode_str(aChannel *chptr, long oldm, long oldl, int pcount,
                }
                tab++;
        }
+#ifdef EXTCMODE
+       /* + paramless extmodes... */
+       for (i=0; i <= Channelmode_highest; i++)
+       {
+               if (!Channelmode_Table[i].flag || Channelmode_Table[i].paracount)
+                       continue;
+               /* have it now and didn't have it before? */
+               if ((chptr->mode.extmode & Channelmode_Table[i].mode) &&
+                   !(oldem & Channelmode_Table[i].mode))
+               {
+                       if (what != MODE_ADD)
+                       {
+                               *x++ = bounce ? '-' : '+';
+                               what = MODE_ADD;
+                       }
+                       *x++ = Channelmode_Table[i].flag;
+               }
+       }
+#endif
 
        *x = '\0';
        /* - param-less modes */
@@ -1508,6 +1639,28 @@ void make_mode_str(aChannel *chptr, long oldm, long oldl, int pcount,
                tab++;
        }
 
+#ifdef EXTCMODE
+       /* - extmodes (both "param modes" and paramless don't have
+        * any params when unsetting...
+        */
+       for (i=0; i <= Channelmode_highest; i++)
+       {
+               if (!Channelmode_Table[i].flag /* || Channelmode_Table[i].paracount */)
+                       continue;
+               /* don't have it now and did have it before */
+               if (!(chptr->mode.extmode & Channelmode_Table[i].mode) &&
+                   (oldem & Channelmode_Table[i].mode))
+               {
+                       if (what != MODE_DEL)
+                       {
+                               *x++ = bounce ? '+' : '-';
+                               what = MODE_DEL;
+                       }
+                       *x++ = Channelmode_Table[i].flag;
+               }
+       }
+#endif
+
        *x = '\0';
        /* user limit */
        if (chptr->mode.limit != oldl)
@@ -1565,7 +1718,12 @@ void make_mode_str(aChannel *chptr, long oldm, long oldl, int pcount,
                *m = '\0';
        }
        if (bounce)
+       {
                chptr->mode.mode = oldm;
+#ifdef EXTCMODE
+               chptr->mode.extmode = oldem;
+#endif
+       }
        z = strlen(para_buf);
        if (para_buf[z - 1] == ' ')
                para_buf[z - 1] = '\0';
@@ -1744,7 +1902,43 @@ int  do_mode_char(aChannel *chptr, long modetype, char modechar, char *param,
                          chptr->mode.mode |= modetype;
                  }
                  else
+                 {
                          chptr->mode.mode &= ~modetype;
+#ifdef NEWCHFLOODPROT
+                         /* reset joinflood on -i, reset msgflood on -m, etc.. */
+                         if (chptr->mode.floodprot)
+                         {
+                               switch(modetype)
+                               {
+                               case MODE_NOCTCP:
+                                       chptr->mode.floodprot->c[FLD_CTCP] = 0;
+                                       break;
+                               case MODE_NONICKCHANGE:
+                                       chptr->mode.floodprot->c[FLD_NICK] = 0;
+                                       break;
+                               case MODE_MODERATED:
+                                       chptr->mode.floodprot->c[FLD_MSG] = 0;
+                                       chptr->mode.floodprot->c[FLD_CTCP] = 0;
+                                       break;
+                               case MODE_NOKNOCK:
+                                       chptr->mode.floodprot->c[FLD_KNOCK] = 0;
+                                       break;
+                               case MODE_INVITEONLY:
+                                       chptr->mode.floodprot->c[FLD_JOIN] = 0;
+                                       break;
+                               case MODE_MODREG:
+                                       chptr->mode.floodprot->c[FLD_MSG] = 0;
+                                       chptr->mode.floodprot->c[FLD_CTCP] = 0;
+                                       break;
+                               case MODE_RGSTRONLY:
+                                       chptr->mode.floodprot->c[FLD_JOIN] = 0;
+                                       break;
+                               default:
+                                       break;
+                               }
+                         }
+#endif
+                 }
                  break;
 
 /* do pro-opping here (popping) */
@@ -1753,7 +1947,10 @@ int  do_mode_char(aChannel *chptr, long modetype, char modechar, char *param,
                       && !is_chanowner(cptr, chptr))
                  {
                          if (IsNetAdmin(cptr))
-                               opermode = 1;
+                         {
+                               if (!is_halfop(cptr, chptr)) /* htrig will take care of halfop override notices */
+                                  opermode = 1;
+                         }
                          else
                          {
                                  sendto_one(cptr, err_str(ERR_ONLYSERVERSCANCHANGE),
@@ -1766,7 +1963,10 @@ int  do_mode_char(aChannel *chptr, long modetype, char modechar, char *param,
                      && !is_chanowner(cptr, chptr))
                  {
                          if (IsNetAdmin(cptr))
-                               opermode = 1;
+                         {
+                               if (!is_halfop(cptr, chptr)) /* htrig will take care of halfop override notices */
+                                  opermode = 1;
+                         }
                          else
                          {
                                  sendto_one(cptr,
@@ -1939,7 +2139,10 @@ int  do_mode_char(aChannel *chptr, long modetype, char modechar, char *param,
                                        *tmp = '\0';
                                  if (*param == '\0')
                                        break;
-                                 param[KEYLEN] = '\0';
+                                 if (strlen(param) > KEYLEN)
+                                   param[KEYLEN] = '\0';
+                                 if (!strcmp(chptr->mode.key, param))
+                                       break;
                                  strncpyzt(chptr->mode.key, param,
                                      sizeof(chptr->mode.key));
                          }
@@ -1968,7 +2171,7 @@ int  do_mode_char(aChannel *chptr, long modetype, char modechar, char *param,
                          break;
                  }
                  retval = 1;
-                 tmpstr = pretty_mask(param);
+                 tmpstr = clean_ban_mask(param);
                  /* For bounce, we don't really need to worry whether
                   * or not it exists on our server.  We'll just always
                   * bounce it. */
@@ -1987,7 +2190,7 @@ int  do_mode_char(aChannel *chptr, long modetype, char modechar, char *param,
                          break;
                  }
                  retval = 1;
-                 tmpstr = pretty_mask(param);
+                 tmpstr = clean_ban_mask(param);
                  /* For bounce, we don't really need to worry whether
                   * or not it exists on our server.  We'll just always
                   * bounce it. */
@@ -2040,7 +2243,8 @@ int  do_mode_char(aChannel *chptr, long modetype, char modechar, char *param,
                                  retval = 0;
                                  break;
                          }
-
+                         if (!stricmp(param, chptr->mode.link))
+                               break;
                          if (!stricmp(param, chptr->chname))
                          {
                                  if (MyClient(cptr))
@@ -2111,6 +2315,7 @@ int  do_mode_char(aChannel *chptr, long modetype, char modechar, char *param,
                  }
                  if (retval == 0)      /* you can't break a case from loop */
                          break;
+#ifndef NEWCHFLOODPROT
                  if (what == MODE_ADD)
                  {
                          if (!bounce)  /* don't do the mode at all. */
@@ -2197,6 +2402,253 @@ int  do_mode_char(aChannel *chptr, long modetype, char modechar, char *param,
                          }
                          retval = 0;
                  }
+#else
+               /* NEW */
+               if (what == MODE_ADD)
+               {
+                       if (!bounce)    /* don't do the mode at all. */
+                       {
+                               ChanFloodProt newf;
+                               memset(&newf, 0, sizeof(newf));
+
+                               if (!param || *pcount >= MAXMODEPARAMS)
+                               {
+                                       retval = 0;
+                                       break;
+                               }
+
+                               /* old +f was like +f 10:5 or +f *10:5
+                                * new is +f [5c,30j,10t#b]:15
+                                * +f 10:5  --> +f [10t]:5
+                                * +f *10:5 --> +f [10t#b]:5
+                                */
+                               if (param[0] != '[')
+                               {
+                                       /* <<OLD +f>> */
+                                 /* like 1:1 and if its less than 3 chars then ahem.. */
+                                 if (strlen(param) < 3)
+                                 {
+                                         break;
+                                 }
+                                 /* may not contain other chars 
+                                    than 0123456789: & NULL */
+                                 hascolon = 0;
+                                 for (xp = param; *xp; xp++)
+                                 {
+                                         if (*xp == ':')
+                                               hascolon++;
+                                         /* fast alpha check */
+                                         if (((*xp < '0') || (*xp > '9'))
+                                             && (*xp != ':')
+                                             && (*xp != '*'))
+                                               goto break_flood;
+                                         /* uh oh, not the first char */
+                                         if (*xp == '*' && (xp != param))
+                                               goto break_flood;
+                                 }
+                                 /* We can avoid 2 strchr() and a strrchr() like this
+                                  * it should be much faster. -- codemastr
+                                  */
+                                 if (hascolon != 1)
+                                       break;
+                                 if (*param == '*')
+                                 {
+                                         xzi = 1;
+                                         //                      chptr->mode.kmode = 1;
+                                 }
+                                 else
+                                 {
+                                         xzi = 0;
+
+                                         //                   chptr->mode.kmode = 0;
+                                 }
+                                 xp = index(param, ':');
+                                 *xp = '\0';
+                                 xxi =
+                                     atoi((*param ==
+                                     '*' ? (param + 1) : param));
+                                 xp++;
+                                 xyi = atoi(xp);
+                                 if (xxi > 500 || xyi > 500)
+                                       break;
+                                 xp--;
+                                 *xp = ':';
+                                 if ((xxi == 0) || (xyi == 0))
+                                         break;
+
+                                 /* ok, we passed */
+                                 newf.l[FLD_TEXT] = xxi;
+                                 newf.per = xyi;
+                                 if (xzi == 1)
+                                     newf.a[FLD_TEXT] = 'b';
+                               } else {
+                                       /* NEW +F */
+                                       char xbuf[256], c, a, *p, *p2, *x = xbuf+1;
+                                       int v, i;
+                                       unsigned short warnings = 0, breakit;
+
+                                       /* '['<number><1 letter>[optional: '#'+1 letter],[next..]']'':'<number> */
+                                       strlcpy(xbuf, param, sizeof(xbuf));
+                                       p2 = strchr(xbuf+1, ']');
+                                       if (!p2)
+                                       {
+                                               if (MyClient(cptr))
+                                                       sendto_one(cptr, ":%s NOTICE %s :bad syntax for channelmode +f", me.name, cptr->name);
+                                               break;
+                                       }
+                                       *p2 = '\0';
+                                       if (*(p2+1) != ':')
+                                       {
+                                               if (MyClient(cptr))
+                                                       sendto_one(cptr, ":%s NOTICE %s :bad syntax for channelmode +f", me.name, cptr->name);
+                                               break;
+                                       }
+                                       breakit = 0;
+                                       for (x = strtok(xbuf+1, ","); x; x = strtok(NULL, ","))
+                                       {
+                                               /* <number><1 letter>[optional: '#'+1 letter] */
+                                               p = x;
+                                               while(isdigit(*p)) { p++; }
+                                               if ((*p == '\0') ||
+                                                   !((*p == 'c') || (*p == 'j') || (*p == 'k') ||
+                                                     (*p == 'm') || (*p == 'n') || (*p == 't')))
+                                               {
+                                                       if (MyClient(cptr) && *p && (warnings++ < 3))
+                                                               sendto_one(cptr, ":%s NOTICE %s :warning: channelmode +f: floodtype '%c' unknown, ignored.",
+                                                                       me.name, cptr->name, *p);
+                                                       continue; /* continue instead of break for forward compatability. */
+                                               }
+                                               c = *p;
+                                               *p = '\0';
+                                               v = atoi(x);
+                                               if ((v < 1) || (v > 999)) /* out of range... */
+                                               {
+                                                       if (MyClient(cptr))
+                                                       {
+                                                               sendto_one(cptr, ":%s NOTICE %s :channelmode +f: floodtype '%c', value should be 1-999",
+                                                                       me.name, cptr->name, c);
+                                                               breakit = 1;
+                                                               break;
+                                                       } else
+                                                               continue; /* just ignore for remote servers */
+                                               }
+                                               p++;
+                                               a = '\0';
+                                               if (*p != '\0')
+                                               {
+                                                       if (*p == '#')
+                                                       {
+                                                               p++;
+                                                               a = *p;
+                                                       }
+                                               }
+
+                                               switch(c)
+                                               {
+                                                       case 'c':
+                                                               newf.l[FLD_CTCP] = v;
+                                                               if ((a == 'm') || (a == 'M'))
+                                                                       newf.a[FLD_CTCP] = a;
+                                                               else
+                                                                       newf.a[FLD_CTCP] = 'C';
+                                                               break;
+                                                       case 'j':
+                                                               newf.l[FLD_JOIN] = v;
+                                                               if (a == 'R')
+                                                                       newf.a[FLD_JOIN] = a;
+                                                               else
+                                                                       newf.a[FLD_JOIN] = 'i';
+                                                               break;
+                                                       case 'k':
+                                                               newf.l[FLD_KNOCK] = v;
+                                                               newf.a[FLD_KNOCK] = 'K';
+                                                               break;
+                                                       case 'm':
+                                                               newf.l[FLD_MSG] = v;
+                                                               if (a == 'M')
+                                                                       newf.a[FLD_MSG] = a;
+                                                               else
+                                                                       newf.a[FLD_MSG] = 'm';
+                                                               break;
+                                                       case 'n':
+                                                               newf.l[FLD_NICK] = v;
+                                                               newf.a[FLD_NICK] = 'N';
+                                                               break;
+                                                       case 't':
+                                                               newf.l[FLD_TEXT] = v;
+                                                               if (a == 'b')
+                                                                       newf.a[FLD_TEXT] = a;
+                                                               break;
+                                                       default:
+                                                               breakit=1;
+                                                               break;
+                                               }
+                                               if (breakit)
+                                                       break;
+                                       } /* for */
+                                       if (breakit)
+                                               break;
+                                       /* parse 'per' */
+                                       p2++;
+                                       if (*p2 != ':')
+                                       {
+                                               if (MyClient(cptr))
+                                                       sendto_one(cptr, ":%s NOTICE %s :bad syntax for channelmode +f", me.name, cptr->name);
+                                               break;
+                                       }
+                                       p2++;
+                                       if (!*p2)
+                                       {
+                                               if (MyClient(cptr))
+                                                       sendto_one(cptr, ":%s NOTICE %s :bad syntax for channelmode +f", me.name, cptr->name);
+                                               break;
+                                       }
+                                       v = atoi(p2);
+                                       if ((v < 1) || (v > 999)) /* 'per' out of range */
+                                       {
+                                               if (MyClient(cptr))
+                                                       sendto_one(cptr, ":%s NOTICE %s :error: channelmode +f: time range should be 1-999",
+                                                               me.name, cptr->name);
+                                               break;
+                                       }
+                                       newf.per = v;
+                                       
+                                       /* Is anything turned on? (to stop things like '+f []:15' */
+                                       breakit = 1;
+                                       for (v=0; v < NUMFLD; v++)
+                                               if (newf.l[v])
+                                                       breakit=0;
+                                       if (breakit)
+                                               break;
+                                       
+                               } /* if param[0] == '[' */ 
+
+                               if (chptr->mode.floodprot &&
+                                   !memcmp(chptr->mode.floodprot, &newf, sizeof(ChanFloodProt)))
+                                       break; /* They are identical */
+
+                               /* Good.. store the mode (and alloc if needed) */
+                               if (!chptr->mode.floodprot)
+                                       chptr->mode.floodprot = MyMalloc(sizeof(ChanFloodProt));
+                               memcpy(chptr->mode.floodprot, &newf, sizeof(ChanFloodProt));
+                       } /* !bounce */
+                       strcpy(tmpbuf, channel_modef_string(chptr->mode.floodprot));
+                       tmpstr = tmpbuf;
+                       retval = 1;
+               } else
+               { /* MODE_DEL */
+                       if (!chptr->mode.floodprot)
+                               break; /* no change */
+                       strcpy(tmpbuf, channel_modef_string(chptr->mode.floodprot));
+                       tmpstr = tmpbuf;
+                       if (!bounce)
+                       {
+                               free(chptr->mode.floodprot);
+                               chptr->mode.floodprot = NULL;
+                       }
+                       retval = 0; /* ??? copied from previous +f code. */
+               }
+#endif
 
                  (void)ircsprintf(pvar[*pcount], "%cf%s",
                      what == MODE_ADD ? '+' : '-', tmpstr);
@@ -2207,6 +2659,101 @@ int  do_mode_char(aChannel *chptr, long modetype, char modechar, char *param,
        return retval;
 }
 
+#ifdef EXTCMODE
+/** Check access and if granted, set the extended chanmode to the requested value in memory.
+  * note: if bounce is requested then the mode will not be set.
+  * @returns amount of params eaten (0 or 1)
+  */
+int do_extmode_char(aChannel *chptr, int modeindex, char *param, u_int what,
+                    aClient *cptr, u_int *pcount, char pvar[MAXMODEPARAMS][MODEBUFLEN + 3],
+                    char bounce)
+{
+int paracnt = (what == MODE_ADD) ? Channelmode_Table[modeindex].paracount : 0;
+int x;
+
+       /* Expected a param and it isn't there? */
+       if (paracnt && (!param || (*pcount >= MAXMODEPARAMS)))
+               return 0;
+
+       if (!IsServer(cptr) &&
+#ifndef NO_OPER_OVERRIDE
+           !IsSkoAdmin(cptr) &&
+#endif
+           (Channelmode_Table[modeindex].is_ok(cptr, chptr, param, EXCHK_ACCESS_ERR, what) == FALSE))
+               return paracnt; /* Denied & error msg sent */
+
+       /* Check for multiple changes in 1 command (like +y-y+y 1 2, or +yy 1 2). */
+       for (x = 0; x < *pcount; x++)
+       {
+               if (pvar[x][1] == Channelmode_Table[modeindex].flag)
+               {
+                       /* this is different than the old chanmode system, coz:
+                        * "mode #chan +kkL #a #b #c" will get "+kL #a #b" which is wrong :p.
+                        * we do eat the parameter. -- Syzop
+                        */
+                       return paracnt;
+               }
+       }
+
+       /* w00t... a parameter mode */
+       if (Channelmode_Table[modeindex].paracount)
+       {
+               if (what == MODE_DEL)
+               {
+                       if (!(chptr->mode.extmode & Channelmode_Table[modeindex].mode))
+                               return paracnt; /* There's nothing to remove! */
+                       /* del means any parameter is ok, the one-who-is-set will be used */
+                       ircsprintf(pvar[*pcount], "-%c", Channelmode_Table[modeindex].flag);
+               } else {
+                       /* add: is the parameter ok? */
+                       if (Channelmode_Table[modeindex].is_ok(cptr, chptr, param, EXCHK_PARAM, what) == FALSE)
+                               return paracnt;
+                       /* is it already set at the same value? if so, ignore it. */
+                       if (chptr->mode.extmode & Channelmode_Table[modeindex].mode)
+                       {
+                               char *p, *p2;
+                               p = Channelmode_Table[modeindex].get_param(extcmode_get_struct(chptr->mode.extmodeparam,Channelmode_Table[modeindex].flag));
+                               p2 = Channelmode_Table[modeindex].conv_param(param);
+                               if (p && p2 && !strcmp(p, p2))
+                                       return paracnt; /* ignore... */
+                       }
+                               ircsprintf(pvar[*pcount], "+%c%s",
+                                       Channelmode_Table[modeindex].flag, Channelmode_Table[modeindex].conv_param(param));
+                       (*pcount)++;
+               }
+       }
+
+       if (bounce) /* bounce here means: only check access and return return value */
+               return paracnt;
+       
+       if (what == MODE_ADD)
+       {       /* + */
+               chptr->mode.extmode |= Channelmode_Table[modeindex].mode;
+               if (Channelmode_Table[modeindex].paracount)
+               {
+                       CmodeParam *p = extcmode_get_struct(chptr->mode.extmodeparam, Channelmode_Table[modeindex].flag);
+                       CmodeParam *r;
+                       r = Channelmode_Table[modeindex].put_param(p, param);
+                       if (r != p)
+                               AddListItem(r, chptr->mode.extmodeparam);
+               }
+       } else
+       {       /* - */
+               chptr->mode.extmode &= ~(Channelmode_Table[modeindex].mode);
+               if (Channelmode_Table[modeindex].paracount)
+               {
+                       CmodeParam *p = extcmode_get_struct(chptr->mode.extmodeparam, Channelmode_Table[modeindex].flag);
+                       if (p)
+                       {
+                               DelListItem(p, chptr->mode.extmodeparam);
+                               Channelmode_Table[modeindex].free_param(p);
+                       }
+               }
+       }
+       return paracnt;
+}
+#endif /* EXTCMODE */
+
 /*
  * ListBits(bitvalue, bitlength);
  * written by Stskeeps
@@ -2253,13 +2800,18 @@ void set_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[], u_int *pco
        unsigned int htrig = 0;
        long oldm, oldl;
        int checkrestr = 0, warnrestr = 1;
-       
+#ifdef EXTCMODE
+       int extm = 1000000; /* (default value not used but stops gcc from complaining) */
+       Cmode_t oldem;
+#endif
        paracount = 1;
        *pcount = 0;
 
        oldm = chptr->mode.mode;
        oldl = chptr->mode.limit;
-
+#ifdef EXTCMODE
+       oldem = chptr->mode.extmode;
+#endif
        if (RESTRICT_CHANNELMODES && MyClient(cptr) && !IsAnOper(cptr) && !IsServer(cptr)) /* "cache" this */
                checkrestr = 1;
 
@@ -2296,11 +2848,22 @@ void set_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[], u_int *pco
                                  tab++;
                          }
                          if (found == 1)
+                         {
                                  modetype = foundat.mode;
+                         } else {
+#ifdef EXTCMODE
+                                       /* Maybe in extmodes */
+                                       for (extm=0; extm <= Channelmode_highest; extm++)
+                                       {
+                                               if (Channelmode_Table[extm].flag == *curchr)
+                                               {
+                                                       found = 2;
+                                                       break;
+                                               }
+                                       }
+#endif
+                         }
                          if (found == 0)
-                                 modetype = 0;
-
-                         if (modetype == 0)
                          {
                                  if (!MyClient(cptr))
                                          break;
@@ -2324,12 +2887,26 @@ void set_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[], u_int *pco
                          }
 
 #ifndef NO_OPEROVERRIDE
+                               if (found == 1)
+                               {
                           if ((Halfop_mode(modetype) == FALSE) && opermode == 2 && htrig != 1)
                           {
                                opermode = 0;
                                htrig = 1;
                           }
-#endif
+                               }
+#ifdef EXTCMODE
+                               else if (found == 2) {
+                                       /* Extended mode */
+                                       if ((Channelmode_Table[extm].is_ok(cptr, chptr, parv[paracount], EXCHK_ACCESS, what) == FALSE) &&
+                                           (opermode == 2) && (htrig != 1))
+                                       {
+                                               opermode = 0;
+                                               htrig = 1;
+                                       }
+                               }
+#endif /* EXTCMODE */
+#endif /* !NO_OPEROVERRIDE */
 
                          /* We can afford to send off a param */
                          if (parc <= paracount)
@@ -2337,15 +2914,29 @@ void set_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[], u_int *pco
                          if (parv[paracount] &&
                              strlen(parv[paracount]) >= MODEBUFLEN)
                                parv[paracount][MODEBUFLEN-1] = '\0';
+                       if (found == 1)
+                       {
                          paracount +=
                              do_mode_char(chptr, modetype, *curchr,
                              parv[paracount], what, cptr, pcount, pvar,
                              bounce);
+                       }
+#ifdef EXTCMODE
+                       else if (found == 2)
+                       {
+                               paracount += do_extmode_char(chptr, extm, parv[paracount],
+                                                            what, cptr, pcount, pvar, bounce);
+                       }
+#endif /* EXTCMODE */
                          break;
                }
        }
 
+#ifdef EXTCMODE
+       make_mode_str(chptr, oldm, oldem, oldl, *pcount, pvar, modebuf, parabuf, bounce);
+#else
        make_mode_str(chptr, oldm, oldl, *pcount, pvar, modebuf, parabuf, bounce);
+#endif
 
 #ifndef NO_OPEROVERRIDE
         if (htrig == 1)
@@ -2402,6 +2993,42 @@ char *pretty_mask(char *mask)
                return make_nick_user_host(NULL, NULL, cp);
        return make_nick_user_host(cp, user, host);
 }
+
+char *trim_str(char *str, int len)
+{
+       int l;
+       if (!str)
+               return NULL;
+       if ((l = strlen(str)) > len)
+       {
+               str += l - len;
+               *str = '*';
+       }
+       return str;
+}
+
+char *clean_ban_mask(char *mask)
+{
+       char *cp;
+       char *user;
+       char *host;
+
+       if ((user = index((cp = mask), '!')))
+               *user++ = '\0';
+       if ((host = rindex(user ? user : cp, '@')))
+       {
+               *host++ = '\0';
+
+               if (!user)
+                       return make_nick_user_host(NULL, trim_str(cp,USERLEN), 
+                               trim_str(host,HOSTLEN));
+       }
+       else if (!user && index(cp, '.'))
+               return make_nick_user_host(NULL, NULL, trim_str(cp,HOSTLEN));
+       return make_nick_user_host(trim_str(cp,NICKLEN), trim_str(user,USERLEN), 
+               trim_str(host,HOSTLEN));
+}
+
 /* Now let _invited_ people join thru bans, +i and +l.
  * Checking if an invite exist could be done only if a block exists,
  * but I'm not too fancy of the complicated structure that'd cause,
@@ -2409,7 +3036,7 @@ char *pretty_mask(char *mask)
  * a user won't have invites on him anyway. -Donwulff
  */
 
-static int can_join(aClient *cptr, aClient *sptr, aChannel *chptr, char *key, char *link, char *parv[])
+int can_join(aClient *cptr, aClient *sptr, aChannel *chptr, char *key, char *link, char *parv[])
 {
         Link *lp;
        Ban *banned;
@@ -2514,7 +3141,7 @@ void clean_channelname(char *cn)
 /*
 ** Return -1 if mask is present and doesnt match our server name.
 */
-static int check_channelmask(aClient *sptr, aClient *cptr, char *chname)
+int check_channelmask(aClient *sptr, aClient *cptr, char *chname)
 {
        char *s;
 
@@ -2537,7 +3164,7 @@ static int check_channelmask(aClient *sptr, aClient *cptr, char *chname)
 **  Get Channel block for i (and allocate a new channel
 **  block, if it didn't exists before).
 */
-static aChannel *get_channel(aClient *cptr, char *chname, int flag)
+aChannel *get_channel(aClient *cptr, char *chname, int flag)
 {
        aChannel *chptr;
        int  len;
@@ -2580,7 +3207,7 @@ static aChannel *get_channel(aClient *cptr, char *chname, int flag)
  * Should U-lined clients have higher limits?   -Donwulff
  */
 
-static void add_invite(aClient *cptr, aChannel *chptr)
+void add_invite(aClient *cptr, aChannel *chptr)
 {
        Link *inv, *tmp;
 
@@ -2654,7 +3281,7 @@ void del_invite(aClient *cptr, aChannel *chptr)
 **  Subtract one user from channel i (and free channel
 **  block, if channel became empty).
 */
-static void sub1_from_channel(aChannel *chptr)
+void sub1_from_channel(aChannel *chptr)
 {
        Ban *ban;
        Link *lp;
@@ -2684,6 +3311,11 @@ static void sub1_from_channel(aChannel *chptr)
                        MyFree(ban->who);
                        free_ban(ban);
                }
+#ifdef EXTCMODE
+               /* free extcmode params */
+               extcmode_free_paramlist(chptr->mode.extmodeparam);
+               chptr->mode.extmodeparam = NULL;
+#endif
                if (chptr->topic)
                        MyFree(chptr->topic);
                if (chptr->topic_nick)
@@ -2863,6 +3495,11 @@ CMD_FUNC(do_join)
                                        ConfigItem_deny_channel *d;
                                        if ((d = Find_channel_allowed(name)))
                                        {
+                                               if (d->warn)
+                                               {
+                                                       sendto_snomask(SNO_EYES, "*** %s tried to join forbidden channel %s",
+                                                               get_client_name(sptr, 1), name);
+                                               }
                                                if (d->reason)
                                                        sendto_one(sptr, 
                                                        ":%s %s %s :*** Can not join %s: %s",
@@ -2907,8 +3544,8 @@ CMD_FUNC(do_join)
 
                if (MyConnect(sptr)) {
                        int breakit = 0;
-                       for (global_i = Hooks[HOOKTYPE_LOCAL_JOIN]; global_i; global_i = global_i->next) {
-                               if((*(global_i->func.intfunc))(cptr,sptr,chptr,parv) > 0) {
+                       for (global_i = Hooks[HOOKTYPE_PRE_LOCAL_JOIN]; global_i; global_i = global_i->next) {
+                               if((*(global_i->func.intfunc))(sptr,chptr,parv) > 0) {
                                        breakit = 1;
                                        break;
                                }
@@ -2920,6 +3557,7 @@ CMD_FUNC(do_join)
                                        sub1_from_channel(chptr);
                                continue;
                        }
+                       RunHook4(HOOKTYPE_LOCAL_JOIN, cptr, sptr,chptr,parv);
                }
 
                /*
@@ -3001,9 +3639,17 @@ CMD_FUNC(do_join)
                        if (chptr->users == 1 && MODES_ON_JOIN)
                        {
                                chptr->mode.mode = MODES_ON_JOIN;
+#ifdef NEWCHFLOODPROT
+                               if (iConf.modes_on_join.floodprot.per)
+                               {
+                                       chptr->mode.floodprot = MyMalloc(sizeof(ChanFloodProt));
+                                       memcpy(chptr->mode.floodprot, &iConf.modes_on_join.floodprot, sizeof(ChanFloodProt));
+                               }
+#else
                                chptr->mode.kmode = iConf.modes_on_join.kmode;
                                chptr->mode.per = iConf.modes_on_join.per;
                                chptr->mode.msgs = iConf.modes_on_join.msgs;
+#endif
                                *modebuf = *parabuf = 0;
                                channel_modes(sptr, modebuf, parabuf, chptr);
                                /* This should probably be in the SJOIN stuff */
@@ -3016,6 +3662,21 @@ CMD_FUNC(do_join)
                        (void)m_names(cptr, sptr, 2, parv);
                }
 
+#ifdef NEWCHFLOODPROT
+               /* I'll explain this only once:
+                * 1. if channel is +f
+                * 2. local client OR synced server
+                * 3. then, increase floodcounter
+                * 4. if we reached the limit AND only if source was a local client.. do the action (+i).
+                * Nr 4 is done because otherwise you would have a noticeflood with 'joinflood detected'
+                * from all servers.
+                */
+               if (chptr->mode.floodprot && (MyClient(sptr) || sptr->srvptr->serv->flags.synced) && 
+                   do_chanflood(chptr->mode.floodprot, FLD_JOIN) && MyClient(sptr))
+               {
+                       do_chanflood_action(chptr, FLD_JOIN, "join");
+               }
+#endif
        }
 
        RET(0)
@@ -3125,7 +3786,12 @@ CMD_FUNC(m_part)
 #endif
                        
                }
-
+               /* +M and not +r? */
+               if ((chptr->mode.mode & MODE_MODREG) && !IsRegNick(sptr) && !IsAnOper(sptr))
+               {
+                       comment = NULL;
+                       parc = 2;
+               }
                if (MyConnect(sptr))
                        RunHook4(HOOKTYPE_LOCAL_PART, cptr, sptr, chptr, comment);
 
@@ -3133,44 +3799,30 @@ CMD_FUNC(m_part)
                {
                        if ((chptr->mode.mode & MODE_AUDITORIUM) && !is_chanownprotop(sptr, chptr))
                        {
-                               if (MyClient(sptr))
+                               if (!comment)
                                {
-                                       if (!comment)
-                                       {
-                                               sendto_chanops_butone(NULL,
-                                                   chptr, ":%s!%s@%s PART %s",
-                                                   sptr->name,
-                                                   sptr->user->username,
-                                                   GetHost(sptr),
-                                                   chptr->chname);
-                                               if (!is_chan_op(sptr, chptr))
-                                                       sendto_one(sptr,
-                                                           ":%s!%s@%s PART %s",
-                                                           sptr->name,
-                                                           sptr->user->
-                                                           username,
-                                                           GetHost(sptr),
-                                                           chptr->chname);
-                                       }
-                                       else
-                                       {
-                                               sendto_chanops_butone(NULL,
-                                                   chptr,
+                                       sendto_chanops_butone(NULL,
+                                           chptr, ":%s!%s@%s PART %s",
+                                           sptr->name, sptr->user->username, GetHost(sptr),
+                                           chptr->chname);
+                                       if (!is_chan_op(sptr, chptr) && MyClient(sptr))
+                                               sendto_one(sptr, ":%s!%s@%s PART %s",
+                                                   sptr->name, sptr->user->username, GetHost(sptr), chptr->chname);
+                               }
+                               else
+                               {
+                                       sendto_chanops_butone(NULL,
+                                           chptr,
+                                           ":%s!%s@%s PART %s %s",
+                                           sptr->name,
+                                           sptr->user->username,
+                                           GetHost(sptr),
+                                           chptr->chname, comment);
+                                       if (!is_chan_op(cptr, chptr) && MyClient(sptr))
+                                               sendto_one(sptr,
                                                    ":%s!%s@%s PART %s %s",
-                                                   sptr->name,
-                                                   sptr->user->username,
-                                                   GetHost(sptr),
+                                                   sptr->name, sptr->user->username, GetHost(sptr),
                                                    chptr->chname, comment);
-                                               if (!is_chan_op(cptr, chptr))
-                                                       sendto_one(sptr,
-                                                           ":%s!%s@%s PART %s %s",
-                                                           sptr->name,
-                                                           sptr->user->
-                                                           username,
-                                                           GetHost(sptr),
-                                                           chptr->chname,
-                                                           comment);
-                                       }
                                }
                        }
                        else
@@ -3351,19 +4003,36 @@ CMD_FUNC(m_kick)
                              attack:
                                if (MyConnect(sptr)) {
                                        int breakit = 0;
-                                       for (global_i = Hooks[HOOKTYPE_LOCAL_KICK]; global_i; global_i = global_i->next) {
-                                               if((*(global_i->func.intfunc))(cptr,sptr,who,chptr,comment) > 0) {
+                                       for (global_i = Hooks[HOOKTYPE_PRE_LOCAL_KICK]; global_i; global_i = global_i->next) {
+                                               if((*(global_i->func.intfunc))(sptr,who,chptr,comment) > 0) {
                                                        breakit = 1;
                                                        break;
                                                }
                                        }
                                        if (breakit)
                                                continue;
+                                       RunHook5(HOOKTYPE_LOCAL_KICK, cptr,sptr,who,chptr,comment);
                                }
                                if (lp)
-                                       sendto_channel_butserv(chptr,
-                                           sptr, ":%s KICK %s %s :%s",
-                                           parv[0], name, who->name, comment);
+                               {
+                                       if ((chptr->mode.mode & MODE_AUDITORIUM) &&
+                                           !(lp->flags & (CHFL_CHANOP|CHFL_CHANPROT|CHFL_CHANOWNER)))
+                                       {
+                                               /* Send it only to chanops & victim */
+                                               sendto_chanops_butone(who, chptr, ":%s!%s@%s KICK %s %s :%s",
+                                                       sptr->name, sptr->user->username, GetHost(sptr),
+                                                       chptr->chname, who->name, comment);
+                                               if (MyClient(who))
+                                                       sendto_one(who, ":%s!%s@%s KICK %s %s :%s",
+                                                               sptr->name, sptr->user->username, GetHost(sptr),
+                                                               chptr->chname, who->name, comment);
+                                       } else {
+                                               /* NORMAL */
+                                               sendto_channel_butserv(chptr,
+                                                   sptr, ":%s KICK %s %s :%s",
+                                                   parv[0], name, who->name, comment);
+                                       }
+                               }
                                sendto_serv_butone_token(cptr, parv[0],
                                    MSG_KICK, TOK_KICK, "%s %s :%s",
                                    name, who->name, comment);
@@ -3376,10 +4045,10 @@ CMD_FUNC(m_kick)
                                sendto_one(sptr,
                                    err_str(ERR_USERNOTINCHANNEL),
                                    me.name, parv[0], user, name);
-                       if (!IsServer(cptr) || !IsULine(sptr))
+                       if (MyClient(cptr))
                                break;
                }               /* loop on parv[2] */
-               if (!IsServer(cptr) || !IsULine(sptr))
+               if (MyClient(cptr))
                        break;
        }                       /* loop on parv[1] */
 
@@ -3546,12 +4215,13 @@ CMD_FUNC(m_topic)
                        if (MyClient(sptr))
                        {
                                Hook *tmphook;
-                               for (tmphook = Hooks[HOOKTYPE_LOCAL_TOPIC]; tmphook; tmphook = tmphook->next) {
-                                       topic = (*(tmphook->func.pcharfunc))(cptr, sptr, chptr, topic);
+                               for (tmphook = Hooks[HOOKTYPE_PRE_LOCAL_TOPIC]; tmphook; tmphook = tmphook->next) {
+                                       topic = (*(tmphook->func.pcharfunc))(sptr, chptr, topic);
                                        if (!topic)
                                                return 0;
                                }
-                       }                                       
+                               RunHook4(HOOKTYPE_LOCAL_TOPIC, cptr, sptr, chptr, topic);
+                       }
                        /* setting a topic */
                        topiClen = strlen(topic);
 #ifndef TOPIC_NICK_IS_NUHOST
@@ -3819,6 +4489,25 @@ void send_list(aClient *cptr, int numsend)
        LOpts *lopt = cptr->user->lopt;
        unsigned int  hashnum;
 
+       /* Begin of /list? then send official channels. */
+       if ((lopt->starthash == 0) && conf_offchans)
+       {
+               ConfigItem_offchans *x;
+               for (x = conf_offchans; x; x = (ConfigItem_offchans *)x->next)
+               {
+                       if (find_channel(x->chname, (aChannel *)NULL))
+                               continue; /* exists, >0 users.. will be sent later */
+                       sendto_one(cptr,
+                           rpl_str(RPL_LIST), me.name,
+                           cptr->name, x->chname,
+                           0,
+#ifdef LIST_SHOW_MODES
+                           "",
+#endif                                     
+                           x->topic ? x->topic : "");
+               }
+       }
+
        for (hashnum = lopt->starthash; hashnum < CH_MAX; hashnum++)
        {
                if (numsend > 0)
@@ -3924,6 +4613,7 @@ int  check_for_chan_flood(aClient *cptr, aClient *sptr, aChannel *chptr)
 {
        Membership *lp;
        MembershipL *lp2;
+       int c_limit, t_limit, banthem;
 
        if (!MyClient(sptr))
                return 0;
@@ -3934,18 +4624,29 @@ int  check_for_chan_flood(aClient *cptr, aClient *sptr, aChannel *chptr)
 
        if (!(lp = find_membership_link(sptr->user->channel, chptr)))
                return 0;
-       
-       if ((chptr->mode.msgs < 1) || (chptr->mode.per < 1))
-               return 0;
 
        lp2 = (MembershipL *) lp;
+
+#ifdef NEWCHFLOODPROT
+       if (!chptr->mode.floodprot || !chptr->mode.floodprot->l[FLD_TEXT])
+               return 0;
+       c_limit = chptr->mode.floodprot->l[FLD_TEXT];
+       t_limit = chptr->mode.floodprot->per;
+       banthem = (chptr->mode.floodprot->a[FLD_TEXT] == 'b') ? 1 : 0;
+#else
+       if ((chptr->mode.msgs < 1) || (chptr->mode.per < 1))
+               return 0;
+       c_limit = chptr->mode.msgs;
+       t_limit = chptr->mode.per;
+       banthem = chptr->mode.kmode;
+#endif
        /* if current - firstmsgtime >= mode.per, then reset,
         * if nummsg > mode.msgs then kick/ban
         */
        Debug((DEBUG_ERROR, "Checking for flood +f: firstmsg=%d (%ds ago), new nmsgs: %d, limit is: %d:%d",
                lp2->flood.firstmsg, TStime() - lp2->flood.firstmsg, lp2->flood.nmsg + 1,
-               chptr->mode.msgs, chptr->mode.per));
-       if ((TStime() - lp2->flood.firstmsg) >= chptr->mode.per)
+               c_limit, t_limit));
+       if ((TStime() - lp2->flood.firstmsg) >= t_limit)
        {
                /* reset */
                lp2->flood.firstmsg = TStime();
@@ -3956,13 +4657,13 @@ int  check_for_chan_flood(aClient *cptr, aClient *sptr, aChannel *chptr)
        /* increase msgs */
        lp2->flood.nmsg++;
 
-       if ((lp2->flood.nmsg) > chptr->mode.msgs)
+       if ((lp2->flood.nmsg) > c_limit)
        {
                char comment[1024], mask[1024];
                ircsprintf(comment,
                    "Flooding (Limit is %i lines per %i seconds)",
-                   chptr->mode.msgs, chptr->mode.per);
-               if (chptr->mode.kmode == 1)
+                   c_limit, t_limit);
+               if (banthem)
                {               /* ban. */
                        ircsprintf(mask, "*!*@%s", GetHost(sptr));
                        add_banid(&me, chptr, mask);
@@ -4159,7 +4860,7 @@ CMD_FUNC(m_list)
                                  nolist = lp;
                                  DupString(lp->value.cp, name + 1);
                          }
-                         else if (strchr(name, '*') || strchr(name, '*'))
+                         else if (strchr(name, '*') || strchr(name, '?'))
                          {
                                  doall = 1;
                                  lp = make_link();
@@ -4254,7 +4955,8 @@ CMD_FUNC(m_names)
        {
                if (*s == ',')
                {
-                       para[TRUNCATED_NAMES] = '\0';
+                       if (strlen(para) > TRUNCATED_NAMES)
+                               para[TRUNCATED_NAMES] = '\0';
                        sendto_realops("names abuser %s %s",
                            get_client_name(sptr, FALSE), para);
                        sendto_one(sptr, err_str(ERR_TOOMANYTARGETS),
@@ -4477,7 +5179,7 @@ CMD_FUNC(m_knock)
                sendto_one(sptr, err_str(ERR_CANNOTKNOCK),
                    me.name,
                    sptr->name,
-                   chptr->chname, "You can not get invited anyways! (+I)");
+                   chptr->chname, "The channel does not allow invites (+V)");
 
                return 0;
        }
@@ -4490,6 +5192,11 @@ CMD_FUNC(m_knock)
 
        sendto_one(sptr, ":%s %s %s :Knocked on %s", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE",
            sptr->name, chptr->chname);
+
+#ifdef NEWCHFLOODPROT
+       if (chptr->mode.floodprot && do_chanflood(chptr->mode.floodprot, FLD_KNOCK) && MyClient(sptr))
+               do_chanflood_action(chptr, FLD_KNOCK, "knock");
+#endif
        return 0;
 }
 
@@ -4703,13 +5410,23 @@ CMD_FUNC(m_sjoin)
                modebuf[1] = '\0';
                parabuf[0] = '\0';
                b = 1;
-               for (ban = chptr->banlist; ban; ban = ban->next)
+               while(chptr->banlist)
                {
+                       ban = chptr->banlist;
                        Addit('b', ban->banstr);
+                       chptr->banlist = ban->next;
+                       MyFree(ban->banstr);
+                       MyFree(ban->who);
+                       free_ban(ban);
                }
-               for (ban = chptr->exlist; ban; ban = ban->next)
+               while(chptr->exlist)
                {
+                       ban = chptr->exlist;
                        Addit('e', ban->banstr);
+                       chptr->exlist = ban->next;
+                       MyFree(ban->banstr);
+                       MyFree(ban->who);
+                       free_ban(ban);
                }
                for (lp = chptr->members; lp; lp = lp->next)
                {
@@ -4873,9 +5590,19 @@ CMD_FUNC(m_sjoin)
 #endif
                        } else {
                                add_user_to_channel(chptr, acptr, modeflags);
-                               sendto_channel_butserv(chptr, acptr,
-                                   ":%s JOIN :%s", nick,
-                                   chptr->chname);
+                               if (chptr->mode.mode & MODE_AUDITORIUM)
+                               {
+                                       if (modeflags & (CHFL_CHANOP|CHFL_CHANPROT|CHFL_CHANOWNER))
+                                               sendto_channel_butserv(chptr, acptr, ":%s JOIN :%s", nick, chptr->chname);
+                                       else
+                                               sendto_chanops_butone(NULL, chptr, ":%s!%s@%s JOIN :%s",
+                                                       acptr->name, acptr->user->username, GetHost(acptr), chptr->chname);
+                               } else
+                                       sendto_channel_butserv(chptr, acptr, ":%s JOIN :%s", nick, chptr->chname);
+#ifdef NEWCHFLOODPROT
+                               if (chptr->mode.floodprot && sptr->serv->flags.synced)
+                               do_chanflood(chptr->mode.floodprot, FLD_JOIN);
+#endif
                        }
                        sendto_serv_butone_sjoin(cptr, ":%s JOIN %s",
                            nick, chptr->chname);
@@ -4945,6 +5672,18 @@ CMD_FUNC(m_sjoin)
        {
                aCtab *acp;
                bcopy(&chptr->mode, &oldmode, sizeof(Mode));
+#ifdef EXTCMODE
+               /* Fun.. we have to duplicate all extended modes too... */
+               oldmode.extmodeparam = NULL;
+               oldmode.extmodeparam = extcmode_duplicate_paramlist(chptr->mode.extmodeparam);
+#endif
+#ifdef NEWCHFLOODPROT
+               if (chptr->mode.floodprot)
+               {
+                       oldmode.floodprot = MyMalloc(sizeof(ChanFloodProt));
+                       memcpy(oldmode.floodprot, chptr->mode.floodprot, sizeof(ChanFloodProt));
+               }
+#endif
                /* merge the modes */
                strlcpy(modebuf, parv[3], sizeof modebuf);
                parabuf[0] = '\0';
@@ -4977,6 +5716,13 @@ CMD_FUNC(m_sjoin)
                {
                        Addit('L', oldmode.link);
                }
+#ifdef NEWCHFLOODPROT
+               if (oldmode.floodprot && !chptr->mode.floodprot)
+               {
+                       char *x = channel_modef_string(oldmode.floodprot);
+                       Addit('f', x);
+               }
+#else
                if ((oldmode.msgs || oldmode.per || oldmode.kmode)
                    && ((chptr->mode.msgs == 0) && (chptr->mode.per == 0)
                    && (chptr->mode.kmode == 0)))
@@ -4986,7 +5732,29 @@ CMD_FUNC(m_sjoin)
                            oldmode.msgs, oldmode.per);
                        Addit('f', modeback);
                }
+#endif
 
+#ifdef EXTCMODE
+               /* First, check if we have something they don't have..
+                * note that: oldmode.* = us, chptr->mode.* = them.
+                */
+               for (i=0; i <= Channelmode_highest; i++)
+               {
+                       if ((Channelmode_Table[i].flag) &&
+                           (oldmode.extmode & Channelmode_Table[i].mode) &&
+                           !(chptr->mode.extmode & Channelmode_Table[i].mode))
+                       {
+                               if (Channelmode_Table[i].paracount)
+                               {
+                                       char *parax = Channelmode_Table[i].get_param(extcmode_get_struct(oldmode.extmodeparam, Channelmode_Table[i].flag));
+                                       Addit(Channelmode_Table[i].flag, parax);
+                               } else {
+                                       Addsingle(Channelmode_Table[i].flag);
+                               }
+                       }
+               }
+#endif
+               /* Add single char modes... */
                for (acp = cFlagTab; acp->mode; acp++)
                {
                        if ((oldmode.mode & acp->mode) &&
@@ -5025,6 +5793,13 @@ CMD_FUNC(m_sjoin)
                {
                        Addit('L', chptr->mode.link);
                }
+#ifdef NEWCHFLOODPROT
+               if (chptr->mode.floodprot && !oldmode.floodprot)
+               {
+                       char *x = channel_modef_string(chptr->mode.floodprot);
+                       Addit('f', x);
+               }
+#else
                if (!(oldmode.msgs || oldmode.per || oldmode.kmode)
                    && (chptr->mode.msgs || chptr->mode.per
                    || chptr->mode.kmode))
@@ -5033,8 +5808,30 @@ CMD_FUNC(m_sjoin)
                            (chptr->mode.kmode == 1 ? "*" : ""),
                            chptr->mode.msgs, chptr->mode.per);
                        Addit('f', modeback);
+               }
+#endif
 
+#ifdef EXTCMODE
+               /* Now, check if they have something we don't have..
+                * note that: oldmode.* = us, chptr->mode.* = them.
+                */
+               for (i=0; i <= Channelmode_highest; i++)
+               {
+                       if ((Channelmode_Table[i].flag) &&
+                           !(oldmode.extmode & Channelmode_Table[i].mode) &&
+                           (chptr->mode.extmode & Channelmode_Table[i].mode))
+                       {
+                               if (Channelmode_Table[i].paracount)
+                               {
+                                       char *parax = Channelmode_Table[i].get_param(extcmode_get_struct(chptr->mode.extmodeparam,Channelmode_Table[i].flag));
+                                       Addit(Channelmode_Table[i].flag, parax);
+                               } else {
+                                       Addsingle(Channelmode_Table[i].flag);
+                               }
+                       }
                }
+#endif
+
                /* now, if we had diffent para modes - this loop really could be done better, but */
 
                /* do we have an difference? */
@@ -5077,6 +5874,20 @@ CMD_FUNC(m_sjoin)
                /* 
                 * run a max on each?
                 */
+#ifdef NEWCHFLOODPROT
+               if (chptr->mode.floodprot && oldmode.floodprot)
+               {
+                       char *x;
+                       int i;
+                       chptr->mode.floodprot->per = MAX(chptr->mode.floodprot->per, oldmode.floodprot->per);
+                       for (i=0; i < NUMFLD; i++)
+                               chptr->mode.floodprot->l[i] = MAX(chptr->mode.floodprot->l[i], oldmode.floodprot->l[i]);
+                       for (i=0; i < NUMFLD; i++)
+                               chptr->mode.floodprot->a[i] = MAX(chptr->mode.floodprot->a[i], oldmode.floodprot->a[i]);
+                       x = channel_modef_string(chptr->mode.floodprot);
+                       Addit('f', x);
+               }
+#else
                if ((oldmode.kmode != chptr->mode.kmode)
                    || (oldmode.msgs != chptr->mode.msgs)
                    || (oldmode.per != chptr->mode.per))
@@ -5095,6 +5906,50 @@ CMD_FUNC(m_sjoin)
                                Addit('f', modeback);
                        }
                }
+#endif
+
+#ifdef EXTCMODE
+               /* Now, check for any param differences in extended channel modes..
+                * note that: oldmode.* = us, chptr->mode.* = them.
+                * if we win: copy oldmode to chptr mode, if they win: send the mode
+                */
+               for (i=0; i <= Channelmode_highest; i++)
+               {
+                       if (Channelmode_Table[i].flag && Channelmode_Table[i].paracount &&
+                           (oldmode.extmode & Channelmode_Table[i].mode) &&
+                           (chptr->mode.extmode & Channelmode_Table[i].mode))
+                       {
+                               int r;
+                               char *parax;
+                               r = Channelmode_Table[i].sjoin_check(chptr, extcmode_get_struct(oldmode.extmodeparam,Channelmode_Table[i].flag), extcmode_get_struct(chptr->mode.extmodeparam, Channelmode_Table[i].flag));
+                               switch (r)
+                               {
+                                       case EXSJ_WEWON:
+                                       {
+                                               CmodeParam *p = extcmode_get_struct(oldmode.extmodeparam, Channelmode_Table[i].flag);
+                                               CmodeParam *r;
+                                               parax = Channelmode_Table[i].get_param(p);
+                                               Debug((DEBUG_DEBUG, "sjoin: we won: '%s'", parax));
+                                               r = Channelmode_Table[i].put_param(p, parax);
+                                               if (r != p)
+                                                       AddListItem(r, chptr->mode.extmodeparam);
+                                               break;
+                                       }
+                                       case EXSJ_THEYWON:
+                                               parax = Channelmode_Table[i].get_param(extcmode_get_struct(chptr->mode.extmodeparam,Channelmode_Table[i].flag));
+                                               Debug((DEBUG_DEBUG, "sjoin: they won: '%s'", parax));
+                                               Addit(Channelmode_Table[i].flag, parax);
+                                               break;
+                                       case EXSJ_SAME:
+                                               Debug((DEBUG_DEBUG, "sjoin: equal"));
+                                               break;
+                                       default:
+                                               ircd_log(LOG_ERROR, "channel.c:m_sjoin:param diff checker: got unk. retval 0x%x??", r);
+                                               break;
+                               }
+                       }
+               }
+#endif
 
                Addsingle('\0');
 
@@ -5107,6 +5962,19 @@ CMD_FUNC(m_sjoin)
                        sendto_channel_butserv(chptr, sptr, ":%s MODE %s %s %s",
                            sptr->name, chptr->chname, modebuf, parabuf);
                }
+#ifdef EXTCMODE
+               /* free the oldmode.* crap :( */
+               extcmode_free_paramlist(oldmode.extmodeparam);
+               oldmode.extmodeparam = NULL; /* just to be sure ;) */
+#endif
+#ifdef NEWCHFLOODPROT
+               /* and the oldmode.floodprot struct too... :/ */
+               if (oldmode.floodprot)
+               {
+                       free(oldmode.floodprot);
+                       oldmode.floodprot = NULL;
+               }
+#endif
        }
 
        /* we should be synched by now, */
@@ -5621,3 +6489,74 @@ char flagbuf[8]; /* For holding "qohva" and "*~@%+" */
                }
        }
 }
+
+#ifdef NEWCHFLOODPROT
+int do_chanflood(ChanFloodProt *chp, int what)
+{
+
+       if (!chp || !chp->l[what]) /* no +f or not restricted */
+               return 0;
+       if (TStime() - chp->t[what] >= chp->per)
+       {
+               chp->t[what] = TStime();
+               chp->c[what] = 1;
+       } else
+       {
+               chp->c[what]++;
+               if ((chp->c[what] > chp->l[what]) &&
+                   (TStime() - chp->t[what] < chp->per))
+               {
+                       /* reset it too (makes it easier for chanops to handle the situation) */
+                       /*
+                        *XXchp->t[what] = TStime();
+                        *XXchp->c[what] = 1;
+                        * 
+                        * BAD.. there are some situations where we might 'miss' a flood
+                        * because of this. The reset has been moved to -i,-m,-N,-C,etc.
+                       */
+                       return 1; /* flood detected! */
+               }
+       }
+       return 0;
+}
+
+void do_chanflood_action(aChannel *chptr, int what, char *text)
+{
+long modeflag = 0;
+aCtab *tab = &cFlagTab[0];
+char m;
+
+       m = chptr->mode.floodprot->a[what];
+       if (!m)
+               return;
+
+       /* [TODO: add extended channel mode support] */
+       
+       while(tab->mode != 0x0)
+       {
+               if (tab->flag == m)
+               {
+                       modeflag = tab->mode;
+                       break;
+               }
+               tab++;
+       }
+
+       if (!modeflag)
+               return;
+               
+       if (!(chptr->mode.mode & modeflag))
+       {
+               char comment[1024], target[CHANNELLEN + 8];
+               ircsprintf(comment, "*** Channel %sflood detected (limit is %d per %d seconds), setting mode +%c",
+                       text, chptr->mode.floodprot->l[what], chptr->mode.floodprot->per, m);
+               ircsprintf(target, "~&@%%%s", chptr->chname);
+               sendto_channelprefix_butone_tok(NULL, &me, chptr,
+                       PREFIX_HALFOP|PREFIX_OP|PREFIX_ADMIN|PREFIX_OWNER,
+                       MSG_NOTICE, TOK_NOTICE, target, comment);
+               sendto_serv_butone(&me, ":%s MODE %s +%c 0", me.name, chptr->chname, m);
+               sendto_channel_butserv(chptr, &me, ":%s MODE %s +%c", me.name, chptr->chname, m);
+               chptr->mode.mode |= modeflag;
+       }
+}
+#endif
index 5f44ee70e4e337eea7423555de4ab7879f13e327..c44a7bb2ba6e9760282ed4adb25babfa387822fb 100644 (file)
@@ -61,6 +61,8 @@ Event *EventAddEx(Module *module, char *name, long every, long howmany,
        
        if (!name || (every < 0) || (howmany < 0) || !event)
        {
+               if (module)
+                       module->errorcode = MODERR_INVALID;
                return NULL;
        }
        newevent = (Event *) MyMallocEx(sizeof(Event));
@@ -78,6 +80,7 @@ Event *EventAddEx(Module *module, char *name, long every, long howmany,
                eventobj->object.event = newevent;
                eventobj->type = MOBJ_EVENT;
                AddListItem(eventobj, module->objects);
+               module->errorcode = MODERR_NOERROR;
        }
        return newevent;
        
@@ -126,7 +129,11 @@ Event      *EventFind(char *name)
 
 int EventMod(Event *event, EventInfo *mods) {
        if (!event || !mods)
+       {
+               if (event && event->owner)
+                       event->owner->errorcode = MODERR_INVALID;
                return -1;
+       }
 
        if (mods->flags & EMOD_EVERY)
                event->every = mods->every;
@@ -140,6 +147,8 @@ int EventMod(Event *event, EventInfo *mods) {
                event->event = mods->event;
        if (mods->flags & EMOD_DATA)
                event->data = mods->data;
+       if (event->owner)
+               event->owner->errorcode = MODERR_NOERROR;
        return 0;
 }
 
diff --git a/src/extcmodes.c b/src/extcmodes.c
new file mode 100644 (file)
index 0000000..2218ace
--- /dev/null
@@ -0,0 +1,227 @@
+/************************************************************************
+ *   IRC - Internet Relay Chat, s_unreal.c
+ *   (C) 2003 Bram Matthys (Syzop) and the UnrealIRCd Team
+ *
+ *   See file AUTHORS in IRC package for additional names of
+ *   the programmers. 
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 1, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "struct.h"
+#include "common.h"
+#include "sys.h"
+#include "numeric.h"
+#include "msg.h"
+#include "proto.h"
+#include "channel.h"
+#include "version.h"
+#include <time.h>
+#ifdef _WIN32
+#include <sys/timeb.h>
+#endif
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _WIN32
+#include <io.h>
+#endif
+#include <fcntl.h>
+#include "h.h"
+
+#ifdef EXTCMODE
+
+extern char cmodestring[512];
+
+extern void make_cmodestr(void);
+
+char extchmstr[4][64];
+
+Cmode *Channelmode_Table = NULL;
+unsigned short Channelmode_highest = 0;
+
+void make_extcmodestr()
+{
+char *p;
+int i;
+       
+       extchmstr[0][0] = extchmstr[1][0] = extchmstr[2][0] = extchmstr[3][0] = '\0';
+       
+       /* type 1: lists (like b/e) */
+       /* [NOT IMPLEMENTED IN EXTCMODES] */
+
+       /* type 2: 1 par to set/unset */
+       /* [NOT IMPLEMENTED] */
+
+       /* type 3: 1 param to set, 0 params to unset */
+       p = extchmstr[2];
+       for (i=0; i <= Channelmode_highest; i++)
+               if (Channelmode_Table[i].paracount && Channelmode_Table[i].flag)
+                       *p++ = Channelmode_Table[i].flag;
+       *p = '\0';
+       
+       /* type 4: paramless modes */
+       p = extchmstr[3];
+       for (i=0; i <= Channelmode_highest; i++)
+               if (!Channelmode_Table[i].paracount && Channelmode_Table[i].flag)
+                       *p++ = Channelmode_Table[i].flag;
+       *p = '\0';
+       printf("dect: %s/%s/%s/%s\n", extchmstr[0], extchmstr[1], extchmstr[2], extchmstr[3]);
+}
+
+
+void   extcmode_init(void)
+{
+       Cmode_t val = 1;
+       int     i;
+       Channelmode_Table = (Cmode *)MyMalloc(sizeof(Cmode) * EXTCMODETABLESZ);
+       bzero(Channelmode_Table, sizeof(Cmode) * EXTCMODETABLESZ);
+       for (i = 0; i < EXTCMODETABLESZ; i++)
+       {
+               Channelmode_Table[i].mode = val;
+               val *= 2;
+       }
+       Channelmode_highest = 0;
+       memset(&extchmstr, 0, sizeof(extchmstr));
+}
+
+Cmode *CmodeAdd(Module *reserved, CmodeInfo req, Cmode_t *mode)
+{
+       short i = 0, j = 0;
+
+       while (i < EXTCMODETABLESZ)
+       {
+               if (!Channelmode_Table[i].flag)
+                       break;
+               i++;
+       }
+       if (i == EXTCMODETABLESZ)
+       {
+               Debug((DEBUG_DEBUG, "CmodeAdd failed, no space"));
+               return NULL;
+       }
+       *mode = Channelmode_Table[i].mode;
+       /* Update extended channel mode table highest */
+       Channelmode_Table[i].flag = req.flag;
+       Channelmode_Table[i].paracount = req.paracount;
+       Channelmode_Table[i].is_ok = req.is_ok;
+       Channelmode_Table[i].put_param = req.put_param;
+       Channelmode_Table[i].get_param = req.get_param;
+       Channelmode_Table[i].conv_param = req.conv_param;
+       Channelmode_Table[i].free_param = req.free_param;
+       Channelmode_Table[i].dup_struct = req.dup_struct;
+       Channelmode_Table[i].sjoin_check = req.sjoin_check;
+       for (j = 0; j < EXTCMODETABLESZ; j++)
+               if (Channelmode_Table[j].flag)
+                       if (j > Channelmode_highest)
+                               Channelmode_highest = j;
+       make_cmodestr();
+       make_extcmodestr();
+       return &(Channelmode_Table[i]);
+}
+
+void CmodeDel(Cmode *cmode)
+{
+       /* TODO: remove from all channel */
+       if (cmode)
+               cmode->flag = '\0';
+       /* Not unloadable, so module object support is not needed (yet) */
+}
+
+/** searches in chptr extmode parameters and returns entry or NULL. */
+CmodeParam *extcmode_get_struct(CmodeParam *p, char ch)
+{
+
+       while(p)
+       {
+               if (p->flag == ch)
+                       return p;
+               p = p->next;
+       }
+       return NULL;
+}
+
+/* bit inefficient :/ */
+CmodeParam *extcmode_duplicate_paramlist(CmodeParam *lst)
+{
+       int i;
+       Cmode *tbl;
+       CmodeParam *head = NULL, *n;
+
+       while(lst)
+       {
+               tbl = NULL;
+               for (i=0; i <= Channelmode_highest; i++)
+               {
+                       if (Channelmode_Table[i].flag == lst->flag)
+                       {
+                               tbl = &Channelmode_Table[i]; /* & ? */
+                               break;
+                       }
+               }
+               n = tbl->dup_struct(lst);
+               if (head)
+               {
+                       AddListItem(n, head);
+               } else {
+                       head = n;
+               }
+               lst = lst->next;
+       }
+       return head;
+}
+
+void extcmode_free_paramlist(CmodeParam *lst)
+{
+       CmodeParam *n;
+       int i;
+       Cmode *tbl;
+
+       while(lst)
+       {
+               /* first remove it from the list... */
+               n = lst;
+               DelListItem(n, lst);
+               /* then hunt for the param free function and let it free */
+               tbl = NULL;
+               for (i=0; i <= Channelmode_highest; i++)
+               {
+                       if (Channelmode_Table[i].flag == n->flag)
+                       {
+                               tbl = &Channelmode_Table[i]; /* & ? */
+                               break;
+                       }
+               }
+               tbl->free_param(n);
+       }
+}
+
+int extcmode_default_requirechop(aClient *cptr, aChannel *chptr, char *para, int checkt, int what)
+{
+       if (IsPerson(cptr) && is_chan_op(cptr, chptr))
+               return 1;
+       return 0;
+}
+
+int extcmode_default_requirehalfop(aClient *cptr, aChannel *chptr, char *para, int checkt, int what)
+{
+       if (IsPerson(cptr) &&
+           (is_chan_op(cptr, chptr) || is_half_op(cptr, chptr)))
+               return 1;
+       return 0;
+}
+
+#endif /* EXTCMODE */
index f6c939516e22189ef7f3ee8b8d720ac6ed4b6559..b3b1b07ccf52b4d2cc366a838931c15964c3bfc1 100644 (file)
 #include "h.h"
 #include "config.h"
 #include "fdlist.h"
+#include "proto.h"
 #include <string.h>
 
+extern fdlist default_fdlist;
+extern fdlist busycli_fdlist;
+extern fdlist serv_fdlist;
+extern fdlist oper_fdlist;
+
 void addto_fdlist(int fd, fdlist * listp)
 {
        int  index;
 
+       /* I prefer this little 5-cpu-cycles-check over memory corruption. -- Syzop */
+       if ((fd < 0) || (fd >= MAXCONNECTIONS))
+       {
+               sendto_realops("[BUG] trying to add fd #%d to 0x%x (%x/%x/%x/%x), range is 0..%d",
+                       fd, listp, &default_fdlist, &busycli_fdlist, &serv_fdlist, &oper_fdlist,
+                       MAXCONNECTIONS);
+               ircd_log(LOG_ERROR, "[BUG] trying to add fd #%d to 0x%x (%x/%x/%x/%x), range is 0..%d",
+                       fd, listp, &default_fdlist, &busycli_fdlist, &serv_fdlist, &oper_fdlist,
+                       MAXCONNECTIONS);
+               return;
+       }
+
        if ((index = ++listp->last_entry) >= MAXCONNECTIONS)
        {
                /*
@@ -49,6 +67,18 @@ void delfrom_fdlist(int fd, fdlist * listp)
 {
        int  i;
 
+       /* I prefer this little 5-cpu-cycles-check over memory corruption. -- Syzop */
+       if ((fd < 0) || (fd >= MAXCONNECTIONS))
+       {
+               sendto_realops("[BUG] trying to remove fd #%d to 0x%x (%x/%x/%x/%x), range is 0..%d",
+                       fd, listp, &default_fdlist, &busycli_fdlist, &serv_fdlist, &oper_fdlist,
+                       MAXCONNECTIONS);
+               ircd_log(LOG_ERROR, "[BUG] trying to remove fd #%d to 0x%x (%x/%x/%x/%x), range is 0..%d",
+                       fd, listp, &default_fdlist, &busycli_fdlist, &serv_fdlist, &oper_fdlist,
+                       MAXCONNECTIONS);
+               return;
+       }
+
        for (i = listp->last_entry; i; i--)
        {
                if (listp->entry[i] == fd)
index 9d339b3f38f61f07b8ca654acede2ea2cdb46047..efe9d3ad6eab5d6e1e33a224517fdaa774a1b2d9 100644 (file)
@@ -106,6 +106,8 @@ aClient *client = &me;              /* Pointer to beginning of Client list */
 extern char backupbuf[8192];
 #ifdef _WIN32
 extern void CleanUpSegv(int sig);
+extern SERVICE_STATUS_HANDLE IRCDStatusHandle;
+extern SERVICE_STATUS IRCDStatus;
 #endif
 #ifndef NO_FDLIST
 fdlist default_fdlist;
@@ -208,24 +210,25 @@ VOIDSIG s_die()
 #ifdef _WIN32
        int  i;
        aClient *cptr;
-#endif
-       unload_all_modules();
-#ifndef _WIN32
-       flush_connections(&me);
-#else
-       for (i = LastSlot; i >= 0; i--)
-               if ((cptr = local[i]) && DBufLength(&cptr->sendQ) > 0)
-                       (void)send_queued(cptr);
        if (!IsService)
-#endif
-       exit(-1);
-#ifdef _WIN32
+       {
+               unload_all_modules();
+               for (i = LastSlot; i >= 0; i--)
+                       if ((cptr = local[i]) && DBufLength(&cptr->sendQ) > 0)
+                               (void)send_queued(cptr);
+               
+               exit(-1);
+       }
        else {
                SERVICE_STATUS status;
                SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
                SC_HANDLE hService = OpenService(hSCManager, "UnrealIRCd", SERVICE_STOP); 
                ControlService(hService, SERVICE_CONTROL_STOP, &status);
        }
+#else
+       unload_all_modules();
+       flush_connections(&me);
+       exit(-1);
 #endif
 }
 
@@ -340,8 +343,11 @@ void server_reboot(char *mesg)
        (void)execv(MYNAME, myargv);
 #else
        close_connections();
-       CleanUp();
-       (void)execv(myargv[0], myargv);
+       if (!IsService)
+       {
+               CleanUp();
+               (void)execv(myargv[0], myargv);
+       }
 #endif
 #ifndef _WIN32
        Debug((DEBUG_FATAL, "Couldn't restart server: %s", strerror(errno)));
@@ -350,6 +356,26 @@ void server_reboot(char *mesg)
            strerror(GetLastError())));
 #endif
        unload_all_modules();
+#ifdef _WIN32
+       if (IsService)
+       {
+               SERVICE_STATUS status;
+               PROCESS_INFORMATION pi;
+               STARTUPINFO si;
+               char fname[MAX_PATH];
+               bzero(&status, sizeof(status));
+               bzero(&si, sizeof(si));
+               IRCDStatus.dwCurrentState = SERVICE_STOP_PENDING;
+               SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
+               GetModuleFileName(GetModuleHandle(NULL), fname, MAX_PATH);
+               CreateProcess(fname, "restartsvc", NULL, NULL, FALSE, 
+                       0, NULL, NULL, &si, &pi);
+               IRCDStatus.dwCurrentState = SERVICE_STOPPED;
+               SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
+               ExitProcess(0);
+       }
+       else
+#endif
        exit(-1);
 }
 
@@ -830,6 +856,9 @@ int InitwIRCD(int argc, char *argv[])
        setup_signals();
        init_ircstats();
        umode_init();
+#ifdef EXTCMODE
+       extcmode_init();
+#endif
        clear_scache_hash_table();
 #ifdef FORCE_CORE
        corelim.rlim_cur = corelim.rlim_max = RLIM_INFINITY;
@@ -987,7 +1016,7 @@ int InitwIRCD(int argc, char *argv[])
                }
        }
 
-#ifndef        CHROOT
+#ifndef        CHROOTDIR
        if (chdir(dpath)) {
 # ifndef _WIN32
                perror("chdir");
@@ -1070,6 +1099,9 @@ int InitwIRCD(int argc, char *argv[])
        load_tunefile();
        make_umodestr();
        make_cmodestr();
+#ifdef EXTCMODE
+       make_extcmodestr();
+#endif
        if (!find_Command_simple("AWAY") || !find_Command_simple("KILL") ||
                !find_Command_simple("OPER") || !find_Command_simple("PING"))
        {
index 30b747a8811779ef6715186bca4ffcee5e73ce62..91c55a6c00c7e1c5fdfe78ef686c2029f57e8283 100644 (file)
@@ -177,15 +177,15 @@ anUser *make_user(aClient *cptr)
        user = cptr->user;
        if (!user)
        {
-               user = (anUser *)MyMalloc(sizeof(anUser));
+               user = (anUser *)MyMallocEx(sizeof(anUser));
 #ifdef DEBUGMODE
                users.inuse++;
 #endif
                user->swhois = NULL;
                user->away = NULL;
 #ifdef NO_FLOOD_AWAY
-               user->last_away = 0;
-               user->away_count = 0;
+               user->flood.away_t = 0;
+               user->flood.away_c = 0;
 #endif
                user->refcnt = 1;
                user->joined = 0;
@@ -211,7 +211,7 @@ aServer *make_server(aClient *cptr)
 
        if (!serv)
        {
-               serv = (aServer *)MyMalloc(sizeof(aServer));
+               serv = (aServer *)MyMallocEx(sizeof(aServer));
 #ifdef DEBUGMODE
                servs.inuse++;
 #endif
@@ -275,7 +275,10 @@ void remove_client_from_list(aClient *cptr)
                        IRCstats.invisible--;
                }
                if (IsOper(cptr) && !IsHideOper(cptr))
+               {
                        IRCstats.operators--;
+                       VERIFY_OPERCOUNT(cptr, "rmvlist");
+               }
                IRCstats.clients--;
                if (cptr->srvptr && cptr->srvptr->serv)
                        cptr->srvptr->serv->users--;
index d4425655886574528d376ac931c3d256c62af2ee..6a623106e8e5a923dbd18a0af54e6c4f8e0a2b36 100644 (file)
@@ -89,7 +89,8 @@ Module *Module_Find(char *name)
        
        for (p = Modules; p; p = p->next)
        {
-               if (!(p->flags & MODFLAG_TESTING) || (p->flags & MODFLAG_DELAYED))
+               if (!(p->options & MOD_OPT_PERM) &&
+                   (!(p->flags & MODFLAG_TESTING) || (p->flags & MODFLAG_DELAYED)))
                        continue;
                if (!strcmp(p->header->name, name))
                {
@@ -120,6 +121,7 @@ char  *Module_Create(char *path_)
        ModuleHeader    *mod_header;
        int             ret = 0;
        Module          *mod = NULL, **Mod_Handle = NULL;
+       int *x;
        int betaversion,tag;
        Debug((DEBUG_DEBUG, "Attempting to load module from %s",
               path_));
@@ -258,6 +260,8 @@ Module *Module_make(ModuleHeader *header,
        modp->header = header;
        modp->dll = mod;
        modp->flags = MODFLAG_NONE;
+       modp->options = 0;
+       modp->errorcode = MODERR_NOERROR;
        modp->children = NULL;
        modp->modinfo.size = sizeof(ModuleInfo);
        modp->modinfo.module_load = 0;
@@ -310,7 +314,7 @@ void Unload_all_loaded_modules(void)
        for (mi = Modules; mi; mi = next)
        {
                next = mi->next;
-               if (!(mi->flags & MODFLAG_LOADED) || (mi->flags & MODFLAG_DELAYED))
+               if (!(mi->flags & MODFLAG_LOADED) || (mi->flags & MODFLAG_DELAYED) || (mi->options & MOD_OPT_PERM))
                        continue;
                irc_dlsym(mi->dll, "Mod_Unload", Mod_Unload);
                if (Mod_Unload)
@@ -341,6 +345,12 @@ void Unload_all_loaded_modules(void)
                        else if (objs->type == MOBJ_VERSIONFLAG) {
                                VersionflagDel(objs->object.versionflag, mi);
                        }
+                       else if (objs->type == MOBJ_SNOMASK) {
+                               SnomaskDel(objs->object.snomask);
+                       }
+                       else if (objs->type == MOBJ_UMODE) {
+                               UmodeDel(objs->object.umode);
+                       }
                }
                for (child = mi->children; child; child = childnext)
                {
@@ -384,6 +394,13 @@ void Unload_all_testing_modules(void)
                        else if (objs->type == MOBJ_VERSIONFLAG) {
                                VersionflagDel(objs->object.versionflag, mi);
                        }
+                       else if (objs->type == MOBJ_SNOMASK) {
+                               SnomaskDel(objs->object.snomask);
+                       }
+                       else if (objs->type == MOBJ_UMODE) {
+                               UmodeDel(objs->object.umode);
+                       }
+
                }
                for (child = mi->children; child; child = childnext)
                {
@@ -433,6 +450,12 @@ int    Module_free(Module *mod)
                else if (objs->type == MOBJ_VERSIONFLAG) {
                        VersionflagDel(objs->object.versionflag, mod);
                }
+               else if (objs->type == MOBJ_SNOMASK) {
+                       SnomaskDel(objs->object.snomask);
+               }
+               else if (objs->type == MOBJ_UMODE) {
+                       UmodeDel(objs->object.umode);
+               }
        }
        for (p = Modules; p; p = p->next)
        {
@@ -693,12 +716,14 @@ int  m_module(aClient *cptr, aClient *sptr, int parc, char *parv[])
        }
        for (mi = Modules; mi; mi = mi->next)
        {
-               char delayed[32];
+               char tmp[256];
+               tmp[0] = '\0';
                if (mi->flags & MODFLAG_DELAYED)
-                       strcpy(delayed, "[Unloading]");
+                       strcat(tmp, "[Unloading] ");
+               if (mi->options & MOD_OPT_PERM)
+                       strcat(tmp, "[PERM] ");
                sendto_one(sptr, ":%s NOTICE %s :*** %s - %s (%s) %s", me.name, sptr->name,
-                       mi->header->name, mi->header->version, mi->header->description,
-                       (mi->flags & MODFLAG_DELAYED) ? delayed : "");  
+                       mi->header->name, mi->header->version, mi->header->description, tmp);
        }
        return 1;
 }
@@ -744,6 +769,7 @@ Versionflag *VersionflagAdd(Module *module, char flag)
                                vflagobj->type = MOBJ_VERSIONFLAG;
                                vflagobj->object.versionflag = vflag;
                                AddListItem(vflagobj, module->objects);
+                               module->errorcode = MODERR_NOERROR;
                        }
                        AddListItem(parent,vflag->parents);
                }
@@ -760,6 +786,7 @@ Versionflag *VersionflagAdd(Module *module, char flag)
                vflagobj->type = MOBJ_VERSIONFLAG;
                vflagobj->object.versionflag = vflag;
                AddListItem(vflagobj, module->objects);
+               module->errorcode = MODERR_NOERROR;
        }
        flag_add(flag);
        AddListItem(parent,vflag->parents);
@@ -772,6 +799,7 @@ void VersionflagDel(Versionflag *vflag, Module *module)
        ModuleChild *owner;
        if (!vflag)
                return;
+
        for (owner = vflag->parents; owner; owner = owner->next)
        {
                if (owner->child == module)
@@ -819,6 +847,7 @@ Hooktype *HooktypeAdd(Module *module, char *string, int *type) {
                                hooktypeobj->type = MOBJ_HOOKTYPE;
                                hooktypeobj->object.hooktype = hooktype;
                                AddListItem(hooktypeobj, module->objects);
+                               module->errorcode = MODERR_NOERROR;
                        }
                        AddListItem(parent,hooktype->parents);
                }
@@ -827,10 +856,14 @@ Hooktype *HooktypeAdd(Module *module, char *string, int *type) {
        }
        for (hooktype = Hooktypes, i = 0; hooktype->string; hooktype++, i++) ;
 
-       if (i >= 29)
+       if (i >= 39)
+       {
+               if (module)
+                       module->errorcode = MODERR_NOSPACE;
                return NULL;
+       }
 
-       Hooktypes[i].id = i+31;
+       Hooktypes[i].id = i+41;
        Hooktypes[i].string = strdup(string);
        parent = MyMallocEx(sizeof(ModuleChild));
        parent->child = module;
@@ -839,9 +872,10 @@ Hooktype *HooktypeAdd(Module *module, char *string, int *type) {
                hooktypeobj->type = MOBJ_HOOKTYPE;
                hooktypeobj->object.hooktype = &Hooktypes[i];
                AddListItem(hooktypeobj,module->objects);
+               module->errorcode = MODERR_NOERROR;
        }
        AddListItem(parent,Hooktypes[i].parents);
-       *type = i+31;
+       *type = i+41;
        return &Hooktypes[i];
 }
 
@@ -892,6 +926,7 @@ Hook        *HookAddMain(Module *module, int hooktype, int (*func)(), void (*vfunc)(),
                hookobj->object.hook = p;
                hookobj->type = MOBJ_HOOK;
                AddListItem(hookobj, module->objects);
+               module->errorcode = MODERR_NOERROR;
        }
        return p;
 }
@@ -949,3 +984,32 @@ void       unload_all_modules(void)
        }
 }
 
+unsigned int ModuleSetOptions(Module *module, unsigned int options)
+{
+       unsigned int oldopts = module->options;
+
+       module->options = options;
+       return oldopts;
+}
+
+unsigned int ModuleGetOptions(Module *module)
+{
+       return module->options;
+}
+
+unsigned int ModuleGetError(Module *module)
+{
+       return module->errorcode;
+}
+
+static const char *module_error_str[] = {
+       "No error",
+       "Object already exists",
+       "No space available",
+       "Invalid parameter(s)"
+};
+
+const char *ModuleGetErrorStr(Module *module)
+{
+       return module_error_str[module->errorcode];
+}
index 9f74a8f4b4e68877f04974ac262b5aab5404b585..20965eab44c37ae752c211fb7ef0661d7e82235b 100644 (file)
@@ -49,12 +49,8 @@ DLLFUNC int m_admins(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_ADMINCHAT  "ADCHAT"
 #define TOK_ADMINCHAT  "x"
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_adminchat_Header
-#else
-#define m_adminchat_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+
+ModuleHeader MOD_HEADER(m_adminchat)
   = {
        "adminchat",    /* Name of module */
        "$Id$", /* Version */
@@ -64,16 +60,8 @@ ModuleHeader Mod_Header
     };
 
 
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_adminchat_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_adminchat)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -83,27 +71,19 @@ int    m_adminchat_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_adminchat_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_adminchat)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
 
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_adminchat_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_adminchat)(int module_unload)
 {
        if (del_Command(MSG_ADMINCHAT, TOK_ADMINCHAT, m_admins) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_adminchat_Header.name);
+                               MOD_HEADER(m_adminchat).name);
        }
        return MOD_SUCCESS;
 }
index 336d0181d2b255639b53a8a3c810c7a3af247f68..d455ed83f4e06cc53967dbe5a2363ac44ca39bd4 100644 (file)
@@ -49,13 +49,7 @@ DLLFUNC int m_akill(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_AKILL       "AKILL" /* AKILL */
 #define TOK_AKILL       "V"     /* 86 */
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_akill_Header
-#else
-#define m_akill_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_akill)
   = {
        "akill",        /* Name of module */
        "$Id$", /* Version */
@@ -64,17 +58,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_akill_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_akill)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -85,27 +70,19 @@ int    m_akill_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_akill_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_akill)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
 
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_akill_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_akill)(int module_unload)
 {
        if (del_Command(MSG_AKILL, TOK_AKILL, m_akill) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_akill_Header.name);
+                               MOD_HEADER(m_akill).name);
        }
        return MOD_SUCCESS;
 }
index 1a60c4e14aad2fcbcdee77a2f3cdd7f792d28b9b..27b1a00aea38ff776a0342c3152c85031e148737 100644 (file)
@@ -51,13 +51,7 @@ DLLFUNC int m_away(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_AWAY       "AWAY"  
 #define TOK_AWAY       "6"     
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_away_Header
-#else
-#define m_away_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_away)
   = {
        "m_away",
        "$Id$",
@@ -66,35 +60,23 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_away_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_away)(ModuleInfo *modinfo)
 {
        add_Command(MSG_AWAY, TOK_AWAY, m_away, 1);
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_away_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_away)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_away_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_away)(int module_unload)
 {
        if (del_Command(MSG_AWAY, TOK_AWAY, m_away) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_away_Header.name);
+                               MOD_HEADER(m_away).name);
        }
        return MOD_SUCCESS;
 }
@@ -138,23 +120,20 @@ int  m_away(aClient *cptr, aClient *sptr, int parc, char *parv[]) {
         }
 
 #ifdef NO_FLOOD_AWAY
-       if (MyClient(sptr) && AWAY_PERIOD)
+       if (MyClient(sptr) && AWAY_PERIOD && !IsAnOper(sptr))
        {
-               if ((sptr->user->last_away + AWAY_PERIOD) <= timeofday)
-                       sptr->user->away_count = 0;
-
-               if (!IsAnOper(sptr))
+               if ((sptr->user->flood.away_t + AWAY_PERIOD) <= timeofday)
                {
-                       sptr->user->last_away = timeofday;
-                       if (sptr->user->away_count < AWAY_COUNT)
-                               sptr->user->away_count++;
-                       if (sptr->user->away_count >= AWAY_COUNT)
-                       {
-                               sendto_one(sptr, err_str(ERR_TOOMANYAWAY), me.name, parv[0]);
-                               return 0;
-                       }
+                       sptr->user->flood.away_c = 0;
+                       sptr->user->flood.away_t = timeofday;
+               }
+               if (sptr->user->flood.away_c <= AWAY_COUNT)
+                       sptr->user->flood.away_c++;
+               if (sptr->user->flood.away_c > AWAY_COUNT)
+               {
+                       sendto_one(sptr, err_str(ERR_TOOMANYAWAY), me.name, parv[0]);
+                       return 0;
                }
-
        }
 #endif
         /* Marking as away */
index 55afe0699b4bbdbd184c6f3e7fb470744c6b3ad2..dcb8435020d47cdec50b2bda007c2b0e292a4dd7 100644 (file)
 #define TOK_CHGHOST    "AL"
 
 DLLFUNC int m_chghost(aClient *cptr, aClient *sptr, int parc, char *parv[]);
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_chghost_Header
-#define Mod_Header m_chghost_Header
-#else
-ModuleHeader Mod_Header
-#endif
+
+ModuleHeader MOD_HEADER(m_chghost)
   = {
        "chghost",      /* Name of module */
        "$Id$", /* Version */
@@ -61,16 +57,7 @@ ModuleHeader Mod_Header
        "3.2-b8-1",
     };
 
-/*
- * The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_chghost_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_chghost)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -79,25 +66,19 @@ int    m_chghost_Init(ModuleInfo *modinfo)
        return MOD_SUCCESS;
        
 }
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_chghost_Load(int module_load)
-#endif
+
+DLLFUNC int MOD_LOAD(m_chghost)(int module_load)
 {
        return MOD_SUCCESS;
        
 }
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_chghost_Unload(int module_unload)
-#endif
+
+DLLFUNC int MOD_UNLOAD(m_chghost)(int module_unload)
 {
        if (del_Command(MSG_CHGHOST, TOK_CHGHOST, m_chghost) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               Mod_Header.name);
+                               MOD_HEADER(m_chghost).name);
        }
        return MOD_SUCCESS;
        
index 13766fb3e53d5f5185794bf1b22823e975640ea8..fc3abca8a44d98b155f7ad67071e3df5304c6c7b 100644 (file)
 
 DLLFUNC int m_chgident(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_chgident_Header
-#else
-#define m_chgident_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+
+ModuleHeader MOD_HEADER(m_chgident)
   = {
        "chgident",     /* Name of module */
        "$Id$", /* Version */
@@ -63,16 +59,7 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-/*
- * The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int   m_chgident_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_chgident)(ModuleInfo *modinfo)
 {
        /* extern variable to export m_chgident_info to temporary
            ModuleHeader *modulebuffer;
@@ -86,25 +73,17 @@ int   m_chgident_Init(ModuleInfo *modinfo)
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int   m_chgident_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_chgident)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_chgident_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_chgident)(int module_unload)
 {
        if (del_Command(MSG_CHGIDENT, TOK_CHGIDENT, m_chgident) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_chgident_Header.name);
+                               MOD_HEADER(m_chgident).name);
        }
        return MOD_SUCCESS;
 }
index 12a9b1274f903ade7b64da98567b1392477c1a3b..c835addfdbe95a902f48b0af8361eeafb2cbeb1b 100644 (file)
@@ -49,12 +49,8 @@ DLLFUNC int m_chgname(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_CHGNAME     "CHGNAME"
 #define TOK_CHGNAME     "BK"
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_chgname_Header
-#else
-#define m_chgname_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+
+ModuleHeader MOD_HEADER(m_chgname)
   = {
        "chgname",      /* Name of module */
        "$Id$", /* Version */
@@ -64,16 +60,8 @@ ModuleHeader Mod_Header
     };
 
 
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_chgname_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_chgname)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -85,11 +73,7 @@ int    m_chgname_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_chgname_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_chgname)(int module_load)
 {
        return MOD_SUCCESS;
        
@@ -97,21 +81,17 @@ int    m_chgname_Load(int module_load)
 
 
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_chgname_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_chgname)(int module_unload)
 {
        if (del_Command(MSG_CHGNAME, TOK_CHGNAME, m_chgname) < 0)
        {
                sendto_realops("Failed to delete command chgname when unloading %s",
-                               m_chgname_Header.name);
+                               MOD_HEADER(m_chgname).name);
        }
        if (del_Command(MSG_SVSNAME, TOK_CHGNAME, m_chgname) < 0)
        {
                sendto_realops("Failed to delete command svsname when unloading %s",
-                               m_chgname_Header.name);
+                               MOD_HEADER(m_chgname).name);
        }
        return MOD_SUCCESS;
        
diff --git a/src/modules/m_chmodetst.c b/src/modules/m_chmodetst.c
new file mode 100644 (file)
index 0000000..d433f08
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Test for modulized channelmode system, adds 2 modes:
+ * +w (paramless)
+ * +y <0-100> (1 parameter)
+ *
+ * It's incomplete (like error signaling) but for testing purposes only.
+ */
+
+#include "config.h"
+#include "struct.h"
+#include "common.h"
+#include "sys.h"
+#include "numeric.h"
+#include "msg.h"
+#include "proto.h"
+#include "channel.h"
+#include <time.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _WIN32
+#include <io.h>
+#endif
+#include <fcntl.h>
+#include "h.h"
+#ifdef STRIPBADWORDS
+#include "badwords.h"
+#endif
+#ifdef _WIN32
+#include "version.h"
+#endif
+
+
+ModuleHeader MOD_HEADER(m_chmodetst)
+  = {
+       "chmodetst",    /* Name of module */
+       "channelmode test", /* Version */
+       "channelmode +w", /* Short description of module */
+       "3.2-b8-1",
+       NULL,
+    };
+
+Cmode_t EXTCMODE_TEST = 0L; /* Just for testing */
+Cmode_t EXTCMODE_TEST2 = 0L; /* Just for testing */
+
+int modey_is_ok(aClient *sptr, aChannel *chptr, char *para, int checkt, int what);
+CmodeParam * modey_put_param(CmodeParam *lst, char *para);
+char *modey_get_param(CmodeParam *lst);
+char *modey_conv_param(char *param);
+void modey_free_param(CmodeParam *lst);
+CmodeParam *modey_dup_struct(CmodeParam *src);
+int modey_sjoin_check(aChannel *chptr, CmodeParam *ourx, CmodeParam *theirx);
+CmodeParam *modey_dup_struct(CmodeParam *src);
+
+typedef struct {
+       EXTCM_PAR_HEADER
+       short val;
+} aModewentry;
+
+/* The purpose of these ifdefs, are that we can "static" link the ircd if we
+ * want to
+*/
+
+Cmode *ModeTest = NULL, *ModeTest2 = NULL;
+/* This is called on module init, before Server Ready */
+DLLFUNC int MOD_INIT(m_dummy)(ModuleInfo *modinfo)
+{
+       CmodeInfo req;
+       ircd_log(LOG_ERROR, "debug: mod_init called from chmodetst module");
+       ModuleSetOptions(modinfo->handle, MOD_OPT_PERM);
+       sendto_realops("chmodetst loading...");
+       /* TODO: load mode here */
+       /* +w doesn't do anything, it's just for testing */
+       memset(&req, 0, sizeof(req));
+       req.paracount = 0;
+       req.is_ok = extcmode_default_requirechop;
+       req.flag = 'w';
+       ModeTest = CmodeAdd(modinfo->handle, req, &EXTCMODE_TEST);
+       /* +y doesn't do anything except that you can set/unset it with a
+        * numeric parameter (1-100)
+        */
+       memset(&req, 0, sizeof(req));
+       req.paracount = 1;
+       req.is_ok = modey_is_ok;
+       req.put_param = modey_put_param;
+       req.get_param = modey_get_param;
+       req.conv_param  = modey_conv_param;
+       req.free_param = modey_free_param;
+       req.sjoin_check = modey_sjoin_check;
+       req.dup_struct = modey_dup_struct;
+       req.flag = 'y';
+       ModeTest2 = CmodeAdd(modinfo->handle, req, &EXTCMODE_TEST2);
+       return MOD_SUCCESS;
+}
+
+/* Is first run when server is 100% ready */
+DLLFUNC int MOD_LOAD(m_dummy)(int module_load)
+{
+       return MOD_SUCCESS;
+}
+
+
+/* Called when module is unloaded */
+DLLFUNC int MOD_UNLOAD(m_dummy)(int module_unload)
+{
+       /* Aaaaaaaargh... we are assumed to be a permanent module */
+       sendto_realops("Mod_Unload was called??? Arghhhhhh..");
+       return MOD_FAILED;
+}
+
+int modey_is_ok(aClient *sptr, aChannel *chptr, char *para, int checkt, int what)
+{
+short t;
+
+       if ((checkt == EXCHK_ACCESS) || (checkt == EXCHK_ACCESS_ERR))
+       {
+               if (!is_chan_op(sptr, chptr))
+               {
+                       if (checkt == EXCHK_ACCESS_ERR)
+                               sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED), me.name, sptr->name, chptr->chname);
+                       return 0;
+               } else {
+                       return 1;
+               }
+       } else
+       if (checkt == EXCHK_PARAM)
+       {
+               t = (short)atoi(para);
+               if ((t < 0) || (t > 100))
+               {
+                       sendto_one(sptr, ":%s NOTICE %s :chanmode +y requires a parameter in the range 0..100",
+                               me.name, sptr->name);
+                       return 0;
+               }
+               return 1;
+       }
+       return 0;
+}
+
+CmodeParam * modey_put_param(CmodeParam *ypara, char *para)
+{
+       aModewentry *r = (aModewentry *)ypara;
+
+       if (!r)
+       {
+               /* Need to create one */
+               r = (aModewentry *)malloc(sizeof(aModewentry));
+               memset(r, 0, sizeof(aModewentry));
+               r->flag = 'y';
+       }
+       r->val = (short)atoi(para);
+       return (CmodeParam *)r;
+}
+
+char *modey_get_param(CmodeParam *ypara)
+{
+       aModewentry *r = (aModewentry *)ypara;
+       static char tmpret[16];
+
+       if (!r)
+               return NULL;
+       sprintf(tmpret, "%hu", r->val);
+       return tmpret;
+}
+
+/* no this is not useless, imagine the parameter "1blah" :P */
+char *modey_conv_param(char *param)
+{
+short i;
+static char tmpret2[16];
+       i = (short)atoi(param);
+       sprintf(tmpret2, "%hu", i);
+       return tmpret2;
+}
+
+void modey_free_param(CmodeParam *ypara)
+{
+       aModewentry *r = (aModewentry *)ypara;
+       free(r);
+}
+
+CmodeParam *modey_dup_struct(CmodeParam *src)
+{
+       aModewentry *n = (aModewentry *)malloc(sizeof(aModewentry));
+       memcpy(n, src, sizeof(aModewentry));
+       return (CmodeParam *)n;
+}
+
+int modey_sjoin_check(aChannel *chptr, CmodeParam *ourx, CmodeParam *theirx)
+{
+aModewentry *our = (aModewentry *)ourx;
+aModewentry *their = (aModewentry *)theirx;
+
+       if (our->val == their->val)
+               return EXSJ_SAME;
+       if (our->val > their->val)
+               return EXSJ_WEWON;
+       else
+               return EXSJ_THEYWON;
+}
index c1fae74cf6a2850b9c48155ce96d0a651e9ae159..dfdd360dcef714e49243a7b319221ac60e7030df 100644 (file)
@@ -49,12 +49,7 @@ DLLFUNC int m_cycle(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_CYCLE       "CYCLE"
 #define TOK_CYCLE       "BP"
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_cycle_Header
-#else
-#define m_cycle_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_cycle)
   = {
        "cycle",        /* Name of module */
        "$Id$", /* Version */
@@ -63,17 +58,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_cycle_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_cycle)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -84,27 +70,19 @@ int    m_cycle_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_cycle_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_cycle)(int module_load)
 {
        return MOD_SUCCESS;
        
 }
 
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_cycle_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_cycle)(int module_unload)
 {
        if (del_Command(MSG_CYCLE, TOK_CYCLE, m_cycle) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_cycle_Header.name);
+                               MOD_HEADER(m_cycle).name);
        }
        return MOD_SUCCESS;     
 }
index 6b975423c0165960621331ba378e3eeb5b8e1abb..f45ed6378e2496b9daa38229ee349ea4a138ed4a 100644 (file)
@@ -33,12 +33,8 @@ DLLFUNC int m_dummy(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_DUMMY      "DUMMY" /* dummy */
 #define TOK_DUMMY      "DU"    /* 127 4ever !;) */
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_dummy_Header
-#else
-#define m_dummy_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+
+ModuleHeader MOD_HEADER(m_dummy)
   = {
        "dummy",        /* Name of module */
        "$Id$", /* Version */
@@ -47,46 +43,32 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_dummy_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_dummy)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
        */
        add_Command(MSG_DUMMY, TOK_DUMMY, m_dummy, MAXPARA);
+       return MOD_SUCCESS;
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_dummy_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_dummy)(int module_load)
 {
+       return MOD_SUCCESS;
 }
 
 
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_dummy_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_dummy)(int module_unload)
 {
        if (del_Command(MSG_DUMMY, TOK_DUMMY, m_dummy) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_dummy_Header.name);
+                               MOD_HEADER(m_dummy).name);
        }
+       return MOD_SUCCESS;
 }
 
 DLLFUNC int m_dummy(aClient *cptr, aClient *sptr, int parc, char *parv[])
index 0a66dd16a2e07a2bcbb3f438d6f0303c82b31a9a..597078fc09a9db67152ac945cc9559e10ef31afa 100644 (file)
@@ -31,7 +31,7 @@
 #include <stdlib.h>
 #include <string.h>
 #ifdef _WIN32
-#define snprintf _snprintf
+//#define snprintf _snprintf
 #include <io.h>
 #endif
 #include <fcntl.h>
@@ -48,12 +48,8 @@ DLLFUNC int m_guest(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 static Hook *GuestHook = NULL;
 #endif
 /* Place includes here */
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_guest_Header
-#else
-#define m_guest_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+
+ModuleHeader MOD_HEADER(m_guest)
   = {
        "guest",        /* Name of module */
        "$Id$", /* Version */
@@ -63,16 +59,8 @@ ModuleHeader Mod_Header
     };
 
 ModuleInfo *ModGuestInfo;
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_guest_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_guest)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -86,11 +74,7 @@ int    m_guest_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_guest_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_guest)(int module_load)
 {
        return MOD_SUCCESS;
        
@@ -98,11 +82,7 @@ int    m_guest_Load(int module_load)
 
 
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_guest_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_guest)(int module_unload)
 {
 #ifdef GUEST
        HookDel(GuestHook);
@@ -110,8 +90,6 @@ int  m_guest_Unload(int module_unload)
        return MOD_SUCCESS;
 }
 
-
-
 DLLFUNC int m_guest(aClient *cptr, aClient *sptr, int parc, char *parv[])
 {
        int randnum;
index e1ce9177701693956799031e3396af1e9890f50e..0e6eabf6882605fa9432f536935921638919a4bf 100644 (file)
@@ -71,12 +71,8 @@ DLLFUNC int htm_stats(aClient *, char *);
 
 ModuleInfo *HtmModInfo;
 static Hook *ConfTest, *ConfRun, *ServerStats;
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_htm_Header
-#else
-#define m_htm_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+
+ModuleHeader MOD_HEADER(m_htm)
   = {
        "htm",  /* Name of module */
        "$Id$", /* Version */
@@ -85,16 +81,7 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Test(ModuleInfo *modinfo)
-#else
-int    m_htm_Test(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_TEST(m_htm)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -106,11 +93,7 @@ int    m_htm_Test(ModuleInfo *modinfo)
 
 
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_htm_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_htm)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -128,27 +111,19 @@ int    m_htm_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_htm_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_htm)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
 
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_htm_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_htm)(int module_unload)
 {
        if (del_Command(MSG_HTM, TOK_HTM, m_htm) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_htm_Header.name);
+                               MOD_HEADER(m_htm).name);
        }
 #ifndef NO_FDLIST
        LockEventSystem();
index 001a5e83e800d0d2abff61b59fd04cc020c668af..5eae37a26b89e8847e1327d35fd1c4b7fb6de77f 100644 (file)
@@ -50,13 +50,7 @@ static char buf[BUFSIZE], buf2[BUFSIZE];
 #define MSG_KILL        "KILL"  /* KILL */
 #define TOK_KILL        "."     /* 46 */
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_kill_Header
-#else
-#define m_kill_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_kill)
   = {
        "kill", /* Name of module */
        "$Id$", /* Version */
@@ -65,17 +59,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_kill_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_kill)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -85,27 +70,19 @@ int    m_kill_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_kill_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_kill)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
 
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_kill_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_kill)(int module_unload)
 {
        if (del_Command(MSG_KILL, TOK_KILL, m_kill) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_kill_Header.name);
+                               MOD_HEADER(m_kill).name);
        }
        return MOD_SUCCESS;
        
@@ -120,22 +97,6 @@ int m_kill_Unload(int module_unload)
 */
 DLLFUNC int  m_kill(aClient *cptr, aClient *sptr, int parc, char *parv[])
 {
-       static anUser UnknownUser = {
-               NULL,           /* channel */
-               NULL,           /* invited */
-               NULL,           /* silence */
-               NULL,           /* away */
-#ifdef NO_FLOOD_AWAY
-               0,              /* last_away */
-               0,              /* away_count */
-#endif
-               0,              /* servicestamp */
-               1,              /* refcount */
-               0,              /* joined */
-               "<Unknown>",    /* username */
-               "<Unknown>",    /* host */
-               "<Unknown>"     /* server */
-       };
        aClient *acptr;
        anUser *auser;
        char inpath[HOSTLEN * 2 + USERLEN + 5];
@@ -281,7 +242,7 @@ DLLFUNC int  m_kill(aClient *cptr, aClient *sptr, int parc, char *parv[])
                   **    have changed the target because of the nickname change.
                 */
 
-               auser = acptr->user ? acptr->user : &UnknownUser;
+               auser = acptr->user;
 
                if (index(parv[0], '.'))
                        sendto_snomask(SNO_KILLS,
index e0ccf5559f7e257626f1728d5d85c5a8a9178a4c..725ddadc4a6500309e67bb96141e7a03486723df 100644 (file)
@@ -49,12 +49,7 @@ DLLFUNC int m_lag(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_LAG         "LAG"   /* Lag detect */
 #define TOK_LAG         "AF"    /* a or ? */
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_lag_Header
-#else
-#define m_lag_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_lag)
   = {
        "lag",  /* Name of module */
        "$Id$", /* Version */
@@ -63,48 +58,29 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_lag_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_lag)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
        */
        add_Command(MSG_LAG, TOK_LAG, m_lag, MAXPARA);
        return MOD_SUCCESS;
-       
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_lag_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_lag)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_lag_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_lag)(int module_unload)
 {
        if (del_Command(MSG_LAG, TOK_LAG, m_lag) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_lag_Header.name);
+                               MOD_HEADER(m_lag).name);
        }
        return MOD_SUCCESS;
        
index cd31f538064c78b8cb857fe3ee7aa26be06d938d..9bc2e1bb311172038ff87e9c836462ef23a2c872 100644 (file)
@@ -49,19 +49,13 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int
 DLLFUNC int  m_notice(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 DLLFUNC int  m_private(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 
-
 /* Place includes here */
 #define MSG_PRIVATE     "PRIVMSG"       /* PRIV */
 #define TOK_PRIVATE     "!"     /* 33 */
 #define MSG_NOTICE      "NOTICE"        /* NOTI */
 #define TOK_NOTICE      "B"     /* 66 */
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_message_Header
-#else
-#define m_message_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_message)
   = {
        "message",      /* Name of module */
        "$Id$", /* Version */
@@ -70,17 +64,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_message_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_message)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -92,33 +77,23 @@ int    m_message_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_message_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_message)(int module_load)
 {
        return MOD_SUCCESS;
-       
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_message_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_message)(int module_unload)
 {
        if (del_Command(MSG_PRIVATE, TOK_PRIVATE, m_private) < 0)
        {
                sendto_realops("Failed to delete command privmsg when unloading %s",
-                               m_message_Header.name);
+                               MOD_HEADER(m_message).name);
        }
        if (del_Command(MSG_NOTICE, TOK_NOTICE, m_notice) < 0)
        {
                sendto_realops("Failed to delete command notice when unloading %s",
-                               m_message_Header.name);
+                               MOD_HEADER(m_message).name);
        }
        return MOD_SUCCESS;
 }
@@ -201,26 +176,28 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int
                 */
                if (!strcasecmp(nick, "ircd") && MyClient(sptr))
                {
+                       int ret = 0;
                        if (!recursive_webtv)
                        {
                                recursive_webtv = 1;
-                               parse(sptr, parv[2], (parv[2] + strlen(parv[2])));
+                               ret = parse(sptr, parv[2], (parv[2] + strlen(parv[2])));
                                recursive_webtv = 0;
                        }
-                       return 0;
+                       return ret;
                }
                if (!strcasecmp(nick, "irc") && MyClient(sptr))
                {
                        if (!recursive_webtv)
                        {
+                               int ret;
                                recursive_webtv = 1;
-                               if (webtv_parse(sptr, parv[2]) == -2)
+                               ret = webtv_parse(sptr, parv[2]);
+                               if (ret == -99)
                                {
-                                       parse(sptr, parv[2],
-                                           (parv[2] + strlen(parv[2])));
+                                       ret = parse(sptr, parv[2], (parv[2] + strlen(parv[2])));
                                }
                                recursive_webtv = 0;
-                               return 0;
+                               return ret;
                        }
                }
                if (*nick != '#' && (acptr = find_person(nick, NULL)))
@@ -316,7 +293,7 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int
                                            acptr->user->away);
 
 #ifdef STRIPBADWORDS
-                               if (!(IsULine(acptr) || IsULine(sptr)) && IsFilteringWords(acptr))
+                               if (MyClient(sptr) && !IsULine(acptr) && IsFilteringWords(acptr))
                                {
                                        text = stripbadwords_message(parv[2], &blocked);
                                        if (blocked)
@@ -399,32 +376,26 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int
                                int blocked = 0;
 #endif
                                Hook *tmphook;
-                               /*if (chptr->mode.mode & MODE_FLOODLIMIT) */
-                               /* When we do it this way it appears to work? */
+#ifdef NEWCHFLOODPROT
+                               if (chptr->mode.floodprot && chptr->mode.floodprot->l[FLD_TEXT])
+#else
                                if (chptr->mode.per)
-                                       if (check_for_chan_flood(cptr, sptr,
-                                           chptr) == 1)
+#endif
+                                       if (check_for_chan_flood(cptr, sptr, chptr) == 1)
                                                continue;
 
-                               sendanyways = (parv[2][0] == '`' ? 1 : 0);
-                               text =
-                                   (chptr->mode.mode & MODE_STRIP ?
-                                   (char *)StripColors(parv[2]) : parv[2]);
+                               if (!CHANCMDPFX)
+                                       sendanyways = (parv[2][0] == '`' ? 1 : 0);
+                               else
+                                       sendanyways = (strchr(CHANCMDPFX,parv[2][0]) ? 1 : 0);
+                               text = parv[2];
+                               if (MyClient(sptr) && (chptr->mode.mode & MODE_STRIP))
+                                       text = StripColors(parv[2]);
 #ifdef STRIPBADWORDS
- #ifdef STRIPBADWORDS_CHAN_ALWAYS
-                               text = stripbadwords_channel(text,& blocked);
-                               if (blocked)
-                               {
-                                       if (!notice)
-                                               sendto_one(sptr, err_str(ERR_CANNOTSENDTOCHAN),
-                                                   me.name, parv[0], parv[0],
-                                                   err_cantsend[6], p2);
-                                       continue;
-                               }
- #else
-                               if (chptr->mode.mode & MODE_STRIPBADWORDS)
+                               if (MyClient(sptr))
                                {
-                                       text = stripbadwords_channel(text, &blocked);
+ #ifdef STRIPBADWORDS_CHAN_ALWAYS
+                                       text = stripbadwords_channel(text,& blocked);
                                        if (blocked)
                                        {
                                                if (!notice)
@@ -433,8 +404,21 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int
                                                            err_cantsend[6], p2);
                                                continue;
                                        }
-                               }
+ #else
+                                       if (chptr->mode.mode & MODE_STRIPBADWORDS)
+                                       {
+                                               text = stripbadwords_channel(text, &blocked);
+                                               if (blocked)
+                                               {
+                                                       if (!notice)
+                                                               sendto_one(sptr, err_str(ERR_CANNOTSENDTOCHAN),
+                                                                   me.name, parv[0], parv[0],
+                                                                   err_cantsend[6], p2);
+                                                       continue;
+                                               }
+                                       }
  #endif
+                               }
 #endif
                                for (tmphook = Hooks[HOOKTYPE_CHANMSG]; tmphook; tmphook = tmphook->next) {
                                        text = (*(tmphook->func.pcharfunc))(cptr, sptr, chptr, text, notice);
@@ -451,13 +435,32 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int
                                    notice ? MSG_NOTICE : MSG_PRIVATE,
                                    notice ? TOK_NOTICE : TOK_PRIVATE,
                                    nick, text);
+
+#ifdef NEWCHFLOODPROT
+                               if (chptr->mode.floodprot && !is_skochanop(sptr, chptr) &&
+                                   !IsULine(sptr) && do_chanflood(chptr->mode.floodprot, FLD_MSG) &&
+                                   MyClient(sptr))
+                               {
+                                       do_chanflood_action(chptr, FLD_MSG, "msg/notice");
+                               }
+                               
+                               if (chptr->mode.floodprot && !is_skochanop(sptr, chptr) &&
+                                   (text[0] == '\001') && strncmp(text+1, "ACTION ", 7) &&
+                                   do_chanflood(chptr->mode.floodprot, FLD_CTCP) && MyClient(sptr))
+                               {
+                                       do_chanflood_action(chptr, FLD_CTCP, "CTCP");
+                               }
+#endif
                                sendanyways = 0;
                                continue;
                        }
-                       else if (!notice)
+                       else
+                       if (!notice && MyClient(sptr))
+                       {
                                sendto_one(sptr, err_str(ERR_CANNOTSENDTOCHAN),
                                    me.name, parv[0], parv[0],
                                    err_cantsend[cansend - 1], p2);
+                       }
                        continue;
                }
                else if (p2)
@@ -609,14 +612,29 @@ static int is_silenced(aClient *sptr, aClient *acptr)
        Link *lp;
        anUser *user;
        static char sender[HOSTLEN + NICKLEN + USERLEN + 5];
-
+       static char senderx[HOSTLEN + NICKLEN + USERLEN + 5];
+       char checkv = 0;
+       
        if (!(acptr->user) || !(lp = acptr->user->silence) ||
            !(user = sptr->user)) return 0;
+
        ircsprintf(sender, "%s!%s@%s", sptr->name, user->username,
            user->realhost);
+       /* We also check for matches against sptr->user->virthost if present,
+        * this is checked regardless of mode +x so you can't do tricks like:
+        * evil has +x and msgs, victim places silence on +x host, evil does -x
+        * and can msg again. -- Syzop
+        */
+       if (sptr->user->virthost)
+       {
+               ircsprintf(senderx, "%s!%s@%s", sptr->name, user->username,
+                   sptr->user->virthost);
+               checkv = 1;
+       }
+
        for (; lp; lp = lp->next)
        {
-               if (!match(lp->value.cp, sender))
+               if (!match(lp->value.cp, sender) || (checkv && !match(lp->value.cp, senderx)))
                {
                        if (!MyConnect(sptr))
                        {
index 649150c2dbd50674bce7b3f34ec5bb0c8a21ded1..3ddd6f57beaafbc7d291ec01686d3e6896bd2cdc 100644 (file)
@@ -51,13 +51,7 @@ DLLFUNC int m_mkpasswd(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_MKPASSWD   "MKPASSWD"      
 #define TOK_MKPASSWD   "y"     
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_mkpasswd_Header
-#else
-#define m_mkpasswd_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_mkpasswd)
   = {
        "m_mkpasswd",
        "$Id$",
@@ -66,40 +60,27 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_mkpasswd_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_mkpasswd)(ModuleInfo *modinfo)
 {
        add_Command(MSG_MKPASSWD, TOK_MKPASSWD, m_mkpasswd, MAXPARA);
        return MOD_SUCCESS;
-       
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_mkpasswd_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_mkpasswd)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_mkpasswd_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_mkpasswd)(int module_unload)
 {
        if (del_Command(MSG_MKPASSWD, TOK_MKPASSWD, m_mkpasswd) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_mkpasswd_Header.name);
+                               MOD_HEADER(m_mkpasswd).name);
        }
        return MOD_SUCCESS;
-       
 }
+
 /*
 ** m_mkpasswd
 **      parv[0] = sender prefix
index 33f2821c4b0af8795c9e114f37623844bbc4d4f7..ef4f463023bd7af58b7a3833adf2a1eeded4484e 100644 (file)
@@ -49,12 +49,7 @@ DLLFUNC int m_nachat(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_NACHAT      "NACHAT"        /* netadmin chat */
 #define TOK_NACHAT      "AC"    /* *beep* */
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_nachat_Header
-#else
-#define m_nachat_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_nachat)
   = {
        "Nachat",       /* Name of module */
        "$Id$", /* Version */
@@ -63,49 +58,29 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_nachat_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_nachat)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
        */
        add_Command(MSG_NACHAT, TOK_NACHAT, m_nachat, 1);
        return MOD_SUCCESS;
-       
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_nachat_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_nachat)(int module_load)
 {      
        return MOD_SUCCESS;
-       
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int m_nachat_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_nachat)(int module_unload)
 {
        if (del_Command(MSG_NACHAT, TOK_NACHAT, m_nachat) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_nachat_Header.name);
+                               MOD_HEADER(m_nachat).name);
        }
        return MOD_SUCCESS;
        
index a7cb8ef7942bded2e34bba84eece40e78cdf1634..5c12058b6db2f70d68d7a90e276fcf541b8f28fd 100644 (file)
@@ -81,12 +81,7 @@ static oper_oflag_t oper_oflags[] = {
                0 },
 };
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_oper_Header
-#else
-#define m_oper_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_oper)
   = {
        "oper", /* Name of module */
        "$Id$", /* Version */
@@ -95,17 +90,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_oper_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_oper)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -115,27 +101,18 @@ int    m_oper_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_oper_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_oper)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_oper_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_oper)(int module_unload)
 {
        if (del_Command(MSG_OPER, TOK_OPER, m_oper) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_oper_Header.name);
+                               MOD_HEADER(m_oper).name);
        }
        return MOD_SUCCESS;
 }
@@ -202,6 +179,8 @@ DLLFUNC int  m_oper(aClient *cptr, aClient *sptr, int parc, char *parv[]) {
                sendto_realops
                    ("Failed OPER attempt by %s (%s@%s) [host doesnt match]",
                    parv[0], sptr->user->username, sptr->sockhost);
+               ircd_log(LOG_OPER, "OPER NOHOSTMATCH (%s) by (%s!%s@%s)", name, parv[0],
+                       sptr->user->username, sptr->sockhost);
                sptr->since += 7;
                return 0;
        }
@@ -223,7 +202,7 @@ DLLFUNC int  m_oper(aClient *cptr, aClient *sptr, int parc, char *parv[]) {
                                MyFree(sptr->user->swhois);
                        sptr->user->swhois = MyMalloc(strlen(aconf->swhois) +1);
                        strcpy(sptr->user->swhois, aconf->swhois);
-                       sendto_serv_butone_token(cptr, sptr->name,
+                       sendto_serv_butone_token(cptr, me.name,
                                MSG_SWHOIS, TOK_SWHOIS, "%s :%s", sptr->name, aconf->swhois);
                }
 
@@ -288,6 +267,12 @@ DLLFUNC int  m_oper(aClient *cptr, aClient *sptr, int parc, char *parv[]) {
                        sptr->user->snomask |= SNO_SNOTICE; /* set +s if needed */
                        sptr->umodes |= UMODE_SERVNOTICE;
                }
+               /* This is for users who have both 'admin' and 'coadmin' in their conf */
+               if (IsCoAdmin(sptr) && IsAdmin(sptr))
+               {
+                       sptr->umodes &= ~UMODE_COADMIN;
+                       sptr->oflag &= ~OFLAG_COADMIN;
+               }
                send_umode_out(cptr, sptr, old);
                sendto_one(sptr, rpl_str(RPL_SNOMASK),
                        me.name, parv[0], get_sno_str(sptr));
@@ -295,6 +280,7 @@ DLLFUNC int  m_oper(aClient *cptr, aClient *sptr, int parc, char *parv[]) {
 #ifndef NO_FDLIST
                addto_fdlist(sptr->slot, &oper_fdlist);
 #endif
+               RunHook2(HOOKTYPE_LOCAL_OPER, sptr, 1);
                sendto_one(sptr, rpl_str(RPL_YOUREOPER), me.name, parv[0]);
                if (IsInvisible(sptr) && !(old & UMODE_INVISIBLE))
                        IRCstats.invisible++;
@@ -324,6 +310,8 @@ DLLFUNC int  m_oper(aClient *cptr, aClient *sptr, int parc, char *parv[]) {
                        sendto_one(sptr,
                            ":%s %s %s :*** Your attempt has been logged.", me.name,
                            IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name);
+               ircd_log(LOG_OPER, "OPER FAILEDAUTH (%s) by (%s!%s@%s)", name, parv[0],
+                       sptr->user->username, sptr->sockhost);
                sendto_realops
                    ("Failed OPER attempt by %s (%s@%s) using UID %s [FAILEDAUTH]",
                    parv[0], sptr->user->username, sptr->sockhost, name);
index 8d17b22c56358d3fcfebafa4bdaf13c3f31cc4b2..bcbb39b99041599f91fa1091234fd5722c0c1eee 100644 (file)
@@ -56,13 +56,7 @@ DLLFUNC int m_nospoof(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_PONG        "PONG"  /* PONG */
 #define TOK_PONG        "9"     /* 57 */  
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_pingpong_Header
-#else
-#define m_pingpong_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_pingpong)
   = {
        "pingpong",     /* Name of module */
        "$Id$", /* Version */
@@ -71,17 +65,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_pingpong_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_pingpong)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -95,37 +80,28 @@ int    m_pingpong_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_pingpong_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_pingpong)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
 
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_pingpong_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_pingpong)(int module_unload)
 {
        if (del_Command(MSG_PING, TOK_PING, m_ping) < 0)
        {
                sendto_realops("Failed to delete command ping when unloading %s",
-                               m_pingpong_Header.name);
+                               MOD_HEADER(m_pingpong).name);
        }
        if (del_Command(MSG_PONG, TOK_PONG, m_pong) < 0)
        {
                sendto_realops("Failed to delete command pong when unloading %s",
-                               m_pingpong_Header.name);
+                               MOD_HEADER(m_pingpong).name);
        }
        return MOD_SUCCESS;
 }
 
-
 /*
 ** m_ping
 **     parv[0] = sender prefix
index 2c905f6809c7fece52c1676bc5708781d59c0ce3..dcabb11356042f9c6383360cf54e2809bf0f3c76 100644 (file)
@@ -49,13 +49,7 @@ DLLFUNC int m_quit(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_QUIT        "QUIT"  /* QUIT */
 #define TOK_QUIT        ","     /* 44 */
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_quit_Header
-#else
-#define m_quit_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_quit)
   = {
        "quit", /* Name of module */
        "$Id$", /* Version */
@@ -64,17 +58,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_quit_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_quit)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -85,34 +70,22 @@ int    m_quit_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_quit_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_quit)(int module_load)
 {
        return MOD_SUCCESS;
-       
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_quit_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_quit)(int module_unload)
 {
        if (del_Command(MSG_QUIT, TOK_QUIT, m_quit) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_quit_Header.name);
+                               MOD_HEADER(m_quit).name);
        }
        return MOD_SUCCESS;
-       
 }
 
-
 /*
 ** m_quit
 **     parv[0] = sender prefix
@@ -122,6 +95,7 @@ DLLFUNC int  m_quit(aClient *cptr, aClient *sptr, int parc, char *parv[])
 {
        char *ocomment = (parc > 1 && parv[1]) ? parv[1] : parv[0];
        static char comment[TOPICLEN + 1];
+       Membership *lp;
 
        if (!IsServer(cptr))
        {
@@ -144,6 +118,34 @@ DLLFUNC int  m_quit(aClient *cptr, aClient *sptr, int parc, char *parv[])
                if (!IsAnOper(sptr) && ANTI_SPAM_QUIT_MSG_TIME)
                        if (sptr->firsttime+ANTI_SPAM_QUIT_MSG_TIME > TStime())
                                ocomment = parv[0];
+
+               /* Strip color codes if any channel is +S, use nick as reason if +c. */
+               if (strchr(ocomment, '\003'))
+               {
+                       unsigned char filtertype = 0; /* 1=filter, 2=block, highest wins. */
+                       for (lp = sptr->user->channel; lp; lp = lp->next)
+                       {
+                               if (lp->chptr->mode.mode & MODE_NOCOLOR)
+                               {
+                                       filtertype = 2;
+                                       break;
+                               }
+                               if (lp->chptr->mode.mode & MODE_STRIP)
+                               {
+                                       if (!filtertype)
+                                               filtertype = 1;
+                               }
+                       }
+                       if (filtertype == 1)
+                       {
+                               ocomment = StripColors(ocomment);
+                               if (*ocomment == '\0')
+                                       ocomment = parv[0];
+                       } else {
+                               ocomment = parv[0];
+                       }
+               } /* (strip color codes) */
+
                strncpy(s, ocomment, TOPICLEN - (s - comment));
                comment[TOPICLEN] = '\0';
                return exit_client(cptr, sptr, sptr, comment);
index 0f32e5b94fd6f34a51ab8dac1a719a41697004bd..363b4dd8d64b3642c662399ba8baeb424d69c42a 100644 (file)
@@ -49,13 +49,7 @@ DLLFUNC int m_rakill(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_RAKILL      "RAKILL"        /* RAKILL */
 #define TOK_RAKILL      "Y"     /* 89 */
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_rakill_Header
-#else
-#define m_rakill_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_rakill)
   = {
        "rakill",       /* Name of module */
        "$Id$", /* Version */
@@ -64,55 +58,33 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_rakill_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_rakill)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
        */
        add_Command(MSG_RAKILL, TOK_RAKILL, m_rakill, MAXPARA);
        return MOD_SUCCESS;
-       
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_rakill_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_rakill)(int module_load)
 {
        return MOD_SUCCESS;
-       
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_rakill_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_rakill)(int module_unload)
 {
        if (del_Command(MSG_RAKILL, TOK_RAKILL, m_rakill) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_rakill_Header.name);
+                               MOD_HEADER(m_rakill).name);
        }
        return MOD_SUCCESS;
-       
 }
 
-
 /*
 ** m_rakill;
 **      parv[0] = sender prefix
index 8c23d88c1406ed3cf9e8179a2ac68601b0a2a692..10d42db86f162006beb5840940f9a313d1862179 100644 (file)
@@ -54,12 +54,7 @@ DLLFUNC char *militime(char *sec, char *usec);
 #define MSG_RPONG       "RPONG"
 #define TOK_RPONG       "AN"
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_rping_Header
-#else
-#define m_rping_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_rping)
   = {
        "rping",        /* Name of module */
        "$Id$", /* Version */
@@ -68,17 +63,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_rping_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_rping)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -86,40 +72,29 @@ int    m_rping_Init(ModuleInfo *modinfo)
        add_Command(MSG_RPING, TOK_RPING, m_rping, MAXPARA);
        add_Command(MSG_RPONG, TOK_RPONG, m_rpong, MAXPARA);
        return MOD_SUCCESS;
-       
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_rping_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_rping)(int module_load)
 {
        return MOD_SUCCESS;
-       
 }
 
 
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_rping_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_rping)(int module_unload)
 {
        if (del_Command(MSG_RPING, TOK_RPING, m_rping) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_rping_Header.name);
+                               MOD_HEADER(m_rping).name);
        }
        if (del_Command(MSG_RPONG, TOK_RPONG, m_rpong) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_rping_Header.name);
+                               MOD_HEADER(m_rping).name);
        }
        return MOD_SUCCESS;     
-       
 }
 
 /*
index 3f7badbe77d8ced6ba32fd886d812bddbb8c4895..62e74cc5a31abf5a13dfecc252464ea02f0b2bf8 100644 (file)
@@ -50,12 +50,7 @@ DLLFUNC int m_sdesc(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_SDESC      "SDESC" /* sdesc */
 #define TOK_SDESC      "AG"    /* 127 4ever !;) */
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_sdesc_Header
-#else
-#define m_sdesc_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_sdesc)
   = {
        "sdesc",        /* Name of module */
        "$Id$", /* Version */
@@ -64,16 +59,7 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-/*
- * The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_sdesc_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_sdesc)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -82,29 +68,19 @@ int    m_sdesc_Init(ModuleInfo *modinfo)
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_sdesc_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_sdesc)(int module_load)
 {
        return MOD_SUCCESS;
-       
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_sdesc_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_sdesc)(int module_unload)
 {
        if (del_Command(MSG_SDESC, TOK_SDESC, m_sdesc) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_sdesc_Header.name);
+                               MOD_HEADER(m_sdesc).name);
        }
        return MOD_SUCCESS;
-       
 }
 
 /* m_sdesc - 15/05/1999 - Stskeeps
index 471715ebef3826b3702750bce491a6fba2039f51..9e6751e5f78a6346901b1b4d647c2c577e7685f1 100644 (file)
@@ -51,14 +51,7 @@ DLLFUNC int m_sendumode(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_SMO         "SMO"
 #define TOK_SMO         "AU"
 
-extern int sno_mask[]; /* someone is going to make this static, I just know it */
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_sendumode_Header
-#else
-#define m_sendumode_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_sendumode)
   = {
        "sendumode",    /* Name of module */
        "$Id$", /* Version */
@@ -67,17 +60,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_sendumode_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_sendumode)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -88,32 +72,23 @@ int    m_sendumode_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_sendumode_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_sendumode)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_sendumode_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_sendumode)(int module_unload)
 {
        if (del_Command(MSG_SENDUMODE, TOK_SENDUMODE, m_sendumode) < 0)
        {
                sendto_realops("Failed to delete command sendumode when unloading %s",
-                               m_sendumode_Header.name);
+                               MOD_HEADER(m_sendumode).name);
        }
        if (del_Command(MSG_SMO, TOK_SMO, m_sendumode) < 0)
        {
                sendto_realops("Failed to delete command smo when unloading %s",
-                               m_sendumode_Header.name);
+                               MOD_HEADER(m_sendumode).name);
        }
        return MOD_SUCCESS;
        
@@ -162,21 +137,24 @@ DLLFUNC int m_sendumode(aClient *cptr, aClient *sptr, int parc, char *parv[])
        {
                umode_s = 0;
                
-               for(i = 0; Usermode_Table[i].flag; i++)
+               for(i = 0; i <= Usermode_highest; i++)
                {
+                       if (!Usermode_Table[i].flag)
+                               continue;
                        if (Usermode_Table[i].flag == *p)
                        {
                                umode_s |= Usermode_Table[i].mode;
+                               break;
                        }
                }
-               if (Usermode_Table[i].flag)
-                       break;
+               if (i <= Usermode_highest)
+                       continue;
 
-               for (i = 1; sno_mask[i]; i += 2)
+               for(i = 0; i <= Snomask_highest; i++)
                {
-                       if (sno_mask[i] ==  *p)         
+                       if (Snomask_Table[i].flag == *p)
                        {
-                               snomask |= sno_mask[i - 1];
+                               snomask |= Snomask_Table[i].mode;
                                break;
                        }
                }
@@ -185,11 +163,11 @@ DLLFUNC int m_sendumode(aClient *cptr, aClient *sptr, int parc, char *parv[])
        if (parc > 3)
            for(p = parv[2]; *p; p++)
        {
-               for (i = 1; sno_mask[i]; i += 2)
+               for (i = 0; i <= Snomask_highest; i++)
                {
-                       if (sno_mask[i] ==  *p)         
+                       if (Snomask_Table[i].flag == *p)
                        {
-                               snomask |= sno_mask[i - 1];
+                               snomask |= Snomask_Table[i].mode;
                                break;
                        }
                }
index f2a1ac7060e9c955aaaac6bd63c0b0270bf35e73..ab52ec53ffcbd2059a4af72c9fc62f7dd3690b70 100644 (file)
@@ -49,12 +49,8 @@ DLLFUNC int m_sethost(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 /* Place includes here */
 #define MSG_SETHOST    "SETHOST"       /* sethost */
 #define TOK_SETHOST    "AA"    /* 127 4ever !;) */
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_sethost_Header
-#define Mod_Header m_sethost_Header
-#else
-ModuleHeader Mod_Header
-#endif
+
+ModuleHeader MOD_HEADER(m_sethost)
   = {
        "sethost",      /* Name of module */
        "$Id$", /* Version */
@@ -63,48 +59,28 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-/*
- * The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_sethost_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_sethost)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
        */
        add_Command(MSG_SETHOST, TOK_SETHOST, m_sethost, MAXPARA);
        return MOD_SUCCESS;
-       
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_sethost_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_sethost)(int module_load)
 {
        return MOD_SUCCESS;
-        
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_sethost_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_sethost)(int module_unload)
 {
        if (del_Command(MSG_SETHOST, TOK_SETHOST, m_sethost) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               Mod_Header.name);
+                               MOD_HEADER(m_sethost).name);
        }
        return MOD_SUCCESS;
-        
 }
 
 /*
index 0a6142f401ff534e83ec53606376d0d9b350f23c..f8040c4e3161ee10b7c5b1cfcc3f51bd3229b932 100644 (file)
 #define        TOK_SETIDENT    "AD"    /* good old BASIC ;P */
 
 DLLFUNC int m_setident(aClient *cptr, aClient *sptr, int parc, char *parv[]);
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_setident_Header
-#else
-#define m_setident_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+
+ModuleHeader MOD_HEADER(m_setident)
   = {
        "setident",     /* Name of module */
        "$Id$", /* Version */
@@ -62,47 +58,28 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-/*
- * The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_setident_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_setident)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
        */
        add_Command(MSG_SETIDENT, TOK_SETIDENT, m_setident, MAXPARA);
        return MOD_SUCCESS;
-       
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_setident_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_setident)(int module_load)
 {
        return MOD_SUCCESS;
-       
 }
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_setident_Unload(int module_unload)
-#endif
+
+DLLFUNC int MOD_UNLOAD(m_setident)(int module_unload)
 {
        if (del_Command(MSG_SETIDENT, TOK_SETIDENT, m_setident) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_setident_Header.name);
+                               MOD_HEADER(m_setident).name);
        }
        return MOD_SUCCESS;
-       
 }
 
 /* m_setident - 12/05/1999 - Stskeeps
index c0c6f491cd3ca04ed72631e5888a932d13142361..671eaf40bccc9e0577da06690e94c8e5d97d5019 100644 (file)
@@ -50,12 +50,7 @@ DLLFUNC int m_setname(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_SETNAME    "SETNAME"       /* setname */
 #define TOK_SETNAME    "AE"    
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_setname_Header
-#else
-#define m_setname_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_setname)
   = {
        "setname",      /* Name of module */
        "$Id$", /* Version */
@@ -64,16 +59,7 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-/*
- * The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_setname_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_setname)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -82,29 +68,20 @@ int    m_setname_Init(ModuleInfo *modinfo)
        return MOD_SUCCESS;
        
 }
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_setname_Load(int module_load)
-#endif
+
+DLLFUNC int MOD_LOAD(m_setname)(int module_load)
 {
        return MOD_SUCCESS;
-       
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_setname_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_setname)(int module_unload)
 {
        if (del_Command(MSG_SETNAME, TOK_SETNAME, m_setname) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_setname_Header.name);
+                               MOD_HEADER(m_setname).name);
        }
        return MOD_SUCCESS;
-       
 }
 
 /* m_setname - 12/05/1999 - Stskeeps
index 635ffc27bc24a9db7be400e9f9dab7a293c232b4..60b07171e2224cde0e6ecd1ffc8b719b55f350b4 100644 (file)
@@ -50,12 +50,8 @@ DLLFUNC int m_sqline(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define TOK_SQLINE      "c"     /* 98 */
 
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_sqline_Header
-#else
-#define m_sqline_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+
+ModuleHeader MOD_HEADER(m_sqline)
   = {
        "sqline",       /* Name of module */
        "$Id$", /* Version */
@@ -64,52 +60,32 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_sqline_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_sqline)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
        */
        add_Command(MSG_SQLINE, TOK_SQLINE, m_sqline, MAXPARA);
        return MOD_SUCCESS;
-       
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_sqline_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_sqline)(int module_load)
 {
        return MOD_SUCCESS;
-       
 }
 
 
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_sqline_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_sqline)(int module_unload)
 {
        if (del_Command(MSG_SQLINE, TOK_SQLINE, m_sqline) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_sqline_Header.name);
+                               MOD_HEADER(m_sqline).name);
        }
        return MOD_SUCCESS;
-       
 }
 
 /*    m_sqline
index 2f12f657d71e07261f789c69c1490065ceb79372..fda2180c304724f69f7971a9bb22580f88c1db41 100644 (file)
@@ -49,12 +49,7 @@ DLLFUNC int m_svsjoin(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_SVSJOIN       "SVSJOIN"
 #define TOK_SVSJOIN       "BR"
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_svsjoin_Header
-#else
-#define m_svsjoin_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_svsjoin)
   = {
        "svsjoin",      /* Name of module */
        "$Id$", /* Version */
@@ -63,49 +58,29 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_svsjoin_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_svsjoin)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
        */
        add_Command(MSG_SVSJOIN, TOK_SVSJOIN, m_svsjoin, MAXPARA);
        return MOD_SUCCESS;
-       
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_svsjoin_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_svsjoin)(int module_load)
 {
        return MOD_SUCCESS;
-       
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_svsjoin_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_svsjoin)(int module_unload)
 {
        if (del_Command(MSG_SVSJOIN, TOK_SVSJOIN, m_svsjoin) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_svsjoin_Header.name);
+                               MOD_HEADER(m_svsjoin).name);
        }
        return MOD_SUCCESS;     
 }
index 904d7385534c7ebf1e3810b3bd1a9737210065ef..478a825e52acc7484e4df914aa0a1a6ee42f742e 100644 (file)
@@ -51,13 +51,7 @@ DLLFUNC int m_svslusers(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_SVSLUSERS  "SVSLUSERS"     
 #define TOK_SVSLUSERS  "BU"    
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_svslusers_Header
-#else
-#define m_svslusers_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_svslusers)
   = {
        "m_svslusers",
        "$Id$",
@@ -66,35 +60,23 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_svslusers_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_svslusers)(ModuleInfo *modinfo)
 {
        add_Command(MSG_SVSLUSERS, TOK_SVSLUSERS, m_svslusers, MAXPARA);
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_svslusers_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_svslusers)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_svslusers_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_svslusers)(int module_unload)
 {
        if (del_Command(MSG_SVSLUSERS, TOK_SVSLUSERS, m_svslusers) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_svslusers_Header.name);
+                               MOD_HEADER(m_svslusers).name);
        }
        return MOD_SUCCESS;
 }
index 9d7c3a4a13a50610fcc51dff9e51fcda71a066c1..22bf1187cb9b913f85789df3d9f43987ea54d264 100644 (file)
@@ -55,12 +55,7 @@ extern ircstats IRCstats;
 #define MSG_SVS2MODE    "SVS2MODE"
 #define TOK_SVS2MODE   "v"
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_svsmode_Header
-#else
-#define m_svsmode_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_svsmode)
   = {
        "m_svsmode",
        "$Id$",
@@ -69,36 +64,24 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_svsmode_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_svsmode)(ModuleInfo *modinfo)
 {
        add_Command(MSG_SVSMODE, TOK_SVSMODE, m_svsmode, MAXPARA);
        add_Command(MSG_SVS2MODE, TOK_SVS2MODE, m_svs2mode, MAXPARA);
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int m_svsmode_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_svsmode)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_svsmode_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_svsmode)(int module_unload)
 {
        if (del_Command(MSG_SVSMODE, TOK_SVSMODE, m_svsmode) < 0 || del_Command(MSG_SVS2MODE, TOK_SVS2MODE, m_svs2mode) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_svsmode_Header.name);
+                               MOD_HEADER(m_svsmode).name);
        }
        return MOD_SUCCESS;
 }
@@ -351,18 +334,28 @@ int  m_svsmode(aClient *cptr, aClient *sptr, int parc, char *parv[])
                                       && !(acptr->umodes & UMODE_OPER))
                                   {
                                           IRCstats.operators++;
-                                          addto_fdlist(acptr->slot, &oper_fdlist);
+#ifndef NO_FDLIST
+                                         if (MyClient(acptr))
+                                                 addto_fdlist(acptr->slot, &oper_fdlist);
+#endif
                                   }
                                   if (what == MODE_DEL
                                       && (acptr->umodes & UMODE_OPER))
                                   {
                                           IRCstats.operators--;
-                                          delfrom_fdlist(acptr->slot, &oper_fdlist);
+                                          VERIFY_OPERCOUNT(acptr, "svsmode1");
+#ifndef NO_FDLIST
+                                         if (MyClient(acptr))
+                                                 delfrom_fdlist(acptr->slot, &oper_fdlist);
+#endif
                                   }
                                   goto setmodex;
                          case 'H':
                                  if (what == MODE_ADD && !(acptr->umodes & UMODE_HIDEOPER))
+                                 {
                                        IRCstats.operators--;
+                                       VERIFY_OPERCOUNT(acptr, "svsmode2");
+                                 }
                                  if (what == MODE_DEL && (acptr->umodes & UMODE_HIDEOPER))
                                        IRCstats.operators++;
                                  goto setmodex;
@@ -483,18 +476,28 @@ int  m_svs2mode(aClient *cptr, aClient *sptr, int parc, char *parv[])
                                       && !(acptr->umodes & UMODE_OPER))
                                   {
                                           IRCstats.operators++;
-                                          addto_fdlist(acptr->slot, &oper_fdlist);
+#ifndef NO_FDLIST
+                                         if (MyClient(acptr))
+                                                 addto_fdlist(acptr->slot, &oper_fdlist);
+#endif
                                   }
                                   if (what == MODE_DEL
                                       && (acptr->umodes & UMODE_OPER))
                                   {
                                           IRCstats.operators--;
-                                          delfrom_fdlist(acptr->slot, &oper_fdlist);
+                                          VERIFY_OPERCOUNT(acptr, "svsmode3");
+#ifndef NO_FDLIST
+                                         if (MyClient(acptr))
+                                                 delfrom_fdlist(acptr->slot, &oper_fdlist);
+#endif
                                   }
                                  goto setmodey;
                          case 'H':
                                  if (what == MODE_ADD && !(acptr->umodes & UMODE_HIDEOPER))
+                                 {
                                        IRCstats.operators--;
+                                       VERIFY_OPERCOUNT(acptr, "svsmode4");
+                                 }
                                  if (what == MODE_DEL && (acptr->umodes & UMODE_HIDEOPER))
                                        IRCstats.operators++;
                                  goto setmodey;
index 39da8b55e814ccf335b64b35f4775c4908d290cb..ab413130d0a3e33e21da39d8aba7080cc88f5b18 100644 (file)
@@ -52,12 +52,7 @@ DLLFUNC int m_svsmotd(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_SVSMOTD    "SVSMOTD"       
 #define TOK_SVSMOTD    "AS"    
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_svsmotd_Header
-#else
-#define m_svsmotd_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_svsmotd)
   = {
        "m_svsmotd",
        "$Id$",
@@ -66,35 +61,23 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_svsmotd_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_svsmotd)(ModuleInfo *modinfo)
 {
        add_Command(MSG_SVSMOTD, TOK_SVSMOTD, m_svsmotd, MAXPARA);
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_svsmotd_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_svsmotd)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_svsmotd_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_svsmotd)(int module_unload)
 {
        if (del_Command(MSG_SVSMOTD, TOK_SVSMOTD, m_svsmotd) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_svsmotd_Header.name);
+                               MOD_HEADER(m_svsmotd).name);
        }
        return MOD_SUCCESS;
 }
@@ -141,8 +124,12 @@ int  m_svsmotd(aClient *cptr, aClient *sptr, int parc, char *parv[])
           default:
                   return 0;
         }
-        sendto_serv_butone_token(cptr, parv[0], MSG_SVSMOTD, TOK_SVSMOTD,
-            "%s :%s", parv[1], parv[2]);
+               if (parv[2])
+               sendto_serv_butone_token(cptr, parv[0], MSG_SVSMOTD, TOK_SVSMOTD,
+                   "%s :%s", parv[1], parv[2]);
+               else
+               sendto_serv_butone_token(cptr, parv[0], MSG_SVSMOTD, TOK_SVSMOTD,
+                   "%s", parv[1]);
 
         if (conf == NULL)
         {
index a4bcb5734bf8707f664b77318e096d6c1718f9bf..58e2ffc87bbbec84fb289047c96b93faa035fadf 100644 (file)
@@ -51,13 +51,7 @@ DLLFUNC int m_svsnick(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_SVSNICK    "SVSNICK"       
 #define TOK_SVSNICK    "e"     
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_svsnick_Header
-#else
-#define m_svsnick_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_svsnick)
   = {
        "m_svsnick",
        "$Id$",
@@ -66,35 +60,23 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_svsnick_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_svsnick)(ModuleInfo *modinfo)
 {
        add_Command(MSG_SVSNICK, TOK_SVSNICK, m_svsnick, MAXPARA);
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_svsnick_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_svsnick)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_svsnick_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_svsnick)(int module_unload)
 {
        if (del_Command(MSG_SVSNICK, TOK_SVSNICK, m_svsnick) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_svsnick_Header.name);
+                               MOD_HEADER(m_svsnick).name);
        }
        return MOD_SUCCESS;
 }
index 222eedc8856fa01854e5f99027b252aa625cc895..634fe838f14bee984d0f03caf20be3797d8cca36 100644 (file)
@@ -52,12 +52,7 @@ DLLFUNC int m_svsnline(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_SVSNLINE   "SVSNLINE"      /* svsnline */
 #define TOK_SVSNLINE   "BR"    /* 127 4ever !;) */
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_svsnline_Header
-#else
-#define m_svsnline_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_svsnline)
   = {
        "svsnline",     /* Name of module */
        "$Id$", /* Version */
@@ -66,17 +61,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_svsnline_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_svsnline)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -86,27 +72,18 @@ int    m_svsnline_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_svsnline_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_svsnline)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_svsnline_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_svsnline)(int module_unload)
 {
        if (del_Command(MSG_SVSNLINE, TOK_SVSNLINE, m_svsnline) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_svsnline_Header.name);
+                               MOD_HEADER(m_svsnline).name);
        }
        return MOD_SUCCESS;
 }
index b32b0f0f197bd73ca161ab6953e926cdd7651ac9..16db1465f27a0603d6c1b47ca3f2f57bedee1838 100644 (file)
@@ -55,13 +55,7 @@ DLLFUNC int m_svsnoop(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 extern ircstats IRCstats;
 extern int SVSNOOP;
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_svsnoop_Header
-#else
-#define m_svsnoop_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_svsnoop)
   = {
        "m_svsnoop",
        "$Id$",
@@ -70,35 +64,23 @@ ModuleHeader Mod_Header
        NULL
     };
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_svsnoop_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_svsnoop)(ModuleInfo *modinfo)
 {
        add_Command(MSG_SVSNOOP, TOK_SVSNOOP, m_svsnoop, MAXPARA);
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_svsnoop_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_svsnoop)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_svsnoop_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_svsnoop)(int module_unload)
 {
        if (del_Command(MSG_SVSNOOP, TOK_SVSNOOP, m_svsnoop) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_svsnoop_Header.name);
+                               MOD_HEADER(m_svsnoop).name);
        }
        return MOD_SUCCESS;
 }
@@ -123,6 +105,7 @@ int m_svsnoop(aClient *cptr, aClient *sptr, int parc, char *parv[])
                                         if (IsAnOper(acptr))
                                         {
                                                 IRCstats.operators--;
+                                                VERIFY_OPERCOUNT(acptr, "svsnoop");
                                                 delfrom_fdlist(acptr->slot, &oper_fdlist);
                                         }
                                         acptr->umodes &=
@@ -133,9 +116,9 @@ int m_svsnoop(aClient *cptr, aClient *sptr, int parc, char *parv[])
                                         acptr->umodes &=
                                             ~(UMODE_KIX | UMODE_DEAF | UMODE_HIDEOPER);
                                         acptr->oflag = 0;
-                                       acptr->user->snomask &= ~(SNO_CLIENT|SNO_FLOOD|SNO_FCLIENT|
-                                                SNO_EYES|SNO_VHOST);
-
+                                        acptr->user->snomask &= ~(SNO_CLIENT|SNO_FLOOD|SNO_FCLIENT|
+                                                SNO_JUNK|SNO_TKL|SNO_EYES|SNO_VHOST|SNO_NICKCHANGE|SNO_QLINE);
+                                       RunHook2(HOOKTYPE_LOCAL_OPER, acptr, 0);
                                 }
                         }
 
index 20a2b9ffaa8a55ce006b32afce68d08f484c028e..706a241e4fcb4a582787b278a9fb5477b8fcde31 100644 (file)
@@ -87,12 +87,7 @@ static int oper_access[] = {
 
 extern ircstats IRCstats;
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_svso_Header
-#else
-#define m_svso_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_svso)
   = {
        "m_svso",
        "$Id$",
@@ -101,35 +96,23 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_svso_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_svso)(ModuleInfo *modinfo)
 {
        add_Command(MSG_SVSO, TOK_SVSO, m_svso, MAXPARA);
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_svso_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_svso)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_svso_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_svso)(int module_unload)
 {
        if (del_Command(MSG_SVSO, TOK_SVSO, m_svso) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_svso_Header.name);
+                               MOD_HEADER(m_svso).name);
        }
        return MOD_SUCCESS;
 }
@@ -180,7 +163,10 @@ int m_svso(aClient *cptr, aClient *sptr, int parc, char *parv[])
         {
                 fLag = acptr->umodes;
                 if (IsOper(acptr) && !IsHideOper(acptr))
+                {
                         IRCstats.operators--;
+                        VERIFY_OPERCOUNT(acptr, "svso");
+                }
                 if (IsAnOper(acptr))
                         delfrom_fdlist(acptr->slot, &oper_fdlist);
                 acptr->umodes &=
@@ -191,7 +177,8 @@ int m_svso(aClient *cptr, aClient *sptr, int parc, char *parv[])
                 acptr->umodes &=
                     ~(UMODE_KIX | UMODE_DEAF | UMODE_HIDEOPER);
                 acptr->oflag = 0;
-                acptr->user->snomask &= ~(SNO_CLIENT|SNO_FLOOD|SNO_FCLIENT|SNO_EYES|SNO_VHOST);
+               acptr->user->snomask &= ~(SNO_CLIENT|SNO_FLOOD|SNO_FCLIENT|SNO_JUNK|SNO_EYES|SNO_VHOST|SNO_NICKCHANGE|SNO_QLINE|SNO_TKL);
+               RunHook2(HOOKTYPE_LOCAL_OPER, acptr, 0);
                 send_umode_out(acptr, acptr, fLag);
         }
        return 0;
index 3c5c22f75fd86ec6b3428381e2a6b385bb5bd528..3c748bf29ce2e42456ee7dc441f0326e0d2e6d5d 100644 (file)
@@ -49,12 +49,7 @@ DLLFUNC int m_svspart(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_SVSPART       "SVSPART"
 #define TOK_SVSPART       "BT"
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_svspart_Header
-#else
-#define m_svspart_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_svspart)
   = {
        "svspart",      /* Name of module */
        "$Id$", /* Version */
@@ -63,49 +58,29 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_svspart_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_svspart)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
        */
        add_Command(MSG_SVSPART, TOK_SVSPART, m_svspart, MAXPARA);
        return MOD_SUCCESS;
-       
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_svspart_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_svspart)(int module_load)
 {
        return MOD_SUCCESS;
-       
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_svspart_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_svspart)(int module_unload)
 {
        if (del_Command(MSG_SVSPART, TOK_SVSPART, m_svspart) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_svspart_Header.name);
+                               MOD_HEADER(m_svspart).name);
        }
        return MOD_SUCCESS;     
 }
index 8d1b2f974ed3b169736315801ecab918fae27485..b6a3489d65b7709cd11c573b05d072b4fac74157 100644 (file)
@@ -49,12 +49,7 @@ DLLFUNC int m_svssilence(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_SVSSILENCE       "SVSSILENCE"
 #define TOK_SVSSILENCE       "Bs"
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_svssilence_Header
-#else
-#define m_svssilence_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_svssilence)
   = {
        "svssilence",   /* Name of module */
        "$Id$", /* Version */
@@ -63,49 +58,29 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_svssilence_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_svssilence)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
        */
        add_Command(MSG_SVSSILENCE, TOK_SVSSILENCE, m_svssilence, MAXPARA);
        return MOD_SUCCESS;
-       
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_svssilence_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_svssilence)(int module_load)
 {
        return MOD_SUCCESS;
-       
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_svssilence_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_svssilence)(int module_unload)
 {
        if (del_Command(MSG_SVSSILENCE, TOK_SVSSILENCE, m_svssilence) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_svssilence_Header.name);
+                               MOD_HEADER(m_svssilence).name);
        }
        return MOD_SUCCESS;     
 }
index 645281031721bca28e02c9173246225eda515429..4d0d554494a9d0b9575199f263c2fcdfa5f7979e 100644 (file)
@@ -49,12 +49,7 @@ DLLFUNC int m_svswatch(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_SVSWATCH       "SVSWATCH"
 #define TOK_SVSWATCH       "BW"
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_svswatch_Header
-#else
-#define m_svswatch_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_svswatch)
   = {
        "svswatch",     /* Name of module */
        "$Id$", /* Version */
@@ -63,17 +58,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_svswatch_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_svswatch)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -84,28 +70,19 @@ int    m_svswatch_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_svswatch_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_svswatch)(int module_load)
 {
        return MOD_SUCCESS;
        
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_svswatch_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_svswatch)(int module_unload)
 {
        if (del_Command(MSG_SVSWATCH, TOK_SVSWATCH, m_svswatch) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_svswatch_Header.name);
+                               MOD_HEADER(m_svswatch).name);
        }
        return MOD_SUCCESS;     
 }
index f2070611e8ed88847c655335dd342511d93d9276..a36cd32fb379b1d4f4f5b7be3303ad8c5e8f5b88 100644 (file)
@@ -51,12 +51,7 @@ DLLFUNC int m_swhois(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_SWHOIS     "SWHOIS"        
 #define TOK_SWHOIS     "BA"    
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_swhois_Header
-#else
-#define m_swhois_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_swhois)
   = {
        "m_swhois",
        "$Id$",
@@ -65,35 +60,23 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_swhois_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_swhois)(ModuleInfo *modinfo)
 {
        add_Command(MSG_SWHOIS, TOK_SWHOIS, m_swhois, MAXPARA);
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_swhois_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_swhois)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_swhois_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_swhois)(int module_unload)
 {
        if (del_Command(MSG_SWHOIS, TOK_SWHOIS, m_swhois) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_swhois_Header.name);
+                               MOD_HEADER(m_swhois).name);
        }
        return MOD_SUCCESS;
 }
index 4b975acd8c69023e2511423bcd34a3597d051a76..bbfe8e31688746efb4c0001ab6aa4ee5c1991bdd 100644 (file)
@@ -45,12 +45,7 @@ DLLFUNC int m_tkl_line(aClient *cptr, aClient *sptr, int parc, char *parv[], cha
 #define MSG_ZLINE "ZLINE"
 #define TOK_NONE ""
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_tkl_Header
-#else
-#define m_tkl_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_tkl)
   = {
        "tkl",  /* Name of module */
        "$Id$", /* Version */
@@ -59,17 +54,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_tkl_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_tkl)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -83,22 +69,13 @@ int    m_tkl_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_tkl_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_tkl)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_tkl_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_tkl)(int module_unload)
 {
        if ((del_Command(MSG_GLINE, TOK_GLINE, m_gline) < 0) ||
            (del_Command(MSG_SHUN, TOK_SHUN, m_shun) < 0 ) ||
@@ -108,7 +85,7 @@ int  m_tkl_Unload(int module_unload)
 
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_tkl_Header.name);
+                               MOD_HEADER(m_tkl).name);
        }
        return MOD_SUCCESS;
 }
@@ -137,7 +114,7 @@ DLLFUNC int m_gline(aClient *cptr, aClient *sptr, int parc, char *parv[])
 
        if (parc == 1)
        {
-               tkl_stats(sptr);
+               tkl_stats(sptr, TKL_KILL|TKL_GLOBAL, NULL);
                sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'g');
                return 0;
        }
@@ -160,7 +137,7 @@ DLLFUNC int m_gzline(aClient *cptr, aClient *sptr, int parc, char *parv[])
 
        if (parc == 1)
        {
-               tkl_stats(sptr);
+               tkl_stats(sptr, TKL_GLOBAL|TKL_ZAP, NULL);
                sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'g');
                return 0;
        }
@@ -183,7 +160,7 @@ DLLFUNC int m_shun(aClient *cptr, aClient *sptr, int parc, char *parv[])
 
        if (parc == 1)
        {
-               tkl_stats(sptr);
+               tkl_stats(sptr, TKL_GLOBAL|TKL_SHUN, NULL);
                sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'g');
                return 0;
        }
@@ -206,7 +183,7 @@ DLLFUNC int m_tkline(aClient *cptr, aClient *sptr, int parc, char *parv[])
 
        if (parc == 1)
        {
-               tkl_stats(sptr);
+               tkl_stats(sptr, TKL_KILL, NULL);
                sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'g');
                return 0;
        }
@@ -233,7 +210,7 @@ DLLFUNC int m_tzline(aClient *cptr, aClient *sptr, int parc, char *parv[])
 
        if (parc == 1)
        {
-               tkl_stats(sptr);
+               tkl_stats(sptr, TKL_ZAP, NULL);
                sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'g');
                return 0;
        }
@@ -276,7 +253,7 @@ DLLFUNC int  m_tkl_line(aClient *cptr, aClient *sptr, int parc, char *parv[], ch
 
        if (parc == 1)
        {
-               tkl_stats(sptr);
+               tkl_stats(sptr, 0, NULL);
                sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'g');
                return 0;
        }
@@ -374,7 +351,12 @@ DLLFUNC int  m_tkl_line(aClient *cptr, aClient *sptr, int parc, char *parv[], ch
        if (whattodo == 0)
        {
                if (secs == 0)
-                       ircsprintf(mo, "%li", secs);
+               {
+                       if (DEFAULT_BANTIME && (parc <= 3))
+                               ircsprintf(mo, "%li", DEFAULT_BANTIME + TStime());
+                       else
+                               ircsprintf(mo, "%li", secs); /* "0" */
+               }
                else
                        ircsprintf(mo, "%li", secs + TStime());
                ircsprintf(mo2, "%li", TStime());
index e750e77c08817c0faa8030d5acba773a242c3a17..00e97d646dbcefbb57b11510031475511e87b479 100644 (file)
@@ -49,13 +49,7 @@ DLLFUNC int m_tsctl(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_TSCTL       "TSCTL"
 #define TOK_TSCTL       "AW"
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_tsctl_Header
-#else
-#define m_tsctl_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_tsctl)
   = {
        "tsctl",        /* Name of module */
        "$Id$", /* Version */
@@ -64,17 +58,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_tsctl_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_tsctl)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -84,27 +69,18 @@ int    m_tsctl_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_tsctl_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_tsctl)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_tsctl_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_tsctl)(int module_unload)
 {
        if (del_Command(MSG_TSCTL, TOK_TSCTL, m_tsctl) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_tsctl_Header.name);
+                               MOD_HEADER(m_tsctl).name);
        }
        return MOD_SUCCESS;
 }
index 9ba286edbdb52a4bcdd35b51331c515b9d784fb8..862c2e51de4178cd0b6e848c525b138e2bad4482 100644 (file)
@@ -49,13 +49,7 @@ DLLFUNC int m_unkline(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_UNKLINE     "UNKLINE"       /* UNKLINE */
 #define TOK_UNKLINE     "X"     /* 88 */  
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_unkline_Header
-#else
-#define m_unkline_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_unkline)
   = {
        "unkline",      /* Name of module */
        "$Id$", /* Version */
@@ -64,17 +58,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_unkline_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_unkline)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -84,27 +69,18 @@ int    m_unkline_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_unkline_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_unkline)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_unkline_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_unkline)(int module_unload)
 {
        if (del_Command(MSG_UNKLINE, TOK_UNKLINE, m_unkline) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_unkline_Header.name);
+                               MOD_HEADER(m_unkline).name);
        }
        return MOD_SUCCESS;
 }
index dcb13e568d51dbc98304637e41a9b70ba08b5bfa..ff42772e64e617bf06892c31cb73c52bc6898b76 100644 (file)
@@ -49,13 +49,7 @@ DLLFUNC int m_unsqline(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_UNSQLINE    "UNSQLINE"      /* UNSQLINE */
 #define TOK_UNSQLINE    "d"     /* 99 */  
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_unsqline_Header
-#else
-#define m_unsqline_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_unsqline)
   = {
        "unsqline",     /* Name of module */
        "$Id$", /* Version */
@@ -64,17 +58,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_unsqline_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_unsqline)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -84,27 +69,18 @@ int    m_unsqline_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_unsqline_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_unsqline)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_unsqline_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_unsqline)(int module_unload)
 {
        if (del_Command(MSG_UNSQLINE, TOK_UNSQLINE, m_unsqline) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_unsqline_Header.name);
+                               MOD_HEADER(m_unsqline).name);
        }
        return MOD_SUCCESS;
 }
index a17a96cc2b47e01c95f60c255318fac4fd8eebf0..fab6da6a0b5f57ef33309b116687b0a180babe21 100644 (file)
@@ -49,13 +49,7 @@ DLLFUNC int m_unzline(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_UNZLINE     "UNZLINE"       /* UNZLINE */
 #define TOK_UNZLINE     "r"     /* 113 */ 
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_unzline_Header
-#else
-#define m_unzline_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_unzline)
   = {
        "unzline",      /* Name of module */
        "$Id$", /* Version */
@@ -64,17 +58,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_unzline_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_unzline)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -84,27 +69,18 @@ int    m_unzline_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_unzline_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_unzline)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_unzline_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_unzline)(int module_unload)
 {
        if (del_Command(MSG_UNZLINE, TOK_UNZLINE, m_unzline) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_unzline_Header.name);
+                               MOD_HEADER(m_unzline).name);
        }
        return MOD_SUCCESS;
 }
index 1ae68b403efd0b97373a338a2a5af05033e60254..24fa916426993369b0079af3cc1855cfa62b7adc 100644 (file)
@@ -49,12 +49,7 @@ DLLFUNC int m_vhost(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_VHOST       "VHOST"
 #define TOK_VHOST       "BE"
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_vhost_Header
-#else
-#define m_vhost_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_vhost)
   = {
        "vhost",        /* Name of module */
        "$Id$", /* Version */
@@ -63,49 +58,30 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_vhost_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_vhost)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
        */
        add_Command(MSG_VHOST, TOK_VHOST, m_vhost, MAXPARA);
        return MOD_SUCCESS;
-       
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_vhost_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_vhost)(int module_load)
 {
        return MOD_SUCCESS;
-       
 }
 
 
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_vhost_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_vhost)(int module_unload)
 {
        if (del_Command(MSG_VHOST, TOK_VHOST, m_vhost) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_vhost_Header.name);
+                               MOD_HEADER(m_vhost).name);
        }
        return MOD_SUCCESS;     
 }
index 7cf9657b5f3fb9c7bd3573c0f313e3ff77c04a46..94b12b7d0c253c57f4c13057606aade6321fc6da 100644 (file)
@@ -45,12 +45,7 @@ DLLFUNC int m_who(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_WHO        "WHO"
 #define TOK_WHO        "\""
 
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_who_Header
-#else
-#define m_who_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_who)
   = {
        "who",  /* Name of module */
        "$Id$", /* Version */
@@ -60,11 +55,7 @@ ModuleHeader Mod_Header
     };
 
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_who_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_who)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -74,27 +65,19 @@ int    m_who_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_who_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_who)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
 
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_who_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_who)(int module_unload)
 {
        if (del_Command(MSG_WHO, TOK_WHO, m_who) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_who_Header.name);
+                               MOD_HEADER(m_who).name);
        }
        return MOD_SUCCESS;
 }
index 8d1167413d45884f15aa4355b1e22f1c27294a19..8e6ce524302eb85fa0996147e12ba0d016c0ea74 100644 (file)
@@ -51,13 +51,7 @@ DLLFUNC int m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[]);
 #define MSG_WHOIS       "WHOIS" /* WHOI */
 #define TOK_WHOIS       "#"     /* 35 */
 
-
-#ifndef DYNAMIC_LINKING
-ModuleHeader m_whois_Header
-#else
-#define m_whois_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(m_whois)
   = {
        "whois",        /* Name of module */
        "$Id$", /* Version */
@@ -66,17 +60,8 @@ ModuleHeader Mod_Header
        NULL 
     };
 
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
 /* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Init(ModuleInfo *modinfo)
-#else
-int    m_whois_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(m_whois)(ModuleInfo *modinfo)
 {
        /*
         * We call our add_Command crap here
@@ -86,27 +71,18 @@ int    m_whois_Init(ModuleInfo *modinfo)
 }
 
 /* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Load(int module_load)
-#else
-int    m_whois_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(m_whois)(int module_load)
 {
        return MOD_SUCCESS;
 }
 
-
 /* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int    Mod_Unload(int module_unload)
-#else
-int    m_whois_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(m_whois)(int module_unload)
 {
        if (del_Command(MSG_WHOIS, TOK_WHOIS, m_whois) < 0)
        {
                sendto_realops("Failed to delete commands when unloading %s",
-                               m_whois_Header.name);
+                               MOD_HEADER(m_whois).name);
        }
        return MOD_SUCCESS;
 }
@@ -119,22 +95,6 @@ int m_whois_Unload(int module_unload)
 */
 DLLFUNC int  m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
 {
-       static anUser UnknownUser = {
-               NULL,           /* channel */
-               NULL,           /* invited */
-               NULL,           /* silence */
-               NULL,           /* away */
-#ifdef NO_FLOOD_AWAY
-               0,              /* last_away */
-               0,              /* away_count */
-#endif
-               0,              /* servicestamp */
-               1,              /* refcount */
-               0,              /* joined */
-               "<Unknown>",    /* username */
-               "<Unknown>",    /* host */
-               "<Unknown>"     /* server */
-       };
        Membership *lp;
        anUser *user;
        aClient *acptr, *a2cptr;
@@ -163,7 +123,7 @@ DLLFUNC int  m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
 
        for (tmp = parv[1]; (nick = strtoken(&p, tmp, ",")); tmp = NULL)
        {
-               int  invis, showchannel, member, wilds;
+               unsigned char invis, showchannel, member, wilds, hideoper; /* <- these are all boolean-alike */
 
                found = 0;
                /* We do not support "WHOIS *" */
@@ -186,7 +146,10 @@ DLLFUNC int  m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
                         *   the target user(s) are on;
                         */
 
-                       user = acptr->user ? acptr->user : &UnknownUser;
+                       if (!IsPerson(acptr))
+                               continue;
+
+                       user = acptr->user;
                        name = (!*acptr->name) ? "?" : acptr->name;
 
                        invis = acptr != sptr && IsInvisible(acptr);
@@ -194,8 +157,9 @@ DLLFUNC int  m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
 
                        a2cptr = find_server_quick(user->server);
 
-                       if (!IsPerson(acptr))
-                               continue;
+                       hideoper = 0;
+                       if (IsHideOper(acptr) && (acptr != sptr) && !IsAnOper(sptr))
+                               hideoper = 1;
 
                        if (IsWhois(acptr) && (sptr != acptr))
                        {
@@ -249,7 +213,7 @@ DLLFUNC int  m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
                                if (acptr == sptr)
                                        showchannel = 1;
                                /* Hey, if you are editting here... don't forget to change the webtv w_whois ;p. */
-                               
+
                                if (showchannel)
                                {
                                        long access;
@@ -313,9 +277,7 @@ DLLFUNC int  m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
                        /* makesure they aren't +H (we'll also check
                           before we display a helpop or IRCD Coder msg)
                           -- codemastr */
-                       if ((IsAnOper(acptr) || IsServices(acptr))
-                           && (!IsHideOper(acptr) || sptr == acptr
-                           || IsAnOper(sptr)))
+                       if ((IsAnOper(acptr) || IsServices(acptr)) && !hideoper)
                        {
                                buf[0] = '\0';
                                if (IsNetAdmin(acptr))
@@ -339,32 +301,21 @@ DLLFUNC int  m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
                                            parv[0], name, buf);
                        }
 
-                       if (IsHelpOp(acptr) && (!IsHideOper(acptr)
-                           || sptr == acptr || IsAnOper(sptr)))
-                               if (!user->away)
-                                       sendto_one(sptr,
-                                           rpl_str(RPL_WHOISHELPOP), me.name,
-                                           parv[0], name);
+                       if (IsHelpOp(acptr) && !hideoper && !user->away)
+                               sendto_one(sptr, rpl_str(RPL_WHOISHELPOP), me.name, parv[0], name);
 
                        if (acptr->umodes & UMODE_BOT)
-                       {
-                               sendto_one(sptr, rpl_str(RPL_WHOISBOT),
-                                   me.name, parv[0], name, ircnetwork);
-                       }
+                               sendto_one(sptr, rpl_str(RPL_WHOISBOT), me.name, parv[0], name, ircnetwork);
+
                        if (acptr->umodes & UMODE_SECURE)
-                       {
                                sendto_one(sptr, ":%s %d %s %s :%s", me.name,
-                                   RPL_WHOISSPECIAL,
-                                   parv[0], name,
-                                   "is a Secure Connection");
-                       }
-                       if (user->swhois && !IsHideOper(acptr))
-                       {
-                               if (*user->swhois != '\0')
+                                   RPL_WHOISSPECIAL, parv[0], name, "is a Secure Connection");
+
+                       if (!BadPtr(user->swhois) && !hideoper)
                                        sendto_one(sptr, ":%s %d %s %s :%s",
                                            me.name, RPL_WHOISSPECIAL, parv[0],
                                            name, acptr->user->swhois);
-                       }
+
                        /*
                         * Fix /whois to not show idle times of
                         * global opers to anyone except another
index 48045edcefe6e0ef06eebbaf76dc1d5b215af907..574f2d22617393b3441886e2ad4a19769b4a1246 100644 (file)
@@ -70,7 +70,7 @@ int  dopacket(aClient *cptr, char *buffer, int length)
                        acpt->receiveB &= 0x03ff;
                }
        }
-       else if (me.receiveB > 1023)
+       if (me.receiveB > 1023)
        {
                me.receiveK += (me.receiveB >> 10);
                me.receiveB &= 0x03ff;
@@ -244,7 +244,7 @@ void        init_CommandHash(void)
        add_Command(MSG_TIME, TOK_TIME, m_time, MAXPARA);
        add_Command(MSG_CONNECT, TOK_CONNECT, m_connect, MAXPARA);
        add_CommandX(MSG_VERSION, TOK_VERSION, m_version, MAXPARA, M_UNREGISTERED|M_USER|M_SERVER);
-       add_Command(MSG_STATS, TOK_STATS, m_stats, MAXPARA);
+       add_Command(MSG_STATS, TOK_STATS, m_stats, 3);
        add_Command(MSG_LINKS, TOK_LINKS, m_links, MAXPARA);
        add_CommandX(MSG_ADMIN, TOK_ADMIN, m_admin, MAXPARA, M_UNREGISTERED|M_USER|M_SHUN);
        add_Command(MSG_SUMMON, NULL, m_summon, 1);
@@ -287,6 +287,7 @@ void        init_CommandHash(void)
        add_Command(MSG_NEWJOIN, TOK_JOIN, m_join, MAXPARA);
        add_Command(MSG_MODULE, TOK_MODULE, m_module, MAXPARA); 
        add_Command(MSG_TKL, TOK_TKL, m_tkl, MAXPARA);
+       add_CommandX(MSG_EOS, TOK_EOS, m_eos, MAXPARA, M_SERVER);
                
 #ifdef DEVELOP_DEBUG
        for (i = 0; i <= 255; i++)
@@ -344,6 +345,7 @@ Command *CommandAdd(Module *module, char *cmd, char *tok, int (*func)(), unsigne
                cmdobj->object.command = command;
                cmdobj->type = MOBJ_COMMAND;
                AddListItem(cmdobj, module->objects);
+               module->errorcode = MODERR_NOERROR;
        }
        return command;
 }
index 8c06957740001297525bf9c3cb33043ed926b494..0a473473e0635708f7940f20a633da9932dee22e 100644 (file)
--- a/src/res.c
+++ b/src/res.c
@@ -40,26 +40,13 @@ static char rcsid[] = "@(#)$Id$";
 #if 0
 #undef DEBUG   /* because there is a lot of debug code in here :-) */
 #endif
-#ifdef _WIN32
-#define HE(x) (x)->he
-#else
 #define HE(x) (&((x)->he))
-#endif
 static char hostbuf[HOSTLEN + 1 + 100];        /* +100 for INET6 */
 static char dot[] = ".";
 static int incache = 0;
 static CacheTable hashtable[ARES_CACSIZE];
 static aCache *cachetop = NULL;
 static ResRQ *last, *first;
-/* control access to request queue - allow only one thread at a time.
-** Currently the list is only protected on Windows because we don't use 
-** threads to access it on Unix
-*/
-#ifdef _WIN32
-static MUTEX g_hResMutex;
-#endif
-static int lock_request();
-static int unlock_request();
 
 static void rem_cache(aCache *);
 static void rem_request(ResRQ *);
@@ -79,14 +66,9 @@ static int hash_number(unsigned char *);
 static void update_list(ResRQ *, aCache *);
 static int hash_name(char *);
 static int bad_hostname(char *, int);
-#ifdef _WIN32
-static void    async_dns(void *parm);
-#endif
 #define CLI_HASH_VALUE local[tcc % 256]
 
-#ifndef _WIN32
 extern TS nextexpire;
-#endif
 
 static struct cacheinfo {
        int  ca_adds;
@@ -117,16 +99,6 @@ int init_resolver(int op)
 {
        int  ret = 0;
 
-#ifdef _WIN32
-       IRCCreateMutex(g_hResMutex);
-       if (g_hResMutex == NULL)
-       {
-               ircd_log(LOG_ERROR, "IRCCreateMutex failed: %s:%i.  %s", 
-                                __FILE__, __LINE__,strerror(GetLastError()));
-               return ret;
-       }
-#endif
-
        if (op & RES_INITLIST)
        {
                bzero((char *)&reinfo, sizeof(reinfo));
@@ -154,7 +126,6 @@ int init_resolver(int op)
 
        if (op & RES_INITSOCK)
        {
-#ifndef _WIN32
                int  on = 0;
 
 #ifdef INET6
@@ -164,7 +135,6 @@ int init_resolver(int op)
                ret = resfd = socket(AF_INET, SOCK_DGRAM, 0);
 #endif
                (void)setsockopt(ret, SOL_SOCKET, SO_BROADCAST, &on, on);
-#endif
        }
 #ifdef DEBUGMODE
        if (op & RES_INITDEBG)
@@ -180,54 +150,10 @@ int init_resolver(int op)
        return ret;
 }
 
-/* get access to resolver request queue */
-static int lock_request()
-{
-       int iRc = 1;
-#ifdef _WIN32
-       DWORD dwWaitRes;
-
-       if (g_hResMutex)
-       {
-               dwWaitRes = IRCMutexLock(g_hResMutex);
-               if (dwWaitRes != WAIT_OBJECT_0)
-               {
-                       ircd_log(LOG_ERROR, "IRCMutexLock failed with %d: %s:%i.  %s", 
-                                        dwWaitRes, __FILE__, __LINE__,strerror(GetLastError()));
-                       iRc = 0;
-               }
-       }
-#endif
-       return iRc;
-}
-
-/* release access to resolver request queue */
-static int unlock_request()
-{
-       int iRc = 1;
-
-#ifdef _WIN32
-       BOOL bRc;
-
-       if (g_hResMutex)
-       {
-               bRc = IRCMutexUnlock(g_hResMutex);
-               if (!bRc)
-               {
-                       ircd_log(LOG_ERROR, "IRCMutexUnlock failed: %s:%i.  %s", 
-                                        __FILE__, __LINE__,strerror(GetLastError()));
-                       iRc = 0;
-               }
-       }
-#endif
-       return iRc;
-}
-
 static int add_request(ResRQ *new)
 {
        if (!new)
                return -1;
-       lock_request();
        if (!first)
                first = last = new;
        else
@@ -237,7 +163,6 @@ static int add_request(ResRQ *new)
        }
        new->next = NULL;
        reinfo.re_requests++;
-       unlock_request();
        return 0;
 }
 
@@ -254,14 +179,6 @@ static void rem_request(ResRQ *old)
        if (!old)
                return;
 
-#ifdef _WIN32
-       /* don't remove if async_dns() thread is running because it needs this memory
-       ** we should consider terminating the thread here esp.
-       ** if exit_client() called us
-       */
-       if (old->locked)
-               return;
-#endif
        for (rptr = &first; *rptr; r2ptr = *rptr, rptr = &(*rptr)->next)
                if (*rptr == old)
                {
@@ -274,16 +191,11 @@ static void rem_request(ResRQ *old)
        Debug((DEBUG_INFO, "rem_request:Remove %#x at %#x %#x", old, *rptr, r2ptr));
 #endif
        r2ptr = old;
-#ifndef _WIN32
        if (r2ptr->he.h_name)
                MyFree(r2ptr->he.h_name);
        for (i = 0; i < MAXALIASES; i++)
                if ((s = r2ptr->he.h_aliases[i]))
                        MyFree(s);
-#else
-       if (r2ptr->he)
-               MyFree(r2ptr->he);
-#endif
        if (r2ptr->name)
                MyFree(r2ptr->name);
        MyFree(r2ptr);
@@ -309,16 +221,9 @@ static ResRQ *make_request(Link *lp)
        else
                bzero((char *)&nreq->cinfo, sizeof(Link));
        nreq->timeout = HOST_TIMEOUT;   /* start at 4 and exponential inc. */
-#ifndef _WIN32
        nreq->he.h_addrtype = AFINET;
        nreq->he.h_name = NULL;
        nreq->he.h_aliases[0] = NULL;
-#else
-        nreq->he = (struct hostent *)MyMalloc(MAXGETHOSTSTRUCT);
-        bzero((char *)nreq->he, MAXGETHOSTSTRUCT);
-        nreq->he->h_addrtype = AFINET;
-        nreq->he->h_name = NULL;
-#endif
        (void)add_request(nreq);
        return nreq;
 }
@@ -334,16 +239,11 @@ time_t timeout_query_list(time_t now)
        aClient *cptr;
 
        Debug((DEBUG_DNS, "timeout_query_list at %s", myctime(now)));
-       lock_request();
        for (rptr = first; rptr; rptr = r2ptr)
        {
                r2ptr = rptr->next;
                tout = rptr->sentat + rptr->timeout;
-#ifndef _WIN32
                if (now >= tout)
-#else
-               if (now >= tout && !rptr->locked)
-#endif
                {
                        if (--rptr->retries <= 0)
                        {
@@ -373,9 +273,7 @@ time_t timeout_query_list(time_t now)
                        {
                                rptr->sentat = now;
                                rptr->timeout += rptr->timeout;
-#ifndef _WIN32
                                resend_query(rptr);
-#endif
                                tout = now + rptr->timeout;
 #ifdef DEBUGMODE
                                Debug((DEBUG_INFO, "r %x now %d retry %d c %x",
@@ -387,7 +285,6 @@ time_t timeout_query_list(time_t now)
                if (!next || tout < next)
                        next = tout;
        }
-       unlock_request();
        return (next > now) ? next : (now + AR_TTL);
 }
 
@@ -399,14 +296,12 @@ void del_queries(char *cp)
 {
        ResRQ *rptr, *r2ptr;
 
-       lock_request();
        for (rptr = first; rptr; rptr = r2ptr)
        {
                r2ptr = rptr->next;
                if (cp == rptr->cinfo.value.cp)
                        rem_request(rptr);
        }
-       unlock_request();
 }
 
 /*
@@ -416,7 +311,6 @@ void del_queries(char *cp)
  * isnt present. Returns number of messages successfully sent to
  * nameservers or -1 if no successful sends.
  */
-#ifndef _WIN32
 static int send_res_msg(char *msg, int len, int rcount)
 {
 #ifdef DEBUGMODE
@@ -469,7 +363,6 @@ static int send_res_msg(char *msg, int len, int rcount)
 #else
                ircd_res.nsaddr_list[i].sin_family = AF_INET;
 #endif
-               ERRNO = 0;
 #ifdef INET6
                if (sendto(resfd, msg, len, 0,
                    (struct sockaddr *)&(ircd_res.nsaddr_list[i]),
@@ -487,12 +380,11 @@ static int send_res_msg(char *msg, int len, int rcount)
                }
                else
                        Debug((DEBUG_ERROR, "s_r_m:sendto: %d on %d",
-                           errno, resfd));
+                           ERRNO, resfd));
        }
 
        return (sent) ? sent : -1;
 }
-#endif
 
 /*
  * find a dns request id (id is determined by dn_mkquery)
@@ -501,11 +393,9 @@ static ResRQ *find_id(int id)
 {
        ResRQ *rptr;
 
-       lock_request();
        for (rptr = first; rptr; rptr = rptr->next)
                if (rptr->id == id)
                        break;
-       unlock_request();
        return rptr;
 }
 
@@ -515,11 +405,7 @@ struct hostent *gethost_byname(char *name, Link *lp)
 
        reinfo.re_na_look++;
        if ((cp = find_cache_name(name)))
-#ifndef _WIN32
                return (struct hostent *)&(cp->he);
-#else
-               return (struct hostent *)cp->he;
-#endif
        if (!lp)
                return NULL;
        (void)do_query_name(lp, name, NULL);
@@ -532,11 +418,7 @@ struct hostent *gethost_byaddr(char *addr, Link *lp)
 
        reinfo.re_nu_look++;
        if ((cp = find_cache_number(NULL, addr)))
-#ifndef _WIN32
                return (struct hostent *)&(cp->he);
-#else
-               return (struct hostent *)cp->he;
-#endif
        if (!lp)
                return NULL;
        (void)do_query_number(lp, (struct IN_ADDR *)addr, NULL);
@@ -545,7 +427,6 @@ struct hostent *gethost_byaddr(char *addr, Link *lp)
 
 static int do_query_name(Link *lp, char *name, ResRQ *rptr)
 {
-#ifndef _WIN32
        char hname[HOSTLEN + 1];
        int  len;
 
@@ -559,7 +440,6 @@ static int do_query_name(Link *lp, char *name, ResRQ *rptr)
                (void)strncat(hname, ircd_res.defdname,
                    sizeof(hname) - len - 1);
        }
-#endif
 
        /*
         * Store the name passed as the one to lookup and generate other host
@@ -577,17 +457,11 @@ static int do_query_name(Link *lp, char *name, ResRQ *rptr)
                (void)strcpy(rptr->name, name);
        }
        Debug((DEBUG_DNS, "do_query_name(): %s ", hname));
-#ifndef _WIN32
 #ifdef INET6
        return (query_name(hname, C_IN, T_ANY, rptr)); /* Was T_AAAA: now using T_ANY so we fetch both A and AAAA -- Syzop */
 #else
        return (query_name(hname, C_IN, T_A, rptr));
 #endif
-#else
-        rptr->id = _beginthread(async_dns, 0, (void *)rptr);
-         rptr->sends++;
-         return 0;
-#endif
 }
 
 /*
@@ -597,7 +471,6 @@ static int do_query_number(Link *lp, struct IN_ADDR *numb, ResRQ *rptr)
 {
        char ipbuf[128];
        u_char *cp;
-#ifndef _WIN32
 #ifdef INET6
        cp = (u_char *)&numb->s6_addr;
        if (cp[0] == 0 && cp[1] == 0 && cp[2] == 0 && cp[3] == 0 && cp[4] == 0
@@ -640,7 +513,6 @@ static int do_query_number(Link *lp, struct IN_ADDR *numb, ResRQ *rptr)
        cp = (u_char *)&numb->s_addr;
        (void)ircsprintf(ipbuf, "%u.%u.%u.%u.in-addr.arpa.",
            (u_int)(cp[3]), (u_int)(cp[2]), (u_int)(cp[1]), (u_int)(cp[0]));
-#endif
 #endif
        Debug((DEBUG_DNS, "do_query_number: built %s rptr = %lx",
                ipbuf, rptr));
@@ -649,7 +521,6 @@ static int do_query_number(Link *lp, struct IN_ADDR *numb, ResRQ *rptr)
        {
                rptr = make_request(lp);
                rptr->type = T_PTR;
-#ifndef _WIN32
 #ifdef INET6
                bcopy(numb->s6_addr, rptr->addr.s6_addr, IN6ADDRSZ);
                bcopy((char *)numb->s6_addr,
@@ -660,31 +531,10 @@ static int do_query_number(Link *lp, struct IN_ADDR *numb, ResRQ *rptr)
                    (char *)&rptr->he.h_addr, sizeof(struct in_addr));
 #endif
                rptr->he.h_length = sizeof(struct IN_ADDR);
-#else
-#ifndef INET6
-               rptr->addr.S_ADDR = numb->S_ADDR;
-#else
-               bcopy(numb->s6_addr, rptr->addr.s6_addr, IN6ADDRSZ);
-#endif
-               rptr->he->h_length = sizeof(struct IN_ADDR);
-
-/*             rptr->addr.s_addr = numb->s_addr;
-               bcopy((char *)&numb->s_addr,
-                   (char *)&rptr->he->h_addr, sizeof(struct in_addr));
-               rptr->he->h_length = sizeof(struct IN_ADDR);*/
-
-#endif
        }
-#ifndef _WIN32
        return (query_name(ipbuf, C_IN, T_PTR, rptr));
-#else
-         rptr->id = _beginthread(async_dns, 0, (void *)rptr);
-         rptr->sends++;
-         return 0;
-#endif
 }
 
-#ifndef _WIN32
 /*
  * generate a query based on class, type and name.
  */
@@ -701,10 +551,11 @@ static int query_name(char *name, int class, int type, ResRQ *rptr)
        if (r <= 0)
        {
                Debug((DEBUG_DNS, "query_name: NO_RECOVERY"));
-               h_errno = NO_RECOVERY;
+               SET_ERRNO(NO_RECOVERY);
                return r;
        }
        hptr = (HEADER *) buf;
+#ifndef _WIN32
        (void)gettimeofday(&tv, NULL);
        do
        {
@@ -720,14 +571,25 @@ static int query_name(char *name, int class, int type, ResRQ *rptr)
                hptr->id = htons(nstmp);
                k++;
        }
+#else
+       do
+       {
+               /* WIN32: actually this should be safe since it was seeded already */
+               hptr->id = htons(rand() & 0xffff);
+       }
+#endif
        while (find_id(ntohs(hptr->id)));
+       /* The above loop takes care of preventing requests with duplicate id's,
+        * it belongs to the do { } block. -- Syzop
+        */
+
        rptr->id = ntohs(hptr->id);
        rptr->sends++;
        s = send_res_msg(buf, r, rptr->sends);
        if (s == -1)
        {
                Debug((DEBUG_DNS, "query_name: TRY_AGAIN"));
-               h_errno = TRY_AGAIN;
+               SET_ERRNO(TRY_AGAIN);
                return -1;
        }
        else
@@ -810,17 +672,13 @@ static int proc_answer(ResRQ *rptr, HEADER *hptr, char *buf, char *eob)
                cp += 2;        /* INT16SZ */
                rptr->type = type;
 
-               len = strlen(hostbuf);
                /* name server never returns with trailing '.' */
                if (!index(hostbuf, '.') && (ircd_res.options & RES_DEFNAMES))
                {
                        (void)strlcat(hostbuf, dot, sizeof hostbuf);
-                       len++;
-                       (void)strncat(hostbuf, ircd_res.defdname,
-                           sizeof(hostbuf) - 1 - len);
-                       len = MIN(len + strlen(ircd_res.defdname),
-                           sizeof(hostbuf) - 1);
+                       (void)strlcat(hostbuf, ircd_res.defdname, sizeof hostbuf);
                }
+               len = strlen(hostbuf);
 
                switch (type)
                {
@@ -936,18 +794,11 @@ static int proc_answer(ResRQ *rptr, HEADER *hptr, char *buf, char *eob)
        }
        return ans;
 }
-#endif
 /*
  * read a dns reply from the nameserver and process it.
  */
-#ifndef _WIN32
 struct hostent *get_res(char *lp)
-#else
-struct hostent *get_res(char *lp,long id)
-#endif
 {
-
-#ifndef _WIN32
        static char buf[sizeof(HEADER) + MAXPACKET];
        HEADER *hptr;
 #ifdef INET6
@@ -957,14 +808,12 @@ struct hostent *get_res(char *lp,long id)
 #endif
        int  rc, a, max;
        SOCK_LEN_TYPE len = sizeof(sin);
-#else
-       struct hostent *he;
-#endif
 
        ResRQ   *rptr = NULL;
        aCache  *cp = NULL;
 #ifndef _WIN32
        (void)alarm((unsigned)4);
+#endif
 #ifdef INET6
        rc = recvfrom(resfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin,
            &len);
@@ -972,8 +821,9 @@ struct hostent *get_res(char *lp,long id)
        rc = recvfrom(resfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin,
            &len);
 #endif
-
+#ifndef _WIN32
        (void)alarm((unsigned)0);
+#endif
        if (rc <= sizeof(HEADER))
                goto getres_err;
        /*
@@ -988,25 +838,18 @@ struct hostent *get_res(char *lp,long id)
 #ifdef DEBUGMODE
        Debug((DEBUG_NOTICE, "get_res:id = %d rcode = %d ancount = %d",
            hptr->id, hptr->rcode, hptr->ancount));
-#endif
 #endif
        reinfo.re_replies++;
        /*
         * response for an id which we have already received an answer for
         * just ignore this response.
         */
-       lock_request();
-#ifndef _WIN32
        rptr = find_id(hptr->id);
-#else
-       rptr = find_id(id);
-#endif
        if (!rptr)
                goto getres_err;
        /*
         * check against possibly fake replies
         */
-#ifndef _WIN32
        max = MIN(ircd_res.nscount, rptr->sends);
        if (!max)
                max = 1;
@@ -1035,19 +878,19 @@ struct hostent *get_res(char *lp,long id)
                switch (hptr->rcode)
                {
                  case NXDOMAIN:
-                         h_errno = TRY_AGAIN;
+                         SET_ERRNO(TRY_AGAIN);
                          break;
                  case SERVFAIL:
-                         h_errno = TRY_AGAIN;
+                         SET_ERRNO(TRY_AGAIN);
                          break;
                  case NOERROR:
-                         h_errno = NO_DATA;
+                         SET_ERRNO(NO_DATA);
                          break;
                  case FORMERR:
                  case NOTIMP:
                  case REFUSED:
                  default:
-                         h_errno = NO_RECOVERY;
+                         SET_ERRNO(NO_RECOVERY);
                          break;
                }
                reinfo.re_errors++;
@@ -1055,10 +898,10 @@ struct hostent *get_res(char *lp,long id)
                   ** If a bad error was returned, we stop here and dont send
                   ** send any more (no retries granted).
                 */
-               if (h_errno != TRY_AGAIN)
+               if (ERRNO != TRY_AGAIN)
                {
                        Debug((DEBUG_DNS, "Fatal DNS error %d for %d",
-                           h_errno, hptr->rcode));
+                           ERRNO, hptr->rcode));
                        rptr->resend = 0;
                        rptr->retries = 0;
                }
@@ -1135,7 +978,7 @@ struct hostent *get_res(char *lp,long id)
         */
        if (rptr)
        {
-               if (h_errno != TRY_AGAIN)
+               if (ERRNO != TRY_AGAIN)
                {
                        /*
                         * If we havent tried with the default domain and its
@@ -1173,49 +1016,6 @@ struct hostent *get_res(char *lp,long id)
                else if (lp)
                        bcopy((char *)&rptr->cinfo, lp, sizeof(Link));
        }
-#else
-/* WIN32 */
-        he = rptr->he;
-         if (he && he->h_name && ((struct IN_ADDR *)he->h_addr)->S_ADDR &&
-                    rptr->locked < 2)
-             {
-                 /*
-                  * We only need to re-check the DNS if its a "byaddr" call,
-                  * the "byname" calls will work correctly. -Cabal95
-                  */
-                 char        tempname[120];
-                 int        i;
-                 long        amt;
-                 struct        hostent        *hp, *he = rptr->he;
-
-                 strlcpy(tempname, he->h_name, sizeof tempname);
-                 hp = gethostbyname(tempname);
-                 if (hp && !bcmp(hp->h_addr, he->h_addr, sizeof(struct IN_ADDR)))
-                     {
-                     }
-
-                 else
-                         rptr->he->h_name = NULL;
-             }
-
-         if (lp)
-                 bcopy((char *)&rptr->cinfo, lp, sizeof(Link));
-
-         cp = make_cache(rptr);
- # ifdef DEBUG
-         Debug((DEBUG_INFO,"get_res:cp=%#x rptr=%#x (made)", cp, rptr));
- # endif
-         rptr->locked = 0;
-         rem_request(rptr);
-        unlock_request();
-         return cp ? (struct hostent *)cp->he : NULL;
-
- getres_err:
-         if (lp && rptr)
-                 bcopy((char *)&rptr->cinfo, lp, sizeof(Link));
-        unlock_request();
-
-#endif
        return (struct hostent *)NULL;
 }
 
@@ -1339,7 +1139,6 @@ static void update_list(ResRQ *rptr, aCache *cachep)
        *cpp = cp->list_next;
        cp->list_next = cachetop;
        cachetop = cp;
-#ifndef _WIN32
        if (!rptr)
                return;
 
@@ -1446,7 +1245,6 @@ static void update_list(ResRQ *rptr, aCache *cachep)
                        bcopy(s, (char *)*--ab, sizeof(struct IN_ADDR));
                }
        }
-#endif
        return;
 }
 
@@ -1584,17 +1382,12 @@ static aCache *make_cache(ResRQ *rptr)
        /*
           ** shouldn't happen but it just might...
         */
-#ifndef _WIN32
        if (!rptr->he.h_name || !WHOSTENTP(rptr->he.h_addr.S_ADDR) )
-#else
-               if (!rptr->he->h_name || !((struct IN_ADDR *)rptr->he->h_addr)->S_ADDR)
-#endif
                return NULL;
        /*
           ** Make cache entry.  First check to see if the cache already exists
           ** and if so, return a pointer to it.
         */
-#ifndef _WIN32
        for (i = 0; WHOSTENTP(rptr->he.h_addr_list[i].S_ADDR); i++)
                if ((cp = find_cache_number(rptr,
 #ifdef INET6
@@ -1603,25 +1396,12 @@ static aCache *make_cache(ResRQ *rptr)
                    (char *)&(rptr->he.h_addr_list[i].S_ADDR))))
 #endif
                return cp;
-#else
-               for (i = 0; rptr->he->h_addr_list[i] &&
-            ((struct IN_ADDR *)rptr->he->h_addr_list[i])->S_ADDR; i++)
-               if ((cp = find_cache_number(rptr,
-                               (char *)&((struct IN_ADDR *)rptr->he->h_addr_list[i])->S_ADDR)))
-                       return cp;
-#endif
-
-
 
        /*
           ** a matching entry wasnt found in the cache so go and make one up.
         */
        cp = (aCache *)MyMalloc(sizeof(aCache));
        bzero((char *)cp, sizeof(aCache));
-#ifdef _WIN32
-         cp->he = (struct hostent *)MyMalloc(MAXGETHOSTSTRUCT);
-         res_copyhostent(rptr->he, cp->he);
-#else
        hp = &cp->he;
        for (i = 0; i < MAXADDRS - 1; i++)
                if (!WHOSTENTP(rptr->he.h_addr_list[i].S_ADDR))
@@ -1661,7 +1441,6 @@ static aCache *make_cache(ResRQ *rptr)
        hp->h_addrtype = rptr->he.h_addrtype;
        hp->h_length = rptr->he.h_length;
        hp->h_name = rptr->he.h_name;
-#endif
        if (rptr->ttl < AR_TTL)
        {
                reinfo.re_shortttl++;
@@ -1670,7 +1449,6 @@ static aCache *make_cache(ResRQ *rptr)
        else
                cp->ttl = rptr->ttl;
        cp->expireat = TStime() + cp->ttl;
-#ifndef _WIN32
        /* Update next dns cache clean time, this way it will be cleaned when needed.
         * I don't know how to do multithreaded (win32), as a consequence it can take
         * AR_TTL (300s) too much before we expire this entry at win32 -- Syzop
@@ -1679,7 +1457,6 @@ static aCache *make_cache(ResRQ *rptr)
                nextexpire = cp->expireat;
                Debug((DEBUG_DNS, "Adjusting nextexpire to %lu", nextexpire));
        }
-#endif
        HE(rptr)->h_name = NULL;
 #ifdef DEBUGMODE
        Debug((DEBUG_INFO, "make_cache:made cache %#x", cp));
@@ -1716,11 +1493,7 @@ static aCache *rem_list(aCache *cp)
 static void rem_cache(aCache *ocp)
 {
        aCache **cp;
-#ifndef _WIN32
        struct hostent *hp = &ocp->he;
-#else
-       struct hostent *hp = ocp->he;
-#endif
        int  hashv;
        aClient *cptr;
 
@@ -1779,9 +1552,6 @@ static void rem_cache(aCache *ocp)
                        *cp = ocp->hnum_next;
                        break;
                }
-#ifdef _WIN32
-         MyFree(hp);
-#else
        /*
         * free memory used to hold the various host names and the array
         * of alias pointers.
@@ -1804,7 +1574,6 @@ static void rem_cache(aCache *ocp)
                        MyFree(*hp->h_addr_list);
                MyFree(hp->h_addr_list);
        }
-#endif
        MyFree(ocp);
 
        incache--;
@@ -1898,6 +1667,19 @@ int m_dns(aClient *cptr, aClient *sptr, int parc, char *parv[])
                }
                return 2;
        }
+       if (IsOper(sptr) && parv[1] && *parv[1] == 'i')
+       {
+               int i;
+               /* Display nameserver list */
+               sendto_one(sptr, "NOTICE %s :Nameserver list has %d server(s):", sptr->name, ircd_res.nscount);
+               for (i = 0; i < ircd_res.nscount; i++)
+                       sendto_one(sptr, "NOTICE %s :%d. %s",
+                               sptr->name, i, inet_ntoa(ircd_res.nsaddr_list[i].sin_addr));
+               sendto_one(sptr, "NOTICE %s :retrans=%d s, retry=%d times", sptr->name, ircd_res.retrans, ircd_res.retry);
+               sendto_one(sptr, "NOTICE %s :Default domain name: %s", sptr->name, ircd_res.defdname);
+               sendto_one(sptr, "NOTICE %s :End of info.", sptr->name);
+               return 2;
+       }
        sendto_one(sptr, "NOTICE %s :Ca %d Cd %d Ce %d Cl %d Ch %d:%d Cu %d",
            sptr->name,
            cainfo.ca_adds, cainfo.ca_dels, cainfo.ca_expires,
@@ -1923,11 +1705,7 @@ u_long cres_mem(aClient *sptr, char *nick)
        for (; c; c = c->list_next)
        {
                sm += sizeof(*c);
-#ifndef _WIN32
                h = &c->he;
-#else
-               h = c->he;
-#endif
 #ifdef INET6
                for (i = 0; h->h_addr_list[i]; i++)
 #else
@@ -1966,120 +1744,3 @@ static int bad_hostname(char *name, int len)
                        return -1;
        return 0;
 }
-
-#ifdef _WIN32
-/*
- * Main thread function for handling DNS requests.
- */
-void   async_dns(void *parm)
-{
-       ResRQ   *rptr = (ResRQ *)parm;
-       struct hostent  *hp, *he = rptr->he;
-       int     i, x;
-       long    amt;
-
-       if (rptr->type == T_A)
-           {
-               rptr->locked = 2;
-               hp = gethostbyname(rptr->name);
-           }
-       else
-           {
-               rptr->locked = 1;
-               hp = gethostbyaddr((char *)(&rptr->addr.S_ADDR), 4, PF_INET);
-           }
-       if ( !hp )
-           {
-               /*
-                * Now heres a stupid check to forget, this apprently is
-                * what hasbeen causing most of the crashes.  I hope anyway.
-                */
-               do_dns_async(rptr->id);
-               _endthread();
-           }
-       if ( (hp->h_aliases[0] && (hp->h_aliases[0]-(char *)hp)>MAXGETHOSTSTRUCT) ||
-            (hp->h_addr_list[0] && (hp->h_addr_list[0]-(char *)hp)>MAXGETHOSTSTRUCT))
-           {
-               /*
-                * Seems windows does some weird, aka stupid, stuff with DNS.
-                * If the address is resolved from the HOSTS file, then the
-                * pointers will exceed MAXGETHOSTSTRUCT. Good and bad. Good
-                * because its an easy way to tell if the Admin is spoofing
-                * with his HOSTS file, bad because it also causes invalid
-                * pointers without this check. -Cabal95
-                */
-               do_dns_async(rptr->id);
-               _endthread();
-           }
-
-       res_copyhostent(hp, rptr->he);
-       do_dns_async(rptr->id);
-       _endthread();
-}
-
-int    res_copyhostent(struct hostent *from, struct hostent *to)
-{
-       int     amt, x, i;
-
-       to->h_addrtype = from->h_addrtype;
-       to->h_length = from->h_length;
-       /*
-        * Get to "primary" offset in to hostent buffer and copy over
-        * to hostname.
-        */
-       amt = (long)to + sizeof(struct hostent);
-       to->h_name = (char *)amt;
-       /*
-        * WIN32: FIXME: THIS LOOKS BAD
-       */
-       strcpy(to->h_name, from->h_name);
-       amt += strlen(to->h_name)+1;
-       /* Setup tto alias list */
-       if (amt&0x3)
-               amt = (amt&0xFFFFFFFC)+4;
-       to->h_aliases = (char **)amt;
-       for (x = 0; from->h_aliases[x]; x++)
-               ;
-       x *= sizeof(char *);
-       amt += sizeof(char *) + x;
-       for (i = 0; from->h_aliases[i]; i++)
-           {
-               to->h_aliases[i] = (char *)amt;
-               strcpy(to->h_aliases[i], from->h_aliases[i]);
-               amt += strlen(to->h_aliases[i])+1;
-               if (amt&0x3)
-                       amt = (amt&0xFFFFFFFC)+4;
-           }
-       to->h_aliases[i] = NULL;
-       /* Setup tto IP address list */
-       to->h_addr_list = (char **)amt;
-       for (x = 0; from->h_addr_list[x]; x++)
-               ;
-       x *= sizeof(char *);
-       amt += sizeof(char *) + x;
-       for (i = 0; from->h_addr_list[i]; i++)
-           {
-               to->h_addr_list[i] = (char *)amt;
-#ifndef INET6
-               ((struct IN_ADDR *)to->h_addr_list[i])->S_ADDR = ((struct IN_ADDR *)from->h_addr_list[i])->S_ADDR;
-#else
-               bcopy(((struct IN_ADDR *)from->h_addr_list[i])->S_ADDR,((struct IN_ADDR *)to->h_addr_list[i])->S_ADDR, IN6ADDRSZ);
-#endif
-               amt += sizeof(struct IN_ADDR); /* Prolly 4 */
-           }
-       to->h_addr_list[i] = NULL;
-
-#ifdef WINDNSDEBUG
-       {
-               int aliascnt = 0, addrcnt = 0;
-               for (aliascnt = 0; from->h_aliases[aliascnt]; aliascnt++);
-               for (addrcnt = 0; from->h_addr_list[addrcnt]; addrcnt++);
-               ircd_log(LOG_ERROR, "resolver: amt=0x%x, to=0x%x, len=%d, max=%d [%d aliases, %d addrs]",
-                       amt, to, (char *)amt - (char *)to, MAXGETHOSTSTRUCT, aliascnt, addrcnt);
-       }
-#endif
-       if ((char *)amt + 4 > (char *)to + MAXGETHOSTSTRUCT)
-               ircd_log(LOG_ERROR, "resolver: overflow???");
-       return 1;
-}
-#endif /*_WIN32*/
index c4094a0f9e250f4932194a0b56ee312559e8b160..7199a0b169727d48fe09d21538b207febca0935d 100644 (file)
@@ -349,21 +349,21 @@ static int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
                if ((n & NS_CMPRSFLGS) != 0)
                {
                        /* Some kind of compression pointer. */
-                       errno = EMSGSIZE;
+                       SET_ERRNO(P_EMSGSIZE);
                        return (-1);
                }
                if (dn != dst)
                {
                        if (dn >= eom)
                        {
-                               errno = EMSGSIZE;
+                               SET_ERRNO(P_EMSGSIZE);
                                return (-1);
                        }
                        *dn++ = '.';
                }
                if (dn + n >= eom)
                {
-                       errno = EMSGSIZE;
+                       SET_ERRNO(P_EMSGSIZE);
                        return (-1);
                }
                for ((void)NULL; n > 0; n--)
@@ -373,7 +373,7 @@ static int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
                        {
                                if (dn + 1 >= eom)
                                {
-                                       errno = EMSGSIZE;
+                                       SET_ERRNO(P_EMSGSIZE);
                                        return (-1);
                                }
                                *dn++ = '\\';
@@ -383,7 +383,7 @@ static int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
                        {
                                if (dn + 3 >= eom)
                                {
-                                       errno = EMSGSIZE;
+                                       SET_ERRNO(P_EMSGSIZE);
                                        return (-1);
                                }
                                *dn++ = '\\';
@@ -395,7 +395,7 @@ static int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
                        {
                                if (dn >= eom)
                                {
-                                       errno = EMSGSIZE;
+                                       SET_ERRNO(P_EMSGSIZE);
                                        return (-1);
                                }
                                *dn++ = (char)c;
@@ -406,14 +406,14 @@ static int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
        {
                if (dn >= eom)
                {
-                       errno = EMSGSIZE;
+                       SET_ERRNO(P_EMSGSIZE);
                        return (-1);
                }
                *dn++ = '.';
        }
        if (dn >= eom)
        {
-               errno = EMSGSIZE;
+               SET_ERRNO(P_EMSGSIZE);
                return (-1);
        }
        *dn++ = '\0';
@@ -452,20 +452,20 @@ static int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
                                if ((c = *src++) == 0 ||
                                    (cp = strchr(digits, c)) == NULL)
                                {
-                                       errno = EMSGSIZE;
+                                       SET_ERRNO(P_EMSGSIZE);
                                        return (-1);
                                }
                                n += (cp - digits) * 10;
                                if ((c = *src++) == 0 ||
                                    (cp = strchr(digits, c)) == NULL)
                                {
-                                       errno = EMSGSIZE;
+                                       SET_ERRNO(P_EMSGSIZE);
                                        return (-1);
                                }
                                n += (cp - digits);
                                if (n > 255)
                                {
-                                       errno = EMSGSIZE;
+                                       SET_ERRNO(P_EMSGSIZE);
                                        return (-1);
                                }
                                c = n;
@@ -482,12 +482,12 @@ static int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
                        c = (bp - label - 1);
                        if ((c & NS_CMPRSFLGS) != 0)
                        {       /* Label too big. */
-                               errno = EMSGSIZE;
+                               SET_ERRNO(P_EMSGSIZE);
                                return (-1);
                        }
                        if (label >= eom)
                        {
-                               errno = EMSGSIZE;
+                               SET_ERRNO(P_EMSGSIZE);
                                return (-1);
                        }
                        *label = c;
@@ -498,21 +498,21 @@ static int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
                                {
                                        if (bp >= eom)
                                        {
-                                               errno = EMSGSIZE;
+                                               SET_ERRNO(P_EMSGSIZE);
                                                return (-1);
                                        }
                                        *bp++ = '\0';
                                }
                                if ((bp - dst) > MAXCDNAME)
                                {
-                                       errno = EMSGSIZE;
+                                       SET_ERRNO(P_EMSGSIZE);
                                        return (-1);
                                }
                                return (1);
                        }
                        if (c == 0)
                        {
-                               errno = EMSGSIZE;
+                               SET_ERRNO(P_EMSGSIZE);
                                return (-1);
                        }
                        label = bp++;
@@ -520,7 +520,7 @@ static int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
                }
                if (bp >= eom)
                {
-                       errno = EMSGSIZE;
+                       SET_ERRNO(P_EMSGSIZE);
                        return (-1);
                }
                *bp++ = (u_char)c;
@@ -528,12 +528,12 @@ static int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
        c = (bp - label - 1);
        if ((c & NS_CMPRSFLGS) != 0)
        {                       /* Label too big. */
-               errno = EMSGSIZE;
+               SET_ERRNO(P_EMSGSIZE);
                return (-1);
        }
        if (label >= eom)
        {
-               errno = EMSGSIZE;
+               SET_ERRNO(P_EMSGSIZE);
                return (-1);
        }
        *label = c;
@@ -541,14 +541,14 @@ static int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
        {
                if (bp >= eom)
                {
-                       errno = EMSGSIZE;
+                       SET_ERRNO(P_EMSGSIZE);
                        return (-1);
                }
                *bp++ = 0;
        }
        if ((bp - dst) > MAXCDNAME)
        {                       /* src too big */
-               errno = EMSGSIZE;
+               SET_ERRNO(P_EMSGSIZE);
                return (-1);
        }
        return (0);
@@ -573,7 +573,7 @@ static int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *sr
        dstlim = dst + dstsiz;
        if (srcp < msg || srcp >= eom)
        {
-               errno = EMSGSIZE;
+               SET_ERRNO(P_EMSGSIZE);
                return (-1);
        }
        /* Fetch next label in domain name. */
@@ -586,7 +586,7 @@ static int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *sr
                          /* Limit checks. */
                          if (dstp + n + 1 >= dstlim || srcp + n >= eom)
                          {
-                                 errno = EMSGSIZE;
+                                 SET_ERRNO(P_EMSGSIZE);
                                  return (-1);
                          }
                          checked += n + 1;
@@ -599,7 +599,7 @@ static int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *sr
                  case NS_CMPRSFLGS:
                          if (srcp >= eom)
                          {
-                                 errno = EMSGSIZE;
+                                 SET_ERRNO(P_EMSGSIZE);
                                  return (-1);
                          }
                          if (len < 0)
@@ -607,7 +607,7 @@ static int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *sr
                          srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
                          if (srcp < msg || srcp >= eom)
                          {     /* Out of range. */
-                                 errno = EMSGSIZE;
+                                 SET_ERRNO(P_EMSGSIZE);
                                  return (-1);
                          }
                          checked += 2;
@@ -618,13 +618,13 @@ static int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *sr
                           */
                          if (checked >= eom - msg)
                          {
-                                 errno = EMSGSIZE;
+                                 SET_ERRNO(P_EMSGSIZE);
                                  return (-1);
                          }
                          break;
 
                  default:
-                         errno = EMSGSIZE;
+                         SET_ERRNO(P_EMSGSIZE);
                          return (-1);  /* flag error */
                }
        }
@@ -681,13 +681,13 @@ static int ns_name_pack(const u_char *src, u_char *dst, int dstsiz, const u_char
                n = *srcp;
                if ((n & NS_CMPRSFLGS) != 0)
                {
-                       errno = EMSGSIZE;
+                       SET_ERRNO(P_EMSGSIZE);
                        return (-1);
                }
                l += n + 1;
                if (l > MAXCDNAME)
                {
-                       errno = EMSGSIZE;
+                       SET_ERRNO(P_EMSGSIZE);
                        return (-1);
                }
                srcp += n + 1;
@@ -707,7 +707,7 @@ static int ns_name_pack(const u_char *src, u_char *dst, int dstsiz, const u_char
                        {
                                if (dstp + 1 >= eob)
                                {
-                                       errno = EMSGSIZE;
+                                       SET_ERRNO(P_EMSGSIZE);
                                        return (-1);
                                }
                                *dstp++ = (l >> 8) | NS_CMPRSFLGS;
@@ -725,12 +725,12 @@ static int ns_name_pack(const u_char *src, u_char *dst, int dstsiz, const u_char
                /* copy label to buffer */
                if (n & NS_CMPRSFLGS)
                {               /* Should not happen. */
-                       errno = EMSGSIZE;
+                       SET_ERRNO(P_EMSGSIZE);
                        return (-1);
                }
                if (dstp + 1 + n >= eob)
                {
-                       errno = EMSGSIZE;
+                       SET_ERRNO(P_EMSGSIZE);
                        return (-1);
                }
                memcpy(dstp, srcp, n + 1);
@@ -743,7 +743,7 @@ static int ns_name_pack(const u_char *src, u_char *dst, int dstsiz, const u_char
        {
                if (msg != NULL)
                        *lpp = NULL;
-               errno = EMSGSIZE;
+               SET_ERRNO(P_EMSGSIZE);
                return (-1);
        }
        return (dstp - dst);
@@ -817,14 +817,14 @@ static int ns_name_skip(const u_char **ptrptr, const u_char *eom)
                          cp++;
                          break;
                  default:      /* illegal type */
-                         errno = EMSGSIZE;
+                         SET_ERRNO(P_EMSGSIZE);
                          return (-1);
                }
                break;
        }
        if (cp > eom)
        {
-               errno = EMSGSIZE;
+               SET_ERRNO(P_EMSGSIZE);
                return (-1);
        }
        *ptrptr = cp;
@@ -925,13 +925,13 @@ static int dn_find(const u_char *domain, const u_char *msg, const u_char *const
                                  break;
 
                          default:      /* illegal type */
-                                 errno = EMSGSIZE;
+                                 SET_ERRNO(P_EMSGSIZE);
                                  return (-1);
                        }
                }
              next:;
        }
-       errno = ENOENT;
+       SET_ERRNO(ENOENT);
        return (-1);
 }
 
index 2d49c35974958a9b8cc87b58cefb13fbd207aa4e..d6958f43871329abb29cc6ed09fe8866679a2b01 100644 (file)
@@ -151,11 +151,294 @@ struct __res_state ircd_res
  * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
  * in the configuration file.
  *
+ * Copied WIN32 specific code from ircu NT port :p.
+ *
  * Return 0 if completes successfully, -1 on error
  */
+
+#ifdef _WIN32
+extern OSVERSIONINFO VerInfo;
+void get_res_from_reg_9x()
+{
+       register char *cp, **pp, *ap;
+       register int n;
+       HKEY hKey;
+       char buf[BUFSIZ];
+       int key_len = BUFSIZ;
+       int key_type;
+       ircd_res.nscount = 0;
+
+       if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD\\MSTCP",
+               0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
+       {
+               Debug((DEBUG_DNS, "Error: get_res_from_reg_9x: unable to open registry key"));
+               return;
+       }
+       /* Retreive the Domain key */
+       if (RegQueryValueEx(hKey, "Domain", 0, &key_type, buf, &key_len) != ERROR_SUCCESS)
+       {
+               Debug((DEBUG_DNS, "get_res_from_reg_9x: RegQueryValueEx: Domain failed"));
+       }
+       else
+               strlcpy(ircd_res.defdname, buf, sizeof(ircd_res.defdname));
+       key_len = BUFSIZ;
+
+       /* Retreive the SearchList key */
+       if (RegQueryValueEx(hKey, "SearchList", 0, &key_type, buf, &key_len) != ERROR_SUCCESS)
+       {
+               Debug((DEBUG_DNS, "get_res_from_reg_9x: RegQueryValueEx: SearchList failed"));
+       }
+       else
+       {
+               cp = ircd_res.defdname;
+               pp = ircd_res.dnsrch;
+               *pp++ = cp;
+               for (n = 0; *cp && pp < ircd_res.dnsrch + MAXDNSRCH; cp++)
+               {
+                       if (*cp == ',')
+                       {
+                               *cp = 0;
+                               n = 1;
+                       } 
+                       else if (n)
+                       {
+                               *pp++ = cp;
+                               n = 0;
+                       }
+               }
+               /* null terminate the last domain if there are excess */
+               while (*cp && *cp != ',')
+                       ++cp;
+               *cp = 0;
+               *pp++ = 0;
+       }
+       key_len = BUFSIZ;
+
+       /* Retreive the NameServer key */
+       if (RegQueryValueEx(hKey, "NameServer", 0, &key_type, buf, &key_len) != ERROR_SUCCESS)
+       {
+               Debug((DEBUG_DNS, "get_res_from_reg_9x: RegQueryValueEx: NameServer failed"));
+       }
+       else
+       {
+               struct in_addr a;
+               cp = ap = buf;
+               if (*buf != '\0')
+               {
+                       do {
+                               n = 0;
+                               while (*cp && *cp != ',')
+                                       ++cp;
+                               if (*cp)
+                               {
+                                       *cp = 0;
+                                       n = 1;
+                               }
+                               if (inet_addr(ap) != INADDR_NONE)
+                               {
+                                       ircd_res.nsaddr_list[ircd_res.nscount].sin_addr.s_addr = inet_addr(ap);
+                                       ircd_res.nsaddr_list[ircd_res.nscount].sin_family = AF_INET;
+                                       ircd_res.nsaddr_list[ircd_res.nscount].sin_port = htons(NAMESERVER_PORT);
+                                       ircd_res.nscount++;
+                               }
+                               if (!n)
+                                       break;
+                               ap = ++cp;
+                       } while (ircd_res.nscount <= MAXNS);
+               }
+       }
+       RegCloseKey(hKey);
+}
+
+int get_res_nt(HKEY hKey, char *subkey, char *obuf, int *size)
+{
+       if (RegQueryValueEx(hKey, subkey, 0, NULL, obuf, size) != ERROR_SUCCESS)
+       {
+               *size = 0;
+               return 0;
+       }
+       if (*size == 1)
+       {
+               *size = 0;
+               return 0;
+       }
+       return 1;
+}
+
+int get_res_interfaces_nt(HKEY hKey, char *subkey, char *obuf, int *size)
+{
+       char buf[BUFSIZ];
+       int key_len = BUFSIZ;
+       int idx = 0;
+       FILETIME lastwrite;
+       HKEY hVal;
+       while (RegEnumKeyEx(hKey, idx++, buf, &key_len, 0, NULL, NULL, &lastwrite) != ERROR_NO_MORE_ITEMS)
+       {
+               if (RegOpenKeyEx(hKey, buf, 0, KEY_QUERY_VALUE, &hVal) != ERROR_SUCCESS)
+                       continue;
+               key_len = BUFSIZ;
+
+               if (!get_res_nt(hVal, subkey, obuf, &key_len))
+               {
+                       RegCloseKey(hVal);
+                       key_len = BUFSIZ;
+                       continue;
+               }
+               else
+               {
+                       RegCloseKey(hVal);
+                       *size = key_len;
+                       return 1;
+               }
+               key_len = BUFSIZ;
+       }
+       *size = 0;
+       return 0;
+}
+
+void get_res_from_reg_nt() 
+{
+       register char *cp, **pp, *ap;
+       register int n;
+       HKEY hKey, hInter;
+       char buf[BUFSIZ];
+       int key_len = BUFSIZ;
+       ircd_res.nscount = 0;
+
+       if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+               0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
+       {
+               Debug((DEBUG_DNS, "Error: get_res_from_reg_nt: unable to open registry key"));
+               return;
+       }
+       RegOpenKeyEx(hKey, "Interfaces", 0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hInter);
+
+       /* Retreive the Domain key */
+       if (!get_res_nt(hKey, "Domain", buf, &key_len))
+       {
+               key_len = BUFSIZ;
+               /* Try DHCP key */
+               if (!get_res_nt(hKey, "DhcpDomain", buf, &key_len))
+               {
+                       key_len = BUFSIZ;
+                       if (!get_res_interfaces_nt(hInter, "Domain", buf, &key_len))
+                       {
+                               key_len = BUFSIZ;
+                               if (!get_res_interfaces_nt(hInter, "DhcpDomain", buf, &key_len))
+                               {
+                                       Debug((DEBUG_DNS, "get_res_from_reg_nt: RegQueryValueEx: Domain failed"));
+                               }
+                       }
+               }
+       }
+       if (key_len > 0)
+               strlcpy(ircd_res.defdname, buf, sizeof(ircd_res.defdname));
+
+       /* Retreive the SearchList key */
+       key_len = BUFSIZ;
+       if (!get_res_nt(hKey, "SearchList", buf, &key_len))
+       {
+               key_len = BUFSIZ;
+               /* Try DHCP key */
+               if (!get_res_nt(hKey, "DhcpSearchList", buf, &key_len))
+               {
+                       key_len = BUFSIZ;
+                       if (!get_res_interfaces_nt(hInter, "SearchList", buf, &key_len))
+                       {
+                               key_len = BUFSIZ;
+                               if (!get_res_interfaces_nt(hInter, "DhcpSearchList", buf, &key_len))
+                               {
+                                       Debug((DEBUG_DNS, "get_res_from_reg_nt: RegQueryValueEx: SearchList failed"));
+                               }
+                       }
+               }
+       }
+       if (key_len > 0)
+       {
+               /*
+                * Set search list to be blank-separated strings
+                * on rest of line.
+                */
+               cp = ircd_res.defdname;
+               pp = ircd_res.dnsrch;
+               *pp++ = cp;
+               for (n = 0; *cp && pp < ircd_res.dnsrch + MAXDNSRCH; cp++)
+               {
+                       if (*cp == ' ' || *cp == '\t')
+                       {
+                               *cp = 0;
+                               n = 1;
+                       } else
+                       if (n)
+                       {
+                               *pp++ = cp;
+                               n = 0;
+                       }
+               }
+               /* null terminate the last domain if there are excess */
+               while (*cp && *cp != ' ' && *cp != '\t')
+                       ++cp;
+               *cp = 0;
+               *pp++ = 0;
+       }       
+
+       /* Retreive the NameServer key */
+       key_len = BUFSIZ;
+       if (!get_res_nt(hKey, "NameServer", buf, &key_len))
+       {
+               key_len = BUFSIZ;
+               /* Try DHCP key */
+               if (!get_res_nt(hKey, "DhcpNameServer", buf, &key_len))
+               {
+                       key_len = BUFSIZ;
+                       if (!get_res_interfaces_nt(hInter, "NameServer", buf, &key_len))
+                       {
+                               key_len = BUFSIZ;
+                               if (!get_res_interfaces_nt(hInter, "DhcpNameServer", buf, &key_len))
+                               {
+                                       Debug((DEBUG_DNS, "get_res_from_reg_nt: RegQueryValue: NameServer failed"));
+                               }
+                       }
+               }
+       }
+       if (key_len > 0)
+       {
+               struct in_addr a;
+               cp = ap = buf;
+               if (*buf != '\0')
+               {
+                       do {
+                               n = 0;
+                               while (*cp && *cp != ' ' && *cp != '\t')
+                                       ++cp;
+                               if (*cp)
+                               {
+                                       *cp = 0;
+                                       n = 1;
+                               }
+                               if (inet_addr(ap) != INADDR_NONE)
+                               {
+                                       ircd_res.nsaddr_list[ircd_res.nscount].sin_addr.s_addr = inet_addr(ap);
+                                       ircd_res.nsaddr_list[ircd_res.nscount].sin_family = AF_INET;
+                                       ircd_res.nsaddr_list[ircd_res.nscount].sin_port = htons(NAMESERVER_PORT);
+                                       ircd_res.nscount++;
+                               }
+                               if (!n)
+                                       break;
+                               ap = ++cp;
+                       } while (ircd_res.nscount <= MAXNS);
+               }
+       }
+       RegCloseKey(hInter);
+       RegCloseKey(hKey);
+}
+#endif
+
 int ircd_res_init(void)
 {
+#ifndef _WIN32
        register FILE *fp;
+#endif
        register char *cp, **pp;
        register int n;
        char buf[MAXDNAME];
@@ -254,6 +537,7 @@ int ircd_res_init(void)
                *pp++ = 0;
        }
 
+#ifndef _WIN32
 #define        MATCH(line, name) \
        (!strncmp(line, name, sizeof(name) - 1) && \
        (line[sizeof(name) - 1] == ' ' || \
@@ -262,7 +546,6 @@ int ircd_res_init(void)
 #ifdef NEXT
        if (ircd_netinfo_res_init(&haveenv, &havesearch) == 0)
 #endif
-#ifndef _WIN32
                if ((fp = fopen(IRC_RESCONF, "r")) != NULL)
                {
                        /* read the config file */
@@ -460,7 +743,14 @@ int ircd_res_init(void)
 #endif
                        (void)fclose(fp);
                }
-#endif         
+#else /* WIN32-specific code follows: */
+       if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+               get_res_from_reg_9x();
+       else if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
+               get_res_from_reg_nt();
+       
+#endif /* WIN32 */
+
        if (ircd_res.defdname[0] == 0 &&
            gethostname(buf, sizeof(ircd_res.defdname) - 1) == 0 &&
            (cp = strchr(buf, '.')) != NULL)
@@ -502,6 +792,15 @@ int ircd_res_init(void)
        if ((cp = getenv("RES_OPTIONS")) != NULL)
                ircd_res_setoptions(cp, "env");
        ircd_res.options |= RES_INIT;
+
+#ifdef DEBUGMODE
+       {
+               int i;
+               Debug((DEBUG_DNS, "res_init: %d nameserver(s):", ircd_res.nscount));
+               for (i=0; i < ircd_res.nscount; i++)
+                       Debug((DEBUG_DNS, "%d. %s", i, inet_ntoa(ircd_res.nsaddr_list[i].sin_addr)));
+       }
+#endif
        return (0);
 }
 
index 4629d61652567e54e5d56db96e5cb53a9dcd2517..beb20001d8e26b1244c132f2ea0e4d1c36508f37 100644 (file)
@@ -89,7 +89,7 @@ const u_char *newrr_in, u_char *buf, int buflen)
 
        if ((ircd_res.options & RES_INIT) == 0 && ircd_res_init() == -1)
        {
-               h_errno = NETDB_INTERNAL;
+               SET_ERRNO(NETDB_INTERNAL);
                return (-1);
        }
 #ifdef DEBUGMODE
index 2f6dc5b5c4097c7e1aecadc8a6c15b27491e483b..85238e2306eeec4617f12a7bc95558bed9e42d78 100644 (file)
@@ -112,12 +112,8 @@ static struct SOCKADDR_IN mysk;
 static struct SOCKADDR *connect_inet(ConfigItem_link *, aClient *, int *);
 int completed_connection(aClient *);
 static int check_init(aClient *, char *, size_t);
-#ifndef _WIN32
 static void do_dns_async();
 void set_sock_opts(int, aClient *);
-#else
-void set_sock_opts(int, aClient *);
-#endif
 static char readbuf[READBUF_SIZE];
 char zlinebuf[BUFSIZE];
 extern char *version;
@@ -426,6 +422,19 @@ int  inetport(aClient *cptr, char *name, int port)
                                ipname, port);
                        strlcat(backupbuf, " - %s:%s", sizeof backupbuf);
                        report_error(backupbuf, cptr);
+#if !defined(_WIN32) && defined(INET6)
+                       /* Check if ipv4-over-ipv6 (::ffff:a.b.c.d, RFC2553
+                        * section 3.7) is disabled, like at newer FreeBSD's. -- Syzop
+                        */
+                       if (!strncasecmp(ipname, "::ffff:", 7))
+                       {
+                               ircd_log(LOG_ERROR, "You are trying to bind to an IPv4 address, "
+                                                   "make sure the address exists at your machine. "
+                                                   "If you are using *BSD you might need to "
+                                                   "enable ipv6_ipv4mapping in /etc/rc.conf "
+                                                   "and/or via sysctl.");
+                       }
+#endif
                        CLOSE_SOCK(cptr->fd);
                        cptr->fd = -1;
                        --OpenFiles;
@@ -708,7 +717,7 @@ static int check_init(aClient *cptr, char *sockn, size_t size)
        (void)strlcpy(sockn, (char *)Inet_si2p(&sk), size);
 
 #ifdef INET6
-       if (IN6_IS_ADDR_LOOPBACK(&sk.SIN_ADDR))
+       if (IN6_IS_ADDR_LOOPBACK(&sk.SIN_ADDR) || !strcmp(sockn, "127.0.0.1"))
 #else
        if (inet_netof(sk.SIN_ADDR) == IN_LOOPBACKNET)
 #endif
@@ -1705,10 +1714,8 @@ int  read_message(time_t delay, fdlist *listp)
                        }
                }
 
-#ifndef _WIN32
                if (resfd >= 0)
                        FD_SET(resfd, &read_set);
-#endif
                if (me.fd >= 0)
                        FD_SET(me.fd, &read_set);
 
@@ -1735,10 +1742,9 @@ int  read_message(time_t delay, fdlist *listp)
 #ifndef _WIN32
                sleep(10);
 #else
-               Sleep(10);
+               Sleep(10000);
 #endif
        }
-#ifndef _WIN32
        if (resfd >= 0 && FD_ISSET(resfd, &read_set))
        {
                Debug((DEBUG_DNS, "Doing DNS async.."));
@@ -1746,7 +1752,6 @@ int  read_message(time_t delay, fdlist *listp)
                nfds--;
                FD_CLR(resfd, &read_set);
        }
-#endif
        /*
         * Check fd sets for the auth fd's (if set and valid!) first
         * because these can not be processed using the normal loops below.
@@ -2539,11 +2544,7 @@ static struct SOCKADDR *connect_inet(ConfigItem_link *aconf, aClient *cptr, int
  * reading.
  */
 
-#ifndef _WIN32
 static void do_dns_async(void)
-#else
-void do_dns_async(int id)
-#endif
 {
        static  Link    ln;
        aClient *cptr;
@@ -2555,11 +2556,7 @@ void do_dns_async(int id)
 
        do {
                ln.flags = -1;
-#ifndef _WIN32
                hp = get_res((char *)&ln);
-#else
-               hp = get_res((char *)&ln, id);
-#endif
                Debug((DEBUG_DNS,"%#x = get_res(%d,%#x)", hp, ln.flags,
                        ln.value.cptr));
 
index e910510211279ae8329c8f56128b5aebb5fa1944..874f50614c7d2b38800845679214fb2de1ca6aa4 100644 (file)
@@ -104,6 +104,7 @@ static int  _conf_loadmodule        (ConfigFile *conf, ConfigEntry *ce);
 static int     _conf_log               (ConfigFile *conf, ConfigEntry *ce);
 static int     _conf_alias             (ConfigFile *conf, ConfigEntry *ce);
 static int     _conf_help              (ConfigFile *conf, ConfigEntry *ce);
+static int     _conf_offchans          (ConfigFile *conf, ConfigEntry *ce);
 
 /* 
  * Validation commands 
@@ -137,6 +138,7 @@ static int  _test_loadmodule        (ConfigFile *conf, ConfigEntry *ce);
 static int     _test_log               (ConfigFile *conf, ConfigEntry *ce);
 static int     _test_alias             (ConfigFile *conf, ConfigEntry *ce);
 static int     _test_help              (ConfigFile *conf, ConfigEntry *ce);
+static int     _test_offchans          (ConfigFile *conf, ConfigEntry *ce);
  
 /* This MUST be alphabetized */
 static ConfigCommand _ConfigCommands[] = {
@@ -158,6 +160,7 @@ static ConfigCommand _ConfigCommands[] = {
        { "loadmodule",         NULL,                   _test_loadmodule},
        { "log",                _conf_log,              _test_log       },
        { "me",                 _conf_me,               _test_me        },
+       { "official-channels",          _conf_offchans,         _test_offchans  },
        { "oper",               _conf_oper,             _test_oper      },
        { "set",                _conf_set,              _test_set       },
        { "tld",                _conf_tld,              _test_tld       },
@@ -325,7 +328,8 @@ extern void         win_error();
 #endif
 extern char modebuf[MAXMODEPARAMS*2+1], parabuf[504];
 extern void add_entropy_configfile(struct stat st, char *buf);
-
+extern void unload_all_unused_snomasks();
+extern void unload_all_unused_umodes();
 /*
  * Config parser (IRCd)
 */
@@ -365,6 +369,7 @@ ConfigItem_badword  *conf_badword_channel = NULL;
 ConfigItem_badword      *conf_badword_message = NULL;
 ConfigItem_badword     *conf_badword_quit = NULL;
 #endif
+ConfigItem_offchans    *conf_offchans = NULL;
 
 aConfiguration         iConf;
 aConfiguration         tempiConf;
@@ -447,6 +452,30 @@ void port_range(char *string, int *start, int *end)
        *end = atoi((c+1));
 }
 
+/** Parses '5:60s' config values.
+ * orig: original string
+ * times: pointer to int, first value (before the :)
+ * period: pointer to int, second value (after the :) in seconds
+ * RETURNS: 0 for parse error, 1 if ok.
+ * REMARK: times&period should be ints!
+ */
+int config_parse_flood(char *orig, int *times, int *period)
+{
+char *x;
+
+       *times = *period = 0;
+       x = strchr(orig, ':');
+       /* 'blah', ':blah', '1:' */
+       if (!x || (x == orig) || (*(x+1) == '\0'))
+               return 0;
+
+       *x = '\0';
+       *times = atoi(orig);
+       *period = config_checkval(x+1, CFG_TIME);
+       *x = ':'; /* restore */
+       return 1;
+}
+
 long config_checkval(char *orig, unsigned short flags) {
        char *value;
        char *text;
@@ -563,7 +592,7 @@ typedef struct {
 } aCtab;
 extern aCtab cFlagTab[];
 
-void set_channelmodes(char *modes, struct ChMode *store)
+void set_channelmodes(char *modes, struct ChMode *store, int warn)
 {
        aCtab *tab;
        char *param = strchr(modes, ' ');
@@ -587,6 +616,127 @@ void set_channelmodes(char *modes, struct ChMode *store)
                {
                        case 'f':
                        {
+#ifdef NEWCHFLOODPROT
+                               /* TODO */
+                               ChanFloodProt newf;
+                               
+                               memset(&newf, 0, sizeof(newf));
+                               if (!param)
+                                       break;
+                               if (param[0] != '[')
+                               {
+                                       if (warn)
+                                               config_status("set::modes-on-join: please use the new +f format: '10:5' becomes '[10t]:5' "
+                                                         "and '*10:5' becomes '[10t#b]:5'.");
+                               } else
+                               {
+                                       char xbuf[256], c, a, *p, *p2, *x = xbuf+1;
+                                       int v, i;
+                                       unsigned short warnings = 0, breakit;
+                                       
+                                       /* '['<number><1 letter>[optional: '#'+1 letter],[next..]']'':'<number> */
+                                       strlcpy(xbuf, param, sizeof(xbuf));
+                                       p2 = strchr(xbuf+1, ']');
+                                       if (!p2)
+                                               break;
+                                       *p2 = '\0';
+                                       if (*(p2+1) != ':')
+                                               break;
+                                       breakit = 0;
+                                       for (x = strtok(xbuf+1, ","); x; x = strtok(NULL, ","))
+                                       {
+                                               /* <number><1 letter>[optional: '#'+1 letter] */
+                                               p = x;
+                                               while(isdigit(*p)) { p++; }
+                                               if ((*p == '\0') ||
+                                                   !((*p == 'c') || (*p == 'j') || (*p == 'k') ||
+                                                   (*p == 'm') || (*p == 'n') || (*p == 't')))
+                                                       break;
+                                               c = *p;
+                                               *p = '\0';
+                                               v = atoi(x);
+                                               if ((v < 1) || (v > 999)) /* out of range... */
+                                                       break;
+                                               p++;
+                                               a = '\0';
+                                               if (*p != '\0')
+                                               {
+                                                       if (*p == '#')
+                                                       {
+                                                               p++;
+                                                               a = *p;
+                                                       }
+                                               }
+                                               switch(c)
+                                               {
+                                                       case 'c':
+                                                               newf.l[FLD_CTCP] = v;
+                                                               if ((a == 'm') || (a == 'M'))
+                                                                       newf.a[FLD_CTCP] = a;
+                                                               else
+                                                                       newf.a[FLD_CTCP] = 'C';
+                                                               break;
+                                                       case 'j':
+                                                               newf.l[FLD_JOIN] = v;
+                                                               if (a == 'R')
+                                                                       newf.a[FLD_JOIN] = a;
+                                                               else
+                                                                       newf.a[FLD_JOIN] = 'i';
+                                                               break;
+                                                       case 'k':
+                                                               newf.l[FLD_KNOCK] = v;
+                                                               newf.a[FLD_KNOCK] = 'K';
+                                                               break;
+                                                       case 'm':
+                                                               newf.l[FLD_MSG] = v;
+                                                               if (a == 'M')
+                                                                       newf.a[FLD_MSG] = a;
+                                                               else
+                                                                       newf.a[FLD_MSG] = 'm';
+                                                               break;
+                                                       case 'n':
+                                                               newf.l[FLD_NICK] = v;
+                                                               newf.a[FLD_NICK] = 'N';
+                                                               break;
+                                                       case 't':
+                                                               newf.l[FLD_TEXT] = v;
+                                                               if (a == 'b')
+                                                                       newf.a[FLD_TEXT] = 'b';
+                                                               break;
+                                                       default:
+                                                               breakit=1;
+                                                               break;
+                                               }
+                                               if (breakit)
+                                                       break;
+                                       } /* for strtok.. */
+                                       if (breakit)
+                                               break;
+                                       /* parse 'per' */
+                                       p2++;
+                                       if (*p2 != ':')
+                                               break;
+                                       p2++;
+                                       if (!*p2)
+                                               break;
+                                       v = atoi(p2);
+                                       if ((v < 1) || (v > 999)) /* 'per' out of range */
+                                               break;
+                                       newf.per = v;
+                                       /* Is anything turned on? (to stop things like '+f []:15' */
+                                       breakit = 1;
+                                       for (v=0; v < NUMFLD; v++)
+                                               if (newf.l[v])
+                                                       breakit=0;
+                                       if (breakit)
+                                               break;
+                                       
+                                       /* w00t, we passed... */
+                                       memcpy(&store->floodprot, &newf, sizeof(newf));
+                                       store->mode |= MODE_FLOODLIMIT;
+                                       break;
+                               }
+#else
                                char kmode = 0;
                                char *xp;
                                int msgs=0, per=0;
@@ -622,6 +772,7 @@ void set_channelmodes(char *modes, struct ChMode *store)
                                store->per = per;
                                store->kmode = kmode;                                        
                                store->mode |= MODE_FLOODLIMIT;
+#endif
                                break;
                        }
                        default:
@@ -646,11 +797,19 @@ void chmode_str(struct ChMode modes, char *mbuf, char *pbuf)
                                *mbuf++ = tab->flag;
                }
        }
+#ifdef NEWCHFLOODPROT
+       if (modes.floodprot.per)
+       {
+               *mbuf++ = 'f';
+               sprintf(pbuf, "%s", channel_modef_string(&modes.floodprot));
+       }
+#else
        if (modes.per)
        {
                *mbuf++ = 'f';
                sprintf(pbuf, "%s%d:%d", modes.kmode ? "*" : "", modes.msgs, modes.per);
        }
+#endif
        *mbuf++=0;
 }
 
@@ -1113,6 +1272,7 @@ void      free_iConf(aConfiguration *i)
        ircfree(i->auto_join_chans);
        ircfree(i->oper_auto_join_chans);
        ircfree(i->oper_only_stats);
+       ircfree(i->channel_command_prefix);
        ircfree(i->oper_snomask);
        ircfree(i->user_snomask);
        ircfree(i->egd_path);
@@ -1149,6 +1309,10 @@ void config_setdefaultsettings(aConfiguration *i)
        i->oper_snomask = strdup(SNO_DEFOPER);
        i->ident_read_timeout = 30;
        i->ident_connect_timeout = 10;
+       i->nick_count = 3; i->nick_period = 60; /* nickflood protection: max 3 per 60s */
+#ifdef NO_FLOOD_AWAY
+       i->away_count = 4; i->away_period = 120; /* awayflood protection: max 4 per 120s */
+#endif
 }
 
 int    init_conf(char *rootconf, int rehash)
@@ -1346,6 +1510,8 @@ void      config_rehash()
        ConfigItem_log                  *log_ptr;
        ConfigItem_alias                *alias_ptr;
        ConfigItem_help                 *help_ptr;
+       ConfigItem_offchans             *of_ptr;
+       OperStat                        *os_ptr;
        ListStruct      *next, *next2;
 
        USE_BAN_VERSION = 0;
@@ -1624,7 +1790,20 @@ void     config_rehash()
                DelListItem(help_ptr, conf_help);
                MyFree(help_ptr);
        }
-
+       for (os_ptr = iConf.oper_only_stats_ext; os_ptr; os_ptr = (OperStat *)next)
+       {
+               next = (ListStruct *)os_ptr->next;
+               ircfree(os_ptr->flag);
+               MyFree(os_ptr);
+       }
+       iConf.oper_only_stats_ext = NULL;
+       for (of_ptr = conf_offchans; of_ptr; of_ptr = (ConfigItem_offchans *)next)
+       {
+               next = (ListStruct *)of_ptr->next;
+               ircfree(of_ptr->topic);
+               MyFree(of_ptr);
+       }
+       conf_offchans = NULL;
 }
 
 int    config_post_test()
@@ -2080,6 +2259,23 @@ int      AllowClient(aClient *cptr, struct hostent *hp, char *sockhost)
                (void)strncat(uhost, sockhost, sizeof(uhost) - strlen(uhost));
                if (!match(aconf->ip, uhost))
                        goto attach;
+
+               /* Hmm, localhost is a special case, hp == NULL and sockhost contains
+                * 'localhost' instead of an ip... -- Syzop. */
+               if (!strcmp(sockhost, "localhost"))
+               {
+                       if (index(aconf->hostname, '@'))
+                       {
+                               strcpy(uhost, cptr->username);
+                               strcat(uhost, "@localhost");
+                       }
+                       else
+                               strcpy(uhost, "localhost");
+
+                       if (!match(aconf->hostname, uhost))
+                               goto attach;
+               }
+               
                continue;
              attach:
 /*             if (index(uhost, '@'))  now flag based -- codemastr */
@@ -2148,6 +2344,7 @@ ConfigItem_vhost *Find_vhost(char *name) {
 }
 
 
+/** returns NULL if allowed and struct if denied */
 ConfigItem_deny_channel *Find_channel_allowed(char *name)
 {
        ConfigItem_deny_channel *dchannel;
@@ -2199,157 +2396,6 @@ char *pretty_time_val(long timeval)
        return buf;
 }
 
-/* Report the unrealircd.conf info -codemastr*/
-void report_dynconf(aClient *sptr)
-{
-       char *uhallow;
-       sendto_one(sptr, ":%s %i %s :*** Dynamic Configuration Report ***",
-           me.name, RPL_TEXT, sptr->name);
-       sendto_one(sptr, ":%s %i %s :kline-address: %s", me.name, RPL_TEXT,
-           sptr->name, KLINE_ADDRESS);
-       sendto_one(sptr, ":%s %i %s :modes-on-connect: %s", me.name, RPL_TEXT,
-           sptr->name, get_modestr(CONN_MODES));
-       sendto_one(sptr, ":%s %i %s :modes-on-oper: %s", me.name, RPL_TEXT,
-           sptr->name, get_modestr(OPER_MODES));
-       *modebuf = *parabuf = 0;
-       chmode_str(iConf.modes_on_join, modebuf, parabuf);
-       sendto_one(sptr, ":%s %i %s :modes-on-join: %s %s", me.name, RPL_TEXT,
-               sptr->name, modebuf, parabuf);
-       sendto_one(sptr, ":%s %i %s :snomask-on-oper: %s", me.name, RPL_TEXT,
-           sptr->name, OPER_SNOMASK);
-       sendto_one(sptr, ":%s %i %s :snomask-on-connect: %s", me.name, RPL_TEXT,
-           sptr->name, CONNECT_SNOMASK ? CONNECT_SNOMASK : "+");
-       if (OPER_ONLY_STATS)
-               sendto_one(sptr, ":%s %i %s :oper-only-stats: %s", me.name, RPL_TEXT,
-                       sptr->name, OPER_ONLY_STATS);
-       if (RESTRICT_USERMODES)
-               sendto_one(sptr, ":%s %i %s :restrict-usermodes: %s", me.name, RPL_TEXT,
-                       sptr->name, RESTRICT_USERMODES);
-       if (RESTRICT_CHANNELMODES)
-               sendto_one(sptr, ":%s %i %s :restrict-channelmodes: %s", me.name, RPL_TEXT,
-                       sptr->name, RESTRICT_CHANNELMODES);
-       switch (UHOST_ALLOWED)
-       {
-               case UHALLOW_ALWAYS:
-                       uhallow = "always";
-                       break;
-               case UHALLOW_NEVER:
-                       uhallow = "never";
-                       break;
-               case UHALLOW_NOCHANS:
-                       uhallow = "not-on-channels";
-                       break;
-               case UHALLOW_REJOIN:
-                       uhallow = "force-rejoin";
-                       break;
-       }
-       sendto_one(sptr, ":%s %i %s :anti-spam-quit-message-time: %s", me.name, RPL_TEXT, 
-               sptr->name, pretty_time_val(ANTI_SPAM_QUIT_MSG_TIME));
-       sendto_one(sptr, ":%s %i %s :allow-userhost-change: %s", me.name, RPL_TEXT, sptr->name, uhallow);
-#ifdef USE_SSL
-       sendto_one(sptr, ":%s %i %s :ssl::egd: %s", me.name, RPL_TEXT,
-               sptr->name, EGD_PATH ? EGD_PATH : (USE_EGD ? "1" : "0"));
-       sendto_one(sptr, ":%s %i %s :ssl::certificate: %s", me.name, RPL_TEXT,
-               sptr->name, SSL_SERVER_CERT_PEM);
-       sendto_one(sptr, ":%s %i %s :ssl::key: %s", me.name, RPL_TEXT,
-               sptr->name, SSL_SERVER_KEY_PEM);
-       sendto_one(sptr, ":%s %i %s :ssl::trusted-ca-file: %s", me.name, RPL_TEXT, sptr->name,
-        iConf.trusted_ca_file ? iConf.trusted_ca_file : "<none>");
-       sendto_one(sptr, ":%s %i %s :ssl::options: %s %s %s", me.name, RPL_TEXT, sptr->name,
-               iConf.ssl_options & SSLFLAG_FAILIFNOCERT ? "FAILIFNOCERT" : "",
-               iConf.ssl_options & SSLFLAG_VERIFYCERT ? "VERIFYCERT" : "",
-               iConf.ssl_options & SSLFLAG_DONOTACCEPTSELFSIGNED ? "DONOTACCEPTSELFSIGNED" : "");
-#endif
-
-       sendto_one(sptr, ":%s %i %s :options::show-opermotd: %d", me.name, RPL_TEXT,
-           sptr->name, SHOWOPERMOTD);
-       sendto_one(sptr, ":%s %i %s :options::hide-ulines: %d", me.name, RPL_TEXT,
-           sptr->name, HIDE_ULINES);
-       sendto_one(sptr, ":%s %i %s :options::webtv-support: %d", me.name, RPL_TEXT,
-           sptr->name, WEBTV_SUPPORT);
-       sendto_one(sptr, ":%s %i %s :options::identd-check: %d", me.name, RPL_TEXT,
-           sptr->name, IDENT_CHECK);
-       sendto_one(sptr, ":%s %i %s :options::fail-oper-warn: %d", me.name, RPL_TEXT,
-           sptr->name, FAILOPER_WARN);
-       sendto_one(sptr, ":%s %i %s :options::show-connect-info: %d", me.name, RPL_TEXT,
-           sptr->name, SHOWCONNECTINFO);
-       sendto_one(sptr, ":%s %i %s :maxchannelsperuser: %i", me.name, RPL_TEXT,
-           sptr->name, MAXCHANNELSPERUSER);
-       sendto_one(sptr, ":%s %i %s :auto-join: %s", me.name, RPL_TEXT,
-           sptr->name, AUTO_JOIN_CHANS ? AUTO_JOIN_CHANS : "0");
-       sendto_one(sptr, ":%s %i %s :oper-auto-join: %s", me.name,
-           RPL_TEXT, sptr->name, OPER_AUTO_JOIN_CHANS ? OPER_AUTO_JOIN_CHANS : "0");
-       sendto_one(sptr, ":%s %i %s :static-quit: %s", me.name, 
-               RPL_TEXT, sptr->name, STATIC_QUIT ? STATIC_QUIT : "<none>");    
-       sendto_one(sptr, ":%s %i %s :dns::timeout: %s", me.name, RPL_TEXT,
-           sptr->name, pretty_time_val(HOST_TIMEOUT));
-       sendto_one(sptr, ":%s %i %s :dns::retries: %d", me.name, RPL_TEXT,
-           sptr->name, HOST_RETRIES);
-       sendto_one(sptr, ":%s %i %s :dns::nameserver: %s", me.name, RPL_TEXT,
-           sptr->name, NAME_SERVER);
-#ifdef THROTTLING
-       sendto_one(sptr, ":%s %i %s :throttle::period: %s", me.name, RPL_TEXT,
-                       sptr->name, THROTTLING_PERIOD ? pretty_time_val(THROTTLING_PERIOD) : "disabled");
-       sendto_one(sptr, ":%s %i %s :throttle::connections: %d", me.name, RPL_TEXT,
-                       sptr->name, THROTTLING_COUNT ? THROTTLING_COUNT : -1);
-#endif
-       sendto_one(sptr, ":%s %i %s :anti-flood::unknown-flood-bantime: %s", me.name, RPL_TEXT,
-                       sptr->name, pretty_time_val(UNKNOWN_FLOOD_BANTIME));
-       sendto_one(sptr, ":%s %i %s :anti-flood::unknown-flood-amount: %dKB", me.name, RPL_TEXT,
-                       sptr->name, UNKNOWN_FLOOD_AMOUNT);
-#ifdef NO_FLOOD_AWAY
-       if (AWAY_PERIOD)
-       {
-               sendto_one(sptr, ":%s %i %s :anti-flood::away-count: %d", me.name, RPL_TEXT, 
-                       sptr->name, AWAY_COUNT);
-               sendto_one(sptr, ":%s %i %s :anti-flood::away-period: %s", me.name, RPL_TEXT,
-                       sptr->name, pretty_time_val(AWAY_PERIOD));
-       }
-#endif
-       sendto_one(sptr, ":%s %i %s :ident::connect-timeout: %s", me.name, RPL_TEXT,
-                       sptr->name, pretty_time_val(IDENT_CONNECT_TIMEOUT));
-       sendto_one(sptr, ":%s %i %s :ident::read-timeout: %s", me.name, RPL_TEXT,
-                       sptr->name, pretty_time_val(IDENT_READ_TIMEOUT));
-       
-}
-
-/* Report the network file info -codemastr */
-void report_network(aClient *sptr)
-{
-       sendto_one(sptr, ":%s %i %s :*** Network Configuration Report ***",
-           me.name, RPL_TEXT, sptr->name);
-       sendto_one(sptr, ":%s %i %s :network-name: %s", me.name, RPL_TEXT,
-           sptr->name, ircnetwork);
-       sendto_one(sptr, ":%s %i %s :default-server: %s", me.name, RPL_TEXT,
-           sptr->name, defserv);
-       sendto_one(sptr, ":%s %i %s :services-server: %s", me.name, RPL_TEXT,
-           sptr->name, SERVICES_NAME);
-       sendto_one(sptr, ":%s %i %s :stats-server: %s", me.name, RPL_TEXT,
-           sptr->name, STATS_SERVER);
-       sendto_one(sptr, ":%s %i %s :hosts::global: %s", me.name, RPL_TEXT,
-           sptr->name, oper_host);
-       sendto_one(sptr, ":%s %i %s :hosts::admin: %s", me.name, RPL_TEXT,
-           sptr->name, admin_host);
-       sendto_one(sptr, ":%s %i %s :hosts::local: %s", me.name, RPL_TEXT,
-           sptr->name, locop_host);
-       sendto_one(sptr, ":%s %i %s :hosts::servicesadmin: %s", me.name, RPL_TEXT,
-           sptr->name, sadmin_host);
-       sendto_one(sptr, ":%s %i %s :hosts::netadmin: %s", me.name, RPL_TEXT,
-           sptr->name, netadmin_host);
-       sendto_one(sptr, ":%s %i %s :hosts::coadmin: %s", me.name, RPL_TEXT,
-           sptr->name, coadmin_host);
-       sendto_one(sptr, ":%s %i %s :hiddenhost-prefix: %s", me.name, RPL_TEXT,
-           sptr->name, hidden_host);
-       sendto_one(sptr, ":%s %i %s :help-channel: %s", me.name, RPL_TEXT,
-           sptr->name, helpchan);
-       sendto_one(sptr, ":%s %i %s :hosts::host-on-oper-up: %i", me.name, RPL_TEXT, sptr->name,
-           iNAH);
-       sendto_one(sptr, ":%s %i %s :cloak-keys: %X", me.name, RPL_TEXT, sptr->name,
-               CLOAK_KEYCRC);
-}
-
-
-
 /*
  * Actual config parser funcs
 */
@@ -3405,6 +3451,15 @@ int      _test_listen(ConfigFile *conf, ConfigEntry *ce)
                        ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
                return 1;
        }
+#ifdef INET6
+       if ((strlen(ip) > 6) && !strchr(ip, ':') && isdigit(ip[strlen(ip)-1]))
+       {
+               config_error("%s:%i: listen: ip set to '%s' (ipv4) on an IPv6 compile, "
+                             "use the ::ffff:1.2.3.4 form instead",
+                                       ce->ce_fileptr->cf_filename, ce->ce_varlinenum, ip);
+               return 1;
+       }
+#endif
        port_range(port, &start, &end);
        if (start == end)
        {
@@ -4267,6 +4322,22 @@ int      _test_vhost(ConfigFile *conf, ConfigEntry *ce)
 }
 
 #ifdef STRIPBADWORDS
+
+static ConfigItem_badword *copy_badword_struct(ConfigItem_badword *ca, int regex, int regflags)
+{
+       ConfigItem_badword *x = MyMalloc(sizeof(ConfigItem_badword));
+       memcpy(x, ca, sizeof(ConfigItem_badword));
+       x->word = strdup(ca->word);
+       if (ca->replace)
+               x->replace = strdup(ca->replace);
+       if (regex) 
+       {
+               memset(&x->expr, 0, sizeof(regex_t));
+               regcomp(&x->expr, x->word, regflags);
+       }
+       return x;
+}
+
 int     _conf_badword(ConfigFile *conf, ConfigEntry *ce)
 {
        ConfigEntry *cep;
@@ -4357,10 +4428,15 @@ int     _conf_badword(ConfigFile *conf, ConfigEntry *ce)
                AddListItem(ca, conf_badword_channel);
        else if (!strcmp(ce->ce_vardata, "message"))
                AddListItem(ca, conf_badword_message);
-       else
+       else if (!strcmp(ce->ce_vardata, "quit"))
                AddListItem(ca, conf_badword_quit);
+       else if (!strcmp(ce->ce_vardata, "all"))
+       {
+               AddListItem(ca, conf_badword_channel);
+               AddListItem(copy_badword_struct(ca,regex,regflags), conf_badword_message);
+               AddListItem(copy_badword_struct(ca,regex,regflags), conf_badword_quit);
+       }
        return 1;
-
 }
 
 int _test_badword(ConfigFile *conf, ConfigEntry *ce) { 
@@ -4379,7 +4455,8 @@ int _test_badword(ConfigFile *conf, ConfigEntry *ce) {
                        ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
                return 1;
        }
-       else if (strcmp(ce->ce_vardata, "channel") && strcmp(ce->ce_vardata, "message") && strcmp(ce->ce_vardata, "quit")) {
+       else if (strcmp(ce->ce_vardata, "channel") && strcmp(ce->ce_vardata, "message") && 
+                strcmp(ce->ce_vardata, "quit") && strcmp(ce->ce_vardata, "all")) {
                        config_error("%s:%i: badword with unknown type",
                                ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
                return 1;
@@ -4779,8 +4856,11 @@ int      _test_link(ConfigFile *conf, ConfigEntry *ce)
                if (cep->ce_vardata && (strlen(cep->ce_vardata) > 6) && !strchr(cep->ce_vardata, ':') &&
                    isdigit(cep->ce_vardata[strlen(cep->ce_vardata)-1]))
                {
-                       config_status("%s:%i: link %s is probably IPv4, use the ::ffff:1.2.3.4 form instead",
-                                               cep->ce_fileptr->cf_filename, cep->ce_varlinenum, ce->ce_vardata);
+                       config_error("%s:%i: link %s has link::hostname set to '%s' (IPv4) on a IPv6 compile, "
+                                     "use the ::ffff:1.2.3.4 form instead",
+                                               cep->ce_fileptr->cf_filename, cep->ce_varlinenum, ce->ce_vardata,
+                                               cep->ce_vardata);
+                       errors++;
                }
        }
 #endif
@@ -4905,6 +4985,7 @@ int     _conf_ban(ConfigFile *conf, ConfigEntry *ce)
        }
        else {
                int value;
+               free(ca); /* ca isn't used, modules have their own list. */
                for (global_i = Hooks[HOOKTYPE_CONFIGRUN]; global_i;
                     global_i = global_i->next)
                {
@@ -5038,7 +5119,7 @@ int       _conf_set(ConfigFile *conf, ConfigEntry *ce)
                        tempiConf.oper_modes = (long) set_usermode(cep->ce_vardata);
                }
                else if (!strcmp(cep->ce_varname, "modes-on-join")) {
-                       set_channelmodes(cep->ce_vardata, &tempiConf.modes_on_join);
+                       set_channelmodes(cep->ce_vardata, &tempiConf.modes_on_join, 0);
                }
                else if (!strcmp(cep->ce_varname, "snomask-on-oper")) {
                        ircstrdup(tempiConf.oper_snomask, cep->ce_vardata);
@@ -5065,6 +5146,9 @@ int       _conf_set(ConfigFile *conf, ConfigEntry *ce)
                        else
                                tempiConf.userhost_allowed = UHALLOW_REJOIN;
                }
+               else if (!strcmp(cep->ce_varname, "channel-command-prefix")) {
+                       ircstrdup(tempiConf.channel_command_prefix, cep->ce_vardata);
+               }
                else if (!strcmp(cep->ce_varname, "restrict-usermodes")) {
                        int i;
                        char *p = MyMalloc(strlen(cep->ce_vardata) + 1), *x = p;
@@ -5093,7 +5177,19 @@ int      _conf_set(ConfigFile *conf, ConfigEntry *ce)
                        tempiConf.anti_spam_quit_message_time = config_checkval(cep->ce_vardata,CFG_TIME);
                }
                else if (!strcmp(cep->ce_varname, "oper-only-stats")) {
-                       ircstrdup(tempiConf.oper_only_stats, cep->ce_vardata);
+                       if (!cep->ce_entries)
+                       {
+                               ircstrdup(tempiConf.oper_only_stats, cep->ce_vardata);
+                       }
+                       else
+                       {
+                               for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
+                               {
+                                       OperStat *os = MyMalloc(sizeof(OperStat));
+                                       ircstrdup(os->flag, cepp->ce_varname);
+                                       AddListItem(os, tempiConf.oper_only_stats_ext);
+                               }
+                       }
                }
                else if (!strcmp(cep->ce_varname, "maxchannelsperuser")) {
                        tempiConf.maxchannelsperuser = atoi(cep->ce_vardata);
@@ -5165,7 +5261,22 @@ int      _conf_set(ConfigFile *conf, ConfigEntry *ce)
                                        tempiConf.away_count = atol(cepp->ce_vardata);
                                else if (!strcmp(cepp->ce_varname, "away-period"))
                                        tempiConf.away_period = config_checkval(cepp->ce_vardata, CFG_TIME);
+                               else if (!strcmp(cepp->ce_varname, "away-flood"))
+                               {
+                                       int cnt, period;
+                                       config_parse_flood(cepp->ce_vardata, &cnt, &period);
+                                       tempiConf.away_count = cnt;
+                                       tempiConf.away_period = period;
+                               }
 #endif
+                               else if (!strcmp(cepp->ce_varname, "nick-flood"))
+                               {
+                                       int cnt, period;
+                                       config_parse_flood(cepp->ce_vardata, &cnt, &period);
+                                       tempiConf.nick_count = cnt;
+                                       tempiConf.nick_period = period;
+                               }
+
                        }
                }
                else if (!strcmp(cep->ce_varname, "options")) {
@@ -5244,6 +5355,10 @@ int      _conf_set(ConfigFile *conf, ConfigEntry *ce)
                                        tempiConf.ident_read_timeout = config_checkval(cepp->ce_vardata,CFG_TIME);
                        }
                }
+               else if (!strcmp(cep->ce_varname, "default-bantime"))
+               {
+                       tempiConf.default_bantime = config_checkval(cep->ce_vardata,CFG_TIME);
+               }
                else if (!strcmp(cep->ce_varname, "ssl")) {
 #ifdef USE_SSL
                        for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next) {
@@ -5356,6 +5471,8 @@ int       _test_set(ConfigFile *conf, ConfigEntry *ce)
                        CheckNull(cep);
                        for (c = cep->ce_vardata; *c; c++)
                        {
+                               if (*c == ' ')
+                                       break; /* don't check the parameter ;p */
                                switch (*c)
                                {
                                        case 'q':
@@ -5377,7 +5494,7 @@ int       _test_set(ConfigFile *conf, ConfigEntry *ce)
                                                break;
                                }
                        }
-                       set_channelmodes(cep->ce_vardata, &temp);
+                       set_channelmodes(cep->ce_vardata, &temp, 1);
                        if (temp.mode & MODE_NOKNOCK && !(temp.mode & MODE_INVITEONLY))
                        {
                                config_error("%s:%i: set::modes-on-join has +K but not +i",
@@ -5417,6 +5534,9 @@ int       _test_set(ConfigFile *conf, ConfigEntry *ce)
                else if (!strcmp(cep->ce_varname, "oper-auto-join")) {
                        CheckNull(cep);
                }
+               else if (!strcmp(cep->ce_varname, "channel-command-prefix")) {
+                       CheckNull(cep);
+               }
                else if (!strcmp(cep->ce_varname, "allow-userhost-change")) {
                        CheckNull(cep);
                        if (stricmp(cep->ce_vardata, "always") && 
@@ -5435,7 +5555,20 @@ int      _test_set(ConfigFile *conf, ConfigEntry *ce)
                        CheckNull(cep);
                }
                else if (!strcmp(cep->ce_varname, "oper-only-stats")) {
-                       CheckNull(cep);
+                       if (!cep->ce_entries)
+                       {
+                               CheckNull(cep);
+                       }
+                       else
+                       {
+                               for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
+                               {
+                                       if (!cepp->ce_varname)
+                                               config_error("%s:%i: blank set::oper-only-stats item",
+                                                       cepp->ce_fileptr->cf_filename,
+                                                       cepp->ce_varlinenum);
+                               }
+                       }
                }
                else if (!strcmp(cep->ce_varname, "maxchannelsperuser")) {
                        CheckNull(cep);
@@ -5594,7 +5727,33 @@ int      _test_set(ConfigFile *conf, ConfigEntry *ce)
                                                errors++;
                                        }
                                }
+                               else if (!strcmp(cepp->ce_varname, "away-flood"))
+                               {
+                                       int cnt, period;
+                                       if (!config_parse_flood(cepp->ce_vardata, &cnt, &period) ||
+                                           (cnt < 1) || (cnt > 255) || (period < 10))
+                                       {
+                                               config_error("%s:%i: set::anti-flood::away-flood error. Syntax is '<count>:<period>' (eg 5:60), "
+                                                            "count should be 1-255, period should be greater than 9",
+                                                       cepp->ce_fileptr->cf_filename,
+                                                       cepp->ce_varname);
+                                               errors++;
+                                       }
+                               }
 #endif
+                               else if (!strcmp(cepp->ce_varname, "nick-flood"))
+                               {
+                                       int cnt, period;
+                                       if (!config_parse_flood(cepp->ce_vardata, &cnt, &period) ||
+                                           (cnt < 1) || (cnt > 255) || (period < 5))
+                                       {
+                                               config_error("%s:%i: set::anti-flood::away-flood error. Syntax is '<count>:<period>' (eg 5:60), "
+                                                            "count should be 1-255, period should be greater than 4",
+                                                       cepp->ce_fileptr->cf_filename,
+                                                       cepp->ce_varname);
+                                               errors++;
+                                       }
+                               }
                                else
                                {
                                        config_error("%s:%i: unknown option set::anti-flood::%s",
@@ -5702,6 +5861,20 @@ int      _test_set(ConfigFile *conf, ConfigEntry *ce)
                                errors++;
                                continue;
                        }               
+                       /* values which are >LONG_MAX are (re)set to LONG_MAX, problem is
+                        * that 'long' could be 32 or 64 bits resulting in different limits (LONG_MAX),
+                        * which then again results in different cloak keys.
+                        * We could warn/error here or silently reset them to 2147483647...
+                        * IMO it's best to error because the value 2147483647 would be predictable
+                        * (actually that's even unrelated to this 64bit problem).
+                        */
+                       if ((l1 >= 2147483647) || (l2 >= 2147483647) || (l3 >= 2147483647))
+                       {
+                               config_error("%s:%i: set::cloak-keys: values must be below 2147483647 (2^31-1)",
+                                       cep->ce_fileptr->cf_filename, cep->ce_varlinenum);
+                               errors++;
+                               continue;
+                       }
                        requiredstuff.settings.cloakkeys = 1;   
                }
                else if (!strcmp(cep->ce_varname, "scan")) {
@@ -5731,6 +5904,16 @@ int      _test_set(ConfigFile *conf, ConfigEntry *ce)
                                }
                        }
                }
+               else if (!strcmp(cep->ce_varname, "default-bantime")) {
+                       long x;
+                       x = config_checkval(cep->ce_vardata,CFG_TIME);
+                       if ((x < 0) > (x > 2000000000))
+                       {
+                               config_error("%s:%i: set::default-bantime: value '%ld' out of range",
+                                       cep->ce_fileptr->cf_filename, cep->ce_varlinenum, x);
+                               errors++;
+                       }
+               }
                else if (!strcmp(cep->ce_varname, "ssl")) {
 #ifdef USE_SSL
                        for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next) {
@@ -5917,6 +6100,84 @@ void     run_configuration(void)
        }
 }
 
+int    _conf_offchans(ConfigFile *conf, ConfigEntry *ce)
+{
+       ConfigEntry *cep, *cepp;
+
+       for (cep = ce->ce_entries; cep; cep = cep->ce_next)
+       {
+               ConfigItem_offchans *of = MyMallocEx(sizeof(ConfigItem_offchans));
+               strlcpy(of->chname, cep->ce_varname, CHANNELLEN+1);
+               for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
+               {
+                       if (!strcmp(cepp->ce_varname, "topic"))
+                               of->topic = strdup(cepp->ce_vardata);
+               }
+               AddListItem(of, conf_offchans);
+       }
+       return 0;
+}
+
+int    _test_offchans(ConfigFile *conf, ConfigEntry *ce)
+{
+       int errors = 0;
+       ConfigEntry *cep, *cep2;
+       char checkchan[CHANNELLEN + 1];
+       
+       if (!ce->ce_entries)
+       {
+               config_error("%s:%i: empty official-channels block", 
+                       ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
+               return 1;
+       }
+       for (cep = ce->ce_entries; cep; cep = cep->ce_next)
+       {
+               if (strlen(cep->ce_varname) > CHANNELLEN)
+               {
+                       config_error("%s:%i: official-channels: '%s' name too long (max %d characters).",
+                               cep->ce_fileptr->cf_filename, cep->ce_varlinenum, cep->ce_varname, CHANNELLEN);
+                       errors++;
+                       continue;
+               }
+               strcpy(checkchan, cep->ce_varname); /* safe */
+               clean_channelname(checkchan);
+               if (strcmp(checkchan, cep->ce_varname) || (*cep->ce_varname != '#'))
+               {
+                       config_error("%s:%i: official-channels: '%s' is not a valid channel name.",
+                               cep->ce_fileptr->cf_filename, cep->ce_varlinenum, cep->ce_varname);
+                       errors++;
+                       continue;
+               }
+               for (cep2 = cep->ce_entries; cep2; cep2 = cep2->ce_next)
+               {
+                       if (!cep2->ce_vardata)
+                       {
+                               config_error("%s:%i: official-channels::%s: %s has no value",
+                                       cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, cep->ce_varname, cep2->ce_varname);
+                               errors++;
+                               continue;
+                       }
+                       if (!strcmp(cep2->ce_varname, "topic"))
+                       {
+                               if (strlen(cep2->ce_vardata) > TOPICLEN)
+                               {
+                                       config_error("%s:%i: official-channels::%s: topic too long (max %d characters).",
+                                               cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, cep->ce_varname, TOPICLEN);
+                                       errors++;
+                                       continue;
+                               }
+                       } else {
+                               config_error("%s:%i: official-channels::%s: unknown directive '%s'.",
+                                       cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, cep->ce_varname, cep2->ce_varname);
+                               errors++;
+                               continue;
+                       }
+               }
+       }
+       return errors;
+}
+
+
 int    _conf_alias(ConfigFile *conf, ConfigEntry *ce)
 {
        ConfigItem_alias *alias = NULL;
@@ -6185,6 +6446,10 @@ int      _conf_deny_channel(ConfigFile *conf, ConfigEntry *ce)
                {
                        ircstrdup(deny->reason, cep->ce_vardata);
                }
+               else if (!strcmp(cep->ce_varname, "warn"))
+               {
+                       deny->warn = config_checkval(cep->ce_vardata,CFG_YESNO);
+               }
        }
        AddListItem(deny, conf_deny_channel);
        return 0;
@@ -6319,6 +6584,8 @@ int     _test_deny(ConfigFile *conf, ConfigEntry *ce)
                                ;
                        else if (!strcmp(cep->ce_varname, "reason"))
                                ;
+                       else if (!strcmp(cep->ce_varname, "warn"))
+                               ;
                        else 
                        {
                                config_error("%s:%i: unknown directive deny::%s",
@@ -6506,6 +6773,7 @@ int     _test_deny(ConfigFile *conf, ConfigEntry *ce)
 
 int     rehash(aClient *cptr, aClient *sptr, int sig)
 {
+       loop.ircd_rehashing = 1;
        flush_connections(&me);
        if (sig == 1)
        {
@@ -6518,7 +6786,9 @@ int     rehash(aClient *cptr, aClient *sptr, int sig)
        }
        if (init_conf(configfile, 1) == 0)
                run_configuration();
-       
+       unload_all_unused_snomasks();
+       unload_all_unused_umodes();
+       loop.ircd_rehashing = 0;        
        return 1;
 }
 
index e33b4226d84c1c286b7b41edc75b64450b6e2e52..0ab4c0609459142e871f8352a976b2739a17c3f1 100644 (file)
@@ -62,9 +62,6 @@ char serveropts[] = {
 #ifdef USE_SYSLOG
        'Y',
 #endif
-#ifdef NO_IDENT_CHECKING
-       'K',
-#endif
 #ifdef INET6
        '6',
 #endif
@@ -85,6 +82,9 @@ char serveropts[] = {
 #endif
 #ifdef ZIP_LINKS
        'Z',
+#endif
+#ifdef EXTCMODE
+       'E',
 #endif
        '\0'
 };
@@ -345,196 +345,4 @@ void send_usage(aClient *cptr, char *nick)
 }
 #endif
 
-void count_memory(aClient *cptr, char *nick)
-{
-       extern aChannel *channel;
-       extern int flinks;
-       extern Link *freelink;
-       extern MemoryInfo StatsZ;
-
-       aClient *acptr;
-       Ban *ban;
-       Link *link;
-       aChannel *chptr;
-
-       int  lc = 0,            /* local clients */
-            ch = 0,            /* channels */
-            lcc = 0,           /* local client conf links */
-            rc = 0,            /* remote clients */
-            us = 0,            /* user structs */
-            chu = 0,           /* channel users */
-            chi = 0,           /* channel invites */
-            chb = 0,           /* channel bans */
-            wwu = 0,           /* whowas users */
-            fl = 0,            /* free links */
-            cl = 0,            /* classes */
-            co = 0;            /* conf lines */
-
-       int  usi = 0,           /* users invited */
-            usc = 0,           /* users in channels */
-            aw = 0,            /* aways set */
-            wwa = 0,           /* whowas aways */
-            wlh = 0,           /* watchlist headers */
-            wle = 0;           /* watchlist entries */
-
-       u_long chm = 0,         /* memory used by channels */
-            chbm = 0,          /* memory used by channel bans */
-            lcm = 0,           /* memory used by local clients */
-            rcm = 0,           /* memory used by remote clients */
-            awm = 0,           /* memory used by aways */
-            wwam = 0,          /* whowas away memory used */
-            wwm = 0,           /* whowas array memory used */
-            com = 0,           /* memory used by conf lines */
-            wlhm = 0,          /* watchlist memory used */
-            db = 0,            /* memory used by dbufs */
-            rm = 0,            /* res memory used */
-            totcl = 0, totch = 0, totww = 0, tot = 0;
-
-       count_whowas_memory(&wwu, &wwam);
-       count_watch_memory(&wlh, &wlhm);
-       wwm = sizeof(aName) * NICKNAMEHISTORYLENGTH;
-
-       for (acptr = client; acptr; acptr = acptr->next)
-       {
-               if (MyConnect(acptr))
-               {
-                       lc++;
-                       /*for (link = acptr->confs; link; link = link->next)
-                               lcc++;
-                       wle += acptr->notifies;*/
-                       
-               }
-               else
-                       rc++;
-               if (acptr->user)
-               {
-                       Membership *mb;
-                       us++;
-                       for (link = acptr->user->invited; link;
-                           link = link->next)
-                               usi++;
-                       for (mb = acptr->user->channel; mb;
-                           mb = mb->next)
-                               usc++;
-                       if (acptr->user->away)
-                       {
-                               aw++;
-                               awm += (strlen(acptr->user->away) + 1);
-                       }
-               }
-       }
-       lcm = lc * CLIENT_LOCAL_SIZE;
-       rcm = rc * CLIENT_REMOTE_SIZE;
-
-       for (chptr = channel; chptr; chptr = chptr->nextch)
-       {
-               Member *member;
-               
-               ch++;
-               chm += (strlen(chptr->chname) + sizeof(aChannel));
-               for (member = chptr->members; member; member = member->next)
-                       chu++;
-               for (link = chptr->invites; link; link = link->next)
-                       chi++;
-               for (ban = chptr->banlist; ban; ban = ban->next)
-               {
-                       chb++;
-                       chbm += (strlen(ban->banstr) + 1 +
-                           strlen(ban->who) + 1 + sizeof(Ban));
-               }
-       }
 
-/*     for (aconf = conf; aconf; aconf = aconf->next)
-       {
-               co++;
-               com += aconf->host ? strlen(aconf->host) + 1 : 0;
-               com += aconf->passwd ? strlen(aconf->passwd) + 1 : 0;
-               com += aconf->name ? strlen(aconf->name) + 1 : 0;
-               com += sizeof(aConfItem);
-       }
-
-       for (cltmp = classes; cltmp; cltmp = cltmp->next)
-               cl++;
-*/
-       sendto_one(cptr, ":%s %d %s :Client Local %d(%d) Remote %d(%d)",
-           me.name, RPL_STATSDEBUG, nick, lc, lcm, rc, rcm);
-       sendto_one(cptr, ":%s %d %s :Users %d(%d) Invites %d(%d)",
-           me.name, RPL_STATSDEBUG, nick, us, us * sizeof(anUser), usi,
-           usi * sizeof(Link));
-       sendto_one(cptr, ":%s %d %s :User channels %d(%d) Aways %d(%d)",
-           me.name, RPL_STATSDEBUG, nick, usc, usc * sizeof(Link), aw, awm);
-       sendto_one(cptr, ":%s %d %s :WATCH headers %d(%d) entries %d(%d)",
-           me.name, RPL_STATSDEBUG, nick, wlh, wlhm, wle, wle * sizeof(Link));
-       sendto_one(cptr, ":%s %d %s :Attached confs %d(%d)",
-           me.name, RPL_STATSDEBUG, nick, lcc, lcc * sizeof(Link));
-
-       totcl = lcm + rcm + us * sizeof(anUser) + usc * sizeof(Link) + awm;
-       totcl += lcc * sizeof(Link) + usi * sizeof(Link) + wlhm;
-       totcl += wle * sizeof(Link);
-
-       sendto_one(cptr, ":%s %d %s :Conflines %d(%d)",
-           me.name, RPL_STATSDEBUG, nick, co, com);
-
-       sendto_one(cptr, ":%s %d %s :Classes %d(%d)",
-           me.name, RPL_STATSDEBUG, nick, StatsZ.classes, StatsZ.classesmem);
-
-       sendto_one(cptr, ":%s %d %s :Channels %d(%d) Bans %d(%d)",
-           me.name, RPL_STATSDEBUG, nick, ch, chm, chb, chbm);
-       sendto_one(cptr, ":%s %d %s :Channel members %d(%d) invite %d(%d)",
-           me.name, RPL_STATSDEBUG, nick, chu, chu * sizeof(Link),
-           chi, chi * sizeof(Link));
-
-       totch = chm + chbm + chu * sizeof(Link) + chi * sizeof(Link);
-
-       sendto_one(cptr, ":%s %d %s :Whowas users %d(%d) away %d(%d)",
-           me.name, RPL_STATSDEBUG, nick, wwu, wwu * sizeof(anUser),
-           wwa, wwam);
-       sendto_one(cptr, ":%s %d %s :Whowas array %d(%d)",
-           me.name, RPL_STATSDEBUG, nick, NICKNAMEHISTORYLENGTH, wwm);
-
-       totww = wwu * sizeof(anUser) + wwam + wwm;
-
-       sendto_one(cptr,
-           ":%s %d %s :Hash: client %d(%d) chan %d(%d) watch %d(%d)", me.name,
-           RPL_STATSDEBUG, nick, U_MAX, sizeof(aHashEntry) * U_MAX, CH_MAX,
-           sizeof(aHashEntry) * CH_MAX, WATCHHASHSIZE,
-           sizeof(aWatch *) * WATCHHASHSIZE);
-       db = dbufblocks * sizeof(dbufbuf);
-       sendto_one(cptr, ":%s %d %s :Dbuf blocks %d(%d)",
-           me.name, RPL_STATSDEBUG, nick, dbufblocks, db);
-
-       link = freelink;
-       while ((link = link->next))
-               fl++;
-       fl++;
-       sendto_one(cptr, ":%s %d %s :Link blocks free %d(%d) total %d(%d)",
-           me.name, RPL_STATSDEBUG, nick, fl, fl * sizeof(Link),
-           flinks, flinks * sizeof(Link));
-
-       rm = cres_mem(cptr,cptr->name);
-
-       tot = totww + totch + totcl + com + cl * sizeof(aClass) + db + rm;
-       tot += fl * sizeof(Link);
-       tot += sizeof(aHashEntry) * U_MAX;
-       tot += sizeof(aHashEntry) * CH_MAX;
-       tot += sizeof(aWatch *) * WATCHHASHSIZE;
-
-       sendto_one(cptr, ":%s %d %s :Total: ww %d ch %d cl %d co %d db %d",
-           me.name, RPL_STATSDEBUG, nick, totww, totch, totcl, com, db);
-#if !defined(_WIN32) && !defined(_AMIGA)
-#ifdef __alpha
-       sendto_one(cptr, ":%s %d %s :TOTAL: %d sbrk(0)-etext: %u",
-           me.name, RPL_STATSDEBUG, nick, tot,
-           (u_int)sbrk((size_t)0) - (u_int)sbrk0);
-#else
-       sendto_one(cptr, ":%s %d %s :TOTAL: %d sbrk(0)-etext: %ul",
-           me.name, RPL_STATSDEBUG, nick, tot,
-           (u_long)sbrk((size_t)0) - (u_long)sbrk0);
-
-#endif
-#else
-       sendto_one(cptr, ":%s %d %s :TOTAL: %d",
-           me.name, RPL_STATSDEBUG, nick, tot);
-#endif
-       return;
-}
index 3ddc129919392813cee42bbd6fa86b668827c29e..d00a3bf908e7d6ccc614ee7a5cb835db2d2d0601 100644 (file)
@@ -261,7 +261,7 @@ static char *replies[] = {
 /* 225    RPL_STATSELINE */ ":%s 225 %s e %s",
 /* 226    RPL_STATSNLINE */ ":%s 226 %s n %s %s",
 /* 227    RPL_STATSVLINE */ ":%s 227 %s V %s %s %s",
-/* 228 */ NULL,
+/* 228    RPL_STATSBANVER */ ":%s 228 %s %s %s",
 /* 229 */ NULL,
 /* 230 */ NULL,
 /* 231 */ NULL,
index 1127de74ea4c524b908c30edd2d958fd2bcc2bf4..50eeeef9eefd330ee74c1a64b6d80e82bbe630dc 100644 (file)
@@ -92,28 +92,6 @@ void dcc_sync(aClient *sptr)
        }
 }
 
-void report_flines(aClient *sptr)
-{
-       ConfigItem_deny_dcc *tmp;
-       char *filemask, *reason;
-       char a = 0;
-
-       for (tmp = conf_deny_dcc; tmp; tmp = (ConfigItem_deny_dcc *) tmp->next)
-       {
-               filemask = BadPtr(tmp->filename) ? "<NULL>" : tmp->filename;
-               reason = BadPtr(tmp->reason) ? "<NULL>" : tmp->reason;
-               if (tmp->flag.type2 == CONF_BAN_TYPE_CONF)
-                       a = 'c';
-               if (tmp->flag.type2 == CONF_BAN_TYPE_AKILL)
-                       a = 's';
-               if (tmp->flag.type2 == CONF_BAN_TYPE_TEMPORARY)
-                       a = 'o';
-               sendto_one(sptr, ":%s %i %s :%c %s %s", me.name, RPL_TEXT,
-                   sptr->name, a, filemask, reason);
-       }
-
-}
-
 void   DCCdeny_add(char *filename, char *reason, int type)
 {
        ConfigItem_deny_dcc *deny = NULL;
index 6484b7057d07df8fe8216771cab65537033ca3b5..21e6fcc63ca52e28e51874dd1a9d538f9c321eee 100644 (file)
@@ -433,26 +433,111 @@ int  find_tkline_match_zap(aClient *cptr)
        return -1;
 }
 
+#define BY_MASK 0x1
+#define BY_REASON 0x2
+#define NOT_BY_MASK 0x4
+#define NOT_BY_REASON 0x8
+#define BY_SETBY 0x10
+#define NOT_BY_SETBY 0x20
+
+typedef struct {
+       int flags;
+       char *mask;
+       char *reason;
+       char *setby;
+} TKLFlag;
+
+void parse_tkl_para(char *para, TKLFlag *flag)
+{
+       char *flags = strtok(para, " ");
+       char *tmp;
+       char what = '+';
+
+       bzero(flag, sizeof(TKLFlag));
+       for (; *flags; flags++)
+       {
+               switch (*flags)
+               {
+                       case '+':
+                               what = '+';
+                               break;
+                       case '-':
+                               what = '-';
+                               break;
+                       case 'm':
+                               if (flag->mask || !(tmp = strtok(NULL, " ")))
+                                       continue;
+                               if (what == '+')
+                                       flag->flags |= BY_MASK;
+                               else
+                                       flag->flags |= NOT_BY_MASK;
+                               flag->mask = tmp;
+                               break;
+                       case 'r':
+                               if (flag->reason || !(tmp = strtok(NULL, " ")))
+                                       continue;
+                               if (what == '+')
+                                       flag->flags |= BY_REASON;
+                               else
+                                       flag->flags |= NOT_BY_REASON;
+                               flag->reason = tmp;
+                               break;
+                       case 's':
+                               if (flag->setby || !(tmp = strtok(NULL, " ")))
+                                       continue;
+                               if (what == '+')
+                                       flag->flags |= BY_SETBY;
+                               else
+                                       flag->flags |= NOT_BY_SETBY;
+                               flag->setby = tmp;
+                               break;
+               }
+       }
+}      
 
-void tkl_stats(aClient *cptr)
+void tkl_stats(aClient *cptr, int type, char *para)
 {
        aTKline *tk;
        TS   curtime;
-
+       TKLFlag tklflags;
        /*
           We output in this row:
           Glines,GZlines,KLine, ZLIne
           Character:
           G, Z, K, z
         */
-       if (!IsAnOper(cptr) && OPER_ONLY_STATS && (strchr(OPER_ONLY_STATS, 'G') || strchr(OPER_ONLY_STATS, 'g'))) {
-               sendto_one(cptr, err_str(ERR_NOPRIVILEGES), me.name, cptr->name);
-               return;
-       }
+
+       if (!BadPtr(para))
+               parse_tkl_para(para, &tklflags);
        tkl_check_expire(NULL);
        curtime = TStime();
        for (tk = tklines; tk; tk = tk->next)
        {
+               if (type && tk->type != type)
+                       continue;
+               if (!BadPtr(para))
+               {
+                       if (tklflags.flags & BY_MASK)
+                               if (match(tklflags.mask, make_user_host(tk->usermask,
+                                       tk->hostmask)))
+                                       continue;
+                       if (tklflags.flags & NOT_BY_MASK)
+                               if (!match(tklflags.mask, make_user_host(tk->usermask,
+                                       tk->hostmask)))
+                                       continue;
+                       if (tklflags.flags & BY_REASON)
+                               if (match(tklflags.reason, tk->reason))
+                                       continue;
+                       if (tklflags.flags & NOT_BY_REASON)
+                               if (!match(tklflags.reason, tk->reason))
+                                       continue;
+                       if (tklflags.flags & BY_SETBY)
+                               if (match(tklflags.setby, tk->setby))
+                                       continue;
+                       if (tklflags.flags & NOT_BY_SETBY)
+                               if (!match(tklflags.setby, tk->setby))
+                                       continue;
+               }
                if (tk->type == (TKL_KILL | TKL_GLOBAL))
                {
                        sendto_one(cptr, rpl_str(RPL_STATSGLINE), me.name,
@@ -706,6 +791,9 @@ int m_tkl(aClient *cptr, aClient *sptr, int parc, char *parv[])
                                              "%s removed %s %s@%s (set at %s - reason: %s)",
                                              parv[5], txt, tk->usermask,
                                              tk->hostmask, gmt, tk->reason);
+                                         ircd_log(LOG_TKL, "%s removed %s %s@%s (set at %s - reason: %s)",
+                                             parv[5], txt, tk->usermask, tk->hostmask,
+                                             gmt, tk->reason);
                                          if (type & TKL_SHUN)
                                              tkl_check_local_remove_shun(tk);
                                          tkl_del_line(tk);
@@ -724,7 +812,7 @@ int m_tkl(aClient *cptr, aClient *sptr, int parc, char *parv[])
 
          case '?':
                  if (IsAnOper(sptr))
-                         tkl_stats(sptr);
+                         tkl_stats(sptr,0,NULL);
        }
        return 0;
 }
index 81a1997fe05b41acfbab4f59a08065e661f38a7b..94a6776bbdc4041950ee90dd76abfcdd671b9c0a 100644 (file)
@@ -406,6 +406,7 @@ int  exit_client(aClient *cptr, aClient *sptr, aClient *from, char *comment)
                                link_cleanup(sptr->serv->conf);
                                MyFree(sptr->serv->conf);
                        }
+                       ircd_log(LOG_SERVER, "SQUIT %s (%s)", sptr->name, comment);
                }
 
                if (sptr->listener)
@@ -443,6 +444,10 @@ int  exit_client(aClient *cptr, aClient *sptr, aClient *from, char *comment)
                                ircd_log(LOG_CLIENT, "Disconnect - (%d:%d:%d) %s!%s@%s",
                                        on_for / 3600, (on_for % 3600) / 60, on_for % 60,
                                        sptr->name, sptr->user->username, sptr->user->realhost);
+               } else
+               if (IsUnknown(sptr))
+               {
+                       RunHook2(HOOKTYPE_UNKUSER_QUIT, sptr, comment);
                }
 
                if (sptr->fd >= 0 && !IsConnecting(sptr))
@@ -650,6 +655,10 @@ static void exit_one_client(aClient *cptr, aClient *sptr, aClient *from, char *c
                                            sptr->user->server, sptr->name,
                                            sptr->user->username,
                                            sptr->user->realhost, comment);
+                       if (!MyClient(sptr))
+                       {
+                               RunHook2(HOOKTYPE_REMOTE_QUIT, sptr, comment);
+                       }
                        while ((mp = sptr->user->channel))
                                remove_user_from_channel(sptr, mp->chptr);
 
@@ -702,91 +711,25 @@ void initstats(void)
        bzero((char *)&ircst, sizeof(ircst));
 }
 
-void tstats(aClient *cptr, char *name)
+void verify_opercount(aClient *orig, char *tag)
 {
-       aClient *acptr;
-       int  i;
-       struct stats *sp;
-       struct stats tmp;
-       time_t now = TStime();
+int counted = 0;
+aClient *acptr;
+char text[2048];
 
-       sp = &tmp;
-       bcopy((char *)ircstp, (char *)sp, sizeof(*sp));
-       for (i = 0; i <= LastSlot; i++)
+       for (acptr = client; acptr; acptr = acptr->next)
        {
-               if (!(acptr = local[i]))
-                       continue;
-               if (IsServer(acptr))
-               {
-                       sp->is_sbs += acptr->sendB;
-                       sp->is_sbr += acptr->receiveB;
-                       sp->is_sks += acptr->sendK;
-                       sp->is_skr += acptr->receiveK;
-                       sp->is_sti += now - acptr->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;
-                       }
-               }
-               else if (IsClient(acptr))
-               {
-                       sp->is_cbs += acptr->sendB;
-                       sp->is_cbr += acptr->receiveB;
-                       sp->is_cks += acptr->sendK;
-                       sp->is_ckr += acptr->receiveK;
-                       sp->is_cti += now - acptr->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;
-                       }
-               }
-               else if (IsUnknown(acptr))
-                       sp->is_ni++;
+               if (IsAnOper(acptr) && !IsHideOper(acptr))
+                       counted++;
        }
-
-       sendto_one(cptr, ":%s %d %s :accepts %u refused %u",
-           me.name, RPL_STATSDEBUG, name, sp->is_ac, sp->is_ref);
-       sendto_one(cptr, ":%s %d %s :unknown commands %u prefixes %u",
-           me.name, RPL_STATSDEBUG, name, sp->is_unco, sp->is_unpf);
-       sendto_one(cptr, ":%s %d %s :nick collisions %u unknown closes %u",
-           me.name, RPL_STATSDEBUG, name, sp->is_kill, sp->is_ni);
-       sendto_one(cptr, ":%s %d %s :wrong direction %u empty %u",
-           me.name, RPL_STATSDEBUG, name, sp->is_wrdi, sp->is_empt);
-       sendto_one(cptr, ":%s %d %s :numerics seen %u mode fakes %u",
-           me.name, RPL_STATSDEBUG, name, sp->is_num, sp->is_fake);
-       sendto_one(cptr, ":%s %d %s :auth successes %u fails %u",
-           me.name, RPL_STATSDEBUG, name, sp->is_asuc, sp->is_abad);
-       sendto_one(cptr, ":%s %d %s :local connections %u udp packets %u",
-           me.name, RPL_STATSDEBUG, name, sp->is_loc, sp->is_udp);
-       sendto_one(cptr, ":%s %d %s :Client Server",
-           me.name, RPL_STATSDEBUG, name);
-       sendto_one(cptr, ":%s %d %s :connected %u %u",
-           me.name, RPL_STATSDEBUG, name, sp->is_cl, sp->is_sv);
-       sendto_one(cptr, ":%s %d %s :bytes sent %u.%uK %u.%uK",
-           me.name, RPL_STATSDEBUG, name,
-           sp->is_cks, sp->is_cbs, sp->is_sks, sp->is_sbs);
-       sendto_one(cptr, ":%s %d %s :bytes recv %u.%uK %u.%uK",
-           me.name, RPL_STATSDEBUG, name,
-           sp->is_ckr, sp->is_cbr, sp->is_skr, sp->is_sbr);
-       sendto_one(cptr, ":%s %d %s :time connected %u %u",
-           me.name, RPL_STATSDEBUG, name, sp->is_cti, sp->is_sti);
-#ifndef NO_FDLIST
-       sendto_one(cptr,
-           ":%s %d %s :incoming rate %0.2f kb/s - outgoing rate %0.2f kb/s",
-           me.name, RPL_STATSDEBUG, name, currentrate, currentrate2);
-#endif
+       if (counted == IRCstats.operators)
+               return;
+       sprintf(text, "[BUG] operator count bug! value in /lusers is '%d', we counted '%d', "
+                      "user='%s', userserver='%s', tag=%s. "
+                      "please report to UnrealIRCd team at http://bugs.unrealircd.org/",
+                      IRCstats.operators, counted, orig->name ? orig->name : "<null>",
+                      orig->srvptr ? orig->srvptr->name : "<null>", tag ? tag : "<null>");
+       sendto_realops("%s", text);
+       ircd_log(LOG_ERROR, "%s", text);
+       IRCstats.operators = counted;
 }
index aec6a1ae218bacabc33f61585e7f469cb86fca46..0bf877b59476fa585f323d349a61c1ea3292cb95 100644 (file)
@@ -1019,6 +1019,7 @@ CMD_FUNC(m_server_remote)
        strncpyzt(acptr->info, info, sizeof(acptr->info));
        acptr->serv->up = find_or_add(parv[0]);
        SetServer(acptr);
+       ircd_log(LOG_SERVER, "SERVER %s", acptr->name);
        /* Taken from bahamut makes it so all servers behind a U:lined
         * server are also U:lined, very helpful if HIDE_ULINES is on
         */
@@ -1064,13 +1065,16 @@ CMD_FUNC(m_server_remote)
  */
 void send_proto(aClient *cptr, ConfigItem_link *aconf)
 {
+char buf[512];
+       sprintf(buf, "CHANMODES=%s%s,%s%s,%s%s,%s%s",
+               CHPAR1, EXPAR1, CHPAR2, EXPAR2, CHPAR3, EXPAR3, CHPAR4, EXPAR4);
 #ifdef ZIP_LINKS
        if (aconf->options & CONNECT_ZIP)
        {
-               sendto_one(cptr, "PROTOCTL %s ZIP", PROTOCTL_SERVER);
+               sendto_one(cptr, "PROTOCTL %s ZIP %s", PROTOCTL_SERVER, buf);
        } else {
 #endif
-               sendto_one(cptr, "PROTOCTL %s", PROTOCTL_SERVER);
+               sendto_one(cptr, "PROTOCTL %s %s", PROTOCTL_SERVER, buf);
 #ifdef ZIP_LINKS
        }
 #endif
@@ -1083,6 +1087,7 @@ int       m_server_synch(aClient *cptr, long numeric, ConfigItem_link *aconf)
        aClient         *acptr;
        int             i;
 
+       ircd_log(LOG_SERVER, "SERVER %s", cptr->name);
 
        if (cptr->passwd)
        {
@@ -1230,6 +1235,24 @@ int      m_server_synch(aClient *cptr, long numeric, ConfigItem_link *aconf)
                                    acptr->name, acptr->hopcount + 1,
                                    acptr->info);
 
+                       /* Also signal to the just-linked server which
+                        * servers are fully linked.
+                        * Now you might ask yourself "Why don't we just
+                        * assume every server you get during link phase
+                        * is fully linked?", well.. there's a race condition
+                        * if 2 servers link (almost) at the same time,
+                        * then you would think the other one is fully linked
+                        * while in fact he was not.. -- Syzop.
+                        */
+                       if (acptr->serv->flags.synced)
+                       {
+                               sendto_one(cptr, ":%s %s", acptr->name,
+                                       (IsToken(cptr) ? TOK_EOS : MSG_EOS));
+#ifdef DEBUGMODE
+                               ircd_log(LOG_ERROR, "[EOSDBG] m_server_synch: sending to uplink '%s' with src %s...",
+                                       cptr->name, acptr->name);
+#endif
+                       }
                }
        }
        /* Synching nick information */
@@ -1424,6 +1447,14 @@ int      m_server_synch(aClient *cptr, long numeric, ConfigItem_link *aconf)
            IRCstats.global_max, TStime(), UnrealProtocol,
            CLOAK_KEYCRC,
            ircnetwork);
+
+       /* Send EOS (End Of Sync) to the just linked server... */
+       sendto_one(cptr, ":%s %s", me.name,
+               (IsToken(cptr) ? TOK_EOS : MSG_EOS));
+#ifdef DEBUGMODE
+       ircd_log(LOG_ERROR, "[EOSDBG] m_server_synch: sending to justlinked '%s' with src ME...",
+                       cptr->name);
+#endif
        return 0;
 
 }
@@ -2021,710 +2052,6 @@ char *get_client_name2(aClient *acptr, int showports)
        return pointer;
 }
 
-/*
-** m_stats
-**     parv[0] = sender prefix
-**     parv[1] = statistics selector (defaults to Message frequency)
-**     parv[2] = server name (current server defaulted, if omitted)
-**
-*/
-/*
-**    Note:   The info is reported in the order the server uses
-**            it--not reversed as in unrealircd.conf!
-*/
-
-CMD_FUNC(m_stats)
-{
-#ifndef DEBUGMODE
-       static char Sformat[] =
-           ":%s %d %s SendQ SendM SendBytes RcveM RcveBytes Open_since :Idle";
-       static char Lformat[] = ":%s %d %s %s%s %u %u %u %u %u %u :%u";
-#else
-       static char Sformat[] =
-           ":%s %d %s SendQ SendM SendBytes RcveM RcveBytes Open_since CPU :Idle";
-       static char Lformat[] = ":%s %d %s %s%s %u %u %u %u %u %u %s";
-       char pbuf[96];          /* Should be enough for to ints */
-#endif
-       ConfigItem_link *link_p;
-       ConfigItem_oper *oper_p;
-       ConfigItem_oper_from *oper_p_from;
-       aCommand *mptr;
-       aClient *acptr;
-       char stat = parc > 1 ? parv[1][0] : '\0';
-       char stat2;
-       int  i;
-       int  doall = 0, wilds = 0, showports = IsAnOper(sptr), remote = 0;
-       char *name;
-
-       if (IsServer(sptr))
-               return 0;
-       if (hunt_server_token(cptr, sptr, MSG_STATS, TOK_STATS, "%s :%s", 2, parc,
-           parv) != HUNTED_ISME)
-               return 0;
-       if (OPER_ONLY_STATS) {
-               if (!IsAnOper(sptr) && strchr(OPER_ONLY_STATS, '*'))
-               {
-                       sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
-                       return 0;
-               }
-               stat2 = tolower(stat);
-               if (!IsAnOper(sptr) && (stat2 == 'c' || stat2 == 'f' || stat2 == 'i' ||  stat2 == 'h' || 
-                       stat2 == 'y' || stat2 == 'x' || stat2 == 'g' || stat2 == 'k' || stat2 == 'o' || 
-                       stat2 == 'z' || stat2 == 'l')) {
-                       if (strchr(OPER_ONLY_STATS, toupper(stat)) || strchr(OPER_ONLY_STATS, stat2)) {
-                               sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
-                               return 0;
-                       }
-                       if (stat2 == 'c') {
-                               if (strchr(OPER_ONLY_STATS, 'h') || strchr(OPER_ONLY_STATS, 'H')) {
-                                       sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
-                                       return 0;
-                               }
-                       }
-                       if (stat2 == 'h') {
-                               if (strchr(OPER_ONLY_STATS, 'c') || strchr(OPER_ONLY_STATS, 'C')) {
-                                       sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
-                                       return 0;
-                               }
-                       }
-               }
-               if (!IsAnOper(sptr) && strchr(OPER_ONLY_STATS, stat))
-               {
-                       sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
-                       return 0;
-               }
-       }
-       if (parc > 2)
-       {
-               name = parv[2];
-               if (!mycmp(name, me.name))
-                       doall = 2;
-               else if (match(name, me.name) == 0)
-                       doall = 1;
-               if (index(name, '*') || index(name, '?'))
-                       wilds = 1;
-       }
-       else
-               name = me.name;
-
-       switch (stat)
-       {
-#ifdef STRIPBADWORDS
-         case 'b':
-         {
-                 ConfigItem_badword *words;
-
-                 for (words = conf_badword_channel; words; words = (ConfigItem_badword *) words->next) {
- #ifdef FAST_BADWORD_REPLACE
-                         sendto_one(sptr, ":%s %i %s :c %c %s%s%s %s",
-                             me.name, RPL_TEXT, sptr->name, words->type & BADW_TYPE_REGEX ? 'R' : 'F',
-                             (words->type & BADW_TYPE_FAST_L) ? "*" : "",
-                             words->word,
-                             (words->type & BADW_TYPE_FAST_R) ? "*" : "",
-                             words->action == BADWORD_REPLACE ? 
-                               (words->replace ? words->replace : "<censored>") : "");
- #else
-                         sendto_one(sptr, ":%s %i %s :c %s %s", me.name, RPL_TEXT, sptr->name,  words->word, 
-                               words->action == BADWORD_REPLACE ? 
-                               (words->replace ? words->replace : "<censored>") : "");
- #endif
-                 }
-                 for (words = conf_badword_message; words; words = (ConfigItem_badword *) words->next) {
- #ifdef FAST_BADWORD_REPLACE
-                         sendto_one(sptr, ":%s %i %s :m %c %s%s%s %s",
-                             me.name, RPL_TEXT, sptr->name, words->type & BADW_TYPE_REGEX ? 'R' : 'F',
-                             (words->type & BADW_TYPE_FAST_L) ? "*" : "",
-                             words->word,
-                             (words->type & BADW_TYPE_FAST_R) ? "*" : "",
-                             words->action == BADWORD_REPLACE ? 
-                               (words->replace ? words->replace : "<censored>") : "");
- #else
-                         sendto_one(sptr, ":%s %i %s :m %s %s", me.name, RPL_TEXT, sptr->name, words->word, 
-                               words->action == BADWORD_REPLACE ? 
-                               (words->replace ? words->replace : "<censored>") : "");
-
- #endif
-                 }
-                 for (words = conf_badword_quit; words; words = (ConfigItem_badword *) words->next) {
- #ifdef FAST_BADWORD_REPLACE
-                         sendto_one(sptr, ":%s %i %s :q %c %s%s%s %s",
-                             me.name, RPL_TEXT, sptr->name, words->type & BADW_TYPE_REGEX ? 'R' : 'F',
-                             (words->type & BADW_TYPE_FAST_L) ? "*" : "",
-                             words->word,
-                             (words->type & BADW_TYPE_FAST_R) ? "*" : "",
-                             words->action == BADWORD_REPLACE ? 
-                               (words->replace ? words->replace : "<censored>") : "");
- #else
-                         sendto_one(sptr, ":%s %i %s :q %s %s", me.name, RPL_TEXT, sptr->name, words->word, 
-                               words->action == BADWORD_REPLACE ? 
-                               (words->replace ? words->replace : "<censored>") : "");
-
- #endif
-                 }
-                 break;
-         }
-#endif
-         case 'L':
-         case 'l':
-                 /*
-                  * send info about connections which match, or all if the
-                  * mask matches me.name.  Only restrictions are on those who
-                  * are invisible not being visible to 'foreigners' who use
-                  * a wild card based search to list it.
-                  */
-                 sendto_one(sptr, Sformat, me.name, RPL_STATSLINKINFO,
-                     parv[0]);
-                 if (IsServer(cptr))
-                 {
-                         remote = 1;
-                         wilds = 0;
-                 }
-                 for (i = 0; i <= LastSlot; i++)
-                 {
-                         if (!(acptr = local[i]))
-                                 continue;
-                         if (IsInvisible(acptr) && (doall || wilds) &&
-                             !(MyConnect(sptr) && IsOper(sptr)) &&
-                             !IsAnOper(acptr) && (acptr != sptr))
-                                 continue;
-                         if (remote && doall && !IsServer(acptr) &&
-                             !IsMe(acptr))
-                                 continue;
-                         if (remote && !doall && IsServer(acptr))
-                                 continue;
-                         if (!doall && wilds && match(name, acptr->name))
-                                 continue;
-                         if (!(parc == 2 && (IsServer(acptr)
-                             || (acptr->flags & FLAGS_LISTEN))) && !(doall
-                             || wilds) && mycmp(name, acptr->name))
-                                 continue;
-
-#ifdef DEBUGMODE
-                         ircsprintf(pbuf, "%d :%d", acptr->cputime,
-                             (acptr->user && MyConnect(acptr)) ?
-                             TStime() - acptr->last : 0);
-#endif
-                         if (IsOper(sptr))
-                         {
-                                 sendto_one(sptr, Lformat, me.name,
-                                     RPL_STATSLINKINFO, parv[0],
-                                     (isupper(stat)) ?
-                                     get_client_name2(acptr, showports) :
-                                     get_client_name(acptr, FALSE),
-                                     get_cptr_status(acptr),
-                                     (int)DBufLength(&acptr->sendQ),
-                                     (int)acptr->sendM, (int)acptr->sendK,
-                                     (int)acptr->receiveM,
-                                     (int)acptr->receiveK,
-                                     TStime() - acptr->firsttime,
-#ifndef DEBUGMODE
-                                     (acptr->user && MyConnect(acptr)) ?
-                                     TStime() - acptr->last : 0);
-#else
-                                     pbuf);
-#endif
-                                 if (!IsServer(acptr) && !IsMe(acptr) && IsAnOper(acptr) && sptr != acptr)
-                                         sendto_one(acptr,
-                                             ":%s %s %s :*** %s did a /stats L on you! IP may have been shown",
-                                             me.name, IsWebTV(acptr) ? "PRIVMSG" : "NOTICE", acptr->name, sptr->name);
-                         }
-                         else if (!strchr(acptr->name, '.'))
-                                 sendto_one(sptr, Lformat, me.name,
-                                     RPL_STATSLINKINFO, parv[0],
-                                     IsHidden(acptr) ? acptr->name :
-                                     (isupper(stat)) ? /* Potvin - PreZ */
-                                     get_client_name2(acptr, showports) :
-                                     get_client_name(acptr, FALSE),
-                                     get_cptr_status(acptr),
-                                     (int)DBufLength(&acptr->sendQ),
-                                     (int)acptr->sendM, (int)acptr->sendK,
-                                     (int)acptr->receiveM,
-                                     (int)acptr->receiveK,
-                                     TStime() - acptr->firsttime,
-#ifndef DEBUGMODE
-                                     (acptr->user && MyConnect(acptr)) ?
-                                     TStime() - acptr->last : 0);
-#else
-                                     pbuf);
-#endif
-                 }
-                 break;
-         case 'C':
-         case 'c':
-         case 'H':
-         case 'h':
-                 for (link_p = conf_link; link_p; link_p = (ConfigItem_link *) link_p->next)
-                 {
-                       sendto_one(sptr, ":%s 213 %s C %s@%s * %s %i %s %s%s%s%s%s",
-                               me.name, sptr->name, IsOper(sptr) ? link_p->username : "*",
-                               IsOper(sptr) ? link_p->hostname : "*", link_p->servername,
-                               link_p->port,
-                               link_p->class->name,
-                               (link_p->options & CONNECT_AUTO) ? "a" : "",
-                               (link_p->options & CONNECT_SSL) ? "S" : "",
-                               (link_p->options & CONNECT_ZIP) ? "z" : "",
-                               (link_p->options & CONNECT_NODNSCACHE) ? "d" : "",
-                               (link_p->options & CONNECT_NOHOSTCHECK) ? "h" : "");
-                       if (link_p->hubmask)
-                       {
-                               sendto_one(sptr, ":%s 244 %s H %s * %s",
-                                       me.name, sptr->name, link_p->hubmask,
-                                       link_p->servername);
-                       }
-                       else
-                       if (link_p->leafmask)
-                       {
-                               sendto_one(sptr, ":%s 241 %s L %s * %s %d",
-                                       me.name, sptr->name,
-                                       link_p->leafmask, link_p->servername, link_p->leafdepth);
-                       }
-                 }
-                 break;
-         case 'f':
-         case 'F':
-                 report_flines(sptr);
-                 break;
-
-         case 'G':
-         case 'g':
-                 tkl_stats(sptr);
-                 break;
-         case 'I':
-         case 'i':
-         {
-                 ConfigItem_allow *allows;
-                 for (allows = conf_allow; allows; allows = (ConfigItem_allow *) allows->next) {
-                         sendto_one(sptr, rpl_str(RPL_STATSILINE), me.name,
-                                 parv[0], allows->ip, allows->hostname, allows->maxperip, allows->class->name, allows->server ? allows->server : defserv, allows->port ? allows->port : 6667);
-                 }
-                 break;
-         }
-         case 'E':
-         {
-                 ConfigItem_except *excepts;
-                 for (excepts = conf_except; excepts; excepts = (ConfigItem_except *) excepts->next) {
-                       if (excepts->flag.type == 1)
-                               sendto_one(sptr, rpl_str(RPL_STATSKLINE), me.name,
-                                   parv[0], "E", excepts->mask, "");
-                 }
-                 break;
-         }
-         case 'e':
-         {
-                 ConfigItem_except *excepts;
-                 for (excepts = conf_except; excepts;
-                     excepts = (ConfigItem_except *) excepts->next)
-                 {
-                         if (excepts->flag.type == 0)
-                                 sendto_one(sptr, rpl_str(RPL_STATSELINE),
-                                     me.name, parv[0], excepts->mask);
-                 }
-                 break;
-         }
-         case 'K':
-         case 'k':
-         {
-                 ConfigItem_ban *bans;
-                 ConfigItem_except *excepts;
-                 char type[2];
-                 for (bans = conf_ban; bans; bans = (ConfigItem_ban *)bans->next) {
-                         if (bans->flag.type == CONF_BAN_USER) {
-                               if (bans->flag.type2 == CONF_BAN_TYPE_CONF)
-                                         type[0] = 'K';
-                               else if (bans->flag.type2 == CONF_BAN_TYPE_AKILL)
-                                         type[0] = 'A';
-                               else if (bans->flag.type2 == CONF_BAN_TYPE_TEMPORARY)
-                                         type[0] = 'k';
-                               type[1] = '\0';
-                               sendto_one(sptr, rpl_str(RPL_STATSKLINE),
-                                   me.name, parv[0], type, bans->mask, bans->reason ? bans->reason : "<no reason>");
-                         }
-                         else if (bans->flag.type == CONF_BAN_IP) {
-                               if (bans->flag.type2 == CONF_BAN_TYPE_CONF)
-                                       type[0] = 'Z';
-                               else if (bans->flag.type2 == CONF_BAN_TYPE_AKILL)
-                                       type[0] = 'S';
-                               else if (bans->flag.type2 == CONF_BAN_TYPE_TEMPORARY)
-                                       type[0] = 'z';
-                               type[1] = '\0';
-                               sendto_one(sptr, rpl_str(RPL_STATSKLINE),
-                                   me.name, parv[0], type, bans->mask, bans->reason ? bans->reason : "<no reason>");
-                         }
-
-                 }
-                 for (excepts = conf_except; excepts; excepts = (ConfigItem_except *)excepts->next) {
-                         if (excepts->flag.type == 1)
-                                sendto_one(sptr, rpl_str(RPL_STATSKLINE),
-                                    me.name, parv[0], "E", excepts->mask, "");
-                 }
-                 break;
-         }
-         case 'm':
-               LockEventSystem();
-               EventStatus(sptr);
-               UnlockEventSystem();
-               break;
-
-         case 'M':
-                 for (i = 0; i <= 255; i++)
-                         for (mptr = CommandHash[i]; mptr; mptr = mptr->next)
-                                 if (mptr->count)
-#ifndef DEBUGMODE
-                                         sendto_one(sptr, rpl_str(RPL_STATSCOMMANDS),
-                                             me.name, parv[0], mptr->cmd,
-                                             mptr->count, mptr->bytes);
-#else
-                                         sendto_one(sptr, rpl_str(RPL_STATSCOMMANDS),
-                                             me.name, parv[0], mptr->cmd,
-                                             mptr->count, mptr->bytes,
-                                             mptr->lticks,
-                                             mptr->lticks / CLOCKS_PER_SEC,
-                                             mptr->rticks,
-                                             mptr->rticks / CLOCKS_PER_SEC);
-#endif
-                 break;
-         case 'n':
-         {
-                 ConfigItem_ban *bans;
-
-                 for (bans = conf_ban; bans; bans = (ConfigItem_ban *)bans->next) {
-                         if (bans->flag.type == CONF_BAN_REALNAME)
-                               sendto_one(sptr, rpl_str(RPL_STATSNLINE),
-                                   me.name, parv[0], bans->mask, bans->reason ? bans->reason : "<no reason>");
-                 }
-                 break;
-         }
-         case 'N':
-                 if (IsOper(sptr))
-                         report_network(sptr);
-                 break;
-         case 'o':
-         case 'O':
-                 for (oper_p = conf_oper; oper_p; oper_p = (ConfigItem_oper *) oper_p->next)
-                 {
-                       if (!oper_p->from)
-                               sendto_one(sptr, rpl_str(RPL_STATSOLINE),
-                                       me.name, sptr->name, 
-                                       'O', "(none)", oper_p->name,
-                                       oflagstr(oper_p->oflags),
-                                       oper_p->class->name ? oper_p->class->name : "");
-                       else
-                               for (oper_p_from = (ConfigItem_oper_from *) oper_p->from; oper_p_from; oper_p_from = (ConfigItem_oper_from *) oper_p_from->next)
-                                       sendto_one(sptr, rpl_str(RPL_STATSOLINE),
-                                               me.name, sptr->name, 
-                                               'O', oper_p_from->name, oper_p->name,
-                                               oflagstr(oper_p->oflags),
-                                               oper_p->class->name? oper_p->class->name : "");
-                 }
-                 break;
-         case 'P':
-                 if (IsOper(sptr))
-                 {
-                         for (i = 0; i <= LastSlot; i++)
-                         {
-                           if (!(acptr = local[i]))
-                                       continue;
-                               if (!IsListening(acptr))
-                                       continue;
-                               sendto_one(sptr, ":%s %s %s :*** Listener on %s:%i, clients %i. is %s",
-                                       me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name,
-                                       ((ConfigItem_listen *)acptr->class)->ip,
-                                       ((ConfigItem_listen *)acptr->class)->port,
-                                       ((ConfigItem_listen *)acptr->class)->clients,
-                                       ((ConfigItem_listen *)acptr->class)->flag.temporary ? "TEMPORARY" : "PERM");
-                         }
-                 }
-                 break;
-         case 'Q':
-         {
-                 ConfigItem_ban *bans;
-
-                 for (bans = conf_ban; bans; bans = (ConfigItem_ban *)bans->next) {
-                         if (bans->flag.type == CONF_BAN_NICK && (bans->flag.type2 != CONF_BAN_TYPE_AKILL))
-                               sendto_one(sptr, rpl_str(RPL_STATSQLINE),
-                                   me.name, parv[0],  bans->reason, bans->mask);
-                 }
-         }
-                 break;
-         case 'q':
-         {
-                 ConfigItem_ban *bans;
-
-                 for (bans = conf_ban; bans; bans = (ConfigItem_ban *)bans->next) {
-                         if (bans->flag.type == CONF_BAN_NICK && (bans->flag.type2 == CONF_BAN_TYPE_AKILL))
-                               sendto_one(sptr, rpl_str(RPL_SQLINE_NICK),
-                                   me.name, parv[0], bans->mask, bans->reason ? bans->reason : "No Reason");
-                 }
-                 break;
-         }
-         case 'R':
-#ifdef DEBUGMODE
-                 send_usage(sptr, parv[0]);
-#endif
-                 break;
-         case 's':
-                 if (IsOper(sptr))
-                 {
-                         sendto_one(sptr, ":%s %s %s :*** SCACHE:",
-                             me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name);
-                         list_scache(sptr);
-                         sendto_one(sptr, ":%s %s %s :*** NS:", me.name,
-                             IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name);
-                         ns_stats(sptr);
-                 }
-                 break;
-         case 'S':
-                 if (IsOper(sptr)) {
-                         report_dynconf(sptr);
-                         RunHook2(HOOKTYPE_STATS, sptr, "S");
-                 }
-                 break;
-         case 'D':
-         {
-                 ConfigItem_deny_link *links;
-
-                 for (links = conf_deny_link; links; links = (ConfigItem_deny_link *) links->next) {
-                         if (links->flag.type == CRULE_ALL)
-                                 sendto_one(sptr, rpl_str(RPL_STATSDLINE), me.name, sptr->name,
-                                         "D", links->mask, links->prettyrule);
-                 }
-                 break;
-         }
-         case 'd':
-         {
-                 ConfigItem_deny_link *links;
-
-                 for (links = conf_deny_link; links; links = (ConfigItem_deny_link *) links->next) {
-                         if (links->flag.type == CRULE_AUTO)
-                                 sendto_one(sptr, rpl_str(RPL_STATSDLINE), me.name, sptr->name,
-                                         "d", links->mask, links->prettyrule);
-                 }
-                 break;
-         }
-         case 'r': {
-                 ConfigItem_deny_channel *dchans;
-                 ConfigItem_allow_channel *achans;
-                 for (dchans = conf_deny_channel; dchans; dchans = (ConfigItem_deny_channel *) dchans->next) {
-                       sendto_one(sptr, ":%s %i %s :deny %s %s", me.name, RPL_TEXT, sptr->name,
-                           dchans->channel, dchans->reason);
-                 }
-                 for (achans = conf_allow_channel; achans; achans = (ConfigItem_allow_channel *) achans->next) {
-                       sendto_one(sptr, ":%s %i %s :allow %s", me.name, RPL_TEXT, sptr->name,
-                           achans->channel);
-                 }
-                 break;
-         }
-         case 't':
-         {
-                 ConfigItem_tld *tld;
-                 for (tld = conf_tld; tld; tld = (ConfigItem_tld *) tld->next)
-                 {
-                         sendto_one(sptr, rpl_str(RPL_STATSTLINE), me.name,
-                             parv[0], tld->mask, tld->motd_file,
-                             tld->rules_file ? tld->rules_file : "none");
-                 }
-                 break;
-         }
-         case 'T':             /* /stats T not t:lines .. */
-                 tstats(sptr, parv[0]);
-                 break;
-         case 'U':
-         {
-                 ConfigItem_ulines *ulines;
-                 for (ulines = conf_ulines; ulines;
-                     ulines = (ConfigItem_ulines *) ulines->next)
-                 {
-                         sendto_one(sptr, rpl_str(RPL_STATSULINE), me.name,
-                             parv[0], ulines->servername);
-                 }
-                 break;
-         }
-         case 'u':
-         {
-                 time_t tmpnow;
-
-                 tmpnow = TStime() - me.since;
-                 sendto_one(sptr, rpl_str(RPL_STATSUPTIME), me.name, parv[0],
-                     tmpnow / 86400, (tmpnow / 3600) % 24, (tmpnow / 60) % 60,
-                     tmpnow % 60);
-                 sendto_one(sptr, rpl_str(RPL_STATSCONN), me.name, parv[0],
-                     max_connection_count, IRCstats.me_max);
-                 break;
-         }
-         case 'v':
-         {
-                 ConfigItem_deny_version *versions;
-
-                 for (versions = conf_deny_version; versions; versions = (ConfigItem_deny_version *) versions->next) {
-                         sendto_one(sptr, rpl_str(RPL_STATSVLINE), me.name, sptr->name,
-                                 versions->version, versions->flags, versions->mask);
-                 }
-                 break;
-         }
-         case 'V': {
-                 ConfigItem_vhost *vhosts;
-                 for(vhosts = conf_vhost; vhosts; vhosts = (ConfigItem_vhost *) vhosts->next) {
-                       for (oper_p_from = (ConfigItem_oper_from *)vhosts->from; oper_p_from; oper_p_from = (ConfigItem_oper_from *)oper_p_from->next) {
-                               sendto_one(sptr, ":%s %i %s :vhost %s%s%s %s %s", me.name, RPL_TEXT, sptr->name,
-                                    vhosts->virtuser ? vhosts->virtuser : "", vhosts->virtuser ? "@" : "",
-                                    vhosts->virthost, vhosts->login, oper_p_from->name);
-                       }
-                 }
-                 break;
-         }
-         case 'X':
-         case 'x':
-                 for (link_p = conf_link; link_p; link_p = (ConfigItem_link *) link_p->next)
-                 {
-                       if (!find_server_quick(link_p->servername))
-                       {
-                               sendto_one(sptr, rpl_str(RPL_STATSXLINE),
-                                       me.name, sptr->name, link_p->servername,
-                                       link_p->port);
-                       }
-                 }
-                 break;
-         case 'Y':
-         case 'y':
-         {
-                 ConfigItem_class *classes;
-                 for (classes = conf_class; classes; classes = (ConfigItem_class *) classes->next) {
-                         sendto_one(sptr, rpl_str(RPL_STATSYLINE),
-                               me.name, sptr->name, classes->name, classes->pingfreq, classes->connfreq,
-                               classes->maxclients, classes->sendq, classes->recvq ? classes->recvq : CLIENT_FLOOD);
-                 }
-                 break;
-         }
-         case 'Z':
-         case 'z':
-                 if (!strcasecmp(parv[1], "zip"))
-                 {
-                       /* Ugly, but I want a '/stats zip' -- Syzop */
-                       if (!IsAnOper(sptr)) {
-                               sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
-                               return 0;
-                       }
-#ifndef ZIP_LINKS
-                       sendto_one(sptr, ":%s %i %s :Sorry this server doesn't support zip links", me.name, RPL_TEXT, parv[0]);
-#else
-                       for (i=0; i <= LastSlot; i++)
-                       {
-                               if (!(acptr = local[i]))
-                                       continue;
-                               if (!IsServer(acptr) || !IsZipped(acptr))
-                                       continue;
-                               if (acptr->zip->in->total_out && acptr->zip->out->total_in)
-                               {
-                                 sendto_one(sptr,
-                                   ":%s %i %s :Zipstats for link to %s (compresslevel %d): decompressed (in): %01lu/%01lu (%3.1f%%), compressed (out): %01lu/%01lu (%3.1f%%)",
-                                   me.name, RPL_TEXT, parv[0], get_client_name(acptr, TRUE),
-                                   acptr->serv->conf->compression_level ? acptr->serv->conf->compression_level : ZIP_DEFAULT_LEVEL,
-                                   acptr->zip->in->total_in, acptr->zip->in->total_out,
-                                   (100.0*(float)acptr->zip->in->total_in) /(float)acptr->zip->in->total_out,
-                                   acptr->zip->out->total_in, acptr->zip->out->total_out,
-                                   (100.0*(float)acptr->zip->out->total_out) /(float)acptr->zip->out->total_in);
-                               } else {
-                                       sendto_one(sptr, ":%s %i %s :Zipstats for link to %s: unavailable", me.name, RPL_TEXT, parv[0]);
-                               }
-                       }
-#endif
-                       sendto_snomask(SNO_EYES, "Stats 'zip' requested by %s (%s@%s)",
-                       sptr->name, sptr->user->username, GetHost(sptr));
-                       stat = '*';
-                       break;
-                 } /* 'zip' */
-                 if (IsAnOper(sptr))
-                         count_memory(sptr, parv[0]);
-                 break;
-         default:
-                 /* Display a help menu */
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "/Stats flags:");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "b - Send the badwords list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "C - Send the link block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "d - Send the deny link (auto) block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "D - Send the deny link (all) block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "e - Send the except socks block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "E - Send the except ban block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "F - Send the deny dcc block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "G - Report TKL information (G:lines/Shuns)");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "H - Send the link block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "I - Send the allow block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "K - Send the ban user/ban ip/except ban block list (Includes AKILLs)");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "L - Send Link information");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "m - Send the events list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "M - Send list of how many times each command was used");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "n - Send the ban realname block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "N - Send network configuration list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "O - Send the oper block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "P - Send information about ports");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "q - Send the SQLINE list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "Q - Send the ban nick block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "r - Send the channel deny/allow block list");
-#ifdef DEBUGMODE
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "R - Send the usage list");
-#endif
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "s - Send the SCache and NS list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "S - Send the dynamic configuration list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "t - Send the tld block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "T - Send connection information");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "u - Send server uptime and connection count");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "U - Send the ulines block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "v - Send the deny version block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "V - Send the vhost block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "X - Send a list of servers that are not currently linked");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "Y - Send the class block list");
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "Z - Send memory usage information");
-#ifdef ZIP_LINKS
-                 sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, parv[0],
-                     "zip - Send compression information about ziplinked servers");
-#endif
-                 stat = '*';
-                 break;
-       }
-       sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, parv[0], stat);
-
-
-       if (stat != '*')
-               sendto_snomask(SNO_EYES, "Stats \'%c\' requested by %s (%s@%s)",
-                   stat, sptr->name, sptr->user->username, GetHost(sptr));
-
-       return 0;
-}
-
 /*
 ** m_summon
 ** parv[0] = sender prefix
@@ -3625,11 +2952,13 @@ CMD_FUNC(m_rehash)
                                opermotd = (aMotd *) read_file(OPATH, &opermotd);
                                botmotd = (aMotd *) read_file(BPATH, &botmotd);
                                rehash_motdrules();
+                               RunHook(HOOKTYPE_REHASHFLAG, parv[1]);
                                return 0;
                        }
                        if (!strnicmp("-gar", parv[1], 4))
                        {
                                loop.do_garbage_collect = 1;
+                               RunHook(HOOKTYPE_REHASHFLAG, parv[1]);
                                return 0;
                        }
                        if (!_match("-o*motd", parv[1]))
@@ -3641,6 +2970,7 @@ CMD_FUNC(m_rehash)
                                if (cptr != sptr)
                                        sendto_serv_butone(&me, ":%s GLOBOPS :%s is remotely rehashing OperMOTD", me.name, sptr->name);
                                opermotd = (aMotd *) read_file(OPATH, &opermotd);
+                               RunHook(HOOKTYPE_REHASHFLAG, parv[1]);
                                return 0;
                        }
                        if (!_match("-b*motd", parv[1]))
@@ -3652,6 +2982,7 @@ CMD_FUNC(m_rehash)
                                if (cptr != sptr)
                                        sendto_serv_butone(&me, ":%s GLOBOPS :%s is remotely rehashing BotMOTD", me.name, sptr->name);
                                botmotd = (aMotd *) read_file(BPATH, &botmotd);
+                               RunHook(HOOKTYPE_REHASHFLAG, parv[1]);
                                return 0;
                        }
                        if (!strnicmp("-motd", parv[1], 5)
@@ -3664,14 +2995,11 @@ CMD_FUNC(m_rehash)
                                if (cptr != sptr)
                                        sendto_serv_butone(&me, ":%s GLOBOPS :%s is remotely rehashing all MOTDs and RULES", me.name, sptr->name);
                                rehash_motdrules();
+                               RunHook(HOOKTYPE_REHASHFLAG, parv[1]);
                                return 0;
                        }
-                       /* didn't match / fall trough... should we continue?? */
-                       sendto_ops("%s is %srehashing server config file (unknown option)",
-                               sptr->name, cptr != sptr ? "Remotely " : "");
-                       if (cptr != sptr)
-                               sendto_serv_butone(&me, ":%s GLOBOPS :%s is remotely rehashing server config file (unknown option)",
-                                       me.name, sptr->name);
+                       RunHook(HOOKTYPE_REHASHFLAG, parv[1]);
+                       return 0;
                }
        }
        else
@@ -4548,3 +3876,25 @@ aClient *find_match_server(char *mask)
        }
        return acptr;
 }
+
+/*
+ * EOS (End Of Sync) command.
+ * Type: Broadcast
+ * Purpose: Broadcasted over a network if a server is synced (after the users, channels,
+ *          etc are introduced). Makes us able to know if a server is linked.
+ * History: Added in beta18 (in cvs since 2003-08-11) by Syzop
+ */
+CMD_FUNC(m_eos)
+{
+       if (!IsServer(sptr))
+               return 0;
+       sptr->serv->flags.synced = 1;
+       /* pass it on ^_- */
+#ifdef DEBUGMODE
+       ircd_log(LOG_ERROR, "[EOSDBG] m_eos: got sync from %s (path:%s)", sptr->name, cptr->name);
+       ircd_log(LOG_ERROR, "[EOSDBG] m_eos: broadcasting it back to everyone except route from %s", cptr->name);
+#endif
+       sendto_serv_butone_token(cptr,
+               parv[0], MSG_EOS, TOK_EOS, "", NULL);
+       return 0;
+}
diff --git a/src/s_stats.c b/src/s_stats.c
new file mode 100644 (file)
index 0000000..6e06e21
--- /dev/null
@@ -0,0 +1,1459 @@
+#include "struct.h"
+#include "common.h"
+#include "sys.h"
+#include "numeric.h"
+#include "msg.h"
+#include "channel.h"
+#include "version.h"
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef _WIN32
+#include <io.h>
+#endif
+#include <time.h>
+#include "h.h"
+#include "proto.h"
+#include <string.h>
+
+extern int  max_connection_count;
+extern char modebuf[MAXMODEPARAMS*2+1], parabuf[504];
+extern char *get_client_name2(aClient *, int);
+
+int stats_banversion(aClient *, char *);
+int stats_links(aClient *, char *);
+int stats_denylinkall(aClient *, char *);
+int stats_gline(aClient *, char *);
+int stats_exceptban(aClient *, char *);
+int stats_allow(aClient *, char *);
+int stats_command(aClient *, char *);
+int stats_oper(aClient *, char *);
+int stats_port(aClient *, char *);
+int stats_bannick(aClient *, char *);
+int stats_usage(aClient *, char *);
+int stats_traffic(aClient *, char *);
+int stats_uline(aClient *, char *);
+int stats_vhost(aClient *, char *);
+int stats_mem(aClient *, char *);
+int stats_badwords(aClient *, char *);
+int stats_denylinkauto(aClient *, char *);
+int stats_exceptthrottle(aClient *, char *);
+int stats_denydcc(aClient *, char *);
+int stats_kline(aClient *, char *);
+int stats_banrealname(aClient *, char *);
+int stats_sqline(aClient *, char *);
+int stats_linkinfoint(aClient *, char *, int);
+int stats_linkinfo(aClient *, char *);
+int stats_linkinfoall(aClient *, char *);
+int stats_chanrestrict(aClient *, char *);
+int stats_shun(aClient *, char *);
+int stats_set(aClient *, char *);
+int stats_tld(aClient *, char *);
+int stats_uptime(aClient *, char *);
+int stats_denyver(aClient *, char *);
+int stats_notlink(aClient *, char *);
+int stats_class(aClient *, char *);
+int stats_zip(aClient *, char *);
+int stats_officialchannels(aClient *, char *);
+
+#define SERVER_AS_PARA 0x1
+#define FLAGS_AS_PARA 0x2
+
+struct statstab {
+       char flag;
+       char *longflag;
+       int (*func)(aClient *sptr, char *para);
+       int options;
+};
+
+//TODO:
+// module help
+// update docs
+// update module docs 
+
+/* Must be listed lexicographically */
+/* Long flags must be lowercase */
+struct statstab StatsTable[] = {
+       { 'B', "banversion",    stats_banversion,       0               },
+       { 'C', "link",          stats_links,            0               },
+       { 'D', "denylinkall",   stats_denylinkall,      0               },
+       { 'E', "exceptban",     stats_exceptban,        0               },
+       { 'F', "denydcc",       stats_denydcc,          0               },
+       { 'G', "gline",         stats_gline,            FLAGS_AS_PARA   },
+       { 'H', "link",          stats_links,            0               },      
+       { 'I', "allow",         stats_allow,            0               },
+       { 'K', "kline",         stats_kline,            0               },
+       { 'L', "linkinfoall",   stats_linkinfoall,      SERVER_AS_PARA  },
+       { 'M', "command",       stats_command,          0               },
+       { 'O', "oper",          stats_oper,             0               },
+       { 'P', "port",          stats_port,             0               },
+       { 'Q', "bannick",       stats_bannick,          0               },
+       { 'R', "usage",         stats_usage,            0               },
+       { 'S', "set",           stats_set,              0               },
+       { 'T', "traffic",       stats_traffic,          0               },
+       { 'U', "uline",         stats_uline,            0               },
+       { 'V', "vhost",         stats_vhost,            0               },
+       { 'X', "notlink",       stats_notlink,          0               },      
+       { 'Y', "class",         stats_class,            0               },      
+       { 'Z', "mem",           stats_mem,              0               },
+       { 'b', "badword",       stats_badwords,         0               },
+       { 'c', "link",          stats_links,            0               },
+       { 'd', "denylinkauto",  stats_denylinkauto,     0               },
+       { 'e', "exceptthrottle",stats_exceptthrottle,   0               },
+       { 'f', "denydcc",       stats_denydcc,          0               },      
+       { 'g', "gline",         stats_gline,            FLAGS_AS_PARA   },
+       { 'h', "link",          stats_links,            0               },
+       { 'j', "officialchans", stats_officialchannels, 0 },
+       { 'k', "kline",         stats_kline,            0               },
+       { 'l', "linkinfo",      stats_linkinfo,         SERVER_AS_PARA  },
+       { 'n', "banrealname",   stats_banrealname,      0               },
+       { 'o', "oper",          stats_oper,             0               },
+       { 'q', "sqline",        stats_sqline,           0               },
+       { 'r', "chanrestrict",  stats_chanrestrict,     0               },
+       { 's', "shun",          stats_shun,             FLAGS_AS_PARA   },
+       { 't', "tld",           stats_tld,              0               },
+       { 'u', "uptime",        stats_uptime,           0               },
+       { 'v', "denyver",       stats_denyver,          0               },
+       { 'x', "notlink",       stats_notlink,          0               },      
+       { 'y', "class",         stats_class,            0               },
+       { 'z', "zip",           stats_zip,              0               },
+       { 0,    NULL,           NULL,                   0               }
+};
+
+int stats_compare(char *s1, char *s2)
+{
+       /* The long stats flags are always lowercase */
+       while (*s1 == tolower(*s2))
+       {
+               if (*s1 == 0)
+                       return 0;
+               s1++;
+               s2++;
+       }
+       return 1;
+}      
+
+inline struct statstab *stats_binary_search(char c) {
+       int start = 0;
+       int stop = sizeof(StatsTable)/sizeof(StatsTable[0])-1;
+       int mid;
+       while (start <= stop) {
+               mid = (start+stop)/2;
+               if (c < StatsTable[mid].flag) 
+                       stop = mid-1;
+               else if (StatsTable[mid].flag == c) 
+                       return &StatsTable[mid];
+               else
+                       start = mid+1;
+       }
+       return NULL;
+}
+
+inline struct statstab *stats_search(char *s) {
+       int i;
+       for (i = 0; StatsTable[i].flag; i++)
+               if (!stats_compare(StatsTable[i].longflag,s))
+                       return &StatsTable[i];
+       return NULL;
+}
+
+inline char *stats_combine_parv(char *p1, char *p2)
+{
+       static char buf[BUFSIZE+1];
+       strcpy(buf, p1);
+       strcat(buf, " ");
+       strcat(buf, p2);
+       return buf;
+}
+
+inline void stats_help(aClient *sptr)
+{
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name, "/Stats flags:");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "B - banversion - Send the ban version list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "b - badword - Send the badwords list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "C - link - Send the link block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "d - denylinkauto - Send the deny link (auto) block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "D - denylinkall - Send the deny link (all) block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "e - excepthrottle - Send the except trottle block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "E - exceptban - Send the except ban block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "F - denydcc - Send the deny dcc block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "G - gline - Send the gline list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "  Extended flags: [+/-mrs] [mask] [reason] [setby]");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "   m Return glines matching/not matching the specified mask");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "   r Return glines with a reason matching/not matching the specified reason");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "   s Return glines set by/not set by clients matching the specified name");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "I - allow - Send the allow block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "j - officialchans - Send the offical channels list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "K - kline - Send the ban user/ban ip/except ban block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "l - linkinfo - Send link information");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "L - linkinfoall - Send all link information");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "M - command - Send list of how many times each command was used");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "n - banrealname - Send the ban realname block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "O - oper - Send the oper block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "S - set - Send the set block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "s - shun - Send the shun list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "  Extended flags: [+/-mrs] [mask] [reason] [setby]");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "   m Return shuns matching/not matching the specified mask");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "   r Return shuns with a reason matching/not matching the specified reason");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "   s Return shuns set by/not set by clients matching the specified name");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "P - port - Send information about ports");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "q - sqline - Send the SQLINE list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "Q - bannick - Send the ban nick block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "r - chanrestrict - Send the channel deny/allow block list");
+#ifdef DEBUGMODE
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "R - usage - Send usage information");
+#endif
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "t - tld - Send the tld block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "T - traffic - Send traffic information");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "u - uptime - Send the server uptime and connection count");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "U - uline - Send the ulines block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "v - Send the deny version block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "V - Send the vhost block list");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "X - notlink - Send the list of servers that are not current linked");
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "Y - class - Send the class block list");
+#ifdef ZIP_LINKS
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "z - zip - Send compression information about ziplinked servers");
+#endif
+       sendto_one(sptr, rpl_str(RPL_STATSHELP), me.name, sptr->name,
+               "Z - mem - Send memory usage information");
+}
+
+inline int stats_operonly_short(char c)
+{
+       char l;
+       if (!OPER_ONLY_STATS)
+               return 0;
+       if (*OPER_ONLY_STATS == '*')
+               return 1;
+       if (strchr(OPER_ONLY_STATS, c))
+               return 1;
+       l = tolower(c);
+       /* Hack for the flags that are case insensitive */
+       if (l == 'o' || l == 'y' || l == 'k' || l == 'g' || l == 'x' || l == 'c' || 
+               l =='f' || l == 'i' || l == 'h')
+       {
+               if (islower(c) && strchr(OPER_ONLY_STATS, toupper(c)))
+                       return 1;
+               else if (isupper(c) && strchr(OPER_ONLY_STATS, tolower(c)))
+                       return 1;
+       }
+       /* Hack for c/C/H/h */
+       if (l == 'c')
+               if (strpbrk(OPER_ONLY_STATS, "hH"))
+                       return 1;
+       else if (l == 'h')
+               if (strpbrk(OPER_ONLY_STATS, "cC"))
+                       return 1;
+       return 0;
+}
+
+inline int stats_operonly_long(char *s)
+{
+       OperStat *os;
+       for (os = iConf.oper_only_stats_ext; os; os = (OperStat *)os->next)
+       {
+               if (!stricmp(os->flag, s))
+                       return 1;
+       }
+       return 0;
+}
+
+/* This is pretty slow, but it isn't used often so it isn't a big deal */
+inline char *stats_operonly_long_to_short()
+{
+       static char buffer[BUFSIZE+1];
+       int i = 0;
+       OperStat *os;
+       for (os = iConf.oper_only_stats_ext; os; os = (OperStat *)os->next)
+       {
+               struct statstab *stat = stats_search(os->flag);
+               if (!stat)
+                       continue;
+               if (!strchr(OPER_ONLY_STATS, stat->flag))
+                       buffer[i++] = stat->flag;
+       }
+       buffer[i] = 0;
+       return buffer;
+}
+
+CMD_FUNC(m_stats)
+{
+       struct statstab *stat;
+
+       if (parc == 3 && parv[2][0] != '+' && parv[2][0] != '-')
+       {
+               if (hunt_server_token(cptr, sptr, MSG_STATS, TOK_STATS, "%s :%s", 2, parc,
+                   parv) != HUNTED_ISME)
+                       return 0;
+       }
+       else if (parc == 4 && parv[2][0] != '+' && parv[2][0] != '-')
+       {
+               if (hunt_server_token(cptr, sptr, MSG_STATS, TOK_STATS, "%s %s %s", 2, parc,
+                       parv) != HUNTED_ISME)
+                               return 0;
+       }
+       if (parc < 2 || !*parv[1])
+       {
+               stats_help(sptr);
+               sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, parv[0], '*');
+               return 0;
+       }
+
+       /* Decide if we are looking for 1 char or a string */
+       if (parv[1][0] && !parv[1][1])
+       {
+               if (!IsAnOper(sptr) && stats_operonly_short(parv[1][0]))
+               {
+                       sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);  
+                       return 0;
+               }       
+               /* Old style, we can use a binary search here */
+               stat = stats_binary_search(parv[1][0]);
+       }
+       else
+       {
+               if (!IsAnOper(sptr) && stats_operonly_long(parv[1]))
+               {
+                       sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);  
+                       return 0;
+               }
+               /* New style, search the hard way */
+               stat = stats_search(parv[1]);
+       }
+       if (stat)
+       {
+               /* It was a short flag, so check oper only on long flags */
+               if (!parv[1][1])
+               {
+                       if (!IsAnOper(sptr) && stats_operonly_long(stat->longflag))
+                       {
+                               sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
+                               return 0;
+                       }
+               }
+               /* It was a long flag, so check oper only on short flags */
+               else
+               {
+                       if (!IsAnOper(sptr) && stats_operonly_short(stat->flag))
+                       {
+                               sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);  
+                               return 0;
+                       }
+               }
+               if (stat->options & FLAGS_AS_PARA)
+               {
+                       if (parc > 2 && (parv[2][0] == '+' || parv[2][0] == '-'))
+                       {
+                               if (parc > 3)
+                                       stat->func(sptr, stats_combine_parv(parv[2],parv[3]));
+                               else
+                                       stat->func(sptr, parv[2]);
+                       }
+                       else if (parc > 3)
+                               stat->func(sptr, parv[3]);
+                       else
+                               stat->func(sptr, NULL);
+               }
+               else if (stat->options & SERVER_AS_PARA)
+               {
+                       if (parc > 2)
+                               stat->func(sptr, parv[2]);
+                       else
+                               stat->func(sptr, NULL);
+               }
+               else
+                       stat->func(sptr, NULL);
+               sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, parv[0], stat->flag);
+               sendto_snomask(SNO_EYES, "Stats \'%c\' requested by %s (%s@%s)",
+                       stat->flag, sptr->name, sptr->user->username, GetHost(sptr));
+       }
+       else
+       {
+               stats_help(sptr);
+               sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, parv[0], '*');
+               return 0;
+       }
+       return 0;
+}
+
+int stats_banversion(aClient *sptr, char *para)
+{
+       ConfigItem_ban *bans;
+       for (bans = conf_ban; bans; bans = (ConfigItem_ban *)bans->next)
+       {
+               if (bans->flag.type != CONF_BAN_VERSION)
+                       continue;
+               sendto_one(sptr, rpl_str(RPL_STATSBANVER), me.name, sptr->name,
+                       bans->mask, bans->reason ? bans->reason : "No Reason");
+       }
+       return 0;
+}
+
+int stats_links(aClient *sptr, char *para)
+{
+       ConfigItem_link *link_p;
+       for (link_p = conf_link; link_p; link_p = (ConfigItem_link *) link_p->next)
+       {
+               sendto_one(sptr, ":%s 213 %s C %s@%s * %s %i %s %s%s%s%s%s",
+                       me.name, sptr->name, IsOper(sptr) ? link_p->username : "*",
+                       IsOper(sptr) ? link_p->hostname : "*", link_p->servername,
+                       link_p->port,
+                       link_p->class->name,
+                       (link_p->options & CONNECT_AUTO) ? "a" : "",
+                       (link_p->options & CONNECT_SSL) ? "S" : "",
+                       (link_p->options & CONNECT_ZIP) ? "z" : "",
+                       (link_p->options & CONNECT_NODNSCACHE) ? "d" : "",
+                       (link_p->options & CONNECT_NOHOSTCHECK) ? "h" : "");
+               if (link_p->hubmask)
+                       sendto_one(sptr, ":%s 244 %s H %s * %s",
+                               me.name, sptr->name, link_p->hubmask,
+                               link_p->servername);
+               else if (link_p->leafmask)
+                       sendto_one(sptr, ":%s 241 %s L %s * %s %d",
+                               me.name, sptr->name,
+                               link_p->leafmask, link_p->servername, link_p->leafdepth);
+       }
+       return 0;
+}
+
+int stats_denylinkall(aClient *sptr, char *para)
+{
+       ConfigItem_deny_link *links;
+
+       for (links = conf_deny_link; links; links = (ConfigItem_deny_link *) links->next) 
+       {
+               if (links->flag.type == CRULE_ALL)
+                       sendto_one(sptr, rpl_str(RPL_STATSDLINE), me.name, sptr->name,
+                       "D", links->mask, links->prettyrule);
+       }
+       return 0;
+}
+
+int stats_gline(aClient *sptr, char *para)
+{
+       tkl_stats(sptr, TKL_GLOBAL|TKL_KILL, para);
+       tkl_stats(sptr, TKL_GLOBAL|TKL_ZAP, para);
+       return 0;
+}
+
+int stats_exceptban(aClient *sptr, char *para)
+{
+       ConfigItem_except *excepts;
+       for (excepts = conf_except; excepts; excepts = (ConfigItem_except *) excepts->next)
+               if (excepts->flag.type == 1)
+                       sendto_one(sptr, rpl_str(RPL_STATSKLINE), me.name,
+                               sptr->name, "E", excepts->mask, "");
+       return 0;
+}
+
+int stats_allow(aClient *sptr, char *para)
+{
+       ConfigItem_allow *allows;
+       for (allows = conf_allow; allows; allows = (ConfigItem_allow *) allows->next) 
+               sendto_one(sptr, rpl_str(RPL_STATSILINE), me.name,
+                       sptr->name, allows->ip, allows->hostname, allows->maxperip, 
+                       allows->class->name, allows->server ? allows->server 
+                       : defserv, allows->port ? allows->port : 6667);
+       return 0;
+}
+
+int stats_command(aClient *sptr, char *para)
+{
+       int i;
+       aCommand *mptr;
+       for (i = 0; i <= 255; i++)
+               for (mptr = CommandHash[i]; mptr; mptr = mptr->next)
+                       if (mptr->count)
+#ifndef DEBUGMODE
+                       sendto_one(sptr, rpl_str(RPL_STATSCOMMANDS),
+                               me.name, sptr->name, mptr->cmd,
+                               mptr->count, mptr->bytes);
+#else
+                       sendto_one(sptr, rpl_str(RPL_STATSCOMMANDS),
+                               me.name, sptr->name, mptr->cmd,
+                               mptr->count, mptr->bytes,
+                               mptr->lticks, mptr->lticks / CLOCKS_PER_SEC,
+                               mptr->rticks, mptr->rticks / CLOCKS_PER_SEC);
+#endif
+       return 0;
+}      
+
+int stats_oper(aClient *sptr, char *para)
+{
+       ConfigItem_oper *oper_p;
+       ConfigItem_oper_from *from;
+       for (oper_p = conf_oper; oper_p; oper_p = (ConfigItem_oper *) oper_p->next)
+       {
+               if(!oper_p->from)
+                       sendto_one(sptr, rpl_str(RPL_STATSOLINE),
+                               me.name, sptr->name, 
+                               'O', "(none)", oper_p->name,
+                               oflagstr(oper_p->oflags),
+                               oper_p->class->name ? oper_p->class->name : "");
+               else
+                       for (from = (ConfigItem_oper_from *) oper_p->from; from; from = (ConfigItem_oper_from *) from->next)
+                               sendto_one(sptr, rpl_str(RPL_STATSOLINE),
+                                       me.name, sptr->name, 
+                                       'O', from->name, oper_p->name,
+                                       oflagstr(oper_p->oflags),
+                                       oper_p->class->name? oper_p->class->name : "");
+       }
+       return 0;
+}
+
+static char *stats_port_helper(aClient *listener)
+{
+static char buf[256];
+       buf[0] = '\0';
+       if (listener->umodes & LISTENER_CLIENTSONLY)
+               strcat(buf, "clientsonly ");
+       if (listener->umodes & LISTENER_SERVERSONLY)
+               strcat(buf, "serversonly ");
+       if (listener->umodes & LISTENER_JAVACLIENT)
+               strcat(buf, "java ");
+       if (listener->umodes & LISTENER_SSL)
+               strcat(buf, "SSL ");
+       return buf;
+}
+
+int stats_port(aClient *sptr, char *para)
+{
+       int i;
+       aClient *acptr;
+       for (i = 0; i <= LastSlot; i++)
+       {
+               if (!(acptr = local[i]))
+                       continue;
+               if (!IsListening(acptr))
+                       continue;
+               sendto_one(sptr, ":%s %s %s :*** Listener on %s:%i, clients %i. is %s %s",
+                       me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name,
+                       ((ConfigItem_listen *)acptr->class)->ip,
+                       ((ConfigItem_listen *)acptr->class)->port,
+                       ((ConfigItem_listen *)acptr->class)->clients,
+                       ((ConfigItem_listen *)acptr->class)->flag.temporary ? "TEMPORARY" : "PERM",
+                       stats_port_helper(acptr));
+       }
+       return 0;
+}
+
+int stats_bannick(aClient *sptr, char *para)
+{
+       ConfigItem_ban *bans;
+
+       for (bans = conf_ban; bans; bans = (ConfigItem_ban *)bans->next) 
+               if (bans->flag.type == CONF_BAN_NICK && (bans->flag.type2 != CONF_BAN_TYPE_AKILL))
+                       sendto_one(sptr, rpl_str(RPL_STATSQLINE),
+                               me.name, sptr->name,  bans->reason, bans->mask);
+       return 0;
+}
+
+int stats_usage(aClient *sptr, char *para)
+{
+#ifdef DEBUGMODE
+       send_usage(sptr, sptr->name);
+#endif
+       return 0;
+}
+
+int stats_traffic(aClient *sptr, char *para)
+{
+       aClient *acptr;
+       int  i;
+       struct stats *sp;
+       struct stats tmp;
+       time_t now = TStime();
+
+       sp = &tmp;
+       bcopy((char *)ircstp, (char *)sp, sizeof(*sp));
+       for (i = 0; i <= LastSlot; i++)
+       {
+               if (!(acptr = local[i]))
+                       continue;
+               if (IsServer(acptr))
+               {
+                       sp->is_sbs += acptr->sendB;
+                       sp->is_sbr += acptr->receiveB;
+                       sp->is_sks += acptr->sendK;
+                       sp->is_skr += acptr->receiveK;
+                       sp->is_sti += now - acptr->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;
+                       }
+               }
+               else if (IsClient(acptr))
+               {
+                       sp->is_cbs += acptr->sendB;
+                       sp->is_cbr += acptr->receiveB;
+                       sp->is_cks += acptr->sendK;
+                       sp->is_ckr += acptr->receiveK;
+                       sp->is_cti += now - acptr->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;
+                       }
+               }
+               else if (IsUnknown(acptr))
+                       sp->is_ni++;
+       }
+
+       sendto_one(sptr, ":%s %d %s :accepts %u refused %u",
+           me.name, RPL_STATSDEBUG, sptr->name, sp->is_ac, sp->is_ref);
+       sendto_one(sptr, ":%s %d %s :unknown commands %u prefixes %u",
+           me.name, RPL_STATSDEBUG, sptr->name, sp->is_unco, sp->is_unpf);
+       sendto_one(sptr, ":%s %d %s :nick collisions %u unknown closes %u",
+           me.name, RPL_STATSDEBUG, sptr->name, sp->is_kill, sp->is_ni);
+       sendto_one(sptr, ":%s %d %s :wrong direction %u empty %u",
+           me.name, RPL_STATSDEBUG, sptr->name, sp->is_wrdi, sp->is_empt);
+       sendto_one(sptr, ":%s %d %s :numerics seen %u mode fakes %u",
+           me.name, RPL_STATSDEBUG, sptr->name, sp->is_num, sp->is_fake);
+       sendto_one(sptr, ":%s %d %s :auth successes %u fails %u",
+           me.name, RPL_STATSDEBUG, sptr->name, sp->is_asuc, sp->is_abad);
+       sendto_one(sptr, ":%s %d %s :local connections %u udp packets %u",
+           me.name, RPL_STATSDEBUG, sptr->name, sp->is_loc, sp->is_udp);
+       sendto_one(sptr, ":%s %d %s :Client Server",
+           me.name, RPL_STATSDEBUG, sptr->name);
+       sendto_one(sptr, ":%s %d %s :connected %u %u",
+           me.name, RPL_STATSDEBUG, sptr->name, sp->is_cl, sp->is_sv);
+       sendto_one(sptr, ":%s %d %s :bytes sent %u.%uK %u.%uK",
+           me.name, RPL_STATSDEBUG, sptr->name,
+           sp->is_cks, sp->is_cbs, sp->is_sks, sp->is_sbs);
+       sendto_one(sptr, ":%s %d %s :bytes recv %u.%uK %u.%uK",
+           me.name, RPL_STATSDEBUG, sptr->name,
+           sp->is_ckr, sp->is_cbr, sp->is_skr, sp->is_sbr);
+       sendto_one(sptr, ":%s %d %s :time connected %u %u",
+           me.name, RPL_STATSDEBUG, sptr->name, sp->is_cti, sp->is_sti);
+#ifndef NO_FDLIST
+       sendto_one(sptr,
+           ":%s %d %s :incoming rate %0.2f kb/s - outgoing rate %0.2f kb/s",
+           me.name, RPL_STATSDEBUG, sptr->name, currentrate, currentrate2);
+#endif
+       return 0;
+}
+
+
+int stats_uline(aClient *sptr, char *para)
+{
+       ConfigItem_ulines *ulines;
+       for (ulines = conf_ulines; ulines; ulines = (ConfigItem_ulines *) ulines->next)
+               sendto_one(sptr, rpl_str(RPL_STATSULINE), me.name,
+                       sptr->name, ulines->servername);
+       return 0;       
+}
+int stats_vhost(aClient *sptr, char *para)
+{
+       ConfigItem_oper_from *from;
+       ConfigItem_vhost *vhosts;
+       for(vhosts = conf_vhost; vhosts; vhosts = (ConfigItem_vhost *) vhosts->next) 
+       {
+               for (from = (ConfigItem_oper_from *)vhosts->from; from; from = (ConfigItem_oper_from *)from->next) 
+                       sendto_one(sptr, ":%s %i %s :vhost %s%s%s %s %s", me.name, RPL_TEXT, sptr->name,
+                            vhosts->virtuser ? vhosts->virtuser : "", vhosts->virtuser ? "@" : "",
+                            vhosts->virthost, vhosts->login, from->name);
+       }
+       return 0;
+}
+
+int stats_mem(aClient *sptr, char *para)
+{
+       extern aChannel *channel;
+       extern int flinks;
+       extern Link *freelink;
+       extern MemoryInfo StatsZ;
+
+       aClient *acptr;
+       Ban *ban;
+       Link *link;
+       aChannel *chptr;
+
+       int  lc = 0,            /* local clients */
+            ch = 0,            /* channels */
+            lcc = 0,           /* local client conf links */
+            rc = 0,            /* remote clients */
+            us = 0,            /* user structs */
+            chu = 0,           /* channel users */
+            chi = 0,           /* channel invites */
+            chb = 0,           /* channel bans */
+            wwu = 0,           /* whowas users */
+            fl = 0,            /* free links */
+            cl = 0,            /* classes */
+            co = 0;            /* conf lines */
+
+       int  usi = 0,           /* users invited */
+            usc = 0,           /* users in channels */
+            aw = 0,            /* aways set */
+            wwa = 0,           /* whowas aways */
+            wlh = 0,           /* watchlist headers */
+            wle = 0;           /* watchlist entries */
+
+       u_long chm = 0,         /* memory used by channels */
+            chbm = 0,          /* memory used by channel bans */
+            lcm = 0,           /* memory used by local clients */
+            rcm = 0,           /* memory used by remote clients */
+            awm = 0,           /* memory used by aways */
+            wwam = 0,          /* whowas away memory used */
+            wwm = 0,           /* whowas array memory used */
+            com = 0,           /* memory used by conf lines */
+            wlhm = 0,          /* watchlist memory used */
+            db = 0,            /* memory used by dbufs */
+            rm = 0,            /* res memory used */
+            totcl = 0, totch = 0, totww = 0, tot = 0;
+
+       if (!IsAnOper(sptr))
+       {
+               sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, sptr->name);
+               return 0;
+       }
+
+       count_whowas_memory(&wwu, &wwam);
+       count_watch_memory(&wlh, &wlhm);
+       wwm = sizeof(aName) * NICKNAMEHISTORYLENGTH;
+
+       for (acptr = client; acptr; acptr = acptr->next)
+       {
+               if (MyConnect(acptr))
+               {
+                       lc++;
+                       /*for (link = acptr->confs; link; link = link->next)
+                               lcc++;
+                       wle += acptr->notifies;*/
+                       
+               }
+               else
+                       rc++;
+               if (acptr->user)
+               {
+                       Membership *mb;
+                       us++;
+                       for (link = acptr->user->invited; link;
+                           link = link->next)
+                               usi++;
+                       for (mb = acptr->user->channel; mb;
+                           mb = mb->next)
+                               usc++;
+                       if (acptr->user->away)
+                       {
+                               aw++;
+                               awm += (strlen(acptr->user->away) + 1);
+                       }
+               }
+       }
+       lcm = lc * CLIENT_LOCAL_SIZE;
+       rcm = rc * CLIENT_REMOTE_SIZE;
+
+       for (chptr = channel; chptr; chptr = chptr->nextch)
+       {
+               Member *member;
+               
+               ch++;
+               chm += (strlen(chptr->chname) + sizeof(aChannel));
+               for (member = chptr->members; member; member = member->next)
+                       chu++;
+               for (link = chptr->invites; link; link = link->next)
+                       chi++;
+               for (ban = chptr->banlist; ban; ban = ban->next)
+               {
+                       chb++;
+                       chbm += (strlen(ban->banstr) + 1 +
+                           strlen(ban->who) + 1 + sizeof(Ban));
+               }
+       }
+
+       sendto_one(sptr, ":%s %d %s :Client Local %d(%d) Remote %d(%d)",
+           me.name, RPL_STATSDEBUG, sptr->name, lc, lcm, rc, rcm);
+       sendto_one(sptr, ":%s %d %s :Users %d(%d) Invites %d(%d)",
+           me.name, RPL_STATSDEBUG, sptr->name, us, us * sizeof(anUser), usi,
+           usi * sizeof(Link));
+       sendto_one(sptr, ":%s %d %s :User channels %d(%d) Aways %d(%d)",
+           me.name, RPL_STATSDEBUG, sptr->name, usc, usc * sizeof(Link), aw, awm);
+       sendto_one(sptr, ":%s %d %s :WATCH headers %d(%d) entries %d(%d)",
+           me.name, RPL_STATSDEBUG, sptr->name, wlh, wlhm, wle, wle * sizeof(Link));
+       sendto_one(sptr, ":%s %d %s :Attached confs %d(%d)",
+           me.name, RPL_STATSDEBUG, sptr->name, lcc, lcc * sizeof(Link));
+
+       totcl = lcm + rcm + us * sizeof(anUser) + usc * sizeof(Link) + awm;
+       totcl += lcc * sizeof(Link) + usi * sizeof(Link) + wlhm;
+       totcl += wle * sizeof(Link);
+
+       sendto_one(sptr, ":%s %d %s :Conflines %d(%d)",
+           me.name, RPL_STATSDEBUG, sptr->name, co, com);
+
+       sendto_one(sptr, ":%s %d %s :Classes %d(%d)",
+           me.name, RPL_STATSDEBUG, sptr->name, StatsZ.classes, StatsZ.classesmem);
+
+       sendto_one(sptr, ":%s %d %s :Channels %d(%d) Bans %d(%d)",
+           me.name, RPL_STATSDEBUG, sptr->name, ch, chm, chb, chbm);
+       sendto_one(sptr, ":%s %d %s :Channel members %d(%d) invite %d(%d)",
+           me.name, RPL_STATSDEBUG, sptr->name, chu, chu * sizeof(Link),
+           chi, chi * sizeof(Link));
+
+       totch = chm + chbm + chu * sizeof(Link) + chi * sizeof(Link);
+
+       sendto_one(sptr, ":%s %d %s :Whowas users %d(%d) away %d(%d)",
+           me.name, RPL_STATSDEBUG, sptr->name, wwu, wwu * sizeof(anUser),
+           wwa, wwam);
+       sendto_one(sptr, ":%s %d %s :Whowas array %d(%d)",
+           me.name, RPL_STATSDEBUG, sptr->name, NICKNAMEHISTORYLENGTH, wwm);
+
+       totww = wwu * sizeof(anUser) + wwam + wwm;
+
+       sendto_one(sptr,
+           ":%s %d %s :Hash: client %d(%d) chan %d(%d) watch %d(%d)", me.name,
+           RPL_STATSDEBUG, sptr->name, U_MAX, sizeof(aHashEntry) * U_MAX, CH_MAX,
+           sizeof(aHashEntry) * CH_MAX, WATCHHASHSIZE,
+           sizeof(aWatch *) * WATCHHASHSIZE);
+       db = dbufblocks * sizeof(dbufbuf);
+       sendto_one(sptr, ":%s %d %s :Dbuf blocks %d(%d)",
+           me.name, RPL_STATSDEBUG, sptr->name, dbufblocks, db);
+
+       link = freelink;
+       while ((link = link->next))
+               fl++;
+       fl++;
+       sendto_one(sptr, ":%s %d %s :Link blocks free %d(%d) total %d(%d)",
+           me.name, RPL_STATSDEBUG, sptr->name, fl, fl * sizeof(Link),
+           flinks, flinks * sizeof(Link));
+
+       rm = cres_mem(sptr,sptr->name);
+
+       tot = totww + totch + totcl + com + cl * sizeof(aClass) + db + rm;
+       tot += fl * sizeof(Link);
+       tot += sizeof(aHashEntry) * U_MAX;
+       tot += sizeof(aHashEntry) * CH_MAX;
+       tot += sizeof(aWatch *) * WATCHHASHSIZE;
+
+       sendto_one(sptr, ":%s %d %s :Total: ww %d ch %d cl %d co %d db %d",
+           me.name, RPL_STATSDEBUG, sptr->name, totww, totch, totcl, com, db);
+#if !defined(_WIN32) && !defined(_AMIGA)
+#ifdef __alpha
+       sendto_one(sptr, ":%s %d %s :TOTAL: %d sbrk(0)-etext: %u",
+           me.name, RPL_STATSDEBUG, nick, tot,
+           (u_int)sbrk((size_t)0) - (u_int)sbrk0);
+#else
+       sendto_one(sptr, ":%s %d %s :TOTAL: %d sbrk(0)-etext: %ul",
+           me.name, RPL_STATSDEBUG, sptr->name, tot,
+           (u_long)sbrk((size_t)0) - (u_long)sbrk0);
+
+#endif
+#else
+       sendto_one(sptr, ":%s %d %s :TOTAL: %d",
+           me.name, RPL_STATSDEBUG, sptr->name, tot);
+#endif
+       return 0;
+}
+
+int stats_badwords(aClient *sptr, char *para)
+{
+#ifdef STRIPBADWORDS
+         ConfigItem_badword *words;
+
+         for (words = conf_badword_channel; words; words = (ConfigItem_badword *) words->next) {
+ #ifdef FAST_BADWORD_REPLACE
+                 sendto_one(sptr, ":%s %i %s :c %c %s%s%s %s",
+                     me.name, RPL_TEXT, sptr->name, words->type & BADW_TYPE_REGEX ? 'R' : 'F',
+                     (words->type & BADW_TYPE_FAST_L) ? "*" : "", words->word,
+                     (words->type & BADW_TYPE_FAST_R) ? "*" : "",
+                     words->action == BADWORD_REPLACE ? 
+                     (words->replace ? words->replace : "<censored>") : "");
+ #else
+                 sendto_one(sptr, ":%s %i %s :c %s %s", me.name, RPL_TEXT,
+                       sptr->name,  words->word, words->action == BADWORD_REPLACE ? 
+                       (words->replace ? words->replace : "<censored>") : "");
+ #endif
+         }
+         for (words = conf_badword_message; words; words = (ConfigItem_badword *) words->next) {
+ #ifdef FAST_BADWORD_REPLACE
+                 sendto_one(sptr, ":%s %i %s :m %c %s%s%s %s",
+                     me.name, RPL_TEXT, sptr->name, words->type & BADW_TYPE_REGEX ? 'R' : 'F',
+                     (words->type & BADW_TYPE_FAST_L) ? "*" : "", words->word,
+                     (words->type & BADW_TYPE_FAST_R) ? "*" : "",
+                     words->action == BADWORD_REPLACE ? 
+                     (words->replace ? words->replace : "<censored>") : "");
+ #else
+                 sendto_one(sptr, ":%s %i %s :m %s %s", me.name, RPL_TEXT, sptr->name,
+                       words->word, words->action == BADWORD_REPLACE ? 
+                       (words->replace ? words->replace : "<censored>") : "");
+
+ #endif
+         }
+         for (words = conf_badword_quit; words; words = (ConfigItem_badword *) words->next) {
+ #ifdef FAST_BADWORD_REPLACE
+                 sendto_one(sptr, ":%s %i %s :q %c %s%s%s %s",
+                     me.name, RPL_TEXT, sptr->name, words->type & BADW_TYPE_REGEX ? 'R' : 'F',
+                     (words->type & BADW_TYPE_FAST_L) ? "*" : "", words->word,
+                     (words->type & BADW_TYPE_FAST_R) ? "*" : "",
+                     words->action == BADWORD_REPLACE ? 
+                     (words->replace ? words->replace : "<censored>") : "");
+ #else
+                 sendto_one(sptr, ":%s %i %s :q %s %s", me.name, RPL_TEXT, sptr->name,
+                       words->word, words->action == BADWORD_REPLACE ? 
+                       (words->replace ? words->replace : "<censored>") : "");
+
+ #endif
+         }
+#endif
+       return 0;
+}
+
+int stats_denylinkauto(aClient *sptr, char *para)
+{
+       ConfigItem_deny_link *links;
+
+       for (links = conf_deny_link; links; links = (ConfigItem_deny_link *) links->next) 
+       {
+               if (links->flag.type == CRULE_AUTO)
+                       sendto_one(sptr, rpl_str(RPL_STATSDLINE), me.name, sptr->name,
+                       "d", links->mask, links->prettyrule);
+       }
+       return 0;
+}
+
+int stats_exceptthrottle(aClient *sptr, char *para)
+{
+       ConfigItem_except *excepts;
+       for (excepts = conf_except; excepts; excepts = (ConfigItem_except *) excepts->next)
+               if (excepts->flag.type == CONF_EXCEPT_THROTTLE)
+                       sendto_one(sptr, rpl_str(RPL_STATSELINE),
+                               me.name, sptr->name, excepts->mask);
+       return 0;
+}
+
+int stats_denydcc(aClient *sptr, char *para)
+{
+       ConfigItem_deny_dcc *tmp;
+       char *filemask, *reason;
+       char a = 0;
+
+       for (tmp = conf_deny_dcc; tmp; tmp = (ConfigItem_deny_dcc *) tmp->next)
+       {
+               filemask = BadPtr(tmp->filename) ? "<NULL>" : tmp->filename;
+               reason = BadPtr(tmp->reason) ? "<NULL>" : tmp->reason;
+               if (tmp->flag.type2 == CONF_BAN_TYPE_CONF)
+                       a = 'c';
+               if (tmp->flag.type2 == CONF_BAN_TYPE_AKILL)
+                       a = 's';
+               if (tmp->flag.type2 == CONF_BAN_TYPE_TEMPORARY)
+                       a = 'o';
+               sendto_one(sptr, ":%s %i %s :%c %s %s", me.name, RPL_TEXT,
+                   sptr->name, a, filemask, reason);
+       }
+       return 0;
+}
+
+int stats_kline(aClient *sptr, char *para)
+{
+       ConfigItem_ban *bans;
+       ConfigItem_except *excepts;
+       char type[2];
+       for (bans = conf_ban; bans; bans = (ConfigItem_ban *)bans->next) {
+               if (bans->flag.type == CONF_BAN_USER) {
+                       if (bans->flag.type2 == CONF_BAN_TYPE_CONF)
+                               type[0] = 'K';
+                       type[1] = '\0';
+                       sendto_one(sptr, rpl_str(RPL_STATSKLINE),
+                               me.name, sptr->name, type, bans->mask, bans->reason
+                               ? bans->reason : "<no reason>");
+               }
+               else if (bans->flag.type == CONF_BAN_IP) {
+                       if (bans->flag.type2 == CONF_BAN_TYPE_CONF)
+                               type[0] = 'Z';
+                       else if (bans->flag.type2 == CONF_BAN_TYPE_TEMPORARY)
+                               type[0] = 'z';
+                       type[1] = '\0';
+                       sendto_one(sptr, rpl_str(RPL_STATSKLINE),
+                               me.name, sptr->name, type, bans->mask, bans->reason 
+                               ? bans->reason : "<no reason>");
+               }
+       }
+       tkl_stats(sptr, TKL_KILL, NULL);
+       tkl_stats(sptr, TKL_ZAP, NULL);
+       for (excepts = conf_except; excepts; excepts = (ConfigItem_except *)excepts->next) {
+               if (excepts->flag.type == 1)
+                       sendto_one(sptr, rpl_str(RPL_STATSKLINE),
+                               me.name, sptr->name, "E", excepts->mask, "");
+       }
+       return 0;
+}
+
+int stats_banrealname(aClient *sptr, char *para)
+{
+       ConfigItem_ban *bans;
+       for (bans = conf_ban; bans; bans = (ConfigItem_ban *)bans->next) 
+               if (bans->flag.type == CONF_BAN_REALNAME)
+                       sendto_one(sptr, rpl_str(RPL_STATSNLINE),
+                               me.name, sptr->name, bans->mask, bans->reason
+                               ? bans->reason : "<no reason>");
+       return 0;
+}
+
+int stats_sqline(aClient *sptr, char *para)
+{
+       ConfigItem_ban *bans;
+
+       for (bans = conf_ban; bans; bans = (ConfigItem_ban *)bans->next) 
+               if (bans->flag.type == CONF_BAN_NICK && (bans->flag.type2 == CONF_BAN_TYPE_AKILL))
+                       sendto_one(sptr, rpl_str(RPL_SQLINE_NICK),
+                               me.name, sptr->name, bans->mask, bans->reason ? bans->reason
+                               : "No Reason");
+       return 0;
+}
+
+int stats_chanrestrict(aClient *sptr, char *para)
+{
+       ConfigItem_deny_channel *dchans;
+       ConfigItem_allow_channel *achans;
+       for (dchans = conf_deny_channel; dchans; dchans = (ConfigItem_deny_channel *) dchans->next) 
+               sendto_one(sptr, ":%s %i %s :deny %s %c %s", me.name, RPL_TEXT, sptr->name,
+                       dchans->channel, dchans->warn ? 'w' : '-', dchans->reason);
+       for (achans = conf_allow_channel; achans; achans = (ConfigItem_allow_channel *) achans->next) 
+               sendto_one(sptr, ":%s %i %s :allow %s", me.name, RPL_TEXT, sptr->name,
+                       achans->channel);
+       return 0;
+}
+
+int stats_shun(aClient *sptr, char *para)
+{
+       tkl_stats(sptr, TKL_GLOBAL|TKL_SHUN, para);
+       return 0;
+}
+
+/* should this be moved to a seperate stats flag? */
+int stats_officialchannels(aClient *sptr, char *para)
+{
+ConfigItem_offchans *x;
+       for (x = conf_offchans; x; x = (ConfigItem_offchans *)x->next)
+               sendto_one(sptr, ":%s %i %s :%s %s",
+                       me.name, RPL_TEXT, sptr->name, x->chname, x->topic ? x->topic : "");
+       return 0;
+}
+
+int stats_set(aClient *sptr, char *para)
+{
+       char *uhallow;
+
+       if (!IsAnOper(sptr))
+       {
+               sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, sptr->name);
+               return 0;
+       }
+
+       sendto_one(sptr, ":%s %i %s :*** Configuration Report ***",
+           me.name, RPL_TEXT, sptr->name);
+       sendto_one(sptr, ":%s %i %s :network-name: %s", me.name, RPL_TEXT,
+           sptr->name, ircnetwork);
+       sendto_one(sptr, ":%s %i %s :default-server: %s", me.name, RPL_TEXT,
+           sptr->name, defserv);
+       sendto_one(sptr, ":%s %i %s :services-server: %s", me.name, RPL_TEXT,
+           sptr->name, SERVICES_NAME);
+       sendto_one(sptr, ":%s %i %s :stats-server: %s", me.name, RPL_TEXT,
+           sptr->name, STATS_SERVER);
+       sendto_one(sptr, ":%s %i %s :hiddenhost-prefix: %s", me.name, RPL_TEXT,
+           sptr->name, hidden_host);
+       sendto_one(sptr, ":%s %i %s :help-channel: %s", me.name, RPL_TEXT,
+           sptr->name, helpchan);
+       sendto_one(sptr, ":%s %i %s :cloak-keys: %X", me.name, RPL_TEXT, sptr->name,
+               CLOAK_KEYCRC);
+       sendto_one(sptr, ":%s %i %s :kline-address: %s", me.name, RPL_TEXT,
+           sptr->name, KLINE_ADDRESS);
+       sendto_one(sptr, ":%s %i %s :modes-on-connect: %s", me.name, RPL_TEXT,
+           sptr->name, get_modestr(CONN_MODES));
+       sendto_one(sptr, ":%s %i %s :modes-on-oper: %s", me.name, RPL_TEXT,
+           sptr->name, get_modestr(OPER_MODES));
+       *modebuf = *parabuf = 0;
+       chmode_str(iConf.modes_on_join, modebuf, parabuf);
+       sendto_one(sptr, ":%s %i %s :modes-on-join: %s %s", me.name, RPL_TEXT,
+               sptr->name, modebuf, parabuf);
+       sendto_one(sptr, ":%s %i %s :snomask-on-oper: %s", me.name, RPL_TEXT,
+           sptr->name, OPER_SNOMASK);
+       sendto_one(sptr, ":%s %i %s :snomask-on-connect: %s", me.name, RPL_TEXT,
+           sptr->name, CONNECT_SNOMASK ? CONNECT_SNOMASK : "+");
+       if (OPER_ONLY_STATS)
+       {
+               char *longflags = stats_operonly_long_to_short();
+               sendto_one(sptr, ":%s %i %s :oper-only-stats: %s%s", me.name, RPL_TEXT,
+                       sptr->name, OPER_ONLY_STATS, longflags ? longflags : "");
+       }
+       if (RESTRICT_USERMODES)
+               sendto_one(sptr, ":%s %i %s :restrict-usermodes: %s", me.name, RPL_TEXT,
+                       sptr->name, RESTRICT_USERMODES);
+       if (RESTRICT_CHANNELMODES)
+               sendto_one(sptr, ":%s %i %s :restrict-channelmodes: %s", me.name, RPL_TEXT,
+                       sptr->name, RESTRICT_CHANNELMODES);
+       switch (UHOST_ALLOWED)
+       {
+               case UHALLOW_ALWAYS:
+                       uhallow = "always";
+                       break;
+               case UHALLOW_NEVER:
+                       uhallow = "never";
+                       break;
+               case UHALLOW_NOCHANS:
+                       uhallow = "not-on-channels";
+                       break;
+               case UHALLOW_REJOIN:
+                       uhallow = "force-rejoin";
+                       break;
+       }
+       sendto_one(sptr, ":%s %i %s :anti-spam-quit-message-time: %s", me.name, RPL_TEXT, 
+               sptr->name, pretty_time_val(ANTI_SPAM_QUIT_MSG_TIME));
+       sendto_one(sptr, ":%s %i %s :channel-command-prefix: %s", me.name, RPL_TEXT, sptr->name, CHANCMDPFX ? CHANCMDPFX : "`");
+#ifdef USE_SSL
+       sendto_one(sptr, ":%s %i %s :ssl::egd: %s", me.name, RPL_TEXT,
+               sptr->name, EGD_PATH ? EGD_PATH : (USE_EGD ? "1" : "0"));
+       sendto_one(sptr, ":%s %i %s :ssl::certificate: %s", me.name, RPL_TEXT,
+               sptr->name, SSL_SERVER_CERT_PEM);
+       sendto_one(sptr, ":%s %i %s :ssl::key: %s", me.name, RPL_TEXT,
+               sptr->name, SSL_SERVER_KEY_PEM);
+       sendto_one(sptr, ":%s %i %s :ssl::trusted-ca-file: %s", me.name, RPL_TEXT, sptr->name,
+        iConf.trusted_ca_file ? iConf.trusted_ca_file : "<none>");
+       sendto_one(sptr, ":%s %i %s :ssl::options: %s %s %s", me.name, RPL_TEXT, sptr->name,
+               iConf.ssl_options & SSLFLAG_FAILIFNOCERT ? "FAILIFNOCERT" : "",
+               iConf.ssl_options & SSLFLAG_VERIFYCERT ? "VERIFYCERT" : "",
+               iConf.ssl_options & SSLFLAG_DONOTACCEPTSELFSIGNED ? "DONOTACCEPTSELFSIGNED" : "");
+#endif
+
+       sendto_one(sptr, ":%s %i %s :options::show-opermotd: %d", me.name, RPL_TEXT,
+           sptr->name, SHOWOPERMOTD);
+       sendto_one(sptr, ":%s %i %s :options::hide-ulines: %d", me.name, RPL_TEXT,
+           sptr->name, HIDE_ULINES);
+       sendto_one(sptr, ":%s %i %s :options::webtv-support: %d", me.name, RPL_TEXT,
+           sptr->name, WEBTV_SUPPORT);
+       sendto_one(sptr, ":%s %i %s :options::identd-check: %d", me.name, RPL_TEXT,
+           sptr->name, IDENT_CHECK);
+       sendto_one(sptr, ":%s %i %s :options::fail-oper-warn: %d", me.name, RPL_TEXT,
+           sptr->name, FAILOPER_WARN);
+       sendto_one(sptr, ":%s %i %s :options::show-connect-info: %d", me.name, RPL_TEXT,
+           sptr->name, SHOWCONNECTINFO);
+       sendto_one(sptr, ":%s %i %s :options::dont-resolve: %d", me.name, RPL_TEXT,
+           sptr->name, DONT_RESOLVE);
+       sendto_one(sptr, ":%s %i %s :options::mkpasswd-for-everyone: %d", me.name, RPL_TEXT,
+           sptr->name, MKPASSWD_FOR_EVERYONE);
+       sendto_one(sptr, ":%s %i %s :maxchannelsperuser: %i", me.name, RPL_TEXT,
+           sptr->name, MAXCHANNELSPERUSER);
+       sendto_one(sptr, ":%s %i %s :auto-join: %s", me.name, RPL_TEXT,
+           sptr->name, AUTO_JOIN_CHANS ? AUTO_JOIN_CHANS : "0");
+       sendto_one(sptr, ":%s %i %s :oper-auto-join: %s", me.name,
+           RPL_TEXT, sptr->name, OPER_AUTO_JOIN_CHANS ? OPER_AUTO_JOIN_CHANS : "0");
+       sendto_one(sptr, ":%s %i %s :static-quit: %s", me.name, 
+               RPL_TEXT, sptr->name, STATIC_QUIT ? STATIC_QUIT : "<none>");    
+       sendto_one(sptr, ":%s %i %s :dns::timeout: %s", me.name, RPL_TEXT,
+           sptr->name, pretty_time_val(HOST_TIMEOUT));
+       sendto_one(sptr, ":%s %i %s :dns::retries: %d", me.name, RPL_TEXT,
+           sptr->name, HOST_RETRIES);
+       sendto_one(sptr, ":%s %i %s :dns::nameserver: %s", me.name, RPL_TEXT,
+           sptr->name, NAME_SERVER);
+#ifdef THROTTLING
+       sendto_one(sptr, ":%s %i %s :throttle::period: %s", me.name, RPL_TEXT,
+                       sptr->name, THROTTLING_PERIOD ? pretty_time_val(THROTTLING_PERIOD) : "disabled");
+       sendto_one(sptr, ":%s %i %s :throttle::connections: %d", me.name, RPL_TEXT,
+                       sptr->name, THROTTLING_COUNT ? THROTTLING_COUNT : -1);
+#endif
+       sendto_one(sptr, ":%s %i %s :anti-flood::unknown-flood-bantime: %s", me.name, RPL_TEXT,
+                       sptr->name, pretty_time_val(UNKNOWN_FLOOD_BANTIME));
+       sendto_one(sptr, ":%s %i %s :anti-flood::unknown-flood-amount: %dKB", me.name, RPL_TEXT,
+                       sptr->name, UNKNOWN_FLOOD_AMOUNT);
+#ifdef NO_FLOOD_AWAY
+       if (AWAY_PERIOD)
+       {
+               sendto_one(sptr, ":%s %i %s :anti-flood::away-flood: %d per %s", me.name, RPL_TEXT, 
+                       sptr->name, AWAY_COUNT, pretty_time_val(AWAY_PERIOD));
+       }
+#endif
+       sendto_one(sptr, ":%s %i %s :anti-flood::nick-flood: %d per %s", me.name, RPL_TEXT, 
+               sptr->name, NICK_COUNT, pretty_time_val(NICK_PERIOD));
+       sendto_one(sptr, ":%s %i %s :ident::connect-timeout: %s", me.name, RPL_TEXT,
+                       sptr->name, pretty_time_val(IDENT_CONNECT_TIMEOUT));
+       sendto_one(sptr, ":%s %i %s :ident::read-timeout: %s", me.name, RPL_TEXT,
+                       sptr->name, pretty_time_val(IDENT_READ_TIMEOUT));
+       sendto_one(sptr, ":%s %i %s :hosts::global: %s", me.name, RPL_TEXT,
+           sptr->name, oper_host);
+       sendto_one(sptr, ":%s %i %s :hosts::admin: %s", me.name, RPL_TEXT,
+           sptr->name, admin_host);
+       sendto_one(sptr, ":%s %i %s :hosts::local: %s", me.name, RPL_TEXT,
+           sptr->name, locop_host);
+       sendto_one(sptr, ":%s %i %s :hosts::servicesadmin: %s", me.name, RPL_TEXT,
+           sptr->name, sadmin_host);
+       sendto_one(sptr, ":%s %i %s :hosts::netadmin: %s", me.name, RPL_TEXT,
+           sptr->name, netadmin_host);
+       sendto_one(sptr, ":%s %i %s :hosts::coadmin: %s", me.name, RPL_TEXT,
+           sptr->name, coadmin_host);
+       sendto_one(sptr, ":%s %i %s :hosts::host-on-oper-up: %i", me.name, RPL_TEXT, sptr->name,
+           iNAH);
+       RunHook2(HOOKTYPE_STATS, sptr, "S");
+       return 1;
+}
+
+int stats_tld(aClient *sptr, char *para)
+{
+       ConfigItem_tld *tld;
+       for (tld = conf_tld; tld; tld = (ConfigItem_tld *) tld->next)
+               sendto_one(sptr, rpl_str(RPL_STATSTLINE), me.name, sptr->name, 
+                       tld->mask, tld->motd_file, tld->rules_file ? 
+                       tld->rules_file : "none");
+       return 0;
+}
+
+int stats_uptime(aClient *sptr, char *para)
+{
+       time_t tmpnow;
+
+       tmpnow = TStime() - me.since;
+       sendto_one(sptr, rpl_str(RPL_STATSUPTIME), me.name, sptr->name,
+           tmpnow / 86400, (tmpnow / 3600) % 24, (tmpnow / 60) % 60,
+           tmpnow % 60);
+       sendto_one(sptr, rpl_str(RPL_STATSCONN), me.name, sptr->name,
+           max_connection_count, IRCstats.me_max);
+       return 0;
+}
+
+int stats_denyver(aClient *sptr, char *para)
+{
+       ConfigItem_deny_version *versions;
+       for (versions = conf_deny_version; versions; versions = (ConfigItem_deny_version *) versions->next) 
+               sendto_one(sptr, rpl_str(RPL_STATSVLINE), me.name, sptr->name,
+                       versions->version, versions->flags, versions->mask);
+       return 0;
+}
+
+int stats_notlink(aClient *sptr, char *para)
+{
+       ConfigItem_link *link_p;
+
+       for (link_p = conf_link; link_p; link_p = (ConfigItem_link *) link_p->next)
+       {
+               if (!find_server_quick(link_p->servername))
+                       sendto_one(sptr, rpl_str(RPL_STATSXLINE),
+                               me.name, sptr->name, link_p->servername,
+                               link_p->port);
+       }
+       return 0;
+}
+
+int stats_class(aClient *sptr, char *para)
+{
+       ConfigItem_class *classes;
+       for (classes = conf_class; classes; classes = (ConfigItem_class *) classes->next) 
+       {
+               sendto_one(sptr, rpl_str(RPL_STATSYLINE),
+                       me.name, sptr->name, classes->name, classes->pingfreq, classes->connfreq,
+                       classes->maxclients, classes->sendq, classes->recvq ? classes->recvq : CLIENT_FLOOD);
+       }
+       return 0;
+}
+
+int stats_zip(aClient *sptr, char *para)
+{
+#ifdef ZIP_LINKS
+       int i;
+       aClient *acptr;
+       for (i=0; i <= LastSlot; i++)
+       {
+               if (!(acptr = local[i]))
+                       continue;
+               if (!IsServer(acptr) || !IsZipped(acptr))
+                       continue;
+               if (acptr->zip->in->total_out && acptr->zip->out->total_in)
+               {
+                       sendto_one(sptr,
+                               ":%s %i %s :Zipstats for link to %s (compresslevel %d): decompressed (in): %01lu/%01lu (%3.1f%%), compressed (out): %01lu/%01lu (%3.1f%%)",
+                               me.name, RPL_TEXT, sptr->name, get_client_name(acptr, TRUE),
+                               acptr->serv->conf->compression_level ? 
+                               acptr->serv->conf->compression_level : ZIP_DEFAULT_LEVEL,
+                               acptr->zip->in->total_in, acptr->zip->in->total_out,
+                               (100.0*(float)acptr->zip->in->total_in) /(float)acptr->zip->in->total_out,
+                               acptr->zip->out->total_in, acptr->zip->out->total_out,
+                               (100.0*(float)acptr->zip->out->total_out) /(float)acptr->zip->out->total_in);
+               } 
+               else 
+                       sendto_one(sptr, ":%s %i %s :Zipstats for link to %s: unavailable", 
+                               me.name, RPL_TEXT, sptr->name);
+       }
+#endif
+       return 0;
+}
+
+int stats_linkinfo(aClient *sptr, char *para)
+{
+       return stats_linkinfoint(sptr, para, 0);
+}
+
+int stats_linkinfoall(aClient *sptr, char *para)
+{
+       return stats_linkinfoint(sptr, para, 1);
+}
+
+int stats_linkinfoint(aClient *sptr, char *para, int all)
+{
+#ifndef DEBUGMODE
+       static char Sformat[] =
+           ":%s %d %s SendQ SendM SendBytes RcveM RcveBytes Open_since :Idle";
+       static char Lformat[] = ":%s %d %s %s%s %u %u %u %u %u %u :%u";
+#else
+       static char Sformat[] =
+           ":%s %d %s SendQ SendM SendBytes RcveM RcveBytes Open_since CPU :Idle";
+       static char Lformat[] = ":%s %d %s %s%s %u %u %u %u %u %u %s";
+       char pbuf[96];          /* Should be enough for to ints */
+#endif
+       int remote = 0;
+       int wilds = 0;
+       int doall = 0;
+       int showports = IsAnOper(sptr);
+       int i;
+       aClient *acptr;
+       /*
+        * send info about connections which match, or all if the
+        * mask matches me.name.  Only restrictions are on those who
+        * are invisible not being visible to 'foreigners' who use
+        * a wild card based search to list it.
+        */
+       if (para)
+       {
+               if (!mycmp(para, me.name))
+                       doall = 2;
+               else if (match(para, me.name) == 0)
+                       doall = 1;
+               if (index(para, '*') || index(para, '?'))
+                       wilds = 1;
+       }
+       else
+               para = me.name;
+       sendto_one(sptr, Sformat, me.name, RPL_STATSLINKINFO, sptr->name);
+       if (!MyClient(sptr))
+       {
+               remote = 1;
+               wilds = 0;
+       }
+       for (i = 0; i <= LastSlot; i++)
+       {
+               if (!(acptr = local[i]))
+                       continue;
+               if (IsInvisible(acptr) && (doall || wilds) &&
+                       !(MyConnect(sptr) && IsOper(sptr)) &&
+                       !IsAnOper(acptr) && (acptr != sptr))
+                       continue;
+               if (remote && doall && !IsServer(acptr) && !IsMe(acptr))
+                       continue;
+               if (remote && !doall && IsServer(acptr))
+                       continue;
+               if (!doall && wilds && match(para, acptr->name))
+                       continue;
+               if (!(para && (IsServer(acptr)
+                       || (acptr->flags & FLAGS_LISTEN))) && !(doall
+                       || wilds) && mycmp(para, acptr->name))
+                       continue;
+
+#ifdef DEBUGMODE
+               ircsprintf(pbuf, "%d :%d", acptr->cputime,
+                     (acptr->user && MyConnect(acptr)) ?
+                     TStime() - acptr->last : 0);
+#endif
+               if (IsOper(sptr))
+               {
+                       sendto_one(sptr, Lformat, me.name,
+                               RPL_STATSLINKINFO, sptr->name, 
+                               all ?
+                               (get_client_name2(acptr, showports)) :
+                               (get_client_name(acptr, FALSE)),
+                               get_cptr_status(acptr),
+                               (int)DBufLength(&acptr->sendQ),
+                               (int)acptr->sendM, (int)acptr->sendK,
+                               (int)acptr->receiveM,
+                               (int)acptr->receiveK,
+                               TStime() - acptr->firsttime,
+#ifndef DEBUGMODE
+                               (acptr->user && MyConnect(acptr)) ?
+                               TStime() - acptr->last : 0);
+#else
+                               pbuf);
+#endif
+                       if (!IsServer(acptr) && !IsMe(acptr) && IsAnOper(acptr) && sptr != acptr)
+                               sendto_one(acptr,
+                                       ":%s %s %s :*** %s did a /stats L on you! IP may have been shown",
+                                       me.name, IsWebTV(acptr) ? "PRIVMSG" : "NOTICE", 
+                                       acptr->name, sptr->name);
+               }
+               else if (!strchr(acptr->name, '.'))
+                       sendto_one(sptr, Lformat, me.name,
+                               RPL_STATSLINKINFO, sptr->name,
+                               IsHidden(acptr) ? acptr->name :
+                               all ?   /* Potvin - PreZ */
+                               get_client_name2(acptr, showports) :
+                               get_client_name(acptr, FALSE),
+                               get_cptr_status(acptr),
+                               (int)DBufLength(&acptr->sendQ),
+                               (int)acptr->sendM, (int)acptr->sendK,
+                               (int)acptr->receiveM,
+                               (int)acptr->receiveK,
+                               TStime() - acptr->firsttime,
+#ifndef DEBUGMODE
+                               (acptr->user && MyConnect(acptr)) ?
+                               TStime() - acptr->last : 0);
+#else
+                               pbuf);
+#endif
+       }
+#ifdef DEBUGMODE
+       for (acptr = client; acptr; acptr = acptr->next)
+       {
+               if (IsServer(acptr))
+                       sendto_one(sptr, ":%s NOTICE %s :Server %s is %s",
+                               me.name, sptr->name, acptr->name, acptr->serv->flags.synced ? "SYNCED" : "NOT SYNCED!!");
+       }
+#endif
+       return 0;
+}
index f0a65ba6a635b3bbdb266eddc7284b474b678d13..fb508bdb315a0eec8945a765ffc3efb9420b905a 100644 (file)
@@ -278,7 +278,6 @@ int m_alias(aClient *cptr, aClient *sptr, int parc, char *parv[], char *cmd) {
                                char output[501];
                                char nums[4];
                                char *current = MyMalloc(strlen(parv[1])+1);
-                               char *xparv[3];
                                bzero(current, strlen(parv[1])+1);
                                bzero(output, sizeof output);
                                while(format->parameters[i] && j < 500) {
@@ -317,10 +316,39 @@ int m_alias(aClient *cptr, aClient *sptr, int parc, char *parv[], char *cmd) {
                                        output[j++] = format->parameters[i++];
                                }
                                output[j] = 0;
-                               xparv[0] = parv[0];
-                               xparv[1] = output;
-                               xparv[2] = NULL;
-                               m_alias(cptr, sptr, 2, xparv, format->nick);
+                               if (format->type == ALIAS_SERVICES) {
+                                       if (SERVICES_NAME && (acptr = find_person(format->nick, NULL)))
+                                               sendto_one(acptr, ":%s %s %s@%s :%s", parv[0],
+                                               IsToken(acptr->from) ? TOK_PRIVATE : MSG_PRIVATE, 
+                                               format->nick, SERVICES_NAME, output);
+                                       else
+                                               sendto_one(sptr, err_str(ERR_SERVICESDOWN), me.name,
+                                                       parv[0], format->nick);
+                               }
+                               else if (format->type == ALIAS_STATS) {
+                                       if (STATS_SERVER && (acptr = find_person(format->nick, NULL)))
+                                               sendto_one(acptr, ":%s %s %s@%s :%s", parv[0],
+                                                       IsToken(acptr->from) ? TOK_PRIVATE : MSG_PRIVATE, 
+                                                       format->nick, STATS_SERVER, output);
+                                       else
+                                       sendto_one(sptr, err_str(ERR_SERVICESDOWN), me.name,
+                                               parv[0], format->nick);
+                               }
+                               else if (format->type == ALIAS_NORMAL) {
+                                       if ((acptr = find_person(format->nick, NULL))) {
+                                               if (MyClient(acptr))
+                                                       sendto_one(acptr, ":%s!%s@%s PRIVMSG %s :%s", parv[0], 
+                                                       sptr->user->username, IsHidden(sptr) ? sptr->user->virthost : sptr->user->realhost,
+                                                       format->nick, output);
+                                               else
+                                                       sendto_one(acptr, ":%s %s %s :%s", parv[0],
+                                                               IsToken(acptr->from) ? TOK_PRIVATE : MSG_PRIVATE, 
+                                                               format->nick, output);
+                                       }
+                                       else
+                                               sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name,
+                                                       parv[0], format->nick);
+                               }
                                free(current);
                                break;
                        }
index 8d1d694d2b04bf2f47cc5204318e091537fd0080..f5840c65d72c20e6c25ec25c8f11c2e17e2b9a62 100644 (file)
@@ -56,30 +56,14 @@ void send_umode_out(aClient *, aClient *, long);
 void send_umode_out_nickv2(aClient *, aClient *, long);
 void send_umode(aClient *, aClient *, long, long, char *);
 void set_snomask(aClient *, char *);
-int create_snomask(char *, int);
+void create_snomask(aClient *, anUser *, char *);
 extern int short_motd(aClient *sptr);
-char *get_snostr(long sno);
 /* static  Link    *is_banned(aClient *, aChannel *); */
 int  dontspread = 0;
 extern char *me_hash;
 extern char backupbuf[];
 static char buf[BUFSIZE];
 
-int sno_mask[] = { 
-       SNO_KILLS, 'k',
-       SNO_CLIENT, 'c',
-       SNO_FLOOD, 'f',
-       SNO_FCLIENT, 'F',
-       SNO_JUNK, 'j',
-       SNO_VHOST, 'v',
-       SNO_EYES, 'e',
-       SNO_TKL, 'G',
-       SNO_NICKCHANGE, 'n',
-       SNO_QLINE, 'q',
-       SNO_SNOTICE, 's',
-       0, 0
-};
-
 void iNAH_host(aClient *sptr, char *host)
 {
        if (!sptr->user)
@@ -367,6 +351,9 @@ int  hunt_server(aClient *cptr, aClient *sptr, char *command, int server, int pa
                        if (IsRegistered(acptr) && (acptr != cptr))
                                break;
                }
+       /* Fix for unregistered client receiving msgs: */
+       if (acptr && MyConnect(acptr) && IsUnknown(acptr))
+               acptr = NULL;
        if (acptr)
        {
                if (IsMe(acptr) || MyClient(acptr))
@@ -443,6 +430,9 @@ int  hunt_server_token(aClient *cptr, aClient *sptr, char *command, char *token,
                        if (IsRegistered(acptr) && (acptr != cptr))
                                break;
                }
+       /* Fix for unregistered client receiving msgs: */
+       if (acptr && MyConnect(acptr) && IsUnknown(acptr))
+               acptr = NULL;
        if (acptr)
        {
                char buff[1024];
@@ -559,6 +549,7 @@ int  check_for_target_limit(aClient *sptr, void *target, const char *name)
        for (p = sptr->targets; p < &sptr->targets[MAXTARGETS - 1];)
                if (*++p == hash)
                {
+                       /* move targethash to first position... */
                        memmove(&sptr->targets[1], &sptr->targets[0],
                            p - sptr->targets);
                        sptr->targets[0] = hash;
@@ -570,7 +561,7 @@ int  check_for_target_limit(aClient *sptr, void *target, const char *name)
                sptr->since += TARGET_DELAY; /* lag them up */
                sptr->nexttarget += TARGET_DELAY;
                sendto_one(sptr, err_str(ERR_TARGETTOOFAST), me.name, sptr->name,
-                       name);
+                       name, sptr->nexttarget - TStime());
 
                return 1;
        }
@@ -1191,7 +1182,7 @@ CMD_FUNC(m_nick)
        Membership *mp;
        time_t lastnick = (time_t) 0;
        int  differ = 1, update_watch = 1;
-
+       unsigned char newusr = 0;
        /*
         * If the user didn't specify a nickname, complain
         */
@@ -1206,6 +1197,19 @@ CMD_FUNC(m_nick)
                *s = '\0';
 
        strncpyzt(nick, parv[1], NICKLEN + 1);
+
+       if (MyConnect(sptr) && sptr->user && !IsAnOper(sptr))
+       {
+               if ((sptr->user->flood.nick_c >= NICK_COUNT) && 
+                   (TStime() - sptr->user->flood.nick_t < NICK_PERIOD))
+               {
+                       /* Throttle... */
+                       sendto_one(sptr, err_str(ERR_NCHANGETOOFAST), me.name, sptr->name, nick,
+                               (int)(NICK_PERIOD - (TStime() - sptr->user->flood.nick_t)));
+                       return 0;
+               }
+       }
+
        /*
         * if do_nick_name() returns a null name OR if the server sent a nick
         * name and do_nick_name() changed it in some way (due to rules of nick
@@ -1315,10 +1319,12 @@ CMD_FUNC(m_nick)
                            (aClient *)find_server_b64_or_real(sptr->user ==
                            NULL ? (char *)parv[6] : (char *)sptr->user->
                            server);
-                       sendto_snomask(SNO_QLINE, "Q:lined nick %s from %s on %s", nick,
-                           (*sptr->name != 0
-                           && !IsServer(sptr) ? sptr->name : "<unregistered>"),
-                           acptrs ? acptrs->name : "unknown server");
+                       /* (NEW: no unregistered q:line msgs anymore during linking) */
+                       if (!acptrs || (acptrs->serv && acptrs->serv->flags.synced))
+                               sendto_snomask(SNO_QLINE, "Q:lined nick %s from %s on %s", nick,
+                                   (*sptr->name != 0
+                                   && !IsServer(sptr) ? sptr->name : "<unregistered>"),
+                                   acptrs ? acptrs->name : "unknown server");
                }
                else
                {
@@ -1668,7 +1674,7 @@ CMD_FUNC(m_nick)
                {
                        for (mp = cptr->user->channel; mp; mp = mp->next)
                        {
-                               if (is_banned(cptr, &me, mp->chptr))
+                               if (is_banned(cptr, &me, mp->chptr) && !is_chanownprotop(cptr, mp->chptr))
                                {
                                        sendto_one(cptr,
                                            err_str(ERR_BANNICKCHANGE),
@@ -1687,6 +1693,14 @@ CMD_FUNC(m_nick)
                                        return 0;
                                }
                        }
+
+                       if (TStime() - sptr->user->flood.nick_t >= NICK_PERIOD)
+                       {
+                               sptr->user->flood.nick_t = TStime();
+                               sptr->user->flood.nick_c = 1;
+                       } else
+                               sptr->user->flood.nick_c++;
+
                        sendto_snomask(SNO_NICKCHANGE, "*** Notice -- %s (%s@%s) has changed his/her nickname to %s", sptr->name, sptr->user->username, sptr->user->realhost, nick);
 
                        RunHook2(HOOKTYPE_LOCAL_NICKCHANGE, sptr, nick);
@@ -1775,7 +1789,7 @@ CMD_FUNC(m_nick)
                            sptr->user->username, NULL, NULL) == FLUSH_BUFFER)
                                return FLUSH_BUFFER;
                        update_watch = 0;
-
+                       newusr = 1;
                }
        }
        /*
@@ -1802,6 +1816,25 @@ CMD_FUNC(m_nick)
        else if (IsPerson(sptr) && update_watch)
                hash_check_watch(sptr, RPL_LOGON);
 
+#ifdef NEWCHFLOODPROT
+       if (sptr->user && !newusr)
+       {
+               for (mp = sptr->user->channel; mp; mp = mp->next)
+               {
+                       aChannel *chptr = mp->chptr;
+                       if (chptr && !(mp->flags & (CHFL_CHANOP|CHFL_VOICE|CHFL_CHANOWNER|CHFL_HALFOP|CHFL_CHANPROT)) &&
+                           chptr->mode.floodprot && do_chanflood(chptr->mode.floodprot, FLD_NICK) && MyClient(sptr))
+                       {
+                               do_chanflood_action(chptr, FLD_NICK, "nick");
+                       }
+               }       
+       }
+#endif
+       if (newusr && !MyClient(sptr) && IsPerson(sptr))
+       {
+               RunHook(HOOKTYPE_REMOTE_CONNECT, sptr);
+       }
+
        return 0;
 }
 
@@ -1812,16 +1845,15 @@ CMD_FUNC(m_nick)
 ** returns an ascii string of modes
 */
 char *get_sno_str(aClient *sptr) {
-       int flag;
-       int *s;
+       int i;
        char *m;
 
        m = buf;
 
        *m++ = '+';
-       for (s = sno_mask; (flag = *s) && (m - buf < BUFSIZE - 4); s += 2)
-               if (sptr->user->snomask & flag)
-                       *m++ = (char)(*(s + 1));
+       for (i = 0; i <= Snomask_highest && (m - buf < BUFSIZE - 4); i++)
+               if (Snomask_Table[i].flag && sptr->user->snomask & Snomask_Table[i].mode)
+                       *m++ = Snomask_Table[i].flag;
        *m = 0;
        return buf;
 }
@@ -1834,7 +1866,6 @@ char *get_mode_str(aClient *acptr)
        m = buf;
        *m++ = '+';
        for (i = 0; (i <= Usermode_highest) && (m - buf < BUFSIZE - 4); i++)
-               
                if (Usermode_Table[i].flag && (acptr->umodes & Usermode_Table[i].mode))
                        *m++ = Usermode_Table[i].flag;
        *m = '\0';
@@ -1858,16 +1889,15 @@ char *get_modestr(long umodes)
 }
 
 char *get_snostr(long sno) {
-       int flag;
-       int *s;
+       int i;
        char *m;
 
        m = buf;
 
        *m++ = '+';
-       for (s = sno_mask; (flag = *s) && (m - buf < BUFSIZE - 4); s += 2)
-               if (sno & flag)
-                       *m++ = (char)(*(s + 1));
+       for (i = 0; i <= Snomask_highest && (m - buf < BUFSIZE - 4); i++)
+               if (Snomask_Table[i].flag && sno & Snomask_Table[i].mode)
+                       *m++ = Snomask_Table[i].flag;
        *m = 0;
        return buf;
 }
@@ -1975,7 +2005,7 @@ CMD_FUNC(m_user)
                if (CONNECT_SNOMASK)
                {
                        sptr->umodes |= UMODE_SERVNOTICE;
-                       user->snomask = create_snomask(CONNECT_SNOMASK, 0);
+                       create_snomask(sptr, user, CONNECT_SNOMASK);
                }
        }
 
@@ -2030,6 +2060,7 @@ CMD_FUNC(m_pass)
                    me.name, parv[0]);
                return 0;
        }
+
        PassLen = strlen(password);
        if (cptr->passwd)
                MyFree(cptr->passwd);
@@ -2037,6 +2068,9 @@ CMD_FUNC(m_pass)
                PassLen = PASSWDLEN;
        cptr->passwd = MyMalloc(PassLen + 1);
        strncpyzt(cptr->passwd, password, PassLen + 1);
+
+       /* note: the original non-truncated password is supplied as 2nd parameter. */
+       RunHookReturnInt2(HOOKTYPE_LOCAL_PASS, sptr, password, !=0);
        return 0;
 }
 
@@ -2161,7 +2195,7 @@ CMD_FUNC(m_ison)
 void set_snomask(aClient *sptr, char *snomask) {
        int what = MODE_ADD;
        char *p;
-       int *s, flag;
+       int i;
        if (snomask == NULL) {
                sptr->user->snomask = 0;
                return;
@@ -2176,28 +2210,32 @@ void set_snomask(aClient *sptr, char *snomask) {
                                what = MODE_DEL;
                                break;
                        default:
-                               for (s = sno_mask; (flag = *s); s += 2)
-                                       if (*p == (char) (*(s + 1))) {
-                                               if (what == MODE_ADD)
-                                                       sptr->user->snomask |= flag;
-                                               else
-                                                       sptr->user->snomask &= ~flag;
-                                       }
-                               
+                        for (i = 0; i <= Snomask_highest; i++)
+                        {
+                               if (!Snomask_Table[i].flag)
+                                       continue;
+                               if (*p == Snomask_Table[i].flag)
+                               {
+                                       if (Snomask_Table[i].allowed && !Snomask_Table[i].allowed(sptr))
+                                               continue;
+                                       if (what == MODE_ADD)
+                                               sptr->user->snomask |= Snomask_Table[i].mode;
+                                       else
+                                               sptr->user->snomask &= ~Snomask_Table[i].mode;
+                               }
+                        }                              
                }
        }
-       if (!IsAnOper(sptr)) {
-               sptr->user->snomask &= (SNO_NONOPERS);
-       }
 }
 
-int create_snomask(char *snomask, int oper) {
+void create_snomask(aClient *sptr, anUser *user, char *snomask) {
        int what = MODE_ADD;
        char *p;
-       int *s, flag, sno = 0;
-       
-       if (snomask == NULL) 
-               return sno;
+       int i;
+       if (snomask == NULL) {
+               user->snomask = 0;
+               return;
+       }
        
        for (p = snomask; p && *p; p++) {
                switch (*p) {
@@ -2208,20 +2246,22 @@ int create_snomask(char *snomask, int oper) {
                                what = MODE_DEL;
                                break;
                        default:
-                               for (s = sno_mask; (flag = *s); s += 2)
-                                       if (*p == (char) (*(s + 1))) {
-                                               if (what == MODE_ADD)
-                                                       sno |= flag;
-                                               else
-                                                       sno &= ~flag;
-                                       }
-                               
+                        for (i = 0; i <= Snomask_highest; i++)
+                        {
+                               if (!Snomask_Table[i].flag)
+                                       continue;
+                               if (*p == Snomask_Table[i].flag)
+                               {
+                                       if (Snomask_Table[i].allowed && !Snomask_Table[i].allowed(sptr))
+                                               continue;
+                                       if (what == MODE_ADD)
+                                               user->snomask |= Snomask_Table[i].mode;
+                                       else
+                                               user->snomask &= ~Snomask_Table[i].mode;
+                               }
+                        }                              
                }
        }
-       if (!oper) {
-               sno &= (SNO_NONOPERS);
-       }
-       return sno;
 }
 
 /*
@@ -2428,7 +2468,6 @@ CMD_FUNC(m_umode)
                ClearHideOper(sptr);
                ClearCoAdmin(sptr);
                ClearHelpOp(sptr);
-               sptr->user->snomask &= (SNO_NONOPERS);
        }
 
        /*
@@ -2457,9 +2496,10 @@ CMD_FUNC(m_umode)
                if ((sptr->umodes & (UMODE_KIX)) && !IsNetAdmin(sptr) && !IsSAdmin(sptr))
                        sptr->umodes &= ~UMODE_KIX;
 
-               if (MyClient(sptr) && (sptr->umodes & UMODE_SECURE)
-                   && !IsSecure(sptr))
+               if (MyClient(sptr) && (sptr->umodes & UMODE_SECURE) && !IsSecure(sptr))
                        sptr->umodes &= ~UMODE_SECURE;
+               if (MyClient(sptr) && !(sptr->umodes & UMODE_SECURE) && IsSecure(sptr))
+                       sptr->umodes |= UMODE_SECURE;
        }
        /*
         * For Services Protection...
@@ -2552,6 +2592,7 @@ CMD_FUNC(m_umode)
                        sptr->user->snomask &= ~SNO_NICKCHANGE;
                if (sptr->user->snomask & SNO_QLINE)
                        sptr->user->snomask &= ~SNO_QLINE;
+               RunHook2(HOOKTYPE_LOCAL_OPER, sptr, 0);
        }
 
        if ((sptr->umodes & UMODE_BOT) && !(setflags & UMODE_BOT))
@@ -2563,10 +2604,16 @@ CMD_FUNC(m_umode)
        if (!(setflags & UMODE_OPER) && IsOper(sptr))
                IRCstats.operators++;
        if ((setflags & UMODE_OPER) && !IsOper(sptr))
+       {
                IRCstats.operators--;
+               VERIFY_OPERCOUNT(sptr, "umode1");
+       }
        /* FIXME: This breaks something */
        if (!(setflags & UMODE_HIDEOPER) && IsHideOper(sptr))
+       {
                IRCstats.operators--;
+               VERIFY_OPERCOUNT(sptr, "umode2");
+       }
        if ((setflags & UMODE_HIDEOPER) && !IsHideOper(sptr))
                IRCstats.operators++;
        if (!(setflags & UMODE_INVISIBLE) && IsInvisible(sptr))
index 382f4de3ad009aba2416f0527812560782878e39..8429c21ae65a92443e912917293cfe6d79f0a579 100644 (file)
@@ -360,7 +360,9 @@ void sendto_channel_butone(aClient *one, aClient *from, aChannel *chptr,
                        /*
                         * Burst messages comes here..
                         */
+                       va_start(vl, pattern);
                        vsendto_prefix_one(acptr, from, pattern, vl);
+                       va_end(vl);
                }
        }
        va_end(vl);
@@ -407,7 +409,9 @@ void sendto_channelprefix_butone(aClient *one, aClient *from, aChannel *chptr,
                                if (!IsSecure(acptr))
                                        continue;
 #endif
+                       va_start(vl, pattern);
                        vsendto_prefix_one(acptr, from, pattern, vl);
+                       va_end(vl);
                        sentalong[i] = sentalong_marker;
                }
                else
@@ -421,10 +425,13 @@ void sendto_channelprefix_butone(aClient *one, aClient *from, aChannel *chptr,
                                        if (!IsSecure(acptr->from))
                                                continue;
 #endif
+                               va_start(vl, pattern);
                                vsendto_prefix_one(acptr, from, pattern, vl);
+                               va_end(vl);
                                sentalong[i] = sentalong_marker;
                        }
                }
+               va_end(vl);
        }
        va_end(vl);
        return;
@@ -492,6 +499,54 @@ void sendto_channelprefix_butone_tok(aClient *one, aClient *from, aChannel *chpt
        return;
 }
 
+/* weird channelmode +mu crap:
+ * - local: deliver msgs to chanops (and higher) like <IRC> SrcNick: hi all
+ * - remote: deliver msgs to every server once (if needed) with real sourcenick.
+ * The problem is we can't send to remote servers with sourcenick (prefix) 'IRC'
+ * because that's a virtual user... Fun... -- Syzop.
+ */
+void sendto_chmodemucrap(aClient *from, aChannel *chptr, char *text)
+{
+       Member *lp;
+       aClient *acptr;
+       int  i;
+
+       sprintf(tcmd, ":%s %s %s :%s", from->name, TOK_PRIVATE, chptr->chname, text); /* token */
+       sprintf(ccmd, ":%s %s %s :%s", from->name, MSG_PRIVATE, chptr->chname, text); /* msg */
+       sprintf(xcmd, ":IRC PRIVMSG %s :%s: %s", chptr->chname, from->name, text); /* local */
+
+       ++sentalong_marker;
+       for (lp = chptr->members; lp; lp = lp->next)
+       {
+               acptr = lp->cptr;
+
+               if (IsDeaf(acptr) && !sendanyways)
+                       continue;
+               if (!(lp->flags & (CHFL_CHANOP|CHFL_CHANOWNER|CHFL_CHANPROT)))
+                       continue;
+               i = acptr->from->slot;
+               if (MyConnect(acptr) && IsRegisteredUser(acptr))
+               {
+                       sendto_one(acptr, "%s", xcmd);
+                       sentalong[i] = sentalong_marker;
+               }
+               else
+               {
+                       /* Now check whether a message has been sent to this
+                        * remote link already */
+                       if (sentalong[i] != sentalong_marker)
+                       {
+                               if (IsToken(acptr->from))
+                                       sendto_one(acptr, "%s", tcmd);
+                               else
+                                       sendto_one(acptr, "%s", ccmd);
+                               sentalong[i] = sentalong_marker;
+                       }
+               }
+       }
+       return;
+}
+
 
 /*
    sendto_chanops_butone -Stskeeps
@@ -512,7 +567,9 @@ void sendto_chanops_butone(aClient *one, aChannel *chptr, char *pattern, ...)
                                           or user not not a channel op */
                if (MyConnect(acptr) && IsRegisteredUser(acptr))
                {
+                       va_start(vl, pattern);
                        vsendto_one(acptr, pattern, vl);
+                       va_end(vl);
                }
        }
        va_end(vl);
@@ -541,10 +598,13 @@ void sendto_serv_butone(aClient *one, char *pattern, ...)
        {
                if (!(cptr = local[i]) || (one && cptr == one->from))
                        continue;
+               va_start(vl, pattern);
+
 #ifdef NO_FDLIST
                if (IsServer(cptr))
 #endif
                        vsendto_one(cptr, pattern, vl);
+               va_end(vl);
        }
        va_end(vl);
        return;
@@ -769,12 +829,15 @@ void sendto_serv_butone_quit(aClient *one, char *pattern, ...)
        {
                if (!(cptr = local[i]) || (one && cptr == one->from))
                        continue;
+               va_start(vl, pattern);
+
 #ifdef NO_FDLIST
                if (IsServer(cptr) && !DontSendQuit(cptr))
 #else
                if (!DontSendQuit(cptr))
 #endif
                        vsendto_one(cptr, pattern, vl);
+               va_end(vl);
        }
        va_end(vl);
        return;
@@ -803,12 +866,15 @@ void sendto_serv_butone_sjoin(aClient *one, char *pattern, ...)
        {
                if (!(cptr = local[i]) || (one && cptr == one->from))
                        continue;
+               va_start(vl, pattern);
+
 #ifdef NO_FDLIST
                if (IsServer(cptr) && !SupportSJOIN(cptr))
 #else
                if (!SupportSJOIN(cptr))
 #endif
                        vsendto_one(cptr, pattern, vl);
+               va_end(vl);
        }
        va_end(vl);
        return;
@@ -838,12 +904,15 @@ void sendto_serv_sjoin(aClient *one, char *pattern, ...)
        {
                if (!(cptr = local[i]) || (one && cptr == one->from))
                        continue;
+               va_start(vl, pattern);
+
 #ifdef NO_FDLIST
                if (IsServer(cptr) && SupportSJOIN(cptr))
 #else
                if (SupportSJOIN(cptr))
 #endif
                        vsendto_one(cptr, pattern, vl);
+               va_end(vl);
        }
        va_end(vl);
        return;
@@ -873,12 +942,15 @@ void sendto_serv_butone_nickv2(aClient *one, char *pattern, ...)
        {
                if (!(cptr = local[i]) || (one && cptr == one->from))
                        continue;
+               va_start(vl, pattern);
+
 #ifdef NO_FDLIST
                if (IsServer(cptr) && !SupportNICKv2(cptr))
 #else
                if (!SupportNICKv2(cptr))
 #endif
                        vsendto_one(cptr, pattern, vl);
+               va_end(vl);
        }
        va_end(vl);
        return;
@@ -908,12 +980,15 @@ void sendto_serv_nickv2(aClient *one, char *pattern, ...)
        {
                if (!(cptr = local[i]) || (one && cptr == one->from))
                        continue;
+               va_start(vl, pattern);
+
 #ifdef NO_FDLIST
                if (IsServer(cptr) && SupportNICKv2(cptr))
 #else
                if (SupportNICKv2(cptr))
 #endif
                        vsendto_one(cptr, pattern, vl);
+               va_end(vl);
        }
        va_end(vl);
        return;
@@ -945,6 +1020,8 @@ void sendto_serv_nickv2_token(aClient *one, char *pattern, char *tokpattern,
        {
                if (!(cptr = local[i]) || (one && cptr == one->from))
                        continue;
+               va_start(vl, tokpattern);
+
 #ifdef NO_FDLIST
                if (IsServer(cptr) && SupportNICKv2(cptr) && !IsToken(cptr))
 #else
@@ -958,6 +1035,7 @@ void sendto_serv_nickv2_token(aClient *one, char *pattern, char *tokpattern,
                if (SupportNICKv2(cptr) && IsToken(cptr))
 #endif
                        vsendto_one(cptr, tokpattern, vl);
+               va_end(vl);
        }
        va_end(vl);
        return;
@@ -993,10 +1071,15 @@ void sendto_common_channels(aClient *user, char *pattern, ...)
                                    !(is_chanownprotop(user, channels->chptr) || is_chanownprotop(cptr, channels->chptr)))
                                        continue;
                                sentalong[cptr->slot] = sentalong_marker;
+                               va_start(vl, pattern);
                                vsendto_prefix_one(cptr, user, pattern, vl);
+                               va_end(vl);
                        }
        if (MyConnect(user))
+       {
+               va_start(vl, pattern);
                vsendto_prefix_one(user, user, pattern, vl);
+       }
        va_end(vl);
        return;
 }
@@ -1006,6 +1089,8 @@ void sendto_common_channels(aClient *user, char *pattern, ...)
  * Send a message to all members of a channel that are connected to this
  * server.
  */
+
+//STOPPED HERE
 void sendto_channel_butserv(aChannel *chptr, aClient *from, char *pattern, ...)
 {
        va_list vl;
@@ -1014,7 +1099,11 @@ void sendto_channel_butserv(aChannel *chptr, aClient *from, char *pattern, ...)
 
        for (va_start(vl, pattern), lp = chptr->members; lp; lp = lp->next)
                if (MyConnect(acptr = lp->cptr))
+               {
+                       va_start(vl, pattern);
                        vsendto_prefix_one(acptr, from, pattern, vl);
+                       va_end(vl);
+               }
        va_end(vl);
        return;
 }
@@ -1030,7 +1119,11 @@ void sendto_channel_butserv_butone(aChannel *chptr, aClient *from, aClient *one,
                if (lp->cptr == one)
                        continue;
                if (MyConnect(acptr = lp->cptr))
+               {
+                       va_start(vl, pattern);
                        vsendto_prefix_one(acptr, from, pattern, vl);
+                       va_end(vl);
+               }
        }
        va_end(vl);
        return;
@@ -1091,7 +1184,9 @@ void sendto_match_servs(aChannel *chptr, aClient *from, char *format, ...)
                        continue;
                if (!BadPtr(mask) && IsServer(cptr) && match(mask, cptr->name))
                        continue;
+               va_start(vl, format);
                vsendto_one(cptr, format, vl);
+               va_end(vl);
        }
        va_end(vl);
 }
@@ -1145,7 +1240,9 @@ void sendto_match_butone(aClient *one, aClient *from, char *mask, int what,
                else if (!cansendlocal || (!(IsRegisteredUser(cptr) &&
                    match_it(cptr, mask, what))))
                        continue;
+               va_start(vl, pattern);
                vsendto_prefix_one(cptr, from, pattern, vl);
+               va_end(vl);
        }
        va_end(vl);
        return;
@@ -1166,7 +1263,11 @@ void sendto_all_butone(aClient *one, aClient *from, char *pattern, ...)
 
        for (va_start(vl, pattern), i = 0; i <= LastSlot; i++)
                if ((cptr = local[i]) && !IsMe(cptr) && one != cptr)
+               {
+                       va_start(vl, pattern);
                        vsendto_prefix_one(cptr, from, pattern, vl);
+                       va_end(vl);
+               }
        va_end(vl);
        return;
 }
@@ -1189,7 +1290,9 @@ void sendto_ops(char *pattern, ...)
                {
                        (void)ircsprintf(nbuf, ":%s NOTICE %s :*** Notice -- ", me.name, cptr->name);
                        (void)strncat(nbuf, pattern, sizeof(nbuf) - strlen(nbuf));
+                       va_start(vl, pattern);
                        vsendto_one(cptr, nbuf, vl);
+                       va_end(vl);
                }
        va_end(vl);
        return;
@@ -1216,7 +1319,9 @@ void sendto_failops(char *pattern, ...)
                            me.name, cptr->name);
                        (void)strncat(nbuf, pattern,
                            sizeof(nbuf) - strlen(nbuf));
+                       va_start(vl, pattern);
                        vsendto_one(cptr, nbuf, vl);
+                       va_end(vl);
                }
        va_end(vl);
        return;
@@ -1241,7 +1346,9 @@ void sendto_umode(int umodes, char *pattern, ...)
                            me.name, cptr->name);
                        (void)strncat(nbuf, pattern,
                            sizeof(nbuf) - strlen(nbuf));
+                       va_start(vl, pattern);
                        vsendto_one(cptr, nbuf, vl);
+                       va_end(vl);
                }
        va_end(vl);
        return;
@@ -1265,7 +1372,9 @@ void sendto_snomask(int snomask, char *pattern, ...)
                            me.name, cptr->name);
                        (void)strncat(nbuf, pattern,
                            sizeof(nbuf) - strlen(nbuf));
+                       va_start(vl, pattern);
                        vsendto_one(cptr, nbuf, vl);
+                       va_end(vl);
                }
        va_end(vl);
        return;
@@ -1292,7 +1401,9 @@ void sendto_failops_whoare_opers(char *pattern, ...)
                            me.name, cptr->name);
                        (void)strncat(nbuf, pattern,
                            sizeof(nbuf) - strlen(nbuf));
+                       va_start(vl, pattern);
                        vsendto_one(cptr, nbuf, vl);
+                       va_end(vl);
                }
        va_end(vl);
        return;
@@ -1318,7 +1429,9 @@ void sendto_locfailops(char *pattern, ...)
                            me.name, cptr->name);
                        (void)strncat(nbuf, pattern,
                            sizeof(nbuf) - strlen(nbuf));
+                       va_start(vl, pattern);
                        vsendto_one(cptr, nbuf, vl);
+                       va_end(vl);
                }
        va_end(vl);
        return;
@@ -1344,7 +1457,9 @@ void sendto_opers(char *pattern, ...)
                            me.name, cptr->name);
                        (void)strncat(nbuf, pattern,
                            sizeof(nbuf) - strlen(nbuf));
+                       va_start(vl, pattern);
                        vsendto_one(cptr, nbuf, vl);
+                       va_end(vl);
                }
        va_end(vl);
        return;
@@ -1374,7 +1489,9 @@ void sendto_ops_butone(aClient *one, aClient *from, char *pattern, ...)
                if (cptr->from == one)
                        continue;       /* ...was the one I should skip */
                sentalong[i] = sentalong_marker;
+               va_start(vl, pattern);
                vsendto_prefix_one(cptr->from, from, pattern, vl);
+               va_end(vl);
        }
        va_end(vl);
        return;
@@ -1406,7 +1523,9 @@ void sendto_opers_butone(aClient *one, aClient *from, char *pattern, ...)
                if (cptr->from == one)
                        continue;       /* ...was the one I should skip */
                sentalong[i] = sentalong_marker;
+               va_start(vl, pattern);
                vsendto_prefix_one(cptr->from, from, pattern, vl);
+               va_end(vl);
        }
        va_end(vl);
        return;
@@ -1435,7 +1554,9 @@ void sendto_ops_butme(aClient *from, char *pattern, ...)
                if (!strcmp(cptr->user->server, me.name))       /* a locop */
                        continue;
                sentalong[i] = sentalong_marker;
+               va_start(vl, pattern);
                vsendto_prefix_one(cptr->from, from, pattern, vl);
+               va_end(vl);
        }
        va_end(vl);
        return;
@@ -1541,7 +1662,9 @@ void sendto_realops(char *pattern, ...)
                            me.name, cptr->name);
                        (void)strncat(nbuf, pattern,
                            sizeof(nbuf) - strlen(nbuf));
+                       va_start(vl, pattern);
                        vsendto_one(cptr, nbuf, vl);
+                       va_end(vl);
                }
        va_end(vl);
        return;
index f63ef55f90b4ce255ed7ee7b8f67b71074658096..f8c188b131dcf27d8dace139f9a2a644f3d75475 100644 (file)
@@ -163,7 +163,7 @@ int  deliver_it(aClient *cptr, char *str, int len)
                                acpt->sendB &= 0x03ff;
                        }
                }
-               else if (me.sendB > 1023)
+               if (me.sendB > 1023)
                {
                        me.sendK += (me.sendB >> 10);
                        me.sendB &= 0x03ff;
index 103e8afb2b06a12a9c0372156d596a84276b406a..67103b953820e7b6363adaf7f9534aa133a509bb 100644 (file)
--- a/src/ssl.c
+++ b/src/ssl.c
@@ -591,7 +591,7 @@ static int fatal_ssl_error(int ssl_error, int where, aClient *sptr)
      * IRC protocol wasn`t SSL enabled .. --vejeta
      */
     sendto_snomask(SNO_JUNK, "Exiting ssl client %s: %s: %s",
-       sptr->name, ssl_func, ssl_errstr);
+       get_client_name(sptr, TRUE), ssl_func, ssl_errstr);
     sptr->flags |= FLAGS_DEADSOCKET;
        if (errtmp)
        {
index 6ecaf7d2dbb5a5da6aea34dc55c8d209752e5646..3307b38b98382a25b0d15d4508ce57c842104a84 100644 (file)
@@ -1,5 +1,5 @@
 /************************************************************************
- *   IRC - Internet Relay Chat, s_unreal.c
+ *   IRC - Internet Relay Chat, umodes.c
  *   (C) 1999-2000 Carsten Munk (Techie/Stskeeps) <stskeeps@tspre.org>
  *
  *   See file AUTHORS in IRC package for additional names of
@@ -25,6 +25,7 @@
 #include "sys.h"
 #include "numeric.h"
 #include "msg.h"
+#include "proto.h"
 #include "channel.h"
 #include "version.h"
 #include <time.h>
 #endif
 #include <fcntl.h>
 #include "h.h"
-
 extern char umodestring[UMODETABLESZ+1];
 
-aUMtable *Usermode_Table = NULL;
+Umode *Usermode_Table = NULL;
 short   Usermode_highest = 0;
 
+Snomask *Snomask_Table = NULL;
+short   Snomask_highest = 0;
+
 /* cptr->umodes (32 bits): 26 used, 6 free */
 long UMODE_INVISIBLE = 0L;     /* makes user invisible */
 long UMODE_OPER = 0L;          /* Operator */
@@ -74,6 +77,18 @@ long UMODE_SETHOST = 0L;       /* Used sethost */
 long UMODE_STRIPBADWORDS = 0L; /* Strip badwords */
 long UMODE_HIDEWHOIS = 0L;     /* Hides channels in /whois */
 
+long SNO_KILLS = 0L;
+long SNO_CLIENT = 0L;
+long SNO_FLOOD = 0L;
+long SNO_FCLIENT = 0L;
+long SNO_JUNK = 0L;
+long SNO_VHOST = 0L;
+long SNO_EYES = 0L;
+long SNO_TKL = 0L;
+long SNO_NICKCHANGE = 0L;
+long SNO_QLINE = 0L;
+long SNO_SNOTICE = 0L;
+
 long AllUmodes;                /* All umodes */
 long SendUmodes;       /* All umodes which are sent to other servers (global umodes) */
 
@@ -81,41 +96,63 @@ void        umode_init(void)
 {
        long val = 1;
        int     i;
-       Usermode_Table = (aUMtable *)MyMalloc(sizeof(aUMtable) * UMODETABLESZ);
-       bzero(Usermode_Table, sizeof(aUMtable) * UMODETABLESZ);
+       Usermode_Table = MyMalloc(sizeof(Umode) * UMODETABLESZ);
+       bzero(Usermode_Table, sizeof(Umode) * UMODETABLESZ);
        for (i = 0; i < UMODETABLESZ; i++)
        {
                Usermode_Table[i].mode = val;
                val *= 2;
        }
        Usermode_highest = 0;
+
+       Snomask_Table = MyMalloc(sizeof(Snomask) * UMODETABLESZ);
+       bzero(Snomask_Table, sizeof(Snomask) * UMODETABLESZ);
+       val = 1;
+       for (i = 0; i < UMODETABLESZ; i++)
+       {
+               Snomask_Table[i].mode = val;
+               val *= 2;
+       }
+       Snomask_highest = 0;
+
        /* Set up modes */
-       UMODE_INVISIBLE = umode_gget('i'); /*  0x0001    makes user invisible */
-       UMODE_OPER = umode_gget('o');      /*  0x0002    Operator */
-       UMODE_WALLOP = umode_gget('w');    /*  0x0004    send wallops to them */
-       UMODE_FAILOP = umode_gget('g');    /*  0x0008    Shows some global messages */
-       UMODE_HELPOP = umode_gget('h');    /*  0x0010    Help system operator */
-       UMODE_REGNICK = umode_gget('r');   /*  0x0020    Nick set by services as registered */
-       UMODE_SADMIN = umode_gget('a');    /*  0x0040    Services Admin */
-       UMODE_ADMIN = umode_gget('A');     /*  0x0080    Admin */
-       UMODE_SERVNOTICE = umode_lget('s');/* 0x0100     server notices such as kill */
-       UMODE_LOCOP = umode_lget('O');     /* 0x0200     Local operator -- SRB */
-       UMODE_RGSTRONLY = umode_gget('R'); /* 0x0400  Only reg nick message */
-       UMODE_WEBTV = umode_gget('V');     /* 0x0800  WebTV Client */
-       UMODE_SERVICES = umode_gget('S');  /* 0x4000     services */
-       UMODE_HIDE = umode_gget('x');        /* 0x8000   Hide from Nukes */
-       UMODE_NETADMIN = umode_gget('N');  /* 0x10000    Network Admin */
-       UMODE_COADMIN = umode_gget('C');   /* 0x80000    Co Admin */
-       UMODE_WHOIS = umode_gget('W');     /* 0x100000   gets notice on /whois */
-       UMODE_KIX = umode_gget('q');       /* 0x200000   usermode +q */
-       UMODE_BOT = umode_gget('B');       /* 0x400000   User is a bot */
-       UMODE_SECURE = umode_gget('z');    /*   0x800000         User is a secure connect */
-       UMODE_VICTIM = umode_gget('v');    /* 0x8000000  Intentional Victim */
-       UMODE_DEAF = umode_gget('d');      /* 0x10000000       Deaf */
-       UMODE_HIDEOPER = umode_gget('H');  /* 0x20000000         Hide oper mode */
-       UMODE_SETHOST = umode_gget('t');   /* 0x40000000         used sethost */
-       UMODE_STRIPBADWORDS = umode_gget('G'); /* 0x80000000     */
-       UMODE_HIDEWHOIS = umode_gget('p'); /* Hides channels in /whois */
+       UmodeAdd(NULL, 'i', UMODE_GLOBAL, NULL, &UMODE_INVISIBLE);
+       UmodeAdd(NULL, 'o', UMODE_GLOBAL, NULL, &UMODE_OPER);
+       UmodeAdd(NULL, 'w', UMODE_GLOBAL, NULL, &UMODE_WALLOP);
+       UmodeAdd(NULL, 'g', UMODE_GLOBAL, NULL, &UMODE_FAILOP);
+       UmodeAdd(NULL, 'h', UMODE_GLOBAL, NULL, &UMODE_HELPOP);
+       UmodeAdd(NULL, 'r', UMODE_GLOBAL, NULL, &UMODE_REGNICK);
+       UmodeAdd(NULL, 'a', UMODE_GLOBAL, NULL, &UMODE_SADMIN);
+       UmodeAdd(NULL, 'A', UMODE_GLOBAL, NULL, &UMODE_ADMIN);
+       UmodeAdd(NULL, 's', UMODE_LOCAL, NULL, &UMODE_SERVNOTICE);
+       UmodeAdd(NULL, 'O', UMODE_LOCAL, NULL, &UMODE_LOCOP);
+       UmodeAdd(NULL, 'R', UMODE_GLOBAL, NULL, &UMODE_RGSTRONLY);
+       UmodeAdd(NULL, 'V', UMODE_GLOBAL, NULL, &UMODE_WEBTV);
+       UmodeAdd(NULL, 'S', UMODE_GLOBAL, NULL, &UMODE_SERVICES);
+       UmodeAdd(NULL, 'x', UMODE_GLOBAL, NULL, &UMODE_HIDE);
+       UmodeAdd(NULL, 'N', UMODE_GLOBAL, NULL, &UMODE_NETADMIN);
+       UmodeAdd(NULL, 'C', UMODE_GLOBAL, NULL, &UMODE_COADMIN);
+       UmodeAdd(NULL, 'W', UMODE_GLOBAL, NULL, &UMODE_WHOIS);
+       UmodeAdd(NULL, 'q', UMODE_GLOBAL, NULL, &UMODE_KIX);
+       UmodeAdd(NULL, 'B', UMODE_GLOBAL, NULL, &UMODE_BOT);
+       UmodeAdd(NULL, 'z', UMODE_GLOBAL, NULL, &UMODE_SECURE);
+       UmodeAdd(NULL, 'v', UMODE_GLOBAL, NULL, &UMODE_VICTIM);
+       UmodeAdd(NULL, 'd', UMODE_GLOBAL, NULL, &UMODE_DEAF);
+       UmodeAdd(NULL, 'H', UMODE_GLOBAL, NULL, &UMODE_HIDEOPER);
+       UmodeAdd(NULL, 't', UMODE_GLOBAL, NULL, &UMODE_SETHOST);
+       UmodeAdd(NULL, 'G', UMODE_GLOBAL, NULL, &UMODE_STRIPBADWORDS);
+       UmodeAdd(NULL, 'p', UMODE_GLOBAL, NULL, &UMODE_HIDEWHOIS);
+       SnomaskAdd(NULL, 'k', umode_allow_all, &SNO_KILLS);
+       SnomaskAdd(NULL, 'c', umode_allow_opers, &SNO_CLIENT);
+       SnomaskAdd(NULL, 'f', umode_allow_opers, &SNO_FLOOD);
+       SnomaskAdd(NULL, 'F', umode_allow_opers, &SNO_FCLIENT);
+       SnomaskAdd(NULL, 'j', umode_allow_opers, &SNO_JUNK);
+       SnomaskAdd(NULL, 'v', umode_allow_opers, &SNO_VHOST);
+       SnomaskAdd(NULL, 'e', umode_allow_opers, &SNO_EYES);
+       SnomaskAdd(NULL, 'G', umode_allow_opers, &SNO_TKL);
+       SnomaskAdd(NULL, 'n', umode_allow_opers, &SNO_NICKCHANGE);
+       SnomaskAdd(NULL, 'q', umode_allow_opers, &SNO_QLINE);
+       SnomaskAdd(NULL, 's', umode_allow_all, &SNO_SNOTICE);
 }
 
 void make_umodestr(void)
@@ -136,18 +173,33 @@ void make_umodestr(void)
  * Add a usermode with character 'ch', if global is set to 1 the usermode is global
  * (sent to other servers) otherwise it's a local usermode
  */
-long   umode_get(char ch, int global, int (*allowed)(aClient *sptr))
+Umode *UmodeAdd(Module *module, char ch, int global, int (*allowed)(aClient *sptr), long *mode)
 {
        short    i = 0;
        short    j = 0;
+       short    save = -1;
        while (i < UMODETABLESZ)
        {
-               if (!Usermode_Table[i].flag)
+               if (!Usermode_Table[i].flag && save == -1)
+                       save = i;
+               else if (Usermode_Table[i].flag == ch)
                {
-                       break;
+                       if (Usermode_Table[i].unloaded)
+                       {
+                               save = i;
+                               Usermode_Table[i].unloaded = 0;
+                               break;
+                       }
+                       else
+                       {
+                               if (module)
+                                       module->errorcode = MODERR_EXISTS;
+                               return NULL;
+                       }
                }
                i++;
        }
+       i = save;
        if (i != UMODETABLESZ)
        {
                Usermode_Table[i].flag = ch;
@@ -163,34 +215,155 @@ long     umode_get(char ch, int global, int (*allowed)(aClient *sptr))
                AllUmodes |= Usermode_Table[i].mode;
                if (global)
                        SendUmodes |= Usermode_Table[i].mode;
-               return (Usermode_Table[i].mode);
+               *mode = Usermode_Table[i].mode;
+               Usermode_Table[i].owner = module;
+               if (module)
+               {
+                       ModuleObject *umodeobj = MyMallocEx(sizeof(ModuleObject));
+                       umodeobj->object.umode = &(Usermode_Table[i]);
+                       umodeobj->type = MOBJ_UMODE;
+                       AddListItem(umodeobj, module->objects);
+                       module->errorcode = MODERR_NOERROR;
+               }
+               return &(Usermode_Table[i]);
        }
        else
        {
-               Debug((DEBUG_DEBUG, "umode_get failed, no space"));
-               return (0);
+               Debug((DEBUG_DEBUG, "UmodeAdd failed, no space"));
+               if (module)
+                       module->errorcode = MODERR_NOSPACE;
+               return NULL;
        }
 }
 
 
-int    umode_delete(char ch, long val)
+void UmodeDel(Umode *umode)
 {
-       int i = 0;
-       Debug((DEBUG_DEBUG, "umode_delete %c, %li",
-               ch, val));      
-       
+       if (loop.ircd_rehashing)
+               umode->unloaded = 1;
+       else    
+       {
+               aClient *cptr;
+               for (cptr = client; cptr; cptr = cptr->next)
+               {
+                       long oldumode = 0;
+                       if (!IsPerson(cptr))
+                               continue;
+                       oldumode = cptr->umodes;
+                       cptr->umodes &= ~umode->mode;
+                       if (MyClient(cptr))
+                               send_umode_out(cptr, cptr, oldumode);
+               }
+               umode->flag = '\0';
+               AllUmodes &= ~(umode->mode);
+               SendUmodes &= ~(umode->mode);
+       }
+
+       if (umode->owner) {
+               ModuleObject *umodeobj;
+               for (umodeobj = umode->owner->objects; umodeobj; umodeobj = umodeobj->next) {
+                       if (umodeobj->type == MOBJ_UMODE && umodeobj->object.umode == umode) {
+                               DelListItem(umodeobj, umode->owner->objects);
+                               MyFree(umodeobj);
+                               break;
+                       }
+               }
+               umode->owner = NULL;
+       }
+       return;
+}
+
+Snomask *SnomaskAdd(Module *module, char ch, int (*allowed)(aClient *sptr), long *mode)
+{
+       short    i = 0;
+       short    j = 0;
+       short    save = -1;
        while (i < UMODETABLESZ)
        {
-               if ((Usermode_Table[i].flag == ch) && (Usermode_Table[i].mode == val))
+               if (!Snomask_Table[i].flag && save == -1)
+                       save = i;
+               else if (Snomask_Table[i].flag == ch)
                {
-                       Usermode_Table[i].flag = '\0';
-                       AllUmodes &= ~val;
-                       SendUmodes &= ~val;
-                       return 1;
-               }       
+                       if (Snomask_Table[i].unloaded)
+                       {
+                               save = i;
+                               Snomask_Table[i].unloaded = 0;
+                               break;
+                       }
+                       else
+                       {
+                               if (module)
+                                       module->errorcode = MODERR_EXISTS;
+                               return NULL;
+                       }
+               }
                i++;
        }
-       return -1;
+       i = save;
+       if (i != UMODETABLESZ)
+       {
+               Snomask_Table[i].flag = ch;
+               Snomask_Table[i].allowed = allowed;
+               /* Update usermode table highest */
+               for (j = 0; j < UMODETABLESZ; j++)
+                       if (Snomask_Table[i].flag)
+                               if (i > Snomask_highest)
+                                       Snomask_highest = i;
+               *mode = Snomask_Table[i].mode;
+               Snomask_Table[i].owner = module;
+               if (module)
+               {
+                       ModuleObject *snoobj = MyMallocEx(sizeof(ModuleObject));
+                       snoobj->object.snomask = &(Snomask_Table[i]);
+                       snoobj->type = MOBJ_SNOMASK;
+                       AddListItem(snoobj, module->objects);
+                       module->errorcode = MODERR_NOERROR;
+               }
+               return &(Snomask_Table[i]);
+       }
+       else
+       {
+               Debug((DEBUG_DEBUG, "SnomaskAdd failed, no space"));
+               *mode = 0;
+               if (module)
+                       module->errorcode = MODERR_NOSPACE;
+               return NULL;
+       }
+}
+
+void SnomaskDel(Snomask *sno)
+{
+       if (loop.ircd_rehashing)
+               sno->unloaded = 1;
+       else    
+       {
+               int i;
+               for (i = 0; i <= LastSlot; i++)
+               {
+                       aClient *cptr = local[i];
+                       long oldsno;
+                       if (!cptr || !IsPerson(cptr))
+                               continue;
+                       oldsno = cptr->user->snomask;
+                       cptr->user->snomask &= ~sno->mode;
+                       if (oldsno != cptr->user->snomask)
+                               sendto_one(cptr, rpl_str(RPL_SNOMASK), me.name,
+                                       cptr->name, get_snostr(cptr->user->snomask));
+               }
+               sno->flag = '\0';
+       }
+       if (sno->owner) {
+               ModuleObject *snoobj;
+               for (snoobj = sno->owner->objects; snoobj; snoobj = snoobj->next) {
+                       if (snoobj->type == MOBJ_SNOMASK && snoobj->object.snomask == sno) {
+                               DelListItem(snoobj, sno->owner->objects);
+                               MyFree(snoobj);
+                               break;
+                       }
+               }
+               sno->owner = NULL;
+       }
+       return;
 }
 
 int umode_allow_all(aClient *sptr)
@@ -203,3 +376,90 @@ int umode_allow_opers(aClient *sptr)
        return IsAnOper(sptr) ? 1 : 0;
 }
 
+void unload_all_unused_umodes()
+{
+       long removed_umode = 0;
+       int i;
+       aClient *cptr;
+       for (i = 0; i < UMODETABLESZ; i++)
+       {
+               if (Usermode_Table[i].unloaded)
+                       removed_umode |= Usermode_Table[i].mode;
+       }
+       if (!removed_umode) /* Nothing was unloaded */
+               return;
+       for (cptr = client; cptr; cptr = cptr->next)
+       {
+               long oldumode = 0;
+               if (!IsPerson(cptr))
+                       continue;
+               oldumode = cptr->umodes;
+               cptr->umodes &= ~(removed_umode);
+               if (MyClient(cptr))
+                       send_umode_out(cptr, cptr, oldumode);
+       }
+       for (i = 0; i < UMODETABLESZ; i++)
+       {
+               if (Usermode_Table[i].unloaded)
+               {
+                       AllUmodes &= ~(Usermode_Table[i].mode);
+                       SendUmodes &= ~(Usermode_Table[i].mode);
+                       Usermode_Table[i].flag = '\0';
+                       Usermode_Table[i].unloaded = 0;
+               }
+       }
+
+}
+
+void unload_all_unused_snomasks()
+{
+       long removed_sno = 0;
+       int i;
+
+       for (i = 0; i < UMODETABLESZ; i++)
+       {
+               if (Snomask_Table[i].unloaded)
+               {
+                       removed_sno |= Snomask_Table[i].mode;
+                       Snomask_Table[i].flag = '\0';
+                       Snomask_Table[i].unloaded = 0;
+               }
+       }
+       if (!removed_sno) /* Nothing was unloaded */
+               return;
+       for (i = 0; i <= LastSlot; i++)
+       {
+               aClient *cptr = local[i];
+               long oldsno;
+               if (!cptr || !IsPerson(cptr))
+                       continue;
+               oldsno = cptr->user->snomask;
+               cptr->user->snomask &= ~(removed_sno);
+               if (oldsno != cptr->user->snomask)
+                       sendto_one(cptr, rpl_str(RPL_SNOMASK), me.name,
+                               cptr->name, get_snostr(cptr->user->snomask));
+               
+       }
+}
+
+long umode_get(char ch, int options, int (*allowed)(aClient *sptr))
+{
+       long flag;
+       if (UmodeAdd(NULL, ch, options, allowed, &flag))
+               return flag;
+       return 0;
+}
+
+int umode_delete(char ch, long val)
+{
+       int i;
+       for (i = 0; i < UMODETABLESZ; i++)
+       {
+               if (Usermode_Table[i].flag == ch && Usermode_Table[i].mode == val)
+               {
+                       UmodeDel(&Usermode_Table[i]);
+                       return 1;
+               }
+       }
+       return -1;
+}
index e3fede759862d8c79ab0fd5b181a484305c8a6c1..f563e885a33186b0248170d1639029744a8d7182 100644 (file)
@@ -79,7 +79,7 @@ int   webtv_parse(aClient *sptr, char *string)
        n = strlen(string);
        cmd = strtok(string, " ");
        if (!cmd)
-               return -2;      
+               return -99;     
                
        for (message = webtv_cmds; message->command; message++)
                if (strcasecmp(message->command, cmd) == 0)
@@ -92,7 +92,7 @@ int   webtv_parse(aClient *sptr, char *string)
                /* restore the string*/
                if (strlen(cmd) < n)
                        cmd[strlen(cmd)]= ' ';
-               return -2;
+               return -99;
        }
 
        i = 0;
@@ -130,28 +130,11 @@ int       webtv_parse(aClient *sptr, char *string)
        }
        para[++i] = NULL;
 
-       (*message->func) (sptr->from, sptr, i, para);
-       return 0;
+       return (*message->func) (sptr->from, sptr, i, para);
 }
 
 int    w_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
 {
-       static anUser UnknownUser = {
-               NULL,           /* channel */
-               NULL,           /* invited */
-               NULL,           /* silence */
-               NULL,           /* away */
-#ifdef NO_FLOOD_AWAY
-               0,              /* last_away */
-               0,              /* away_count */
-#endif
-               0,              /* servicestamp */
-               1,              /* refcount */
-               0,              /* joined */
-               "<Unknown>",    /* username */
-               "<Unknown>",    /* host */
-               "<Unknown>"     /* server */
-       };
        Membership *lp;
        anUser *user;
        aClient *acptr, *a2cptr;
@@ -204,7 +187,9 @@ int w_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
                         */
                        if (!MyConnect(sptr) && !MyConnect(acptr) && wilds)
                                continue;
-                       user = acptr->user ? acptr->user : &UnknownUser;
+                       if (!IsPerson(acptr))
+                               continue;
+                       user = acptr->user;
                        name = (!*acptr->name) ? "?" : acptr->name;
 
                        invis = acptr != sptr && IsInvisible(acptr);
@@ -234,8 +219,8 @@ int w_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
                                continue;
                        a2cptr = find_server_quick(user->server);
 
-                       if (!IsPerson(acptr))
-                               continue;
+                       /* if (!IsPerson(acptr))
+                               continue; ** moved to top -- Syzop */
                        sendto_one(sptr, ":IRC PRIVMSG %s :WHOIS information for %s", sptr->name, acptr->name);
                        if (IsWhois(acptr))
                        {
index 6f006f72b1176ca3b6e26e9ab4dca957aef72856..b382e1091f0b4b84a3f8af3454554d2e58275654 100644 (file)
@@ -1,6 +1,6 @@
 /************************************************************************
  *   IRC - Internet Relay Chat, Win32GUI.c
- *   Copyright (C) 2000-2002 David Flynn (DrBin) & Dominick Meglio (codemastr)
+ *   Copyright (C) 2000-2003 David Flynn (DrBin) & Dominick Meglio (codemastr)
  *   
  *   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
@@ -46,7 +46,7 @@
 #include <richedit.h>
 #include <commdlg.h>
 
-#define MIRC_COLORS "{\\colortbl ;\\red255\\green255\\blue255;\\red0\\green0\\blue127;\\red0\\green147\\blue0;\\red255\\green0\\blue0;\\red147\\green0\\blue0;\\red128\\green0\\blue128;\\red255\\green128\\blue0;\\red255\\green255\\blue0;\\red0\\green255\\blue0;\\red0\\green128\\blue128;\\red0\\green255\\blue255;\\red0\\green0\\blue252;\\red255\\green0\\blue255;\\red128\\green128\\blue128;\\red192\\green192\\blue192;\\red0\\green0\\blue0;}"
+#define MIRC_COLORS "{\\colortbl;\\red255\\green255\\blue255;\\red0\\green0\\blue127;\\red0\\green147\\blue0;\\red255\\green0\\blue0;\\red127\\green0\\blue0;\\red156\\green0\\blue156;\\red252\\green127\\blue0;\\red255\\green255\\blue0;\\red0\\green252\\blue0;\\red0\\green147\\blue147;\\red0\\green255\\blue255;\\red0\\green0\\blue252;\\red255\\green0\\blue255;\\red127\\green127\\blue127;\\red210\\green210\\blue210;\\red0\\green0\\blue0;}"
 
 /* Lazy macro */
 #define ShowDialog(handle, inst, template, parent, proc) {\
@@ -109,12 +109,12 @@ HWND hwIRCDWnd=NULL;
 HWND hwTreeView;
 HWND hWndMod;
 HANDLE hMainThread = 0;
-UINT WM_TASKBARCREATED;
+UINT WM_TASKBARCREATED, WM_FINDMSGSTRING;
 FARPROC lpfnOldWndProc;
 HMENU hContext;
 OSVERSIONINFO VerInfo;
 char OSName[256];
-
+HWND hFind;
 void TaskBarCreated() {
        HICON hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON,16, 16, 0);
        SysTray.cbSize = sizeof(NOTIFYICONDATA);
@@ -189,48 +189,6 @@ LRESULT RESubClassFunc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
 /* Somewhat respectable RTF to IRC parser
  * (c) 2001 codemastr
  */
-typedef struct colorlist {
-       struct colorlist *prev,*next;
-       unsigned char *color;
-} ColorList;
-
-ColorList *TextColors = NULL;
-void AddColor(unsigned char *color) {
-       ColorList *clist;
-
-       clist = MyMallocEx(sizeof(ColorList));
-       if (!clist)
-               return;
-       clist->color = strdup(color);
-       AddListItem(clist,TextColors);
-}
-
-ColorList *DelNewestColor() {
-       ColorList *p = TextColors, *q;
-       if (!p)
-               return NULL;
-       q = TextColors->next;
-       MyFree(p->color);
-
-       TextColors = p->next;
-
-       if (p->next)
-               p->next->prev = NULL;
-       MyFree(p);
-       return q;
-}
-
-void WipeColors() {
-       ColorList *clist, *next;
-
-       for (clist = TextColors; clist; clist = next)
-       {
-                       next = clist->next;
-                       MyFree(clist->color);
-                       MyFree(clist);
-       }
-
-}
 DWORD CALLBACK SplitIt(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) {
        StreamIO *stream = (StreamIO*)dwCookie;
        if (*stream->size == 0)
@@ -276,199 +234,303 @@ DWORD CALLBACK BufferIt(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) {
        return 0;
 }
 
-DWORD CALLBACK RTFToIRC(int fd, unsigned char *pbBuff, long cb) {
-       unsigned char *buffer = malloc(cb);
-       int i = 0, j = 0, k = 0, start = 0, end = 0;
-       int incolor = 0, bold = 0, uline = 0;
-       unsigned char cmd[15], value[500], color[25], colorbuf[4];
-       unsigned char colors[16];
-       pbBuff++;
-       TextColors = NULL;
+#define iseol(x) ((x) == '\r' || (x) == '\n')
+
+typedef struct colorlist {
+       struct colorlist *next;
+       unsigned char *color;
+} IRCColor;
+
+IRCColor *TextColors = NULL;
+IRCColor *BgColors = NULL;
+
+void ColorPush(unsigned char *color, IRCColor **stack)
+{
+       IRCColor *t = MyMallocEx(sizeof(IRCColor));
+       t->color = strdup(color);
+       t->next = *stack;
+       (*stack) = t;
+}
+
+void ColorPop(IRCColor **stack)
+{
+       IRCColor *p = *stack;
+       if (!(*stack))
+               return;
+       MyFree(p->color);
+       
+       *stack = p->next;
+       MyFree(p);
+}
+
+void ColorEmpty(IRCColor **stack)
+{
+       IRCColor *t, *next;
+       for (t = *stack; t; t = next)
+       {
+               next = t->next;
+               MyFree(t->color);
+               MyFree(t);
+       }
+}
+
+DWORD CALLBACK RTFToIRC(int fd, unsigned char *pbBuff, long cb) 
+{
+       unsigned char *buffer = malloc(cb*2);
+       int colors[17], bold = 0, uline = 0, incolor = 0, inbg = 0;
+       int lastwascf = 0, lastwascf0 = 0;
+       int i = 0;
+       TextColors = BgColors = NULL;
        bzero(buffer, cb);
-       for (; *pbBuff; pbBuff++) {
-               if (*pbBuff == '\r' || *pbBuff == '\n')
-                       continue;
-               if (*pbBuff == '{' || *pbBuff == '}')
+
+       for (; *pbBuff; pbBuff++)
+       {
+               if (iseol(*pbBuff) || *pbBuff == '{' || *pbBuff == '}')
                        continue;
-               if (*pbBuff == '\\') {
+               else if (*pbBuff == '\\')
+               {
+                       /* RTF control sequence */
                        pbBuff++;
-                       if (*pbBuff == '\\') {
-                               buffer[i] = '\\';
-                               i++;
-                               continue;
-                       }
-                       if (*pbBuff == '{') {
-                               buffer[i] = '{';
-                               i++;
-                               continue;
-                       }
-                       if (*pbBuff == '}') {
-                               buffer[i] = '}';
-                               i++;
-                               continue;
-                       }
-                       if (*pbBuff == '\'') {
+                       if (*pbBuff == '\\' || *pbBuff == '{' || *pbBuff == '}')
+                               buffer[i++] = *pbBuff;
+                       else if (*pbBuff == '\'')
+                       {
+                               /* Extended ASCII character */
                                unsigned char ltr, ultr[3];
-                               ultr[0] = *++pbBuff;
-                               ultr[1] = *++pbBuff;
+                               ultr[0] = *(++pbBuff);
+                               ultr[1] = *(++pbBuff);
                                ultr[2] = 0;
                                ltr = strtoul(ultr,NULL,16);
-                               buffer[i] = ltr;
-                               i++;
-                               continue;
+                               buffer[i++] = ltr;
                        }
-                       value[0] = cmd[0] = 0;
-                       for (j = k = start = end = 0;
-                               *pbBuff && *pbBuff != '\\' && *pbBuff != '\r' && *pbBuff != '\n';
-                               pbBuff++) {
-                                       if (*pbBuff == '{') {
-                                               start++;
+                       else
+                       {
+                               int j;
+                               char cmd[128];
+                               /* Capture the control sequence */
+                               for (j = 0; *pbBuff && *pbBuff != '\\' && !isspace(*pbBuff) &&
+                                       !iseol(*pbBuff); pbBuff++)
+                               {
+                                       cmd[j++] = *pbBuff;
+                               }
+                               if (*pbBuff != ' ')
+                                       pbBuff--;
+                               cmd[j] = 0;
+                               if (!strcmp(cmd, "fonttbl{"))
+                               {
+                                       /* Eat the parameter */
+                                       while (*pbBuff && *pbBuff != '}')
                                                pbBuff++;
-                                               for (; *pbBuff; pbBuff++) {
-                                                       if (*pbBuff == '{')
-                                                               start++;
-                                                       if (*pbBuff == '}') {
-                                                               end++;
-                                                               if (start == end) {
-                                                                       pbBuff++;
-                                                                       break;
-                                                               }
-                                                       }
-                                                       value[k] = *pbBuff;
-                                                       k++;
+                                       lastwascf = lastwascf0 = 0;
+                               }
+                               if (!strcmp(cmd, "colortbl"))
+                               {
+                                       char color[128];
+                                       int k = 0, m = 1;
+                                       /* Capture the color table */
+                                       while (*pbBuff && !isalnum(*pbBuff))
+                                               pbBuff++;
+                                       for (; *pbBuff && *pbBuff != '}'; pbBuff++)
+                                       {
+                                               if (*pbBuff == ';')
+                                               {
+                                                       color[k]=0;
+                                                       if (!strcmp(color, "\\red255\\green255\\blue255"))
+                                                               colors[m++] = 0;
+                                                       else if (!strcmp(color, "\\red0\\green0\\blue0"))
+                                                               colors[m++] = 1;
+                                                       else if (!strcmp(color, "\\red0\\green0\\blue127"))
+                                                               colors[m++] = 2;
+                                                       else if (!strcmp(color, "\\red0\\green147\\blue0"))
+                                                               colors[m++] = 3;
+                                                       else if (!strcmp(color, "\\red255\\green0\\blue0"))
+                                                               colors[m++] = 4;
+                                                       else if (!strcmp(color, "\\red127\\green0\\blue0"))
+                                                               colors[m++] = 5;
+                                                       else if (!strcmp(color, "\\red156\\green0\\blue156"))
+                                                               colors[m++] = 6;
+                                                       else if (!strcmp(color, "\\red252\\green127\\blue0"))
+                                                               colors[m++] = 7;
+                                                       else if (!strcmp(color, "\\red255\\green255\\blue0"))
+                                                               colors[m++] = 8;
+                                                       else if (!strcmp(color, "\\red0\\green252\\blue0"))
+                                                               colors[m++] = 9;
+                                                       else if (!strcmp(color, "\\red0\\green147\\blue147"))
+                                                               colors[m++] = 10;
+                                                       else if (!strcmp(color, "\\red0\\green255\\blue255"))
+                                                               colors[m++] = 11;
+                                                       else if (!strcmp(color, "\\red0\\green0\\blue252"))
+                                                               colors[m++] = 12;
+                                                       else if (!strcmp(color, "\\red255\\green0\\blue255"))
+                                                               colors[m++] = 13;
+                                                       else if (!strcmp(color, "\\red127\\green127\\blue127"))
+                                                               colors[m++] = 14;
+                                                       else if (!strcmp(color, "\\red210\\green210\\blue210")) 
+                                                               colors[m++] = 15;
+                                                       k=0;
                                                }
-                                               break;
+                                               else
+                                                       color[k++] = *pbBuff;
                                        }
-                               if (*pbBuff == ' ') {
-                                       pbBuff++;
-                                       break;
+                                       lastwascf = lastwascf0 = 0;
                                }
-
-                                       cmd[j] = *pbBuff;
-                                       j++;
-                       }
-                               cmd[j] = 0;
-                               value[k] = 0;
-                               if (!strcmp(cmd, "par")) {
-                                       if (bold) 
-                                               buffer[i++] = '\2';
-                                       if (uline)
-                                               buffer[i++] = '\37';
-                                       if (incolor)
-                                               buffer[i++] = '\3';
+                               else if (!strcmp(cmd, "tab"))
+                               {
+                                       buffer[i++] = '\t';
+                                       lastwascf = lastwascf0 = 0;
+                               }
+                               else if (!strcmp(cmd, "par"))
+                               {
+                                       if (bold || uline || incolor || inbg)
+                                               buffer[i++] = '\17';
                                        buffer[i++] = '\r';
                                        buffer[i++] = '\n';
+                                       if (!*(pbBuff+3) || *(pbBuff+3) != '}')
+                                       {
                                        if (bold)
                                                buffer[i++] = '\2';
                                        if (uline)
                                                buffer[i++] = '\37';
-                                       if (incolor) {
+                                       if (incolor)
+                                       {
                                                buffer[i++] = '\3';
                                                strcat(buffer, TextColors->color);
                                                i += strlen(TextColors->color);
+                                               if (inbg)
+                                               {
+                                                       buffer[i++] = ',';
+                                                       strcat(buffer, BgColors->color);
+                                                       i += strlen(BgColors->color);
+                                               }
                                        }
+                                       else if (inbg) {
+                                               buffer[i++] = '\3';
+                                               buffer[i++] = '0';
+                                               buffer[i++] = '1';
+                                               buffer[i++] = ',';
+                                               strcat(buffer, BgColors->color);
+                                               i += strlen(BgColors->color);
+                                       }
+}
                                }
-                               else if (!strcmp(cmd, "tab"))
-                                       buffer[i++] = '\t';
-                               else if (!strcmp(cmd, "b")) {
+                               else if (!strcmp(cmd, "b"))
+                               {
                                        bold = 1;
                                        buffer[i++] = '\2';
+                                       lastwascf = lastwascf0 = 0;
                                }
-                               else if (!strcmp(cmd, "b0")) {
+                               else if (!strcmp(cmd, "b0"))
+                               {
                                        bold = 0;
                                        buffer[i++] = '\2';
+                                       lastwascf = lastwascf0 = 0;
                                }
-
-                               else if (!strcmp(cmd, "ul")) { 
+                               else if (!strcmp(cmd, "ul"))
+                               {
                                        uline = 1;
                                        buffer[i++] = '\37';
+                                       lastwascf = lastwascf0 = 0;
                                }
-                               else if (!strcmp(cmd, "ulnone")) {
+                               else if (!strcmp(cmd, "ulnone"))
+                               {
                                        uline = 0;
                                        buffer[i++] = '\37';
+                                       lastwascf = lastwascf0 = 0;
                                }
-                               else if (!strcmp(cmd, "colortbl")) {
-                                       int l = 0, m = 0;
-                                       color[0] = 0;
-                                       pbBuff++;
-                                       for (; *pbBuff && *pbBuff != '}'; pbBuff++) {
-                                               if (*pbBuff != ';') {
-                                                       color[l] = *pbBuff;
-                                                       l++;
-                                               }
-                                               else {
-                                                       color[l] = 0;
-                                                       l = 0;
-                                                       m++;
-                                                       if (!strcmp(color, "\\red255\\green255\\blue255"))
-                                                               colors[m] = 0;
-                                                       else if (!strcmp(color, "\\red0\\green0\\blue0"))
-                                                               colors[m] = 1;
-                                                       else if (!strcmp(color, "\\red0\\green0\\blue127"))
-                                                               colors[m] = 2;
-                                                       else if (!strcmp(color, "\\red0\\green147\\blue0"))
-                                                               colors[m] = 3;
-                                                       else if (!strcmp(color, "\\red255\\green0\\blue0"))
-                                                               colors[m] = 4;
-                                                       else if (!strcmp(color, "\\red127\\green0\\blue0"))
-                                                               colors[m] = 5;
-                                                       else if (!strcmp(color, "\\red156\\green0\\blue156"))
-                                                               colors[m] = 6;
-                                                       else if (!strcmp(color, "\\red252\\green127\\blue0"))
-                                                               colors[m] = 7;
-                                                       else if (!strcmp(color, "\\red255\\green255\\blue0"))
-                                                               colors[m] = 8;
-                                                       else if (!strcmp(color, "\\red0\\green252\\blue0"))
-                                                               colors[m] = 9;
-                                                       else if (!strcmp(color, "\\red0\\green147\\blue147"))
-                                                               colors[m] = 10;
-                                                       else if (!strcmp(color, "\\red0\\green255\\blue255"))
-                                                               colors[m] = 11;
-                                                       else if (!strcmp(color, "\\red0\\green0\\blue252"))
-                                                               colors[m] = 12;
-                                                       else if (!strcmp(color, "\\red255\\green0\\blue255"))
-                                                               colors[m] = 13;
-                                                       else if (!strcmp(color, "\\red127\\green127\\blue127"))
-                                                               colors[m] = 14;
-                                                       else if (!strcmp(color, "\\red210\\green210\\blue210")) 
-                                                               colors[m] = 15;
-                                               }
-                                       }
-                                       pbBuff++;
-                               }
-                               else if (!strcmp(cmd, "f1")) {
-                                       write(fd, buffer, i);
-                                       close(fd);
-                                       return 0;
+                               else if (!strcmp(cmd, "cf0"))
+                               {
+                                       lastwascf0 = 1;
+                                       lastwascf = 0;
                                }
-                               else if (!strcmp(cmd, "cf0")) {
-                                       incolor = 0;
+                               else if (!strcmp(cmd, "highlight0"))
+                               {
+                                       inbg = 0;
+                                       ColorPop(&BgColors);
                                        buffer[i++] = '\3';
-                                       DelNewestColor();
+                                       if (lastwascf0)
+                                       {
+                                               incolor = 0;
+                                               ColorPop(&TextColors);
+                                               lastwascf0 = 0;
+                                       }
+                                       else if (incolor)
+                                       {
+                                               strcat(buffer, TextColors->color);
+                                               i += strlen(TextColors->color);
+                                               buffer[i++] = ',';
+                                               buffer[i++] = '0';
+                                               buffer[i++] = '0';
+                                       }
+                                       lastwascf = lastwascf0 = 0;
                                }
-                               else if (!strncmp(cmd, "cf", 2)) {
+                               else if (!strncmp(cmd, "cf", 2))
+                               {
                                        unsigned char number[3];
-                                       int num = 0;
+                                       int num;
                                        incolor = 1;
                                        strcpy(number, &cmd[2]);
                                        num = atoi(number);
                                        buffer[i++] = '\3';
-                                       sprintf(number, "%d", colors[num]);
-                                       AddColor(number);
+                                       if (colors[num] < 10)
+                                               sprintf(number, "0%d", colors[num]);
+                                       else
+                                               sprintf(number, "%d", colors[num]);
+                                       ColorPush(number, &TextColors);
+                                       strcat(buffer,number);
+                                       i += strlen(number);
+                                       lastwascf = 1;
+                                       lastwascf0 = 0;
+                               }
+                               else if (!strncmp(cmd, "highlight", 9))
+                               {
+                                       int num;
+                                       unsigned char number[3];
+                                       inbg = 1;
+                                       num = atoi(&cmd[9]);
+                                       if (colors[num] < 10)
+                                               sprintf(number, "0%d", colors[num]);
+                                       else
+                                               sprintf(number, "%d", colors[num]);
+                                       if (incolor && !lastwascf)
+                                       {
+                                               buffer[i++] = '\3';
+                                               strcat(buffer, TextColors->color);
+                                               i += strlen(TextColors->color);
+                                       }
+                                       else if (!incolor)
+                                       {
+                                               buffer[i++] = '\3';
+                                               buffer[i++] = '0';
+                                               buffer[i++] = '1';
+                                       }
+                                       buffer[i++] = ',';
                                        strcat(buffer, number);
                                        i += strlen(number);
+                                       ColorPush(number, &BgColors);
+                                       lastwascf = lastwascf0 = 0;
                                }
-                               pbBuff--;
-                               continue;
+                               else
+                                       lastwascf = lastwascf0 = 0;
+
+                               if (lastwascf0 && incolor)
+                               {
+                                       incolor = 0;
+                                       ColorPop(&TextColors);
+                                       buffer[i++] = '\3';
+                               }
+                       }
                }
-               else {
-                       buffer[i] = *pbBuff;
-                       i++;
+               else
+               {
+                       lastwascf = lastwascf0 = 0;
+                       buffer[i++] = *pbBuff;
                }
+                               
        }
        write(fd, buffer, i);
        close(fd);
-       WipeColors();
+       ColorEmpty(&TextColors);
+       ColorEmpty(&BgColors);
        return 0;
 }
 
@@ -490,12 +552,37 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
        if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
                SC_HANDLE hService, hSCManager = OpenSCManager(NULL, NULL, GENERIC_EXECUTE);
                if ((hService = OpenService(hSCManager, "UnrealIRCd", GENERIC_EXECUTE))) {
-                       StartServiceCtrlDispatcher(DispatchTable);
+                       int save_err = 0;
+                       StartServiceCtrlDispatcher(DispatchTable); 
                        if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
-                               StartService(hService, 0, NULL);
+                       { 
+                               SERVICE_STATUS status;
+                               /* Restart handling, it's ugly but it's as 
+                                * pretty as it is gonna get :)
+                                */
+                               if (__argc == 2 && !strcmp(__argv[1], "restartsvc"))
+                               {
+                                       QueryServiceStatus(hService, &status);
+                                       if (status.dwCurrentState != SERVICE_STOPPED)
+                                       {
+                                               ControlService(hService,
+                                                       SERVICE_CONTROL_STOP, &status);
+                                               while (status.dwCurrentState == SERVICE_STOP_PENDING)
+                                               {
+                                                       QueryServiceStatus(hService, &status);
+                                                       if (status.dwCurrentState != SERVICE_STOPPED)
+                                                               Sleep(1000);
+                                               }
+                                       }
+                               }
+                               if (!StartService(hService, 0, NULL))
+                                       save_err = GetLastError();
+                       }
+
                        CloseServiceHandle(hService);
                        CloseServiceHandle(hSCManager);
-                       exit(0);
+                       if (save_err != ERROR_SERVICE_DISABLED)
+                               exit(0);
                }
        }
        strcpy(OSName, "Windows ");
@@ -526,7 +613,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
                        else if (VerInfo.dwMinorVersion == 1) 
                                strcat(OSName, "XP ");
                        else if (VerInfo.dwMinorVersion == 2)
-                               strcat(OSName, ".NET Server ");
+                               strcat(OSName, "Server 2003 ");
                }
                strcat(OSName, VerInfo.szCSDVersion);
        }
@@ -534,6 +621,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
                OSName[strlen(OSName)-1] = 0;
        InitCommonControls();
        WM_TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");
+       WM_FINDMSGSTRING = RegisterWindowMessage(FINDMSGSTRING);
        atexit(CleanUp);
        if(!LoadLibrary("riched20.dll"))
                LoadLibrary("riched32.dll");
@@ -655,6 +743,7 @@ static HMENU hRehash, hAbout, hConfig, hTray, hLogs;
                                                }
 
                                                AppendMenu(hConfig, MF_STRING, IDM_MOTD, MPATH);
+                                               AppendMenu(hConfig, MF_STRING, IDM_SMOTD, SMPATH);
                                                AppendMenu(hConfig, MF_STRING, IDM_OPERMOTD, OPATH);
                                                AppendMenu(hConfig, MF_STRING, IDM_BOTMOTD, BPATH);
                                                AppendMenu(hConfig, MF_STRING, IDM_RULES, RPATH);
@@ -667,6 +756,8 @@ static HMENU hRehash, hAbout, hConfig, hTray, hLogs;
                                                                        AppendMenu(hConfig, MF_STRING, i++, tlds->motd_file);
                                                                if (!tlds->flag.rulesptr)
                                                                        AppendMenu(hConfig, MF_STRING, i++, tlds->rules_file);
+                                                               if (tlds->smotd_file)
+                                                                       AppendMenu(hConfig, MF_STRING, i++, tlds->smotd_file);
                                                        }
                                                }
                                                AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
@@ -740,6 +831,7 @@ static HMENU hRehash, hAbout, hConfig, hTray, hLogs;
                                }
 
                                AppendMenu(hConfig, MF_STRING, IDM_MOTD, MPATH);
+                               AppendMenu(hConfig, MF_STRING, IDM_SMOTD, SMPATH);
                                AppendMenu(hConfig, MF_STRING, IDM_OPERMOTD, OPATH);
                                AppendMenu(hConfig, MF_STRING, IDM_BOTMOTD, BPATH);
                                AppendMenu(hConfig, MF_STRING, IDM_RULES, RPATH);
@@ -752,6 +844,8 @@ static HMENU hRehash, hAbout, hConfig, hTray, hLogs;
                                                        AppendMenu(hConfig, MF_STRING, i++, tlds->motd_file);
                                                if (!tlds->flag.rulesptr)
                                                        AppendMenu(hConfig, MF_STRING, i++, tlds->rules_file);
+                                               if (tlds->smotd_file)
+                                                       AppendMenu(hConfig, MF_STRING, i++, tlds->smotd_file);
                                        }
                                }
                                AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
@@ -853,6 +947,10 @@ static HMENU hRehash, hAbout, hConfig, hTray, hLogs;
                                                DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG, 
                                                        (LPARAM)MPATH);
                                                break;
+                                       case IDM_SMOTD:
+                                               DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG, 
+                                                       (LPARAM)SMPATH);
+                                               break;
                                        case IDM_OPERMOTD:
                                                DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
                                                        (LPARAM)OPATH);
@@ -983,7 +1081,7 @@ LRESULT CALLBACK FromFileReadDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM
                                /* Only allocate the amount we need */
                                buffer = malloc(sb.st_size+1);
                                buffer[0] = 0;
-                               len = read(fd, buffer, sb.st_size);
+                               len = read(fd, buffer, sb.st_size); 
                                buffer[len] = 0;
                                len = CountRTFSize(buffer)+1;
                                string = malloc(len);
@@ -1124,21 +1222,27 @@ HWND DrawToolbar(HWND hwndParent, UINT iID) {
                { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, 0}
        };
                
-       TBBUTTON tbAddButtons[3] = {
+       TBBUTTON tbAddButtons[7] = {
                { 0, IDC_BOLD, TBSTATE_ENABLED, TBSTYLE_CHECK, {0}, 0L, 0},
                { 1, IDC_UNDERLINE, TBSTATE_ENABLED, TBSTYLE_CHECK, {0}, 0L, 0},
-               { 2, IDC_COLOR, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0}
+               { 2, IDC_COLOR, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
+               { 3, IDC_BGCOLOR, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
+               { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, 0},
+               { 4, IDC_GOTO, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
+               { STD_FIND, IDC_FIND, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0}
        };
        hTool = CreateToolbarEx(hwndParent, WS_VISIBLE|WS_CHILD|TBSTYLE_FLAT|TBSTYLE_TOOLTIPS, 
                                IDC_TOOLBAR, 0, HINST_COMMCTRL, IDB_STD_SMALL_COLOR,
                                tbButtons, 10, 0,0,100,30, sizeof(TBBUTTON));
        tbBit.hInst = hInst;
        tbBit.nID = IDB_BITMAP1;
-       newidx = SendMessage(hTool, TB_ADDBITMAP, (WPARAM)3, (LPARAM)&tbBit);
+       newidx = SendMessage(hTool, TB_ADDBITMAP, (WPARAM)5, (LPARAM)&tbBit);
        tbAddButtons[0].iBitmap += newidx;
        tbAddButtons[1].iBitmap += newidx;
        tbAddButtons[2].iBitmap += newidx;
-       SendMessage(hTool, TB_ADDBUTTONS, (WPARAM)3, (LPARAM)&tbAddButtons);
+       tbAddButtons[3].iBitmap += newidx;
+       tbAddButtons[5].iBitmap += newidx;
+       SendMessage(hTool, TB_ADDBUTTONS, (WPARAM)7, (LPARAM)&tbAddButtons);
        return hTool;
 }
 
@@ -1182,9 +1286,55 @@ LRESULT CALLBACK GotoDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 LRESULT CALLBACK FromFileDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
        HWND hWnd;
        static FINDREPLACE find;
+       static char findbuf[256];
        static unsigned char *file;
        static HWND hTool, hClip, hStatus;
+       static RECT rOld;
        CHARFORMAT2 chars;
+
+       if (message == WM_FINDMSGSTRING)
+       {
+               FINDREPLACE *fr = (FINDREPLACE *)lParam;
+
+               if (fr->Flags & FR_FINDNEXT)
+               {
+                       HWND hRich = GetDlgItem(hDlg, IDC_TEXT);
+                       DWORD flags=0;
+                       FINDTEXTEX ft;
+                       CHARRANGE chrg;
+
+                       if (fr->Flags & FR_DOWN)
+                               flags |= FR_DOWN;
+                       if (fr->Flags & FR_MATCHCASE)
+                               flags |= FR_MATCHCASE;
+                       if (fr->Flags & FR_WHOLEWORD)
+                               flags |= FR_WHOLEWORD;
+                       ft.lpstrText = fr->lpstrFindWhat;
+                       SendMessage(hRich, EM_EXGETSEL, 0, (LPARAM)&chrg);
+                       if (flags & FR_DOWN)
+                       {
+                               ft.chrg.cpMin = chrg.cpMax;
+                               ft.chrg.cpMax = -1;
+                       }
+                       else
+                       {
+                               ft.chrg.cpMin = chrg.cpMin;
+                               ft.chrg.cpMax = -1;
+                       }
+                       if (SendMessage(hRich, EM_FINDTEXTEX, flags, (LPARAM)&ft) == -1)
+                       {
+                               MessageBox(NULL, "Unreal has finished searching the document",
+                                       "Find", MB_ICONINFORMATION|MB_OK);
+                       }
+                       else
+                       {
+                               SendMessage(hRich, EM_EXSETSEL, 0, (LPARAM)&(ft.chrgText));
+                               SendMessage(hRich, EM_SCROLLCARET, 0, 0);
+                               SetFocus(hRich);
+                       }
+               }
+               return TRUE;
+       }
        switch (message) {
                case WM_INITDIALOG: {
                        int fd,len;
@@ -1245,6 +1395,38 @@ LRESULT CALLBACK FromFileDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPar
                        }
                        return (TRUE);
                        }
+               case WM_WINDOWPOSCHANGING:
+               {
+                       GetClientRect(hDlg, &rOld);
+                       return FALSE;
+               }
+               case WM_SIZE:
+               {
+                       DWORD new_width, new_height;
+                       HWND hRich;
+                       RECT rOldRich;
+                       DWORD old_width, old_height;
+                       DWORD old_rich_width, old_rich_height;
+                       if (hDlg == hFind)
+                               return FALSE;
+                       new_width =  LOWORD(lParam);
+                       new_height = HIWORD(lParam);
+                       hRich  = GetDlgItem(hDlg, IDC_TEXT);
+                       SendMessage(hStatus, WM_SIZE, 0, 0);
+                       SendMessage(hTool, TB_AUTOSIZE, 0, 0);
+                       old_width = rOld.right-rOld.left;
+                       old_height = rOld.bottom-rOld.top;
+                       new_width = new_width - old_width;
+                       new_height = new_height - old_height;
+                       GetWindowRect(hRich, &rOldRich);
+                       old_rich_width = rOldRich.right-rOldRich.left;
+                       old_rich_height = rOldRich.bottom-rOldRich.top;
+                       SetWindowPos(hRich, NULL, 0, 0, old_rich_width+new_width, 
+                               old_rich_height+new_height,
+                               SWP_NOMOVE|SWP_NOREPOSITION|SWP_NOZORDER);
+                       bzero(&rOld, sizeof(RECT));
+                       return TRUE;
+               }
                case WM_NOTIFY:
                        switch (((NMHDR *)lParam)->code) {
                                case EN_SELCHANGE: {
@@ -1323,6 +1505,15 @@ LRESULT CALLBACK FromFileDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPar
                                        case IDC_COLOR:
                                                strcpy(lpttt->szText, "Text Color");
                                                break;
+                                       case IDC_BGCOLOR:
+                                               strcpy(lpttt->szText, "Background Color");
+                                               break;
+                                       case IDC_GOTO:
+                                               strcpy(lpttt->szText, "Goto");
+                                               break;
+                                       case IDC_FIND:
+                                               strcpy(lpttt->szText, "Find");
+                                               break;
                                }
                                return (TRUE);
                        }
@@ -1374,7 +1565,32 @@ LRESULT CALLBACK FromFileDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPar
                                return TRUE;
                        }
                        if (LOWORD(wParam) == IDC_COLOR) 
+                       {
                                DialogBoxParam(hInst, "Color", hDlg, (DLGPROC)ColorDLG, (LPARAM)WM_USER+10);
+                               return 0;
+                       }
+                       if (LOWORD(wParam) == IDC_BGCOLOR)
+                       {
+                               DialogBoxParam(hInst, "Color", hDlg, (DLGPROC)ColorDLG, (LPARAM)WM_USER+11);
+                               return 0;
+                       }
+                       if (LOWORD(wParam) == IDC_GOTO)
+                       {
+                               DialogBox(hInst, "GOTO", hDlg, (DLGPROC)GotoDLG);
+                               return 0;
+                       }
+                       if (LOWORD(wParam) == IDC_FIND)
+                       {
+                               static FINDREPLACE fr;
+                               bzero(&fr, sizeof(FINDREPLACE));
+                               fr.lStructSize = sizeof(FINDREPLACE);
+                               fr.hwndOwner = hDlg;
+                               fr.lpstrFindWhat = findbuf;
+                               fr.wFindWhatLen = 255;
+                               hFind = FindText(&fr);
+                               return 0;
+                       }
+                               
                hWnd = GetDlgItem(hDlg, IDC_TEXT);
                if (LOWORD(wParam) == IDM_COPY) {
                        SendMessage(hWnd, WM_COPY, 0, 0);
@@ -1480,6 +1696,17 @@ LRESULT CALLBACK FromFileDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPar
                        SetFocus(hWnd);
                        break;
                }
+               case WM_USER+11: {
+                       HWND hWnd = GetDlgItem(hDlg, IDC_TEXT);
+                       EndDialog((HWND)lParam, TRUE);
+                       chars.cbSize = sizeof(CHARFORMAT2);
+                       chars.dwMask = CFM_BACKCOLOR;
+                       chars.crBackColor = (COLORREF)wParam;
+                       SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
+                       SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
+                       SetFocus(hWnd);
+                       break;
+               }
                case WM_CHANGECBCHAIN:
                        if ((HWND)wParam == hClip)
                                hClip = (HWND)lParam;
@@ -1510,6 +1737,7 @@ LRESULT CALLBACK FromFileDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPar
                        }
                        else
                                EndDialog(hDlg, TRUE);
+                       break;
                }
                case WM_DESTROY:
                        ChangeClipboardChain(hDlg, hClip);
@@ -1721,169 +1949,406 @@ LRESULT CALLBACK ColorDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 /* find how big a buffer expansion we need for RTF transformation */
 int CountRTFSize(unsigned char *buffer) {
        int size = 0;
-       short bold = 0, uline = 0, reverse = 0;
-       unsigned char *buf = buffer;
+       char bold = 0, uline = 0, incolor = 0, inbg = 0, reverse = 0;
+       char *buf = buffer;
 
-       for (; *buf; buf++, size++) {
-               if (*buf == '{' || *buf == '}' || *buf == '\\') {
+       for (; *buf; buf++) 
+       {
+               if (*buf == '{' || *buf == '}' || *buf == '\\')
                        size++;
-                       continue;
-               }
-               if (*buf == '\r') {
-                       buf++;
-                       if (*buf == '\n')
-                               size += 5;
+               else if (*buf == '\r')
+               {
+                       if (*(buf+1) && *(buf+1) == '\n')
+                       {
+                               buf++;
+                               if (bold)
+                                       size += 3;
+                               if (uline)
+                                       size += 7;
+                               if (incolor && !reverse)
+                                       size += 4;
+                               if (inbg && !reverse)
+                                       size += 11;
+                               if (reverse)
+                                       size += 15;
+                               if (bold || uline || incolor || inbg || reverse)
+                                       size++;
+                               bold = uline = incolor = inbg = reverse = 0;
+                               size +=6;
+                               continue;
+                       }
                }
-               if (*buf == '\2') {
-                       if (bold) 
+               else if (*buf == '\2')
+               {
+                       if (bold)
+                               size += 4;
+                       else
                                size += 3;
-                       else  
-                               size += 2;
-                       bold = ~bold;
+                       bold = !bold;
+                       continue;
                }
-               if (*buf == '\3') {
-                       unsigned char color[3];
-                       int number;
+               else if (*buf == '\3' && reverse)
+               {
+                       if (*(buf+1) && isdigit(*(buf+1)))
+                       {
+                               ++buf;
+                               if (*(buf+1) && isdigit(*(buf+1)))
+                                       ++buf;
+                               if (*(buf+1) && *(buf+1) == ',')
+                               {
+                                       if (*(buf+2) && isdigit(*(buf+2)))
+                                       {
+                                               buf+=2;
+                                               if (*(buf+1) && isdigit(*(buf+1)))
+                                                       ++buf;
+                                       }
+                               }
+                       }
+                       continue;
+               }
+               else if (*buf == '\3' && !reverse)
+               {
                        size += 3;
-                       if (!isdigit(*(buf+1)))
-                               size += 12;
-                       if (isdigit(*(buf+1))) {
+                       if (*(buf+1) && !isdigit(*(buf+1)))
+                       {
+                               incolor = 0;
+                               size++;
+                               if (inbg)
+                               {
+                                       inbg = 0;
+                                       size += 11;
+                               }
+                       }
+                       else if (*(buf+1))
+                       {
+                               unsigned char color[3];
+                               int number;
                                color[0] = *(++buf);
                                color[1] = 0;
-                               if (isdigit(*(buf+1)))
+                               if (*(buf+1) && isdigit(*(buf+1)))
                                        color[1] = *(++buf);
                                color[2] = 0;
                                number = atoi(color);
-                               if (number > 15 && number != 99)
-                                       number %= 16;
-                               if (number > 9)
+                               if (number == 99 || number == 1) 
                                        size += 2;
-                               else
+                               else if (number == 0) 
                                        size++;
+                               else  {
+                                       number %= 16;
+                                       _itoa(number, color, 10);
+                                       size += strlen(color);
+                               }
+                               color[2] = 0;
+                               number = atoi(color);
+                               if (*(buf+1) && *(buf+1) == ',')
+                               {
+                                       if (*(buf+2) && isdigit(*(buf+2)))
+                                       {
+                                               size += 10;
+                                               buf++;
+                                               color[0] = *(++buf);
+                                               color[1] = 0;
+                                               if (*(buf+1) && isdigit(*(buf+1)))
+                                                       color[1] = *(++buf);
+                                               color[2] = 0;
+                                               number = atoi(color);
+                                               if (number == 1)
+                                                       size += 2;
+                                               else if (number == 0 || number == 99)
+                                                       size++;
+                                               else
+                                               {
+                                                       number %= 16;
+                                                       _itoa(number, color, 10);
+                                                       size += strlen(color);
+                                               }
+                                               inbg = 1;
+                                       }
+                               }
+                               incolor = 1;
                        }
+                       size++;
+                       continue;
                }
-
-               if (*buf == '\37') {
+               else if (*buf == '\17')
+               {
+                       if (bold)
+                               size += 3;
                        if (uline)
                                size += 7;
+                       if (incolor && !reverse)
+                               size += 4;
+                       if (inbg && !reverse)
+                               size += 11;
+                       if (reverse)
+                               size += 15;
+                       if (bold || uline || incolor || inbg || reverse)
+                               size++;
+                       bold = uline = incolor = inbg = reverse = 0;
+                       continue;
+               }
+               else if (*buf == '\26')
+               {
+                       if (reverse)
+                               size += 16;
                        else
-                               size += 3;
-                       uline = ~uline;
+                               size += 17;
+                       reverse = !reverse;
+                       continue;
                }
-               if (*buf == '\17') {
+               else if (*buf == '\37')
+               {
                        if (uline)
-                               size += 7;
-                       if (bold)
-                               size += 3;
-                       uline = bold = 0;
+                               size += 8;
+                       else
+                               size += 4;
+                       uline = !uline;
+                       continue;
                }
-       }
-       return (size+494);
+               size++;
+       }                       
+       size+=strlen("{\\rtf1\\ansi\\ansicpg1252\\deff0{\\fonttbl{\\f0\\fmodern\\fprq1\\"
+               "fcharset0 Fixedsys;}}\r\n"
+               MIRC_COLORS
+               "\\viewkind4\\uc1\\pard\\lang1033\\f0\\fs20")+1;
+       return (size);
 }
 
 void IRCToRTF(unsigned char *buffer, unsigned char *string) {
-       unsigned char *tmp = buffer;
+       unsigned char *tmp;
        int i = 0;
-       short bold = 0, uline = 0;
+       short bold = 0, uline = 0, incolor = 0, inbg = 0, reverse = 0;
        sprintf(string, "{\\rtf1\\ansi\\ansicpg1252\\deff0{\\fonttbl{\\f0\\fmodern\\fprq1\\"
                "fcharset0 Fixedsys;}}\r\n"
                MIRC_COLORS
                "\\viewkind4\\uc1\\pard\\lang1033\\f0\\fs20");
-       i = 487;
-       for (tmp; *tmp; tmp++, i++) {
-               if (*tmp == '{') {
+       i = strlen(string);
+       for (tmp = buffer; *tmp; tmp++)
+       {
+               if (*tmp == '{')
+               {
                        strcat(string, "\\{");
-                       i++;
+                       i+=2;
                        continue;
                }
-               if (*tmp == '}') {
+               else if (*tmp == '}')
+               {
                        strcat(string, "\\}");
-                       i++;
+                       i+=2;
                        continue;
                }
-               if (*tmp == '\\') {
+               else if (*tmp == '\\')
+               {
                        strcat(string, "\\\\");
-                       i++;
+                       i+=2;
                        continue;
                }
-               if (*tmp == '\r') {
-                       tmp++;
-                       if (*tmp == '\n') {
+               else if (*tmp == '\r')
+               {
+                       if (*(tmp+1) && *(tmp+1) == '\n')
+                       {
+                               tmp++;
+                               if (bold)
+                               {
+                                       strcat(string, "\\b0 ");
+                                       i+=3;
+                               }
+                               if (uline)
+                               {
+                                       strcat(string, "\\ulnone");
+                                       i+=7;
+                               }
+                               if (incolor && !reverse)
+                               {
+                                       strcat(string, "\\cf0");
+                                       i+=4;
+                               }
+                               if (inbg && !reverse)
+                               {
+                                       strcat(string, "\\highlight0");
+                                       i +=11;
+                               }
+                               if (reverse) {
+                                       strcat(string, "\\cf0\\highlight0");
+                                       i += 15;
+                               }
+                               if (bold || uline || incolor || inbg || reverse)
+                                       string[i++] = ' ';
+                               bold = uline = incolor = inbg = reverse = 0;
                                strcat(string, "\\par\r\n");
-                               i += 5;
-                               continue;
+                               i +=6;
                        }
+                       else
+                               string[i++]='\r';
+                       continue;
                }
-               if (*tmp == '\2') {
-                       if (bold) {
+               else if (*tmp == '\2')
+               {
+                       if (bold)
+                       {
                                strcat(string, "\\b0 ");
-                               i += 3;
+                               i+=4;
                        }
-                       else {
+                       else
+                       {
                                strcat(string, "\\b ");
-                               i += 2;
+                               i+=3;
+                       }
+                       bold = !bold;
+                       continue;
+               }
+               else if (*tmp == '\3' && reverse)
+               {
+                       if (*(tmp+1) && isdigit(*(tmp+1)))
+                       {
+                               ++tmp;
+                               if (*(tmp+1) && isdigit(*(tmp+1)))
+                                       ++tmp;
+                               if (*(tmp+1) && *(tmp+1) == ',')
+                               {
+                                       if (*(tmp+2) && isdigit(*(tmp+2)))
+                                       {
+                                               tmp+=2;
+                                               if (*(tmp+1) && isdigit(*(tmp+1)))
+                                                       ++tmp;
+                                       }
+                               }
                        }
-                       bold = ~bold;
                        continue;
                }
-               if (*tmp == '\3') {
-                       unsigned char color[3];
-                       int number;
+               else if (*tmp == '\3' && !reverse)
+               {
                        strcat(string, "\\cf");
                        i += 3;
-                       if (!isdigit(*(tmp+1))) {
-                               strcat(string, "0");
-                               i++;
+                       if (*(tmp+1) && !isdigit(*(tmp+1)))
+                       {
+                               incolor = 0;
+                               string[i++] = '0';
+                               if (inbg)
+                               {
+                                       inbg = 0;
+                                       strcat(string, "\\highlight0");
+                                       i += 11;
+                               }
                        }
-                       else {
+                       else if (*(tmp+1))
+                       {
+                               unsigned char color[3];
+                               int number;
                                color[0] = *(++tmp);
                                color[1] = 0;
-                               if (isdigit(*(tmp+1)))
+                               if (*(tmp+1) && isdigit(*(tmp+1)))
                                        color[1] = *(++tmp);
                                color[2] = 0;
                                number = atoi(color);
-                               if (number == 99 || number == 1) {
-                                       strcat(string, "16");
+                               if (number == 99 || number == 1)
+                               {
+                                       strcat(string, "16"); 
                                        i += 2;
                                }
-                               else if (number == 0) {
-                                       string[i] = '1';
+                               else if (number == 0) 
+                               {
+                                       strcat(string, "1");
                                        i++;
                                }
-                               else {
+                               else
+                               {
                                        number %= 16;
                                        _itoa(number, color, 10);
                                        strcat(string, color);
                                        i += strlen(color);
                                }
+                               if (*(tmp+1) && *(tmp+1) == ',')
+                               {
+                                       if (*(tmp+2) && isdigit(*(tmp+2)))
+                                       {
+                                               strcat(string, "\\highlight");
+                                               i += 10;
+                                               tmp++;
+                                               color[0] = *(++tmp);
+                                               color[1] = 0;
+                                               if (*(tmp+1) && isdigit(*(tmp+1)))
+                                                       color[1] = *(++tmp);
+                                               color[2] = 0;
+                                               number = atoi(color);
+                                               if (number == 1)
+                                               {
+                                                       strcat(string, "16");
+                                                       i += 2;
+                                               }
+                                               else if (number == 0 || number == 99)
+                                                       string[i++] = '1';
+                                               else
+                                               {
+                                                       number %= 16;
+                                                       _itoa(number, color, 10);
+                                                       strcat(string,color);
+                                                       i += strlen(color);
+                                               }
+                                               inbg = 1;
+                                       }
+                               }
+                               incolor=1;
                        }
-                       string[i] = ' ';
+                       string[i++] = ' ';
                        continue;
                }
-               if (*tmp == '\37') {
+               else if (*tmp == '\17') {
                        if (uline) {
-                               strcat(string, "\\ulnone ");
+                               strcat(string, "\\ulnone");
                                i += 7;
                        }
-                       else {
-                               strcat(string, "\\ul ");
+                       if (bold) {
+                               strcat(string, "\\b0");
                                i += 3;
                        }
-                       uline = ~uline;
+                       if (incolor && !reverse) {
+                               strcat(string, "\\cf0");
+                               i += 4;
+                       }
+                       if (inbg && !reverse)
+                       {
+                               strcat(string, "\\highlight0");
+                               i += 11;
+                       }
+                       if (reverse) {
+                               strcat(string, "\\cf0\\highlight0");
+                               i += 15;
+                       }
+                       if (uline || bold || incolor || inbg || reverse)
+                               string[i++] = ' ';
+                       uline = bold = incolor = inbg = reverse = 0;
+                       continue;
+               }
+               else if (*tmp == '\26')
+               {
+                       if (reverse)
+                       {
+                               strcat(string, "\\cf0\\highlight0 ");
+                               i += 16;
+                       }
+                       else
+                       {
+                               strcat(string, "\\cf1\\highlight16 ");
+                               i += 17;
+                       }
+                       reverse = !reverse;
                        continue;
                }
-               if (*tmp == '\17') {
+
+               else if (*tmp == '\37') {
                        if (uline) {
                                strcat(string, "\\ulnone ");
-                               i += 7;
+                               i += 8;
                        }
-                       if (bold) {
-                               strcat(string, "\\b0 ");
-                               i += 3;
+                       else {
+                               strcat(string, "\\ul ");
+                               i += 4;
                        }
-                       uline = bold = 0;
+                       uline = !uline;
+                       continue;
                }
-               string[i] = *tmp;
+               string[i++] = *tmp;
        }
        strcat(string, "}");
        return;
index 8b8346963942e05959690287138d222866e4d0e0..50f7528d66912a9c08be14aae64da5f025844766 100644 (file)
@@ -43,7 +43,7 @@ END
 
 FROMVAR DIALOG DISCARDABLE  0, 0, 418, 183
 STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP | WS_VISIBLE | 
-    WS_CAPTION | WS_SYSMENU
+    WS_CAPTION | WS_SYSMENU 
 CAPTION "UnrealIRCd License"
 FONT 8, "MS Sans Serif"
 BEGIN
@@ -74,7 +74,7 @@ END
 
 FROMFILE DIALOG DISCARDABLE  0, 0, 418, 224
 STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP | WS_VISIBLE | 
-    WS_CAPTION | WS_SYSMENU
+    WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX
 CAPTION "UnrealIRCd Configuration File"
 FONT 8, "MS Sans Serif"
 BEGIN
diff --git a/src/win32/gnu_regex.dll b/src/win32/gnu_regex.dll
deleted file mode 100644 (file)
index e5d929f..0000000
Binary files a/src/win32/gnu_regex.dll and /dev/null differ
diff --git a/src/win32/gnu_regex.lib b/src/win32/gnu_regex.lib
deleted file mode 100644 (file)
index ff6054b..0000000
Binary files a/src/win32/gnu_regex.lib and /dev/null differ
index cddac25667a13319f2a25cc0a07c18f96b0128e6..26b12fa9e1d95c1b7405873af97a70bfd92425d8 100644 (file)
@@ -44,6 +44,7 @@
 #define IDC_DIRUP                       1139
 #define IDC_DIRDOWN                     1140
 #define IDC_COLOR                       1141
+#define IDC_BGCOLOR                    1142
 #define IDC_WHITE                       1163
 #define IDC_BLACK                       1164
 #define IDC_DARKBLUE                    1165
@@ -67,6 +68,7 @@
 #define IDM_HELP                        40030
 #define IDM_SAVE                        40031
 #define IDM_REDO                        40032
+#define IDM_SMOTD                      40036
 #define IDM_CONF                        40037
 #define IDM_MOTD                        40038
 #define IDM_BOTMOTD                     40039
index 7d5c3d60dadf8f5b8e06ba9d24564f58b1969dde..9e50220fff3cb8b36153e23745e4d07d19d1a278 100644 (file)
@@ -26,8 +26,8 @@
 #include "version.h"
 #include <string.h>
 
-static SERVICE_STATUS IRCDStatus; 
-static SERVICE_STATUS_HANDLE IRCDStatusHandle; 
+SERVICE_STATUS IRCDStatus; 
+SERVICE_STATUS_HANDLE IRCDStatusHandle; 
 #define IRCD_SERVICE_CONTROL_REHASH 128
 
 BOOL IsService = FALSE;
@@ -116,13 +116,13 @@ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
                        else if (VerInfo.dwMinorVersion == 1)
                                strcat(OSName, "XP ");
                        else if (VerInfo.dwMinorVersion == 2)
-                               strcat(OSName, ".NET Server ");
+                               strcat(OSName, "Server 2003 ");
                }
                strcat(OSName, VerInfo.szCSDVersion);
        }
        if (OSName[strlen(OSName)-1] == ' ')
                OSName[strlen(OSName)-1] = 0;
-
+       InitDebug();
        if ((error = WSAStartup(MAKEWORD(1, 1), &WSAData)) != 0) {
                IRCDStatus.dwCurrentState = SERVICE_STOPPED;
                IRCDStatus.dwCheckPoint = 0;
@@ -141,11 +141,9 @@ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
                SetServiceStatus(IRCDStatusHandle, &IRCDStatus); 
                return;
        }       
-
        IRCDStatus.dwCurrentState = SERVICE_RUNNING;
        IRCDStatus.dwCheckPoint = 0;
        IRCDStatus.dwWaitHint = 0;  
-
        SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
 
        SocketLoop(0);
index 947a23199b8021ca615a97ac559f98fe31bfd50d..aa29ec685317c948dfa18604f9c1719d86a6c2f9 100644 (file)
Binary files a/src/win32/toolbar.bmp and b/src/win32/toolbar.bmp differ
diff --git a/src/win32/tre.dll b/src/win32/tre.dll
new file mode 100644 (file)
index 0000000..ac6679c
Binary files /dev/null and b/src/win32/tre.dll differ
diff --git a/src/win32/tre.lib b/src/win32/tre.lib
new file mode 100644 (file)
index 0000000..fcfe4b0
Binary files /dev/null and b/src/win32/tre.lib differ
index 873016d73253a6544edfd0e69b10a7942cddc3b9..13d0dffda16d29bb6beb299555993a42f8c9ac93 100644 (file)
@@ -3,13 +3,13 @@
 
 ; #define USE_SSL
 ; Uncomment the above line to package an SSL build
-#define USE_ZIP
+#define USE_ZIP
 ; Uncomment the above line to package with ZIP support
 
 
 [Setup]
 AppName=UnrealIRCd
-AppVerName=UnrealIRCd3.2-beta17
+AppVerName=UnrealIRCd3.2-beta18
 AppPublisher=UnrealIRCd Team
 AppPublisherURL=http://www.unrealircd.com
 AppSupportURL=http://www.unrealircd.com
@@ -51,7 +51,6 @@ Source: "..\..\badwords.message.conf"; DestDir: "{app}"; Flags: ignoreversion
 Source: "..\..\Changes"; DestDir: "{app}"; DestName: "Changes.txt"; Flags: ignoreversion
 Source: "..\..\Changes.old"; DestDir: "{app}"; DestName: "Changes.old.txt"; Flags: ignoreversion
 Source: "..\..\Donation"; DestDir: "{app}"; DestName: "Donation.txt"; Flags: ignoreversion
-Source: ".\gnu_regex.dll"; DestDir: "{app}"; Flags: ignoreversion
 Source: "..\..\help.conf"; DestDir: "{app}"; Flags: ignoreversion
 Source: "..\..\LICENSE"; DestDir: "{app}"; DestName: "LICENSE.txt"; Flags: ignoreversion
 Source: "..\..\Unreal.nfo"; DestDir: "{app}"; Flags: ignoreversion
@@ -59,6 +58,7 @@ Source: "..\..\doc\*.*"; DestDir: "{app}\doc"; Flags: ignoreversion
 Source: "..\..\aliases\*"; DestDir: "{app}\aliases"; Flags: ignoreversion
 Source: "..\..\networks\*"; DestDir: "{app}\networks"; Flags: ignoreversion
 Source: "..\..\unreal.exe"; DestDir: "{app}"; Flags: ignoreversion; MinVersion: 0,4.0
+Source: "tre.dll"; DestDir: "{app}"; Flags: ignoreversion
 #ifdef USE_SSL
 Source: "c:\openssl\bin\openssl.exe"; DestDir: "{app}"; Flags: ignoreversion
 Source: "c:\openssl\bin\ssleay32.dll"; DestDir: "{app}"; Flags: ignoreversion
diff --git a/update b/update
index 3f1dcb6665e3128e4cc5fa32d6ee13fe6a6efec5..a1dfb29563b1e69b161baa88d4381ae78d9f3cc4 100755 (executable)
--- a/update
+++ b/update
@@ -7,6 +7,12 @@
 # or included in any package without permission from the author.
 #
 # NO WARRANTY IS INCLUDED
+
+# TEMP added by Syzop till the new updater thing is finished.
+echo "Please see doc/unreal32docs.html section 1.2 (\"Notes on upgrading between 3.2 versions\")."
+exit 1
+# ORIGINAL CODE FOLLOWS:
+
 CURRENT_VERSION="Unreal3.2-beta12"
 WHATYAWANT="wget"
 clear