\___/|_| |_|_| \___|\__,_|_|\___/\_| \_| \____/\__,_|
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.
-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
echo Modules:\n
echo ----------------------\n
dumparray Modules 50
-quit
\ No newline at end of file
+quit
- 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'
'CRYPTOINCLUDES=${CRYPTOINCLUDES}'
custommodule:
- cd src; ${MAKE} ${MAKEARGS} MODULEFILE=${MODULEFILE} EXLIBS=${EXLIBS} custommodule
+ cd src; ${MAKE} ${MAKEARGS} MODULEFILE=${MODULEFILE} 'EXLIBS=${EXLIBS}' custommodule
server:
build:
--- /dev/null
+==[ 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.
===============================================
-= UnrealIRCd v3.2 (beta17) =
+= UnrealIRCd v3.2 (beta18) =
===============================================
Was brought to you by:
IRCDLIBS="$IRCDLIBS -lresolv "
;;
esac
+
dnl AC_MSG_RESULT(configuring TRE regex library)
dnl cur_dir=`pwd`
dnl cd extras/tre
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
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
"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;}
fi
chmod 0700 unreal
+chmod 0700 ircdcron/ircdchk
* 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 */
/*
* 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)";
stats-server "stats.roxnet.org";
help-channel "#ROXnet";
hiddenhost-prefix "rox";
- prefix-quit "no";
+ /* prefix-quit "no"; */
cloak-keys {
9666;
3333;
/* 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!
*/
<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
-- 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 –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. – 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 – Notes on upgrading/mixing 3.1.x -> 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>
<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>
<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 -> modules
or use google to find 3rd party modules.</p>
<p>Note that you need to load at least the commands module!</p></div>
<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>
<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<->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> </td></tr>
+<tr><td>j</td><td>joins</td><td>auto +i</td><td>R</td><td> </td></tr>
+<tr><td>k</td><td>knocks</td><td>auto +K</td><td> </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> </td></tr>
+<tr><td>n</td><td>nickchanges</td><td>auto +N</td><td> </td><td> </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 />
+Example:
+<pre>
+<font color=green>*** ChanOp sets mode: +f [20j,50m,7n]:15</font>
+<ChanOp> 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>
+<Evil2> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl
+<Evil12> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl
+<Evil15> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl
+<Evil10> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl
+<Evil8> 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 (>20 joins in 15 seconds),
+and will set the channel +M if the msg limit is reached (>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>
<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 {
no options are required, you may specify this without any directives in the
form listen <ip:port>;.</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>
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">
</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">
<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>
<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>
</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>
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">
mask <server-name>;
reason <reason-for-ban>;
};</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 {
channel "<channel-mask>";
reason <reason-for-ban>;
redirect "<channel-name>";
+ 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 {
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";
};</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 <censored>. The badword::action defines
what action should be taken if this badword is found. If you specify replace, then the
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 <block-name>::<block-directive>
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
<p><font class="set">set::oper-only-stats <stats-list>;</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 {<stats-flag>; <stats-flag>;};</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 <amount-of-channels>;</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 <command-prefixes>;</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
<p><font class="set">set::anti-flood::unknown-flood-amount <amount>;</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 <amount>;</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 <timevalue>;</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 <count>:<period></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 <count>:<period></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 <time></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 – 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 />
<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>
</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>
<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 – 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>
<td>All</td>
</tr>
<tr>
- <td height="39">part <channel1, channel2, ...></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 <channel1, channel2, ...></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>
of a channel.<br></td>
<td>All</td>
</tr>
+ <tr>
+ <td height="39">dns <option></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 <userid> <password><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 <message></td>
+ <td height="39">wallops <message></td>
<td>Sends a message to all users with umode +w</td>
<td>IRCop</td>
</tr>
</tr>
<tr>
<td height="39">shun +-<user@host> <time to shun> :<reason><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 –user@host. Setting time to 0 makes it permanent.
<br></td>
<td>IRCop</td>
</tr>
<tr>
<td height="36">stats <option><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>
+ Extended flags: [+/-mrs] [mask] [reason] [setby]<br>
+ m Return glines matching/not matching the specified mask<br>
+ r Return glines with a reason matching/not matching the specified reason<br>
+ 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>
+ Extended flags: [+/-mrs] [mask] [reason] [setby]<br>
+ m Return shuns matching/not matching the specified mask<br>
+ r Return shuns with a reason matching/not matching the specified reason<br>
+ 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>
" 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-----------------==";
" LAG SETHOST SETIDENT CHGHOST CHGIDENT";
" CHGNAME SQUIT CONNECT DCCDENY UNDCCDENY";
" SAJOIN SAPART SAMODE RPING TRACE";
- " OPERMOTD SDESC MKPASSWD";
+ " OPERMOTD SDESC MKPASSWD CLOSE MODULE";
" ==----------------oOo---------------==";
};
" 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)";
" 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";
" 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.";
" -";
" 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 {
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.";
" 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.";
#include <process.h>
#include <io.h>
#endif
-#include "dynconf.h"
+//#include "dynconf.h"
#include "ircsprintf.h"
#include "config.h"
#ifdef PARAMH
/* 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" \
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" \
" 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" \
*/
#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
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;
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;
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;
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;
};
#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
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);
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, ...);
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
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();
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
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);
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);
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 *);
#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 */
#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;
Command *command;
Hooktype *hooktype;
Versionflag *versionflag;
+ Snomask *snomask;
+ Umode *umode;
} object;
} ModuleObject;
* 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;
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
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)
#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
#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 */
#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
#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();
#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
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;
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
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;
* -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. */
#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)
unsigned do_garbage_collect : 1;
unsigned ircd_booted : 1;
unsigned do_bancheck : 1;
+ unsigned ircd_rehashing : 1;
unsigned tainted : 1;
};
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 */
#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 {
#ifdef LIST_DEBUG
aClient *bcptr;
#endif
+ struct {
+ unsigned synced:1; /* Server linked? (3.2beta18+) */
+ } flags;
};
#define M_UNREGISTERED 0x0001
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
ConfigItem *prev, *next;
ConfigFlag flag;
char *channel, *reason, *redirect;
+ unsigned char warn;
};
struct _configitem_allow_channel {
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
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 */
#include "ssl.h"
#endif
#define EVENT_HASHES EVENT_DRUGS
-#include "modules.h"
#include "events.h"
struct Command {
aCommand *prev, *next;
#endif
+#define VERIFY_OPERCOUNT(clnt,tag) { if (IRCstats.operators < 0) verify_opercount(clnt,tag); } while(0)
+
#endif /* __struct_include__ */
+#include "dynconf.h"
#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)
#define P_ECONNABORTED WSAECONNABORTED
#define P_ECONNRESET WSAECONNRESET
#define P_ENOTCONN WSAENOTCONN
+#define P_EMSGSIZE WSAEMSGSIZE
#endif
#endif /* __sys_include__ */
#define UnrealProtocol 2303
#define PATCH1 "3"
#define PATCH2 ".2"
-#define PATCH3 "-beta17"
+#define PATCH3 "-beta18"
#define PATCH4 ""
#define PATCH5 ""
#define PATCH6 ""
# 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`
echo ""
echo "Couldn't find the ircd running. Reloading it..."
echo ""
-./$ircdexe
+$ircdexe
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 \
./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
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
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
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
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 \
./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
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
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
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
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 \
./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
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
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
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
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 \
./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
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
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
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
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)
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)
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
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.
/* 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 *);
{
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';
}
** 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);
/* 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;
*/
/* 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;
* 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;
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;
*/
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))
|| !(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 &&
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.
{
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))
*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';
}
}
/* 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;
{
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)
{
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);
* 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;
}
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 */
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)
*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';
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) */
&& !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),
&& !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,
*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));
}
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. */
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. */
retval = 0;
break;
}
-
+ if (!stricmp(param, chptr->mode.link))
+ break;
if (!stricmp(param, chptr->chname))
{
if (MyClient(cptr))
}
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. */
}
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);
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
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;
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;
}
#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)
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)
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,
* 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;
/*
** 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;
** 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;
* 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;
** 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;
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)
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",
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;
}
sub1_from_channel(chptr);
continue;
}
+ RunHook4(HOOKTYPE_LOCAL_JOIN, cptr, sptr,chptr,parv);
}
/*
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 */
(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)
#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);
{
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
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);
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] */
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
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)
{
Membership *lp;
MembershipL *lp2;
+ int c_limit, t_limit, banthem;
if (!MyClient(sptr))
return 0;
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();
/* 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);
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();
{
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),
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;
}
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;
}
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)
{
#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);
{
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';
{
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)))
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) &&
{
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))
(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? */
/*
* 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))
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');
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, */
}
}
}
+
+#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
if (!name || (every < 0) || (howmany < 0) || !event)
{
+ if (module)
+ module->errorcode = MODERR_INVALID;
return NULL;
}
newevent = (Event *) MyMallocEx(sizeof(Event));
eventobj->object.event = newevent;
eventobj->type = MOBJ_EVENT;
AddListItem(eventobj, module->objects);
+ module->errorcode = MODERR_NOERROR;
}
return newevent;
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;
event->event = mods->event;
if (mods->flags & EMOD_DATA)
event->data = mods->data;
+ if (event->owner)
+ event->owner->errorcode = MODERR_NOERROR;
return 0;
}
--- /dev/null
+/************************************************************************
+ * 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 */
#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)
{
/*
{
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)
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;
#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
}
(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)));
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);
}
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;
}
}
-#ifndef CHROOT
+#ifndef CHROOTDIR
if (chdir(dpath)) {
# ifndef _WIN32
perror("chdir");
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"))
{
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;
if (!serv)
{
- serv = (aServer *)MyMalloc(sizeof(aServer));
+ serv = (aServer *)MyMallocEx(sizeof(aServer));
#ifdef DEBUGMODE
servs.inuse++;
#endif
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--;
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))
{
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_));
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;
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)
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)
{
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)
{
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)
{
}
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;
}
vflagobj->type = MOBJ_VERSIONFLAG;
vflagobj->object.versionflag = vflag;
AddListItem(vflagobj, module->objects);
+ module->errorcode = MODERR_NOERROR;
}
AddListItem(parent,vflag->parents);
}
vflagobj->type = MOBJ_VERSIONFLAG;
vflagobj->object.versionflag = vflag;
AddListItem(vflagobj, module->objects);
+ module->errorcode = MODERR_NOERROR;
}
flag_add(flag);
AddListItem(parent,vflag->parents);
ModuleChild *owner;
if (!vflag)
return;
+
for (owner = vflag->parents; owner; owner = owner->next)
{
if (owner->child == module)
hooktypeobj->type = MOBJ_HOOKTYPE;
hooktypeobj->object.hooktype = hooktype;
AddListItem(hooktypeobj, module->objects);
+ module->errorcode = MODERR_NOERROR;
}
AddListItem(parent,hooktype->parents);
}
}
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;
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];
}
hookobj->object.hook = p;
hookobj->type = MOBJ_HOOK;
AddListItem(hookobj, module->objects);
+ module->errorcode = MODERR_NOERROR;
}
return p;
}
}
}
+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];
+}
#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 */
};
-/* 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
}
/* 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;
}
#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 */
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
}
/* 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;
}
#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$",
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;
}
}
#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 */
#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 */
"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
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;
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 */
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;
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;
}
#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 */
};
-/* 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
}
/* 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;
/* 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;
--- /dev/null
+/*
+ * 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;
+}
#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 */
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
}
/* 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;
}
#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 */
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[])
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
-#define snprintf _snprintf
+//#define snprintf _snprintf
#include <io.h>
#endif
#include <fcntl.h>
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 */
};
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
}
/* 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;
/* 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);
return MOD_SUCCESS;
}
-
-
DLLFUNC int m_guest(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
int randnum;
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 */
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
/* 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
}
/* 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();
#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 */
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
}
/* 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;
*/
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];
** 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,
#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 */
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;
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 */
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
}
/* 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;
}
*/
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)))
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)
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)
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);
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)
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))
{
#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$",
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
#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 */
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;
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 */
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
}
/* 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;
}
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;
}
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);
}
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));
#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++;
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);
#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 */
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
}
/* 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
#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 */
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
}
/* 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
{
char *ocomment = (parc > 1 && parv[1]) ? parv[1] : parv[0];
static char comment[TOPICLEN + 1];
+ Membership *lp;
if (!IsServer(cptr))
{
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);
#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 */
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
#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 */
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
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;
-
}
/*
#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 */
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
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
#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 */
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
}
/* 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;
{
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;
}
}
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;
}
}
/* 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 */
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;
-
}
/*
#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 */
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
#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 */
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
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
#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 */
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
#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 */
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;
}
#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$",
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;
}
#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$",
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;
}
&& !(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;
&& !(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;
#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$",
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;
}
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)
{
#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$",
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;
}
#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 */
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
}
/* 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;
}
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$",
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;
}
if (IsAnOper(acptr))
{
IRCstats.operators--;
+ VERIFY_OPERCOUNT(acptr, "svsnoop");
delfrom_fdlist(acptr->slot, &oper_fdlist);
}
acptr->umodes &=
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);
}
}
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$",
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;
}
{
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 &=
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;
#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 */
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;
}
#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 */
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;
}
#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 */
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
}
/* 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;
}
#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$",
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;
}
#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 */
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
}
/* 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 ) ||
{
sendto_realops("Failed to delete commands when unloading %s",
- m_tkl_Header.name);
+ MOD_HEADER(m_tkl).name);
}
return MOD_SUCCESS;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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());
#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 */
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
}
/* 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;
}
#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 */
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
}
/* 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;
}
#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 */
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
}
/* 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;
}
#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 */
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
}
/* 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;
}
#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 */
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;
}
#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 */
};
/* 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
}
/* 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;
}
#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 */
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
}
/* 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;
}
*/
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;
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 *" */
* 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);
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))
{
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;
/* 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))
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
acpt->receiveB &= 0x03ff;
}
}
- else if (me.receiveB > 1023)
+ if (me.receiveB > 1023)
{
me.receiveK += (me.receiveB >> 10);
me.receiveB &= 0x03ff;
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);
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++)
cmdobj->object.command = command;
cmdobj->type = MOBJ_COMMAND;
AddListItem(cmdobj, module->objects);
+ module->errorcode = MODERR_NOERROR;
}
return command;
}
#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 *);
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;
{
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));
if (op & RES_INITSOCK)
{
-#ifndef _WIN32
int on = 0;
#ifdef INET6
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)
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
}
new->next = NULL;
reinfo.re_requests++;
- unlock_request();
return 0;
}
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)
{
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);
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;
}
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)
{
{
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",
if (!next || tout < next)
next = tout;
}
- unlock_request();
return (next > now) ? next : (now + AR_TTL);
}
{
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();
}
/*
* 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
#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]),
}
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)
{
ResRQ *rptr;
- lock_request();
for (rptr = first; rptr; rptr = rptr->next)
if (rptr->id == id)
break;
- unlock_request();
return rptr;
}
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);
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);
static int do_query_name(Link *lp, char *name, ResRQ *rptr)
{
-#ifndef _WIN32
char hname[HOSTLEN + 1];
int len;
(void)strncat(hname, ircd_res.defdname,
sizeof(hname) - len - 1);
}
-#endif
/*
* Store the name passed as the one to lookup and generate other host
(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
}
/*
{
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
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));
{
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,
(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.
*/
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
{
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
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)
{
}
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
#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);
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;
/*
#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;
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++;
** 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;
}
*/
if (rptr)
{
- if (h_errno != TRY_AGAIN)
+ if (ERRNO != TRY_AGAIN)
{
/*
* If we havent tried with the default domain and its
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;
}
*cpp = cp->list_next;
cp->list_next = cachetop;
cachetop = cp;
-#ifndef _WIN32
if (!rptr)
return;
bcopy(s, (char *)*--ab, sizeof(struct IN_ADDR));
}
}
-#endif
return;
}
/*
** 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
(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))
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++;
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
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));
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;
*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.
MyFree(*hp->h_addr_list);
MyFree(hp->h_addr_list);
}
-#endif
MyFree(ocp);
incache--;
}
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,
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
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*/
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--)
{
if (dn + 1 >= eom)
{
- errno = EMSGSIZE;
+ SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*dn++ = '\\';
{
if (dn + 3 >= eom)
{
- errno = EMSGSIZE;
+ SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*dn++ = '\\';
{
if (dn >= eom)
{
- errno = EMSGSIZE;
+ SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*dn++ = (char)c;
{
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';
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;
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;
{
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++;
}
if (bp >= eom)
{
- errno = EMSGSIZE;
+ SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*bp++ = (u_char)c;
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;
{
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);
dstlim = dst + dstsiz;
if (srcp < msg || srcp >= eom)
{
- errno = EMSGSIZE;
+ SET_ERRNO(P_EMSGSIZE);
return (-1);
}
/* Fetch next label in domain name. */
/* Limit checks. */
if (dstp + n + 1 >= dstlim || srcp + n >= eom)
{
- errno = EMSGSIZE;
+ SET_ERRNO(P_EMSGSIZE);
return (-1);
}
checked += n + 1;
case NS_CMPRSFLGS:
if (srcp >= eom)
{
- errno = EMSGSIZE;
+ SET_ERRNO(P_EMSGSIZE);
return (-1);
}
if (len < 0)
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;
*/
if (checked >= eom - msg)
{
- errno = EMSGSIZE;
+ SET_ERRNO(P_EMSGSIZE);
return (-1);
}
break;
default:
- errno = EMSGSIZE;
+ SET_ERRNO(P_EMSGSIZE);
return (-1); /* flag error */
}
}
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;
{
if (dstp + 1 >= eob)
{
- errno = EMSGSIZE;
+ SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*dstp++ = (l >> 8) | NS_CMPRSFLGS;
/* 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);
{
if (msg != NULL)
*lpp = NULL;
- errno = EMSGSIZE;
+ SET_ERRNO(P_EMSGSIZE);
return (-1);
}
return (dstp - dst);
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;
break;
default: /* illegal type */
- errno = EMSGSIZE;
+ SET_ERRNO(P_EMSGSIZE);
return (-1);
}
}
next:;
}
- errno = ENOENT;
+ SET_ERRNO(ENOENT);
return (-1);
}
* 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];
*pp++ = 0;
}
+#ifndef _WIN32
#define MATCH(line, name) \
(!strncmp(line, name, sizeof(name) - 1) && \
(line[sizeof(name) - 1] == ' ' || \
#ifdef NEXT
if (ircd_netinfo_res_init(&haveenv, &havesearch) == 0)
#endif
-#ifndef _WIN32
if ((fp = fopen(IRC_RESCONF, "r")) != NULL)
{
/* read the config file */
#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)
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);
}
if ((ircd_res.options & RES_INIT) == 0 && ircd_res_init() == -1)
{
- h_errno = NETDB_INTERNAL;
+ SET_ERRNO(NETDB_INTERNAL);
return (-1);
}
#ifdef DEBUGMODE
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;
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;
(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
}
}
-#ifndef _WIN32
if (resfd >= 0)
FD_SET(resfd, &read_set);
-#endif
if (me.fd >= 0)
FD_SET(me.fd, &read_set);
#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.."));
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.
* reading.
*/
-#ifndef _WIN32
static void do_dns_async(void)
-#else
-void do_dns_async(int id)
-#endif
{
static Link ln;
aClient *cptr;
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));
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
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[] = {
{ "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 },
#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)
*/
ConfigItem_badword *conf_badword_message = NULL;
ConfigItem_badword *conf_badword_quit = NULL;
#endif
+ConfigItem_offchans *conf_offchans = NULL;
aConfiguration iConf;
aConfiguration tempiConf;
*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;
} 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, ' ');
{
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;
store->per = per;
store->kmode = kmode;
store->mode |= MODE_FLOODLIMIT;
+#endif
break;
}
default:
*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;
}
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);
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)
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;
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()
(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 */
}
+/** returns NULL if allowed and struct if denied */
ConfigItem_deny_channel *Find_channel_allowed(char *name)
{
ConfigItem_deny_channel *dchannel;
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
*/
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)
{
}
#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;
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) {
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;
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
}
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)
{
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);
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;
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);
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")) {
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) {
CheckNull(cep);
for (c = cep->ce_vardata; *c; c++)
{
+ if (*c == ' ')
+ break; /* don't check the parameter ;p */
switch (*c)
{
case 'q':
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",
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") &&
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);
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",
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")) {
}
}
}
+ 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) {
}
}
+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;
{
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;
;
else if (!strcmp(cep->ce_varname, "reason"))
;
+ else if (!strcmp(cep->ce_varname, "warn"))
+ ;
else
{
config_error("%s:%i: unknown directive deny::%s",
int rehash(aClient *cptr, aClient *sptr, int sig)
{
+ loop.ircd_rehashing = 1;
flush_connections(&me);
if (sig == 1)
{
}
if (init_conf(configfile, 1) == 0)
run_configuration();
-
+ unload_all_unused_snomasks();
+ unload_all_unused_umodes();
+ loop.ircd_rehashing = 0;
return 1;
}
#ifdef USE_SYSLOG
'Y',
#endif
-#ifdef NO_IDENT_CHECKING
- 'K',
-#endif
#ifdef INET6
'6',
#endif
#endif
#ifdef ZIP_LINKS
'Z',
+#endif
+#ifdef EXTCMODE
+ 'E',
#endif
'\0'
};
}
#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;
-}
/* 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,
}
}
-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;
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,
"%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);
case '?':
if (IsAnOper(sptr))
- tkl_stats(sptr);
+ tkl_stats(sptr,0,NULL);
}
return 0;
}
link_cleanup(sptr->serv->conf);
MyFree(sptr->serv->conf);
}
+ ircd_log(LOG_SERVER, "SQUIT %s (%s)", sptr->name, comment);
}
if (sptr->listener)
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))
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);
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;
}
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
*/
*/
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
aClient *acptr;
int i;
+ ircd_log(LOG_SERVER, "SERVER %s", cptr->name);
if (cptr->passwd)
{
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 */
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;
}
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
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]))
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]))
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)
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
}
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;
+}
--- /dev/null
+#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;
+}
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) {
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;
}
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)
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))
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];
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;
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;
}
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
*/
*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
(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
{
{
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),
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);
sptr->user->username, NULL, NULL) == FLUSH_BUFFER)
return FLUSH_BUFFER;
update_watch = 0;
-
+ newusr = 1;
}
}
/*
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;
}
** 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;
}
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';
}
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;
}
if (CONNECT_SNOMASK)
{
sptr->umodes |= UMODE_SERVNOTICE;
- user->snomask = create_snomask(CONNECT_SNOMASK, 0);
+ create_snomask(sptr, user, CONNECT_SNOMASK);
}
}
me.name, parv[0]);
return 0;
}
+
PassLen = strlen(password);
if (cptr->passwd)
MyFree(cptr->passwd);
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;
}
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;
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) {
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;
}
/*
ClearHideOper(sptr);
ClearCoAdmin(sptr);
ClearHelpOp(sptr);
- sptr->user->snomask &= (SNO_NONOPERS);
}
/*
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...
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))
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))
/*
* Burst messages comes here..
*/
+ va_start(vl, pattern);
vsendto_prefix_one(acptr, from, pattern, vl);
+ va_end(vl);
}
}
va_end(vl);
if (!IsSecure(acptr))
continue;
#endif
+ va_start(vl, pattern);
vsendto_prefix_one(acptr, from, pattern, vl);
+ va_end(vl);
sentalong[i] = sentalong_marker;
}
else
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;
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
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);
{
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;
{
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;
{
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;
{
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;
{
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;
{
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;
{
if (!(cptr = local[i]) || (one && cptr == one->from))
continue;
+ va_start(vl, tokpattern);
+
#ifdef NO_FDLIST
if (IsServer(cptr) && SupportNICKv2(cptr) && !IsToken(cptr))
#else
if (SupportNICKv2(cptr) && IsToken(cptr))
#endif
vsendto_one(cptr, tokpattern, vl);
+ va_end(vl);
}
va_end(vl);
return;
!(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;
}
* 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;
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;
}
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;
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);
}
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;
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;
}
{
(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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
acpt->sendB &= 0x03ff;
}
}
- else if (me.sendB > 1023)
+ if (me.sendB > 1023)
{
me.sendK += (me.sendB >> 10);
me.sendB &= 0x03ff;
* 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)
{
/************************************************************************
- * 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
#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 */
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) */
{
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)
* 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;
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)
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;
+}
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)
/* restore the string*/
if (strlen(cmd) < n)
cmd[strlen(cmd)]= ' ';
- return -2;
+ return -99;
}
i = 0;
}
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;
*/
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);
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))
{
/************************************************************************
* 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
#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) {\
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);
/* 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)
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;
}
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 ");
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);
}
OSName[strlen(OSName)-1] = 0;
InitCommonControls();
WM_TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");
+ WM_FINDMSGSTRING = RegisterWindowMessage(FINDMSGSTRING);
atexit(CleanUp);
if(!LoadLibrary("riched20.dll"))
LoadLibrary("riched32.dll");
}
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);
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);
}
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);
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);
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);
/* 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);
{ 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;
}
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;
}
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: {
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);
}
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);
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;
}
else
EndDialog(hDlg, TRUE);
+ break;
}
case WM_DESTROY:
ChangeClipboardChain(hDlg, hClip);
/* 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;
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
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
#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
#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
#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;
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;
SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
return;
}
-
IRCDStatus.dwCurrentState = SERVICE_RUNNING;
IRCDStatus.dwCheckPoint = 0;
IRCDStatus.dwWaitHint = 0;
-
SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
SocketLoop(0);
; #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
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
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
# 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