diff --git a/.CHANGES.NEW b/.CHANGES.NEW
index fe1a4331b..5d9834b7f 100644
--- a/.CHANGES.NEW
+++ b/.CHANGES.NEW
@@ -7,7 +7,7 @@
\___/|_| |_|_| \___|\__,_|_|\___/\_| \_| \____/\__,_|
Configuration Program
- for Unreal3.2.1
+ for Unreal3.2.2
This program will help you to compile your IRC server, and ask you
questions regarding the compile-time settings of it during the process.
diff --git a/.RELEASE.NOTES b/.RELEASE.NOTES
index 3e1fa2e1a..075563bb9 100644
--- a/.RELEASE.NOTES
+++ b/.RELEASE.NOTES
@@ -1,113 +1,91 @@
-Unreal3.2.1 Release Notes
+Unreal3.2.2 Release Notes
==========================
-Please READ this document carefully, otherwise your ircd won't boot!
-
-This is a RECOMMENDED RELEASE due to the fact that the previous
-cloaking algorithm has been cracked. Besides that, this version
-also brings quite some exciting new features (win32 module support,
-and a _lot_ more).
-
==[ GENERAL INFORMATION ]==
-- If you are upgrading on *NIX, make sure you run make clean and ./Config before doing make
+- If you are upgrading on *NIX, make sure you run 'make clean' and './Config'
+ first before doing 'make'
- 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/
+- When upgrading a network, we assume you are upgrading from the previous
+ version (3.2.1). If you got a net running with servers that are several
+ versions behind (eg: 3.2) then you might experience (desynch) problems.
+ Also, if you try to use the new features, some might not work properly
+ until all your servers are upgraded. It is therefore recommended to
+ upgrade all servers in a 'short' timespan (x day[s], not weeks).
== [ NEW ]==
-- [!] Cloaking has been modulized.
- - This means you now MUST load a cloaking module in order to boot.
- Example: loadmodule "src/modules/cloak.so";
- - 2 cloaking modules are provided: 'cloak' and 'oldcloak':
- - 'cloak' is the new, RECOMMENDED, and much more secure cloaking algorithm that uses
- md5 internally. It requires 3 keys of 5-100 characters (10-20 is fine) consisting
- of mixed lowercase (a-z), uppercase (A-Z) and digits (0-9). So for example:
- set { cloak-keys { "AHsHS6ds2sQGAkish"; "qF5D3orm6Evba26hjf"; "f6oaO2hhd6sIHSfs"; };
- - 'oldcloak' is the <=3.2 cloaking algorithm, it is ONLY meant for use during the
- upgrade process (it will give a warning if you use it), you should switch to the
- much more secure 'cloak' module AS SOON AS POSSIBLE. As mentioned earlier, the old
- cloaking algorithm has been cracked so it makes no sense to keep using it.
- - 3rd party cloak modules are also possible.
-- [!] Windows now also supports modules
- - This means you MUST load commands.dll and a cloaking module on windows too, eg:
- loadmodule "modules/commands.dll";
- loadmodule "modules/cloak.dll";
- - 3rd party modules are now easy to install too... developers can put .dll files
- online which you just need to put in your modules\ directory (or, that could
- even be done by an installer), after that you just add a loadmodule line for it,
- like: loadmodule "modules/leetmod.dll";
- NOTE: Just as on *NIX, you'll have to upgrade your modules every release.
-- set::spamfilter::virus-help-channel-deny: blocks any normal joins to the
- virus-help-channel (only people force-joined by spamfilter and opers can join).
-- set::options::flat-map: Makes all server appear as directly-linked in /links,
- /map, etc. Thus, link info (which server is linked to which) is hidden from users.
-- NickIP was added, this means IP's of users are now known by all servers:
- - IP is now shown in the 'is connecting from' line in /whois (if selfwhois or oper)
- - "Far connects" (+s +F) together with HCN (Hybrid Connect Notice) can now see
- IP's as well. This allows you to use for example 1 central BOPM.
- - New /who options:
- - /who +i ' now).
-- Win32: now using dynamically linked libc to get rid of some crashbugs. The dll,
- msvcr70d.dll, will be downloaded automatically if needed.
-- Made the 'negative TS' warning a bit more annoying since a lot of people don't
- understand how critical correct time for IRC is.
-- Several servernotices were turned into numerics
+- allow-userhost-change force-rejoin is now also applied to opers that oper
+ up and receive a vhost.
+- Removed * and ^ flags from /whois if PREFIX_AQ is disabled
+- Using a new Makefile on *NIX so it requires less memory to compile unreal
+- *NIX: 'md5' password encryption is now always available.
+- Win32: 'Install as a service' is now unchecked by default
+- Win32: zip/non-zip modules are now binary compatible (just like ssl/non-ssl)
+- Made /whois show the usermodes to opers regardless of the eyes snomask
+- Snomasks are now shown in the /whois umode output
+- 005 tokens heavily updated, also modulized.
+- Docs, help.conf, spamfilter.conf and other text updates
+- Win32: Now using the release library msvcr70.dll [*]
+- Module coders: HOOKTYPE_REMOTE_CONNECT now also gets called upon netsynch.
+- Slowed down qline floods
+- You can now specify multiple types in an except tkl { } block
+
+ [*]: fix was also in the 3.2.1b win32 release
==[ ADDITIONAL INFO ]==
-* See Changelog
+* See Changelog for more details
diff --git a/Changes b/Changes
index 074b30a30..91dce4664 100644
--- a/Changes
+++ b/Changes
@@ -244,3 +244,170 @@
- Changed version to 3.2.1
- Moved the 3.2 changes to Changes.old
** 3.2.1 release **
+- Fixed a win32 module problem where file not found errors would display random characters,
+ reported by STING
+- Fixed a bug where the allow-userhost-change force-rejoin setting was not applied to users
+ who /oper and receive an oper-host (#0001901) reported by hypnetric.
+- Removed the /hs alias pointing to HelpServ for Anope since this conflicts with HostServ
+ (#0001709) reported by DukePyrolator
+- Fixed ban bug: halfops were also prevented from doing nickchanges if banned, plus..
+ +b ~n:*!*@* also made nickchanges impossible for voiced(&halfop'ed) people (so like half
+ of the purpose of it was defeated @$#&@#). Reported by Rocko.
+- Fixed a bug where an ident in a vhost {} was never sent out to other servers and added
+ user@host support for set::hosts (#0001834) reported/suggested by bleepy.
+- Fixed defizzer module. Reported by Rocko and netrixtardis.
+- Removed the * and ^ flags from /whois if PREFIX_AQ is not enabled (requested by many people)
+- Updated the /who docs to use correct English
+- Added documentation for the /who and /whois flags (#0001881) reported by AngryWolf and Bugz.
+- Added src/win32/win32.c for generic win32 helper functions
+- Renamed src/win32/win32gui.c to src/win32/gui.c
+- Reorganized much of the Windows code
+- Fixed a whois bug when PREFIX_AQ is undefined, reported by Shaun
+- Moved the RTF win32 code to a seperate file
+- More win32 code cleanups
+- Added src/win32/editor.c (woops), (#0001932) reported by Troco
+- Fixed a problem with /who incorrectly showing the ? flag to opers even when the user should
+ be visible (#0001888) reported by Bugz and aquanight
+- Added SAPART and SVSPART reasons. Note, to fully work it requires all servers to upgrade,
+ and due to a bug in older versions, it could cause problems if linked to 3.2 or earlier
+ (#0001859) suggested by Bugz
+- Fixed a minor issue where Unreal registered itself as an NT service incorrectly
+ (#0001950) reported by rocafella
+- Possibly fixed a bug that could cause Unreal to eat 100% CPU at startup on Windows.
+ (#0001635) reported by eggburt. Thanks to STING for helping to debug this.
+- Implemented a new modules Makefile written by fez (#0001930).
+- Added oper::modes to specify modes to be set for a particular oper (overrides
+ set::modes-on-oper), suggested by parker182 (#0001899).
+- doc/example.conf now simply refers to unreal32docs.html for oper flags (#0001973)
+ reported by vonitsanet and AngryWolf.
+- Fixed crash-on-first-connect if SSL was enabled. This seemed to happen on Mac OS X,
+ Sun Solaris, Opteron@Linux and perhaps others (#1982, #1984, #2110), reported by bit,
+ lion and liverbugg.
+- Fixed a bug if me::info was set to "".
+- Added a missing error message for ModuleGetErrorStr. Additionally added error checking to
+ ensure NULL is returned when an invalid error code is specified (#0001986) reported by
+ AngryWolf.
+- Applied patch from slePP for bug #0001252: if IPv6 was enabled then in some cases names
+ were not properly resolved. Original bug reported by kormat.
+- Fixed bugs regarding HOOKTYPE_SERVER_QUIT: was sometimes called twice and could cause
+ crashes due read-after-free. Reported by SET (#0001988).
+- Fixed possible crash if /rehash'ing and a servername was just resolving (due to
+ /connect or autoconnect) and was not present in the cache. Reported and traced by sh0
+ (#0001976).
+- Fixed compile bug at *NIX caused by ModuleGetErrorStr fix.
+- Improved doc/compiling_win32.txt a lot: now VC7 only, and has instructions on:
+ compiling modules and their (binary) compatability, zip links (zlib), ssl (OpenSSL)...
+ Remote includes (curl and c-ares) instructions still need to be added.
+- Made 'Install as a service' unchecked by default, this should help beginners a lot.
+- Updated doc/compiling_win32.txt again with curl build instructions.
+ Also linked to a page with an unreal dev package which contains zlib+ssl+curl
+ precompiled. This basically means many people no longer need to compile zlib/ssl/curl
+ anymore themselves (which is a pain to do and takes a lot of time).
+- Windows: the 'notice' parameter in the usermsg callback was always 0 due some windows/vc
+ weirdness, this also affected spamfilter (so any spamfilters added only at notice
+ and not at msg on windows would not work). Now using the real 'notice' parameter.
+- unbroke spamfilter not working for msgs/notices (oops..).
+- Made zip/non-zip modules on win32 binary compatible. Since it was nowhere documented
+ that you should pass the ZIP_LINKS etc options to 'nmake -f makefile.win32 custommodule'
+ many people didn't do this which caused odd problems when reading certain clientstructs.
+ Module coders: in the meantime, for 3.2.1 mods, use something like:
+ nmake -f makefile.win32 USE_ZIPLINKS=1 ZLIB_INC_DIR="c:\dev\zlib"
+ ZLIB_LIB_DIR="c:\dev\zlib\dll32" custommodule MODULEFILE=m_mymodule
+ For 3.2.2+ these additional parameters will no longer be needed (but wouldn't harm either).
+- Some doc/example.conf clarifications, mainly for modules @ win32.
+- Made /whois show the user's modes to opers regardless of +e
+- Added snomask to the /whois umode output
+- Added a patch by rocafella to fix a crash when installing Unreal on Win2003 (#0001949).
+- Moved the Command API functions to a separate file.
+- Redesigned the 005 token:
+ - Now renamed to RPL_ISUPPORT.
+ - Replaced KNOCK and MAP tokens with new CMDS token (see doc/technical/005.txt)
+ - Implemented most tokens from the isupport draft (STATUSMSG, EXCEPTS, CHANLIMIT,
+ CHANNELLEN, MAXLIST).
+ - Removed MAXBANS.
+ - Made the isupport system dynamic and provide an API for modules to add tokens, may need
+ testing.
+ - Added an M_ANNOUNCE flag for CommandAdd to add the command to the CMDS token, may need
+ testing.
+- Fixed some compile warnings.
+- Fixed a bug where bans were not matched against IPs in all circumstances (#0002045)
+ reported by heper.
+- Fixed a bug with IP based except tkl {} lines did not validate the ident portion of the mask
+ (#0002049) reported by Rocko.
+- Fixed a problem where a local TKL could be sent to remote servers when it is being changed
+ (#0002048) reported by AngryWolf.
+- Added documentation for link::ciphers to unreal32docs.html (#0002019) reported by Bugz.
+- Updated documentation to reflect that cmode +M allows voiced users to talk, not just
+ registered users (#0002020) reported by crazy.
+- Made it so WATCH will not respond with an erroneous reply if the parameter was simply + or -
+ (#0002017) reported by GouraudShading.
+- SVSO now removes +v (#0002023) reported by w00t and aquanight.
+- Exported the isupport functions for use in Windows modules.
+- Added a new snomask, +o to show oper-up notices (oper only), (#0001965) suggested by
+ vonitsanet.
+- Added a /userip command that works just like ircu's.
+- Fixed a typo in the *nix Makefile reported by Troco (#0002059)
+- Added french docs, translated by Kolibot & Babass.
+- Changed some stuff to use the release version of MS libraries.
+- Updated installer for msvcr70.dll
+- Fixed prefix bug caused by previous 'fix'/behavior change. Reported by aquanight (#0002067).
+- Updated doc/technical/token.txt and resolved 2 token conflicts. SVSWATCH is now Sw and
+ SVSJOIN is now BX (#0002073) reported by trystanscott.
+- Fixed a bug regarding chanmode +mu where the
+Hungarian |
+French
+
http://www.unrealircd.com
- Version: 3.2.1
- Aktuelle Version: 3.2.1
- Letztes Dokumentation Update: 2004-07-03
+ Aktuelle Version: 3.2.2
+ Letztes Dokumentation Update: 2004-10-11
Head Coders: Stskeeps / codemastr / Syzop / Luke
Contributors: McSkaf / Zogg / NiQuiL / assyrian / chasm / DrBin / llthangel / Griever / nighthawk
Dokumentation: CKnight^ / Syzop
@@ -208,8 +210,8 @@ Bug gemeldet wird!
Installationsanleitungen
Linux:
Es kann eingestellt werden, welche snomasks man automatisch erhält (set::snomask-on-connect)
@@ -734,87 +737,152 @@ Ebenso k
Spamfilter ist ein neues System gegen Spam, Belästigungen, Würmer etc. Es
arbeitet ein wenig ähnlich wie 'badwords', hat aber einige Erweiterungen..
-Spamfilter werden durch den /spamfilter Befehl gesetzt, der die folgende
-Syntax hat:
+Spamfilter werden durch den /spamfilter Befehl mit der folgenden Syntax
+gesetzt:
/spamfilter [add|del|remove|+|-] [type] [action] [tkltime] [reason] [regex]
| [type] | -gibt den Zieltyp an, also welche Art von Nachrichten. Man kann -verschiedene angeben. es gilt: 'c' für Channel Nachrichten, 'p' für private -Nachrichten, 'n' für private Notice, 'N' für Channel Notice, 'P' Part Meldung, 'q' -für Quit Meldung und 'd' für dcc | +gibt an, auf welchen Nachrichtentyp reagiert + werden soll; | +||||
| + | Zeichen: | +Config Eintrag | +Bedeutung | +|||
| + | c | +channel | +Nachricht im Channel (öffentlich) | +|||
| + | p | +privat | +Private Nachricht (von User --> User) | +|||
| + | n | +private-notice | +Private Notiz | +|||
| + | N | +channel-notice | +Channel Notiz | +|||
| + | P | +part | +Grund Angabe beim Verlassen des Channels | +|||
| + | q | +quit | +Grund Angabe beim Beenden des Chats | +|||
| + | d | +dcc | +DCC Dateiname | +|||
| + | u | +user | +bannt User, geprüft wird auf nick!user@host:realname | +|||
| + | Es ist möglich, mehrere Ziele anzugeben, wie + z.B.: cpNn | +|||||
| + | ||||||
| [action] | -[action] gibt an, welche Aktion erfolgen soll (es kann nur 1 Aktion + | gibt an, welche Aktion erfolgen soll (es kann nur 1 Aktion angegeben werden) | ||||
| - | kill | -Killt den User | +||||
| - | tempshun | -setzt für die laufende Verbindung einen Shun auf den User + | kill | +Killt den User | +||
| + | tempshun | +setzt für die laufende Verbindung einen Shun auf den User (bei Reconnect ist der Shun aufgehoben | ||||
| - | shun | -Setzt einen Shun auf den Host | +shun | +Setzt einen Shun auf den Host | ||
| - | kline | -Setzt eine kline auf den Host | +kline | +Setzt eine kline auf den Host | ||
| - | gline | -Setzt eine gline auf den Host | +gline | +Setzt eine gline auf den Host | ||
| - | zline | -Setzt eine zline auf den Host | +zline | +Setzt eine zline auf den Host | ||
| - | gzline | -Setzt eine gzline (globale zline) auf den Host | +gzline | +Setzt eine gzline (globale zline) auf den Host | ||
| - | block | -Blockiert lediglich die Nachricht | +block | +Blockiert lediglich die Nachricht | ||
| - | dccblock | -markiert den User derart, dass er nicht in der Lage ist, + | dccblock | +markiert den User derart, dass er nicht in der Lage ist, irgend welche DCCs zu senden | ||
| - | viruschan | -User wird aus allen Channels entfernt, wird in den unter set::spamfilter::virus-help-channel + | viruschan | +User wird aus allen Channels entfernt, wird in den unter set::spamfilter::virus-help-channel eingetragenen Channel geforwardet, alle Befehle außer PONG und ADMIN werden deaktiviert und msg/notices werden zum Channel aus set::spamfilter::virus-help-channel - geleitet | + geleitet.||
| [tkltime] | -Die Zeitdauer, die für eine durch den Filter + | Die Zeitdauer, die für eine durch den Filter gesetzte Line gilt. Um den Default zu benutzen oder zum Übergehen (z.B. wenn action = 'block'), lediglich ein '-' eintragen, | ||||
| [reason] | -Der anzuzeigende Grund für Block- oder *lines + | Der anzuzeigende Grund für Block- oder *lines Befehle. Man kann hier KEINE Leerzeichen eintragen, aber Unterstriche ('_') werden zur Laufzeit in Leerzeichen umgesetzt. Ein doppelter Underscore ('__') erzeugt einen Underscore ('_') in der Ausgabe. Auch hier @@ -822,7 +890,7 @@ angegeben werden) | ||||
| [regex] | -gibt den Ausdruck oder das 'bad word' an, welches geblockt werden + | gibt den Ausdruck oder das 'bad word' an, welches geblockt werden soll, oder worauf die Aktion erfolgen soll | ||||
spamfilter {
+ regex "//write \$decode\(.+\|.+load -rs";
+ target { private; channel; };
+ reason "Generic $decode exploit";
+ action block;
+};
+
+
set::spamfilter::ban-time ermöglicht die Festlegung einer Default Bann
Dauer für *lines die durch den Spamfilter gesetzt wurden (default: 1 Tag)
@@ -1203,6 +1280,7 @@ bekannt als O:Line)
Mit dem Oper Block können für den Server IRC Operatoren festgelegt werden.
@@ -1514,9 +1592,12 @@ Form (wie z.B.: "services-admin") verwenden m
Information eines Opers gesetzt werden. [optional]
Mit der oper::snomask Anweisung kann eine server notice Mask für einen Oper voreingestellt werden, so dass man beim oper Befehl bestimmte Flags automatisch -voreingestellt bekommt. Siehe Abschnitt 3.3 +voreingestellt sind. Siehe Abschnitt 3.3 für Infos über snomasks. [optional] +
Mit der oper::modes Anweisung können Modi für Opers voreingestellt +werden, so dass man beim oper Befehl bestimmte Flags automatisch +voreingestellt sind. [optional]
Mit der oper::maxlogins Anweisung kann man die die Anzahl gleichzeitiger Oper Logins einschränken. Wenn hier z.B. der Wert 1 eingestellt wird, kann immer nur eine Person über diesen Oper Block eingeloggt @@ -1792,7 +1873,7 @@ setzen, bislang ist hier aber nur tld::options::ssl m
TLD Einträge werden von unten nach oben abgearbeitet.
Beispiel:
tld {
- mask *@*.fr;<
+ mask *@*.fr;
motd "ircd.motd.fr";
rules "ircd.rules.fr";
};
@@ -1965,19 +2046,25 @@ connecten d
OPTIONAL (Früher
nicht vorhanden)Syntax: -
except tkl {
+except tkl {
mask <hostmask>;
type <type>;
-};
+ type {
+ <type>;
+ <type>;
+ ...
+ };
+};
Mit dem "except tkl Block" kann man user@host -Masken angeben, die von den gesetzten Banns tkl Banns (also G-Lines, Shuns, GZ -Lines) ausgenommen werden sollen. So etwas kann verwendet werden, falls man z.B. +Masken angeben, die von den gesetzten tkl Banns (also G-Lines, Shuns, GZ +Lines) auf breitere Hosts ausgenommen werden sollen. So etwas kann verwendet werden, falls man z.B. ganze ISP bannen möchte, aber einzelnen Usern trotzdem die Verbindung erlauben möchte. Dazu bei except::mask den oder die Hosts eintragen (als user@host Mask) die trotz globalem Bann connecten dürfen. Bei except::type wird angegeben, welcher Bann Typ ausgenommen werden soll. Gültige Typen sind hier: gline, gzline, qline, gqline und shun, für Ausnahmen von Glines, Global Zlines, -Qlines, Global Qlines und Shuns.
+Qlines, Global Qlines und Shuns. Wenn das {} Format benutzt wird, können +unterschiedliche Typen angegeben werden.Beispiel:
except tkl {
mask myident@my.isp.com;
@@ -2181,9 +2268,6 @@ normale ('harte') dcc Banns.
filename "*.jpg"; /* Bilder sind üblicherweise sicher */
soft yes;
};
-allow channel {
- channel "#smart_*";
-};
4.28 - Vhost Block @@ -2296,6 +2380,7 @@ bekannt als C/N/H:Lines) leaf <leaf-mask>; leafdepth <depth>; class <class-name>; + ciphers <ssl-ciphers> options { <option>; <option>; @@ -2370,6 +2455,12 @@ definiert. Gibt den Kompressions Level (1-9) für diesen Link an. Wird nur verwendet, wenn auch "link::options::zip" gesetzt ist.
+ciphers (optional)
+Gibt die SSL Verschlüsselung an, die für diesen Link benutzt wird. Um eine
+Liste der verfügbaren Verschlüsselungscodes zu erhalten, kann man den 'openssl
+ciphers' Befehl benutzen. ciphers ist als eine durch ':' getrennte Liste
+anzugeben.
+
options block
Eine oder mehrere Optionen für eine Verbindung zu diesem Server. Wird manchmal
nicht benötigt.
@@ -2410,17 +2501,17 @@ nicht vorhanden)
Syntax [standard alias]:
alias <name> {
- nick <nick-to-forward-to>;
+ target <nick-to-forward-to>;
type <type-of-alias>;
};
(Hinweis: siehe auch hier , welche Standard Alias Dateien bei UnrealIRCd mitgeliefert werden.)
-Mit dem "alias block [standard alias]" kann festgelegt werden, daß +
Mit dem "alias block [standard alias]" kann festgelegt werden, dass ein Befehl an einen User geleitet wird. So wird z.B. durch /chanserv eine Nachricht an den "User" chanserv weitergeleitet. alias:: legt -den Namen des Befehls fest, der das Alias wird, z.B. 'chanserv'. alias::nick ist +den Namen des Befehls fest, der das Alias wird, z.B. 'chanserv'. alias::target ist der Nickname, an den weitergeleitet wird. Wenn "alias::" identisch mit -dem Nick ist, an den weitergeleitet wird, kann "alias::nick" +dem Nick ist, an den weitergeleitet wird, kann "alias::target" weggelassen werden. alias::type gibt den Typ des Alias an, gültige Typen sind hier "services" (der User ist auf dem Services Server), "stats" (der User ist auf dem Stats Server), und "normal" (der @@ -2429,7 +2520,7 @@ auch einen weiteren Zweck, der nachfolgend erkl
Syntax [Befehl alias]:
alias <name> {
format <regex-expression> {
- nick <nick-to-forward-to>;
+ target <nick-to-forward-to>;
type <type-of-alias>;
parameters <parameter-string>;
};
@@ -2445,7 +2536,7 @@ erstellen. alias::
einen regulären Ausdruck fest, der mit dem Text verglichen wird, der als Alias
Befehl gesandt wurde. Es können mehrere "alias::format" angegeben
werden, um unterschiedliche Dinge in Abhängigkeit vom gesandten Text
-durchführen zu lassen. alias::format::nick ist der Nickname, an den der
+durchführen zu lassen. alias::format::target ist das Ziel (der Name), an den der
Alias weitergeleitet wird. alias::format::type definiert den Typ des
Alias, zu dem die Nachricht geleitet wird. alias::format::parameters
ist, was als Parameter an den Alias geschickt wird. Um Parameter für einen
@@ -2453,32 +2544,10 @@ Befehl an den Alias anzugeben, wird ein "%" gefolgt von einer Nummer
angegeben. So ist z.B. %1 der erste Parameter, %2 der zweite Parameter usw.
Man kann auch festlegen, dass ab einem Parameter alle bis zum Ende gelten
sollen, dann gibt man z.B. an: %1- (das Minuszeichen bedeutet: "alle
-weiteren")
-Beispiele:
-alias "identify" {
-
-format "^#" {
-
-nick "chanserv";
-
-type services;
-
-parameters "IDENTIFY %1-";
-
-};
-
-format "^[^#]" {
-
-nick "nickserv";
- type
-services;
- parameters
-"IDENTIFY %1-";
-
-};
- type command;
-};
-
+weiteren") Zusätzlich kann man %n angeben, was durch den Nicknamen des
+Users ersetzt wird, der den befehl ausgeführt hat. Um Beispiele zum Alias Block
+zu sehen, schaue man in doc/example.conf.
+
4.33 - Help Block
@@ -2539,10 +2608,9 @@ Syntax:
};
regex ist der Ausdruck, auf den geprüft wird.
-target gibt die Art der Nachrichten an. Möglich ist hier: channel,
-private, private-notice, channel-notice, part, quit, dcc.
+target gibt die Ziele an. Eine Liste möglicher Ausdrücke (z.B.: 'channel') kann hier nachgelesen werden..
action gibt die Aktion an, die erfolgen soll. Eine Liste möglicher
-Aktionen kann hier nachgelesen werden.
+Aktionen (z.B.: 'gline') kann hier nachgelesen werden.
reason ist optional und legt den Grund für die Aktion fest, der dem User
angezeigt wird. Der Text ist in Anführungszeichen anzugeben und sollte - anders
als beim /spamfilter Befehl - keinerlei Undersores "_" zwischen den
@@ -2784,18 +2852,22 @@ Legt die ersten Zeichen eines verdeckten Hosts (+x) fest.
man hier 3 oder 4 Buchstaben, die den Netzwerksnamen bezeichnen.
set::hosts::local <locop-host-name>;
Legt den Hostnamen fest, der lokalen Operatoren zugewiesen wird, wenn sie +x
-setzen.
set::hosts::global <globop-host-name>;
Legt den Hostnamen fest, der globalen Operatoren zugewiesen wird, wenn sie +x
-setzen.
set::hosts::coadmin <coadmin-host-name>;
-Legt den Hostnamen fest, der co-admins zugewiesen wird, wenn sie +x setzen.
set::hosts::admin <admin-host-name>;
-Legt den Hostnamen fest, der Admins zugewiesen wird, wenn sie +x setzen.
set::hosts::servicesadmin <servicesadmin-host-name>;
-Legt den Hostnamen fest, der Service-Admins zugewiesen wird, wenn sie +x setzen.
set::hosts::netadmin <netadmin-host-name>;
-Legt den Hostnamen fest, der Netadmins zugewiesen wird, wenn sie +x setzen.
set::hosts::host-on-oper-up <yes/no>;
Falls auf 'yes' eingestellt, wird das H/get_host Flag akzeptiert und +x
wird automatisch bei /oper gesetzt.. Falls 'no', muss sich der User manuell +x
diff --git a/doc/unreal32docs.es.html b/doc/unreal32docs.es.html
index c272db4d9..6f903a941 100644
--- a/doc/unreal32docs.es.html
+++ b/doc/unreal32docs.es.html
@@ -1,2928 +1,2978 @@
-
-
-
Debido a la crecida de la complejidad de UnrealIRCd3.2, hemos cambiado una documentación más detallada para una más fácil navegación. Para ver esta documentación debe tener un navegador compatible. Tiene un listado debajo. Los documentos actualizados están disponibles en http://www.vulnscan.org/UnrealIrcd/unreal32docs.html - y una FAQ en http://www.vulnscan.org/UnrealIrcd/faq/. -
-Navegadores compatibles:
-
ÍNDICE / TABLA DE CONTENIDOS
- 1. Introducción y notas
- ---1.1. Notas al actualizar de 3.1.x a 3.2
- ---1.2. Notas al actualizar entre versiones 3.2
- 2. Instalación
- 3. Características
- -- 3.1. Cifrado
- -- 3.2. Módulos
- -- 3.3. Máscaras de usuario
- -- 3.4. Aliases
- -- 3.5. Helpop
- -- 3.6. Niveles de acceso a operadores
- -- 3.7. Comandos para operadores
- -- 3.8. SSL
- -- 3.9. IPv6
- -- 3.10. Zip links
- -- 3.11. Soporte conexión DNS/IP dinámico
- -- 3.12. Características anti-flood
- -- 3.13. Tipos de ban
- -- 3.14. Filtro de spam
- -- 3.15. CIDR
- -- 3.16. Otras características
- 4. Configurando su fichero unrealircd.conf
- ---4.1. Explicación del archivo
- ---4.2. Bloque me -=- (M:Line)
- ---4.3. Bloque admin -=- (A:Line)
- ---4.4. Bloque class -=- (Y:Line)
- ---4.5. Bloque allow -=- (I:Line)
- ---4.6. Bloque listen -=- (P:Line)
- ---4.7. Bloque oper -=- (O:Line)
- ---4.8. Bloque drpass -=-(X:Line)
- ---4.9. Directriz include
- ---4.10. Directriz loadmodule
- ---4.11. Bloque log
- ---4.12. Bloque TLD -=- (T:Line)
- ---4.13. Bloque ban nick -=- (Q:Line)
- ---4.14. Bloque ban user -=- (K:Line)
- ---4.15. Bloque ban ip -=- (Z:Line)
- ---4.16. Bloque ban server -=-(q:Line)
- ---4.17. Bloque ban realname -=- (n:Line)
- ---4.18. Bloque ban version
- ---4.19. Bloque ban exception -=- (E:Line)
- ---4.20. Bloque TKL exception
- ---4.21. Bloque throttle exception
- ---4.22. Bloque deny DCC -=- (dccdeny.conf)
- ---4.23. Bloque deny version -=- (V:Line)
- ---4.24. Bloque deny link -=- (D:Line / d:Line)
- ---4.25. Bloque deny channel -=- (chrestrict.conf)
- ---4.26. Bloque allow channel
- ---4.27. Bloque allow DCC
- ---4.28. Bloque vhost -=- (vhost.conf)
- ---4.29. Bloque badword -=- (badwords.conf)
- ---4.30. Bloque uline -=- (U:Line)
- ---4.31. Bloque link -=- (C/N/H:Lines)
- ---4.32. Bloque alias
- ---4.33. Bloque help
- ---4.34. Bloque official channels
- ---4.35. Bloque spamfilter
- ---4.36. Bloque set -=- (networks/unrealircd.conf)
- 5. Archivos adicionales
- 6. Modos de usuario y canal
- 7. Comandos de usuario y operador
- 8. Consejos de seguridad
- ---8.1. Contraseñas
- ---8.2. Vulnerabilidades no-IRCd
- ---8.3. Permisos y archivo de configuración
- ---8.4. Problemas de usuario
- ---8.5. SSL/SSH y análisis de conexión
- ---8.6. Ataques Denegación de Servicio (DoS) [o: cómo proteger mi hub]
- ---8.7. Información descubierta
- ---8.8. Protección contra agujeros explotables
- ---8.9. Sumario
- 9. Dudas más comunes (FAQ)
-
Este documento se escribió exclusivamente para el uso con UnrealIRCd. El uso de este documento con otro programa - o la distribución de este documento con otro programa - está terminantemente prohibida sin los permisos de escritura del Equipo de Desarrollo de UnrealIRCd. - Este documento se puede copiar, imprimir, reproducir o publicar tantas veces se quiera, para el uso de UnrealIRCd y sin - modificación alguna. – Copyright UnrealIRCd Development Team 2002-2004
-Por favor lea este manual antes de solicitar ayuda, el 80% de las dudas más frecuentes están en una - FAQ. Si todavía requiere ayuda, - puede encontrarla en irc.ircsystems.net (puerto 6667) canal #unreal-support (nota: - le pedimos que sean dudas relacionadas con UnrealIRCd, no con servicios). - Si ha encontrado un error (como un bloqueo del programa) notifíquelo en - http://bugs.unrealircd.org.
-1.1 – Notas al actualizar de 3.1.x a 3.2
-
En el caso que esté actualizando desde Unreal3.1.x a Unreal3.2 apreciará que toda la configuración ha cambiado. - Lo encontrará difícil en un principio, pero una vez la haya cambiado encontrará que es mucho mejor.
-No olvide leer la sección 3 sobre las características, todo y que conocerá algunas de 3.1.x existen cuantiosas mejoras.
-No se recomienda unir servidores 3.1.x con 3.2. Aun así, si quiere hacerlo deberá ser a partir de la versión 3.1.4, pero se recomienda encarecidamente 3.1.5.1.
-1.2 – Notas al actualizar entre versiones 3.2
-
La mejor manera de actualizar es:
-Linux:
-
Por favor lea .RELEASE.NOTES para saber los últimos cambios. - Si notifica algún cambio (o errores) entre versiones, hágalo después de haber leído el fichero.
-Instrucciones de instalación
-Linux:
-
-Windows:
-
Algunas de las características más relevantes se explican en esta sección. Da una idea general de su potencia - y a veces hace referencia al archivo de configuración (algo que quizás no conozca todavía).
-Puede omitir esta sección, sin embargo es interesante leerla antes y despues de la instalación.
-Las direcciones host de los usuarios se encriptan mediante un cifrado. Por ejemplo, si su host es d5142341.cable.wanadoo.nl, - se mostrará (en join, part, whois, etc) como rox-2DCA3201.cable.wanadoo.nl. - Esta medida es muy útil para prevenir ataques entre usuarios.
-Está controlado por el modo de usuario +x (uso: /mode tunick +x). Los administradores pueden forzar el uso por defecto, o restringir su uso.
-Un host cifrado está generado por un módulo (requerido). Actualmente existen dos módulos oficiales:
- cloak: Este es el nuevo módulo de cifrado que es mucho más seguro que el viejo. Usa md5 internamente y requiere la especificación de tres claves set::cloak-keys:: alfanuméricas [ej: "AopAS6WQH2Os6hfosh4SFJHs"]. Mire el archivo example.conf para hacerse una idea.
- oldcloak: Es el viejo cifrado usado por Unreal3.2 y anteriores. Sólo se recomienda su uso en procesos de migración y actualización. No se considera seguro (se le avisará de ello si lo usa) y deberá utilizar 'cloak' tan pronto como sus servidores puedan.
Las claves de cifrado (en adelante "cloak keys") deben ser las mismas en todos los servidores de la red. Procure que estas claves sean secretas. Si alguien las conociera, podría decodificar el host original, lo que provocaría la pérdida de efectividad del modo de usuario +x.
-UnrealIRCd soporta módulos que aportan cuantiosas ventajas:
- - Puede cargarlos, refrescarlos y descargarlos mientras tiene el servidor abierto (usando /rehash). Esto le permite corregir fallos o disponer de las nuevas mejoras de los módulos cargados y todo sin la necesidad de reiniciar.
- - Otra gente puede crear nuevos módulos con nuevos comandos, modos de usuario e incluso modos de canales.
- UnrealIRCd sólo se distribuye con unos pocos módulos. Visite www.unrealircd.com en módulos o use google para encontrar más.
-
Se necesita cargar almenos dos módulos:
- - El módulo de comandos: commands.so (commands.dll en windows)
- - El módulo de cifrado: generalmente cloak.so (cloak.dll en windows).
Las máscaras de usuario (conocidas como snomasks) son un tipo especial de modo de usuario que controla qué notificaciones del servidor quiere recibir (generalmente usado para operadores).
-Se pueden usar mediante: /mode tu nick +s MÁSCARA. Por ejemplo:: /mode yournick +s +cF
- Para quitar algunas máscaras, use algo como: /mode tunick +s -c, por ejemplo.
- Puede quitarse todas las máscaras quitándose simplemente el modo s: /mode tunick -s
Se disponen de las siguientes máscaras:
- c - conexiones locales
- F - conexiones remotas (menos de servidores de servicios)
- f - notificaciones de flood
- k - notificaciones de desconexiones forzadas [*]
- e - notificaciones de información
- j - notificaciones de medidas
- v - notificaciones de hosts virtuales
- G - notificaciones de gline/shun
- n - notificaciones de cambios de nicks locales
- N - notificaciones de cambios de nicks remotos
- q - notificaciones de denegación de nicksdeny nick (Q:line)
- s - notificaciones del servidor [*]
- S - notificaciones del filtro de spam
- [*: disponible para usuarios no operadores]
-
Puede controlar qué máscaras puede obtener (set::snomask-on-connect) y cuáles para operadores (set::snomask-on-oper, oper::snomask)
-Con los aliases puede configurar comandos de usuario. Puede, por ejemplo, permitir "/ns identify blah" sea redirigido a nickserv (que se traduciría como: privmsg nickserv identify blah). Puede incluso hacer aliases más complejos como /register sea redirigido a chanserv si el primer parámetro empieza por # o a nickserv si no empieza.
-Los aliases se configuran con los bloques alias en el archivo de configuración y puede incluír varios archivos en el mismo para la mayoría de servicios.
-UnrealIRCd tiene un sistema accesible de ayuda usando /helpop. Este comando es completamente configurable vía el bloque help. Además, se incluye el archivo help.conf con algunas nociones básicas para todos los comandos soportados.
- Por ejemplo, /helpop chmodes le muestra una lista de todos los modos de canal que tiene UnrealIRCd.
- Recuerde que si es un operador (helpop) tiene que prefijar los mensajes con '?'. Así, /helpop es /helpop ? y /helpop chmodes es /helpop ?chmodes etc..
3.6 - Niveles de acceso a operadores
-Existen varios niveles de operadores en UnrealIRCd y puede utilizar privilegios adicionales (como el uso de /gline) para cada uno, según los que necesite el operador.
-Se controla mediante opciones en el bloque oper. Vea el bloque oper para más información.
-3.7 - Comandos para operadores
-UnrealIRCd tiene muchos comandos para operadores, explicados en Comandos de usuario y operadores.
-SSL se entiende por Secure Socket Layer. Con SSL puede hacer conexiones encriptadas de una forma segura. Puede usarse para encriptar conexiones servidor a servidor y de cliente a servidor. Usará SSL para proteger contra análisis y para una autentificación de la otra máquina.
-Necesita tener compilado su servidor con soporte SSL. Además, necesitará disponer de un puerto SSL, configurable en listen::options::ssl.
-No puede conectar normalmente a un puerto SSL. Así, no podrá usar el puerto 6667 para SSL. Además se requiere un cliente o una pasarela que entienda el protocolo SSL.
-Clientes que soportan SSL: XChat, - irssi, - mIRC (6.14 y posteriores, - con pasos adicionales)
-Para clientes que no soporten SSL puede usar una pasarela como stunnel. Aquí tiene un ejemplo (para stunnel 4.x):
-
- client = yes - [irc] - accept = 127.0.0.1:6667 - connect = irc.myserv.com:6697 -- Entonces, si conecta a 127.0.0.1 en el puerto 6667, su tráfico será encriptado y enviado a irc.myserv.com - en el puerto 6697 (puerto SSL). - -
Probablemente necesitará validar certificados cuando conecte a un servidor y no los acepte a ciegas (como en el ejemplo anterior). Si no, será todavía vulnerable a ataques por análisis de conexión ("sniffing"). Sin embargo, es muy denso para explicar aquí (lea información sobre SSL, no nos pregunte). [mIRC y xchat muestran una ventana preguntando si aceptar o rechazar el certificado, eso es bueno].
-UnrealIRCd soporta IPv6. Desde la versión beta15 parece ser estable.
- Su sistema opertivo necesita tener soporte IPv6 y tenerlo activado en UnrealIRCd en ./Config.
-
Aun así, microsoft ha añadido una implementación experimental para w2k/XP que no soporta UnrealIRCd (todavía).
-Zip links se pueden utilizar para conexiones servidor a servidor, que comprime el tráfico usando zlib. Puede ahorrar un 60-80% del ancho de banda. Así pues, puede serle util para conexiones de baja capacidad o para conexiones con muchos usuarios.
-Para compilar con soporte zip links necesita responder Yes a la pregunta zlib en ./Config configurar link::options::zip (en ambos servidores).
-3.11 - Soporte conexión DNS/IP dinámico
-UnrealIRCd tiene algunas características (nuevas) que ayudan a usuarios con IP dinámicas a usar DNS dinámicos (como blah.dyndns.org). Si está conectando dos DNS dinámicos, entonces establezca link::options::nodnscache y link::options::nohostcheck. -
-3.12 - Características anti-flood
-
-Throttling
-Throttling es un método que le permite fijar un límite de cuántas veces pueden los usuarios conectarse y desconectarse de su servidor. Puede configurarlo en el bloque set::throttle para permitir X conexiones en YY segundos para la misma IP.
-Modos de canal
-Existen varios modos de canal para prevenir ataques. Algunos son:
-K = no /knock, N = no cambios de nick, C = no CTCPs, M = sólo usuarios reigstrados (+r) pueden hablar.
-Desde la versión beta18 eixste el modo +f que es mucho más avanzado...
-Modo de canal f
-En vez de usar scripts y bots para proteger un canal contra floods ahora se incluye en el propio ircd.
-Un ejemplo del modo +f es:*** Blah sets mode: +f [10j]:15
-Significa que se permiten 10 joins cada 15 segundos. Si se supera este límite el servidor pondrá el modo +i automáticamente.
-Aquí se detallan los tipos de flood:
-
-
| tipo: | -nombre: | -acción por defecto: | -otras acciones: | -comentarios | -
| c | CTCPs | auto +C | m, M | |
| j | joins | auto +i | R | |
| k | knocks | auto +K | - | para clientes locales | -
| m | messages/notices | auto +m | M | |
| n | nickchanges | auto +N | ||
| t | text | kick | b | -antiguo +f. Expulsará o baneará al usuario | -
-*** ChanOp sets mode: +f [20j,50m,7n]:15 -<ChanOp> lalala -*** 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 --- snip XX lines -- -*** Evil21 (~jiovoihew@Clk-48D826C3.e.something.org) has joined #test --server1.test.net:#test *** Channel joinflood detected (limit is 20 per 15 seconds), putting +i -*** server1.test.net sets mode: +i -<Evil2> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl -<Evil12> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl -<Evil15> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl -<Evil10> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl -<Evil8> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl --- snip XX lines -- --server1.test.net:#test *** Channel msg/noticeflood detected (limit is 50 per 15 seconds), putting +m -*** server1.test.net sets mode: +m -*** Evil1 is now known as Hmmm1 -*** Evil2 is now known as Hmmm2 -*** Evil3 is now known as Hmmm3 -*** Evil4 is now known as Hmmm4 -*** Evil5 is now known as Hmmm5 -*** Evil6 is now known as Hmmm6 -*** Evil7 is now known as Hmmm7 -*** Evil8 is now known as Hmmm8 --server1.test.net:#test *** Channel nickflood detected (limit is 7 per 15 seconds), putting +N -*** server1.test.net sets mode: +N -- -De hecho, puede complicarse más:
-Tipos de ban básicos y hosts cifrados
-UnrealIRCd soporta los bans básicos como +b nick!user@host.
-Además, si un host cifrado como 'rox-ACB17294.isp.com' y pone un ban a *!*@rox-ACB17294.isp.com,
-entonces si el usuario se pone -x (y su host es 'dial-123.isp.com') el ban continuará siendo vigente. Los bans se comprueban con los hosts virtuales y reales.
-También se admiten bans a la IP (ej: *!*@128.*) y siempre se comprueba.
-
-Los bans a IPs cifradas requieren una atención especial:
-
-Si el usuario tiene la IP 1.2.3.4 y su host cifrado es 341C6CEC.8FC6128B.303AEBC6.IP, entonces:
-Si pone +b *!*@341C6CEC.8FC6128B.303AEBC6.IP estará baneando*!*@1.2.3.4 (obviamente)
-Si pone +b *!*@*.8FC6128B.303AEBC6.IP estará baneando a *!*@1.2.3.*
-Si pone +b *!*@*.303AEBC6.IP estará baneando a *!*@1.2.*
- Puede serle útil cuando decida poner un ban.
-
- Tipos de ban extendidos
- Un ban extendido sigue este formato ~[!]<tipo>:<ban>. Se soportan los tipos:
-
-
| tipo: | -nombre | -explicación | -
| ~q | quiet | -Los usuarios que coincidan con este ban no podrán hablar, a menos que tenga +v o superior. Ej: ~q:*!*@blah.blah.com | -
| ~n | nickchange | -Los usuarios que coincidan con este ban no podrán cambiarse el nick, - a menos que tenga +v o superior. Ej: ~n:*!*@*.aol.com | -
| ~c | channel | -Si el usuario está en ese canal no podrá entrar. -Ej: ~c:#lamers | -
| ~r | realname | -Si su realname coincide no podrá entrar - Ej: ~r:*Stupid_bot_script* - NOTA: un guión bajo ('_') coincide con un espacio (' ') y un guión bajo. Será lo mismo - 'Stupid bot script v1.4'. |
-
El filtro de spam es un nuevo sistema para luchar contra el spam, la publicidad, los guasnos y otras cosas. Trabaja como las badwords pero con algunas ventajas.
-Los filtros spam se añaden vía /spamfilter que utiliza la sintaxis:
- /spamfilter [add|del|remove|+|-] [tipo] [acción] [tkltiempo] [razón] [regex]
-
| [tipo] | -especifica la ubicación, puede especificar varias ubicaciones: 'c' mensajes de canales, 'p' privados, 'n' notices, 'N' notices al canal, 'P' mensajes part, 'q' mensajes quit, 'd' dcc | -||||||||||||||||||||
| [accción] | - especifica una acción a tomar (sólo una) -
| ||||||||||||||||||||
| [tkltiempo] | -Duración de la *line añadida por el filtro, use '-' para el valor por defecto o para saltarlo (ej: si la acción es 'block') | -||||||||||||||||||||
| [razón] | -Motivo de la *line. No puede usar espacios, pero los guiones bajos ('_') se transforman en espacios. Los guiones bajos dobles ('__') en simples ('_'). Use '-' para una razón por defecto. | -||||||||||||||||||||
| [regex] | -expresión regular que debe ser filtrada | -
Puede añadir filtros de spam en el archivo de configuración pero estos filtros serán locales. Su uso se describe en el bloque spamfilter here
-
set::spamfilter::ban-time permite modificar el valor por defecto del tkltiempo (por defecto 1 día)
- set::spamfilter::ban-reason permite especificar una razón por defecto (por defecto 'Spam/advertising')
- set::spamfilter::virus-help-channel permite especificar un canal para forzar la entrada en la acción 'viruschan' (por defecto #help)
- set::spamfilter::virus-help-channel-deny permite bloquear los joins normales al canal virus-help-channel (por defecto no)
-
UnrealIRCd dispone de soporte para CIDR (Classless Interdomain Routing). CIDR te permite banear rangos de IPs. Todas las IPs se localizan en los ISPs usando CIDR. Así pues, pudiendo banear fácilmente un ISP. Unreal soporta CIDR para IPv4 y IPv6. Las máscaras CIDR se pueden usar en allow::ip, ban user::mask, ban ip::mask, except ban::mask, except throttle::mask y except tkl::mask (para gzline, gline y shun). Además, se puede utilizar CIDR en /kline, /gline, /gzline, /zline y /sun. Se utiliza el estándar de IP/bits, por ejemplo, 12.0.0.0/8 (es 127.0.0.0 - 127.255.255.255) y fe80:0:0:123::/64 (es -fe80:0:0:123:0:0:0:0 - fe80:0:0:123:ffff:ffff:ffff:ffff).
-UnrealIRCd tiene muchísimas más características que no se detallan... Deberá encontrarlas por usted mismo.
--
4.0 - Configurando su unrealircd.conf
-Antes de todo, crear un buen archivo unrealircd.conf puede tomarle algo de tiempo, probablemente entre 10 y 60 minutos. Puede intentar hacer uno rápido y mejorarlo más tarde, o puede aprender las secciones directamente paso a paso. Si tiene problemas, compruebe su sintaxis, compruebe el manual y la FAQ antes de preguntar o notificar un fallo.
-4.1 Archivo de configuración
-
El nuevo sistema está basado en bloques. Cada entrada, o bloque, tiene un formato concreto, parecido a:
-
-<nombre-bloque> <valor-bloque> {
- <directriz-bloque> <valor-directriz>;
-};
-
-<nombre-bloque> es el tipo de bloque, como me o admin. <valor-bloque> a veces requiere un valor, como /oper login, pero la mayoría de veces será un sub-tipo como en ban user.
-<directriz-bloque> es una variable individual del bloque, y <valor-directriz> es su valor asociado. Si <valor-directriz> - contiene espacios, o caracteres que representan un comentario, deberá entrecomillarlo. Si quiere usar una doble comilla, deberá escaparla \".
-Un <bloque-directriz> puede tener varias directrices. Si es el caso, tendrá sus propias subsecciones. Algunos bloques sólo requieren un <valor-bloque>, como ocurre en include. Fíjese que no hay un formato fijado, significa que el bloque entero puede aparecer en una o varias líneas. El formato mencionado es el más utilizado (y el que se usará en adelante) porque facilita su lectura.
-Nota: el archivo es sensible a mayúsculas/minúsculas. Es una notación especial usada para refererirse a las entradas. Por ejemplo, hablar de <nombre-directriz>, está diciendo <nombre-bloque>::<directriz-bloque>, y si la directriz tiene un subbloque, deberá añadir otros :: y el nombre de la subdirectriz.
-Hablar sobre una directriz sin nombre deberá hacerlo con <nombre-bloque>:: que en este caso significa <valor-bloque>, o puede tener un subbloque sin nombre.
-Se soportan tres tipos de comentario:
- # Una sola línea
- // Una sola línea
- /* Varias
- líneas */
-
Ahora que ya conoce como funciona, cree su archivo unrealircd.conf o cópielo de doc/example.conf y edítelo. Es recomendable ir paso a paso.
-4.2 - Bloque me - REQUERIDO (conocido como M:Line) -
Sintaxis:
-
-me {
- name <nombre-del-servidor>;
- info <descripción-servidor>;
- numeric <numérico>;
-};
-
-Estos valores se sobreentienden. name especifica el nombre del servidor, info su descripción y numeric el numérico con el que se identifica el servidor. Debe ser un valor entre 1 y 255 y debe ser único en la red. Otro servidor no podrá tener el mismo numérico.
-Ejemplo:
-
-me {
- name "irc.foonet.com";
- info "FooNet Server";
- numeric 1;
-};
-4.3 - Bloque admin - REQUERIDO (conocido como A:Line) -
Sintaxis:
-
-admin {
- <text-line>;
- <text-line>;
-};
-
--
El bloque admin define el texto a mostrar en /admin. Puede especificar tantas líneas como quiera que contengan, pero se suele incluir el nick de los administradores y alguna dirección e-mail de referencia.
-Ejemplo:
-
-admin {
- "Bob Smith";
- "bob";
- "widely@used.name";
-};
-4.4 - Bloque class - REQUERIDO (conocido como Y:Line) -
Sintaxis:
-
-class <nombre> {
- pingfreq <frecuencia-ping>;
- connfreq <frecuencia-connect>;
- maxclients <máximo-clientes>;
- sendq <cola-de-salida>;
- recvq <cola-de-llegada>;
-};
-
-
--
Este bloque contiene qué conexiones deben relacionarse. Generalmente tendrá varias clases, para servidores, clientes, operadores.
-name es un nombre descriptivo de la clase, como "clients" o "servers", que se usará para la referencia
-pingfreq es el número de segundos de PINGs entre servidores (se recomienda un valor entre 90 y 180)
-connfreq se usa sólo para servidores y es el número de segundos para el intento de conexión si está activado autoconnect
-maxclients especifica el número máximo de clientes o servidores que puede albergar la clase
-sendq especifica la cantidad de tráfico que puede enviar (muy alto para servidores con poco ancho de banda y mediano para clientes)
-recvq especifica la cantidad de tráfico que puede recibir y se usa para evitar flood (sólo se aplica en usuarios). Pruebe con valores entre 3000 y 8000, que es el valor por defecto
-Ejemplos:
-
-class clients {
- pingfreq 90;
- maxclients 500;
- sendq 100000;
- recvq 8000;
-};
-
-class servers {
- pingfreq 90;
- maxclients 10; /* máximo de servidores unidos al mismo tiempo */
- sendq 1000000;
- connfreq 100; /* segundos antes de cada intento de conexión */
-};
-
-
-
4.5 - Bloque allow - REQUERIDO (conocido como I:Line) -
Sintaxis:
-
-allow {
- ip <user@máscara-ip>;
- hostname <user@máscara-host>;
- class <clase-de-conexión>;
- password <contraseña> { <tipo-identificación>; };
- maxperip <máximo-usuarios-por-misma-ip>;
- redirect-server <servidor-a-redirigir>;
- redirect-port <puerto-a-redirigir>;
- options {
- <opción>;
- <opción>;
- ...
- };
-};
-
-
-Este bloque define quién puede conectar al servidor. Puede tener varios bloques allow.
-Sobre la correspondencia
- El control de acceso funciona con ip o hosts, así "hostname *@*;" y "ip *@1.2.3.4;" significa que siempre corresponderá. Además siempre tendrá preferencia el bloque que ponga después del bloque general *@*. Si quiere relacionar un bloque por ip, entonces fije el hostname a algo inválido, como "hostname NOBODY;", para hacerlo sólo por ip.
ip
- La máscara ip es de la forma user@ip, user es la ident, generalmente *, y la ip es la ip en cuestión. Ej: *@* (para todos), *@192.168.* (para direcciones que empiecen por 192.168), etc.
host
- También user@host. user user generalmente se pone a *. Ej: *@* (todos), *@*.retevision.es (sólo para retevisión.es).
password (opcional)
- Precisa una contraseña para conectar. Puede especificar el método de cifrado de la contraseña.
class
- Especifica la clase a la que se relacionará la conexión.
maxperip (opcional, recomendado)
- Le permite especificar cuántas conexiones simultáneas se permiten en el servidor.
redirect-server (opcional)
- Si la clase está llena, a qué servidor redireccionar los clientes (si el cliente lo soporta [mIRC 6 lo hace]).
redirect-port (opcional)
- Si se especifica redirect-server puede especificar el puerto, si no se asume 6667.
bloque options (opcional)
- Opciones válidas:
- useip siempre usa la ip en vez del host
- noident no utiliza la ident especificada por el cliente
- ssl sólo relaciona si el cliente usa SSL
- nopasscont relaciona aunque no se especifique contraseña (así puede poner clientes en clases diferentes si dan o no dan contraseña)
-
Ejemplos:
-
-allow {
- ip *;
- hostname *;
- class clients;
- maxperip 5;
-};
-
-allow {
- ip *@*;
- hostname *@*.passworded.ugly.people;
- class clients;
- password "f00Ness";
- maxperip 1;
-};
--
4.6 - Bloque listen - REQUERIDO (conocido como P:Line) -
-
Sintaxis:
-
-listen <ip:puerto> {
- options {
- <opción>;
- <opción>;
- ...
- };
-};
-
-
--
Este bloque especifica qué puertos deberán escucharse. Si no se requieren opciones, deberá hacerlo sin directrices, con la forma <ip>:<puerto>;.
-ip y puerto
- Puedes fijar la ip a * para enlazar con todas las ips posibles, o especificar una ip a enlazar (usada en proveedores de shells). El puerto es el puerto que se va a escuchar. Puede especificar un rango. Por ejemplo, 6660-6669 escuchará los puertos desde 6660 hasta 6669, ambos incluídos. Para usuarios IPv6 vea a continuación.
Información para usuarios IPv6
- Si tiene un servidor IPv6 necesitará englobar la IP entre llaves, com [::1]:6667 (escucha localhost en el puerto 6667). Si usa IPv6 y quiere escuchar una ip IPv4 necesitará usar ::ffff:ipv4ip. Por ejemplo, [::fff:203.123.67.1]:6667 pondrá en escucha el puerto 6667 de la ip 203.123.67.1. Obviamente puede usar *.
bloque options (opcional)
- Puede especificar opciones adicionales:
-
| puerto exclusivo para clientes | -|
| puerto exclusivo para servidores | -|
| soporte CR javachat | -|
| puerto SSL | -
Ejemplos:
-
-listen *:6601 {
- options {
- ssl;
- clientsonly;
- };
-};
-
-
-O si no hay opciones:
-listen *:8067;
- listen 213.12.31.126:6667;
- listen *:6660-6669;
4.7 - Bloque oper - RECOMENDADO (conocido comoO:Line) -
-
oper <nombre> {
- from {
- userhost <hostmask>;
- userhost <hostmask>;
- };
- password <contraseña> { <auth-type>; };
- class <clasee>;
- flags <flags>;
- flags {
- <flag>;
- <flag>;
- ...
- };
- swhois <información whois>;
- snomask <snomask>;
- maxlogins <num>;
-};
-
-El bloque oper permite asignar Operadores de Red para tu servidor. oper:: especifica el nombre de usuario para /oper. oper::from::userhost es una máscara user@host que debe coincidir. Puede especificar más de una máscara usando varios oper::from::userhost. oper::password es la contraseña que deberá especificar, oper::password:: permite especificar un método de cifrado para esta contraseña. Métodos válidos: crypt, md5, sha1 y ripemd-160. Si no utilizará método de cifrado, este bloque puede omitirse.
-Note que es sensible a maýusculas y minúsculas.
-La directriz oper::class especifica el nombre de una clase preexistente (que aparezca antes del archivo) y es a la que relacionará el operador.
-La directriz oper::flags tiene dos formatos. Si quiere usar el antiguo sistema (ej: OAa) deberá usar flags <flags>; si quiere usar el nuevo estilo, flags { <flag>; }. A continuación se detallan los flags soportados:
-Antiguo |
- Nuevo |
- Descripción | -
o |
- local |
- Le hace operador local | -
O |
- global |
- Le hace operador global | -
C |
- coadmin |
- Le hace coadmin | -
A |
- admin |
- Le hace admin | -
a |
- services-admin |
- Le hace admin de servicios | -
N |
- netadmin |
- Le hace administrador de red | -
r |
- can_rehash |
- Puede usar /rehash | -
D |
- can_die |
- Puede usar /die | -
R |
- can_restart |
- Puede usar /restart | -
h |
- helpop |
- Recibe modo +h (helpop) | -
w |
- can_wallops |
- Puede usar /wallops | -
g |
- can_globops |
- Puede usar /globops | -
c |
- can_localroute |
- Puede conectar servidores localmente | -
L |
- can_globalroute |
- Puede conectar servidores remotamente | -
k |
- can_localkill |
- Puede usar /kill en usuarios locales | -
K |
- can_globalkill |
- Puede usar /kill en usuarios remotos | -
b |
- can_kline |
- Puede usar /kline | -
B |
- can_unkline |
- Puede usar /kline -user@host | -
n |
- can_localnotice |
- Puede enviar notificaciones locales | -
G |
- can_globalnotice |
- Puede enviar notificaciones globales | -
z |
- can_zline |
- Puede usar /zline | -
t |
- can_gkline |
- Puede usar /gline, /shun y /spamfilter | -
Z |
- can_gzline |
- Puede usar /gzline | -
W |
- get_umodew |
- Recibe modo +W | -
H |
- get_host |
- Fija su host de operador | -
v |
- can_override |
- Puede usar OperOverride | -
q |
- can_setq |
- Puede usar el modo de usuario +q | -
X |
- can_addline |
- Puede usar /addline | -
d |
- can_dccdeny |
- Puede usar /dccdeny y /undccdeny | -
Algunos flags se incluyen al recibirse:
-| local | -global | -admin/coadmin | -services-admin | -netadmin | -
| can_rehash | -can_rehash | -can_rehash | -can_rehash | -can_rehash | -
| helpop | -helpop | -helpop | -helpop | -helpop | -
| can_globops | -can_globops | -can_globops | -can_globops | -can_globops | -
| can_wallops | -can_wallops | -can_wallops | -can_wallops | -can_wallops | -
| can_localroute | -can_localroute | -can_localroute | -can_localroute | -can_localroute | -
| can_localkill | -can_localkill | -can_localkill | -can_localkill | -can_localkill | -
| can_kline | -can_kline | -can_kline | -can_kline | -can_kline | -
| can_unkline | -can_unkline | -can_unkline | -can_unkline | -can_unkline | -
| can_localnotice | -can_localnotice | -can_localnotice | -can_localnotice | -can_localnotice | -
| - | can_globalroute | -can_globalroute | -can_globalroute | -can_globalroute | -
| - | can_globalkill | -can_globalkill | -can_globalkill | -can_globalkill | -
| - | can_globalnotice | -can_globalnotice | -can_globalnotice | -can_globalnotice | -
| - | - | global | -global | -global | -
| - | - | can_dccdeny | -can_dccdeny | -can_dccdeny | -
| - | - | - | can_setq | -can_setq | -
| - | - | - | - | admin | -
| - | - | - | - | services-admin | -
La directriz oper::swhois añade una línea adicional a su whois. [opcional]
-La directriz oper::snomask fija las máscaras de servidor que recibirá. Vea la sección 3.3 - [opcional]
-La directriz oper::maxlogins restringe el número de intentos para hacerse operador. Si lo fija a 1, sólo podrá haber un operador usando este bloque al mismo tiempo [opcional]
- -Ejemplo:
-
-oper bobsmith {
- class clients;
- from {
- userhost bob@smithco.com;
- userhost boblaptop@somedialupisp.com;
- };
- password "f00";
- flags {
- netadmin;
- can_gkline;
- can_gzline;
- can_zline;
- can_restart;
- can_die;
- global;
- };
- swhois "Example of a whois mask";
- snomask frebWqFv;
-};
-
-
-Un poco sobre OperOverride:
4.8 - Bloque drpass - RECOMENDADO (conocido como X:Line) -
Sintaxis:
-
-drpass {
- restart <contraseña-reinicio> { <auth-type>; };
- die <contraseña-fin> { <auth-type>; };
-};
-
-Este bloque fija las contraseñas para /restart y /die con drpass::restart y drpass::die respectivamente. Las directrices drpass::restart:: y drpass::die:: permiten especificar un método de cifrado de contraseñas. Los métodos soportados son crypt, md5, sha1 y ripemd-160.
-Eejemplo:
-
-drpass {
- restart "I-love-to-restart";
- die "die-you-stupid";
-};
-
-
Sintaxis:
- include <archivo>;
Especifica el archivo a cargar como archivo de configuración. Puede contener configuraciones de bloques e incluso contener otros archivos. Se permite el uso de comodines en el nombre del archivo para cargar varios archivos a la vez.
-ejemplo 1: un archivo de red
-
include mynetwork.network;-
Usará un archivo de red por separado, aunque ya no se necesitan; toda la configuración de red puede insertarse directamente en el archivo unrealircd.conf.
-ejemplo 2: aliases
-
include aliases/ircservices.conf-
Otro ejemplo para incluir aliases. UnrealIRCd viene con varios archivos que contienen aliases para la mayoría de servicios:
-
4.10 - Directriz loadmoule - REQUERIDO -
Sintaxis:
- loadmodule <archivo>;
Vea aquí por qué son útiles.
-Los módulos que vienen de serie con Unreal3.2:
-commands.so / commands.dll - Todos los comandos (casi todos) REQUERIDO
- cloak.so / cloak.dll - Módulo de cifrado REQUERIDO (u otro módulo de cifrado)
Cerciórese de cargar estos dos módulos
--loadmodule "src/modules/commands.so"; -loadmodule "src/modules/cloak.so"; --
o en windows:
--loadmodule "modules/commands.dll"; -loadmodule "modules/cloak.dll"; --
4.11 - Bloque log - OPCIONAL -
Sintaxis:
-
-log <archivo> {
- maxsize <tamaño-máximo>;
- flags {
- <flag>;
- <flag>;
- ...
- };
-};
-
-
-Este bloque permite loguear varios eventos: log:: contiene el nombre del archivo. log::maxsize es opcional y permite especificar el tamaño máximo que puede tener el archivo. Puede entrar este valor usando MB para megabytes, KB para kilobytes y GB para gigabytes. log::flags especifica qué tipo de información va a loguearse. Estos eventos se detallan a continuación.
-Puede especificar varios bloques para loguear varios eventos en distintos archivos.
-Flags disponibles :
-
| errors | -loguea errores | -
| kills | -loguea /kill | -
| tkl | -loguea información de *lines, shuns y spamfilters | -
| connects | -loguea conexiones/desconexiones de usuarios | -
| server-connects | -loguea conexiones/desconexiones de servidores | -
| kline | -loguea el uso /kline | -
| oper | -intento de oper | -
| sadmin-commands | -loguea el uso de los comandos /sa* (samode, sajoin, sapart, etc.) | -
| chg-commands | -loguea el uso de los comandos /chg* (chghost, chgname, chgident, etc.) | -
| oper-override | -loguea el uso de operoverride | -
| spamfilter | -loguea las coincidencias de spam | -
Ejemplo:
-
-log ircd.log {
- maxsize 5MB;
- flags {
- errors;
- kills;
- oper;
- kline;
- tkl;
- };
-};
-
-4.12 - Bloque TLD - OPCIONAL (conocido como T:Line) -
Sintaxis:
-
-tld {
- mask <hostmask>;
- motd <archivo-motd>;
- rules <archivo-reglas>;
- shortmotd <archivo-shortmotd>;
- channel <nombre-canal>;
- options {
- ssl;
- }
-};
-
-Este bloque le permite especificar motd, rules y canales para usuarios en función de su host. Es útil para tener varios motds en distintos lenguajes. tld::mask es una máscara user@host que coincide con la máscara del usuario. tld::motd, tld::shortmotd, y tld::rules especifican el motd, shortmod y archivo de reglas espectivamente para mostrar en función del host. tld::shortmotd es opcional. tld::channel es opcional y permite especificar un canal al que el usuario será forzado cuando conecte. Si existe, omitirá el canal por defecto en autojoin. El bloque tld::options le permite definir parámetros adicionales. Sólo existen tld::options::ssl para clientes SSL y tld::options::remote para clientes remotos.
-Las entradas TLD se relacionan de arriba abajo.
-Ejemplo:
-
-tld {
- mask *@*.es;<
- motd "ircd.motd.es";
- rules "ircd.rules.es";
-};
-
-4.13 - Bloque ban nick OPCIONAL (conocido como Q:Line) -
Sintaxis:
-
-ban nick {
- mask <nickname>;
- reason <razón>;
-};
-
-Este bloque permite deshabilitar el uso de ciertos nicks en su servidor. ban::mask acepta comodines para relacionar varios nicks. ban::reason permite especificar la razón de esta prohibición. Generalmente se usa para los servicios de red.
-Ejemplo:
-
-ban nick {
- mask "*C*h*a*n*S*e*r*v*";
- reason "Reservado para servicios";
-};
-
-4.14 - Bloque ban user - OPCIONAL (conocido como K:Line) -
Sintaxis:
-
-ban user {
- mask <hostmask>;
- reason <razón>;
-};
-
-Este bloque permite banear una máscara user@host para que no pueda conectar al servidor. ban::mask es una cadena con comodines. ban::reason es la razón de este bloqueo. Note que sólo es un ban local: el usuario podrá conectar a otro servidor.
-Ejemplo:
-
-ban user {
- mask *tirc@*.saturn.bbn.com;
- reason "Idiota";
-};
-
-4.15 - Bloque ban ip - OPCIONAL (conocido como Z:Line) -
Sintaxis:
-
-ban ip {
- mask <ipmask>;
- reason <razónn>;
-};
-
-Este bloque prohibe que determinadas IPs lleguen a conectar al servidor. Incluye tanto a servidores como clientes. ban::mask es una IP que puede contener comodines. ban::reason es la razón de este bloqueo.
-Ejemplo:
-
-ban ip {
- mask 192.168.1.*;
- reason "Coge una ip real lamer";
-};
-
-
4.16 - Bloque ban server - OPCIONAL (conocido como q:Line) -
Sintaxis:
-
-ban server {
- mask <server-name>;
- reason <razón>;
-};
-
-Este bloque tiene la característica de prohibir la unión de un servidor a la red. Si el servidor se une directamente a su servidor, esta unión se deniega. Si el servidor conecta a uno remoto, el servidor local lo desconectará de la red. ban::mask puede contener comodines y es el nombre del servidor que quiere prohibir. ban::reason es la razón de este bloqueo.
-Ejemplo:
-
-ban server {
- mask broken.server.my.network.com;
- reason "Está cerrado";
-};
-
-
4.17 - Bloque ban realname - OPCIONAL (conocido como n:Line) -
Sintaxis:
-
-ban realname {
- mask <realname-mask>;
- reason <reason-for-ban>;
-};
-Este bloque permite banear a clientes en función de su GECOS (realname). Es muy útil para evitar flood de clones, según algunos bots con el mismo realname. ban::mask especifica el nombre a banear y puede contener comodines. ban::reason especifica la razón de este bloqueo.
-Ejemplo:
-
-ban realname {
- mask "Bob*";
- reason "Bob apesta!";
-};
-
-4.18 - Bloque ban version - OPCIONAL -
Sintaxis:
-
-ban version {
- mask <máscara-versión>;
- reason <razón>;
- action [kill|tempshun|shun|kline|zline|gline|gzline];
-};
-
-Este bloque permite banear el uso de un determinado cliente en función de su programa mediante la respuesta CTCP version. Si el usuario no responde, el ban no prosigue. Es recomendable para evitar scripts maliciosos. ban::mask especifica la versión y puede contener comodines. ban::reason especifica la razón del bloqueo. Puede especificar también ban::action para tomar una medida, kill se usa por defecto. tempshun pondrá un shun a esa conexión. shun/kline/zline/gline/gzline lo harán a la ip (*@ip), la duración se configura en set::ban-version-tkl-time cuyo valor por defecto es de 1 día.
-Ejemplo:
-
-ban version {
- mask "*SomeLameScript*";
- reason "SomeLameScript contiene una puerta trasera";
-};
-
-ban version {
- mask "*w00tZombie*";
- reason "En ocasiones veo muertos";
- action zline;
-};
-
-4.19 - Bloque except ban - OPCIONAL (conocido como E:Line) -
Sintaxis:
-
-except ban {
- mask <hostmask>;
-};
-Este bloque permitirá al host especificado saltarse los bans. Es útil cuando se banea a todo un proveedor o ISP y quiere permitir la entrada de alguien en concreto. La directriz except::mask especifica la máscara del cliente user@host a permitir.
-Ejemplo:
-
-except ban {
- mask myident@my.isp.com;
-};
-4.20 - Bloque except tkl OPCIONAL -
Sintaxis:
-
-except tkl {
- mask <hostmask>;
- type <tipo>;
-};
-
-Este bloque permite a un usuario saltarse los bloqueos tkl puestos a su host. Es muy útil cuando se banea a todo un proveedor o ISP y quiere permitir a alguien en concreto. La directriz except::mask especifica la máscara user@host a permitir. except::type especifica el tipo de ban a saltarse. Tipos válidos: gline, gzline, qline, gqline y shun, para Glines, Global Zlines, Qlines, Global Qlines y shuns, respectivamente.
-Ejemplo:
-
-except tkl {
- mask myident@my.isp.com;
- type gline;
-};
-4.21 - Bloque except throttle - OPCIONAL -
-Sintaxis:
-
-except throttle {
- mask <ipmask>;
-};
-Este bloque especifica qué ips se saltarán la protección throttle. Sólo funciona si ha escogido throttle. except::mask especifica la ip a la que no se le aplicará el throttle.
-Ejemplo
-
-except throttle {
- mask 192.168.1.*;
-};
-4.22 - Bloque deny dcc - OPCIONAL (conocido como dccdeny.conf) -
-Sintaxis:
-
-deny dcc {
- filename <archivo-a-bloquear>;
- reason <razón>;
- soft [yes|no];
-};
-
-Este bloque permite especificar qué archivos no se pueden enviar vía DCC a través del servidor. Es muy útil para evitar la propagación de virus y troyanos.
-El parámetro deny::filename especifica el archivo en cuestión y puede contener comodines. deny::reason especifica la razón del bloqueo.
-Existe la opción deny::soft que si está fijada a 'yes' el dcc es bloqueado hasta que el usuario lo permite mediante /dccallow +nick. Vea dccallow.conf para más ejemplos.
-Ejemplo:
-
-deny dcc {
- filename virus.exe;
- reason "Virus GD";
-};
-
-deny dcc {
- filename "*.exe";
- reason "Contenido ejecutable";
- soft yes;
-};
-4.23 - Bloque deny version - OPCIONAL (conocido como V:Line) -
Sintaxis:
-
-deny version {
- mask <nombre-servidor>;
- version <versión>;
- flags <flags-compilación>;
-};
-
-Este bloque permite parar la unión de un servidor a la red en función de su versión y sus modos de compilación. El formato de este bloque es algo complicado pero no es muy difícil imaginarselo. La directriz deny::mask especifica una máscara con comodines del servidor al que se le aplica. deny::version especifica el número de protocolo que se refiere.
-Por ejemplo, 3.0 es 2301, 3.1.1/3.1.2 es 2302, 3.2 es 2303. El primer caracter de este parámetro puede ser >, <, = o !. Si es >, todas las versiones superiores a esta son bloqueadas; con < todo lo contrario; con =, sólo esa versión y con ! todas las versiones menos esta. La directriz deny::Flags permite especificar qué modos de compilación debe o no debe tener. Estos modos se ponen uno detrás de otro y si cada modo es prefijado por ! significa que no debe tenerlo.
-4.24 - Bloque deny link - OPCIONAL (conocido como D/d:Line) -
Sintaxis:
-
-deny link {
- mask <nombre-servidor>;
- rule <expresión-crule>;
- type <tipo>;
-};
-
-Este bloque permite especificar reglas para denegar la unión de servidores. La directriz deny::mask especifica el nombre de servidor con comodines al que aplicar esta regla. La directriz deny::rule es bastante compleja. Una expresión crule le permite controlar detalladamente y es algo parecido a una expresión de programación. Se soportan cuantro operadores: connected(<servermask>) devuelve true si el servidor conectado coincide, directcon(<servermask>) devuelve true si el servidor está conectado directamente a su servidor, via(<viamask>,<servermask>) devuelve true si el servidor servermask está conectado conectado a viamask y directop() devuelve true si el operador que se usa con /connect está conectado directamente a este servidor. Estos operadores pueden combinarse usando && (y), || (o) y englobados entre llaves. Además, un operador precedido por ! comprueba si devuelve false. Si la expresión entera devuelve true, entonces se deniega el link. deny::type acepta dos valores: auto (sólo para autoconnects, pero /connect seguirá funcionando) y all (aplicado a todos los intentos).
-4.25 - Bloque deny channel OPCIONAL (conocido como chrestrict.conf) -
-Sintaxis::
-
-deny channel {
- channel "<máscara-canal>";
- reason <razón>;
- redirect "<nombre-canal>";
- warn [on|off];
-};
-
--
Este bloque deshabilita la entrada a ciertos canales. La directriz deny::channel especifica los nombres de canales, con comodines, a los que los usuarios no pueden entrar. deny::reason, la razón por qué no pueden hacerlo. Además, puede especificar deny::redirect para redirigir a los usuarios a este canal. deny::warn si está en on enviará un notice a los operadores (con la snomask 'e') si algún usuario intenta entrar.
-Ejemplo:
-
-deny channel {
- channel "#unrealsucks";
- reason "Tu si que apestas!";
-};
-
-deny channel {
- channel "#*teen*sex*";
- reason "Estás salido";
- warn on;
-};
-
-deny channel {
- channel "#operhelp";
- reason "Nuestro canal de ayuda es #help, no #operhelp";
- redirect "#help";
-};
-
-
-4.26 - Bloque allow channel - OPCIONAL -
-Sintaxis:
-
-allow channel {
- channel "<máscara-canal>";
-};
-
-Este bloque especifica los canales a los que los usuarios deben entrar.
-Ejemplo:
-
-allow channel {
- channel "#algo";
-};
-
-4.27 - Bloque allow dcc - OPCIONAL -
-Sinaxis:
-
-allow dcc {
- filename "<máscara-archivo>";
- soft [yes|no];
-};
-
-Este bloque permite establecer archivos que puedan ser enviados. Si allow dcc::soft está en 'yes' se aplica a la lista 'soft dcc bans', si está en 'no' se aplica a la lista normal ('hard').
-Ejemplo:
-
-allow dcc {
- filename "*.jpg"; /* las imágenes son seguras */
- soft yes;
-};
-
-4.28 - Bloque vhost - OPCIONAL (conocido como vhosts.conf) -
-Sintaxis:
-
-vhost {
- vhost <vhost>;
- from {
- userhost <hostmask>;
- userhost <hostmask>;
- ...
- };
- login <login-name>;
- password <contraseña> { <auth-type>; };
- swhois "<swhois info>";
-};
-
-Este bloque permite usar el comando /vhost para obtener un host virtual. El parámetro vhost::vhost puede ser user@host o simplemente el host que el usuario recibirá. vhost::from::userhost contiene las máscaras user@host que deben coincidir para recibir el host virtual. Puedes especificar más de una. vhost::login es el login que utilizará y vhost::password la contraseña. vhost::password:: acepta métodos de cifrado de contraseña como crypt, md5, sha y ripemd-160. vhost::swhois añade una línea extra a su whois.
-Ejemplo:
-
-vhost {
- vhost my.own.personal.vhost.com;
- from {
- userhost my@isp.com;
- userhost myother@isp.com;
- };
- login mynick;
- password mypassword;
- swhois "Soy la monda";
-};
-
-4.29 - Bloque badword - OPCIONAL (conocido como badwords.*.conf) -
-Sintaxis:
-
-badword <tipo> {
- word <texto>;
- replace <palabra-reemplazar>;
- action <replace|block>;
-};
-
-Este bloque permite gestionar la lista de palabras para canales y usuarios con modo +G de "badwords". badword:: especifica el tipo: channel, message, quit y all. badword::word puede ser una simple palabra o una compleja expresión regular, según lo que necesite. badword::replace es una cadena por la que se reemplazará si coincide. Si se deja en blanco, se reemplazará por "<censored>". badword::action define la acción a tomar: si es replace la reemplazará y si es block bloqueará el mensaje entero. Si se deja en blanco, se asume replace.
-Ejemplo:
-
-badword channel {
- word shit;
- replace shoot;
-};
-4.30 - Bloque ulines - OPCIONAL (conocido como U:Line) -
Sintaxis: -
-ulines {
- <nombre-servidor>;
- <nombre-servidor>;
- ...
-};
-
-Este bloque define ciertos servidores para que tengan habilidades extras. Es recomendable únicamente para servidores de servicios y estadísticas, nunca para servidores normales. Cada entrada es el nombre del servidor.
-Ejemplo:
-
-ulines {
- services.mynetwork.com;
- stats.mynetwork.com;
-};
-4.31 - Bloque link - OPCIONAL (conocido como C/N/H:Lines) -
-Sintaxis:
-
-link <nombre-servidor> {
- username <usermask>;
- hostname <ipmask>;
- bind-ip <ip-a-enlazar>;
- port <puerto-a-conectar>;
- password-connect <contraseña-de-conexión-local>;
- password-receive <contraseña-de-conexión-remotas> { <auth-type>; };
- hub <hub-mask>;
- leaf <leaf-mask>;
- leafdepth <profundidad>;
- class <clase>;
- options {
- <opción>;
- <opción>;
- ...
- };
-};
-
-Este bloque es necesario para unir servidores. Tómese su tiempo para leerlo todo porque es bastante complicado y con lo que los usuarios tienen más errores.
-Primero de todo, server-name es el nombre del servidor remoto, al que quiere unir.
-username
- Puedes especificarlo si tiene una autentificación ident. Normalmente pondrá "*".
hostname
- El host o la IP del servidor remoto. Es usado por ambos lados al conectar y en la verificación del servidor que se une. Algunos ejemplos:
-
| 1.2.3.4 | -IP normal | -
| hub.blah.com | -host: sólo para conexiones salientes, nunca para entrantes a menos que link::options::nohostcheck esté presente | -
| * | -no podrá conectar a * pero sí recibir la conexión | -
| ::ffff:1.2.3.4 | -unión de ipv6 a ipv4 | -
bind-ip (opcional)
- Puede usarse para enlazar con una ip (ej: 192.168.0.1), nunca suele usarse.
port
- Puerto a conectar (en el servidor remoto).
password-connect
- Es la contraseña para conectar al servidor remoto. Debe ser texto plano.
password-receive
- Es la contraseña para validar uniones entrantes y puede ser encriptada (métodos crypt, md5, sha1 y ripemd-160). Puede dejarlo como texto plano. Generalmente es el mismo que la contraseña anterior.
hub vs leaf
- Un hub es un servidor con varios servidores unidos a él. Un leaf sólo tiene una unión, a su servidor. Un servidor o es un hub o un leaf, nunca ambos.
hub (opcional)
- Este valor es la máscara de los servidores a los que puede conectar (ej: *.mi.red).
leaf (opcional)
- Este valor es la máscara que este servidor actuará como leaf.towards.
-
leaf-depth (opcional)
- Si se especifica, la directriz leaf también debe especificarse. Este valor es la profundidad o número de uniones que puede tener.
class
- Es la clase a la se relacionará este servidor, generalmente la clase server.
compression-level (opcional)
- Especifica el nivel de compresión (1-9) si se especifica el parámetro link::options::zip.
bloque options
- Algunas de las opciones son:
-
| ssl | -si conecta a un puerto SSL | -
| autoconnect | -su servidor intentará conectar automáticamente. El tiempo usado entre intentos es el que especificó en class::connfreq (se recomienda para un sólo lado, de leaf a hub) | -
| zip | -si quiere usar compresión, ambos servidores deben soportarla | -
| nodnscache | -no guarda la IP saliente. Úselo si tiene un host dinámico (como dyndns.org) | -
| nohostcheck | -no valida el host remoto (link::hostname). Úselo si tiene un host dinámico (como dyndns.org) | -
| quarantine | -los operadores mantendrán el estado de locales, no globales | -
Ejemplo:
-
-link hub.mynet.com {
- username *;
- hostname 1.2.3.4;
- bind-ip *;
- port 7029;
- hub *;
- password-connect "LiNk";
- password-receive "LiNk";
- class servers;
- options {
- autoconnect;
- ssl;
- zip;
- };
-};
-
4.32 - Bloque alias - OPCIONAL -
-Sintaxis [alias estándar]:
-
-alias <nombre> {
- nick <nick-destino>;
- type <tipo>;
-};
-
-(Nota: puede ver más archivos de alias estándars que lleva UnrealIRCd en este enlace)
-Este bloque (estándar) le permite redireccionar comandos a usuarios, generlamente a bots como por ejemplo /chanserv para enviarle privados. alias:: especifica el nombre del comando, por ejemplo chanserv. alias::nick el nick al que se le enviará el mensaje y puede omitirse. alias::type define el tipo de alias: services (el usuario está en el servidor de servicios), stats (en el de estadísticas) y normal (en un servidor normal). Este bloque tiene otro propósito detallado a continuación.
-Sintaxis [alias de comandos]:
-
-alias <nombre> {
- format <expresión-regular> {
- nick <nick-destino>;
- type <tipo>;
- parameters <parámetros-del-mensaje>;
- };
- format <expresión-regular> {
- ...
- };
- type command;
-};
-
-Este uso es más extenso y tiene más posibilidades. Por ejemplo, puede crear aliases como /identify. alias:: es el mismo que el anterior: el nombre del comando. alias::format especifica la expresión regular que debe coincidir con el texto enviado. Si lo hace, se usan las subentradas. Así puede tener varios alias::format para seguir distintas acciones según la coincidencia, a partir de sus subentradas. alias::format::nick es el nick de destino. alias::format::type es el tipo de alias. alias::format::parameters es lo que se enviará como parámetro al alias. Para especificar un parámetro que se enviará al nick, use % seguido del número de parámetro. Por ejemplo, %1 enviará el primer parámetro. Para especificar todos los parámetros a partir de uno, use %n- donde n es el número de parámetro. Por ejemplo, %2- enviaría todos los parámetros a partir del segundo, incluído. Para más información consulte doc/example.conf.
-4.33 - Bloque help - OPCIONAL -
-Sintaxis:
-
-help <nombre> {
- <línea>;
- <línea>;
- ...
-};
-
-(Nota: use generalmente help.conf)
-Este bloque le permite crear entradas para /helpop. help:: es el valor que se pasará a /helpop como parámetro. Si se omite, se usará si no se envían parámetros a /helpop. Las entradas serán las que se mostrarán al usuario cuando lo solicite.
-4.34 - Bloque official-channels - OPCIONAL -
-Sintaxis:
-
-official-channels {
- "#canal" { topic "El topic por defecto"; };
-};
-
-Estos canales se muestran en /list, aunque no haya usuarios. topic es opcional y sólo se muestra si tiene 0 usuarios.
- -Ejemplo:
-
-official-channels {
- "#Help" { topic "Canal oficial de ayuda. Si nadie está presente, use /helpop ayuda"; };
- "#Home";
- "#Main" { topic "Canal principal"; };
-};
-
-4.35 - Bloque spamfilter - OPCIONAL -
-
-Este bloque le permite añadir filtros de spam locales.
-Vea las características del filtro de spam para más información.
-
Sintaxis:
-
-spamfilter {
- regex <palabra>;
- target { <target(s)> };
- action <acción>;
- reason <razón>;
- ban-time <tiempo>;
-};
-
-regex es la expresión regular a comparar.
- target especifica las ubicaciones: channel, private, private-notice, channel-notice, part, quit, dcc.
- action define la acción a tomar, vea aquí para las acciones posibles.
- reason opcional: especifica la razón.
- ban-time opcional: especifica la durada de la *line..
-
Ejemplos:
-
-spamfilter {
- regex "Come watch me on my webcam";
- target { private; channel; };
- action gline;
- reason "You are infected, please go to www.antivirus.xx/blah/virus=GrrTrojan";
- ban-time 6h;
-};
-
-spamfilter {
- regex "come to irc\..+\..+";
- target { private; channel; };
- action gline;
- action gline;
- reason "No spamming allowed";
-};
-
-4.36 - Bloque set - REQUERIDO (conocido como archivo unrealircd.conf/networks) -
-Este bloque se usa para configurar la red. Si sólo tiene un servidor, puede meterlo todo en el archivo unrealircd.conf. Si tiene varios, se recomienda ponerlo por separado.
-Si su servidor está en una red, puede poner la configuración de red en un archivo aparte y cargarlo con include en cada servidor.
-En este documento, la configuración y directrices están de forma <nombre-bloque>::<nombre-directriz>. Este formato no debe usarse en el archivo, debe convertirse al formato detallado a continuación. Es una representación para simplificar su lectura.
-Sintaxis:
-
-set {
- <entrada> <valor>;
- <entrada> <valor>;
- ...
-};
-
-Este bloque fija las opciones para cada servidor. Cada entrada tiene su propósito que se explica a continuación. Algunas directrices tienen subbloques que también se detallan. Hay varios puntos a prestar atención. Todas las directrices y parámetros deben estar dentro de tan sólo un bloque set. Si una directriz tiene varias opciones, deben incluirse dentro del bloque set.
- Ejemplo:
-
-set {
- kline-address my@emailaddress.com;
- auto-join #welcome;
- options {
- hide-ulines;
- };
- hosts {
- local LocalOp.MyNet.com;
- global globalop.mynet.com;
- };
-};
-Si quiere poner algunos bloques por separado, debe hacerlo en una sóla línea.
- Ejemplo:
- set { options { hide-ulines; no-stealth; }; };
-
set::kline-address <direción-email>;
- La dirección email para cualquier referencia. Valor obligado.
set::modes-on-connect <+modos>;
- Los modos que se pondrán al usuario al conectar.
set::snomask-on-connect <+modos>
- La máscara de noticias que se pondrán al usuario al conectar.
set::modes-on-oper <+modos>;
- Los modos que recibirán los operadores cuando hagan /oper.
set::snomask-on-oper <+modos>;
- La máscara de noticias que recibirán los operadores.
set::modes-on-join <+modos>;
- Los modos que se pondrán a un canal cuando sea creado. No se pueden usar los modos +qaohvbeOAzlLk.
set::restrict-usermodes <modos>
- Modos a restringir (no use + o -).
- Por ejemplo puede usar +G en modes-on-connect y G en restrict-usermodes para que no puedan quitarse este modo.
set::restrict-channelmodes <modos>
- Modos a restringir en canales (no use + o -).
- Por ejemplo puede usar +G en modes-on-join y G en restrict-channelmodes para que no puedan quitar este modo.
- NOTA: es posible usar esta característica con la opción MLOCK de los servicios si se diera el caso. Sin embargo no podemos dar soporte a eso.
set::restrict-extendedbans <tipos|*>
- No se permite el uso de bans extendidos ("*") o algunos en concreto (ej: "qc").
set::auto-join <canaless>;
- Los canales a los que se forzará el usuario a entrar. Para especificar varios, use la coma.
- [Nota: no olvide entrecomillarlo, como auto-join "#chan";]
set::oper-auto-join <canales>;
- Los canales a los que se forzará el operador entrar. Para especificar varios, use la coma.
-[Nota: no olvide entrecomillarlo, como auto-join "#chan";]
set::anti-spam-quit-message-time <tiempo>;
- Tiempo que debe transcurrir entre /quit para que el mensaje sea mostrado. Úselo para prevenir el abuso de publicidad. Si el valor es una cadena alfanumérica, use d para días, h para horas, m para minutos y s para segundos. Por ejemplo 1d2h3m significa 1 día, 2 horas y 3 minutos.
set::prefix-quit <prefijo>;
- Prefijo que se usará para preceder los mensajes en desconexiones voluntarias. Si se pone a 0 se usa "Quit:".
set::static-quit <mensaje quit >;
- Fija un mensaje permanente en desconexiones. Sea cual sea el mensaje del usuario siempre se mostrará este. Elimina la necesidad de usar anti-spam-quit-message-time, como también prefix-quit. No reemplaza errores con el mensaje static-quit.
set::static-part <no|yes|mensaje part>;
- Si se usa 'yes' se quitan todos los mensajes part. Con 'no' no modifica nada. Cualquier otro valor se usará como comentario. Puede ser algo confuso, úselo con determinación.
set::who-limit <límite>;
- Límite de entradas a mostrar en /who. Si se omite, no hay límite.
set::silence-limit <límite>;
- Límite de entradas en la lista silence. Si se omite, el límite es de 15.
set::oper-only-stats <lista-stats>;
- Lista de stats que sólo los operadores pueden usar en /stats. Omítalo para permitir a los usuarios ver toda la información o "*" para restringirla toda a operadores. Sólo se aceptan las stats en forma corta.
set::oper-only-stats {<stats-flag>; <stats-flag>;};
- El caso anterior pero con stats en forma larga.
set::maxchannelsperuser <nº-canales>;
- Límite de canales que pueden entrar los usuarios al mismo tiempo.
set::maxdccallow <nº-entradas>;
- Límite de entradas en la lista dccallow.
set::channel-command-prefix <prefijo>;
- Especifica el prefijo para mostrar el mensaje a los usuarios que estén con +d. Suele usarse para bots. Si se omite, el prefijo es "`".
set::allow-userhost-change [never|always|not-on-channels|force-rejoin]
- Especifica qué hacer cuando el user@host cambia (+x/-x/chghost/chgident/setident/vhost/etc.).
- never deshabilita todos los comandos, always los permite aunque estén en canales (causa desincronización) [por defecto], not-on-channels si el usuario no está en ningún canal, force-rejoin forzará al usuario a reentrar en los canales y se le dará op/voz, etc. si fuera necesario.
set::options::hide-ulines;
- Si está presente, los servidores u-line no se muestran en /links si lo solicita un usuario no operador.
set::options::flat-map;
- Si está presente, los servidores aparecerán directamente unidos en /map y /links, sin saber a qué servidor están unidos. Es una pequeña ayuda para evitar ataques (D)DoS a los servidores importantes o puntos vitales de la red.
set::options::show-opermotd;
- Si está presente, se mostrará el opermotd cuando hagan /oper con éxito.
set::options::identd-check;
- Si está presente, se comprobará el servidor ident y devolverá el valor del username. Si no devuelve nada o no existe servidor ident, el username se prefijará con ~. Si se omite, no se hace la comprobación.
set::options::show-connect-info;
- Si está presente, se muestran los mensajes "ident request", "hostname lookup", etc. cuando el usuario conecte.
set::options::dont-resolve;
- Si está presente, no se resolverán los hosts. Puede ser útil para acelerar la conexión.
- Note que si no se usa, el bloque allow deberá basarse en ips, no en hosts.
set::options::mkpasswd-for-everyone;
- Todos los usuarios pueden usar /mkpasswd.
set::options::allow-part-if-shunned;
- Permite usar /part a los usuarios con shun.
set::dns::timeout <timevalue>;
- Tiempo de espera del servidor DNS si no obtiene respuesta. Si el valor es una cadena alfanumérica, use d para días, h para horas, m para minutos y s para segundos. Por ejemplo 1d2h3m significa 1 día, 2 horas y 3 minutos.
set::dns::retries <nº-intentos>;
- Número de intentos si el servidor DNS no obtiene respuesta.
set::dns::nameserver <name-of-dns-server>;
- Especifica el host del servidor a usar en las búsquedas DNS.
set::network-name <nombre-de-red>;
- Fija el nombre de la red. Debe ser el mismo en todos los servidores.
set::default-server <nombre-servidor>;
- Define el servidor por defecto a conectar si la clase está llena.
set::services-server <nombre-servidor>;
- Especifica el nombre del servidor de los servicios. Requerido. Use un valor aleatorio como servicios.mi.red si no dispone de ellos.
set::stats-server <nombre-servidor>;
- Especifica el nombre del servidor de estádisticas. Si no dispone de ellas, puede omitir este valor.
set::help-channel <canal-ayuda>;
- Canal de ayuda.
set::cloak-keys { "clave1"; "clave2"; "clave3"; };
- Fija las claves de cifrado para generar los hosts virtuales. Deben ser las mismas en toda la red. Deben ser cadenas de 5 a 100 caracteres (con 10-20 es suficiente) alfanuméricas: a-z, A-Z y 0-9. Según el módulo de cifrado cargado, usará otras reglas.
set::hiddenhost-prefix <prefijo>;
- Define el prefijo del host virtual. Suele ser un reflejo del nombre de la red.
set::hosts::local <vhost-locop>;
- Define el host que se les asignará a los operadores locales si llevan +x.
set::hosts::global <vhost-globop>;
- Define el host que se les asignará a los operadores globales si llevan +x.
set::hosts::coadmin <vhost-coadmin>;
- Define el host que se les asignará a los co-admin si llevan +x.
set::hosts::admin <vhost-admin>;
- Define el host que se les asignará a los administradores si llevan +x.
set::hosts::servicesadmin <vhost-admin-servicios>;
- Define el host que se les asignará a los administradores de servicios si llevan +x.
set::hosts::netadmin <vhost-admin-red>;
- Define el host que se les asignará a los administradores de red si llevan +x.
set::hosts::host-on-oper-up <yes/no>;
- Si está en 'yes', recibirán el host automáticamente acompañado del modo +x si no lo tuvieran. Si no, deberán ponerse el modo +x manualmente.
set::ssl::egd <archivo>;
- Especifica el archivo EGD (Entropy Gathering Daemon) para SSL. Si usa OpenSSL 0.9.7 o mayor, entonces se buscan por defecto las rutas /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool,
- y /etc/entropy y no es necesario especificarlo, simplemente dejándolo en blanco (set::ssl::edg).
set::ssl::certificate <archivo>;
- Especifica la ubicación del archivo de certificado SSL.
set::ssl::key <archivo>;
- Especifica la ubicación del archivo de llave privada SSL.
set::ssl::trusted-ca-file <filename>;
- Especifica la ubicación del archivo de los CAs permitidos.
set::ssl::options::fail-if-no-clientcert;
- Sólo acepta clientes con certificado.
set::ssl::options::no-self-signed;
- Sólo acepta clientes con un certificado no propio.
set::ssl::options::verify-certificate;
- Verifica la autenticidad del certificado SSL antes de la conexión.
set::throttle::period <tiempo>
- Tiempo que debe esperar el usuario para volver a conectar si rebasa el número de intentos de conexión.
set::throttle::connections <nº>;
- Número de veces que puede conectar con el mismo host sin que se le haga throttle.
set::ident::connect-timeout <segundos>;
- Número de segundos que debe esperar a obtener respuesta del servidor ident. (por defecto: 10s).
set::ident::read-timeout <segundos>;
- Número de segundos que debe esperar respuesta (por defecto: 30s).
set::anti-flood::unknown-flood-bantime <tiempo>;
- Especifica el tiempo que debe estar bloqueado una conexión desconocida por flood.
set::anti-flood::unknown-flood-amount <kbs>;
- Especifica la cantidad de tráfico (en kilobytes) que una conexión desconocida puede enviar antes de ser desconectada.
set::anti-flood::away-flood <veces>:<periodo>
- Protección flood por away: límita el número de veces que puede usarse /away dentro de un periodo de segundos. Requiere tener activado NO_FLOOD_AWAY en config.h. Por ejemplo: away-flood 5:60s; significa podrán usar /away un máximo de 5 veces cada 60 segundos.
set::anti-flood::nick-flood <veces>:<periodo>
- Protección flood por nick: límita el número de veces que se pueden cambiar el nick dentro de un periodo de segundos. Por ejemplo: nick-flood 4:90; significa que sólo podrán cambiarse el nick 4 veces cada 90 segundos. Por defecto: 3 cada 60s.
set::default-bantime <tiempo>
- Tiempo por defecto en comandos como /kline, /gline, /zline, /shun, etc. sin parámetro. Por defecto es permanente (0).
set::modef-default-unsettime <valor>
- Tiempo por defecto para quitar un modo que se ponga debido al efecto de +f. Por ejemplo: si especifica 10, se transformarán a +f [5j#i10]:15. Por defecto no hay tiempo para quitar el modo.
set::modef-max-unsettime <valor>
- Máximo de minutos que pueden especificar en el modo +f (+f [5j#i<TIEMPO>]:15). Debe ser un valor entre 0 y 255. Por defecto 60 (1 hora).
set::ban-version-tkl-time <valor>
- Especifica cuánto debe durar una acción como zline/gline/etc en ban version. Por defecto 86400 (1 día).
set::spamfilter::ban-time <valor>
- Similar a la directriz anterior pero para filtros de spam.
set::spamfilter::ban-reason <razón>
- Razón por defecto en los filtros de spam.
set::spamfilter::virus-help-channel <canal>
- Canal usado para la acción viruschan en los filtros de spam.
set::spamfilter::virus-help-channel-deny <yes|no>
- Si está en 'yes' (o '1') sólo los usuarios invitados por el filtro de spam pueden entrar en ese canal, a excepción de los operadores.
set::spamfilter::except <target(s)>
- Estos "target(s)" se omiten del filtro de spam (no se toma ninguna acción). Puede especificar varios separándolos con comas. Ej: except "#help,#spamreport";.
| ircd.motd | -Se muestra cuando se usa /motd y (si ircd.smotd no está presente) cuando el cliente conecta | -
| ircd.smotd | -Se muestra al conectar solamente (short MOTD, motd corto) | -
| ircd.rules | -Se muestra cuando se usa /rules | -
| oper.motd | -Se muestra cuando se usa /opermotd o cuando se identifican como operadores | -
| bot.motd | -Se muestr cuando se usa /botmotd | -
6 – Modos de usuario y canal -
-Modo |
- Descripcción |
-
Channel Modes |
- |
A |
- Sólo pueden entrar administradores | -
a <nick> |
- Hace de nick administrador del canal | -
b <nick!user@host> - |
- Pone un ban | -
c |
- No se pueden enviar colores ANSI | -
C |
- No se permiten CTCP's | -
e <nick!user@host> |
- Exception ban – si alguien coincide, siempre podrá entrar al canal aunque esté baneado | -
f * <líneas:segundos> |
- Protección flood. Si se especifica * el usuario será baneado y expulsado si envía más de líneas en menos de segundos. Si no se usa *, sólo se expulsa | -
G |
- Marca el canal con la lista de "badwords" | -
M |
- Sólo pueden hablar los usuarios registrados (+r) | -
h <nick> |
- Da el estado de semi operador del canal a nick | -
i |
- Se precisa invitación | -
K |
- No se permite /knock | -
k <clave> |
- Se precisa clave para entrar | -
l <##> |
- Fija el número máximo de usuarios que puede haber en el canal | -
L <#canal> |
- Si se pasa el límite del +l, los usuarios son enviados directamente a este canal | -
m |
- Canal moderado: sólo +v y superiores pueden hablar | -
N |
- No se permiten cambios de nick en el canal | -
n |
- No se permiten mensajes externos | -
O |
- Sólo operadores pueden entrar | -
o <nick> |
- Da el estado de operador del canal a nick | -
p |
- Marca el canal como privado | -
q <nick> |
- Marca nick como fundador del canal | -
Q |
- Sólo los servidores uline pueden expulsar a los usuarios | -
R |
- Sólo pueden entrar usuarios registrados (+r) | -
S |
- Quita todos los colores | -
s |
- Hace el canal secreto | -
t |
- Sólo halfops y superiores pueden cambiar el tema del canal | -
T |
- No se permiten notices al canal | -
u |
- Auditorium – Sólo se muestran los operadores del canal en /names o /who #canal | -
V |
- No se permite /invite | -
v <nick> |
- Da voz a los usuarios (pueden hablar en canales +m) | -
z |
- Sólo pueden entrar usuarios conectados bajo SSL | -
-
Modo |
- Descripción |
-
Modos de usuario |
- |
r |
- Identifica al nick como registrado | -
s |
- Puede escuchar las notificaciones del servidor | -
v |
- Rechaza los DCC infectados automáticamente | -
o |
- Operador de red global | -
O |
- Operador de red local | -
B |
- Es un bot | -
i |
- Invisible (no se muestra en /who) | -
A |
- Administrador de servidor | -
x |
- Da al usuario un host virtual | -
q |
- Sólo ulines pueden expulsarle (sólo administradores de servicios) | -
a |
- Administrador de servicios | -
g |
- Puede leer y escribir globops y locops | -
H |
- Oculta el estado de operador de red | -
S |
- Protege a los servicios de red | -
t |
- Nota que el usuario usa un host virtual | -
C |
- Co administrador | -
d |
- No recibe mensajes de canal | -
N |
- Administrador de Red | -
w |
- Puede recibir wallops | -
h |
- Disponible para ayuda (HelpOp) | -
G |
- Filtra las palabras con la lista "badwords" | -
W |
- Le permite ver cuando le hacen /whois | -
p |
- Oculta sus canales de /whois | -
R |
- Le permite recibir mensajes de usuarios registrados (+r) | -
V |
- Usuario WebTV | -
z |
- Cliente SSL | -
T |
- Le previene de recibir CTCPs | -
7 – Tabla de comandos para usuarios y operadores
-NOTA: /helpop muestra información más actualizada. Use /helpop comando (o /helpop ?comando si es operador) para obtener más información sobre ese comando.
- -Comando |
- Descripcción |
- Quién |
-
| nick <nuevo_nick> | -Cambia tu nick. Alerta de ello a los demás usuarios. |
- Todos | -
| whois <nick> | -Muestra información sobre el nick. Incluye el nombre completo, host, canales en los que está y el estado de operador, entre otros |
- Todos | -
| who <patrón> | -Le permite buscar usuarios. El patrón incluye: nick, #canal, host (*.attbi.com) |
- Todos | -
| whowas <nick> [max_respuestas] | -Muestra información sobre un nick desconectado. Puedes especificar un max_respuestas como máximo de entradas mostradas |
- Todos | -
| ison <nick1 nick2 nick3 ...> | -Le permite comprobar si están conectados ciertos usuarios. Usado generalmente por scripts |
- Todos | -
| join <canal1,canal2, ...> | -Le permite unirse en varios canales. Si usa /join 0 sale de todos | -Todos | -
| cycle <canal1,canal2, ...> | -Reentra de los canales especificados. Es equivalente a usar PART y luego JOIN | -Todos | -
| motd [servidor] | -Muestra el motd del servidor. Añadiendo un servidor, muestra el motd de ese servidor |
- Todos | -
| rules [servidor] | -Muestra las reglas del servidor. Añadiendo un servidor, muestra las reglas de ese servidor | -Todos | -
| lusers [servidor] | -Muestra los usuarios actuales y el número máximo de usuarios en la red, globales y locales. Añadiendo un servidor, muestra los usuarios de ese servidor |
- Todos | -
| map | -Muestra el mapa de la red | -Todos | -
| quit [razón] | -Le desconecta del servidor. Si incluye una razón, se mostrará en los canales en los que esté | -Todos | -
| ping <usuario> | -Envía una petición PING a un usuario. Se usa para medir el lag. Entre servidores, se usa para verificar que todavía sigue conectado |
- Todos | -
| version <nick> | -Envía un CTCP version a un usuario. Si pertoca, el cliente responderá a ella |
- Todos | -
| links | -Muestra una lista de los servidores de la red | -Todos | -
| admin [servidor] | -Muestra la información de contacto del servidor. Si se añade un servidor, muestra la información de ese servidor |
- Todos | -
| userhost <nick> | -Muestra el userhost del nick dado. Generalmente se usa en scripts |
- Todos | -
| topic <canal> [tema] | -Topic <canal> muestra el tema del canal. Topic <canal> <mensaje> fija como tema del canal ese mensaje |
- Todos | -
| invite <nick> <canal> | -Invita a este nick a un canal (debe ser operador del canal) |
- Op Canal | -
| kick <canal,canal> <user, user> [razón] | -Expulsa a un o varios usuarios de un canal o varios canales. Puede incluir un motivo |
- Op Canal | -
| away <razón> | -Le marca como ausente. Puede incluir una razón |
- Todos | -
| Watch +-<nick> +-<nick> |
- Watch es un sistema de notificaciones en UnrealIRCd, siendo más rápido ya que usa menos recursos de red que el viejo sistema. El servidor le envía un mensaje cuando un usuario de su lista watch se desconecta o se conecta. Esta lista no se conserva a cada sesión (su cliente o script deberá enviarla cada vez que se conecte) | -Todos | -
| helpop ?<tema> or !<tema> |
- HelpOp es un nuevo sistema de ayuda. Puede usar /helpop ? <tema> o /helpop ! <tema>. Si usa "?" busca la ayuda en el propio programa. Si no obtiene ayuda, use "!" para mandarlo a los operadores de red. Si no usa ni "?" ni "!" primero consulta en la ayuda interna y si no la encuentra la manda a los operadores | -Todos | -
| list <patrón> | -
- Si no incluye un patrón, se le manda la lista de canales sin filtrar. El patrón acepta estas opciones: - >n Lista los canales con más de n personas - <n Lista los canales con menos de n personas - C>n Lista los canales creados entre ahora y hace n minutos - C<n Lista los canales creados antes de hace n minutos - T>n Lista los canales cuyos topics son mas antiguos que n minutos (que no han cambiados hace n minutos) - T<n Lista los canales cuyos topics son mas nuevo que hace n minutos - *máscara* Lista los canales que concuerdan con *máscara* - !*máscara* Lista los canales que no concuerdan con *máscara* |
- Todos | -
| Knock <canal> <mensajee> |
- Le permite hacer 'knock' en un canal para invitados preguntando por su invitación. No funcionará si el canal está en +V y +K, o si está baneado |
- Todo | -
| setname | -Le permite cambiar su nombre completo sin necesidad de reconectar |
- Todos | -
| vhost <login> <contraseña> | -Oculta su host usando un host virtual proporcionado por el servidor |
- Todos | -
| mode <canal/nick> <modo> |
- Le permite cambiar los modos de un canal o sus propios modos. Vea Modos de usuario y canales para más información |
- Todos | -
| credits | -Muestra los créditos de la gente que ha ayudado a crear UnrealIRCd |
- Todos | -
| license | -Muestra la licencia GNU | -Todos | -
| time [servidor] | -Muestra la fecha y la hora del servidor. Si añade un servidor, lo hace de ese servidor |
- Todos | -
| botmotd [servidor] |
- Muestra el mensaje para bots del servidor. Si añade un servidor, muestra el de ese servidor | -Todos | -
| identify <contraseña> | -Envía su contraseña a los servicios para identificarse como dueño de su nick |
- Todos | -
| identify <canal> <contraseña> | -Envía su contraseña a los servicios para identificarse como fundador del canal | -Todos | -
| dns <opción> | -Devuelve información sobre el caché DNS de los servidores. Muchos clientes llevan este comando incluído, por ello se recomienda usar /raw DNS. Los operadores pueden especificar una l en el primer parámetro para recibir la lista de entradas DNS | -Todos | -
| oper <userid> <contraseña> |
- Comando para identificarse como operador de red |
- IRCop | -
| wallops <mensaje> | -Envía un mensaje a los usuarios con +w | -IRCop | -
| globops <mensaje> | -Envía un mensaje a todos los IRCops | -IRCop | -
| chatops <mensaje> | -Envía un mensaje a todos los IRCops con +c | -IRCop | -
| locops <mensaje> | -Envía un mensaje a todos los IRCops locales | -IRCop | -
| adchat <mensaje> | -Envía un mensaje a todos los Administradores | -IRCop | -
| nachat <mensaje> | -Envía un mensaje a todos los Administradores de Red | -IRCop | -
| kill <nick> <razón> | -Desconecta a un usuario de la red | -IRCop | -
| kline [+|-]<user@host | nick> [<duración> <razón>] | -Banea la máscara host del servidor. Una kline no es un ban global, tan sólo local. - duración es: a) un valor en segundos, b) un valor de tiempo como '1d' es un día o c) '0' par que sea permanente. La duración y razón son opcionales. Si no se especifican se toman los valores de set::default-bantime y razón como 'no reason' - Para quitar una kline use /kline -user@host |
- IRCop | -
| zline [+|-]<*@ip> [<duración> <razón>] | -Banea una dirección IP del servidor local. Vea kline para más información. Use /zline -*@ip para quitarla | -IRCop | -
| gline [+|-]<user@host | nick> [<duración> <razón>] |
- Añade un ban global. Vea kline para más información. Use /gline -user@host para quitarla |
- IRCop | -
| shun [+|-]<user@host | nick> [<duración> <razón>] |
- Previene de que un usuario ejecute cualquier comando. Son globales. Vea kline para más información. Use /shun -user@host para quitarlo |
- IRCop | -
| gzline [+|-]<ip> [<duración> <razón>] |
- Añade una zline global. Vea kline para más información. Use /gzline -*@ip para quitarla |
- IRCop | -
| rehash <servidor> –<opciones> | -Refresca los archivos de configuración de los servidores. Añadiendo un servidor, lo hará en ese servidor. Puede pasarle varias opciones: - -motd - Sólo refresca todos los motd y rules (incluyendo el bloque tld) - -opermotd - Sólo el archivo opermotd - -botmotd - Sólo el archivo botmotd - -garbage - Fuerza un garbage collection - | IRCop | -
| restart <servidor <contraseña> |
- Reinicia el servidor. Se requiere una contraseña. Puede especificar qué servidor quiere reiniciar |
- IRCop | -
| die <contraseña> |
- Cierra el servidor. Requiere contraseña | -IRCop | -
| lag <servidor> |
- Este comando actúa como un trazado. Puede escribir /lag servidor y todos los servidores por los que pase este comando le responderán. Así verá qué puntos de la red hay más lag | -IRCop | -
| sethost <nuevohost> | -Le permite cambiar su host al que quiera |
- IRCop | -
| setident <nuevaident> |
- Le permite cambiar su ident a la que quiera | -IRCop | -
| chghost <nick> <nuevohost> |
- Cambia el host de un usuario | -IRCop | -
| chgident <nick> <nuevaident> |
- Cambia la ident de un usuario | -IRCop | -
| chgname <nick> <nuevonombre> |
- Cambia el nombre de un usuario | -IRCop | -
| squit <servidor> |
- Desconecta a un servidor de la red | -IRCop | -
| connect <servidor> [[<puerto>] <servidor>] | -Si sólo se da un servidor, intentará conectar a ese servidor. Si especifica dos servidores, intentará conectarlos entre sí. Ponga primero el leaf y luego el hub |
- IRCop | -
| dccdeny <archivo> <razón> |
- Prohibe el envío de un archivo o de archivos que coincidan con este |
- IRCop | -
| undccdeny <archivo> |
- Quita una entrada anterior | -IRCop | -
| sajoin <nick> <canal>, <canal> |
- Fuerza a un usuario a entrar en estos canales | -IRCop | -
| sapart <nick> <canal>, <canal> |
- Fuerza a un usuario a salir de estos canales | -IRCop | -
| samode <canal> <modos> |
- Permite a los Administradores de Red y Servicios cambiar los modos de un canal |
- IRCop | -
| rping <servidor> |
- Calcula en milisegundos el lag entre servidores |
- IRCop | -
| trace <servidor|nick> |
- Devuelve la clase y el lag. Si lo usa sobre un servidor, le devuelve la clase y versión |
- IRCop | -
| opermotd |
- Le muestra el opermotd |
- IRCop | -
| addmotd :<texto> |
- Añade el texto al final del motd |
- IRCop | -
| addomotd :<texto> |
- Añade el texto al final del opermotd |
- IRCop | -
| sdesc <descripción> |
- Introduce una nueva descripción del servidor sin reiniciar |
- IRCop | -
| addline <texto> |
- Le permite añadir líneas al archivo unrealircd.conf |
- IRCop | -
| mkpasswd <contraseña> |
- Encripta un texto para añadirlo en unrealircd.conf |
- IRCop | -
| tsctl offset +/- <tiempo> |
- Ajusta el reloj interno del IRCD (no lo use si no sabe lo qué es) |
- IRCop | -
| tsctl time |
- Le da el tiempo TS | -IRCop | -
| tsctl alltime | -Le da el tiempo TS de todos los servidores | -IRCop | -
| tsctl svstime <timestamp> |
- Fija el tiempo TS en todos los servidores (no lo use si no sabe lo qué es) |
- IRCop | -
| htm <opción> |
- Controla el tráfico. En modo HTM básicamente deshabilita el uso de comandos como list, whois o who, puesto que ocupan mucho ancho de banda. Opciones: - -ON Servidor en HTM - -OFF Servidor fuera de HTM - -NOISY Informa a los usuarios administradores cuando se entra y sale del modo HTM - -QUIET No informa el caso anterior - -TO <valor> Especifica el ratio a usar |
- IRCop | -
| stats <opción> |
-
- B - banversion - Lista de bans - b - badword - Lista de badwords - C - link - Lista del bloque link - d - denylinkauto - Lista del bloque deny link (auto) - D - denylinkall - Lista del bloque deny link (todo) - e - exceptthrottle - Lista del bloque except throttle - E - exceptban - Lista del bloque except ban - f - spamfilter - Lista de filtros de spam - F - denydcc - Lista del bloque deny dcc - G - gline - Lista gline - Flags: [+/-mrs] [máscara] [razón] [autor] - m Devuelve las glines que coincidan o no con la máscara - r Devuelve las glines que coincidan o no con la razón - s Devuelve las glines que coincidan o no con el autor - I - allow - Lista bloque allow - j - officialchans - Lista de canales oficiales - K - kline - Lista del bloque ban user/ban ip/except ban - l - linkinfo - Información de las uniones de servidores - L - linkinfoall - Toda la información anterior - M - command - Lista del uso de cada comando - n - banrealname - Lista del bloque ban realname - O - oper - Lista del bloque oper - S - set - Lista del bloque set - s - shun - Lista de shuns - Flags: [+/-mrs] [máscara] [razón] [autor] - m Devuelve las glines que coincidan o no con la máscara - r Devuelve las glines que coincidan o no con la razón - s Devuelve las glines que coincidan o no con el autor - P - port - Información sobre puertos - q - sqline - Lista sqline - Q - bannick - Lista del bloque ban nick - r - chanrestrict - Lista del bloque channel deny/allow - R - usage - Uso de los recursos - t - tld - Lista del bloque tld - T - traffic - Información del tráfico de datos - u - uptime - Uptime del servidor - U - uline - Lista del bloque ulines - v - denyver - Lista del bloque deny version - V - vhost - Lista del bloque vhost - X - notlink - Lista servidores que están separados de la red - Y - class - Lista del bloque class - z - zip - Información sobre la compresión zlib (si está compilado así) - Z - mem - Uso de memoria - |
- Todos | -
| module |
- - Lista todos los módulos | -Todos | -
| close |
- - Cierra todas las conexiones desconocidas | -IRCop | -
Si está preocupado por la seguridad (debería), esta sección le ayudará. Alternativamente puede usarlo como patrones a seguir en toda la red para afianzarla.
-Esta lista está ordenada de mayor a menor riesgo.
-8.2 Vulnerabilidades no-IRCD
-
8.3 Permisos y archivo de configuración
-
8.5 SSL/SSH y análisis de conexión
-
8.6 Ataques de Denegación de Servicio (DoS) [o: cómo proteger mi hub)
-
8.8 Protección contra agujeros explotables
-
9 – Dudas más frecuentes (FAQ)
-Tiene una FAQ disponible en este enlace
-Debido a la crecida de la complejidad de UnrealIRCd3.2, hemos cambiado una documentación más detallada para una más fácil navegación. Para ver esta documentación debe tener un navegador compatible. Tiene un listado debajo. Los documentos actualizados están disponibles en http://www.vulnscan.org/UnrealIrcd/unreal32docs.html + y una FAQ en http://www.vulnscan.org/UnrealIrcd/faq/. +
+Navegadores compatibles:
+
ÍNDICE / TABLA DE CONTENIDOS
+ 1. Introducción y notas
+ ---1.1. Notas al actualizar de 3.1.x a 3.2
+ ---1.2. Notas al actualizar entre versiones 3.2
+ 2. Instalación
+ 3. Características
+ -- 3.1. Cifrado
+ -- 3.2. Módulos
+ -- 3.3. Máscaras de usuario
+ -- 3.4. Aliases
+ -- 3.5. Helpop
+ -- 3.6. Niveles de acceso a operadores
+ -- 3.7. Comandos para operadores
+ -- 3.8. SSL
+ -- 3.9. IPv6
+ -- 3.10. Zip links
+ -- 3.11. Soporte conexión DNS/IP dinámico
+ -- 3.12. Características anti-flood
+ -- 3.13. Tipos de ban
+ -- 3.14. Filtro de spam
+ -- 3.15. CIDR
+ -- 3.16. Otras características
+ 4. Configurando su fichero unrealircd.conf
+ ---4.1. Explicación del archivo
+ ---4.2. Bloque me -=- (M:Line)
+ ---4.3. Bloque admin -=- (A:Line)
+ ---4.4. Bloque class -=- (Y:Line)
+ ---4.5. Bloque allow -=- (I:Line)
+ ---4.6. Bloque listen -=- (P:Line)
+ ---4.7. Bloque oper -=- (O:Line)
+ ---4.8. Bloque drpass -=-(X:Line)
+ ---4.9. Directriz include
+ ---4.10. Directriz loadmodule
+ ---4.11. Bloque log
+ ---4.12. Bloque TLD -=- (T:Line)
+ ---4.13. Bloque ban nick -=- (Q:Line)
+ ---4.14. Bloque ban user -=- (K:Line)
+ ---4.15. Bloque ban ip -=- (Z:Line)
+ ---4.16. Bloque ban server -=-(q:Line)
+ ---4.17. Bloque ban realname -=- (n:Line)
+ ---4.18. Bloque ban version
+ ---4.19. Bloque ban exception -=- (E:Line)
+ ---4.20. Bloque TKL exception
+ ---4.21. Bloque throttle exception
+ ---4.22. Bloque deny DCC -=- (dccdeny.conf)
+ ---4.23. Bloque deny version -=- (V:Line)
+ ---4.24. Bloque deny link -=- (D:Line / d:Line)
+ ---4.25. Bloque deny channel -=- (chrestrict.conf)
+ ---4.26. Bloque allow channel
+ ---4.27. Bloque allow DCC
+ ---4.28. Bloque vhost -=- (vhost.conf)
+ ---4.29. Bloque badword -=- (badwords.conf)
+ ---4.30. Bloque uline -=- (U:Line)
+ ---4.31. Bloque link -=- (C/N/H:Lines)
+ ---4.32. Bloque alias
+ ---4.33. Bloque help
+ ---4.34. Bloque official channels
+ ---4.35. Bloque spamfilter
+ ---4.36. Bloque set -=- (networks/unrealircd.conf)
+ 5. Archivos adicionales
+ 6. Modos de usuario y canal
+ 7. Comandos de usuario y operador
+ 8. Consejos de seguridad
+ ---8.1. Contraseñas
+ ---8.2. Vulnerabilidades no-IRCd
+ ---8.3. Permisos y archivo de configuración
+ ---8.4. Problemas de usuario
+ ---8.5. SSL/SSH y análisis de conexión
+ ---8.6. Ataques Denegación de Servicio (DoS) [o: cómo proteger mi hub]
+ ---8.7. Información descubierta
+ ---8.8. Protección contra agujeros explotables
+ ---8.9. Sumario
+ 9. Dudas más comunes (FAQ)
+
Este documento se escribió exclusivamente para el uso con UnrealIRCd. El uso de este documento con otro programa + o la distribución de este documento con otro programa + está terminantemente prohibida sin los permisos de escritura del Equipo de Desarrollo de UnrealIRCd. + Este documento se puede copiar, imprimir, reproducir o publicar tantas veces se quiera, para el uso de UnrealIRCd y sin + modificación alguna. – Copyright UnrealIRCd Development Team 2002-2004
+Por favor lea este manual antes de solicitar ayuda, el 80% de las dudas más frecuentes están en una + FAQ. Si todavía requiere ayuda, + puede encontrarla en irc.ircsystems.net (puerto 6667) canal #unreal-support (nota: + le pedimos que sean dudas relacionadas con UnrealIRCd, no con servicios). + Si ha encontrado un error (como un bloqueo del programa) notifíquelo en + http://bugs.unrealircd.org.
+1.1 – Notas al actualizar de 3.1.x a 3.2
+
En el caso que esté actualizando desde Unreal3.1.x a Unreal3.2 apreciará que toda la configuración ha cambiado. + Lo encontrará difícil en un principio, pero una vez la haya cambiado encontrará que es mucho mejor.
+No olvide leer la sección 3 sobre las características, todo y que conocerá algunas de 3.1.x existen cuantiosas mejoras.
+No se recomienda unir servidores 3.1.x con 3.2. Aun así, si quiere hacerlo deberá ser a partir de la versión 3.1.4, pero se recomienda encarecidamente 3.1.5.1.
+1.2 – Notas al actualizar entre versiones 3.2
+
La mejor manera de actualizar es:
+Linux:
+
Por favor lea .RELEASE.NOTES para saber los últimos cambios. + Si notifica algún cambio (o errores) entre versiones, hágalo después de haber leído el fichero.
+Instrucciones de instalación
+Linux:
+
+Windows:
+
Algunas de las características más relevantes se explican en esta sección. Da una idea general de su potencia + y a veces hace referencia al archivo de configuración (algo que quizás no conozca todavía).
+Puede omitir esta sección, sin embargo es interesante leerla antes y despues de la instalación.
+Las direcciones host de los usuarios se encriptan mediante un cifrado. Por ejemplo, si su host es d5142341.cable.wanadoo.nl, + se mostrará (en join, part, whois, etc) como rox-2DCA3201.cable.wanadoo.nl. + Esta medida es muy útil para prevenir ataques entre usuarios.
+Está controlado por el modo de usuario +x (uso: /mode tunick +x). Los administradores pueden forzar el uso por defecto, o restringir su uso.
+Un host cifrado está generado por un módulo (requerido). Actualmente existen dos módulos oficiales:
+ cloak: Este es el nuevo módulo de cifrado que es mucho más seguro que el viejo. Usa md5 internamente y requiere la especificación de tres claves set::cloak-keys:: alfanuméricas [ej: "AopAS6WQH2Os6hfosh4SFJHs"]. Mire el archivo example.conf para hacerse una idea.
+ oldcloak: Es el viejo cifrado usado por Unreal3.2 y anteriores. Sólo se recomienda su uso en procesos de migración y actualización. No se considera seguro (se le avisará de ello si lo usa) y deberá utilizar 'cloak' tan pronto como sus servidores puedan.
Las claves de cifrado (en adelante "cloak keys") deben ser las mismas en todos los servidores de la red. Procure que estas claves sean secretas. Si alguien las conociera, podría decodificar el host original, lo que provocaría la pérdida de efectividad del modo de usuario +x.
+UnrealIRCd soporta módulos que aportan cuantiosas ventajas:
+ - Puede cargarlos, refrescarlos y descargarlos mientras tiene el servidor abierto (usando /rehash). Esto le permite corregir fallos o disponer de las nuevas mejoras de los módulos cargados y todo sin la necesidad de reiniciar.
+ - Otra gente puede crear nuevos módulos con nuevos comandos, modos de usuario e incluso modos de canales.
+ UnrealIRCd sólo se distribuye con unos pocos módulos. Visite www.unrealircd.com en módulos o use google para encontrar más.
+
Se necesita cargar almenos dos módulos:
+ - El módulo de comandos: commands.so (commands.dll en windows)
+ - El módulo de cifrado: generalmente cloak.so (cloak.dll en windows).
Las máscaras de usuario (conocidas como snomasks) son un tipo especial de modo de usuario que controla qué notificaciones del servidor quiere recibir (generalmente usado para operadores).
+Se pueden usar mediante: /mode tu nick +s MÁSCARA. Por ejemplo:: /mode yournick +s +cF
+ Para quitar algunas máscaras, use algo como: /mode tunick +s -c, por ejemplo.
+ Puede quitarse todas las máscaras quitándose simplemente el modo s: /mode tunick -s
Se disponen de las siguientes máscaras:
+ c - conexiones locales
+ F - conexiones remotas (menos de servidores de servicios)
+ f - notificaciones de flood
+ k - notificaciones de desconexiones forzadas [*]
+ e - notificaciones de información
+ j - notificaciones de medidas
+ v - notificaciones de hosts virtuales
+ G - notificaciones de gline/shun
+ n - notificaciones de cambios de nicks locales
+ N - notificaciones de cambios de nicks remotos
+ q - notificaciones de denegación de nicksdeny nick (Q:line)
+ s - notificaciones del servidor [*]
+ S - notificaciones del filtro de spam
+ o - notificaciones de identificaciones de Operadores de red
+
+ [*: disponible para usuarios no operadores]
+
Puede controlar qué máscaras puede obtener (set::snomask-on-connect) y cuáles para operadores (set::snomask-on-oper, oper::snomask)
+Con los aliases puede configurar comandos de usuario. Puede, por ejemplo, permitir "/ns identify blah" sea redirigido a nickserv (que se traduciría como: privmsg nickserv identify blah). Puede incluso hacer aliases más complejos como /register sea redirigido a chanserv si el primer parámetro empieza por # o a nickserv si no empieza.
+Los aliases se configuran con los bloques alias en el archivo de configuración y puede incluír varios archivos en el mismo para la mayoría de servicios.
+UnrealIRCd tiene un sistema accesible de ayuda usando /helpop. Este comando es completamente configurable vía el bloque help. Además, se incluye el archivo help.conf con algunas nociones básicas para todos los comandos soportados.
+ Por ejemplo, /helpop chmodes le muestra una lista de todos los modos de canal que tiene UnrealIRCd.
+ Recuerde que si es un operador (helpop) tiene que prefijar los mensajes con '?'. Así, /helpop es /helpop ? y /helpop chmodes es /helpop ?chmodes etc..
3.6 - Niveles de acceso a operadores
+Existen varios niveles de operadores en UnrealIRCd y puede utilizar privilegios adicionales (como el uso de /gline) para cada uno, según los que necesite el operador.
+Se controla mediante opciones en el bloque oper. Vea el bloque oper para más información.
+3.7 - Comandos para operadores
+UnrealIRCd tiene muchos comandos para operadores, explicados en Comandos de usuario y operadores.
+SSL se entiende por Secure Socket Layer. Con SSL puede hacer conexiones encriptadas de una forma segura. Puede usarse para encriptar conexiones servidor a servidor y de cliente a servidor. Usará SSL para proteger contra análisis y para una autentificación de la otra máquina.
+Necesita tener compilado su servidor con soporte SSL. Además, necesitará disponer de un puerto SSL, configurable en listen::options::ssl.
+No puede conectar normalmente a un puerto SSL. Así, no podrá usar el puerto 6667 para SSL. Además se requiere un cliente o una pasarela que entienda el protocolo SSL.
+Clientes que soportan SSL: XChat, + irssi, + mIRC (6.14 y posteriores, + con pasos adicionales)
+Para clientes que no soporten SSL puede usar una pasarela como stunnel. Aquí tiene un ejemplo (para stunnel 4.x):
+
+ client = yes + [irc] + accept = 127.0.0.1:6667 + connect = irc.myserv.com:6697 ++ Entonces, si conecta a 127.0.0.1 en el puerto 6667, su tráfico será encriptado y enviado a irc.myserv.com + en el puerto 6697 (puerto SSL). + +
Probablemente necesitará validar certificados cuando conecte a un servidor y no los acepte a ciegas (como en el ejemplo anterior). Si no, será todavía vulnerable a ataques por análisis de conexión ("sniffing"). Sin embargo, es muy denso para explicar aquí (lea información sobre SSL, no nos pregunte). [mIRC y xchat muestran una ventana preguntando si aceptar o rechazar el certificado, eso es bueno].
+UnrealIRCd soporta IPv6. Desde la versión beta15 parece ser estable.
+ Su sistema opertivo necesita tener soporte IPv6 y tenerlo activado en UnrealIRCd en ./Config.
+
Aun así, microsoft ha añadido una implementación experimental para w2k/XP que no soporta UnrealIRCd (todavía).
+Zip links se pueden utilizar para conexiones servidor a servidor, que comprime el tráfico usando zlib. Puede ahorrar un 60-80% del ancho de banda. Así pues, puede serle util para conexiones de baja capacidad o para conexiones con muchos usuarios.
+Para compilar con soporte zip links necesita responder Yes a la pregunta zlib en ./Config configurar link::options::zip (en ambos servidores).
+3.11 - Soporte conexión DNS/IP dinámico
+UnrealIRCd tiene algunas características (nuevas) que ayudan a usuarios con IP dinámicas a usar DNS dinámicos (como blah.dyndns.org). Si está conectando dos DNS dinámicos, entonces establezca link::options::nodnscache y link::options::nohostcheck. +
+3.12 - Características anti-flood
+
+Throttling
+Throttling es un método que le permite fijar un límite de cuántas veces pueden los usuarios conectarse y desconectarse de su servidor. Puede configurarlo en el bloque set::throttle para permitir X conexiones en YY segundos para la misma IP.
+Modos de canal
+Existen varios modos de canal para prevenir ataques. Algunos son:
+K = no /knock, N = no cambios de nick, C = no CTCPs, M = sólo usuarios reigstrados (+r) pueden hablar.
+Desde la versión beta18 eixste el modo +f que es mucho más avanzado...
+Modo de canal f
+En vez de usar scripts y bots para proteger un canal contra floods ahora se incluye en el propio ircd.
+Un ejemplo del modo +f es:*** Blah sets mode: +f [10j]:15
+Significa que se permiten 10 joins cada 15 segundos. Si se supera este límite el servidor pondrá el modo +i automáticamente.
+Aquí se detallan los tipos de flood:
+
+
| tipo: | +nombre: | +acción por defecto: | +otras acciones: | +comentarios | +
| c | CTCPs | auto +C | m, M | |
| j | joins | auto +i | R | |
| k | knocks | auto +K | + | para clientes locales | +
| m | messages/notices | auto +m | M | |
| n | nickchanges | auto +N | ||
| t | text | kick | b | +antiguo +f. Expulsará o baneará al usuario | +
+*** ChanOp sets mode: +f [20j,50m,7n]:15 +<ChanOp> lalala +*** 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 +-- snip XX lines -- +*** Evil21 (~jiovoihew@Clk-48D826C3.e.something.org) has joined #test +-server1.test.net:#test *** Channel joinflood detected (limit is 20 per 15 seconds), putting +i +*** server1.test.net sets mode: +i +<Evil2> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl +<Evil12> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl +<Evil15> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl +<Evil10> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl +<Evil8> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl +-- snip XX lines -- +-server1.test.net:#test *** Channel msg/noticeflood detected (limit is 50 per 15 seconds), putting +m +*** server1.test.net sets mode: +m +*** Evil1 is now known as Hmmm1 +*** Evil2 is now known as Hmmm2 +*** Evil3 is now known as Hmmm3 +*** Evil4 is now known as Hmmm4 +*** Evil5 is now known as Hmmm5 +*** Evil6 is now known as Hmmm6 +*** Evil7 is now known as Hmmm7 +*** Evil8 is now known as Hmmm8 +-server1.test.net:#test *** Channel nickflood detected (limit is 7 per 15 seconds), putting +N +*** server1.test.net sets mode: +N ++ +De hecho, puede complicarse más:
+Tipos de ban básicos y hosts cifrados
+UnrealIRCd soporta los bans básicos como +b nick!user@host.
+Además, si un host cifrado como 'rox-ACB17294.isp.com' y pone un ban a *!*@rox-ACB17294.isp.com,
+entonces si el usuario se pone -x (y su host es 'dial-123.isp.com') el ban continuará siendo vigente. Los bans se comprueban con los hosts virtuales y reales.
+También se admiten bans a la IP (ej: *!*@128.*) y siempre se comprueba.
+
+Los bans a IPs cifradas requieren una atención especial:
+
+Si el usuario tiene la IP 1.2.3.4 y su host cifrado es 341C6CEC.8FC6128B.303AEBC6.IP, entonces:
+Si pone +b *!*@341C6CEC.8FC6128B.303AEBC6.IP estará baneando*!*@1.2.3.4 (obviamente)
+Si pone +b *!*@*.8FC6128B.303AEBC6.IP estará baneando a *!*@1.2.3.*
+Si pone +b *!*@*.303AEBC6.IP estará baneando a *!*@1.2.*
+ Puede serle útil cuando decida poner un ban.
+
+ Tipos de ban extendidos
+ Un ban extendido sigue este formato ~[!]<tipo>:<ban>. Se soportan los tipos:
+
+
| tipo: | +nombre | +explicación | +
| ~q | quiet | +Los usuarios que coincidan con este ban no podrán hablar, a menos que tenga +v o superior. Ej: ~q:*!*@blah.blah.com | +
| ~n | nickchange | +Los usuarios que coincidan con este ban no podrán cambiarse el nick, + a menos que tenga +v o superior. Ej: ~n:*!*@*.aol.com | +
| ~c | channel | +Si el usuario está en ese canal no podrá entrar. +Ej: ~c:#lamers | +
| ~r | realname | +Si su realname coincide no podrá entrar + Ej: ~r:*Stupid_bot_script* + NOTA: un guión bajo ('_') coincide con un espacio (' ') y un guión bajo. Será lo mismo + 'Stupid bot script v1.4'. |
+
El filtro de spam es un nuevo sistema para luchar contra el spam, la publicidad, los guasnos y otras cosas. Trabaja como las badwords pero con algunas ventajas.
+Los filtros spam se añaden vía /spamfilter que utiliza la sintaxis:
+ /spamfilter [add|del|remove|+|-] [tipo] [acción] [tkltiempo] [razón] [regex]
+
| [tipo] | + especifica el destino: +
|
+ |||||||||||||||||||||||||||
| [accción] | + especifica una acción a tomar (sólo una) +
| |||||||||||||||||||||||||||
| [tkltiempo] | +Duración de la *line añadida por el filtro, use '-' para el valor por defecto o para saltarlo (ej: si la acción es 'block') | +|||||||||||||||||||||||||||
| [razón] | +Motivo de la *line. No puede usar espacios, pero los guiones bajos ('_') se transforman en espacios. Los guiones bajos dobles ('__') en simples ('_'). Use '-' para una razón por defecto. | +|||||||||||||||||||||||||||
| [regex] | +expresión regular que debe ser filtrada | +
Puede añadir filtros de spam en el archivo de configuración pero estos filtros serán locales. Su uso se describe en el bloque spamfilter here
+ Ejemplo:
+
spamfilter {
+ regex "//write \$decode\(.+\|.+load -rs";
+ target { private; channel; };
+ reason "Generic $decode exploit";
+ action block;
+};
+set::spamfilter::ban-time permite modificar el valor por defecto del tkltiempo (por defecto 1 día)
+ set::spamfilter::ban-reason permite especificar una razón por defecto (por defecto 'Spam/advertising')
+ set::spamfilter::virus-help-channel permite especificar un canal para forzar la entrada en la acción 'viruschan' (por defecto #help)
+ set::spamfilter::virus-help-channel-deny permite bloquear los joins normales al canal virus-help-channel (por defecto no)
+
UnrealIRCd dispone de soporte para CIDR (Classless Interdomain Routing). CIDR te permite banear rangos de IPs. Todas las IPs se localizan en los ISPs usando CIDR. Así pues, pudiendo banear fácilmente un ISP. Unreal soporta CIDR para IPv4 y IPv6. Las máscaras CIDR se pueden usar en allow::ip, ban user::mask, ban ip::mask, except ban::mask, except throttle::mask y except tkl::mask (para gzline, gline y shun). Además, se puede utilizar CIDR en /kline, /gline, /gzline, /zline y /sun. Se utiliza el estándar de IP/bits, por ejemplo, 12.0.0.0/8 (es 127.0.0.0 - 127.255.255.255) y fe80:0:0:123::/64 (es +fe80:0:0:123:0:0:0:0 - fe80:0:0:123:ffff:ffff:ffff:ffff).
+UnrealIRCd tiene muchísimas más características que no se detallan... Deberá encontrarlas por usted mismo.
++
4.0 - Configurando su unrealircd.conf
+Antes de todo, crear un buen archivo unrealircd.conf puede tomarle algo de tiempo, probablemente entre 10 y 60 minutos. Puede intentar hacer uno rápido y mejorarlo más tarde, o puede aprender las secciones directamente paso a paso. Si tiene problemas, compruebe su sintaxis, compruebe el manual y la FAQ antes de preguntar o notificar un fallo.
+4.1 Archivo de configuración
+
El nuevo sistema está basado en bloques. Cada entrada, o bloque, tiene un formato concreto, parecido a:
+
+<nombre-bloque> <valor-bloque> {
+ <directriz-bloque> <valor-directriz>;
+};
+
+<nombre-bloque> es el tipo de bloque, como me o admin. <valor-bloque> a veces requiere un valor, como /oper login, pero la mayoría de veces será un sub-tipo como en ban user.
+<directriz-bloque> es una variable individual del bloque, y <valor-directriz> es su valor asociado. Si <valor-directriz> + contiene espacios, o caracteres que representan un comentario, deberá entrecomillarlo. Si quiere usar una doble comilla, deberá escaparla \".
+Un <bloque-directriz> puede tener varias directrices. Si es el caso, tendrá sus propias subsecciones. Algunos bloques sólo requieren un <valor-bloque>, como ocurre en include. Fíjese que no hay un formato fijado, significa que el bloque entero puede aparecer en una o varias líneas. El formato mencionado es el más utilizado (y el que se usará en adelante) porque facilita su lectura.
+Nota: el archivo es sensible a mayúsculas/minúsculas. Es una notación especial usada para refererirse a las entradas. Por ejemplo, hablar de <nombre-directriz>, está diciendo <nombre-bloque>::<directriz-bloque>, y si la directriz tiene un subbloque, deberá añadir otros :: y el nombre de la subdirectriz.
+Hablar sobre una directriz sin nombre deberá hacerlo con <nombre-bloque>:: que en este caso significa <valor-bloque>, o puede tener un subbloque sin nombre.
+Se soportan tres tipos de comentario:
+ # Una sola línea
+ // Una sola línea
+ /* Varias
+ líneas */
+
Ahora que ya conoce como funciona, cree su archivo unrealircd.conf o cópielo de doc/example.conf y edítelo. Es recomendable ir paso a paso.
+4.2 - Bloque me + REQUERIDO (conocido como M:Line) +
Sintaxis:
+
+me {
+ name <nombre-del-servidor>;
+ info <descripción-servidor>;
+ numeric <numérico>;
+};
+
+Estos valores se sobreentienden. name especifica el nombre del servidor, info su descripción y numeric el numérico con el que se identifica el servidor. Debe ser un valor entre 1 y 255 y debe ser único en la red. Otro servidor no podrá tener el mismo numérico.
+Ejemplo:
+
+me {
+ name "irc.foonet.com";
+ info "FooNet Server";
+ numeric 1;
+};
+4.3 - Bloque admin + REQUERIDO (conocido como A:Line) +
Sintaxis:
+
+admin {
+ <text-line>;
+ <text-line>;
+};
+
++
El bloque admin define el texto a mostrar en /admin. Puede especificar tantas líneas como quiera que contengan, pero se suele incluir el nick de los administradores y alguna dirección e-mail de referencia.
+Ejemplo:
+
+admin {
+ "Bob Smith";
+ "bob";
+ "widely@used.name";
+};
+4.4 - Bloque class + REQUERIDO (conocido como Y:Line) +
Sintaxis:
+
+class <nombre> {
+ pingfreq <frecuencia-ping>;
+ connfreq <frecuencia-connect>;
+ maxclients <máximo-clientes>;
+ sendq <cola-de-salida>;
+ recvq <cola-de-llegada>;
+};
+
+
++
Este bloque contiene qué conexiones deben relacionarse. Generalmente tendrá varias clases, para servidores, clientes, operadores.
+name es un nombre descriptivo de la clase, como "clients" o "servers", que se usará para la referencia
+pingfreq es el número de segundos de PINGs entre servidores (se recomienda un valor entre 90 y 180)
+connfreq se usa sólo para servidores y es el número de segundos para el intento de conexión si está activado autoconnect
+maxclients especifica el número máximo de clientes o servidores que puede albergar la clase
+sendq especifica la cantidad de tráfico que puede enviar (muy alto para servidores con poco ancho de banda y mediano para clientes)
+recvq especifica la cantidad de tráfico que puede recibir y se usa para evitar flood (sólo se aplica en usuarios). Pruebe con valores entre 3000 y 8000, que es el valor por defecto
+Ejemplos:
+
+class clients {
+ pingfreq 90;
+ maxclients 500;
+ sendq 100000;
+ recvq 8000;
+};
+
+class servers {
+ pingfreq 90;
+ maxclients 10; /* máximo de servidores unidos al mismo tiempo */
+ sendq 1000000;
+ connfreq 100; /* segundos antes de cada intento de conexión */
+};
+
+
+
4.5 - Bloque allow + REQUERIDO (conocido como I:Line) +
Sintaxis:
+
+allow {
+ ip <user@máscara-ip>;
+ hostname <user@máscara-host>;
+ class <clase-de-conexión>;
+ password <contraseña> { <tipo-identificación>; };
+ maxperip <máximo-usuarios-por-misma-ip>;
+ redirect-server <servidor-a-redirigir>;
+ redirect-port <puerto-a-redirigir>;
+ options {
+ <opción>;
+ <opción>;
+ ...
+ };
+};
+
+
+Este bloque define quién puede conectar al servidor. Puede tener varios bloques allow.
+Sobre la correspondencia
+ El control de acceso funciona con ip o hosts, así "hostname *@*;" y "ip *@1.2.3.4;" significa que siempre corresponderá. Además siempre tendrá preferencia el bloque que ponga después del bloque general *@*. Si quiere relacionar un bloque por ip, entonces fije el hostname a algo inválido, como "hostname NOBODY;", para hacerlo sólo por ip.
ip
+ La máscara ip es de la forma user@ip, user es la ident, generalmente *, y la ip es la ip en cuestión. Ej: *@* (para todos), *@192.168.* (para direcciones que empiecen por 192.168), etc.
host
+ También user@host. user user generalmente se pone a *. Ej: *@* (todos), *@*.retevision.es (sólo para retevisión.es).
password (opcional)
+ Precisa una contraseña para conectar. Puede especificar el método de cifrado de la contraseña.
class
+ Especifica la clase a la que se relacionará la conexión.
maxperip (opcional, recomendado)
+ Le permite especificar cuántas conexiones simultáneas se permiten en el servidor.
redirect-server (opcional)
+ Si la clase está llena, a qué servidor redireccionar los clientes (si el cliente lo soporta [mIRC 6 lo hace]).
redirect-port (opcional)
+ Si se especifica redirect-server puede especificar el puerto, si no se asume 6667.
bloque options (opcional)
+ Opciones válidas:
+ useip siempre usa la ip en vez del host
+ noident no utiliza la ident especificada por el cliente
+ ssl sólo relaciona si el cliente usa SSL
+ nopasscont relaciona aunque no se especifique contraseña (así puede poner clientes en clases diferentes si dan o no dan contraseña)
+
Ejemplos:
+
+allow {
+ ip *;
+ hostname *;
+ class clients;
+ maxperip 5;
+};
+
+allow {
+ ip *@*;
+ hostname *@*.passworded.ugly.people;
+ class clients;
+ password "f00Ness";
+ maxperip 1;
+};
++
4.6 - Bloque listen + REQUERIDO (conocido como P:Line) +
+
Sintaxis:
+
+listen <ip:puerto> {
+ options {
+ <opción>;
+ <opción>;
+ ...
+ };
+};
+
+
++
Este bloque especifica qué puertos deberán escucharse. Si no se requieren opciones, deberá hacerlo sin directrices, con la forma <ip>:<puerto>;.
+ip y puerto
+ Puedes fijar la ip a * para enlazar con todas las ips posibles, o especificar una ip a enlazar (usada en proveedores de shells). El puerto es el puerto que se va a escuchar. Puede especificar un rango. Por ejemplo, 6660-6669 escuchará los puertos desde 6660 hasta 6669, ambos incluídos. Para usuarios IPv6 vea a continuación.
Información para usuarios IPv6
+ Si tiene un servidor IPv6 necesitará englobar la IP entre llaves, com [::1]:6667 (escucha localhost en el puerto 6667). Si usa IPv6 y quiere escuchar una ip IPv4 necesitará usar ::ffff:ipv4ip. Por ejemplo, [::fff:203.123.67.1]:6667 pondrá en escucha el puerto 6667 de la ip 203.123.67.1. Obviamente puede usar *.
bloque options (opcional)
+ Puede especificar opciones adicionales:
+
| puerto exclusivo para clientes | +|
| puerto exclusivo para servidores | +|
| soporte CR javachat | +|
| puerto SSL | +
Ejemplos:
+
+listen *:6601 {
+ options {
+ ssl;
+ clientsonly;
+ };
+};
+
+
+O si no hay opciones:
+listen *:8067;
+ listen 213.12.31.126:6667;
+ listen *:6660-6669;
4.7 - Bloque oper + RECOMENDADO (conocido comoO:Line) +
+
oper <nombre> {
+ from {
+ userhost <hostmask>;
+ userhost <hostmask>;
+ };
+ password <contraseña> { <auth-type>; };
+ class <clasee>;
+ flags <flags>;
+ flags {
+ <flag>;
+ <flag>;
+ ...
+ };
+ swhois <información whois>;
+ snomask <snomask>;
+ maxlogins <num>;
+modes <modos>;
+};
+
+El bloque oper permite asignar Operadores de Red para tu servidor. oper:: especifica el nombre de usuario para /oper. oper::from::userhost es una máscara user@host que debe coincidir. Puede especificar más de una máscara usando varios oper::from::userhost. oper::password es la contraseña que deberá especificar, oper::password:: permite especificar un método de cifrado para esta contraseña. Métodos válidos: crypt, md5, sha1 y ripemd-160. Si no utilizará método de cifrado, este bloque puede omitirse.
+Note que es sensible a maýusculas y minúsculas.
+La directriz oper::class especifica el nombre de una clase preexistente (que aparezca antes del archivo) y es a la que relacionará el operador.
+La directriz oper::flags tiene dos formatos. Si quiere usar el antiguo sistema (ej: OAa) deberá usar flags <flags>; si quiere usar el nuevo estilo, flags { <flag>; }. A continuación se detallan los flags soportados:
+Antiguo |
+ Nuevo |
+ Descripción | +
o |
+ local |
+ Le hace operador local | +
O |
+ global |
+ Le hace operador global | +
C |
+ coadmin |
+ Le hace coadmin | +
A |
+ admin |
+ Le hace admin | +
a |
+ services-admin |
+ Le hace admin de servicios | +
N |
+ netadmin |
+ Le hace administrador de red | +
r |
+ can_rehash |
+ Puede usar /rehash | +
D |
+ can_die |
+ Puede usar /die | +
R |
+ can_restart |
+ Puede usar /restart | +
h |
+ helpop |
+ Recibe modo +h (helpop) | +
w |
+ can_wallops |
+ Puede usar /wallops | +
g |
+ can_globops |
+ Puede usar /globops | +
c |
+ can_localroute |
+ Puede conectar servidores localmente | +
L |
+ can_globalroute |
+ Puede conectar servidores remotamente | +
k |
+ can_localkill |
+ Puede usar /kill en usuarios locales | +
K |
+ can_globalkill |
+ Puede usar /kill en usuarios remotos | +
b |
+ can_kline |
+ Puede usar /kline | +
B |
+ can_unkline |
+ Puede usar /kline -user@host | +
n |
+ can_localnotice |
+ Puede enviar notificaciones locales | +
G |
+ can_globalnotice |
+ Puede enviar notificaciones globales | +
z |
+ can_zline |
+ Puede usar /zline | +
t |
+ can_gkline |
+ Puede usar /gline, /shun y /spamfilter | +
Z |
+ can_gzline |
+ Puede usar /gzline | +
W |
+ get_umodew |
+ Recibe modo +W | +
H |
+ get_host |
+ Fija su host de operador | +
v |
+ can_override |
+ Puede usar OperOverride | +
q |
+ can_setq |
+ Puede usar el modo de usuario +q | +
X |
+ can_addline |
+ Puede usar /addline | +
d |
+ can_dccdeny |
+ Puede usar /dccdeny y /undccdeny | +
Algunos flags se incluyen al recibirse:
+| local | +global | +admin/coadmin | +services-admin | +netadmin | +
| can_rehash | +can_rehash | +can_rehash | +can_rehash | +can_rehash | +
| helpop | +helpop | +helpop | +helpop | +helpop | +
| can_globops | +can_globops | +can_globops | +can_globops | +can_globops | +
| can_wallops | +can_wallops | +can_wallops | +can_wallops | +can_wallops | +
| can_localroute | +can_localroute | +can_localroute | +can_localroute | +can_localroute | +
| can_localkill | +can_localkill | +can_localkill | +can_localkill | +can_localkill | +
| can_kline | +can_kline | +can_kline | +can_kline | +can_kline | +
| can_unkline | +can_unkline | +can_unkline | +can_unkline | +can_unkline | +
| can_localnotice | +can_localnotice | +can_localnotice | +can_localnotice | +can_localnotice | +
| + | can_globalroute | +can_globalroute | +can_globalroute | +can_globalroute | +
| + | can_globalkill | +can_globalkill | +can_globalkill | +can_globalkill | +
| + | can_globalnotice | +can_globalnotice | +can_globalnotice | +can_globalnotice | +
| + | + | global | +global | +global | +
| + | + | can_dccdeny | +can_dccdeny | +can_dccdeny | +
| + | + | + | can_setq | +can_setq | +
| + | + | + | + | admin | +
| + | + | + | + | services-admin | +
La directriz oper::swhois añade una línea adicional a su whois. [opcional]
+La directriz oper::snomask fija las máscaras de servidor que recibirá. Vea la sección 3.3 + [opcional]
+La directriz oper::maxlogins restringe el número de intentos para hacerse operador. Si lo fija a 1, sólo podrá haber un operador usando este bloque al mismo tiempo [opcional]
+La directriz oper::modes establece qué modos recibe el operador cuando se identifica. [opcional]
+Ejemplo:
+
+oper bobsmith {
+ class clients;
+ from {
+ userhost bob@smithco.com;
+ userhost boblaptop@somedialupisp.com;
+ };
+ password "f00";
+ flags {
+ netadmin;
+ can_gkline;
+ can_gzline;
+ can_zline;
+ can_restart;
+ can_die;
+ global;
+ };
+ swhois "Example of a whois mask";
+ snomask frebWqFv;
+};
+
+
+Un poco sobre OperOverride:
4.8 - Bloque drpass + RECOMENDADO (conocido como X:Line) +
Sintaxis:
+
+drpass {
+ restart <contraseña-reinicio> { <auth-type>; };
+ die <contraseña-fin> { <auth-type>; };
+};
+
+Este bloque fija las contraseñas para /restart y /die con drpass::restart y drpass::die respectivamente. Las directrices drpass::restart:: y drpass::die:: permiten especificar un método de cifrado de contraseñas. Los métodos soportados son crypt, md5, sha1 y ripemd-160.
+Eejemplo:
+
+drpass {
+ restart "I-love-to-restart";
+ die "die-you-stupid";
+};
+
+
Sintaxis:
+ include <archivo>;
Especifica el archivo a cargar como archivo de configuración. Puede contener configuraciones de bloques e incluso contener otros archivos. Se permite el uso de comodines en el nombre del archivo para cargar varios archivos a la vez.
+ejemplo 1: un archivo de red
+
include mynetwork.network;+
Usará un archivo de red por separado, aunque ya no se necesitan; toda la configuración de red puede insertarse directamente en el archivo unrealircd.conf.
+ejemplo 2: aliases
+
include aliases/ircservices.conf+
Otro ejemplo para incluir aliases. UnrealIRCd viene con varios archivos que contienen aliases para la mayoría de servicios:
+
4.10 - Directriz loadmoule + REQUERIDO +
Sintaxis:
+ loadmodule <archivo>;
Vea aquí por qué son útiles.
+Los módulos que vienen de serie con Unreal3.2:
+commands.so / commands.dll - Todos los comandos (casi todos) REQUERIDO
+ cloak.so / cloak.dll - Módulo de cifrado REQUERIDO (u otro módulo de cifrado)
Cerciórese de cargar estos dos módulos
++loadmodule "src/modules/commands.so"; +loadmodule "src/modules/cloak.so"; ++
o en windows:
++loadmodule "modules/commands.dll"; +loadmodule "modules/cloak.dll"; ++
4.11 - Bloque log + OPCIONAL +
Sintaxis:
+
+log <archivo> {
+ maxsize <tamaño-máximo>;
+ flags {
+ <flag>;
+ <flag>;
+ ...
+ };
+};
+
+
+Este bloque permite loguear varios eventos: log:: contiene el nombre del archivo. log::maxsize es opcional y permite especificar el tamaño máximo que puede tener el archivo. Puede entrar este valor usando MB para megabytes, KB para kilobytes y GB para gigabytes. log::flags especifica qué tipo de información va a loguearse. Estos eventos se detallan a continuación.
+Puede especificar varios bloques para loguear varios eventos en distintos archivos.
+Flags disponibles :
+
| errors | +loguea errores | +
| kills | +loguea /kill | +
| tkl | +loguea información de *lines, shuns y spamfilters | +
| connects | +loguea conexiones/desconexiones de usuarios | +
| server-connects | +loguea conexiones/desconexiones de servidores | +
| kline | +loguea el uso /kline | +
| oper | +intento de oper | +
| sadmin-commands | +loguea el uso de los comandos /sa* (samode, sajoin, sapart, etc.) | +
| chg-commands | +loguea el uso de los comandos /chg* (chghost, chgname, chgident, etc.) | +
| oper-override | +loguea el uso de operoverride | +
| spamfilter | +loguea las coincidencias de spam | +
Ejemplo:
+
+log ircd.log {
+ maxsize 5MB;
+ flags {
+ errors;
+ kills;
+ oper;
+ kline;
+ tkl;
+ };
+};
+
+4.12 - Bloque TLD + OPCIONAL (conocido como T:Line) +
Sintaxis:
+
+tld {
+ mask <hostmask>;
+ motd <archivo-motd>;
+ rules <archivo-reglas>;
+ shortmotd <archivo-shortmotd>;
+ channel <nombre-canal>;
+ options {
+ ssl;
+ }
+};
+
+Este bloque le permite especificar motd, rules y canales para usuarios en función de su host. Es útil para tener varios motds en distintos lenguajes. tld::mask es una máscara user@host que coincide con la máscara del usuario. tld::motd, tld::shortmotd, y tld::rules especifican el motd, shortmod y archivo de reglas espectivamente para mostrar en función del host. tld::shortmotd es opcional. tld::channel es opcional y permite especificar un canal al que el usuario será forzado cuando conecte. Si existe, omitirá el canal por defecto en autojoin. El bloque tld::options le permite definir parámetros adicionales. Sólo existen tld::options::ssl para clientes SSL y tld::options::remote para clientes remotos.
+Las entradas TLD se relacionan de arriba abajo.
+Ejemplo:
+
+tld {
+ mask *@*.es;<
+ motd "ircd.motd.es";
+ rules "ircd.rules.es";
+};
+
+4.13 - Bloque ban nick OPCIONAL (conocido como Q:Line) +
Sintaxis:
+
+ban nick {
+ mask <nickname>;
+ reason <razón>;
+};
+
+Este bloque permite deshabilitar el uso de ciertos nicks en su servidor. ban::mask acepta comodines para relacionar varios nicks. ban::reason permite especificar la razón de esta prohibición. Generalmente se usa para los servicios de red.
+Ejemplo:
+
+ban nick {
+ mask "*C*h*a*n*S*e*r*v*";
+ reason "Reservado para servicios";
+};
+
+4.14 - Bloque ban user + OPCIONAL (conocido como K:Line) +
Sintaxis:
+
+ban user {
+ mask <hostmask>;
+ reason <razón>;
+};
+
+Este bloque permite banear una máscara user@host para que no pueda conectar al servidor. ban::mask es una cadena con comodines. ban::reason es la razón de este bloqueo. Note que sólo es un ban local: el usuario podrá conectar a otro servidor.
+Ejemplo:
+
+ban user {
+ mask *tirc@*.saturn.bbn.com;
+ reason "Idiota";
+};
+
+4.15 - Bloque ban ip + OPCIONAL (conocido como Z:Line) +
Sintaxis:
+
+ban ip {
+ mask <ipmask>;
+ reason <razónn>;
+};
+
+Este bloque prohibe que determinadas IPs lleguen a conectar al servidor. Incluye tanto a servidores como clientes. ban::mask es una IP que puede contener comodines. ban::reason es la razón de este bloqueo.
+Ejemplo:
+
+ban ip {
+ mask 192.168.1.*;
+ reason "Coge una ip real lamer";
+};
+
+
4.16 - Bloque ban server + OPCIONAL (conocido como q:Line) +
Sintaxis:
+
+ban server {
+ mask <server-name>;
+ reason <razón>;
+};
+
+Este bloque tiene la característica de prohibir la unión de un servidor a la red. Si el servidor se une directamente a su servidor, esta unión se deniega. Si el servidor conecta a uno remoto, el servidor local lo desconectará de la red. ban::mask puede contener comodines y es el nombre del servidor que quiere prohibir. ban::reason es la razón de este bloqueo.
+Ejemplo:
+
+ban server {
+ mask broken.server.my.network.com;
+ reason "Está cerrado";
+};
+
+
4.17 - Bloque ban realname + OPCIONAL (conocido como n:Line) +
Sintaxis:
+
+ban realname {
+ mask <realname-mask>;
+ reason <reason-for-ban>;
+};
+Este bloque permite banear a clientes en función de su GECOS (realname). Es muy útil para evitar flood de clones, según algunos bots con el mismo realname. ban::mask especifica el nombre a banear y puede contener comodines. ban::reason especifica la razón de este bloqueo.
+Ejemplo:
+
+ban realname {
+ mask "Bob*";
+ reason "Bob apesta!";
+};
+
+4.18 - Bloque ban version + OPCIONAL +
Sintaxis:
+
+ban version {
+ mask <máscara-versión>;
+ reason <razón>;
+ action [kill|tempshun|shun|kline|zline|gline|gzline];
+};
+
+Este bloque permite banear el uso de un determinado cliente en función de su programa mediante la respuesta CTCP version. Si el usuario no responde, el ban no prosigue. Es recomendable para evitar scripts maliciosos. ban::mask especifica la versión y puede contener comodines. ban::reason especifica la razón del bloqueo. Puede especificar también ban::action para tomar una medida, kill se usa por defecto. tempshun pondrá un shun a esa conexión. shun/kline/zline/gline/gzline lo harán a la ip (*@ip), la duración se configura en set::ban-version-tkl-time cuyo valor por defecto es de 1 día.
+Ejemplo:
+
+ban version {
+ mask "*SomeLameScript*";
+ reason "SomeLameScript contiene una puerta trasera";
+};
+
+ban version {
+ mask "*w00tZombie*";
+ reason "En ocasiones veo muertos";
+ action zline;
+};
+
+4.19 - Bloque except ban + OPCIONAL (conocido como E:Line) +
Sintaxis:
+
+except ban {
+ mask <hostmask>;
+};
+Este bloque permitirá al host especificado saltarse los bans. Es útil cuando se banea a todo un proveedor o ISP y quiere permitir la entrada de alguien en concreto. La directriz except::mask especifica la máscara del cliente user@host a permitir.
+Ejemplo:
+
+except ban {
+ mask myident@my.isp.com;
+};
+4.20 - Bloque except tkl OPCIONAL +
Sintaxis:
+
+except tkl {
+ mask <hostmask>;
+ type <tipo>;
+ type {
+ <type>;
+ <type>;
+ ...
+ };
+};
+
+Este bloque permite a un usuario saltarse los bloqueos tkl puestos a su host. Es muy útil cuando se banea a todo un proveedor o ISP y quiere permitir a alguien en concreto. La directriz except::mask especifica la máscara user@host a permitir. except::type especifica el tipo de ban a saltarse. Tipos válidos: gline, gzline, qline, gqline y shun, para Glines, Global Zlines, Qlines, Global Qlines y shuns, respectivamente. +Si se usa el formato type { }, se pueden especificar varios tipos a la vez.
+Ejemplo:
+
+except tkl {
+ mask myident@my.isp.com;
+ type gline;
+};
+4.21 - Bloque except throttle + OPCIONAL +
+Sintaxis:
+
+except throttle {
+ mask <ipmask>;
+};
+Este bloque especifica qué ips se saltarán la protección throttle. Sólo funciona si ha escogido throttle. except::mask especifica la ip a la que no se le aplicará el throttle.
+Ejemplo
+
+except throttle {
+ mask 192.168.1.*;
+};
+4.22 - Bloque deny dcc + OPCIONAL (conocido como dccdeny.conf) +
+Sintaxis:
+
+deny dcc {
+ filename <archivo-a-bloquear>;
+ reason <razón>;
+ soft [yes|no];
+};
+
+Este bloque permite especificar qué archivos no se pueden enviar vía DCC a través del servidor. Es muy útil para evitar la propagación de virus y troyanos.
+El parámetro deny::filename especifica el archivo en cuestión y puede contener comodines. deny::reason especifica la razón del bloqueo.
+Existe la opción deny::soft que si está fijada a 'yes' el dcc es bloqueado hasta que el usuario lo permite mediante /dccallow +nick. Vea dccallow.conf para más ejemplos.
+Ejemplo:
+
+deny dcc {
+ filename virus.exe;
+ reason "Virus GD";
+};
+
+deny dcc {
+ filename "*.exe";
+ reason "Contenido ejecutable";
+ soft yes;
+};
+4.23 - Bloque deny version + OPCIONAL (conocido como V:Line) +
Sintaxis:
+
+deny version {
+ mask <nombre-servidor>;
+ version <versión>;
+ flags <flags-compilación>;
+};
+
+Este bloque permite parar la unión de un servidor a la red en función de su versión y sus modos de compilación. El formato de este bloque es algo complicado pero no es muy difícil imaginarselo. La directriz deny::mask especifica una máscara con comodines del servidor al que se le aplica. deny::version especifica el número de protocolo que se refiere.
+Por ejemplo, 3.0 es 2301, 3.1.1/3.1.2 es 2302, 3.2 es 2303. El primer caracter de este parámetro puede ser >, <, = o !. Si es >, todas las versiones superiores a esta son bloqueadas; con < todo lo contrario; con =, sólo esa versión y con ! todas las versiones menos esta. La directriz deny::Flags permite especificar qué modos de compilación debe o no debe tener. Estos modos se ponen uno detrás de otro y si cada modo es prefijado por ! significa que no debe tenerlo.
+4.24 - Bloque deny link + OPCIONAL (conocido como D/d:Line) +
Sintaxis:
+
+deny link {
+ mask <nombre-servidor>;
+ rule <expresión-crule>;
+ type <tipo>;
+};
+
+Este bloque permite especificar reglas para denegar la unión de servidores. La directriz deny::mask especifica el nombre de servidor con comodines al que aplicar esta regla. La directriz deny::rule es bastante compleja. Una expresión crule le permite controlar detalladamente y es algo parecido a una expresión de programación. Se soportan cuantro operadores: connected(<servermask>) devuelve true si el servidor conectado coincide, directcon(<servermask>) devuelve true si el servidor está conectado directamente a su servidor, via(<viamask>,<servermask>) devuelve true si el servidor servermask está conectado conectado a viamask y directop() devuelve true si el operador que se usa con /connect está conectado directamente a este servidor. Estos operadores pueden combinarse usando && (y), || (o) y englobados entre llaves. Además, un operador precedido por ! comprueba si devuelve false. Si la expresión entera devuelve true, entonces se deniega el link. deny::type acepta dos valores: auto (sólo para autoconnects, pero /connect seguirá funcionando) y all (aplicado a todos los intentos).
+4.25 - Bloque deny channel OPCIONAL (conocido como chrestrict.conf) +
+Sintaxis::
+
+deny channel {
+ channel "<máscara-canal>";
+ reason <razón>;
+ redirect "<nombre-canal>";
+ warn [on|off];
+};
+
++
Este bloque deshabilita la entrada a ciertos canales. La directriz deny::channel especifica los nombres de canales, con comodines, a los que los usuarios no pueden entrar. deny::reason, la razón por qué no pueden hacerlo. Además, puede especificar deny::redirect para redirigir a los usuarios a este canal. deny::warn si está en on enviará un notice a los operadores (con la snomask 'e') si algún usuario intenta entrar.
+Ejemplo:
+
+deny channel {
+ channel "#unrealsucks";
+ reason "Tu si que apestas!";
+};
+
+deny channel {
+ channel "#*teen*sex*";
+ reason "Estás salido";
+ warn on;
+};
+
+deny channel {
+ channel "#operhelp";
+ reason "Nuestro canal de ayuda es #help, no #operhelp";
+ redirect "#help";
+};
+
+
+4.26 - Bloque allow channel + OPCIONAL +
+Sintaxis:
+
+allow channel {
+ channel "<máscara-canal>";
+};
+
+Este bloque especifica los canales a los que los usuarios deben entrar.
+Ejemplo:
+
+allow channel {
+ channel "#algo";
+};
+
+4.27 - Bloque allow dcc + OPCIONAL +
+Sinaxis:
+
+allow dcc {
+ filename "<máscara-archivo>";
+ soft [yes|no];
+};
+
+Este bloque permite establecer archivos que puedan ser enviados. Si allow dcc::soft está en 'yes' se aplica a la lista 'soft dcc bans', si está en 'no' se aplica a la lista normal ('hard').
+Ejemplo:
+
+allow dcc {
+ filename "*.jpg"; /* las imágenes son seguras */
+ soft yes;
+};
+
+4.28 - Bloque vhost + OPCIONAL (conocido como vhosts.conf) +
+Sintaxis:
+
+vhost {
+ vhost <vhost>;
+ from {
+ userhost <hostmask>;
+ userhost <hostmask>;
+ ...
+ };
+ login <login-name>;
+ password <contraseña> { <auth-type>; };
+ swhois "<swhois info>";
+};
+
+Este bloque permite usar el comando /vhost para obtener un host virtual. El parámetro vhost::vhost puede ser user@host o simplemente el host que el usuario recibirá. vhost::from::userhost contiene las máscaras user@host que deben coincidir para recibir el host virtual. Puedes especificar más de una. vhost::login es el login que utilizará y vhost::password la contraseña. vhost::password:: acepta métodos de cifrado de contraseña como crypt, md5, sha y ripemd-160. vhost::swhois añade una línea extra a su whois.
+Ejemplo:
+
+vhost {
+ vhost my.own.personal.vhost.com;
+ from {
+ userhost my@isp.com;
+ userhost myother@isp.com;
+ };
+ login mynick;
+ password mypassword;
+ swhois "Soy la monda";
+};
+
+4.29 - Bloque badword + OPCIONAL (conocido como badwords.*.conf) +
+Sintaxis:
+
+badword <tipo> {
+ word <texto>;
+ replace <palabra-reemplazar>;
+ action <replace|block>;
+};
+
+Este bloque permite gestionar la lista de palabras para canales y usuarios con modo +G de "badwords". badword:: especifica el tipo: channel, message, quit y all. badword::word puede ser una simple palabra o una compleja expresión regular, según lo que necesite. badword::replace es una cadena por la que se reemplazará si coincide. Si se deja en blanco, se reemplazará por "<censored>". badword::action define la acción a tomar: si es replace la reemplazará y si es block bloqueará el mensaje entero. Si se deja en blanco, se asume replace.
+Ejemplo:
+
+badword channel {
+ word shit;
+ replace shoot;
+};
+4.30 - Bloque ulines + OPCIONAL (conocido como U:Line) +
Sintaxis: +
+ulines {
+ <nombre-servidor>;
+ <nombre-servidor>;
+ ...
+};
+
+Este bloque define ciertos servidores para que tengan habilidades extras. Es recomendable únicamente para servidores de servicios y estadísticas, nunca para servidores normales. Cada entrada es el nombre del servidor.
+Ejemplo:
+
+ulines {
+ services.mynetwork.com;
+ stats.mynetwork.com;
+};
+4.31 - Bloque link + OPCIONAL (conocido como C/N/H:Lines) +
+Sintaxis:
+
+link <nombre-servidor> {
+ username <usermask>;
+ hostname <ipmask>;
+ bind-ip <ip-a-enlazar>;
+ port <puerto-a-conectar>;
+ password-connect <contraseña-de-conexión-local>;
+ password-receive <contraseña-de-conexión-remotas> { <auth-type>; };
+ hub <hub-mask>;
+ leaf <leaf-mask>;
+ leafdepth <profundidad>;
+ class <clase>;
+ciphers <ssl-ciphers>;
+ options {
+ <opción>;
+ <opción>;
+ ...
+ };
+};
+
+Este bloque es necesario para unir servidores. Tómese su tiempo para leerlo todo porque es bastante complicado y con lo que los usuarios tienen más errores.
+Primero de todo, server-name es el nombre del servidor remoto, al que quiere unir.
+username
+ Puedes especificarlo si tiene una autentificación ident. Normalmente pondrá "*".
hostname
+ El host o la IP del servidor remoto. Es usado por ambos lados al conectar y en la verificación del servidor que se une. Algunos ejemplos:
+
| 1.2.3.4 | +IP normal | +
| hub.blah.com | +host: sólo para conexiones salientes, nunca para entrantes a menos que link::options::nohostcheck esté presente | +
| * | +no podrá conectar a * pero sí recibir la conexión | +
| ::ffff:1.2.3.4 | +unión de ipv6 a ipv4 | +
bind-ip (opcional)
+ Puede usarse para enlazar con una ip (ej: 192.168.0.1), nunca suele usarse.
port
+ Puerto a conectar (en el servidor remoto).
password-connect
+ Es la contraseña para conectar al servidor remoto. Debe ser texto plano.
password-receive
+ Es la contraseña para validar uniones entrantes y puede ser encriptada (métodos crypt, md5, sha1 y ripemd-160). Puede dejarlo como texto plano. Generalmente es el mismo que la contraseña anterior.
hub vs leaf
+ Un hub es un servidor con varios servidores unidos a él. Un leaf sólo tiene una unión, a su servidor. Un servidor o es un hub o un leaf, nunca ambos.
hub (opcional)
+ Este valor es la máscara de los servidores a los que puede conectar (ej: *.mi.red).
leaf (opcional)
+ Este valor es la máscara que este servidor actuará como leaf.towards.
+
leaf-depth (opcional)
+ Si se especifica, la directriz leaf también debe especificarse. Este valor es la profundidad o número de uniones que puede tener.
class
+ Es la clase a la se relacionará este servidor, generalmente la clase server.
compression-level (opcional)
+ Especifica el nivel de compresión (1-9) si se especifica el parámetro link::options::zip.
ciphers (opcional)
+ Especifica los "ciphers" ssl para este enlace. Para obtener una lista de los "ciphers" disponibles, use el comando 'openssl ciphers. Deben especificarse separados por ':'.
bloque options
+ Algunas de las opciones son:
+
| ssl | +si conecta a un puerto SSL | +
| autoconnect | +su servidor intentará conectar automáticamente. El tiempo usado entre intentos es el que especificó en class::connfreq (se recomienda para un sólo lado, de leaf a hub) | +
| zip | +si quiere usar compresión, ambos servidores deben soportarla | +
| nodnscache | +no guarda la IP saliente. Úselo si tiene un host dinámico (como dyndns.org) | +
| nohostcheck | +no valida el host remoto (link::hostname). Úselo si tiene un host dinámico (como dyndns.org) | +
| quarantine | +los operadores mantendrán el estado de locales, no globales | +
Ejemplo:
+
+link hub.mynet.com {
+ username *;
+ hostname 1.2.3.4;
+ bind-ip *;
+ port 7029;
+ hub *;
+ password-connect "LiNk";
+ password-receive "LiNk";
+ class servers;
+ options {
+ autoconnect;
+ ssl;
+ zip;
+ };
+};
+
4.32 - Bloque alias + OPCIONAL +
+Sintaxis [alias estándar]:
+
+alias <nombre> {
+ target <destino>;
+ type <tipo>;
+};
+
+(Nota: puede ver más archivos de alias estándars que lleva UnrealIRCd en este enlace)
+Este bloque (estándar) le permite redireccionar comandos a usuarios, generlamente a bots como por ejemplo /chanserv para enviarle privados. alias:: especifica el nombre del comando, por ejemplo chanserv. alias::target el nick o canal al que se le enviará el mensaje y puede omitirse. alias::type define el tipo de alias: services (el usuario está en el servidor de servicios), stats (en el de estadísticas), normal (en un servidor normal) y channel (el target es un canal). Este bloque tiene otro propósito detallado a continuación.
+Sintaxis [alias de comandos]:
+
+alias <nombre> {
+ format <expresión-regular> {
+ target <destino>;
+ type <tipo>;
+ parameters <parámetros-del-mensaje>;
+ };
+ format <expresión-regular> {
+ ...
+ };
+ type command;
+};
+
+Este uso es más extenso y tiene más posibilidades. Por ejemplo, puede crear aliases como /identify. alias:: es el mismo que el anterior: el nombre del comando. alias::format especifica la expresión regular que debe coincidir con el texto enviado. Si lo hace, se usan las subentradas. Así puede tener varios alias::format para seguir distintas acciones según la coincidencia, a partir de sus subentradas. alias::format::target es el nick o canal de destino. alias::format::type es el tipo de alias. alias::format::parameters es lo que se enviará como parámetro al alias. Para especificar un parámetro que se enviará al nick, use % seguido del número de parámetro. Por ejemplo, %1 enviará el primer parámetro. Para especificar todos los parámetros a partir de uno, use %n- donde n es el número de parámetro. Por ejemplo, %2- enviaría todos los parámetros a partir del segundo, incluído. Además, puede usarse %n para que sea reemplazado por el nick que ejecuta el comando. Para más información consulte doc/example.conf.
+4.33 - Bloque help + OPCIONAL +
+Sintaxis:
+
+help <nombre> {
+ <línea>;
+ <línea>;
+ ...
+};
+
+(Nota: use generalmente help.conf)
+Este bloque le permite crear entradas para /helpop. help:: es el valor que se pasará a /helpop como parámetro. Si se omite, se usará si no se envían parámetros a /helpop. Las entradas serán las que se mostrarán al usuario cuando lo solicite.
+4.34 - Bloque official-channels + OPCIONAL +
+Sintaxis:
+
+official-channels {
+ "#canal" { topic "El topic por defecto"; };
+};
+
+Estos canales se muestran en /list, aunque no haya usuarios. topic es opcional y sólo se muestra si tiene 0 usuarios.
+ +Ejemplo:
+
+official-channels {
+ "#Help" { topic "Canal oficial de ayuda. Si nadie está presente, use /helpop ayuda"; };
+ "#Home";
+ "#Main" { topic "Canal principal"; };
+};
+
+4.35 - Bloque spamfilter + OPCIONAL +
+
+Este bloque le permite añadir filtros de spam locales.
+Vea las características del filtro de spam para más información.
+
Sintaxis:
+
+spamfilter {
+ regex <palabra>;
+ target { <target(s)> };
+ action <acción>;
+ reason <razón>;
+ ban-time <tiempo>;
+};
+
+regex es la expresión regular a comparar.
+ target especifica los destinos, vea aquí para los tipos posibles (ej: 'channel').
+ action define la acción a tomar, vea aquí para las acciones posibles (ej: 'gline').
+ reason opcional: especifica la razón.
+ ban-time opcional: especifica la durada de la *line..
+
Ejemplos:
+
+spamfilter {
+ regex "Come watch me on my webcam";
+ target { private; channel; };
+ action gline;
+ reason "You are infected, please go to www.antivirus.xx/blah/virus=GrrTrojan";
+ ban-time 6h;
+};
+
+spamfilter {
+ regex "come to irc\..+\..+";
+ target { private; channel; };
+ action gline;
+ action gline;
+ reason "No spamming allowed";
+};
+
+4.36 - Bloque set + REQUERIDO (conocido como archivo unrealircd.conf/networks) +
+Este bloque se usa para configurar la red. Si sólo tiene un servidor, puede meterlo todo en el archivo unrealircd.conf. Si tiene varios, se recomienda ponerlo por separado.
+Si su servidor está en una red, puede poner la configuración de red en un archivo aparte y cargarlo con include en cada servidor.
+En este documento, la configuración y directrices están de forma <nombre-bloque>::<nombre-directriz>. Este formato no debe usarse en el archivo, debe convertirse al formato detallado a continuación. Es una representación para simplificar su lectura.
+Sintaxis:
+
+set {
+ <entrada> <valor>;
+ <entrada> <valor>;
+ ...
+};
+
+Este bloque fija las opciones para cada servidor. Cada entrada tiene su propósito que se explica a continuación. Algunas directrices tienen subbloques que también se detallan. Hay varios puntos a prestar atención. Todas las directrices y parámetros deben estar dentro de tan sólo un bloque set. Si una directriz tiene varias opciones, deben incluirse dentro del bloque set.
+ Ejemplo:
+
+set {
+ kline-address my@emailaddress.com;
+ auto-join #welcome;
+ options {
+ hide-ulines;
+ };
+ hosts {
+ local LocalOp.MyNet.com;
+ global globalop.mynet.com;
+ };
+};
+Si quiere poner algunos bloques por separado, debe hacerlo en una sóla línea.
+ Ejemplo:
+ set { options { hide-ulines; no-stealth; }; };
+
set::kline-address <direción-email>;
+ La dirección email para cualquier referencia. Valor obligado.
set::modes-on-connect <+modos>;
+ Los modos que se pondrán al usuario al conectar.
set::snomask-on-connect <+modos>
+ La máscara de noticias que se pondrán al usuario al conectar.
set::modes-on-oper <+modos>;
+ Los modos que recibirán los operadores cuando hagan /oper.
set::snomask-on-oper <+modos>;
+ La máscara de noticias que recibirán los operadores.
set::modes-on-join <+modos>;
+ Los modos que se pondrán a un canal cuando sea creado. No se pueden usar los modos +qaohvbeOAzlLk.
set::restrict-usermodes <modos>
+ Modos a restringir (no use + o -).
+ Por ejemplo puede usar +G en modes-on-connect y G en restrict-usermodes para que no puedan quitarse este modo.
set::restrict-channelmodes <modos>
+ Modos a restringir en canales (no use + o -).
+ Por ejemplo puede usar +G en modes-on-join y G en restrict-channelmodes para que no puedan quitar este modo.
+ NOTA: es posible usar esta característica con la opción MLOCK de los servicios si se diera el caso. Sin embargo no podemos dar soporte a eso.
set::restrict-extendedbans <tipos|*>
+ No se permite el uso de bans extendidos ("*") o algunos en concreto (ej: "qc").
set::auto-join <canaless>;
+ Los canales a los que se forzará el usuario a entrar. Para especificar varios, use la coma.
+ [Nota: no olvide entrecomillarlo, como auto-join "#chan";]
set::oper-auto-join <canales>;
+ Los canales a los que se forzará el operador entrar. Para especificar varios, use la coma.
+[Nota: no olvide entrecomillarlo, como auto-join "#chan";]
set::anti-spam-quit-message-time <tiempo>;
+ Tiempo que debe transcurrir entre /quit para que el mensaje sea mostrado. Úselo para prevenir el abuso de publicidad. Si el valor es una cadena alfanumérica, use d para días, h para horas, m para minutos y s para segundos. Por ejemplo 1d2h3m significa 1 día, 2 horas y 3 minutos.
set::prefix-quit <prefijo>;
+ Prefijo que se usará para preceder los mensajes en desconexiones voluntarias. Si se pone a 0 se usa "Quit:".
set::static-quit <mensaje quit >;
+ Fija un mensaje permanente en desconexiones. Sea cual sea el mensaje del usuario siempre se mostrará este. Elimina la necesidad de usar anti-spam-quit-message-time, como también prefix-quit. No reemplaza errores con el mensaje static-quit.
set::static-part <no|yes|mensaje part>;
+ Si se usa 'yes' se quitan todos los mensajes part. Con 'no' no modifica nada. Cualquier otro valor se usará como comentario. Puede ser algo confuso, úselo con determinación.
set::who-limit <límite>;
+ Límite de entradas a mostrar en /who. Si se omite, no hay límite.
set::silence-limit <límite>;
+ Límite de entradas en la lista silence. Si se omite, el límite es de 15.
set::oper-only-stats <lista-stats>;
+ Lista de stats que sólo los operadores pueden usar en /stats. Omítalo para permitir a los usuarios ver toda la información o "*" para restringirla toda a operadores. Sólo se aceptan las stats en forma corta.
set::oper-only-stats {<stats-flag>; <stats-flag>;};
+ El caso anterior pero con stats en forma larga.
set::maxchannelsperuser <nº-canales>;
+ Límite de canales que pueden entrar los usuarios al mismo tiempo.
set::maxdccallow <nº-entradas>;
+ Límite de entradas en la lista dccallow.
set::channel-command-prefix <prefijo>;
+ Especifica el prefijo para mostrar el mensaje a los usuarios que estén con +d. Suele usarse para bots. Si se omite, el prefijo es "`".
set::allow-userhost-change [never|always|not-on-channels|force-rejoin]
+ Especifica qué hacer cuando el user@host cambia (+x/-x/chghost/chgident/setident/vhost/etc.).
+ never deshabilita todos los comandos, always los permite aunque estén en canales (causa desincronización) [por defecto], not-on-channels si el usuario no está en ningún canal, force-rejoin forzará al usuario a reentrar en los canales y se le dará op/voz, etc. si fuera necesario.
set::options::hide-ulines;
+ Si está presente, los servidores u-line no se muestran en /links si lo solicita un usuario no operador.
set::options::flat-map;
+ Si está presente, los servidores aparecerán directamente unidos en /map y /links, sin saber a qué servidor están unidos. Es una pequeña ayuda para evitar ataques (D)DoS a los servidores importantes o puntos vitales de la red.
set::options::show-opermotd;
+ Si está presente, se mostrará el opermotd cuando hagan /oper con éxito.
set::options::identd-check;
+ Si está presente, se comprobará el servidor ident y devolverá el valor del username. Si no devuelve nada o no existe servidor ident, el username se prefijará con ~. Si se omite, no se hace la comprobación.
set::options::show-connect-info;
+ Si está presente, se muestran los mensajes "ident request", "hostname lookup", etc. cuando el usuario conecte.
set::options::dont-resolve;
+ Si está presente, no se resolverán los hosts. Puede ser útil para acelerar la conexión.
+ Note que si no se usa, el bloque allow deberá basarse en ips, no en hosts.
set::options::mkpasswd-for-everyone;
+ Todos los usuarios pueden usar /mkpasswd.
set::options::allow-part-if-shunned;
+ Permite usar /part a los usuarios con shun.
set::dns::timeout <timevalue>;
+ Tiempo de espera del servidor DNS si no obtiene respuesta. Si el valor es una cadena alfanumérica, use d para días, h para horas, m para minutos y s para segundos. Por ejemplo 1d2h3m significa 1 día, 2 horas y 3 minutos.
set::dns::retries <nº-intentos>;
+ Número de intentos si el servidor DNS no obtiene respuesta.
set::dns::nameserver <name-of-dns-server>;
+ Especifica el host del servidor a usar en las búsquedas DNS.
set::network-name <nombre-de-red>;
+ Fija el nombre de la red. Debe ser el mismo en todos los servidores.
set::default-server <nombre-servidor>;
+ Define el servidor por defecto a conectar si la clase está llena.
set::services-server <nombre-servidor>;
+ Especifica el nombre del servidor de los servicios. Requerido. Use un valor aleatorio como servicios.mi.red si no dispone de ellos.
set::stats-server <nombre-servidor>;
+ Especifica el nombre del servidor de estádisticas. Si no dispone de ellas, puede omitir este valor.
set::help-channel <canal-ayuda>;
+ Canal de ayuda.
set::cloak-keys { "clave1"; "clave2"; "clave3"; };
+ Fija las claves de cifrado para generar los hosts virtuales. Deben ser las mismas en toda la red. Deben ser cadenas de 5 a 100 caracteres (con 10-20 es suficiente) alfanuméricas: a-z, A-Z y 0-9. Según el módulo de cifrado cargado, usará otras reglas.
set::hiddenhost-prefix <prefijo>;
+ Define el prefijo del host virtual. Suele ser un reflejo del nombre de la red.
set::hosts::local <vhost-locop>;
+ Define el host que se les asignará a los operadores locales si llevan +x. Puede especificar un user@host para este campo.
set::hosts::global <vhost-globop>;
+ Define el host que se les asignará a los operadores globales si llevan +x. Puede especificar un user@host para este campo.
set::hosts::coadmin <vhost-coadmin>;
+ Define el host que se les asignará a los co-admin si llevan +x. Puede especificar un user@host para este campo.
set::hosts::admin <vhost-admin>;
+ Define el host que se les asignará a los administradores si llevan +x. Puede especificar un user@host para este campo.
set::hosts::servicesadmin <vhost-admin-servicios>;
+ Define el host que se les asignará a los administradores de servicios si llevan +x. Puede especificar un user@host para este campo.
set::hosts::netadmin <vhost-admin-red>;
+ Define el host que se les asignará a los administradores de red si llevan +x. Puede especificar un user@host para este campo.
set::hosts::host-on-oper-up <yes/no>;
+ Si está en 'yes', recibirán el host automáticamente acompañado del modo +x si no lo tuvieran. Si no, deberán ponerse el modo +x manualmente.
set::ssl::egd <archivo>;
+ Especifica el archivo EGD (Entropy Gathering Daemon) para SSL. Si usa OpenSSL 0.9.7 o mayor, entonces se buscan por defecto las rutas /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool,
+ y /etc/entropy y no es necesario especificarlo, simplemente dejándolo en blanco (set::ssl::edg).
set::ssl::certificate <archivo>;
+ Especifica la ubicación del archivo de certificado SSL.
set::ssl::key <archivo>;
+ Especifica la ubicación del archivo de llave privada SSL.
set::ssl::trusted-ca-file <filename>;
+ Especifica la ubicación del archivo de los CAs permitidos.
set::ssl::options::fail-if-no-clientcert;
+ Sólo acepta clientes con certificado.
set::ssl::options::no-self-signed;
+ Sólo acepta clientes con un certificado no propio.
set::ssl::options::verify-certificate;
+ Verifica la autenticidad del certificado SSL antes de la conexión.
set::throttle::period <tiempo>
+ Tiempo que debe esperar el usuario para volver a conectar si rebasa el número de intentos de conexión.
set::throttle::connections <nº>;
+ Número de veces que puede conectar con el mismo host sin que se le haga throttle.
set::ident::connect-timeout <segundos>;
+ Número de segundos que debe esperar a obtener respuesta del servidor ident. (por defecto: 10s).
set::ident::read-timeout <segundos>;
+ Número de segundos que debe esperar respuesta (por defecto: 30s).
set::anti-flood::unknown-flood-bantime <tiempo>;
+ Especifica el tiempo que debe estar bloqueado una conexión desconocida por flood.
set::anti-flood::unknown-flood-amount <kbs>;
+ Especifica la cantidad de tráfico (en kilobytes) que una conexión desconocida puede enviar antes de ser desconectada.
set::anti-flood::away-flood <veces>:<periodo>
+ Protección flood por away: límita el número de veces que puede usarse /away dentro de un periodo de segundos. Requiere tener activado NO_FLOOD_AWAY en config.h. Por ejemplo: away-flood 5:60s; significa podrán usar /away un máximo de 5 veces cada 60 segundos.
set::anti-flood::nick-flood <veces>:<periodo>
+ Protección flood por nick: límita el número de veces que se pueden cambiar el nick dentro de un periodo de segundos. Por ejemplo: nick-flood 4:90; significa que sólo podrán cambiarse el nick 4 veces cada 90 segundos. Por defecto: 3 cada 60s.
set::default-bantime <tiempo>
+ Tiempo por defecto en comandos como /kline, /gline, /zline, /shun, etc. sin parámetro. Por defecto es permanente (0).
set::modef-default-unsettime <valor>
+ Tiempo por defecto para quitar un modo que se ponga debido al efecto de +f. Por ejemplo: si especifica 10, se transformarán a +f [5j#i10]:15. Por defecto no hay tiempo para quitar el modo.
set::modef-max-unsettime <valor>
+ Máximo de minutos que pueden especificar en el modo +f (+f [5j#i<TIEMPO>]:15). Debe ser un valor entre 0 y 255. Por defecto 60 (1 hora).
set::ban-version-tkl-time <valor>
+ Especifica cuánto debe durar una acción como zline/gline/etc en ban version. Por defecto 86400 (1 día).
set::spamfilter::ban-time <valor>
+ Similar a la directriz anterior pero para filtros de spam.
set::spamfilter::ban-reason <razón>
+ Razón por defecto en los filtros de spam.
set::spamfilter::virus-help-channel <canal>
+ Canal usado para la acción viruschan en los filtros de spam.
set::spamfilter::virus-help-channel-deny <yes|no>
+ Si está en 'yes' (o '1') sólo los usuarios invitados por el filtro de spam pueden entrar en ese canal, a excepción de los operadores.
set::spamfilter::except <target(s)>
+ Estos "target(s)" se omiten del filtro de spam (no se toma ninguna acción). Puede especificar varios separándolos con comas. Ej: except "#help,#spamreport";.
| ircd.motd | +Se muestra cuando se usa /motd y (si ircd.smotd no está presente) cuando el cliente conecta | +
| ircd.smotd | +Se muestra al conectar solamente (short MOTD, motd corto) | +
| ircd.rules | +Se muestra cuando se usa /rules | +
| oper.motd | +Se muestra cuando se usa /opermotd o cuando se identifican como operadores | +
| bot.motd | +Se muestr cuando se usa /botmotd | +
6 – Modos de usuario y canal +
+Modo |
+ Descripcción |
+
Channel Modes |
+ |
A |
+ Sólo pueden entrar administradores | +
a <nick> |
+ Hace de nick administrador del canal | +
b <nick!user@host> + |
+ Pone un ban | +
c |
+ No se pueden enviar colores ANSI | +
C |
+ No se permiten CTCP's | +
e <nick!user@host> |
+ Exception ban – si alguien coincide, siempre podrá entrar al canal aunque esté baneado | +
f * <líneas:segundos> |
+ Protección flood. Si se especifica * el usuario será baneado y expulsado si envía más de líneas en menos de segundos. Si no se usa *, sólo se expulsa | +
G |
+ Marca el canal con la lista de "badwords" | +
M |
+ Sólo pueden hablar los usuarios registrados (+r) | +
h <nick> |
+ Da el estado de semi operador del canal a nick | +
i |
+ Se precisa invitación | +
K |
+ No se permite /knock | +
k <clave> |
+ Se precisa clave para entrar | +
l <##> |
+ Fija el número máximo de usuarios que puede haber en el canal | +
L <#canal> |
+ Si se pasa el límite del +l, los usuarios son enviados directamente a este canal | +
m |
+ Canal moderado: sólo +v y superiores pueden hablar | +
N |
+ No se permiten cambios de nick en el canal | +
n |
+ No se permiten mensajes externos | +
O |
+ Sólo operadores pueden entrar | +
o <nick> |
+ Da el estado de operador del canal a nick | +
p |
+ Marca el canal como privado | +
q <nick> |
+ Marca nick como fundador del canal | +
Q |
+ Sólo los servidores uline pueden expulsar a los usuarios | +
R |
+ Sólo pueden entrar usuarios registrados (+r) | +
S |
+ Quita todos los colores | +
s |
+ Hace el canal secreto | +
t |
+ Sólo halfops y superiores pueden cambiar el tema del canal | +
T |
+ No se permiten notices al canal | +
u |
+ Auditorium – Sólo se muestran los operadores del canal en /names o /who #canal | +
V |
+ No se permite /invite | +
v <nick> |
+ Da voz a los usuarios (pueden hablar en canales +m) | +
z |
+ Sólo pueden entrar usuarios conectados bajo SSL | +
+
Modo |
+ Descripción |
+
Modos de usuario |
+ |
r |
+ Identifica al nick como registrado | +
s |
+ Puede escuchar las notificaciones del servidor | +
v |
+ Rechaza los DCC infectados automáticamente | +
o |
+ Operador de red global | +
O |
+ Operador de red local | +
B |
+ Es un bot | +
i |
+ Invisible (no se muestra en /who) | +
A |
+ Administrador de servidor | +
x |
+ Da al usuario un host virtual | +
q |
+ Sólo ulines pueden expulsarle (sólo administradores de servicios) | +
a |
+ Administrador de servicios | +
g |
+ Puede leer y escribir globops y locops | +
H |
+ Oculta el estado de operador de red | +
S |
+ Protege a los servicios de red | +
t |
+ Nota que el usuario usa un host virtual | +
C |
+ Co administrador | +
d |
+ No recibe mensajes de canal | +
N |
+ Administrador de Red | +
w |
+ Puede recibir wallops | +
h |
+ Disponible para ayuda (HelpOp) | +
G |
+ Filtra las palabras con la lista "badwords" | +
W |
+ Le permite ver cuando le hacen /whois | +
p |
+ Oculta sus canales de /whois | +
R |
+ Le permite recibir mensajes de usuarios registrados (+r) | +
V |
+ Usuario WebTV | +
z |
+ Cliente SSL | +
T |
+ Le previene de recibir CTCPs | +
7 – Tabla de comandos para usuarios y operadores
+NOTA: /helpop muestra información más actualizada. Use /helpop comando (o /helpop ?comando si es operador) para obtener más información sobre ese comando.
+ +Comando |
+ Descripcción |
+ Quién |
+
| nick <nuevo_nick> | +Cambia tu nick. Alerta de ello a los demás usuarios. |
+ Todos | +
| whois <nick> | +Muestra información sobre el nick. Incluye el nombre completo, host, canales en los que está y el estado de operador, entre otros |
+ Todos | +
| who <patrón> | +Le permite buscar usuarios. El patrón incluye: nick, #canal, host (*.attbi.com) |
+ Todos | +
| whowas <nick> [max_respuestas] | +Muestra información sobre un nick desconectado. Puedes especificar un max_respuestas como máximo de entradas mostradas |
+ Todos | +
| ison <nick1 nick2 nick3 ...> | +Le permite comprobar si están conectados ciertos usuarios. Usado generalmente por scripts |
+ Todos | +
| join <canal1,canal2, ...> | +Le permite unirse en varios canales. Si usa /join 0 sale de todos | +Todos | +
| cycle <canal1,canal2, ...> | +Reentra de los canales especificados. Es equivalente a usar PART y luego JOIN | +Todos | +
| motd [servidor] | +Muestra el motd del servidor. Añadiendo un servidor, muestra el motd de ese servidor |
+ Todos | +
| rules [servidor] | +Muestra las reglas del servidor. Añadiendo un servidor, muestra las reglas de ese servidor | +Todos | +
| lusers [servidor] | +Muestra los usuarios actuales y el número máximo de usuarios en la red, globales y locales. Añadiendo un servidor, muestra los usuarios de ese servidor |
+ Todos | +
| map | +Muestra el mapa de la red | +Todos | +
| quit [razón] | +Le desconecta del servidor. Si incluye una razón, se mostrará en los canales en los que esté | +Todos | +
| ping <usuario> | +Envía una petición PING a un usuario. Se usa para medir el lag. Entre servidores, se usa para verificar que todavía sigue conectado |
+ Todos | +
| version <nick> | +Envía un CTCP version a un usuario. Si pertoca, el cliente responderá a ella |
+ Todos | +
| links | +Muestra una lista de los servidores de la red | +Todos | +
| admin [servidor] | +Muestra la información de contacto del servidor. Si se añade un servidor, muestra la información de ese servidor |
+ Todos | +
| userhost <nick> | +Muestra el userhost del nick dado. Generalmente se usa en scripts |
+ Todos | +
| topic <canal> [tema] | +Topic <canal> muestra el tema del canal. Topic <canal> <mensaje> fija como tema del canal ese mensaje |
+ Todos | +
| invite <nick> <canal> | +Invita a este nick a un canal (debe ser operador del canal) |
+ Op Canal | +
| kick <canal,canal> <user, user> [razón] | +Expulsa a un o varios usuarios de un canal o varios canales. Puede incluir un motivo |
+ Op Canal | +
| away <razón> | +Le marca como ausente. Puede incluir una razón |
+ Todos | +
| Watch +-<nick> +-<nick> |
+ Watch es un sistema de notificaciones en UnrealIRCd, siendo más rápido ya que usa menos recursos de red que el viejo sistema. El servidor le envía un mensaje cuando un usuario de su lista watch se desconecta o se conecta. Esta lista no se conserva a cada sesión (su cliente o script deberá enviarla cada vez que se conecte) | +Todos | +
| helpop ?<tema> or !<tema> |
+ HelpOp es un nuevo sistema de ayuda. Puede usar /helpop ? <tema> o /helpop ! <tema>. Si usa "?" busca la ayuda en el propio programa. Si no obtiene ayuda, use "!" para mandarlo a los operadores de red. Si no usa ni "?" ni "!" primero consulta en la ayuda interna y si no la encuentra la manda a los operadores | +Todos | +
| list <patrón> | +
+ Si no incluye un patrón, se le manda la lista de canales sin filtrar. El patrón acepta estas opciones: + >n Lista los canales con más de n personas + <n Lista los canales con menos de n personas + C>n Lista los canales creados entre ahora y hace n minutos + C<n Lista los canales creados antes de hace n minutos + T>n Lista los canales cuyos topics son mas antiguos que n minutos (que no han cambiados hace n minutos) + T<n Lista los canales cuyos topics son mas nuevo que hace n minutos + *máscara* Lista los canales que concuerdan con *máscara* + !*máscara* Lista los canales que no concuerdan con *máscara* |
+ Todos | +
| Knock <canal> <mensajee> |
+ Le permite hacer 'knock' en un canal para invitados preguntando por su invitación. No funcionará si el canal está en +V y +K, o si está baneado |
+ Todo | +
| setname | +Le permite cambiar su nombre completo sin necesidad de reconectar |
+ Todos | +
| vhost <login> <contraseña> | +Oculta su host usando un host virtual proporcionado por el servidor |
+ Todos | +
| mode <canal/nick> <modo> |
+ Le permite cambiar los modos de un canal o sus propios modos. Vea Modos de usuario y canales para más información |
+ Todos | +
| credits | +Muestra los créditos de la gente que ha ayudado a crear UnrealIRCd |
+ Todos | +
| license | +Muestra la licencia GNU | +Todos | +
| time [servidor] | +Muestra la fecha y la hora del servidor. Si añade un servidor, lo hace de ese servidor |
+ Todos | +
| botmotd [servidor] |
+ Muestra el mensaje para bots del servidor. Si añade un servidor, muestra el de ese servidor | +Todos | +
| identify <contraseña> | +Envía su contraseña a los servicios para identificarse como dueño de su nick |
+ Todos | +
| identify <canal> <contraseña> | +Envía su contraseña a los servicios para identificarse como fundador del canal | +Todos | +
| dns <opción> | +Devuelve información sobre el caché DNS de los servidores. Muchos clientes llevan este comando incluído, por ello se recomienda usar /raw DNS. Los operadores pueden especificar una l en el primer parámetro para recibir la lista de entradas DNS | +Todos | +
| oper <userid> <contraseña> |
+ Comando para identificarse como operador de red |
+ IRCop | +
| wallops <mensaje> | +Envía un mensaje a los usuarios con +w | +IRCop | +
| globops <mensaje> | +Envía un mensaje a todos los IRCops | +IRCop | +
| chatops <mensaje> | +Envía un mensaje a todos los IRCops con +c | +IRCop | +
| locops <mensaje> | +Envía un mensaje a todos los IRCops locales | +IRCop | +
| adchat <mensaje> | +Envía un mensaje a todos los Administradores | +IRCop | +
| nachat <mensaje> | +Envía un mensaje a todos los Administradores de Red | +IRCop | +
| kill <nick> <razón> | +Desconecta a un usuario de la red | +IRCop | +
| kline [+|-]<user@host | nick> [<duración> <razón>] | +Banea la máscara host del servidor. Una kline no es un ban global, tan sólo local. + duración es: a) un valor en segundos, b) un valor de tiempo como '1d' es un día o c) '0' par que sea permanente. La duración y razón son opcionales. Si no se especifican se toman los valores de set::default-bantime y razón como 'no reason' + Para quitar una kline use /kline -user@host |
+ IRCop | +
| zline [+|-]<*@ip> [<duración> <razón>] | +Banea una dirección IP del servidor local. Vea kline para más información. Use /zline -*@ip para quitarla | +IRCop | +
| gline [+|-]<user@host | nick> [<duración> <razón>] |
+ Añade un ban global. Vea kline para más información. Use /gline -user@host para quitarla |
+ IRCop | +
| shun [+|-]<user@host | nick> [<duración> <razón>] |
+ Previene de que un usuario ejecute cualquier comando. Son globales. Vea kline para más información. Use /shun -user@host para quitarlo |
+ IRCop | +
| gzline [+|-]<ip> [<duración> <razón>] |
+ Añade una zline global. Vea kline para más información. Use /gzline -*@ip para quitarla |
+ IRCop | +
| rehash <servidor> –<opciones> | +Refresca los archivos de configuración de los servidores. Añadiendo un servidor, lo hará en ese servidor. Puede pasarle varias opciones: + -motd - Sólo refresca todos los motd y rules (incluyendo el bloque tld) + -opermotd - Sólo el archivo opermotd + -botmotd - Sólo el archivo botmotd + -garbage - Fuerza un garbage collection + | IRCop | +
| restart <servidor <contraseña> |
+ Reinicia el servidor. Se requiere una contraseña. Puede especificar qué servidor quiere reiniciar |
+ IRCop | +
| die <contraseña> |
+ Cierra el servidor. Requiere contraseña | +IRCop | +
| lag <servidor> |
+ Este comando actúa como un trazado. Puede escribir /lag servidor y todos los servidores por los que pase este comando le responderán. Así verá qué puntos de la red hay más lag | +IRCop | +
| sethost <nuevohost> | +Le permite cambiar su host al que quiera |
+ IRCop | +
| setident <nuevaident> |
+ Le permite cambiar su ident a la que quiera | +IRCop | +
| chghost <nick> <nuevohost> |
+ Cambia el host de un usuario | +IRCop | +
| chgident <nick> <nuevaident> |
+ Cambia la ident de un usuario | +IRCop | +
| chgname <nick> <nuevonombre> |
+ Cambia el nombre de un usuario | +IRCop | +
| squit <servidor> |
+ Desconecta a un servidor de la red | +IRCop | +
| connect <servidor> [[<puerto>] <servidor>] | +Si sólo se da un servidor, intentará conectar a ese servidor. Si especifica dos servidores, intentará conectarlos entre sí. Ponga primero el leaf y luego el hub |
+ IRCop | +
| dccdeny <archivo> <razón> |
+ Prohibe el envío de un archivo o de archivos que coincidan con este |
+ IRCop | +
| undccdeny <archivo> |
+ Quita una entrada anterior | +IRCop | +
| sajoin <nick> <canal>, <canal> |
+ Fuerza a un usuario a entrar en estos canales | +IRCop | +
| sapart <nick> <canal>, <canal> |
+ Fuerza a un usuario a salir de estos canales | +IRCop | +
| samode <canal> <modos> |
+ Permite a los Administradores de Red y Servicios cambiar los modos de un canal |
+ IRCop | +
| rping <servidor> |
+ Calcula en milisegundos el lag entre servidores |
+ IRCop | +
| trace <servidor|nick> |
+ Devuelve la clase y el lag. Si lo usa sobre un servidor, le devuelve la clase y versión |
+ IRCop | +
| opermotd |
+ Le muestra el opermotd |
+ IRCop | +
| addmotd :<texto> |
+ Añade el texto al final del motd |
+ IRCop | +
| addomotd :<texto> |
+ Añade el texto al final del opermotd |
+ IRCop | +
| sdesc <descripción> |
+ Introduce una nueva descripción del servidor sin reiniciar |
+ IRCop | +
| addline <texto> |
+ Le permite añadir líneas al archivo unrealircd.conf |
+ IRCop | +
| mkpasswd <contraseña> |
+ Encripta un texto para añadirlo en unrealircd.conf |
+ IRCop | +
| tsctl offset +/- <tiempo> |
+ Ajusta el reloj interno del IRCD (no lo use si no sabe lo qué es) |
+ IRCop | +
| tsctl time |
+ Le da el tiempo TS | +IRCop | +
| tsctl alltime | +Le da el tiempo TS de todos los servidores | +IRCop | +
| tsctl svstime <timestamp> |
+ Fija el tiempo TS en todos los servidores (no lo use si no sabe lo qué es) |
+ IRCop | +
| htm <opción> |
+ Controla el tráfico. En modo HTM básicamente deshabilita el uso de comandos como list, whois o who, puesto que ocupan mucho ancho de banda. Opciones: + -ON Servidor en HTM + -OFF Servidor fuera de HTM + -NOISY Informa a los usuarios administradores cuando se entra y sale del modo HTM + -QUIET No informa el caso anterior + -TO <valor> Especifica el ratio a usar |
+ IRCop | +
| stats <opción> |
+
+ B - banversion - Lista de bans + b - badword - Lista de badwords + C - link - Lista del bloque link + d - denylinkauto - Lista del bloque deny link (auto) + D - denylinkall - Lista del bloque deny link (todo) + e - exceptthrottle - Lista del bloque except throttle + E - exceptban - Lista del bloque except ban + f - spamfilter - Lista de filtros de spam + F - denydcc - Lista del bloque deny dcc + G - gline - Lista gline + Flags: [+/-mrs] [máscara] [razón] [autor] + m Devuelve las glines que coincidan o no con la máscara + r Devuelve las glines que coincidan o no con la razón + s Devuelve las glines que coincidan o no con el autor + I - allow - Lista bloque allow + j - officialchans - Lista de canales oficiales + K - kline - Lista del bloque ban user/ban ip/except ban + l - linkinfo - Información de las uniones de servidores + L - linkinfoall - Toda la información anterior + M - command - Lista del uso de cada comando + n - banrealname - Lista del bloque ban realname + O - oper - Lista del bloque oper + S - set - Lista del bloque set + s - shun - Lista de shuns + Flags: [+/-mrs] [máscara] [razón] [autor] + m Devuelve las glines que coincidan o no con la máscara + r Devuelve las glines que coincidan o no con la razón + s Devuelve las glines que coincidan o no con el autor + P - port - Información sobre puertos + q - sqline - Lista sqline + Q - bannick - Lista del bloque ban nick + r - chanrestrict - Lista del bloque channel deny/allow + R - usage - Uso de los recursos + t - tld - Lista del bloque tld + T - traffic - Información del tráfico de datos + u - uptime - Uptime del servidor + U - uline - Lista del bloque ulines + v - denyver - Lista del bloque deny version + V - vhost - Lista del bloque vhost + X - notlink - Lista servidores que están separados de la red + Y - class - Lista del bloque class + z - zip - Información sobre la compresión zlib (si está compilado así) + Z - mem - Uso de memoria + |
+ Todos | +
| module |
+ + Lista todos los módulos | +Todos | +
| close |
+ + Cierra todas las conexiones desconocidas | +IRCop | +
Si está preocupado por la seguridad (debería), esta sección le ayudará. Alternativamente puede usarlo como patrones a seguir en toda la red para afianzarla.
+Esta lista está ordenada de mayor a menor riesgo.
+8.2 Vulnerabilidades no-IRCD
+
8.3 Permisos y archivo de configuración
+
8.5 SSL/SSH y análisis de conexión
+
8.6 Ataques de Denegación de Servicio (DoS) [o: cómo proteger mi hub)
+
8.8 Protección contra agujeros explotables
+
9 – Dudas más frecuentes (FAQ)
+Tiene una FAQ disponible en este enlace
+En raison de la complexité croissante d'UnrealIRCd 3.2, nous avons changé pour une navigation plus facile, ce qui nous a permis + de vous donner accès à beaucoup plus de documentations. Pour voir ce document vous devez avoir un navigateur compatible, ils sont + listés ci-dessous. Les mises à jour de ce document sont disponibles ici : + http://www.vulnscan.org/UnrealIrcd/unreal32docs.html + ainsi qu'un FAQ http://www.vulnscan.org/UnrealIrcd/faq/. +
+Navigateurs compatibles:
+
INDEX / TABLE DES MATIERES
+ 1. Introduction & Notes
+ ---1.1. Notes sur la mise à jour/mixing 3.1.x -> 3.2
+ ---1.2. Notes sur la mise à jour entre versions 3.2
+ 2. Installation
+ 3. Caractéristiques
+ -- 3.1. Cloaking
+ -- 3.2. Modules
+ -- 3.3. Snomasks
+ -- 3.4. Aliases
+ -- 3.5. Helpop
+ -- 3.6. Niveau d'accès des opérateurs
+ -- 3.7. Commandes opérateurs
+ -- 3.8. SSL
+ -- 3.9. IPv6
+ -- 3.10. Zip links
+ -- 3.11. Support des links avec DNS/IP dynamiques
+ -- 3.12. Caractéristiques de l'anti-flood
+ -- 3.13. Types de ban
+ -- 3.14. Spamfilter
+ -- 3.15. CIDR
+ -- 3.16. Autres particularités
+ 4. Configurer votre fichier unrealircd.conf
+
+ ---4.1. Explication du fichier de configuration
+ ---4.2. Me Block -=- (M:Line)
+ ---4.3. Admin Block -=- (A:Line)
+ ---4.4. Class Block -=- (Y:Line)
+ ---4.5. Allow Block -=- (I:Line)
+ ---4.6. Listen Block -=- (P:Line)
+ ---4.7. Oper Block -=- (O:Line)
+ ---4.8. DRpass Block -=-(X:Line)
+ ---4.9. Include Directive
+ ---4.10. Loadmodule Directive
+ ---4.11. Log Block
+ ---4.12. TLD Block -=- (T:Line)
+ ---4.13. Ban Nick Block -=- (Q:Line)
+ ---4.14. Ban User Block -=- (K:Line)
+ ---4.15. Ban IP Block -=- (Z:Line)
+ ---4.16. Ban Server Block -=-(q:Line)
+ ---4.17. Ban Realname Block -=- (n:Line)
+ ---4.18. Ban Version Block
+ ---4.19. Ban Exception Block -=- (E:Line)
+ ---4.20. TKL Exception Block
+ ---4.21. Throttle Exception Block
+ ---4.22. Deny DCC Block -=- (dccdeny.conf)
+ ---4.23. Deny Version Block -=- (V:Line)
+ ---4.24. Deny Link Block -=- (D:Line / d:Line)
+ ---4.25. Deny Channel Block -=- (chrestrict.conf)
+ ---4.26. Allow Channel Block
+ ---4.27. Allow DCC Block
+ ---4.28. Vhost Block -=- (vhost.conf)
+ ---4.29. Badword Block -=- (badwords.conf)
+ ---4.30. Uline Block -=- (U:Line)
+ ---4.31. Link Block -=- (C/N/H:Lines)
+ ---4.32. Alias Block
+ ---4.33. Help Block
+ ---4.34. Official Channels Block
+ ---4.35. Spamfilter Block
+ ---4.36. Set Block -=- (networks/unrealircd.conf)
+ 5. Fichiers additionnels
+ 6. Modes utilisateurs & salons
+ 7. Commandes utilisateurs & Opérateurs
+ 8. Conseils de sécurité/checklist
+ ---8.1. Mots de passe
+ ---8.2. Vulnérabilités non liées à l'Ircd
+ ---8.3. Permissions et fichier de configuration
+ ---8.4. Problèmes liés aux utilisateurs
+ ---8.5. SSL/SSH & sniffing
+ ---8.6. Denial of Service attacks (DoS) [ou: comment protéger mon hub]
+ ---8.7. Conseil sur la divulgation d'informations
+ ---8.8. Protection contre les exploits
+ ---8.9. Conclusion
+ 9. Foire au questions (FAQ)
+
Ce document a été écris exclusivement pour l'utilisation d'UnrealIRCd. Utiliser ce + document avec un autre logiciel, ou le distribuer avec un autre logiciel est strictement + interdit sans la permission écrite de l'équipe de développement d'UnrealIRCd. Ce document + peut être copié/imprimé/reproduit/publié autant de fois que vous le souhaitez, à condition + que ce soit pour l'utilisation d'UnrealIRCd et qu'il ne soit jamais modifié d'une quelconque manière. + – Copyright UnrealIRCd Development Team 2002-2004
+Lisez ce manuel avant de demander de l'aide, vous devez aussi lire attentivement la + FAQ qui répond à plus de 80% de + vos questions/problèmes. Si vous avez encore besoin d'aide vous pouvez demander du support sur + irc.ircsystems.net (port 6667) channel #unreal-support (notez que nous requerrons de votre part une + parfaite connaissance de ce document et de la FAQ et que nous donnons uniquement de l'aide sur UnrealIRCD, + pas sur les services !). Si vous avez un réel bug (comme un crash) alors reportez le ici + http://bugs.unrealircd.org.
1.1 – Notes sur la mise à jour/mixing 3.1.x -> 3.2
+
Au cas où vous souhaiteriez mettre à jour Unreal3.1.x vers Unreal3.2 vous noterez que l'ensemble des fichiers + de configuration a changé, vous devriez trouver cela difficile au début, mais une fois que vous aurez changé + vous trouverez cela beaucoup mieux !
+N'oubliez pas de lire la section 3 à propos des caractéristiques, bien que vous connaissiez déjà la plupart + d'entre elles car elles sont issues des 3.1.x, il y en a tout de même de nouvelles !!
+Le mieux n'est pas de mixer une 3.1.x avec une 3.2, mais si vous souhaitez réellement faire cela, vous + aurez besoin d'une version 3.1.4 minimum, mais une 3.1.5 est fortement conseillée.
1.2 – Notes sur la mise à jour entre versions 3.2
+
Le protocole recommandé pour mettre à jour est :
+Linux:
+
Veuillez vérifier les RELEASE NOTES pour voir ce qui a changé. Si vous notez des changements (ou bug) + entre les versions, VOUS DEVEZ ÊTRE SUR D'AVOIR LU LES RELEASE NOTES EN PREMIER avant de reporter cela comme un bug.
Instructions d'installation:
+Linux:
+
+Windows:
+
La plupart des caractéristiques majeures/mineures sont expliquées dans cette section. + Elle fourni une vue d'ensemble, et fait parfois référence aux fichiers de configuration + (quelque chose dont vous ne connaissez encore rien).
+Vous pouvez sauter cette section, toutefois il est suggéré de la lire avant/après l'installation.
Le Cloaking vous permet de cacher le véritable host des utilisateurs, par exemple si votre host réel est d5142341.cable.wanadoo.nl, + il sera montré (lors des join, part, whois, etc) ainsi : rox-2DCA3201.cable.wanadoo.nl. + Cette spécificité est utile pour prévenir les floods entre utilisateurs depuis qu'ils ne peuvent plus voir l'host ou l'IP réel.
+Cela est contrôlé par le usermode +x (comme : /mode votrepseudo +x), les administrateurs peuvent forcer le mode +x par défaut, + ou rendre impossible aux utilisateurs d'enlever ce mode.
+Un host cloaked est généré par un module de cloaking (vous devez en avoir un d'amorcé), il y en a 2 officiels à ce jour :
+ cloak: C'est le nouveau module officiel de cloaking qui est plus sécurisé que l'ancien, il utilise la méthode de
+ hachage md5 et requière 3 set::cloak-keys:: consistant à mixer des caractères alphanumérique (a-z, A-Z et 0-9)
+ [ex: CZCBd45Q6DmtExAd8Bm2"]. Regardez l'example.conf pour un exemple.
+ oldcloak: C'est l'ancien algorithme utilisé par Unreal3.2 et les versions précédentes, il est ici dans le but
+ de vous montrer l'évolution du processus de chiffrage des hosts/IP réels. Il n'est plus considéré comme sécurisé
+ (vous devriez avoir un avertissement si vous l'utilisez)
+ et vous devriez passer au 'cloak' dès que tous les serveurs seront mis à jour.
Les Cloak keys DOIVENT être les mêmes sur TOUS LES SERVEURS d'un réseau. Elles doivent être gardées SECRETES car + il est possible de déchiffrer l'host original si vous connaissez ces clés (ce qui rendrait le umode +x obsolète).
+UnrealIRCd supporte des modules, ce qui est très sympathique car :
+ - Vous pouvez les charger/décharger pendant que l'ircd est lancé (avec /rehash).
+ Cela vous permet de corriger certains bugs ou d'ajouter de nouvelles spécificités
+ sans être obligé de redémarrer !
+ - D'autres personnes peuvent créer (3rd party) des modules avec de nouvelles commandes, modes utilisateurs et même des modes channels.
+ UnrealIRCd contient seulement quelques modules. Regarder ici www.unrealircd.com -> modules ou utiliser google pour trouver des 3rd party modules.
+
Vous avez besoin de lancer au moins 2 modules ausinon vous n'aurez pas la possibilité d'amorcer l'ircd ! :
+ - Le module des commandes : commands.so (commands.dll sous windows)
+ - un module de cloaking: habituellement cloak.so (cloak.dll sous windows)
Les Snomasks sont des notices serveurs, c'est un type spécial de usermode que vous recevrez sous forme de notices serveurs. + (la plupart du temps, cela est utilisé par les opérateurs).
+Cela peut être établi par: /mode votrepseudo +s SNOMASK, par exemple: /mode votrepseudo +s +cF
+ Pour enlever certains snomasks, utilisez quelque chose comme : /mode votrepseudo +s -c
+ Ou vous pouvez aussi enlever tous vos snomasks en écrivant simplement: /mode votrepseudo -s
Les snomasks disponibles sont :
+ c - les connexions locales
+ F - les connexions globales (exceptées celles qui proviennent des serveurs qui sont dans vos U:lines)
+ f - les notices de flood
+ k - les notices de kill [*]
+ e - les notices de 'eyes'
+ j - les notices de 'junk'
+ v - les notices de vhost
+ G - les notices de gline/shun
+ n - les changements de pseudo locaux
+ N - les changements de pseudo globaux
+ q - les notices d'interdiction d'utilisation de nick (Q:line)
+ s - recevoir les notices serveurs [*]
+ S - recevoir les notices de l'anti-spam
+ o - recevoir les notices d'identification oper
+ [*: ces snomasks sont autorisés aux non-opérateurs]
+
Vous pouvez rendre automatique le don de snomasks (set::snomask-on-connect) et aussi + ceux que vous souhaitez quand vous vous /oper (set::snomask-on-oper, oper::snomask)
Avec les aliases vous pouvez configurer des commandes rapides. Par exemple "/ns identify blah" + sera envoyé à nickserv (cela sera traduis par : privmsg nickserv identify blah). Vous pouvez + bien entendu créer des alias plus compliqués comme /register qui sera retourné vers Chanserv + si le premier paramètre est un # ou sinon vers nickserv.
+Les aliases sont à configurer dans les alias blocks contenus dans le fichier de configuration, + vous pouvez aussi inclure un fichier avec des aliases par défaut dont la plupart des services se servent.
UnrealIRCd a un système d'aide accessible via /helpop. La commande /helpop est entièrement configurable
+ via l'help block dans le fichier de configuration. En supplément, un help.conf est inclus, il contient
+ une aide basique pour toutes les commandes par défaut.
+ Par exemple /helpop chmodes vous donne la liste de tous les modes channels disponibles d'UnrealIRCd.
+ Rappelez vous que si vous êtes un opérateur (helpop) vous devrez ajouter le préfix ? aux mots clés,
+ donc /helpop devient /helpop ? et
+ /helpop chmodes devient /helpop ?chmodes etc..
3.6 - Niveau d'accés des opérateurs
Dans UnrealIRCd, plusieurs niveaux d'opérateurs sont accessibles. Vous pouvez définir des droits supplémentaires (comme l'utilisation de /gline). + Grâce à cela vous pouvez donner aux opérateurs les privilèges dont ils ont besoin.
+Cela est contrôlé par les flags opérateurs dans l'oper block, regardez l'oper block pour plus d'informations.
UnrealIRCd a beaucoup de commandes performantes pour les opérateurs qui sont expliquées dans Commandes utilisateurs et opérateurs, + vous voudrez probablement lire cela après l'installation :)
Le SSL (Secure Socket Layer) vous permet de sécuriser les connexions grâce à un chiffrement des E/S. + Vous pouvez l'utiliser pour sécuriser le trafic entre serveurs mais aussi le trafic client<->serveur. + Habituellement, le SSL est utilisé pour protéger contre le sniffing et pour l'authentification.
+Pour l'utiliser, il vous faudra compiler votre IRCd avec le support SSL. Pour avoir un port SSL, voici la syntaxe : listen::options::ssl.
+Les connexions SSL ne sont pas par défaut (donc ne mettez pas le port 6667 en SSL !!), il vous faut un client ou un tunnel qui supporte le protocol SSL.
+Clients supportant le SSL: XChat, + irssi, + mIRC (6.14 et supérieures, + requiert certaines dlls additionelles)
+Pour les clients ne supportant pas le SSL vous pouvez utiliser un tunnel comme
+ stunnel, ci-dessous, un exemple de stunnel.conf ( pour stunnel 4.x):
+
client = yes + [irc] + accept = 127.0.0.1:6667 + connect = irc.myserv.com:6697 ++ Si vous vous connectez sur 127.0.0.1 port 6667, votre trafic sera chiffré et retourné vers irc.myserv.com port 6697 (un port SSL). +
Il faut aussi que vous ayez des certificats valides quand vous vous connectez aux serveurs et ne pas les accepter aveuglément + (comme dans l'exemple stunnel) sinon vous serez vulnérable aux attaques "active sniffing" (ssl redirects). + Ce n'est toutefois pas l'endroit approprié pour en parler (renseignez vous sur le SSL, ne nous demandez rien). + [mIRC et xchat vous donne la possibilité d'accepter ou non un certificat, ce qui est parfait].
UnrealIRCd supporte l'IPv6, depuis la beta15 cela semble être stable.
+ Votre OS a besoin d'avoir le support IPv6 et il faut valider le support IPv6 durant le ./Config.
+
Bien que Microsoft ai une implantation expérimentale de l'IPv6 pour w2k/XP, cela n'est pas (encore) supporté par UnrealIRCd.
Les Zip links peuvent être activés pour les links entre serveurs, il compresse les données en utilisant zlib. + Il peut sauvegarder entre 60 et 80% de votre bande passante... Donc, cela est très utilisé pour les links ayant + des bandes passantes faibles ou les links avec énormément d'utilisateurs, cela peut beaucoup aider quand vous + lancez un /connect et que le serveur à relier contient de nombreux utilisateurs/channels/etc...
+Pour compiler avec le support zip links, il faudra répondre Yes lors de la question portant sur le zlib pendant le + ./Config et ajouter dans votre link block link::options::zip (des deux côtés).
3.11 - Support des links avec IP/DNS dynamiques
UnrealIRCd a quelques (nouvelles) spécificités qui aideront les utilisateurs ayant des IP dynamiques et qui utilisent des DNS dynamiques + (comme blah.dyndns.org). Si vous linkez 2 hosts DNS dynamiques, voici ce que vous devrez mettre : + link::options::nodnscache et link::options::nohostcheck.
3.12 - Caractéristiques Anti-Flood
+Throttling
+Le Throttling est une méthode qui vous permet de déterminer le temps minimum pour qu'un client se reconnecte après une déconnexion à votre serveur.
+Vous pouvez configurer cela dans votre set::throttle block pour autoriser X connexions toutes les YY secondes depuis la même IP.
+Modes des salons
+Certains modes channels sont très efficaces contre le flood. En voici quelque uns:
+K = /knock interdit, N = changements de pseudo interdits, C = CTCPs interdits, M = seul les utilisateurs enregistrés peuvent parler.
+Depuis la beta18, il y a un mode channel beaucoup plus avancé +f...
+Mode salon f
+A la place d'utiliser des scripts ou des bots pour vous protéger du flood, cela est maintenant possible dans l'ircd.
+Un exemple du mode +f est : *** Blah sets mode: +f [10j]:15
+Cela signigie que 10 joins sont autorisés toutes les 15secondes sur le salon, si la limite est atteinte, le salon va mettre automatiquement le mode +i
+Les types de flood suivant sont disponibles :
+
| Type: | Nom: | Action par défaut: | Autres actions possibles: | Commentaires |
| c | CTCPs | auto +C | m, M | |
| j | joins | auto +i | R | |
| k | knocks | auto +K | (uniquement pour les clients locaux) | |
| m | messages/notices | auto +m | M | |
| n | nickchanges | auto +N | ||
| t | text | kick | b | par messages/notices utilisateurs comme l'ancien +f. Kick ou ban l'utilisateur. |
+Example: +
*** ChanOp sets mode: +f [20j,50m,7n]:15 +<ChanOp> lalala +*** 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 +-- snip XX lines -- +*** Evil21 (~jiovoihew@Clk-48D826C3.e.something.org) has joined #test +-server1.test.net:#test *** Channel joinflood detected (limit is 20 per 15 seconds), putting +i +*** server1.test.net sets mode: +i +<Evil2> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl +<Evil12> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl +<Evil15> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl +<Evil10> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl +<Evil8> fsdjfdshfdkjfdkjfdsgdskjgsdjgsdsdfsfdujsflkhsfdl +-- snip XX lines -- +-server1.test.net:#test *** Channel msg/noticeflood detected (limit is 50 per 15 seconds), putting +m +*** server1.test.net sets mode: +m +*** Evil1 is now known as Hmmm1 +*** Evil2 is now known as Hmmm2 +*** Evil3 is now known as Hmmm3 +*** Evil4 is now known as Hmmm4 +*** Evil5 is now known as Hmmm5 +*** Evil6 is now known as Hmmm6 +*** Evil7 is now known as Hmmm7 +*** Evil8 is now known as Hmmm8 +-server1.test.net:#test *** Channel nickflood detected (limit is 7 per 15 seconds), putting +N +*** server1.test.net sets mode: +N ++ +En fait, cela peut être plus avancé/compliqué:
+Les types de ban basiques et les cloaked hosts
+UnrealIRCd supporte les types de ban basiques comme +b nick!user@host.
+Mais aussi, si l'host masqué de quelqu'un est 'rox-ACB17294.isp.com' et que vous posez un ban *!*@rox-ACB17294.isp.com,
+alors si l'utilisateur enlève le mode x (/mode votrepseudo -x) (et son host devient par exemple 'dial-123.isp.com')
+alors le ban fonctionnera toujours. Les bans sont toujours vérifiés pour les hosts réels ET les hosts masqués.
+Les bans avec des IP sont aussi disponibles (ex: *!*@128.*) et sont aussi toujours vérifiés.
+
+Les bans sur les cloaked IPs requièrent quelques explications :
+Si l'IP d'un utilisateur est 1.2.3.4 son cloaked host pourrait être 341C6CEC.8FC6128B.303AEBC6.IP.
+Si vous bannissez *!*@341C6CEC.8FC6128B.303AEBC6.IP vous bannirez donc aussi *!*@1.2.3.4 (ce qui semble évident...)
+Si vous bannissez *!*@*.8FC6128B.303AEBC6.IP vous bannissez *!*@1.2.3.*
+Si vous bannissez *!*@*.303AEBC6.IP vous bannissez *!*@1.2.*
+Cela devrait vous aider à savoir comment un ban doit être établi le moment venu.
+
+Types de ban étendus
+Les bans étendus ressemble à ~[!]<type>:<stuff>. Actuellement, les types suivant sont disponibles:
+
| type: | nom: | explication: |
| ~q | quiet | Les personnes conformes à ces bans peuvent rejoindre les salons mais ne peuvent pas parler, + si ils n'ont pas au moins comme flag +v. Ex: ~q:*!*@blah.blah.com |
| ~n | nickchange | Les personnes conformes à ces bans ne peuvent pas changer de pseudo, + si ils n'ont pas au moins comme flag +v. Ex: ~n:*!*@*.aol.com |
| ~c | channel | Si l'utilisateur est sur ce salon, il ou elle ne pourra pas rejoindre le salon. +Ex: ~c:#lamers |
| ~r | realname | Si le nom réel d'un utilisateur est conforme alors il ne pourra pas rejoindre le salon. + Ex: ~r:*Stupid_bot_script* + NOTE: un underscore ('_') correspond aussi bien à un espace (' ') qu'à un underscore ('_'), donc ce ban correspondra à + 'Stupid bot script v1.4'. |
Le Spamfilter est un nouveau système de lutte contre le spam, la publicité, les worms et plein d'autres choses. + Il fonctionne un peu comme que le système de badwords mais il a de nombreux avantages.
+Les Spamfilters sont ajoutés grâce à la commande /spamfilter qui utilise la syntaxe suivante:
+ /spamfilter [add|del|remove|+|-] [type] [action] [tkltime] [reason] [regex]
+
| [type] | Spécifie le type de la cible: +
| |||||||||||||||||||||||||||
| [action] | specifie l'action devant être prise (seule 1 action peut être specifiée) +
| |||||||||||||||||||||||||||
| [tkltime] | Durée de la *line ajoutée par le filre, utilisez '-' pour mettre la valeur par défaut ou pour passer outre + (ex: si action = 'block') | |||||||||||||||||||||||||||
| [reason] | Raison du Block ou de la *line... Vous NE POUVEZ PAS, mais des underscores ('_') seront traduits + par des espaces lors de l'utilisation. Et un double underscore ('__') donne un underscore ('_'). Encore une fois, utilisez '-' pour utiliser la valeur par défaut. | |||||||||||||||||||||||||||
| [regex] | Ceci est le vrai regex ou "bad word" correspondant au terme qui doit bloquer le message et lancer l'action. |
Vous pouvez aussi ajouter des spamfilters dans le fichier de configuration mais ceux ci seront des
+ spamfilters locaux (non globaux, mais vous pouvez utiliser d'autres "includes" pour cela).
+ La syntaxe de ces spamfilters { } block sont expliqués ici
+ Exemple:
+
spamfilter {
+ regex "//write \$decode\(.+\|.+load -rs";
+ target { private; channel; };
+ reason "Generic $decode exploit";
+ action block;
+};
+
+set::spamfilter::ban-time vous autorise à modifier le ban time par défaut pour les *lines ajoutées par le spamfilter (défaut: 1 jour)
+ set::spamfilter::ban-reason vous autorise à spécifier une raison par défaut pour les *lines (défaut: 'Spam/advertising')
+ set::spamfilter::virus-help-channel vous autorise à spécifier le salon à joindre pour l'action 'viruschan' (défaut: #help)
+ set::spamfilter::virus-help-channel-deny vous autorise à bloquer tout join normal au virus-help-channel (défaut: no)
+
UnrealIRCd a maintenant un support pour le CIDR (Classless Interdomain Routing). CIDR vous + permet de bannir des ranges d'IP. Des Ips sont allouées aux FAI en utilisant CIDR, cela vous + permet en plaçant un ban basé sur le CIDR de bannir facilement un FAI. Unreal supporte le CIDR + pour l'IPv4 et l'IPv6. Les masques CIDR peuvent être utilisés dans l'allow::ip, ban user::mask, + ban ip::mask, except ban::mask, except throttle::mask, et except tkl::mask (pour gzline, gline, et shun). + De plus, le CIDR peut être utilisé dans les /kline, /gline, /zline, /gzline, et /shun. Unreal + utilise la syntaxe standard d'IP/bits, 127.0.0.0/8 (correspond à 127.0.0.0 - 127.255.255.255), + et fe80:0:0:123::/64 (correspond à fe80:0:0:123:0:0:0:0 - fe80:0:0:123:ffff:ffff:ffff:ffff).
UnrealIRCd a énormément de particularités donc tout n'est pas exposé ici... Vous découvrirez tout cela par vous même.
+
4.0 - Configurer votre unrealircd.conf +
Tout d'abord, créer un bon unrealircd.conf vous prendra un peu de temps, certainement quelquechose + comme 10 - 60 min. Vous pouvez essayer de le lancer le plus tôt que vous pouvez et le modifier plus tard, + ou alors vous pouvez étudier les sections principales directement pas-à-pas ce qui est la méthode recommandée :p. + Si vous avez un problème, vérifiez votre syntaxe, regardez dans le manuel et la FAQ avant de demander + de l'aide ou de rapporter un bug.
4.1 Explication du fichier de configuration
Le nouveau système utilise un système basé sur des blocs. Chaque entrée, ou bloc, dans le nouveau format a un format spécifique. + Le format est du type :
+<nom du bloc> <valeur du bloc> {
+ <directive du bloc> <valeur du bloc>;
+};
+
+<nom du bloc> est le type du bloc, tel que me, ou admin. <valeur du bloc> + parfois spécifie une valeur, telle que /oper login, mais d'autres fois ce sera des + sous-types tel que dans un ban utilisateur.
+<directive du bloc> est une variable individuelle spécifique au bloc, et + <valeur de la directive> contient des espaces, ou des caractères représentant + un commentaire qui doit être contenu entre des guillemets. Si vous voulez utiliser un + guillemet à l'intérieur à l'intérieur d'un commentaire (texte entre guillemets) + utilisez \" et il sera interprété comme un caractère simple.
+Une <directive du bloc> peut contenir des directives, si c'est le cas elle aura + elle aura son propre jeu d'accolades l'entourant. Certains blocs n'ont pas de directives + et sont juste spécifiés par <valeur du bloc>, tel que include. + Notez aussi qu'il n'y a pas de format défini, cela veut dire qu'un bloc peut tenir sur une + seule ligne comme sur plusieurs lignes. Le format ci-dessus est ce qui est normalement utilisé + (et qui sera utilisé dans ce fichier) parce qu'il est facile à lire.
+Note : le fichier de configuration est sensible aux majuscules / minuscules (case sensitive) + donc NOM-DU-BLOC n'est pas la même chose que nom-du-bloc. Il y a une notation spéciale utilisée + pour parler d'entrées dans le fichier de configuration. Par exemple pour parler du <nom de la directive> + dans l'exemple ci-dessus, vous devrez dire <nom du bloc>::<directive du bloc>, et si + la directive a un sous bloc que vous voulez référencer, vous ajouterez un autre :: et le nom + de la sous directive.
+Pour parler d'une directive non nommée vous devrez mettre <nom du bloc>:: qui voudra + dans ce cas dire <valeur du bloc>, ou cela pourra être une entrée dans un sous bloc + qui n'a pas de nom.
+Trois types de commentaires sont supportés :
+ # commentaire d'une seule ligne
+ // Ocommentaire d'une seule ligne
+ /* Commentaire
+ multi-ligne */
+
Maintenant que vous savez comment ça fonctionne, créez votre unrealircd.conf ou copiez doc/example.conf + et commencez à l'éditer. Il est recommandé d'y aller pas à pas avec les différents blocs et de suivre ce + manuel de référence.
+4.2 - Me Block + OBLIGATOIRE (Connu précédemment comme M:Line)
Syntaxe:
+
me {
+ name <nom du serveur>;
+ info <description du server>;
+ numeric <numeric du serveur>;
+};
+
+Ces valeurs sont plutôt claires. Le nom défini le nom du serveur, + info défini les ligne d'information sur le serveur, numeric défini + un numérique pour identifier le serveur. Ce dernier doit avoir une valeur comprise + entre 1 et 255 qui est SPÉCIFIQUE au serveur ce qui signifie qu'aucun autre serveur + du réseau ne doit avoir le même numérique.
+Exemple:
+
me {
+ name "irc.foonet.com";
+ info "FooNet Server";
+ numeric 1;
+};
+4.3 - Admin Block + OBLIGATOIRE (Connu précédemment comme A:Line)
Syntaxe:
+
admin {
+ <text-line>;
+ <text-line>;
+};
+
++
Ce bloc défini le texte qui sera affiché lors d'une requête /admin. Vous pouvez + spécifier autant de lignes que vous le souhaitez et elles peuvent contenir toutes + les informations que vous voulez, mais il est standard d'indiquer les pseudos et email + des admins au minimum. Vous pouvez également inclure d'autres informations sur les + contacts que vous désirez donner.
+Exemple:
+
admin {
+ "Bob Smith";
+ "bob";
+ "widely@used.name";
+};
+4.4 - Class Block + OBLIGATOIRE (Connu précédement comme Y:Line)
Syntaxe:
+
class <name> {
+ pingfreq <ping-frequency>;
+ connfreq <connect-frequency>;
+ maxclients <maximum-clients>;
+ sendq <send-queue>;
+ recvq <recv-queue>;
+};
+
++
Les Class blocks sont les classes dans lequels les connections seront placées (par exemple pour les + allow blocks ou les serveurs des link blocks), vous avez généralement plusieurs class blocks (exemple : pour les serveurs, clients, opers).
+name est la description, comme "clients" ou "serveurs", ce nom est utilisé comme + référence pour les classes dans allow/link/oper/etc blocks.
+pingfreq est le nombre de secondes entres les PINGs depuis le server (quelquechose entre 90 et 180 secondes est recommandé).
+connfreq est utilisé uniquement pour les serveurs et représente le nombre de secondes entre 2 tentatives de connections si l'autoconnection est activée.
+maxclients spécifie le nombre maximum (total) de clients / serveurs pouvant faire partie de cette classe.
+sendq spécifie la quantité d'informations pouvant être dans la file d'envoi (send queue) (très grand pour les serveurs avec une faible bande passante, moyen pour les clients).
+recvq spécifie la quantité d'informations pouvant être dans la file de reception (receive queue) et est utilisé pour contrôler le flood (cela s'applique uniquement aux + utilisateurs normaux, essayez avec des valeurs 3000-8000, 8000 est la valeur par défaut).
+Exemples:
+
class clients {
+ pingfreq 90;
+ maxclients 500;
+ sendq 100000;
+ recvq 8000;
+};
+
+class servers{
+ pingfreq 90;
+ maxclients 10; /* Nombre maximal de serveur pouvant être linké au même moment */
+ sendq 1000000;
+ connfreq 100; /* Combien de secondes entre 2 tentatives de connexions */
+};
+
+
4.5 - Allow Block + OBLIGATOIRE (connu précédemment comme I:Line)
Syntaxe:
+
allow {
+ ip <user@ip-connection-mask>;
+ hostname <user@host-connection-mask>;
+ class <connection-class>;
+ password <connection-password> { <auth-type>; };
+ maxperip <max-connections-per-ip>;
+ redirect-server <server-to-forward-to>;
+ redirect-port <port-to-forward-to>;
+ options {
+ <option>;
+ <option>;
+ ...
+ };
+};
+
+C'est ici que vous spécifiez qui peut se connecter à ce serveur, vous pouvez avoir plusieurs allow blocks.
+A propos des correspondances
+ Le contrôle des accès fonctionne comme ceci : concordances des ip ou des host, donc "hostname *@*"; et "ip *@1.2.3.4"
+ signifiera que ça concordera toujours. Les allow blocks sont lus de haut en bas, donc vous devez spécifier les host/ip
+ particuliers APRÈS votre allow block général *@*. De plus, si vous voulez spécifier un bloc basé uniquement sur la
+ correspondance à un ip, alors mettez pour l'hostname quelque chose d'invalide, tel que "hostname PERSONNE;",
+ cela permettra au bloc de ne vérifier que la correspondance de l'ip.
ip
+ L'ip mask est de la forme user@ip, user est l'ident et souvent est défini par *, ip est l'ipmask. Quelques exemples : *@*
+ (depuis n'importe où), *@192.168. * (seulement depuis les adresses commençant par 192.168), etc.
host
+ Également un user@host hostmask, encore une fois... user est souvent défini par *. Quelques exemples : *@* (n'importe où),
+ *@*.wanadoo.fr (seulement depuis wanadoo.fr).
password (optionnel)
+ Requiert un mot de passe à la connexion. Vous devez également spécifier une méthode d'encryption des mot de passe ici.
+
class
+ Spécifie le nom de la classe dans lequel les connections relevant de cet allow block sont placées.
+
maxperip (optionnel, mais recommendé)
+ Vous permet de spécifier combien de connections à ce serveur sont autorisées par ip (exemple : maxperip 4;).
+
redirect-server (optionnel)
+ Si la classe est pleine, les utilisateurs seront redirigés vers ce serveur (si les clients le supporte [mIRC 6 le fait]).
redirect-port (optionnel)
+ Si un serveur de redirection est spécifié vous pouvez définir le port ici, sinon ce sera le 6667.
options block (optionnel)
+ Les options valides sont :
+ useip toujours afficher l'ip à la place de l'hostname
+ noident n'utilise pas d'ident mais l'username spécifié par le client
+ ssl ne fonctionne que si le client est connecté via ssl
+ nopasscont concordance continue si aucun mot de passe n'est donnée (ainsi vous pourrez mettre des clients dans des
+classes spéciales si ils fournissent un mot de passe).
+
Exemples:
+
allow {
+ ip *;
+ hostname *;
+ class clients;
+ maxperip 5;
+};
+
+allow {
+ ip *@*;
+ hostname *@*.passworded.ugly.people;
+ class clients;
+ password "f00Ness";
+ maxperip 1;
+};
++
4.6 - Listen Block + OBLIGATOIRE (Connu précédemment comme P:Line)
Syntaxe:
+
listen <ip:port> {
+ options {
+ <option>;
+ <option>;
+ ...
+ };
+};
+
++
Ce bloc vous permet de spécifier les ports d'écoute de votre IRCd. + Si aucune option n'est requise, vous devez le spécifier sans aucune directive + sous la forme listen <ip:port>;.
+ip et port
+ Vous pouvez mettre * comme valeur pour ip pour toutes les accepter, ou en spécifier une pour accepter
+ uniquement les connexions sur cette ip (habituellement requis chez des loueurs de shell). Le port est
+ le port que vous voulez écouter. Vous pouvez également spécifier un intervalle de ports à la place d'une
+ valeur unique. Par exemple, 6660-6669 écoutera du port 6660 au port 6669 (inclus). Pour les utilisateur
+ d'IPv6, voir ci-dessous.
Info pour les utilisateurs de l'IPv6
+ Si vous avez un serveur Ipv6 vous devrez inclure les ip entre crochets. Comme [::1]:6667 (écouter en localhost
+ sur le port 6667). Si vous utilisez l'IPv6 et que vous voulez écouter une adresse Ipv4 spécifique vous devrez
+ utiliser ::ffff:ipv4ip. Par exemple : [::ffff:203.123.67.1]:6667 qui écoutera à 203.123.67.1 sur le port 6667.
+ Évidemment, vous pouvez aussi juste utiliser *.
options block (optionnel)
+ Vous pouvez spécifier des options spéciales pour ce port si vous le souhaitez, les options possibles sont :
+
| port réservé aux clients | |
| port réservé aux serveurs | |
| support CR java | |
| port encrypté SSL |
Exemples:
+listen *:6601 {
+ options {
+ ssl;
+ clientsonly;
+ };
+};
+
+
+Si il n'y a pas d'options :
+listen *:8067;
+ listen 213.12.31.126:6667;
+ listen *:6660-6669;
4.7 - Oper Block + RECOMMENDE (Connu précédemment comme O:Line)
+
oper <name> {
+ from {
+ userhost <hostmask>;
+ userhost <hostmask>;
+ };
+ password <password> { <auth-type>; };
+ class <class-name>;
+ flags <flags>;
+ flags {
+ <flag>;
+ <flag>;
+ ...
+ };
+ swhois <whois info>;
+ snomask <snomask>;
+ modes <modes>;
+ maxlogins <num>;
+};
+
+L'oper block vous permet d'assigner des IRC Opérateurs pour votre serveur. Le oper:: + spécifie le login pour la commande /oper. Le oper::from::userhost est le masque user@host + auquel l'utilisateur doit correspondre, vous pouvez spécifier plus qu'un seul hostmask en + créant plusieurs oper::from::userhost. Le oper::password est le mot de passe que l'utilisateur + doit spécifier, oper::password:: vous permet de spécifier une méthode d'authentification pour ce mot de passe, + les types d'authentifications valides sont crypt, md5 et sha1, ripemd-160. Si vous voulez laisser + un mot de passe non crypté ne mettez pas ce sous-bloc.
+Notez s'il vous plait que le login et le mot de passe sont tous deux case sensitive autrement dit les majuscules + et les minuscules ont leurs importance.
+La directive oper::class spécifie le nom d'une classe préexistante (apparaît avant dans le fichier + de configuration) que le oper block utilisera.
+La directive oper::flags a deux formats. Si vous voulez utiliser l'ancien style d'oper flags, + OAa, vous utilisez la méthode flags <flags> method, si vous voulez utiliser la nouvelle méthode, + alors vous utiliserez la méthode flags { <flag>; } Ci-dessous ce trouve la liste des flags + (dans les deux formats) et leurs correspondances.
+Ancien Flag |
+ Nouveau Flag |
+ Description | +
o |
+ local |
+ Fait de vous un local operator | +
O |
+ global |
+ Fait de vous un global operator | +
C |
+ coadmin |
+ Fait de vous un coadmin | +
A |
+ admin |
+ Fait de vous un admin | +
a |
+ services-admin |
+ Fait de vous un services admin | +
N |
+ netadmin |
+ Fait de vous un Network Admin | +
r |
+ can_rehash |
+ Oper pouvant utiliser /rehash | +
D |
+ can_die |
+ Oper pouvant utiliser /die | +
R |
+ can_restart |
+ Oper pouvant utiliser /restart | +
h |
+ helpop |
+ Oper reçoit umode +h (helpop) | +
w |
+ can_wallops |
+ Oper pouvant envoyer des /wallops | +
g |
+ can_globops |
+ Oper pouvant envoyer des /globops | +
c |
+ can_localroute |
+ Peut se connecter aux serveurs localement | +
L |
+ can_globalroute |
+ Peut se connecter aux serveurs globalement | +
k |
+ can_localkill |
+ Peut /kill les utilisateurs locaux | +
K |
+ can_globalkill |
+ Peut /kill les utilisateurs globaux | +
b |
+ can_kline |
+ Peut utiliser /kline | +
B |
+ can_unkline |
+ Peut utiliser /kline -u@h | +
n |
+ can_localnotice |
+ Peut envoyer des notices sur le serveur local | +
G |
+ can_globalnotice |
+ Peut envoyer des notices globales | +
z |
+ can_zline |
+ Peut utiliser /zline | +
t |
+ can_gkline |
+ Peut utiliser /gline, /shun et /spamfilter | +
Z |
+ can_gzline |
+ Peut utiliser /gzline | +
W |
+ get_umodew |
+ Mets umode +W lorsque vous vous oper | +
H |
+ get_host |
+ Vous applique un oper host | +
v |
+ can_override |
+ Peut utiliser OperOverride | +
q |
+ can_setq |
+ Peut utiliser l'usermode +q | +
X |
+ can_addline |
+ Peut utiliser /addline | +
d |
+ can_dccdeny |
+ Peut utiliser /dccdeny et /undccdeny | +
Certain flags give you other flags by default:
+| local | +global | +admin/coadmin | +services-admin | +netadmin | +
| can_rehash | +can_rehash | +can_rehash | +can_rehash | +can_rehash | +
| helpop | +helpop | +helpop | +helpop | +helpop | +
| can_globops | +can_globops | +can_globops | +can_globops | +can_globops | +
| can_wallops | +can_wallops | +can_wallops | +can_wallops | +can_wallops | +
| can_localroute | +can_localroute | +can_localroute | +can_localroute | +can_localroute | +
| can_localkill | +can_localkill | +can_localkill | +can_localkill | +can_localkill | +
| can_kline | +can_kline | +can_kline | +can_kline | +can_kline | +
| can_unkline | +can_unkline | +can_unkline | +can_unkline | +can_unkline | +
| can_localnotice | +can_localnotice | +can_localnotice | +can_localnotice | +can_localnotice | +
| + | can_globalroute | +can_globalroute | +can_globalroute | +can_globalroute | +
| + | can_globalkill | +can_globalkill | +can_globalkill | +can_globalkill | +
| + | can_globalnotice | +can_globalnotice | +can_globalnotice | +can_globalnotice | +
| + | + | global | +global | +global | +
| + | + | can_dccdeny | +can_dccdeny | +can_dccdeny | +
| + | + | + | can_setq | +can_setq | +
| + | + | + | + | admin | +
| + | + | + | + | services-admin | +
La directive oper::swhois vous permet d'ajouter une ligne supplémentaire dans le + whois d'un oper. [optionnel]
+La directive oper::snomask vous permet d'obtenir automatiquement les snomaks que vous + souhaitez lors d'un /oper. Pour avoir la liste des SNOMASKs possibles reportez vous à la + Section 3.3 [optionnel]
+La directive oper::modes vous permet de prédéfinir un mode oper lors de l'identification. + [optionnel]
+La directive oper::maxlogins vous permet de restreindre le nombre de login oper concurrent + pour un host, par exemple si vous définissez 1 alors, une seule personne pourra se oper à partir + d'un bloc à n'importe quel moment. + [optionnel]
+ +Exemple:
+
oper bobsmith {
+ class clients;
+ from {
+ userhost bob@smithco.com;
+ userhost boblaptop@somedialupisp.com;
+ };
+ password "f00";
+ flags {
+ netadmin;
+ can_gkline;
+ can_gzline;
+ can_zline;
+ can_restart;
+ can_die;
+ global;
+ };
+ swhois "Example of a whois mask";
+ snomask frebWqFv;
+};
+
+Quelques petites informations à propos d' OperOverride :4.8 - DRpass Block + RECOMMENDE (connu précédemment comme X:Line)
Syntaxe:
+
drpass {
+ restart <restart-password> { <auth-type>; };
+ die <die-password> { <auth-type>; };
+};
+Ce bloc défini les mots de passe /restart et /die avec respectivement drpass::restart + et drpass::die. Les drpass::restart:: et drpass::die:: vous permettent de spécifier le + type d'authentification qu'ils utilisent. Les types d'authentification actuellement + supportés sont crypté, md5 et sha1, ripemd-160.
+Exemple:
+drpass {
+ restart "I-love-to-restart";
+ die "die-you-stupid";
+};
+
+
Syntaxe:
+ include <file-name>;
Cette directive spécifie le nom de fichier devant être chargé comme fichier de configuration séparé. + Ce fichier peut contenir n'importe quel type de bloc de configuration et peut également inclure d'autres + fichiers. Les wildcards sont supporté dans le nom du fichiers pour vous permettre de charger plusieurs + fichiers en une fois.
+exemple 1: un fichier réseau
+
include mynetwork.network;+
Ce sera la syntaxe à utiliser si vous voulez utiliser un fichier réseau séparé. Les fichiers réseaux + séparés ne sont plus requis; tous les paramètres réseaux peuvent être insérés directement dans + unrealircd.conf. Ou vous pouvez mettre un include pour les charger depuis le fichier.
+exemple 2: aliases
+
include aliases/ircservices.conf+
Un autre exemple est de l'utiliser pour inclure des alias blocks, UnrealIRCd est fournis avec des fichiers
+ contenant les bons aliases pour beaucoup de services:
+
4.10 - LoadModule Directive + OBLIGATOIRE
Syntaxe:
+ loadmodule <file-name>;
Reportez-vous ici pour voir pourquoi les modules sont biens/utiles.
+Modules qui viennent standards avec Unreal3.2 :
+commands.so / commands.dll - Toutes les / commandes (en réalité pas encore toutes, mais pourra éventuellement être toutes) OBLIGATOIRE
+ cloak.so / cloak.dll - Cloaking module OBLIGATOIRE (ou n'importe quel autre cloaking module)
Si vous voulez être sur que ceux si seront chargés :
+loadmodule "src/modules/commands.so"; +loadmodule "src/modules/cloak.so"; ++
ou sous windows:
+loadmodule "modules/commands.dll"; +loadmodule "modules/cloak.dll"; ++
Syntaxe:
+
log <file-name> {
+ maxsize <max-file-size>;
+ flags {
+ <flag>;
+ <flag>;
+ ...
+ };
+};
+
+Le log block vous permet d'assigner différents fichiers de log pour différentes actions. + Le log:: contient le nom du fichier de log. log::maxsize est une directive optionnelle + vous permettant de spécifier la taille à laquelle vous voulez que le fichier soit effacé et relancé. + Vous pouvez utiliser MB pour megabytes, KB pour kilobytes, GB pour gigabytes. + Le log::flags spécifie quel type d'information sera dans ce log. + Ci-dessous la liste des flags disponibles.
+Vous pouvez également avoir plusieurs log block, pour loguer différentes choses dans des fichiers différents.
+Flags disponibles:
+
| errors | erreurs |
| kills | logue le /kill notices |
| tkl | logue les infos sur les *lines, shun et spamfilters (ajout/suppression/expiration) |
| connects | logue les connexions / déconnexions des utilisateurs |
| server-connects | logue les connections / squit des serveurs |
| kline | logue l'usage des /kline |
| oper | logue les tentatives de s'oper (réussies et ratées) |
| sadmin-commands | logue l'usage des /sa* (samode, sajoin, sapart, etc.) |
| chg-commands | logue l'usage des /chg* (chghost, chgname, chgident, ect.) |
| oper-override | logue l'usage des operoverrides |
| spamfilter | logue les concordances au spamfilter |
Exemple:
+log ircd.log {
+ maxsize 5MB;
+ flags {
+ errors;
+ kills;
+ oper;
+ kline;
+ tkl;
+ };
+};
+
+4.12 - TLD Block + OPTIONNEL (connu précédemment comme T:Line)
Syntaxe:
+
tld {
+ mask <hostmask>;
+ motd <motd-file>;
+ rules <rules-file>;
+ shortmotd <shortmotd-file>;
+ channel <channel-name>;
+ options {
+ ssl;
+ }
+};
+Le tld block vous permet de spécifier un motd, rules (règles), et salon pour un utilisateur + en se basant sur son host. C'est utile si vous voulez différents motd pour différentes langues. + Le tld::mask est un masque user@host auquel l'username et l'host de l'utilisateur doivent + correspondre. Les tld::motd, tld::shortmotd, et tld::rules spécifie respectivement + les fichiers motd, shortmotd et rules qui doivent être affichés pour un hostmask. + Le tld::shortmotd est optionnel. tld::channel spécifie respectivement les fichiers motd, + shortmotd et rules qui doivent être affichés pour un hostmask. Le tld::shortmotd est optionnel. + Le bloc tld::options vous permet de définir des exigences supplémentaires, habituellement + seuls tld::options::ssl qui affiche seulement le fichier pour les usagers SSL, et tld::options::remotes + qui affiche seulement le fichier pour les utilisateurs étrangers existent.
+Les entrées TLD sont vérifiées de haut en bas.
+Exemple:
+
tld {
+ mask *@*.fr;<
+ motd "ircd.motd.fr";
+ rules "ircd.rules.fr";
+};
+4.13 - Ban Nick Block + OPTIONNEL (connu précédemment comme Q:Line)
Syntaxe:
+
ban nick {
+ mask <nickname>;
+ reason <reason-for-ban>;
+};
+Le ban nick block vous permet d'interdire l'utilisation d'un pseudo sur le serveur. + Le ban::mask permet à des masques avec joker de correspondre à plusieurs pseudos, et + ban::reason vous permet de spécifier la raison pour laquelle ce ban a été placé. + Le plus souvent ces blocs sont utilisés pour bannir l'usage de pseudos généralement + utilisés par des services réseaux.
+Exemple:
+
ban nick {
+ mask "*C*h*a*n*S*e*r*v*";
+ reason "Reserved for Services";
+};
+4.14 - Ban User Block + OPTIONNEL (connu précédemment comme K:Line)
Syntaxe:
+
ban user {
+ mask <hostmask>;
+ reason <reason-for-ban>;
+};
+Ce bloc vous permet de bannir un masque user@host à sa connexion au serveur. + Le ban::mask est une version avec joker du user@host à bannir, et ban::reason est la raison pour + laquelle ce ban a été placé. Notez que ceci est uniquement un ban local et l'utilisateur peut + toujours se connecter à un autre serveur pour rejoindre le réseau.
+Exemple:
+
ban user {
+ mask *tirc@*.saturn.bbn.com;
+ reason "Idiot";
+};
+4.15 - Ban IP Block + OPTIONNEL (connu précédemment comme Z:Line)
Syntaxe:
+
ban ip {
+ mask <ipmask>;
+ reason <reason-for-ban>;
+};
+Le ban ip block banni une IP lorsqu'il se connecte au serveur. Cela inclus aussi bien les + utilisateurs que les serveurs qui essayent de se connecter. Le paramètre ban::mask est un IP + pouvant contenir un joker, et ban::reason est la raison pour laquelle ce ban a été placé. + Depuis que ce ban affecte les serveur il doit être utilisé très prudemment.
+Exemple:
+
ban ip {
+ mask 192.168.1.*;
+ reason "Get a real ip u lamer!";
+};
+
4.16 - Ban Server Block + OPTIONNEL (connu précédemment comme q:Line)
Syntaxe:
+
ban server {
+ mask <server-name>;
+ reason <reason-for-ban>;
+};
+Ce bloc retire la possibilité d'un serveur de se connecter au réseau. Si le serveur se link directement + à votre serveur, le link sera rejeté. Si le serveur se link à un autre serveur, le serveur local se + déconnectera du réseau. Le champ ban::mask spécifie un masque avec joker à confronter au nom du serveur + tentant de se connecter, et ban::reason spécifie la raison pour laquelle ce ban a été placé.
+Exemple:
+
ban server {
+ mask broken.server.my.network.com;
+ reason "Its broken!";
+};
+
4.17 - Ban RealName Block + OPTIONNEL (connu précédemment comme n:Line)
Syntaxe:
+
ban realname {
+ mask <realname-mask>;
+ reason <reason-for-ban>;
+};
+Le ban realname block vous permet de bannir un client basé sur le champs GECOS (realname). + Cela est utilisé pour les flood de clones car souvent les bots clones utilisent le même realname. + Le ban::mask spécifie le realname devant être banni. Le masque peut contenir un joker. + Le ban::reason spécifie pour ce ban a été placé.
+Exemple:
+
ban realname {
+ mask "Bob*";
+ reason "Bob sucks!";
+};
+4.18 - Ban Version Block + OPTIONNEL
Syntaxe:
+
ban version {
+ mask <version-mask>;
+ reason <reason-for-ban>;
+ action [kill|tempshun|shun|kline|zline|gline|gzline];
+};
+Le ban version block vous permet de bannir un utilisateur pour l'utilisation du client IRC qu'il utilise. + Ceci se base sur la réponse au CTCP version envoyé au client. Il est donc bien entendu que si le + client n'envoie pas de réponse au CTCP version, le ban ne fonctionnera pas. Cette fonction doit vous + permettre de bloquer des scripts dangereux. Le ban::mask spécifie la version devant être bannie. + Le mask peut contenir un joker. Le ban::reason spécifie la raison pour laquelle le ban a été placé. + Vous pouvez également spécifier ban::action, kill est la valeur par défaut, + tempshun shunera uniquement la connexion de l'utilisateur et devrait fonctionner très efficacement + contres les bots/zombies avec des IPs dynamiques car il n'affectera pas les utilisateurs innocents. + shun/kline/zline/gline/gzline placeront un ban de ce type sur l'ip (*@IPADDR), la durée de ce ban + peut être configurée avec set::ban-version-tkl-time et est de 1 jour par défaut.
+Exemples:
+
ban version {
+ mask "*SomeLameScript*";
+ reason "SomeLameScript contains backdoors";
+};
+ban version {
+ mask "*w00tZombie*";
+ reason "I hate those hundreds of zombies";
+ action zline;
+};
+
+4.19 - Ban Exceptions Block + OPTIONNEL (connu précédemment comme E:Line)
Syntaxe:
+
except ban {
+ mask <hostmask>;
+};
+L'except ban block vous permet de spécifier un user@host qui outrepassera un ban placé sur une plage de host. + Ceci est très utile lorsque vous voulez bannir un FAI, mais que vous voulez que certains utilisateurs + spécifiques puissent toujours se connecter. La directive except::mask spécifie le masque user@host + du client qui sera autorisé à se connecter.
+Exemple:
+
except ban {
+ mask myident@my.isp.com;
+};
+4.20 - TKL Exceptions Block + OPTIONNEL
Syntaxe:
+
except tkl {
+ mask <hostmask>;
+ type <type>;
+ type {
+ <type>;
+ <type>;
+ ...
+ };
+};
+L'except tkl block vous permet de spécifier un user@host qui pourra outrepasser un ban tkl + placé sur une plage de host. Ceci est très utile lorsque vous voulez bannir un FAI, mais que + vous voulez que certains utilisateurs spécifiques puissent toujours se connecter. La directive + except::mask spécifie le masque user@host du client qui sera autorisé à se connecter. + L' except::type spécifie quel type de ban pourra être outrepassé. Les types valides sont + gline, gzline, qline, gqline et shun qui feront une exception pour les Glines, Global Zlines, + Qlines, Global Qlines, et shuns.
+Exemple:
+
except tkl {
+ mask myident@my.isp.com;
+ type gline;
+};
+4.21 - Throttle Exceptions Block + OPTIONNEL +
Syntaxe:
+
except throttle {
+ mask <ipmask>;
+};
+L'except throttle block vous permet de spécifier une IP qui pourra outrepasser le throttling system. + Ceci fonctionne uniquement si vous avez choisi d'activer le throttling. L'except::mask spécifie l'IP + qui ne sera pas bannie à cause du throttling.
+Exemple
+
except throttle {
+ mask 192.168.1.*;
+};
+4.22 - Deny DCC Block + OPTIONNEL (connu précédemment comme dccdeny.conf) +
Syntaxe:
+
deny dcc {
+ filename <file-to-block>;
+ reason <reason-for-ban>;
+ soft [yes|no];
+};
+Le deny dcc block vous permet de spécifier un nom de fichier qui ne pourra être envoyé + par DCC via le serveur. Ceci est très utile pour aider à stopper la propagation de + virus et / ou trojans.
+Le paramètre deny::filename spécifie un masque avec joker du nom de fichier à rejeter, + et deny::reason spécifie la raison pour laquelle ce fichier est bloqué.
+Il existe aussi une option deny::soft ,si elle a la valeur 'yes' (oui) le dcc sera bloqué + à moins que l'utilisateur le permette explicitement via /DCCALLOW + pseudo-essayant-d'envoyer. + Regardez le dccallow.conf pour avoir un bon exemple de configuration pour dccallow.
+Exemples
+
deny dcc {
+ filename virus.exe;
+ reason "This is a GD Virus";
+};
+
+deny dcc {
+ filename "*.exe";
+ reason "Executable content";
+ soft yes;
+};
+4.23 - Deny Version Block + OPTIONNEL (connu précédemment comme V:Line)
Syntaxe:
+
deny version {
+ mask <server-name>;
+ version <version-number>;
+ flags <compile-flags>;
+};
+Ce bloc vous permet d'interdire à un serveur de se linker en fonction de la version + d'Unreal qu'il utilise et quelle option de compilation il a. Le format pour ce bloc + est un peu complexe mais il n'est pas trop difficile à comprendre. La directive deny::mask + spécifie le nom du serveur avec joker auquel il s'applique. Le deny::version spécifie le + numéro de protocole de la version auquel on fait référence.
+Par exemple, 3.0 d'où 2301, 3.1.1/3.1.2 d'où 2032, 3.2 d'où 2303. Le premier + caractère de ce paramètre peut être un des suivant >, <, =, !. Ce caractère + dit à l' IRCd comment interpréter la version. Si ce caractère est un > + alors toutes les versions supérieures à celle spécifiée seront interdites, Si c'est un < + toutes les versions inférieures seront interdites, si c'est un = seulement cette version sera interdite, + et si c'est un ! alors toutes les versions seront interdites excepté celle spécifiée. La directive + deny::flags vous permet de spécifier que compile time flag le serveur doit ou ne doit pas avoir. + Les flags sont arrangé l'un après l'autre sans séparation entre eux, si un caractère est précédé d'un ! + alors cela signifiera que le serveur ne pourra pas être compilé avec ce flag, si il n'y a pas de préfixe !, + alors cela signifiera que le serveur devra être compilé avec ce flag.
+4.24 - Deny Link Block + OPTIONNEL (connu précédemment comme D/d:Line)
Syntaxe:
+
deny link {
+ mask <server-name>;
+ rule <crule-expression>;
+ type <type-of-denial>;
+};
+Ce bloc vous permets d'utiliser des règles spécifiques pour interdire le link d'un serveur. + Le deny::mask spécifie un nom de serveur avec joker auquel cette règle s'applique. + La directive deny::rules est très complexe. Une expression crule vous permet de contrôler + le link en détail, et il se règle comme un programme. Quatre opérateurs sont supportés, + connected(<servermask>), retourne vrai si un serveur correspondant au + servermask est connecté, directcon(<servermask>), etourne vrai si un serveur + correspondant au servermask est directement connecté à ce serveur, + via(<viamask>,<servermask>), retourne vrai si un serveur correspondant au + servermask est connecté à partir d'un serveur correspondant au viamask, et directop(), + qui retourne vrai si l'IRCOP utilisant /connect est directement connecté sur ce serveur. + Ces opérateurs peuvent être combinés en utilisant && (et) et || (ou), les items + peuvent également être mis entre parenthèses pour permettre le regroupement. De plus, un + opérateur précédé d'un ! vérifier si l'opérateur retourne faux. Si l'expression est évaluée + comme entièrement vraie, alors le link est refusé. Le deny::type permet deux valeurs différentes, + auto (s'applique uniquement aux autoconnexions, /connect fonctionnera toujours), et all + (s'applique à toutes les tentatives de connections).
+4.25 - Deny Channel Block + OPTIONNEL (connu précédemment comme chrestrict.conf) +
Syntaxe:
+
deny channel {
+ channel "<channel-mask>";
+ reason <reason-for-ban>;
+ redirect "<channel-name>";
+ warn [on|off];
+};
++
Le deny channel block vous permet d'interdire aux utilisateurs de rejoindre un salon. + La directive deny::channel spécifie le nom d'un salon avec joker que les utilisateurs + ne pourront rejoindre, et le deny::reason spécifie la raison pour laquelle le salon + ne peut être rejoint. De plus, vous pouvez spécifier un deny::redirect. Si celui-ci est + spécifié, lorsqu'un utilisateur essaye de rejoindre un salon correspondant à un deny::channel, + il ou elle sera redirigé(e) vers deny::redirect. Et il y a également deny::warn + qui (si il est activé) enverra une opernotice (au EYES snomask) si un utilisateur essaye de rejoindre le salon. +
+Exemples
+deny channel {
+ channel "#unrealsucks";
+ 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";
+ redirect "#help";
+};
+
+4.26 - Allow Channel Block + OPTIONNEL +
Syntaxe:
+
allow channel {
+ channel "<channel-mask>";
+};
+Le allow channel block vous permet de spécifier des salons spécifiques que les utilisateurs pourront joindre. + La directive allow::channel spécifie les noms de salon avec joker pouvant être rejoint.
+Exemple:
+
allow channel {
+ channel "#something";
+};
+4.27 - Allow DCC Block + OPTIONNEL +
Syntaxe:
+
allow dcc {
+ filename "<filename-mask>";
+ soft [yes|no];
+};
+Le allow dcc block vous permet de spécifier des exceptions au deny dcc block, + les jokers sont permis. Si allow dcc::soft est mis à 'yes' il applique la liste + des 'soft dcc bans', si il est mis à 'no' il applique la listes des dcc bans normaux ('hard').
+Exemple:
+
allow dcc {
+ filename "*.jpg"; /* Images are usually safe */
+ soft yes;
+};
+4.28 - Vhost Block + OPTIONNEL (connu précédemment comme vhosts.conf) +
Syntaxe:
+
vhost {
+ vhost <vhost>;
+ from {
+ userhost <hostmask>;
+ userhost <hostmask>;
+ ...
+ };
+ login <login-name>;
+ password <password> { <auth-type>; };
+ swhois "<swhois info>";
+};
+Le vhost block vous permet de spécifier un login/mot-de-passe pouvant être utilisé avec + la commande /vhost pour obtenir un faux hostname. Le paramètre vhost::vhost peut être un + user@host ou juste un host que l'utilisateur recevra après un /vhost réussi. Le vhost::from::userhost + contient un user@host auquel l'utilisateur doit correspondre pour être éligible pour un vhost. Vous + pouvez spécifier plus d'un hostmask. Le vhost::login est le login que l'utilisateur doit rentrer + et vhost::password est le mot de passe devant être entré. Le vhost::password:: vous permet de spécifier + le type d'authentification utilisé par cet item. Les types d'authentification actuellement supportés + sont crypté, md5 et sha1, ripemd-160. Finallement, vhost::swhois vous permet d'ajouter un ligne + supplémentaire au whois des utilisateurs, exactement comme dans le oper block oper::swhois.
+Exemple:
+
vhost {
+ vhost my.own.personal.vhost.com;
+ from {
+ userhost my@isp.com;
+ userhost myother@isp.com;
+ };
+ login mynick;
+ password mypassword;
+ swhois "Im Special";
+};
+4.29 - Badword Block + OPTIONNEL (connu précédemment comme badwords.*.conf) +
Syntaxe:
+
badword <type> {
+ word <text-to-match>;
+ replace <replace-with>;
+ action <replace|block>;
+};
+Le badword block vous permet de manipuler la liste utilisée pour le mode utilisateur + et salon +G pour cacher les 'mauvais mots'. Le badword:: spécifie le type, les types + valides sont channel, message, quit et all. Channel est pour la liste des salons +G, message + est pour la liste des utilisateurs +G, quit est pour la censure des messages de quit et all + est pour ajouter les trois listes. Le badword::word peut être un simple mot ou une expression + régulière que nous pouvons chercher. Le badword::replace est ce par quoi doit être remplacé + le mot correspondant. Si badword::replace n'est pas spécifié, le mot est remplacé + par <censored>. Le badword::action défini quelle action doit être réalisée si un mauvais + mots est trouvé. Si vous spécifiez replace, alors le mauvais mots est remplacé, si vous spécifez + block, le message entier sera bloqué. Si vous ne spécifiez pas un badword::action, le mot sera remplacé.
+Exemple:
+
badword channel {
+ word shit;
+ replace shoot;
+};
+4.30 - ULines Block + OPTIONNEL (connu précédemment comme the U:Line)
Syntaxe:
+
ulines {
+ <server-name>;
+ <server-name>;
+ ...
+};
+Le ulines block vous permet d'accorder à certains serveurs des possibilités supplémentaires. + Ceci doit uniquement être utilisé pour des serveurs comme les services et les stats. + Ceci ne doit pas être appliqué à un serveur normal. Chaque entrée est le nom du serveur qui + recevra les possibilités supplémentaires.
+Exemple
+
ulines {
+ services.mynetwork.com;
+ stats.mynetwork.com;
+};
+4.31 - Link Block + OPTIONNEL (connu précédemment comme C/N/H:Lines) +
Syntaxe:
+
link <server-name> {
+ username <usermask>;
+ hostname <ipmask>;
+ bind-ip <ip-to-bind-to>;
+ port <port-to-connect-on>;
+ password-connect <password-to-connect-with>;
+ password-receive <password-to-receive> { <auth-type>; };
+ hub <hub-mask>;
+ leaf <leaf-mask>;
+ leafdepth <depth>;
+ class <class-name>;
+ ciphers <ssl-ciphers>;
+ options {
+ <option>;
+ <option>;
+ ...
+ };
+};
+C'est le bloc dont vous avez besoin pour linker les serveurs, s'il vous plaît prenez le temps de + lire tout ceci car c'est l'une des parties les plus difficiles et les utilisateurs font souvent des erreurs. ;P
+D'abord server-name est le nom du serveur distant, le nom que le serveur distant a dans son bloc me { }, + tel que hub.blah.com (pas l'ip et peut être différent de l'hostname).
+username
+ Vous pouvez le spécifier si vous utilisez l'ident pour l'authentification,normalement vous mettrez "*".
+
hostname
+ L'host ou l'ip du serveur distant. Ceci est utilisé pour la connexion et pour l'authentification / vérification
+ du coté entrant. Quelques exemples :
+
| 1.2.3.4 | IP normale |
| hub.blah.com | host: seulement pour sortie, ne peut accepter de connexion entrante sans + la présence de link::options::nohostcheck |
| * | ne peut pas se connecter mais accepte la connexion de n'importe quel serveur (avec le bon mot de passe) |
| ::ffff:1.2.3.4 | pour linker de l'ipv6 à de l'ipv4. |
bind-ip (optionnel)
+ Peut être utilisé pour spécifier un IP (ex. : 192.168.0.1) depuis lequel nous devons nous connecter,
+ presque jamais utilisé.
+
port
+ Port auquel on se connecte (celui que le serveur distant écoutera).
+
password-connect
+ Le mot de passe utilisé pour se connecter au serveur distant, doit être écrit en clair.
+
password-receive
+ Le mot de passe utilisé pour valider les links entrants, peut être encrypté
+ (les méthodes d'encryptions valides sont crypt, md5, sha1, ripemd-160).
+ Vous pouvez laisser le paramètre auth-type décrypté. Souvent, il est le même que le password-connect.
+
hub vs leaf
+ Un hub a plusieurs serveurs linké à lui, un leaf n'a qu'un seul link... le vôtre.
+ Un serveur est soit un hub, soit un leaf, vous ne pouvez combiner ces options.
+
hub (optionnel)
+ Cette valeur est un masque des serveurs auquel ce hub peut se connecter (ex. : *.my.net).
+
leaf (optionnel)
+ Cette valeur est un masque que ce serveur interprétera comme un leaf.
+
leaf-depth (optionnel)
+ Si celui-ci est spécifier, alors leaf doit l'être aussi.
+ Cette valeur spécifie la profondeur (nombre de sauts) que ce serveur peut avoir derrière lui.
+
class
+ La classe dont ce serveur fait partie, souvent une classe de serveurs séparés est utilisé pour ceci.
+
compression-level (optionnel)
+ Spécifie le taux de compression (1-9) pour ce link. Seulement utilisé si link::options::zip est activé.
+
ciphers (optionnel)
+ Specifie le SSL ciphers a utiliser pour ce link. Pour obtenir une liste de ciphers disponibles, utilisez
+ la commande `openssl ciphers`. Les ciphers doivent être spécifiés comme : une liste séparée.
+
options block
+ Une ou plusieurs options utilisées pour se connecter à ce serveur. Parfois pas requises.
+
| ssl | si vous êtes connecté à un port ssl. |
| autoconnect | le serveur essayera de se connecter automatiquement, le temps est + spécifié dans votre class::connfreq (il est mieux d'activer ceci seulement dans un sens, comme leaf->hub) |
| zip | si vous voulez des links compressés, vous devez compiler les deux serveurs concernés avec l'option zip activé |
| nodnscache | ne pas cacher l'ip pour les connexions des serveurs sortants, utilisez cela + pour des serveurs dont l'host change souvent (comme dyndns.org) |
| nohostcheck | ne pas valider l'host distant (link::hostname), utilisez cela pour des + serveurs dont l'host change souvent (comme dyndns.org) |
| quarantine | les opers sur ce serveur conserveront le status de locop. |
Exemple:
+link hub.mynet.com {
+ username *;
+ hostname 1.2.3.4;
+ bind-ip *;
+ port 7029;
+ hub *;
+ password-connect "LiNk";
+ password-receive "LiNk";
+ class servers;
+ options {
+ autoconnect;
+ ssl;
+ zip;
+ };
+};
+
4.32 - Alias Block + OPTIONNEL +
Syntaxe [standard alias]:
+
alias <name> {
+ target <nick-to-forward-to>;
+ type <type-of-alias>;
+};
+(Note: reportez-vous également ici à propos des fichiers d'alias standards d'UnrealIRCd)
+L'alias block (alias standards) vous permet de transmettre une commande à un + utilisateur, par exemple /chanserv envoie un message à l'utilisateur chanserv. + L' alias:: spécifie le nom de la commande qui sera l'alias (ici : chanserv), + alias::target est le pseudo ou le salon à qui il sera envoyé, si l' alias:: est + le même que la cible à qui il sera envoyé alias::target peut ne pas être rempli. + L' alias::type spécifie le type d'alias, les types valides sont services + (l'utilisateur est sur le serveur des services), stats (l'utilisateur est sur le + serveur de statistiques), normal (la cible est sur n'importe quel serveur). + L'alias block a également une autre utilité expliqué ci-dessous.
+Syntaxe [command alias]:
+
alias <name> {
+ format <regex-expression> {
+ target <nick-to-forward-to>;
+ type <type-of-alias>;
+ parameters <parameter-string>;
+ };
+ format <regex-expression> {
+ ...
+ };
+ type command;
+};
+Lorsque l'alias block est utilisé dans ce format, il vous permet une plus vaste plage d'usage. + Par exemple, vous pouvez créer des alias tels que /identify. L' alias:: est comme ci-dessus, + le nom de l'alias de commande. L' alias::format spécifie une expression régulière comparée au + texte envoyé à l'alias de commande, si l'entrée correspond à l' alias::format elle sera utilisée, + vous pouvez définir plusieurs alias::format qui feront faire différentes choses à la commande suivant + la syntaxe utilisée. L'alias::format::target est la cible à qui envoyer cette commande. + L' alias::format::type spécifie le type d'alias devant être transmit. L'alias::format::parameters + est ce qui sera envoyé à cet alias en tant que paramètre. Pour spécifier un des paramètres donné à + l'alias de commande, spécifiez % suivi d'un nombre, par exemple %1 est le premier paramètre. + Pour spécifier tous les paramètres depuis un paramètre donné jusqu'à la fin, mettez % suivi par + le nombre et un -, par exemple %2- retourne tous les paramètres depuis le deuxième jusqu'au dernier. + De plus, vous pouvez spécifier %n qui sera remplacé par le pseudo de l'utilisateur qui a tappé la commande. + Pour des exemples d'utilisation de l'alias block dans le format de commande, consultez le doc/example.conf.
+4.33 - Help Block + OPTIONNEL +
Syntaxe:
+
help <name> {
+ <text-line>;
+ <text-line>;
+ ...
+};
+(Note: normalement vous ajoutez seulement l'help.conf)
+L'help block vous permet des créer des entrées à utiliser dans /helpop. + L' help:: est la valeur qui doit être interprétée comme paramètre dans /helpop, + si l'help:: est laissé vide, alors il sera utilisé lorsqu'aucun paramètre n'est + précisé dans /helpop. Les entrées pour l'help block sont les textes qui seront affiché + lorsque l'utilisateur demandera l' /helpop.
+4.34 - Official Channels Block + OPTIONNEL +
Syntaxe:
+
official-channels {
+ "#channel" { topic "The default topic"; };
+};
+Les salons officiels sont affichés dans la /list même si aucun utilisateurs n'y sont. + Le topic est optionnel et est montré dans la /list si il y a 0 utilisateur. +
+ +Exemple:
+
official-channels {
+ "#Help" { topic "The official help channel, if nobody is present type /helpop helpme"; };
+ "#Home";
+ "#Main" { topic "The main channel"; };
+};
+4.35 - Spamfilter Block + OPTIONNEL +
+Le spamfilter block vous permet d'ajouter un filtre anti-spam local (pas au niveau du réseau).
+Voir Features - Spamfilter pour plus d'information à propos des filtres anti-spam.
+
Syntaxe:
+
spamfilter {
+ regex <word>;
+ target { <target(s)> };
+ action <action>;
+ reason <reason>;
+ ban-time <time>;
+};
+regex est le regex auquel on doit correspondre.
+ target spécifie les cibles, reportez-vous ici pour obtenir la liste des types disponibles (ex: 'channel').
+ action spécifie l'action à effectuer, reportez-vous ici pour obtenir la liste des types disponibles (ex: 'gline')
+ reason optionnel : spécifie la raison du ban ou du blocage, sinon la raison par défaut est utilisée.
+ ban-time optionnel : spécifie la durée d'un ban *line, sinon la valeur par défaut est utilisée (1 jour).
+
Exemples:
+
spamfilter {
+ regex "Come watch me on my webcam";
+ target { private; channel; };
+ action gline;
+ reason "You are infected, please go to www.antivirus.xx/blah/virus=GrrTrojan";
+ ban-time 6h;
+};
+
+spamfilter {
+ regex "come to irc\..+\..+";
+ target { private; channel; };
+ action gline;
+ action gline;
+ reason "No spamming allowed";
+};
+
+4.36 - Set Block + OBLIGATOIRE (connu précédemment comme unrealircd.conf/networks file) +
Le fichier set est ce qui est utilisé en tant que notre networks/unrealircd.conf et notre + fichier networks. Sur les réseaux d'un seul serveur, plutôt que d'avoir 3 fichiers vous pouvez + tout mettre dans l'unrealircd.conf lui même, sur les réseaux multi-serveurs, je vous recommande + d'utiliser des fichiers networks séparés.
+Maintenant, si votre serveur est sur un réseau, il y a des chances pour que vous utilisiez + basiquement les mêmes réglages Set. Dans ce cas, il est plus logique d'avoir un fichier network, + qui est chargé avec une directive include. + Ci-dessous, vous trouverez toutes les directives set disponibles.
+Dans cette documentation, nous nous référons aux réglages / directives sous la forme + <block-name>::<block-directive> Ce format N'est PAS le format pouvant être + entré dans le fichiers de configuration. IL DOIT être converti dans le format listé ci-dessous. + Il est présenté dans un format qui le rend plus simple à expliquer.
+Syntaxe:
+
set {
+ <entry> <value>;
+ <entry> <value>;
+ ...
+};
+Le set block appliques des options pour les réglages d'un serveur individuel. Chaque entrée
+ fait quelque chose de différent et elles seront toutes décrites ci-dessous. Certaines directives
+ ont des sous blocs qui seront également décrits. Il y a beaucoup de intitulés réglages à couvrir,
+ toutes les directives listées ci-dessous peuvent être incluses sous UN intitulé. Si une directive
+ a des options, elles seront incluses dans l'intitulé de réglages au mieux.
+ Exemple:
+
set {
+ kline-address my@emailaddress.com;
+ auto-join #welcome;
+ options {
+ hide-ulines;
+ };
+ hosts {
+ local LocalOp.MyNet.com;
+ global globalop.mynet.com;
+ };
+};
+Maintenant si vous voulez faire les intitulés de réglages séparément,
+ dites que vous voulez régler vos options sur une simple ligne.
+ Exemple:
+ set { options { hide-ulines; no-stealth; }; };
+
set::kline-address <email-address>;
+ L'adresse email à laquelle doivent être envoyés les questions sur les K:line.
+ Cette valeur doit être spécifiée.
set::modes-on-connect <+modes>;
+ Les modes qui seront appliqués à un utilisateur à la connexion.
set::snomask-on-connect <+modes>
+ Les snomask qui seront appliqués à un utilisateur à la connexion.
set::modes-on-oper <+modes>;
+ Les modes qui seront appliqués à un utilisateur lorsqu'il s' /oper.
set::snomask-on-oper <+modes>;
+ Les snomask qui seront appliqués à un utilisateur lorsqu'il s' /oper.
set::modes-on-join <+modes>;
+ Les modes qui seront appliqués à un salon lors de sa création.
+ Tous les modes ne peuvent pas être utilisés par cette commande.
+ +qaohvbeOAzlLk ne peuvent être appliqués par cette commande.
set::restrict-usermodes <modes>
+ Empêche les utilisateurs d'appliquer / enlever les modes listés ici (n'utilisez pas + ou -).
+ Par exemple, vous pouvez mettre le +G en modes-on-connect et G en restrict-usermodes,
+ de cette façon vous obligez tous les utilisateurs à avoir le mode +G et les empêcher
+ de se mettre en -G.
set::restrict-channelmodes <modes>
+ Empêche les utilisateurs d'appliquer / enlever les modes de salon listés ici (n'utilisez pas + ou -).
+ Par exemple, vous pouvez mettre le +G en modes-on-connect et G en restrict-channelmodes,
+ de cette façon vous obligez tous les (nouveaux) salons à avoir le mode +G et les empêcher de se mettre en -G.
+ NOTE : il peut toujours être possible d'utiliser ces modes de salon sans passer par les
+ services en utilisant MLOCK. Malheureusement nous ne pouvons pas en faire plus à ce propos, vous
+ devrez le demander aux codeurs de vos services d'implémenter une option restrict-channelmodes également.
set::restrict-extendedbans <types|*>
+ Ne permet pas aux utilisateurs d'utiliser des bans étendus ("*") ou en empêche certains (ex. : "qc").
set::auto-join <channels>;
+ Les salons qu'un utilisateur est forcé de rejoindre à la connexion.
+ Pour spécifier plus d'un salon, utilisez une virgule pour les séparer.
+ [Note : n'oubliez pas d'ajouter des quotes comme : auto-join "#chan";]
set::oper-auto-join <channels>;
+ Le(s) salon(s) qu'un utilisateur sera forcé de rejoindre après /oper.
+ Pour spécifier plus d'un salon, utilisez une virgule pour les séparer.
+ [Note: n'oubliez pas d'ajouter des quotes comme : oper-auto-join "#chan";]
set::anti-spam-quit-message-time <timevalue>;
+ Cette valeur de temps spécifie la durée minimale pendant laquelle l'utilisateur
+ doit être connecté avant de pouvoir afficher un message /quit. Utilisé pour prévenir le spam.
+ Une valeur de temps est une valeur numérique avec d pour jour, h pour heure, m pour minutes,
+ et s pour secondes, par exemple 1d2h3m signifie 1 jour, 2 heures, 3 minutes.
set::prefix-quit <text-to-prefix-quit>;
+ Défini le texte qui sera affiché devant le message de quit.
+ Si la valeur est 0, alors le texte standard "Quit:" sera appliqué.
set::static-quit <quit message>;
+ Défini le message de quit qui sera envoyé quel que soit le message envoyé par
+ le client lorsqu'il quitte le réseau. Ceci élimine le besoin de recourir à
+ l'anti-spam-quit-message-time, ainsi que le set::prefix-quit. Cela NE remplacera
+ PAS les ERREURS par le message static-quit.
set::static-part <no|yes|part message>;
+ Le 'yes' empêchera tous les commentaires de part, le 'no' laissera fonctionner
+ les part comme d'habitude, n'importe quoi d'autre sera utilisé comme commentaire
+ de part (ex. : static-part "Bye!") mais ca peut être assez ennuyeux, alors utilisez le prudemment.
set::who-limit <limit>;
+ Défini le nombre maximum de réponses retournées lors d'un /who.
+ Si cette option n'est pas spécifiée, il n'y aura pas de limite.
set::silence-limit <limit>;
+ Défini le maximum d'entrées dans la SILENCE list.
+ Si la directive n'est pas spécifiée, une limite de 15 sera appliquée.
set::oper-only-stats <stats-list>;
+ Spécifie une liste de flags stats sans séparateur qui défini les flags stats
+ que seuls les opérateurs pourront utiliser. Ne donnez pas de valeur si vous
+ voulez permettre aux utilisateurs d'utiliser tous les flags, ou spécifiez *
+ pour que les utilisateurs ne puissent en utiliser aucun. Seul les flags stats
+ cours peuvent être spécifiés ici.
set::oper-only-stats {<stats-flag>; <stats-flag>;};
+ Spécifie une liste de flags stats pouvant être utilisés uniquement par les opérateurs.
+ Ceci ne marche qu'avec les flags stats longs.
set::maxchannelsperuser <amount-of-channels>;
+ Spécifie le nombre de salons sur lesquels un simple utilisateur peut être en même temps.
set::maxdccallow <amount-of-entries>;
+ Spécifie le nombre maximum d'entrées qu'un utilisateur peut avoir dans son / sa list DCCALLOW.
set::channel-command-prefix <command-prefixes>;
+ Spécifie le caractère de préfixe pour les services dans les "commandes de salons".
+ Les messages commençant par le caractère spécifié seront envoyé même si le client est en +d.
+ La valeur par défaut est "`".
set::allow-userhost-change [never|always|not-on-channels|force-rejoin]
+ Spécifie ce qu'il arrive quand un user@host change (+x/-x/chghost/chgident/setident/vhost/etc).
+ never supprime toutes les commandes, always le permet toujours même si
+ le client est sur un salon (peut causer le desync du client) [défaut] not-on-channels
+ le permet uniquement si l'utilisateur n'est sur aucun salon, force-rejoin forcera à
+ rejoindre tous les salons avec re-op/voice/etc si nécessaire.
set::options::hide-ulines;
+ Si il est présent, Les serveurs avec Uline seront cachés dans une requête /links par les non-opers.
set::options::flat-map;
+ Si il est présent, tous les serveurs apparaîtrons comme directement linkés dans /map et /links,
+ ainsi vous ne pourrez plus voir quel serveur est linké directement au quel. C'est une petite aide
+ contre les attaque (D)DoS parce que les personnes mal-intentionnées ne peuvent plus voir
+ facilement les 'points faibles'.
set::options::show-opermotd;
+ Si il est présent, l'opermotd sera montré aux utilisateurs une fois qu'ils se seront /oper avec succès.
set::options::identd-check;
+ Si il est présent, la présence d'un serveur d'identd sera vérifiée et la valeur retournée
+ sera utilisée comme username. Si aucune requête d'ident n'est retournée ou si le serveur
+ d'identd n'existe pas, l'username de l'utilisateur spécifié sera préfixé d'un ~.
+ Si cette valeur est omise, aucune vérification ne sera faite.
set::options::show-connect-info;
+ Si il est présent, les notices "ident request", "hostname lookup", etc.
+ seront affichées à la connexion de l'utilisateur..
set::options::dont-resolve;
+ Si il est présent, les hosts des utilisateurs entrants ne seront pas résolus,
+ peut être utile si beaucoup de vos utilisateur n'ont pas d'host pour accélérer la connexion.
+ Notez que depuis que le 'non resolving' existe vous pouvez également avoir des allow blocks basés sur les hosts.
set::options::mkpasswd-for-everyone;
+ Fait en sorte que le /mkpasswd puisse être utilisé par tout le monde à la place des opers uniquement,
+ l'usage de cette commande par les non-opers est envoyé aux EYES snomask.
set::options::allow-part-if-shunned;
+ Permet aux utilisateurs shun d'utiliser /part.
set::dns::timeout <timevalue>;
+ Une valeur de temps spécifie la durée qu'un serveur DNS a pour répondre.
+ Une valeur de temps est un numérique avec d pour jour, h pour heure,
+ m pour minutes, et s pour secondes, par exemple 1d2h3m signifie 1 jour, 2 heures, 3 minutes.
set::dns::retries <number-of-retries>;
+ Une valeur numérique spécifie le nombre de fois que la résolution de DNS reprendra en cas d'échec.
set::dns::nameserver <name-of-dns-server>;
+ Spécifie l'hostname du serveur qui sera utilisé pour la résolution de DNS.
set::network-name <name-of-network>;
+ Spécifie le nom du réseau sur lequel ce serveur tourne.
+ Cette valeur devrait être exactement la même sur tous les serveurs d'un réseau.
set::default-server <server-name>;
+ Défini le nom au serveur par défaut à indiquer aux utilisateurs pour se
+ connecter si celui-ci est remplis.
set::services-server <server-name>;
+ Spécifie le nom du serveur auquel les services sont connectés. Obligatoire,
+ définissez le avec quelquechose comme services.yournet.com si vous n'avez pas de services.
set::stats-server <server-name>;
+ Établis le nom du serveur sur lequel le bot de statistique est présent.Si aucun service de
+ statistique n'est lancé, cette valeur peut être ignoré.
set::help-channel <network-help-channel>;
+ Spécifie le nom du channel d'aide du réseau.
set::cloak-keys { "key1"; "key2"; "key3"; };
+ Spécifie les clés qui seront utilisés pour générer les +x hosts.
+ Cette valeur doit être la même sur tous les serveurs d'un réseau.
+ Si ce n'est pas le cas, les serveurs ne pourront plus linker.
+ Les 3 set::cloak-keys:: doivent être des strings de 5 à 100 caractères
+ (10 à 20, c'est bien), elles doivent contenir des lowercases (a-z),
+ des uppercases (A-Z) et des chiffres (0-9). Noter que cela dépend du module
+ de cloaking que vous utilisez, d'autres règles peuvent être appliquées.
set::hiddenhost-prefix <prefix-value>;
+ Définis le préfix qui sera utilisé dans les hiddenhosts (+x).
+ Il est composé généralement de trois ou quatre lettres qui représente le nom du réseau.
set::hosts::local <locop-host-name>;
+ Définie l'hostname qui sera assigné aux opérateurs locaux quand ils se mettent le umode +x.
+ Vous pouvez optionnellement specifier un username@host pour cette valeur.
set::hosts::global <globop-host-name>;
+ Définie l'hostname qui sera assigné aux opérateurs globaux quand ils se mettent le umode +x.
+ Vous pouvez optionnellement specifier un username@host pour cette valeur.
set::hosts::coadmin <coadmin-host-name>;
+ Définie l'hostname qui sera assigné aux co-admins quand ils se mettent le umode +x.
+ Vous pouvez optionnellement specifier un username@host pour cette valeur.
set::hosts::admin <admin-host-name>;
+ Définie l'hostname qui sera assigné aux admins quand ils se mettent le umode +x.
+ Vous pouvez optionnellement specifier un username@host pour cette valeur.
set::hosts::servicesadmin <servicesadmin-host-name>;
+ Définie l'hostname qui sera assigné aux services-admins quand ils se mettent le umode +x.
+ Vous pouvez optionnellement specifier un username@host pour cette valeur.
set::hosts::netadmin <netadmin-host-name>;
+ Définie l'hostname qui sera assigné aux netadmins quand ils se mettent le umode +x.
+ Vous pouvez optionnellement specifier un username@host pour cette valeur.
set::hosts::host-on-oper-up <yes/no>;
+ Si vous mettez yes, le flag H/get_host sera honoré et le umode +x sera automatiquement
+ mis quand vous vous /oper. Si vous mettez no, l'utilisateur doit se mettre le umode +x
+ manuellement pour recevoir l'oper host.
set::ssl::egd <filename>;
+ Spécifie que le support de l'EGD (Entropy Gathering Deamon) devrait être activé.
+ Si vous utilisez OpenSSL 0.9.7 ou une version postérieure, alors /var/run/egd-pool,
+ /dev/egd-pool, /etc/egd-pool, et /etc/entropy seront recherchés par défaut donc aucun
+ nom de fichier n'est nécessaire, vous pouvez simplement spécifier set::ssl::egd sans valeur.
+ Si vous utilisez une version d'OpenSSL antérieure à la 0.9.7 ou vous voulez utiliser
+ un socket EGD placé ailleurs que dans la liste des emplacements listés ci-dessus,
+ vous pouvez spécifier le nom de fichier de l'UNIX Domain Socket qu'un EGD écoute.
set::ssl::certificate <filename>;
+ Spécifie le nom de fichier où le certificat SSL du serveur est situé.
set::ssl::key <filename>;
+ Spécifie le nom de fichier où la clé privée SSL du serveur est située.
set::ssl::trusted-ca-file <filename>;
+ Spécifie le nom de fichier où les certificats du trusted CAs sont situés.
set::ssl::options::fail-if-no-clientcert;
+ Force les clients n'ayant pas de certificat a être refusé.
set::ssl::options::no-self-signed;
+ N'autorise par de connexion en provenance de personne ayant des certificats auto-signés.
set::ssl::options::verify-certificate;
+ Fais qu' Unreal détermine si le certificat SSL est valide avant d'accepter la connexion.
set::throttle::period <timevalue>
+ Combien de temps un utilisateur doit attendre avant de ce reconnecter.
set::throttle::connections <amount>;
+ Combien de fois un utilisateur doit se connecter avec le même host pour être throttled. ( stoppé )
set::ident::connect-timeout <amount>;
+ Nombre de secondes avant de renoncer à la connexion au serveur d'ident (défaut : 10s).
set::ident::read-timeout <amount>;
+ Nombre de secondes avant de renoncer à une réponse (défaut : 30s).
set::anti-flood::unknown-flood-bantime <timevalue>;
+ Spécifie combien de temps une connexion inconnue d'un floodeur est bannie.
set::anti-flood::unknown-flood-amount <amount>;
+ Spécifie la quantité de données (en KiloBytes) que la connexion inconnue
+ doit envoyer pour que l'utilisateur soit killé.
set::anti-flood::away-flood <count>:<period>
+ Protection contre le flood d'away : limite le nombre de /away par périodes en secondes.
+ Ceci réclame que le NO_FLOOD_AWAY soit activé dans le config.h. Exemple : away-flood 5:60s;
+ signifie maximum 5 changements en 60 secondes.
set::anti-flood::nick-flood <count>:<period>
+ Protection contre le NickFlood : limite le nombre de changements de pseudo par
+ périodes en secondes. Par exemple nick-flood 4:90
+ signifie 4 en 90 secondes, le défaut est 3 en 60 secondes.
set::default-bantime <time>
+ Le bantime par défaut quand vous faites /kline, /gline, /zline, /shun, etc sans paramètre
+ de temps (comme /gline *@some.nasty.isp), par défaut, celui ci est permanent (0).
+ Exemple: default-bantime 90d;
set::modef-default-unsettime <value>
+ Pour le chmode +f vous pouvez spécifier un unsettime par défaut, si vous spécifiez 10 par exemple,
+ alors +f [5j]:15 sera transformé en [5j#i10]:15. La valeur par défaut est pas d'unsettime par défaut.
set::modef-max-unsettime <value>
+ Le nombre maximum de minutes pour un mode +f unsettime (in +f [5j#i
set::ban-version-tkl-time <value>
+ Si vous spécifiez une 'action' like zline/gline/etc dans les ban version, alors vous pouvez
+ spécifier ici combien de temps l'ip va être bannie, par défaut, ceci est établi à 86400 (1 jour).
set::spamfilter::ban-time <value>
+ Même chose qu'au dessus mais pour les *lines ajoutés par le spamfilter
set::spamfilter::ban-reason <reason>
+ La raison utilisée pour l'ajout de *lines par le spamfilter
set::spamfilter::virus-help-channel <channel>
+ Le salon a utiliser pour l'action 'viruschan' dans le spamfilter
set::spamfilter::virus-help-channel-deny <yes|no>
+ Si vous mettez yes (ou "1") cela enverra "invite only" à tous les utilisateurs normaux
+ essayant de rejoindre le virus-help-channel. Seul les opérateurs, les personnes qui
+ résulte des spamfilters et les personnes qui sont /invite peuvent le rejoindre.
set::spamfilter::except <target(s)>
+ Ces cibles sont exemptés du spamfilter ( aucune action sera entrepris ), cela peut être
+ une simple cible, ou une liste séparé par des virgules. Ex: except "#help,#spamreport"
+
| ircd.motd | Affiché lorsqu'un /motd est exécuté et (si ircd.smotd n'est pas présent) lorsqu'un utilisateur se connecte | +
| ircd.smotd | Affiché à la connexion uniquement (MOTD court) | +
| ircd.rules | Affiché lorsqu'un /rules est exécuté | +
| oper.motd | Affiché lorsqu'un /opermotd est exécuté ou lorsque vous tapez /oper | +
| bot.motd | Affiché lorsqu'un /botmotd est exécuté | +
6 – Modes des salons et des utilisateurs +
Mode |
+ Description |
+
Modes des salons |
+ |
A |
+ Seul les administrateurs peuvent rejoindre le salon | +
a <nick> |
+ Rend l'utilisateur administrateur du salon | +
b <nick!user@host> + |
+ Banni du salon l'utilisateur spécifié | +
c |
+ Aucune couleur ANSI ne peut être envoyé sur le salon | +
C |
+ Aucun CTCP n'est accepté sur le salon | +
e <nick!user@host> |
+ Exception ban – L'utilisateur spécifié peut rejoindre le salon même + si il en est banni | +
f * <lines:seconds> |
+ Flood protection, Si le * est spécifié, un utilisateur sera kickban + si il envoie <lines:seconds> si le * n'est pas spécifié, il sera juste kické | +
G |
+ Contrôle les mots listés dans les Badword Blocks + et les remplace par les mots spécifiés. | +
M |
+ Seul les utilisateurs dont le pseudo est enregistré (+r) peuvent parler sur le salon | +
h <nick> |
+ Donne le statut de half-op à l'utilisateur | +
i |
+ Le salon ne peut être rejoint que sous invitation | +
K |
+ /knock n'est pas autorisé | +
k <key> |
+ Attribue un mot de passe à spécifier pour rejoindre le salon | +
l <##> |
+ Spécifie le nombre maximum d'utilisateurs | +
L <Chan> |
+ Si le maximum spécifié par +l est atteint, les utilisateurs seront redirigés vers ce salon | +
m |
+ Salon modéré. Seuls les utilisateurs +v/h/o peuvent parler | +
N |
+ Aucun changement de pseudo n'est autorisé | +
n |
+ Aucune message ne peut être envoyé de l'extérieur du salon | +
O |
+ Seul les IRCops peuvent joindre le salon | +
o <nick> |
+ Donne le statut d'opérateur à l'utilisateur | +
p |
+ Rend le salon privé (n'apparaît plus dans la liste des salons) | +
q <nick> |
+ Rend l'utilisateur « owner » (propriétaire) du salon | +
Q |
+ Seul les U:Lined peuvent kicker les utilisateurs | +
R |
+ Seuls les utilisateurs enregistrés peuvent rejoindre le salon | +
S |
+ Supprime toutes les couleurs | +
s |
+ Rend le salon secret (n'apparaît plus dans la liste des salons) | +
t |
+ Seuls les chanops peuvent changer le topic | +
T |
+ Aucune notice ne peut être envoyée sur le salon | +
u |
+ Auditorium – Les commandes /names et /who #chan n'affichent que les opérateurs | +
V |
+ /invite n'est pas autorisé | +
v <nick> |
+ Donne le statut de voice à l'utilisateur (peut parler quand le salon est modéré, +m) | +
z |
+ Seul les utilisateurs avec une connexion sécurisée (SSL) peuvent joindre le salon | +
+
Mode |
+ Description |
+
Modes des utilisateurs |
+ |
r |
+ Identifie le pseudo comme étant enregistré | +
s |
+ Peut lire les server notices | +
v |
+ Reçoit les notices de refus de DCC infectés | +
o |
+ Global IRC Operator (défini par Oper Block) | +
O |
+ Local IRC Operator (défini par Oper Block) | +
B |
+ Vous renseigne comme étant un bot | +
i |
+ Invisible (n'est pas montré dans un /who) | +
A |
+ Server Admin (défini dans Oper Block) | +
x |
+ Donne à l'utilisateur un hostname caché | +
q |
+ Seul les U:Lines peuvent vous kicker (Services Admin uniquement) | +
a |
+ Services Admin (défini dans Oper Block) | +
g |
+ Peut envoyer et lire les globops et locops | +
H |
+ Cache le status d'IRCop (IRCop uniquement) | +
S |
+ Utilisé pour protéger les Services Daemons | +
t |
+ Dis que vous utilisé un /vhost | +
C |
+ Co-Admin (défini dans Oper Block) | +
d |
+ Fait en sorte que vous ne puissiez pas recevoir de message provenant des channels | +
N |
+ Network Administrator (défini dans Oper Block) | +
w |
+ Peut lire les wallops | +
h |
+ Disponible pour aide (HelpOp) (défini dans Oper Block) | +
G |
+ Filtre tous les bad words définis par configuration | +
W |
+ Vous laisse voir quand quelqu'un vous /whois (IRCop uniquement) | +
p |
+ Cache les canaux sur lesquels vous êtes dans les /whois | +
R |
+ Vous permet de ne recevoir de messages privés et de notices que d'utilisateurs enregistrés (+r) | +
V |
+ Vous marque comme un utilisateur de WebTV | +
z |
+ Indique que vous êtes un client SSL | +
T |
+ Vous empêche de recevoir des CTCPs | +
7 – Commandes utilisateurs et opérateurs
Notez que la documentation fournie par /helpop est plus à jour, utilisez /helpop commande (ou /helpop ?commande si vous êtes oper) + pour avoir des informations sur une commande.
+ +Commande |
+ Description |
+ Qui |
+
| nick <newnickname> | +Change votre pseudo. Averti les autres de votre changement de pseudo |
+ Tous | +
| whois <nick> | +Affiche les informations sur l'utilisateur ciblé. Inclus le pseudo, l'host, les salons sur lesquels il se trouve et son statut d'Oper.
+ Si vous êtes un IRCOP, vous avez accès à plus d'informations tel que les umodes de l'utilisateur. |
+ Tous | +
| who <mask> | +Vous permet de chercher des utilisateurs.
+ Masks inclus : pseudo, #salon, hostmask (*.attbi.com) |
+ Tous | +
| whowas <nick> <max de réponses> | +Affiche les informations sur un pseudo qui n'est plus connecté.
+ Le nombre maximum de réponses est facultatif et limite le nombre d'enregistrements qui seront retournés |
+ Tous | +
| ison <nick1 nick2 nick3 ...> | +Vous permet de vérifier qu'un utilisateur (ou plusieurs) est connecté.
+ Réponse simple, meilleur usage pour les scripts. |
+ Tous | +
| join <channel1,channel2, ...> | +Vous permet de rejoindre des salons. Utiliser /join #salon1,#salon2,#salon3 + vous permettra de rejoindre plus d'un salon en une fois. La commande /join 0 vous + fait partir (PART) de tous les salons. | +Tous | +
| cycle <channel1, channel2, ...> | +Cycle les salons spécifiés. Cette commande équivaut à faire un PART suivi d'un JOIN. + ( Pour les utilisateurs de mIRC, la commande /hop est équivalente ) | +Tous | +
| motd <server> | +Affiche le motd ( Message Of The Day ) du serveur. Vous pouvez spécifier un nom de
+ serveur si vous souhaitez voir le motd d'un serveur particulier sur un réseau. |
+ Tous | +
| rules <server> | +Affiche le ircd.rules d'un serveur. Ajouter le nom d'un serveur. Vous pouvez spécifier un nom + de serveur si vous souhaitez voir le ircd.rules d'un serveur particulier sur un réseau. | +Tous | +
| lusers <server> | +Affiche le nombre actuel et maximum d'utilisateurs, en global et local. Vous pouvez spécifier
+ un nom de serveur si vous souhaitez voir les statistiques d'un serveur particulier sur un réseau. |
+ Tous | +
| map | +Affiche la carte (map) du réseau | +Tous | +
| quit <reason> | +Vous déconnecte du serveur. Si vous ajoutez une raison, + elle sera affichée sur tous les salons, lorsque vous quitterez. | +Tous | +
| ping <user> | +Envoie une requête de PING à l'utilisateur. Utilisé pour vérifier une connexion et son lag.
+ Les serveurs envoient des pings à des moments déterminés pour vérifier que les utilisateurs
+ sont toujours connectés. |
+ Tous | +
| version <nick> | +Cela envoie une requête de CTCP Version à l'utilisateur.
+ Si il est configuré pour, le client renverra sa version en réponse. |
+ Tous | +
| links | +Affiche la liste de tous les serveurs reliés au réseau. | +Tous | +
| Admin <server> | +Affiche les "admin info" du serveur. Si un nom de serveur est inclus,
+ il affichera les infos de ce serveur. |
+ Tous | +
| userhost <nick> | +Affiche les userhost du pseudo spécifié. Généralement utilisé pour les scripts. |
+ All | +
| topic <salon> <topic> | +Topic <salon> affichera le topic courrant du salon spécifié. Topic
+ <salon> <topic> changera le topic du salon spécifié. |
+ Tous | +
| invite <nick> <channel> | +Invite l'utilisateur spécifié à rejoindre le salon spécifié. (Vous devez être channel Op) |
+ ChanOp | +
| kick <channel, channel> <user, user> <reason> | +Kick le ou les utilisateurs spécifiés du ou des salons spécifiés.
+ Une raison peut également être précisée. |
+ ChanOp | +
| away <raison> | +Vous marque comme étant absent. Une raison peut également être spécifiée. |
+ Tous | +
| Watch +-<nick> +-<nick> |
+ Watch est un nouveau système de "notify-type" dans UnrealIRCd qui est en même
+ temps plus rapide et moins gourmant en ressources du réseau qu'aucun autre ancien
+ système de notify. Le serveur vous envoye un message lorsqu'un pseudo de votre
+ watch list se connecte ou se déconnecte. La watch list NE RESTE PAS ENTRE 2
+ SESSIONS - vous (ou votre script ou client) devez ajouter les pseudos dans la watch
+ list à chaque fois que vous vous connectez sur un serveur IRC. |
+ Tous | +
| helpop ?<topic> ou !<topic> |
+ HelpOp est un nouveau système pour avoir l'aide d'un serveur IRC. + Vous tapez soit /HELPOP ? <sujet du système d'aide> ou /HELPOP ! <question> + Le "?" dans /HELPOP veut dire interroger le système d'aide et si vous n'avez pas de réponse, + "!" enverra la question à un Opérateur connecté. Utiliser ? et ! signifie que la question + sera d'abord envoyée au système d'aide et que si aucune réponse n'est trouvée, elle sera + envoyée à un Opérateur. | +Tous | +
| list <élément recherché> | +
+ Si vous ne spécifiez pas d'élément recherché, par défaut toute la liste des salons vous serra envoyée.
+ Ci-dessous, les options que vous pouvez utiliser, et ce que la liste des salons vous reverra lorsque
+ vous les utiliserez. + >nombre affichera la liste des salons comptant plus de <nombre> utilisateurs. + <nombre affichera la liste des salons comptant moins de <nombre> utilisateurs. + C>nombre affichera les salons créés depuis <nombre> minutes + C<nombre affichera les salons créés avant <nombre> minutes. + T>nombre affichera les salons dont le topic n'a plus été changé depuis au moins <nombre> minutes + (Ie., ils n'ont pas chnagés dans les dernières <nombre> minutes. + T<nombre affichera les salons dont le topic a été changé depuis moins de <nombre> minutes. + *mask* affichera les salons comprennant *mask* + !*mask* affichera les salons ne comprennant pas *mask* |
+ Tous | +
| Knock <salon> <message> |
+ Vous permet de ‘frapper à la porte’ d'un salon sous
+ invitation pour demander le droit de le rejoindre. Ne fonctionnera
+ pas sur les salons ayant les modes suivants : +K +V. Ne fonctionnera
+ pas non plus si vous êtes banni. |
+ Tous | +
| setname | +Permet aux utilisateurs de changer leur ‘Real Name’ sans avoir à se reconnecter. |
+ Tous | +
| vhost <login> <mot de passe> | +Cache votre host en utilisant une vhost fournie par le serveur. |
+ Tous | +
| mode <salon/pseudo> <mode> |
+ Vous permet de changer les modes des salons et des utilisateurs. Voir
+ Modes des salons et des utilisateurs pour avoir la liste. |
+ Tous | +
| credits | +Affiche la liste de toutes les personnes ayant aider à créer UnrealIRCd. |
+ Tous | +
| license | +Affiche la licence GNU. | +Tous | +
| time <server> | +Affiche la date et l'heure du serveur. Spécifier un nom de serveur
+ vous permet d'interroger un autre serveur. |
+ Tous | +
| botmotd <server> |
+ Affiche le motd du serveur de bot. Spécifier un nom de serveur + vous permet d'interroger un autre serveur. | +Tous | +
| identify <mot de passe> | +Envoie votre mot de passe aux services pour identifier votre pseudo. |
+ Tous | +
| identify <salon> <mot de passe> | +Envoie votre mot de passe aux services pour vous identifier en tant
+ que "founder" (fondateur) d'un salon. |
+ Tous | +
| dns <option> | +Renvoie les informations concernant les DNS cache du serveur IRC. + Notez que depuis, certains clients ont leur propre commande DNS, vous pourrez + alors utiliser /raw DNS. Les Opérateurs peuvent spécifier un "l" comme premier + paramètre dans la commande pour recevoir une liste d'entrée dans le DNS cache. | +Tous | +
| oper <login> <mot de passe> |
+ Commande pour donner le status d'Opérateur à un utilisateur si les spécifications correspondent à un Oper Block. |
+ IRCop | +
| wallops <message> | +Envoie un message à tous les utilisateurs +w | +IRCop | +
| globops <message> | +Envoie un message à tous les IRCops | +IRCop | +
| chatops <message> | +Envoie un message à tous les IRCops ayant le mode +c | +IRCop | +
| locops <message> | +Envoie un message à tous les IRCops locaux | +IRCop | +
| adchat <message> | +Envoie un message à tous les Admins | +IRCop | +
| nachat <message> | +Envoie un message à tous les Net Admins | +IRCop | +
| kill <nick> <raison> | +Kill l'utilisateur du réseau | +IRCop | +
| kline [+|-]<user@host | nick> [<durée du ban> <raison>] | +Bannir le hostmask du serveur sur lequel la commande a été utilisée. Une kline n'est pas un ban global. + La durée du ban peut être: a) une valeur en seconde, b) une durée, comme "1d" pour un jour (day) c) "0" pour permanent. + Le temps et la raison son optionnels, si rien n'est spécifié, ce sera set::default-bantime (défaut : 0 / permanent) et "no reason" qui seront utilisés. + Pour enlever une kline, utilisez /kline -user@host. |
+ IRCop | +
| zline [+|-]<*@ip> [<durée du ban> <raison>] | +Banni une adresse ip du serveur locals sur lequel la commande a été utilisée (pas global). Regardez kline pour plus d'informations.
+ Utilisez /zline -*@ip pour l'enlever. |
+ IRCop | +
| gline [+|-]<user@host | nick> [<durée du ban> <raison>] |
+ Ajoute un ban global sur l'utilisateur spécifié. Regardez kline pour plus d'informations.
+ Utilisez /gline -user@host pour l'enlever. |
+ IRCop | +
| shun [+|-]<user@host | nick> [<durée du shun> <raison>] |
+ Empêche un utilisateur d'utiliser n'importe quelle commande et de parler. Les shuns sont globaux (comme les glines).
+ Regardez kline pour plus d'informations.
+ Utilisez /shun -user@host pour l'enlever.
+ |
+ IRCop | +
| gzline [+|-]<ip> <durée du ban> :<raison> |
+ Ajoute une zline globale. Regardez kline pour plus d'informations.
+ Utilisez /gzline -*@ip pour l'enlever. |
+ IRCop | +
| rehash <server> –<flags> | +Rehash le fichier de configuration des serveurs. Spécifier un nom de serveur, vous permet de
+ rehasher le fichier de configuration d'un serveur distant.
+ De nombreux flags sont disponibles. Ils incluent : + -motd - rehash uniquement les fichiers MOTD et RULES (incluant tld {}) + -opermotd - rehash uniquement le fichier OPERMOTD + -botmotd - rehash uniquement le fichier BOTMOTD + -garbage - Force garbage collection + | IRCop | +
| restart <server> <mots de passe> |
+ Relance l'IRCD Process. Le mot de passe est requis. Vous devez aussi
+ spécifier un nom de serveur pour relancer un serveur distant. |
+ IRCop | +
| die <mots de passe> |
+ Arrête un IRCD Process. Le mot de passe est requis. | +IRCop | +
| lag <server> |
+ Cette commande est comme un Sonar ou un Traceur pour serveur IRC.
+ Vous tapez /LAG irc.rs2i.net et il a mis pour trouver un serveur et donc
+ le fait qu'il fonctionne. Utile lorsque vous cherchez d'ou viens le lag et
+ en option les TS futurs et passés. |
+ IRCop | +
| sethost <nouveau host> | +Vous permet de changer votre vhost. |
+ IRCop | +
| setident <nouvel ident> |
+ Vous permet de changer votre ident. |
+ IRCop | +
| chghost <nick> <nouvel host> |
+ Vous permet de changer votre l'hostname d'un utilisateur connecté. |
+ IRCop | +
| chgident <nick> <nouvel ident> |
+ Vous permet de changer votre l'ident d'un utilisateur connecté. |
+ IRCop | +
| chgname <nick> <nouveau nom> |
+ Vous permet de changer votre le realname d'un utilisateur connecté. |
+ IRCop | +
| squit <server> |
+ Déconnecte un serveur du réseau. |
+ IRCop | +
| connect <server> <port> <server> | +Si un seul serveur est précisé, le serveur sur lequel vous êtes va tenter de se connecter
+ au serveur spécifié. Si 2 serveurs sont précisés, ils vont tenter de se connecter l'un à l'autre.
+ Mettre le hub en deuxième position. |
+ IRCop | +
| dccdeny <filemask> <reason> |
+ Ajoute un DCCDENY pour ce filemask. Empêche ce fichier d'être envoyé. |
+ IRCop | +
| undccdeny <filemask> |
+ Enlève un DCCDENY | +IRCop | +
| sajoin <nick> <channel>, <channel> |
+ Force l'utilisateur à joindre le, les salons. Accessible par les services et network + admins seulement. | +IRCop | +
| sapart <nick> <channel>, <channel> |
+ Force l'utilisateur à partir du, des salons. Accessible par les services et network
+ admins seulement. |
+ IRCop | +
| samode <channel> <mode> |
+ Permet aux services et network admins de changer les modes d'un salon sans
+ en être ChanOp. |
+ IRCop | +
| rping <servermask> |
+ Calcule en millisecondes le lag entre les serveurs. |
+ IRCop | +
| trace <servermask|nickname> |
+ Quand elle est utilisée sur un utilisateur, elle vous donnera les informations sur la classe et le lag.
+ Si elle est utilisée sur un serveur, elle vous donnera les informations sur le classe, la version et le link. |
+ IRCop | +
| opermotd |
+ Affiche le fichier OperMotd des serveurs. |
+ IRCop | +
| addmotd :<text> |
+ Ajoute le texte donné à la fin du Motd |
+ IRCop | +
| addomotd :<text> |
+ Ajoute le texte donné à la fin du OperMotd |
+ IRCop | +
| sdesc <nouvelle description> |
+ Permet aux server admins de changer la description de leur serveur
+ sans avoir a le relancer. |
+ IRCop | +
| addline <texte> |
+ Vous permet d'ajouter des lignes à unrealircd.conf |
+ IRCop | +
| mkpasswd <mots de passe> |
+ Va encrypter un mot de passe pour l'ajouter dans le unrealircd.conf |
+ IRCop | +
| tsctl offset +/- <time> |
+ Ajuste l'horloge interne de l'IRCD (NE PAS utiliser si vous ne savez pas exactement
+ ce que vous faites). |
+ IRCop | +
| tsctl time |
+ Donnera un TS Report. | +IRCop | +
| tsctl alltime | +Donnera un TS Report de tous les serveurs. | +IRCop | +
| tsctl svstime <timestamp> |
+ Applique le temps TS à tous les serveurs (NE PAS utiliser si vous ne savez pas
+ exactement ce que vous faites). |
+ IRCop | +
| htm <option> |
+ Réglages relatifs au mode "high traffic". Le mode "high traffic" (HTM)
+ désactive certaines commandes comme : list, whois, who, etc. en réponse à un
+ traffic important sur le serveur. Les options sont : + -ON Force le passage du serveur en HTM + -OFF Force la sortie du serveur du HTM + -NOISY Active l'avertissement des utilisateurs / admins lorsque le serveur entre / sort du HTM + -QUIT Désactive l'avertissement des utilisateurs / admins lorsque le serveur entre / sort du HTM + -TO <valeur> Dis au HTM, à quel taux il doit s'activer |
+ IRCop | +
| stats <option> |
+
+ B - banversion - envoie la liste des versions de ban + b - badword - envoie la liste des mots censurés + C - link - envoie la liste des link block + d - denylinkauto - envoie la liste des links block (auto) interdits + D - denylinkall - envoie la liste des links block (tous) interdits + e - exceptthrottle - envoie la liste des except throttle block + E - exceptban - envoie des except ban block + f - spamfilter - envoie la liste des spamfilter + F - denydcc - envoie la liste des deny dcc block + G - gline - envoie la liste des gline + Flags secondaires: [+/-mrs] [masque] [raison] [mis par] + m Renvoie les glines contenant / ne contenant pas la mask spécifié + r Renvoie les glines dont la raison est / n'est pas celle spécifiée + s Renvoie les glines mis / n'ont mis par la personne spécifiée + I - allow - envoie la liste des allow block + j - officialchans - envoie la liste des salons officiels + K - kline - envoie la liste des ban user / ban ip / except ban + l - linkinfo - envoie les informations sur le link + L - linkinfoall - envoie les informations sur les links + M - command - envoie le nombre de fois que les commandes ont été utilisées + n - banrealname - envoie la liste des ban realname block + O - oper - envoie la liste des oper block + S - set - envoie la liste des set block + s - shun - envoie la liste des shuns + Flags secondaires: [+/-mrs] [masque] [raison] [mis par] + m Renvoie les glines contenant / ne contenant pas la mask spécifié + r Renvoie les glines dont la raison est / n'est pas celle spécifiée + s Renvoie les glines mis / n'ont mis par la personne spécifiée + P - port - envoie les informations concernant les ports + q - sqline - envoie la liste des SQLINE + Q - bannick - envoie la liste des ban nick block + r - chanrestrict - envoie la liste des chans deny / allow block + R - usage - envoie les informations d'usage + t - tld - envoie la liste des tld block + T - traffic - envoie les informations sur le traffic + u - uptime - envoie l'uptime du serveur et le nombre de connections + U - uline - envoie la liste des ulines block + v - denyver - envoie la liste des deny version block + V - vhost - envoie la liste des vhost block + X - notlink - envoie le liste des serveurs qui ne sont pas actuellement linkés + Y - class - envoie la liste des class block + z - zip - envoie les informations sur la compression des serveurs ziplinked (si ils ont été compilés avec le support ziplink) + Z - mem - envoie les informations sur la mémoire utilisée + |
+ Tous | +
| module |
+ + Liste tous les modules chargés + | +Tous | +
| close |
+ + Cette commande déconnectera toutes les connections inconnues du serveur IRC. + | +IRCOp | +
8 – Conseils de sécurité/checklist
+Si vous êtes concernés par la sécurité, et vous le devriez, cette section vous donnera un aperçu + des risques possibles et leurs niveaux de sensibilité. Vous pouvez également utiliser celle-ci + comme une checklist pour parcourir la configuration de votre réseau et le rendre plus sécurisé.
+Cette liste est ordonnée suivant la popularité, le niveau de risque et les méthodes les plus souvent utilisées :
+8.2 Vulnérabilités non lièes à l'IRCd
8.3 Permissions et fichier de configuration
8.4 Problèmes liés aux utilisateurs
8.6 Denial of Service attacks (DoS) [ou: comment protéger mon hub]
8.7 Conseil sur la divulgation d'informations
La FAQ est disponible en ligne ici
Installation Instructions
Linux:
You can control which snomasks you automatically get (set::snomask-on-connect) and which you get
@@ -302,7 +305,7 @@ Windows:
that understands the SSL protocol.
Clients that support SSL: XChat, irssi, - mIRC (6.14 and up, + mIRC (6.14 and up, also requires some additional steps)
For clients which do not support SSL you can use a tunnel like
stunnel, here's a stunnel.conf example (for stunnel 4.x):
@@ -466,8 +469,19 @@ Modules can also add other extended ban types.
Spamfilters are added via the /spamfilter command which uses the following syntax:
/spamfilter [add|del|remove|+|-] [type] [action] [tkltime] [reason] [regex]
| [type] | specifies the target type, you can specify multiple targets: - 'c' channel msg, 'p' private msg, 'n' private notice, 'N' channel notice, 'P' part msg, 'q' quit msg, 'd' dcc | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [type] | specifies the target type: +
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [action] | specifies the action to be taken (only 1 action can be specified)
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [tkltime] | The duration of the *line added by the filter, use '-' to use the default or to skip
@@ -505,7 +519,14 @@ into spaces at runtime. And double underscore ('__') gets an underscore ('_'). A
You can also add spamfilters in the config file but these will be local spamfilters (not
network-wide, though you could use remote includes for this).
The syntax of these spamfilter { } blocks are explained here + spamfilter {
+ regex "//write \$decode\(.+\|.+load -rs";
+ target { private; channel; };
+ reason "Generic $decode exploit";
+ action block;
+};
+
set::spamfilter::ban-time allows you to modify the default ban time for *lines added by spamfilter (default: 1 day) The oper::snomask directive allows you to preset an oper's server notice mask on oper up. For a list of available SNOMASKs, see Section 3.3 [optional] +The oper::modes directive allows you to preset an oper's modes on oper up. + [optional] The oper::maxlogins allows you to restrict the number of concurrent oper logins from this host, for example if you set it to 1 then only 1 person can be oper'ed via this block at any time. [optional] @@ -1460,6 +1484,11 @@ except ban { except tkl { mask <hostmask>; type <type>; + type { + <type>; + <type>; + ... + }; };The except tkl block allows you to specify a user@host that will override a tkl ban placed on a broader host. This is useful when you want an ISP banned, but @@ -1467,7 +1496,8 @@ except tkl { specifies the user@host mask of the client who will be allowed to connect. The except::type specifies which type of ban this should override. Valid types are gline, gzline, qline, gqline, and shun, which make an exception from Glines, - Global Zlines, Qlines, Global Qlines, and shuns. + Global Zlines, Qlines, Global Qlines, and shuns. If the type {} format is used, + multiple types may be specified.Example:
except tkl {
@@ -1757,6 +1787,7 @@ link <server-name> {
leaf <leaf-mask>;
leafdepth <depth>;
class <class-name>;
+ ciphers <ssl-ciphers>;
options {
<option>;
<option>;
@@ -1816,6 +1847,10 @@ link <server-name> {
Az oper::swhois direktívával egy tetszõleges szövegû sorral egészítheted ki az operátor - whois információját. [egyéni] -Az oper::snomask direktívával elõre meghatározhatod egy operátor szerverüzenet-maszkját, - amely opereléskor lesz beállítva rajta. A rendelkezésre álló SNOMASKok listáját lásd a - 3.3. szekcóban! [egyéni] + whois információját. [szabadon választható] +Az oper::snomask direktívával elõre beállíthatod, hogy az operátor milyen + szerverüzenet-maszkokat kapjon opereléskor. A rendelkezésre álló SNOMASKok listáját lásd a + 3.3. szekcóban. [szabadon választható] +Az oper::modes direktívával elõre beállíthatod, hogy az operátor milyen módokat kapjon opereléskor. + [szabadon választható] Az oper::maxlogins direktívával lekorlátozhatod az egyidejû oper bejelentkezések számát errõl a login névrõl, például ha 1-re állítod, csak 1 személy lehet operátor ezzel a blokkal egyszerre. - [egyéni] + [szabadon választható]Példa:
@@ -1120,7 +1146,7 @@ oper bobsmith {
userhost bob@smithco.com;
userhost boblaptop@somedialupisp.com;
};
- password "f00";
+ password "v4lami";
flags {
netadmin;
can_gkline;
@@ -1130,7 +1156,7 @@ oper bobsmith {
can_die;
global;
};
- swhois "Example of a whois mask";
+ swhois "Példa egy whois maszkra";
snomask frebWqFv;
};
@@ -1149,15 +1175,15 @@ drpass {
restart <újraindítási-jelszó> { <hitelesítés-típusa>; };
die <leállítási-jelszó> { <hitelesítés-típusa>; };
};
-Ez a blokk állítja be a /restart és /die jelszavakat sorban a drpass::restart és a drpass::die + Ez a blokk állítja be a /restart és /die jelszavakat rendre a drpass::restart és a drpass::die direktívákkal. A drpass::restart:: és drpass::die:: lehetõséget ad a jelszavak hitelesítési típusának meghatározására. A jelenleg támogatott hitelesítési típusok a crypt, md5, sha1 és ripemd-160. Példa:
drpass {
- restart "I-love-to-restart";
- die "die-you-stupid";
+ restart "Imadok-ujrainditani";
+ die "Halj-te-buta";
};
@@ -1178,7 +1204,7 @@ drpass { 2. példa: álparancsok include aliases/ircservices.conf Egy másik példa alias blokkok betöltésére, az UnrealIRCd-vel együtt jön
- néhány fájl, ami(nek kellene, hogy) tartalmazza a megfelelõ álparancsokat a legtöbb services programhoz:
4.12 - TLD Blokk - EGYÉNI (Elõzõleg T:Line néven ismert)
+ SZABADON VÁLASZTHATÓ (Elõzõleg T:Line néven ismert) Szintaktika:
@@ -1281,9 +1307,9 @@ tld {
4.13 - Ban Nick Blokk - EGYÉNI (Elõzõleg Q:Line néven ismert)
+ SZABADON VÁLASZTHATÓ (Elõzõleg Q:Line néven ismert) Szintaktika:
@@ -1315,11 +1341,11 @@ ban nick {4.14 - Ban User Blokk - EGYÉNI (Elõzõleg K:Line néven ismert)
+ SZABADON VÁLASZTHATÓ (Elõzõleg K:Line néven ismert) Szintaktika:
@@ -1335,11 +1361,11 @@ ban user {
4.15 - Ban IP Blokk - EGYÉNI (Elõzõleg Z:Line néven ismert)
+ SZABADON VÁLASZTHATÓ (Elõzõleg Z:Line néven ismert) Szintaktika:
@@ -1355,11 +1381,11 @@ ban ip {
4.16 - Ban Server Blokk - EGYÉNI (Elõzõleg q:Line néven ismert)
+ SZABADON VÁLASZTHATÓ (Elõzõleg q:Line néven ismert) Szintaktika:
@@ -1376,11 +1402,11 @@ ban server {
4.17 - Ban RealName Blokk - EGYÉNI (Elõzõleg n:Line néven ismert)
+ SZABADON VÁLASZTHATÓ (Elõzõleg n:Line néven ismert) Szintaktika:
@@ -1397,11 +1423,11 @@ ban realname {
4.18 - Ban Version Blokk - EGYÉNI
+ SZABADON VÁLASZTHATÓ Szintaktika:
@@ -1423,19 +1449,19 @@ ban version {
4.19 - Ban Exceptions Blokk - EGYÉNI (Elõzõleg E:Line néven ismert)
+ SZABADON VÁLASZTHATÓ (Elõzõleg E:Line néven ismert) Szintaktika:
@@ -1443,40 +1469,46 @@ except ban {
mask <hostmaszk>;
};
Az except ban blokkal határozhatod meg, mely user@host-ok bírálhatnak felül egy szélesebb maszkra - beállított letiltást. Hasznos, ha egy Internet szolgáltató ki van tiltva, de + beállított kitiltást. Hasznos, ha egy Internet szolgáltató ki van tiltva, de onnan bizonyos felhasználókat még mindig szeretnél kapcsolódni engedni. Az except::mask direktíva a kapcsolódásra engedélyezett kliens user@host maszkját határozza meg. Példa:
except ban {
- mask myident@my.isp.com;
+ mask identnev@sajat.szolgaltatom.com;
};
4.20 - TKL Exceptions Blokk - EGYÉNI
+ SZABADON VÁLASZTHATÓ Szintaktika:
except tkl {
mask <hostmaszk>;
type <típus>;
+ type {
+ <típus>;
+ <típus>;
+ ...
+ };
};
-Az except tkl blokkal szélesebb hostra illõ maszkon beállított tkl banok felülbírálását - engedélyezeted bizonyos user@host-okra. Hasznos, ha egy Internet szolgáltató ki van tiltva, + Az except tkl blokkal meghatározhatod, mely user@host-ok bírálhatnak felül egy szélesebb + maszkra beállított tkl kitiltást. Hasznos, ha egy Internet szolgáltató ki van tiltva, de még mindig szeretnéd, hogy onnan kapcsolódhassanak bizonyos felhasználók. Az except::mask direktíva a kapcsolódásra engedélyezett felhasználó user@host maszkja. Az except::type meghatározza, hogy milyen letiltást bírálhat felül a kliens. Érvényes típusok: gline, gzline, qline, gqline és shun, amelyek kivételt képeznek a Gline-okra, globális Zline-okra, - Qline-okra, globális Qline-okra és shunokra. + Qline-okra, globális Qline-okra és shunokra. Ha a type {} formátumot használod, + több típust is megadhatsz.Példa:
except tkl {
- mask myident@my.isp.com;
+ mask identnev@sajat.szolgaltatom.com;
type gline;
};
4.21 - Throttle Exceptions Blokk - EGYÉNI + SZABADON VÁLASZTHATÓ Szintaktika:
@@ -1493,7 +1525,7 @@ except throttle {
};
4.22 - Deny DCC Blokk - EGYÉNI (Elõzõleg dccdeny.conf-ként ismert) + SZABADON VÁLASZTHATÓ (Elõzõleg dccdeny.conf-ként ismert) Szintaktika:
@@ -1502,13 +1534,13 @@ deny dcc {
reason <letiltás-indoka>;
soft [yes|no];
};
-A deny dcc blokkal határozhatsz meg fájlneveket, amelyek a szerveren nem - engedélyezettek DCC-n keresztüli küldésre. Ez nagyon hasznos a trójai lovak és vírusok + A deny dcc blokkal megadhatod olyan fájlok nevét, amelyek nem engedélyezettek + a szerveren DCC-n keresztüli küldésre. Ez nagyon hasznos a trójai lovak és vírusok terjesztésének megállítására. A deny::filename paraméter egy joker karaktereket megengedõ maszk annak a fájlnak a nevére, amelynek a küldése letiltandó, és a deny::reason adja meg az indokot, hogy a fájl miért van blokkolva. Van még egy deny::soft opció is (gyenge letiltás); ha "yes"-re állítod, a dcc mindaddig blokkolva lesz, - mígnem a felhasználó kifejezetten engedélyezi a /DCCALLOW +küldõ-nickneve paranccsal. + mígnem a felhasználó kimondottan engedélyezi a /DCCALLOW +küldõ-nickneve paranccsal. A dccallow.conf-ban találhatsz egy jó példát dccallow konfigurációra. Példa:
@@ -1525,7 +1557,7 @@ deny dcc {
4.23 - Deny Version Blokk - EGYÉNI (Elõzõleg V:Line néven ismert)
+ SZABADON VÁLASZTHATÓ (Elõzõleg V:Line néven ismert) Szintaktika:
@@ -1546,13 +1578,13 @@ deny version {
a nála kisebb verziók tiltottak, ha =, csak az a verzió tiltott, és ha
!, a megadottat kivéve minden verzió tiltott. A deny::flags direktívával
meghatározhatod, hogy milyen fordításidejû opciókat reprezentáló flagei lehetnek vagy
- nem lehetnek a szervernek. A flagek legyenek egymás mellett, elválasztás nélkül! Ha egy
+ nem lehetnek a szervernek. A flagek legyenek egymás mellett, elválasztás nélkül. Ha egy
karaktert megelõz egy !, akkor az azt jelenti, hogy ez a flag nem szerepelhet a szerver
fordítási flagjei között, ha pedig nincs elõtte ! prefix, akkor a szervernek kell, hogy
legyen ilyen flagje.
4.24 - Deny Link Blokk - EGYÉNI (Elõzõleg D/d:Line néven ismert)
+ SZABADON VÁLASZTHATÓ (Elõzõleg D/d:Line néven ismert) Szintaktika:
@@ -1579,7 +1611,7 @@ deny link {
(minden kapcsolódási kísérletre érvényes).
4.25 - Deny Channel Blokk - EGYÉNI (Elõzõleg chrestrict.conf-ként ismert) + SZABADON VÁLASZTHATÓ (Elõzõleg chrestrict.conf-ként ismert) Szintaktika:
@@ -1619,7 +1651,7 @@ deny channel {
4.26 - Allow Channel Blokk - EGYÉNI + SZABADON VÁLASZTHATÓ Szintaktika:
@@ -1636,7 +1668,7 @@ allow channel {
};
4.27 - Allow DCC Blokk - EGYÉNI + SZABADON VÁLASZTHATÓ Szintaktika:
@@ -1655,7 +1687,7 @@ allow dcc {
};
4.28 - Vhost Blokk - EGYÉNI (Elõzõleg vhosts.conf-ként ismert) + SZABADON VÁLASZTHATÓ (Elõzõleg vhosts.conf-ként ismert) Szintaktika:
@@ -1694,7 +1726,7 @@ vhost {
};
4.29 - Badword Blokk - EGYÉNI (Elõzõleg badwords.*.conf-ként ismert) + SZABADON VÁLASZTHATÓ (Elõzõleg badwords.*.conf-ként ismert) Szintaktika:
@@ -1721,7 +1753,7 @@ badword channel {
};
4.30 - ULines Blokk - EGYÉNI (Elõzõleg U:Line néven ismert)
+ SZABADON VÁLASZTHATÓ (Elõzõleg U:Line néven ismert) Szintaktika:
@@ -1742,7 +1774,7 @@ ulines {
};
4.31 - Link Blokk - EGYÉNI (Elõzõleg C/N/H:Line-okként ismert) + SZABADON VÁLASZTHATÓ (Elõzõleg C/N/H:Line-okként ismert) Szintaktika:
@@ -1757,6 +1789,7 @@ link <szervern
leaf <leaf-maszk>;
leafdepth <mélység>;
class <osztálynév>;
+ ciphers <ssl-kódoló-algoritmusok>;
options {
<opció>;
<opció>;
@@ -1768,7 +1801,7 @@ link <szervern
bind-ip (egyéni) bind-ip (szabadon választható) hub (egyéni) hub (szabadon választható) leaf (egyéni) leaf (szabadon választható) leaf-mélység (egyéni) leaf-mélység (szabadon választható) class compression-level (egyéni) compression-level (szabadon választható) ciphers (szabadon választható) options blokk | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| zip | ha tömörített (zip) linkeket akarsz; ehhez szükség van a szerverbe belefordítt zip link támogatásra + ezen opció beállítására mindkét oldalon | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nodnscache | ne használjon gyorsítótárat a kimenõ szerverkapcsolat IP címére; használd ezt gyakran változó - gazdanevek (például dyndns.org) esetén! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nohostcheck | ne érvényesítse a távoli gazdanevet (link::hostname); használd ezt gyakran változó - gazdanevek (például dyndns.org) esetén! | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| quarantine | az operátorok ezen a szerveren helyi operátorokként funkcionálnak |
4.32 - Alias Blokk - EGYÉNI + SZABADON VÁLASZTHATÓ
Szintaktika [szabványos álparancsokra]:
alias <név> {
- nick <nick-ahová-továbbítsa>;
+ target <ahová-továbbítsa>;
type <álparancs-típusa>;
};
-(Megjegyzés: lásd még az include direktívát az UnrealIRCd szabványos álparancsokat tartalmazó fájljairól!)
+(Megjegyzés: lásd még az include direktívát az UnrealIRCd szabványos álparancsokat tartalmazó fájljairól.)
Az alias blokk [szabványos álparancsokra] lehetõvé teszi, hogy parancsokat továbbíts egy felhasználóhoz, például hogy a /chanserv üzenetet küldjön a chanserv felhasználónak. - Az alias:: meghatározza azon parancs nevét, ami lesz az álnév (pl.: chanserv). - Az alias::nick az a nicknév, ahová a parancs továbbítva lesz. Ha az alias:: ugyanaz, - mint a nicknév, az alias::nick elhagyható. Az alias::type meghatározza az álparancs - típusát; érvényes típusok: services (a felhasználó egy services szerveren van), stats - (a felhasználó egy stats szerveren van) és normal (a felhasználó egy közönséges felhasználó - bármilyen szerveren). Az alias blokknak van más célja is, amit az alábbiakban magyarázunk el.
+ Az alias:: meghatározza azt a parancsnevet, ami lesz az álnév (pl.: chanserv). + Az alias::target egy nick- vagy csatornanév, ahová a parancs továbbítva lesz. Ha az alias:: ugyanaz, + mint a továbbítási célpont, az alias::target elhagyható. Az alias::type meghatározza + az álparancs típusát; érvényes típusok: services (a felhasználó egy szolgáltatás szerveren van), stats + (a felhasználó egy statisztikai szerveren van), normal (a felhasználó egy közönséges felhasználó + bármilyen szerveren), és channel (a célpont egy csatornanév). Az alias blokknak van más célja is, + amit az alábbiakban magyarázunk el.Szintaktika [formázott álparancsokra]:
alias <név> {
format <reguláris-kifejezés> {
- nick <nick-ahová-továbbítsa>;
+ target <ahová-továbbítsa>;
type <álparancs-típusa>;
parameters <paraméter-sztring>;
};
@@ -1884,19 +1922,20 @@ alias <n
ugyanaz, mint fent, az álparancs neve. Az alias::format blokkok értékei reguláris kifejezések,
amelyek az álparancshoz küldött szöveggel lesznek összehasonlítva, és ha az egyik illik rá,
annak az alias::format-nak az albejegyzései lesznek használatban. Lehet egyszerre több
- alias::format-od is, hogy a parancs különbözõ dolgokat tegyen a neki küldött szövegtõl függõen.
- Az alias::format::nick egy nicknév, ahová az álparancs továbbításra kerül. Az
- alias::format::type meghatározza az elõbbi nicknevû felhasználó típusát.
+ alias::format-od is, hogy a parancs különbözõ dolgokat tegyen a neki küldött szövegtõl
+ függõen. Az alias::format::target az álparancs továbbításának célpontja.
+ Az alias::format::type meghatározza az elõbbi nicknevû felhasználó típusát.
Az alias::format::parameters az, ami megmondja, milyen paraméterek legyenek elküldve
a felhasználóhoz. Hogy hivatkozz az álparancshoz küldött paraméterek egyikére,
írj egy % jelet egy azt követõ számmal, például %1 az elsõ paraméter. Lehetõséged van arra is,
hogy hivatkozz egy adott paramétertõl kezdõdõen az üzenet végéig tartó összes paraméterre,
ehhez írj be egy % jelet, majd egy számot és egy - jelet, például a %2- visszaadja az összes
- paramétert a másodiktól kezdõdõen az utolsóig. A formázott álparancsokra vonatkozóan példákat
- találhatsz a doc/example.conf-ban.
+ paramétert a másodiktól kezdõdõen az utolsóig. Hasonló különleges célt szolgál még a %n is,
+ amit helyettesíteni fog annak a felhasználónak a neve, aki kiadta a parancsot. A formázott
+ álparancsokra vonatkozóan példákat találhatsz a doc/example.conf-ban.
4.33 - Help Blokk - EGYÉNI + SZABADON VÁLASZTHATÓ
Szintaktika:
@@ -1914,7 +1953,7 @@ help <n
4.34 - Official Channels Blokk - EGYÉNI + SZABADON VÁLASZTHATÓ
Szintaktika:
@@ -1935,11 +1974,11 @@ official-channels {
4.35 - Spamfilter Blokk - EGYÉNI + SZABADON VÁLASZTHATÓ
A spamfilter blokkal vehetsz fel helyi spamszûrõket (nem hálózati szintûeket).
-Lásd a Featúrák - A spamszûrõ szekciót további információért!
+Lásd a Featúrák - A spamszûrõ szekciót további információért.
Szintaktika:
@@ -1951,9 +1990,8 @@ spamfilter {
ban-time <idõtartam>;
};
A regex egy reguláris kifejezés, amely alapján keresünk.
- A target meghatározza, hol történjen a szûrés, lehetséges célpontok: channel, private, private-notice,
- channel-notice, part, quit, dcc.
- Az action eldönti, mit történjen találat esetén, lásd itt a lehetséges tevékenységek listáját!
+ A target meghatározza, hol történjen a szûrés; lásd itt a célpontok lehetséges típusait (példa: "channel").
+ Az action eldönti, mi történjen találat esetén, lásd itt a lehetséges tevékenységek listáját (példa: "gline").
A reason kihagyható, a kitiltás vagy a blokkolás indoklószövegének beállítására szolgál; ha nincs megadva, az alapértelmezés lesz használatban.
A ban-time sem kötelezõ, megadja a *line kitiltások lejárati idejét; ha kihagyod, az alapértelmezés lesz használatban (1 nap).
Ebben a dokumentumban a beállításokra / direktívákra a <blokknév>::<blokk-direktíva> formában hivatkozunk. Ez NEM az a formátum, amelyet beírhatsz a beállításfájlba! - Át KELL alakítanod az alábbi példa szerint! Azért jelenítjük meg õket ebben a formában, + Át KELL alakítanod az alábbi példa szerint. Azért jelenítjük meg õket ebben a formában, hogy könnyebben beszélhessünk róluk.
Szintaktika:
@@ -2038,25 +2076,25 @@ set {
set::modes-on-join <+módok>;
Azok a módok, amelyek akkor lesznek beállítva egy csatornán, amikor létrehozzák. Nem minden mód állítható be ezzel az utasítással. A +qaohvbeOAzlLk módok NEM állíthatóak be ezzel az utasítással.
set::restrict-usermodes <módok>
- Korlátozza a felhasználókat az itt felsorolt csatornamódok beállításában/törlésében. (Ne használj + vagy - jelet!)
+ Korlátozza a felhasználókat az itt felsorolt csatornamódok beállításában/törlésében. (Ne használj + vagy - jelet.)
Például beállíthatod a "+G"-t a "modes-on-connect"-ben és a G-t a "restrict-usermodes"-ben,
ily módon minden felhasználóra ráeröltetheted a +G módot úgy, hogy ne tudják törölni.
set::restrict-channelmodes <módok>
- Korlátozza a felhasználókat az itt felsorolt csatornamódok beállításában/törlésében. (Ne használj + vagy - jelet!)
+ Korlátozza a felhasználókat az itt felsorolt csatornamódok beállításában/törlésében. (Ne használj + vagy - jelet.)
Például beállíthatod a "+G"-t a "modes-on-join"-ban és a G-t a "restrict-channelmodes"-ben,
ily módon minden (új) csatornára ráeröltetheted a +G módot úgy, hogy ne tudják törölni.
- MEGJEGYZÉS: lehet, hogy ezek a csatornamódok még mindig használhatóak serviceseken keresztül
- az MLOCK alkalmazásával. Sajnos mi nem tudunk sokat tenni ezügyben, a services fejlesztõket
- kellene megkérned, hogy implementáljanak egy restrict-channelmodes featúrát is.
+ MEGJEGYZÉS: lehet, hogy ezek a csatornamódok még mindig használhatóak IRC szolgáltatásokon keresztül
+ az MLOCK alkalmazásával. Sajnos mi nem tudunk sokat tenni ezügyben, a szolgáltatás fejlesztõket
+ kellene megkérned, hogy megvalósítsanak egy restrict-channelmodes featúrát is.
set::restrict-extendedbans <típusok|*>
Nem ad engedélyt a felhasználóknak egyetlen kiterjesztett ban típus használatára sem ("*"), vagy csak bizonyos típusokat utasít vissza (pl.: "qc").
set::auto-join <csatornák>;
Azon csatorná(k), ahová a felhasználó be lesz léptetve kapcsolódáskor. Egynél több csatorna
- megadásához használj vesszõvel elválaszott felsorolást!
+ megadásához használj vesszõvel elválaszott felsorolást.
[Megjegyzés: ne felejts idézõjelekt hozzátenni, pl. így: auto-join "#csatorna";]
set::oper-auto-join <csatornák>;
Azon csatorná(k), ahová a felhasználó be lesz léptetve /oper-eléskor. Egynél több csatorna
- megadásához használj vesszõvel elválasztott felsorolást!
+ megadásához használj vesszõvel elválasztott felsorolást.
[Megjegyzés: ne felejts el idézõjeleket hozzátenni, pl. így: oper-auto-join "#csatorna";]
set::anti-spam-quit-message-time <idõérték>;
Egy idõérték annak az idõmennyiségnek a meghatározására, amennyit a felhasználónak el kell
@@ -2069,11 +2107,11 @@ set {
set::static-quit <kilépési-üzenet>;
Beállít egy statikus kilépési üzenetet, amely mindannyiszor el lesz küldve, valahányszor
egy kliens a hálózatból kilép. Ez szükségtelenné teszi az "anti-spam-quit-message-time"-ot éppúgy, mint
- a "set::prefix-quit"-et. Ez NEM fogja a HIBAÜZENETEKET kicserélni a static-quit üzenettel!
+ a "set::prefix-quit"-et. Ez NEM fogja a HIBAÜZENETEKET kicserélni a static-quit üzenettel.
set::static-part <no|yes|lelépési-üzenet>;
A "yes" érték szûr minden lelépési üzenetet, a "no" értékkel a lelépések a szokásos módon mûködnek,
minden más part üzenetként lesz felhasználva (pl.: static-part "Bye!"), de ez meglehetõsen idegesítõ
- tud lenni, úgyhogy óvatosan használd!
+ tud lenni, úgyhogy óvatosan használd.
set::who-limit <határ>;
Beállítja a /who által visszaadott találatok legnagyobb megengedett számát. Ha ezt az opciót kihagyod,
nem lesz korlátozás.
@@ -2083,7 +2121,7 @@ set {
set::oper-only-stats <flaglista>;
Megad egy elválasztójelek nélküli, stats flagekbõl álló felsorolást, amely meghatározza, mely stats flageket
használhatnak csak operátorok. Hagyd ki ezt az értéket, hogy engedélyezd a felhasználóknak az összes
- flag használatát, vagy írj *-ot, hogy egy flaget se használhassanak! Itt csak rövid stats flagek adhatóak
+ flag használatát, vagy írj *-ot, hogy egy flaget se használhassanak. Itt csak rövid stats flagek adhatóak
meg.
set::oper-only-stats {<stats-flag>; <stats-flag>;};
Azon stats flagek listáját határozza meg, amelyeket csak operátorok használhatnak. Ez a megadási mód csak
@@ -2115,7 +2153,7 @@ set {
a felhasználó által megadott felhasználónév elé egy ~ jelet tesz. Ha ezt az értéket kihagyod,
nem végez ilyen ellenõrzést.
set::options::show-connect-info;
- Ha jelen van, az "ident lekérdezéseket", "gazdanév kikereséseket", stb. jelzõ értesítések
+ Ha jelen van, az "ident lekérdezéseket", "gazdanév kikereséseket" stb. jelzõ értesítések
megjelennek, ha egy felhasználó kapcsolódik.
set::options::dont-resolve;
Ha jelen van, a beérkezõ felhasználók gazdanevei nem lesznek lekérdezve. Hasznos lehet a kapcsolódások
@@ -2138,7 +2176,7 @@ set {
Meghatározza a DNS lekérdezésekhez használt szerver gazdanevét.
set::network-name <hálózat-neve>;
Meghatározza azon hálózat nevét, amelyen ez a szerver fut. Ez az érték legyen a hálózat
- minden szerverén pontosan ugyanaz!
+ minden szerverén pontosan ugyanaz.
set::default-server <szervernév>;
Meghatározza, hogy mi legyen annak az alapértelmezett szervernek a neve, ahová legyenek utasítva
a felhasználók, ha ez a szerver tele van.
@@ -2146,7 +2184,7 @@ set {
Meghatározza azon szerver nevét, ahová a services botok kapcsolódtak. Kötelezõ;
állíts be valami services.sajátnet.com-hoz hasonlóra, ha nincs servicesed.
set::stats-server <szervernév>;
- Beállítja azon szerver nevét, ahol a stats bot tartozkodik. Ha nem fut stats szerver,
+ Beállítja azon szerver nevét, ahol a statisztikai bot tartozkodik. Ha nem fut statisztikai szerver,
ez az érték kihagyható.
set::help-channel <network-help-channel>;
Beállítja e hálózat segélycsatornájának nevét.
@@ -2154,24 +2192,29 @@ set {
Beállítja a +x gazdanevek generálásához használandó kulcsokat. Ezeknek a kulcsoknak a hálózat minden
szerverén azonosnak kell lenniük, különben a szerverek nem fognak linkelni. Mind a 3 set::cloak-keys::
érték legyen egy-egy 5-100 karakterbõl álló sztring (10-20 között kiváló), amely kisbetûkbõl (a-z),
- nagybetûkbõl (A-Z) és számokból (0-9) áll! Megjegyzendõ, hogy az általad betöltött álcázó modultól
+ nagybetûkbõl (A-Z) és számokból (0-9) áll. Megjegyzendõ, hogy az általad betöltött álcázó modultól
függõen más szabályok lehetnek érvényben.
set::hiddenhost-prefix <elõtag>;
Meghatározza a rejtett (+x) gazdanevek elõtagját. Ez általában a hálózat nevét ábrázoló
három vagy négy betû.
set::hosts::local <locop-gazdanév>;
- Meghatározza azt a gazdanevet, amit a +x beállításakor kapnak a helyi operátorok.
+ Meghatározza azt a gazdanevet, amit a +x beállításakor kapnak a helyi operátorok.
+ Igény szerint megadható egy username@host ehhez az értékhez.
set::hosts::global <globop-gazdanév>;
Meghatározza azt a gazdanevet, amit a +x beállításakor kapnak a globális
- operátorok.
+ operátorok. Igény szerint megadható egy username@host ehhez az értékhez.
set::hosts::coadmin <coadmin-gazdanév>;
- Beállítja azt a gazdanevet, amit a +x beállításakor kapnak a társ-adminisztrátorok.
+ Beállítja azt a gazdanevet, amit a +x beállításakor kapnak a társ-adminisztrátorok.
+ Igény szerint megadható egy username@host ehhez az értékhez.
set::hosts::admin <admin-gazdanév>;
- Meghatározza azt a gazdanevet, amit a +x beállításakor kapnak az adminisztrátorok.
+ Meghatározza azt a gazdanevet, amit a +x beállításakor kapnak az adminisztrátorok.
+ Igény szerint megadható egy username@host ehhez az értékhez.
set::hosts::servicesadmin <servicesadmin-gazdanév>;
- Beállítja azt a gazdanevet, amit a +x beállításakor kapnak a services adminisztrátorok.
+ Beállítja azt a gazdanevet, amit a +x beállításakor kapnak a services adminisztrátorok.
+ Igény szerint megadható egy username@host ehhez az értékhez.
set::hosts::netadmin <netadmin-gazdanév>;
- Beállítja azt a gazdanevet, amit a +x beállításakor kapnak a hálózati adminisztrátorok.
+ Beállítja azt a gazdanevet, amit a +x beállításakor kapnak a hálózati adminisztrátorok.
+ Igény szerint megadható egy username@host ehhez az értékhez.
set::hosts::host-on-oper-up <yes/no>;
Ha "yes"-re állítod, a H/get_host operflag figyelembe lesz véve, és a +x automatikusan be lesz
állítva /oper-eléskor. Ha "no" az értéke, a felhasználónak saját magának kell beállítania a +x módot,
@@ -2218,7 +2261,7 @@ set {
Árasztásvédelem névváltásokra: meghatározza, mennyi névváltás engedélyezett adott idõ alatt.
Például a nick-flood 4:90 azt jelenti, 4 névváltás 90 másodpercenként. Az alapértelmezés 3 per 60.
set::default-bantime <idõérték>
- Az alapértelmezett kitiltási idõ, amikor a /kline, /gline, /zline, /shun, stb. parancsokat idõ paraméter nélkül használod
+ Az alapértelmezett kitiltási idõ, amikor a /kline, /gline, /zline, /shun stb. parancsokat idõ paraméter nélkül használod
(mint pl. /gline *@valamelyik.csúnya.isp). Az alapérték "állandó" (0). Példa: default-bantime 90d;
set::modef-default-unsettime <szám>
Ezzel megadhatod a +f csatornamódhoz használt alapértelmezett törlési idõt (percekben). Ha például 10-et állítasz be,
@@ -2227,7 +2270,7 @@ set {
A +f csatornamódhoz használt törlési idõ legnagyobb megengedett hossza percekben (itt arról a törlési idõrõl van szó, amit
megadunk pl. a +f [5j#i<IDÕ>]:15 paraméterben). Ez egy 0 és 255 közötti érték. Az alapértelmezés 60 (= 1 óra).
set::ban-version-tkl-time <idõérték>
- Ha megadod az "action"-t (pl. zline, gline, stb.) a ban version blokkban, itt beállíthatod,
+ Ha megadod az "action"-t (pl. zline, gline stb.) a ban version blokkban, itt beállíthatod,
mennyi idõre legyen az IP kitiltva. Az alapértelmezés 86400 (1 nap).
set::spamfilter::ban-time <idõérték>
Ugyanaz, mint a fenti, de a spamszûrõk által beállított *line-okra.
@@ -2315,7 +2358,7 @@ set {
M
- Egy regisztrált nicknév (+r) szükséges a beszélgetéshez
+ Egy regisztrált nicknév (+r) kell, hogy beszélhess
h <nick>
@@ -2404,7 +2447,7 @@ set {
v <nick>
- Beszédjogot ad a felhasználónak. (Beszélhet +M csatornákon)
+ Beszédjogot ad a felhasználónak. (Beszélhet +m csatornákon)
z
@@ -2532,7 +2575,7 @@ set {
7 – Felhasználói és operátori parancsok táblázata
MEGJEGYZÉS: a /helpop dokumentáció sokkal frissebb, használd /helpop parancs-ot (vagy a /helpop ?parancs-ot, ha operátor vagy), hogy egy parancsról
-további információt kapj!
+további információt kapj.
@@ -2560,7 +2603,7 @@ tov
whowas <nick> <maxválasz>
Információt jelenít meg egy nickrõl, amely kilépett a hálózatról. A <max válasz>
- mezõ egyéni, és korlátozza a visszaadott bejegyzések számát.
+ mezõ szabadon választható, és korlátozza a visszaadott bejegyzések számát.
Mindenki
@@ -2719,7 +2762,7 @@ tov
mode <csatorna/nick> <mód>
Csatorna- és felhasználói módok beállítására szolgál. Lásd a
- Felhasználói és csatornamódok listáját!
+ Felhasználói és csatornamódok listáját.
Mindenki
@@ -2746,12 +2789,12 @@ tov
identify <jelszó>
- Elküldi a jelszavad a services rendszerhez a nickneved azonosítására.
+ Elküldi a jelszavad a szolgáltatás rendszerhez a nickneved azonosítására.
Mindenki
identify <csatorna> <jelszó>
- Elküldi a jelszavad a services rendszerhez, hogy a csatorna alapítójaként
+ Elküldi a jelszavad a szolgáltatás rendszerhez, hogy a csatorna alapítójaként
azonosítsd magad.
Mindenki
@@ -2809,33 +2852,33 @@ tov
Kitiltja a hostmaszkot arról a szerverrõl, ahonnan a parancsot kiadod. A kline nem globális kitiltás.
Az idõtartam a kitiltás lejárati ideje, és egyike a következõknek: a) egy érték másodpercekben, b) egy idõérték, pl. "1d" (1 nap), vagy c) "0" az állandó kitiltáshoz.
Az idõ és az indok nem kötelezõ, ha kihagyod õket, a set::default-bantime (alapértelmezés: 0/állandó) és "no reason" (nincs indok) lesz használatban.
- Egy kline eltávolításához használd a /kline -user@host parancsot!
+ Egy kline eltávolításához használd a /kline -user@host parancsot.
IRCop
zline [+|-]<*@ip> [<idõtartam> <indok>]
Kitilt egy IP címet arról a helyi szerverrõl, ahonnan a parancsot kiadod (nem globális). Lásd a kline-t további
- szintaktikai információért! Használd a /zline -*@ip parancsot az eltávolításhoz!
+ szintaktikai információért. Használd a /zline -*@ip parancsot az eltávolításhoz.
IRCop
gline [+|-]<user@host | nick> [<idõtartam> <indok>]
Globális kitiltást állít be mindazokon a személyeken, akikre a maszk illik. Lásd a kline-t további
- szintaktikai információért! Használd a /gline -user@host parancsot az eltávolításhoz!
+ szintaktikai információért. Használd a /gline -user@host parancsot az eltávolításhoz.
IRCop
shun [+|-]<user@host | nick> [<idõtartam> <indok>]
Megakadályozza, hogy egy felhasználó BÁRMILYEN parancsot végrehajtson ill. beszéljen.
- A shunok globálisak (mint a gline-ok). Lásd a kline-t további szintaktikai információért!
- Használd a /shun -user@host parancsot az eltávolításhoz!
+ A shunok globálisak (mint a gline-ok). Lásd a kline-t további szintaktikai információért.
+ Használd a /shun -user@host parancsot az eltávolításhoz.
IRCop
gzline [+|-]<ip> <idõtartam> :<indok>
- Globális zline-t állít be. Lásd a kline-t további információért!
- Használd a /gzline -*@ip parancsot az eltávolításhoz!
+ Globális zline-t állít be. Lásd a kline-t további információért.
+ Használd a /gzline -*@ip parancsot az eltávolításhoz.
IRCop
@@ -2903,7 +2946,7 @@ tov
Ha csak egy szervert adsz meg, azt a szervert, amelyiken RAJTA vagy, megpróbálja
csatlakoztatni a megadott szerverhez. Ha 2 szerver van megadva, a két szervert
kísérli meg csatlakoztatni egymáshoz. A leaf szervert írd be elõször, és a hubot
- másodiknak!
+ másodiknak.
IRCop
@@ -2979,7 +3022,7 @@ tov
tsctl offset +/- <idõ>
Beigazítja az IRCD belsõ óráját. (NE használd, ha nem érted,
- PONTOSAN mit csinál!)
+ PONTOSAN mit csinál.)
IRCop
@@ -2995,13 +3038,13 @@ tov
tsctl svstime <idõbélyeg>
Beállítja minden szerver TS idõjét. (NE használd, ha nem érted, PONTOSAN
- mit csinál!)
+ mit csinál.)
IRCop
htm <opció>
Szabályozza a magas forgalmi móddal kapcsolatos beállításokat. A magas forgalmi mód
- (High Traffic Mode, HTM) alapvetõen letilt bizonyos parancsokat, mint a list, whois, who, stb.,
+ (High Traffic Mode, HTM) alapvetõen letilt bizonyos parancsokat, mint a list, whois, who stb.,
válaszul szerveren kialakult rendkívül magas forgalomra. Az alábbi opciók használhatóak:
-ON Belép a HTM-be
-OFF Kilép a HTM-bõl
@@ -3086,25 +3129,25 @@ a (h
-Használj jó oper jelszavakat, link jelszavakat, stb.:
+Használj jó oper jelszavakat, link jelszavakat stb.:
- használj kis- és nagybetûket, számokat ("Whbviwf5") és/vagy valami hosszú szöveget ("blaheatsafish", "AlphaBeta555").
-- NE HASZNÁLD a link/oper jelszavaidat semmi másra, legyen az akár az elekronikus postafiókod, botod jelszava, fórumokban, stb...
+- NE HASZNÁLD a link/oper jelszavaidat semmi másra, legyen az akár az elekronikus postafiókod, botod jelszava, fórumokban stb...
8.2. Nem ircd-vel kapcsolatos sebezhetõségek
Sokkal több esély van arra, hogy a gépedet egy irc(d)-n kívüli sebezhetõséggel törik fel, mint hogy egy UnrealIRCd-beli hibával.
Például ha http, dns, smtp és ftp szervereket üzemeltetsz ugyanazon a gépen, a veszély sokkal nagyobb. Ezenkívül, ha többfelhasználós
rendszered van (pl.: egy shellt vásároltál), megvan a veszély helyi kiskapukra és rossz fájljogosultsági beállításokra (lásd a
-következõ pontot). Ennek a veszélye elég magas, ezért vigyázz, amikor shell szolgáltatót választasz!
+következõ pontot). Ennek a veszélye elég magas, ezért vigyázz, amikor shell szolgáltatót választasz.
8.3. Engedélybeállítások és a konfigurációs fájlok
Mindig gyõzõdj meg arról, hogy a home könyvtáradnak és az UnrealIRCd könyvtárnak megvannak megfelelõ engedélybeállításai;
a (csoportnak/)többieknek nem kell, hogy olvasásra engedélyük legyen. Különben egy helyi felhasználó símán megkaparinthatja
konfigurációs fájlokat, és jelszavakat kereshet bennük... Röviden: használd a chmod -R go-rwx /ahol/van/az/Unreal3.2
-parancsot, ha nem vagy biztos a dolgodban!
-További ilyen tanácsok: soha ne rakd az UnrealIRCd-t egy weben látható vagy egyéb módon megoszott könyvtárba! És arról is
-gondoskodj, hogy a biztonsági mentéseid is megkapják a megfelelõ engedélybeállításokat! (Elég gyakran megesik, hogy minden
+parancsot, ha nem vagy biztos a dolgodban.
+További ilyen tanácsok: soha ne rakd az UnrealIRCd-t egy weben látható vagy egyéb módon megoszott könyvtárba. És arról is
+gondoskodj, hogy a biztonsági mentéseid is megkapják a megfelelõ engedélybeállításokat. (Elég gyakran megesik, hogy minden
biztonságos, mégis megbújik valahol egy mindenki számára olvasható mentes.tar.gz.)
Javasolt még, hogy használj titkosított jelszavakat, ahol lehetséges.
@@ -3115,17 +3158,17 @@ inform
8.4. Felhasználószintû problémák
Mint a legtöbb dolog, ez sem kimondottan az UnrealIRCd-vel kapcsolatos, de...
-Mindig figyelmesen válogasd meg az operátoraidat és az adminisztrátoraidat! És emlékezz a leggyengébb láncszem fogalmára is!
+Mindig figyelmesen válogasd meg az operátoraidat és az adminisztrátoraidat. És emlékezz a leggyengébb láncszem fogalmára is.
Akkor is, ha óvatos voltál, és mindent megcsináltál, ami ebben a leírásban van, lehet, hogy a barátod, aki szintén operátor,
elkövet valami hülyeséget. Például megosztja a merevlemezét valamilyen programmal, mint pl. a netbios/kazaa/morpheus/.., trójai
-vírust kap, túl egyszerû jelszót használ, stb., stb... Sajnos, ez nem mindig a te irányításod alatt van.
+vírust kap, túl egyszerû jelszót használ, stb. stb... Sajnos, ez nem mindig a te irányításod alatt van.
8.5. SSL/SSH és a szimatolások
Használj SSL kapcsolatokat a szerverek között valamint operátorként, így megvédheted magad a "szimatolások" ellen. Egy támadó
akkor tud szimatolni, ha feltört egy gépet valahol te és az ircd szervered között. Ekkor MINDEN keresztülhaladó hálózati forgalmat
-meg tud nézni; például figyelhet minden beszélgetést, jelszavakat lophat (operátori bejelentkezésekhez, nickservhez, stb.)...
-Ugyanezen okból mindig használj SSL-t telnet helyett!
+meg tud nézni; például figyelhet minden beszélgetést, jelszavakat lophat (operátori bejelentkezésekhez, nickservhez stb.)...
+Ugyanezen okból mindig használj SSL-t telnet helyett.
8.6. Denial of Service támadások (DoS) [avagy: hogyan védd meg a hubodat]
@@ -3134,7 +3177,7 @@ n
de úgy tûnik, néhányan elfelejtik, hogy meglehetõsen könnyû megvédeni a hub szervert a támadásoktól.
Itt elmagyarázom:
1. Állítsd a hub nevét egy nemlétezõ gazdanévre, pl. "hub.sajátnet.com"-ra, de
- de ne csinálj neki dns rekordot! Ily módon a támadó nem tudja feloldani a gazdanevet, és
+ de ne csinálj neki dns rekordot. Ily módon a támadó nem tudja feloldani a gazdanevet, és
nem is tudja floodoltatni. Ezután egyszerûen linkeld a szervereidet a hubra az
IP cím vagy egyéb más, nem nyilvános gazdanév megadásával.
1. Példa: link lathatonev.sajatnet.com { hostname 194.15.123.16; [stb] };.
@@ -3144,13 +3187,13 @@ b
2. Egy másik fontos lépés, hogy elrejtsd a "/stats c" és egyéb statisztikai információkat, máskülönben a támadók egyszerûen
listát kaphatnak a link blokkokról. Rendszerint, ha paranoiás vagy (mint én), egyszerûen beírhatod,
hogy: set { oper-only-stats "*"; }; és ezzel letilthatsz minden /stats használatot. Vagy ha nem akarod
- ezt, akkor legalább a "CdDlLXz" flageket tiltsd le! Errõl bõvebb információ a következõ pontban.
+ ezt, akkor legalább a "CdDlLXz" flageket tiltsd le. Errõl bõvebb információ a következõ pontban.
Természetesen ezek a lépések kevésbé hasznosak, ha túl késõn történnek meg (pl.: egy hónap után), mintsem
a kezdetektõl fogva, mert lehet, hogy az IP címek már ismertek néhány gonosz fickó számára, de mégis... azért megéri megtenni.
Az is megjegyzendõ, hogy a támadók még így is lefloodolhatnak minden nem hub szervert, de az több erõfeszítést igényel,
-mint megtámadni csak 1-2 gyenge pontot (a hubokat), és így a hubjaid valamint a services
-életben marad :).
+mint megtámadni csak 1-2 gyenge pontot (a hubokat), és így a hubjaid valamint a szolgáltatások
+életben maradnak :).
@@ -3171,14 +3214,14 @@ Hogy n
- /stats E, /stats e: eléggé bizalmas információ, különösen, ha egy támadó használhatja ezeket a címeket
- /stats i, /stats y: segíthet a támadónak olyan hostot keresni, amely sok kapcsolatot engedélyez.
- /stats P: segít neki a csak szerverek részére engedélyezett portok keresésében
-stb., stb...
+stb. stb...
MAP / LINKS
Többen is megkérdezték már, hogy van-e valamilyen módja a /map vagy a /links letiltásának.
A mi álláspontunk az, hogy ez ostobaság, és hamis biztonságérzetet ad, hadd magyarázzam el... Elrejteni szervereket,
amiket tulajdonképpen a felhasználók használnak, hiábavaló, mivel már régen tudnak a szervereidrõl (hogyan tudnának
különben felmenni rájuk, elõször is?). Bármely olyan szerverrel kapcsolatban, amelyeken nem akarsz felhasználókat
-látni, lásd a 8.6. szekciót!
Most mit TEHETSZ? A 3.2.1 óta van egy "flat map" nevû opció (set::options::flat-map),
+látni, lásd a 8.6. szekciót.
Most mit TEHETSZ? A 3.2.1 óta van egy "flat map" nevû opció (set::options::flat-map),
ezzel minden szerver úgy jelenik meg a /map-ben és a /links-ben, mintha közvetlenül lennének
kapcsolódva, eképpen a közönséges felhasználók többé nem látják, melyik szerver hová lett linkelve...
Ez egy hasznos kiegészítõ védelmi réteg lehet, mert a gyerkõcök nem tudják kiszemelni a "gyenge pontokat"
@@ -3213,8 +3256,8 @@ a kiad
Mint mostmár remélhetõleg érted, soha nem lehetsz 100% biztonságban. Neked és nekünk is rentegeg biztonsági
lyukat kell megtalálnunk odakint, miközben egy támadónak elég csak 1 szervert megtalálnia 1 lyukkal.
Minden, amit itt elmagyaráztunk, azonban SEGÍT megfontoltan minimálissá tenni a veszélyeket.
-Áldozz egy kevés idõt arra, hogy a hálózatodat biztonságossá tedd, és oktasd az operátoraidat!
-Nagyon sokan nem is törõdnek a biztonsággal, egészen addíg, amíg bajba nem kerülnek. Próbáld ezt elkerülni! :)
+Áldozz egy kevés idõt arra, hogy a hálózatodat biztonságossá tedd, és oktasd az operátoraidat.
+Nagyon sokan nem is törõdnek a biztonsággal, egészen addíg, amíg bajba nem kerülnek. Próbáld ezt elkerülni. :)
diff --git a/extras/defizzer.c b/extras/defizzer.c
index 9b1fcc934..fec37d6b5 100644
--- a/extras/defizzer.c
+++ b/extras/defizzer.c
@@ -35,12 +35,7 @@ DLLFUNC int h_defizzer_connect(aClient *sptr);
static Hook *LocConnect = NULL;
ModuleInfo DefizzerModInfo;
-#ifndef DYNAMIC_LINKING
-ModuleHeader defizzer_Header
-#else
-#define defizzer_Header Mod_Header
-ModuleHeader Mod_Header
-#endif
+ModuleHeader MOD_HEADER(defizzer)
= {
"defizzer", /* Name of module */
"$Id$", /* Version */
@@ -49,43 +44,25 @@ ModuleHeader Mod_Header
NULL
};
-
-/* The purpose of these ifdefs, are that we can "static" link the ircd if we
- * want to
-*/
-
-/* This is called on module init, before Server Ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int Mod_Init(ModuleInfo *modinfo)
-#else
-int defizzer_Init(ModuleInfo *modinfo)
-#endif
+DLLFUNC int MOD_INIT(defizzer)(ModuleInfo *modinfo)
{
bcopy(modinfo,&DefizzerModInfo,modinfo->size);
LocConnect = HookAddEx(DefizzerModInfo.handle, HOOKTYPE_PRE_LOCAL_CONNECT, h_defizzer_connect);
return MOD_SUCCESS;
}
-/* Is first run when server is 100% ready */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int Mod_Load(int module_load)
-#else
-int defizzer_Load(int module_load)
-#endif
+DLLFUNC int MOD_LOAD(defizzer)(int module_load)
{
+ return MOD_SUCCESS;
}
-/* Called when module is unloaded */
-#ifdef DYNAMIC_LINKING
-DLLFUNC int Mod_Unload(int module_unload)
-#else
-int defizzer_Unload(int module_unload)
-#endif
+DLLFUNC int MOD_UNLOAD(defizzer)(int module_unload)
{
HookDel(LocConnect);
return MOD_SUCCESS;
}
+
static void ban_fizzer(aClient *cptr)
{
int i;
@@ -148,4 +125,4 @@ DLLFUNC int h_defizzer_connect(aClient *sptr)
return exit_client(sptr, sptr, &me, "Fizzer client");
}
return 0;
-}
\ No newline at end of file
+}
diff --git a/extras/tre.tar.gz b/extras/tre.tar.gz
index 569ad760b..b927a2858 100644
Binary files a/extras/tre.tar.gz and b/extras/tre.tar.gz differ
diff --git a/help.conf b/help.conf
index 4af1fb18e..b11c9291a 100644
--- a/help.conf
+++ b/help.conf
@@ -37,7 +37,7 @@ help Usercmds {
" CYCLE LINKS NOTICE SILENCE WHO";
" DALINFO LIST PART STATS WHOIS";
" INVITE LUSERS PING TIME WHOWAS";
- " ISON MAP PONG TOPIC";
+ " ISON MAP PONG TOPIC USERIP";
" JOIN MODE PRIVMSG USERHOST";
" ==-----------------oOo-----------------==";
};
@@ -130,7 +130,9 @@ help Snomasks {
" k = View KILL notices";
" n = View nick changes on local server";
" N = View nick changes on remote servers";
+ " o = View oper-up notices";
" q = View rejected nick changes due to Q:lines";
+ " s = View general notices";
" S = View spamfilter matches";
" v = View usage of /VHOST command";
" ==-------------------------oOo------------------------==";
@@ -164,7 +166,7 @@ help Chmodes {
" A = Server/Net Admin only channel (settable by Admins)";
" C = No CTCPs allowed in the channel [o]";
" G = Filters out all Bad words in messages with [o]";
- " M = Must be using a registered nick (+r) to talk [o]";
+ " M = Must be using a registered nick (+r), or have voice access to talk [o]";
" K = /KNOCK is not allowed [o]";
" L = Channel link (If +l is full, the next user will auto-join ) [q]";
" N = No Nickname changes are permitted in the channel [o]";
@@ -232,31 +234,60 @@ help Whois {
" -";
" Syntax: WHOIS ";
" Example: WHOIS hAtbLaDe";
+ " -";
+ " Status flags:";
+ " The list of channels shown in the WHOIS reply can include one or more";
+ " status flags to indicate information about the channel. These flags are";
+ " described below:";
+ " ~ - User is a Channel Owner (+q)";
+ " & - User is a Channel Admin (+a)";
+ " @ - User is a Channel Operator (+o)";
+ " % - User is a Halfop (+h)";
+ " + - User is Voiced (+v)";
+ " ! - User has channels hidden in whois (+p) and you are an IRC Operator";
+ " ? - The channel is secret (+s) and you are an IRC Operator";
};
help Who {
" Retrieves information about users";
" -";
" Syntax:";
- " /WHO [+|-][acghmnsuCM] [args]";
+ " /WHO [+|-][acghimnsuMRI] [args]";
" Flags are specified like channel modes, the flags cgmnsu all have arguments";
" Flags are set to a positive check by +, a negative check by -";
" The flags available:";
" Flag a: user is away";
" Flag c : user is on , no wildcards accepted";
- " Flag g : user has string in their GCOS,";
+ " Flag g : user has string in his/her GCOS,";
" wildcards accepted, oper only";
- " Flag h : user has string in their hostname, wildcards are accepted";
- " Flag m : user has set on them, only o/A/a for nonopers";
- " Flag n : user has string in their nickname, wildcards accepted";
+ " Flag h : user has string in his/her hostname, wildcards are accepted";
+ " Flag i : user has string in his/her IP address";
+ " Flag m : user has set, only o/C/A/a/N for nonopers";
+ " Flag n : user has string in his/her nickname, wildcards accepted";
" Flag s : user is on server , wildcards not accepted";
- " Flag u : user has string in their username, wildcards accepted";
+ " Flag u : user has string in his/her username, wildcards accepted";
" Behavior flags:";
- " Flag C: show first visible channel user is in";
" Flag M: check for user in channels I am a member of";
+ " Flag R: show users' real hostnames";
+ " Flag I: show users' IP addresses";
" -";
" For backwards compatibility, /who 0 o still shows +o users";
" Example: WHO +m o";
+ " -";
+ " Status flags:";
+ " The who command shows several flags in the returned result to indicate";
+ " different information about the user. These flags are explained below:";
+ " G - User is /away (gone)";
+ " H - User is not /away (here)";
+ " r - User is using a registered nickname";
+ " * - User is an IRC Operator";
+ " ~ - User is a Channel Owner (+q)";
+ " & - User is a Channel Admin (+a)";
+ " @ - User is a Channel Operator (+o)";
+ " % - User is a Halfop (+h)";
+ " + - User is Voiced (+v)";
+ " ! - User is +H and you are an IRC Operator";
+ " ? - User is only visible because you are an IRC Operator";
};
help Whowas {
@@ -427,6 +458,14 @@ help Userhost {
" Example: USERHOST hAtbLaDe";
};
+help Userip {
+ " Returns the userip of the user in question.";
+ " Usually used by scripts or bots.";
+ " -";
+ " Syntax: USERIP ";
+ " Example: USERIP codemastr";
+};
+
help Topic {
" Sets/Changes the topic of the channel in question,";
" or just display the current Topic.";
@@ -907,9 +946,10 @@ help Sapart {
" Forces a user to part a channel.";
" Services Admin Command";
" -";
- " Syntax: SAPART ,[..]";
+ " Syntax: SAPART ,[..] []";
" Example: SAPART hAtbLaDe #OperHelp";
" SAPART hAtbLaDe #Support,#IRCHelp";
+ " SAPART hAtbLaDe #Support,#IRCHelp Go away";
};
help Samode {
@@ -955,13 +995,16 @@ help Sdesc {
};
help Mkpasswd {
- " This command will Encrypt the string it has been given";
- " So you can add it directly to the unrealircd.conf if you use";
- " Encrypted passwords. Type can be crypt, sha1, or md5. Sha1";
- " and md5 are only available when compiled with SSL support.";
+ " This command will return a 'hash' of the string that has been specified,"
+ " you can use this hash for any encrypted passwords in your configuration file:";
+ " eg: for oper::password, vhost::password, etc.";
+ " Available types (in order of 'secureness'):";
+ " *NIX: crypt, md5, sha1 [*], ripemd160 [*]";
+ " Windows: crypt [*], md5, sha1, ripemd160 [*]";
+ " [*: only available if compiled with SSL support]";
" -";
" Syntax: MKPASSWD ";
- " Example: MKPASSWD crypt mpsare";
+ " Example: MKPASSWD md5 IamTeh1337";
};
help Module {
@@ -1066,9 +1109,10 @@ help Svspart {
" Forces a user to leave a channel.";
" Must be sent through an U:Lined server.";
" -";
- " Syntax: SVSPART [,..]";
+ " Syntax: SVSPART [,..] []";
" Example: SVSPART hAtbLaDe #Hanson";
" SVSPART hAtbLaDe #Hanson,#AOL";
+ " SVSPART hAtbLaDe #Hanson,#AOL You must leave";
};
help Svso {
@@ -1195,7 +1239,8 @@ help Spamfilter {
" Use: /spamfilter [add|del|remove|+|-] [type] [action] [tkltime] [reason] [regex]";
" [type] specifies the target type, you can specify multiple targets:";
" 'c' channel msg, 'p' private msg, 'n' private notice,";
- " 'N' channel notice, 'P' part msg, 'q' quit msg, 'd' dcc";
+ " 'N' channel notice, 'P' part msg, 'q' quit msg, 'd' dcc,";
+ " 'a' away, 'u' user (nick!user@host:realname ban)";
" [action] specifies the action to be taken (only 1 action can be specified):";
" 'kill', 'tempshun' (only shun current session), 'shun',";
" 'kline', 'gline', 'zline', 'gzline', 'block' (blocks the msg),";
diff --git a/include/auth.h b/include/auth.h
index f2434d683..fa1c19bfe 100644
--- a/include/auth.h
+++ b/include/auth.h
@@ -31,8 +31,9 @@ typedef struct {
#define AUTHTYPE_SSL_CLIENTCERT 4
#define AUTHTYPE_RIPEMD160 5
-#ifdef USE_SSL
+/* md5 is always available and enabled as of Unreal3.2.1 */
#define AUTHENABLE_MD5
+#ifdef USE_SSL
#define AUTHENABLE_SHA1
#define AUTHENABLE_SSL_CLIENTCERT
#define AUTHENABLE_RIPEMD160
@@ -47,11 +48,7 @@ typedef struct {
#endif
#endif
-
#ifdef _WIN32
-#ifndef AUTHENABLE_MD5
-#define AUTHENABLE_MD5
-#endif
#ifndef AUTHENABLE_SHA1
#define AUTHENABLE_SHA1
#endif
diff --git a/include/common.h b/include/common.h
index 9deaca0c7..7131c34ba 100644
--- a/include/common.h
+++ b/include/common.h
@@ -150,8 +150,9 @@ extern char *strtoken(char **, char *, char *);
extern MODVAR u_char tolowertab[], touppertab[];
-#if defined(CHINESE_NICK) || defined(JAPANESE_NICK)
+#if defined(NICK_GB2312) || defined(NICK_GBK) || defined(NICK_GBK_JAP)
#define USE_LOCALE
+#include
#endif
#ifndef USE_LOCALE
@@ -248,67 +249,18 @@ extern struct SLink *find_user_link( /* struct SLink *, struct Client * */ );
#define EXPAR4 ""
#endif /* EXTCMODE */
-#define PROTOCTL_CLIENT_1 \
- "MAP" \
- " KNOCK" \
- " SAFELIST" \
- " HCN" \
- " MAXCHANNELS=%i" \
- " MAXBANS=%i" \
- " NICKLEN=%i" \
- " TOPICLEN=%i" \
- " KICKLEN=%i" \
- " MAXTARGETS=%i" \
- " AWAYLEN=%i" \
- " :are supported by this server"
-#define PROTOCTL_PARAMETERS_1 \
- MAXCHANNELSPERUSER, \
- MAXBANS, \
- NICKLEN, \
- TOPICLEN, \
- TOPICLEN, \
- MAXTARGETS, \
- TOPICLEN
-
#ifdef PREFIX_AQ
-#define CHPFIX "(qaohv)~&@%+"
-#define CHPAR1 "be"
+#define CHPFIX "(qaohv)~&@%+"
+#define CHPAR1 "be"
#else
-#define CHPFIX "(ohv)@%+"
-#define CHPAR1 "beqa"
+#define CHPFIX "(ohv)@%+"
+#define CHPAR1 "beqa"
#endif /* PREFIX_AQ */
-#define CHPAR2 "kfL"
-#define CHPAR3 "l"
-#define CHPAR4 "psmntirRcOAQKVGCuzNSM"
+#define CHPAR2 "kfL"
+#define CHPAR3 "l"
+#define CHPAR4 "psmntirRcOAQKVGCuzNSM"
-#define PROTOCTL_CLIENT_2 \
- "WALLCHOPS" \
- " WATCH=%i" \
- " SILENCE=%i" \
- " MODES=%i" \
- " CHANTYPES=%s" \
- " PREFIX=%s" \
- " CHANMODES=%s%s,%s%s,%s%s,%s%s" \
- " NETWORK=%s" \
- " CASEMAPPING=%s" \
- " EXTBAN=~,%s" \
- " ELIST=MNUCT" \
- " :are supported by this server"
-
-#define PROTOCTL_PARAMETERS_2 \
- MAXWATCH, \
- SILENCE_LIMIT, \
- MAXMODEPARAMS, \
- "#", \
- CHPFIX, \
- CHPAR1, EXPAR1, \
- CHPAR2, EXPAR2, \
- CHPAR3, EXPAR3, \
- "psmntirRcOAQKVGCuzNSM", EXPAR4, \
- ircnet005, \
- "ascii", \
- extbanstr
/* Server-Server PROTOCTL -Stskeeps
* Please check send_proto() for more. -- Syzop
diff --git a/include/config.h b/include/config.h
index a7eba3a33..2b82771c0 100644
--- a/include/config.h
+++ b/include/config.h
@@ -92,14 +92,6 @@
*/
#undef SECURECHANMSGSONLYGOTOSECURE
-/*
- * be compatible with older cloak keys? If you link to servers beta4 and
- * earlier without this the cloak keys will produce diff results
- * Not recommended, however, as beta4 and earlier 3.2 has an insecure
- * cloak algo -griever
- */
-#undef COMPAT_BETA4_KEYS
-
/*
If you want SHUN_NOTICES, define this
*/
@@ -108,8 +100,9 @@
/*
If you want to support chinese and/or japanese nicks
*/
-#undef CHINESE_NICK
-#undef JAPANESE_NICK
+#undef NICK_GB2312
+#undef NICK_GBK
+#undef NICK_GBK_JAP
/*
Remote rehash
@@ -377,25 +370,13 @@
#define PORTNUM 6667 /* 6667 is default */
/*
- * Maximum number of network connections your server will allow. This should
- * never exceed max. number of open file descrpitors and wont increase this.
- * Should remain LOW as possible. Most sites will usually have under 30 or so
- * connections. A busy hub or server may need this to be as high as 50 or 60.
- * Making it over 100 decreases any performance boost gained from it being low.
- * if you have a lot of server connections, it may be worth splitting the load
- * over 2 or more servers.
- * 1 server = 1 connection, 1 user = 1 connection.
- * This should be at *least* 3: 1 listen port, 1 dns port + 1 client
- *
- * Note: this figure will be too high for most systems. If you get an
- * fd-related error on compile, change this to 256.
- *
- * Windows users: This should be a fairly high number. Some operations
- * will slow down because of this, but it is _required_ because of the way
- * windows NT(and possibly 95) allocate fd handles. A good number is 16384.
+ * Maximum number of network connections your server will allow.
+ * This is usually configured via ./Config on *NIX,
+ * the setting mentioned below is the default for Windows.
+ * 2004-10-13: 1024 -> 4096
*/
#ifndef MAXCONNECTIONS
-#define MAXCONNECTIONS 1024
+#define MAXCONNECTIONS 4096
#endif
/*
diff --git a/include/h.h b/include/h.h
index c5624d4c8..e6c9d2822 100644
--- a/include/h.h
+++ b/include/h.h
@@ -457,6 +457,7 @@ extern MODVAR long SNO_FNICKCHANGE;
extern MODVAR long SNO_QLINE;
extern MODVAR long SNO_SNOTICE;
extern MODVAR long SNO_SPAMF;
+extern MODVAR long SNO_OPER;
#ifdef EXTCMODE
/* Extended chanmodes... */
@@ -703,3 +704,7 @@ extern int add_dccallow(aClient *sptr, aClient *optr);
extern int del_dccallow(aClient *sptr, aClient *optr);
extern void delete_linkblock(ConfigItem_link *link_ptr);
extern void delete_classblock(ConfigItem_class *class_ptr);
+extern void del_async_connects(void);
+extern int find_spamfilter_user(aClient *sptr);
+extern void make_extbanstr(void);
+extern void isupport_init(void);
diff --git a/include/macros.h b/include/macros.h
new file mode 100644
index 000000000..20a1b6c3d
--- /dev/null
+++ b/include/macros.h
@@ -0,0 +1,23 @@
+/************************************************************************
+ * Unreal Internet Relay Chat Daemon, include/macros.h
+ * Copyright (c) 2004 Dominick Meglio & The UnrealIRCd Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ */
+
+/* Calculate the size of an array */
+#define ARRAY_SIZEOF(x) (sizeof((x))/sizeof((x)[0]))
diff --git a/include/modules.h b/include/modules.h
index 8feb615e5..95771a893 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -99,6 +99,7 @@ typedef struct {
#define MOBJ_CMDOVERRIDE 0x0080
#define MOBJ_EXTBAN 0x0100
#define MOBJ_CALLBACK 0x0200
+#define MOBJ_ISUPPORT 0x0400
typedef struct {
long mode;
@@ -294,6 +295,13 @@ typedef struct _versionflag {
ModuleChild *parents;
} Versionflag;
+typedef struct _isupport {
+ struct _isupport *prev, *next;
+ char *token;
+ char *value;
+ Module *owner;
+} Isupport;
+
typedef struct _ModuleObject {
struct _ModuleObject *prev, *next;
short type;
@@ -308,6 +316,7 @@ typedef struct _ModuleObject {
Cmdoverride *cmdoverride;
Extban *extban;
Callback *callback;
+ Isupport *isupport;
} object;
} ModuleObject;
@@ -461,6 +470,11 @@ void *obsd_dlsym(void *handle, char *symbol);
Versionflag *VersionflagAdd(Module *module, char flag);
void VersionflagDel(Versionflag *vflag, Module *module);
+Isupport *IsupportAdd(Module *module, const char *token, const char *value);
+void IsupportSetValue(Isupport *isupport, const char *value);
+void IsupportDel(Isupport *isupport);
+Isupport *IsupportFind(const char *token);
+
#define add_Hook(hooktype, func) HookAddMain(NULL, hooktype, func, NULL, NULL)
#define HookAdd(hooktype, func) HookAddMain(NULL, hooktype, func, NULL, NULL)
#define HookAddEx(module, hooktype, func) HookAddMain(module, hooktype, func, NULL, NULL)
@@ -569,6 +583,9 @@ int CallCmdoverride(Cmdoverride *ovr, aClient *cptr, aClient *sptr, int parc, ch
#define HOOKTYPE_TKL_DEL 40
#define HOOKTYPE_LOCAL_KILL 41
#define HOOKTYPE_LOG 42
+#define HOOKTYPE_REMOTE_JOIN 43
+#define HOOKTYPE_REMOTE_PART 44
+#define HOOKTYPE_REMOTE_KICK 45
/* Hook return values */
#define HOOK_CONTINUE 0
diff --git a/include/msg.h b/include/msg.h
index 90ada1180..225c089e2 100644
--- a/include/msg.h
+++ b/include/msg.h
@@ -239,7 +239,6 @@
#define MSG_TSCTL "TSCTL"
#define TOK_TSCTL "AW"
#define MSG_SVSJOIN "SVSJOIN"
-#define TOK_SVSJOIN "BR"
#define MSG_SAJOIN "SAJOIN"
#define TOK_SAJOIN "AX"
#define MSG_SVSPART "SVSPART"
diff --git a/include/numeric.h b/include/numeric.h
index 7aec7d7e4..3f66693cb 100644
--- a/include/numeric.h
+++ b/include/numeric.h
@@ -33,11 +33,11 @@
#define RPL_YOURHOST 002
#define RPL_CREATED 003
#define RPL_MYINFO 004
-#define RPL_PROTOCTL 005
+#define RPL_ISUPPORT 005
#define RPL_REDIR 10
-#define RPL_REMOTEPROTOCTL 105
+#define RPL_REMOTEISUPPORT 105
/*
* Errors are in the range from 400-599 currently and are grouped by what
@@ -184,6 +184,7 @@
#define RPL_LISTSYNTAX 334
#define RPL_WHOISBOT 335
+#define RPL_USERIP 340
#define RPL_INVITING 341
#define RPL_SUMMONING 342
diff --git a/include/struct.h b/include/struct.h
index 271297001..71c8b7d26 100644
--- a/include/struct.h
+++ b/include/struct.h
@@ -263,6 +263,8 @@ typedef unsigned int u_int32_t; /* XXX Hope this works! */
#define SetClient(x) ((x)->status = STAT_CLIENT)
#define SetLog(x) ((x)->status = STAT_LOG)
+#define IsSynched(x) (x->serv->flags.synced)
+
/* opt.. */
#define OPT_SJOIN 0x0001
#define OPT_NOT_SJOIN 0x0002
@@ -327,7 +329,7 @@ typedef unsigned int u_int32_t; /* XXX Hope this works! */
* -DuffJ
*/
-#define SNO_DEFOPER "+kscfvGq"
+#define SNO_DEFOPER "+kscfvGqo"
#define SNO_DEFUSER "+ks"
#define SEND_UMODES (SendUmodes)
@@ -684,7 +686,9 @@ struct MotdItem {
struct aloopStruct {
unsigned do_garbage_collect : 1;
unsigned ircd_booted : 1;
- unsigned do_bancheck : 1;
+ unsigned do_bancheck : 1; /* perform *line bancheck? */
+ unsigned do_bancheck_spamf_user : 1; /* perform 'user' spamfilter bancheck */
+ unsigned do_bancheck_spamf_away : 1; /* perform 'away' spamfilter bancheck */
unsigned ircd_rehashing : 1;
unsigned tainted : 1;
aClient *rehash_save_cptr, *rehash_save_sptr;
@@ -768,6 +772,7 @@ struct Server {
#define M_ALIAS 0x0020
#define M_RESETIDLE 0x0040
#define M_VIRUS 0x0080
+#define M_ANNOUNCE 0x0100
/* tkl:
@@ -791,6 +796,8 @@ struct Server {
#define SPAMF_PART 0x0010 /* P */
#define SPAMF_QUIT 0x0020 /* q */
#define SPAMF_DCC 0x0040 /* d */
+#define SPAMF_USER 0x0080 /* u */
+#define SPAMF_AWAY 0x0100 /* a */
struct _spamfilter {
unsigned short action; /* see BAN_ACT* */
@@ -921,11 +928,13 @@ struct Client {
long receiveM; /* Statistics: protocol messages received */
#ifdef ZIP_LINKS
struct Zdata *zip; /* zip data */
+#elif defined(_WIN32)
+ void *zip_NOTUSED; /* (win32 binary compatability) */
#endif
#ifdef USE_SSL
SSL *ssl;
#elif defined(_WIN32)
- void *ssl_NOTUSED;
+ void *ssl_NOTUSED; /* (win32 binary compatability) */
#endif
#ifndef NO_FDLIST
long lastrecvM; /* to check for activity --Mika */
@@ -1091,6 +1100,7 @@ struct _configitem_oper {
anAuthStruct *auth;
ConfigItem_class *class;
ConfigItem *from;
+ unsigned long modes;
long oflags;
int maxlogins;
};
@@ -1260,24 +1270,24 @@ struct _configitem_unknown_ext {
ConfigEntry *ce_entries;
};
-#define ALIAS_SERVICES 1
-#define ALIAS_STATS 2
-#define ALIAS_NORMAL 3
-#define ALIAS_COMMAND 4
+
+typedef enum {
+ ALIAS_SERVICES=1, ALIAS_STATS, ALIAS_NORMAL, ALIAS_COMMAND, ALIAS_CHANNEL
+} AliasType;
struct _configitem_alias {
ConfigItem *prev, *next;
ConfigFlag flag;
ConfigItem_alias_format *format;
char *alias, *nick;
- short type;
+ AliasType type;
};
struct _configitem_alias_format {
ConfigItem *prev, *next;
ConfigFlag flag;
char *nick;
- short type;
+ AliasType type;
char *format, *parameters;
regex_t expr;
};
diff --git a/include/version.h b/include/version.h
index c3d4d4509..3a2a7f18d 100644
--- a/include/version.h
+++ b/include/version.h
@@ -24,12 +24,12 @@
/**/
#define COMPILEINFO DEBUGMODESET DEBUGSET
/*
- * Version Unreal3.2.1
+ * Version Unreal3.2.2
*/
-#define UnrealProtocol 2304
+#define UnrealProtocol 2305
#define PATCH1 "3"
#define PATCH2 ".2"
-#define PATCH3 ".1"
+#define PATCH3 ".2"
#define PATCH4 ""
#define PATCH5 ""
#define PATCH6 ""
diff --git a/include/win32/regex.h b/include/win32/regex.h
index ae709c9e2..394115313 100644
--- a/include/win32/regex.h
+++ b/include/win32/regex.h
@@ -51,6 +51,14 @@ extern "C" {
typedef int reg_errcode_t;
#endif /* !HAVE_REG_ERRCODE_T */
+/* Extra regcomp() flags. */
+#define REG_LITERAL 0x1000
+#define REG_RIGHT_ASSOC (REG_LITERAL << 1)
+
+/* Extra regexec() flags. */
+#define REG_APPROX_MATCHER 0x1000
+#define REG_BACKTRACKING_MATCHER (REG_APPROX_MATCHER << 1)
+
#else /* !TRE_USE_SYSTEM_REGEX_H */
/* If the we're not using system regex.h, we need to define the
@@ -59,7 +67,7 @@ typedef int reg_errcode_t;
typedef int regoff_t;
typedef struct {
size_t re_nsub; /* Number of parenthesized subexpressions. */
- void *value; /* For internal use only. */
+ void *value; /* For internal use only. */
} regex_t;
typedef struct {
@@ -69,45 +77,50 @@ typedef struct {
typedef enum {
- REG_OK = 0, /* No error. */
+ REG_OK = 0, /* No error. */
/* POSIX regcomp() return error codes. (In the order listed in the
- standard.) */
- REG_NOMATCH, /* No match. */
- REG_BADPAT, /* Invalid regexp. */
- REG_ECOLLATE, /* Unknown collating element. */
- REG_ECTYPE, /* Unknown character class name. */
- REG_EESCAPE, /* Trailing backslash. */
- REG_ESUBREG, /* Invalid back reference. */
- REG_EBRACK, /* "[]" imbalance */
- REG_EPAREN, /* "\(\)" or "()" imbalance */
- REG_EBRACE, /* "\{\}" or "{}" imbalance */
- REG_BADBR, /* Invalid content of {} */
- REG_ERANGE, /* Invalid use of range operator */
- REG_ESPACE, /* Out of memory. */
+ standard.) */
+ REG_NOMATCH, /* No match. */
+ REG_BADPAT, /* Invalid regexp. */
+ REG_ECOLLATE, /* Unknown collating element. */
+ REG_ECTYPE, /* Unknown character class name. */
+ REG_EESCAPE, /* Trailing backslash. */
+ REG_ESUBREG, /* Invalid back reference. */
+ REG_EBRACK, /* "[]" imbalance */
+ REG_EPAREN, /* "\(\)" or "()" imbalance */
+ REG_EBRACE, /* "\{\}" or "{}" imbalance */
+ REG_BADBR, /* Invalid content of {} */
+ REG_ERANGE, /* Invalid use of range operator */
+ REG_ESPACE, /* Out of memory. */
REG_BADRPT
} reg_errcode_t;
/* POSIX regcomp() flags. */
-#define REG_EXTENDED 1
-#define REG_ICASE (REG_EXTENDED << 1)
-#define REG_NEWLINE (REG_ICASE << 1)
-#define REG_NOSUB (REG_NEWLINE << 1)
+#define REG_EXTENDED 1
+#define REG_ICASE (REG_EXTENDED << 1)
+#define REG_NEWLINE (REG_ICASE << 1)
+#define REG_NOSUB (REG_NEWLINE << 1)
/* Extra regcomp() flags. */
-#define REG_BASIC 0
-#define REG_LITERAL (REG_NOSUB << 1)
+#define REG_BASIC 0
+#define REG_LITERAL (REG_NOSUB << 1)
+#define REG_RIGHT_ASSOC (REG_LITERAL << 1)
/* POSIX regexec() flags. */
#define REG_NOTBOL 1
#define REG_NOTEOL (REG_NOTBOL << 1)
+/* Extra regexec() flags. */
+#define REG_APPROX_MATCHER (REG_NOTEOL << 1)
+#define REG_BACKTRACKING_MATCHER (REG_APPROX_MATCHER << 1)
+
#endif /* !TRE_USE_SYSTEM_REGEX_H */
/* REG_NOSPEC and REG_LITERAL mean the same thing. */
#if defined(REG_LITERAL)
-#define REG_NOSPEC REG_LITERAL
+#define REG_NOSPEC REG_LITERAL
#elif defined(REG_NOSPEC)
-#define REG_LITERAL REG_NOSPEC
+#define REG_LITERAL REG_NOSPEC
#endif /* defined(REG_NOSPEC) */
/* The maximum number of iterations in a bound expression. */
@@ -148,24 +161,24 @@ int regwnexec(const regex_t *preg, const wchar_t *string, size_t len,
/* Approximate matching parameter struct. */
typedef struct {
- int cost_ins; /* Default cost of an inserted character. */
- int cost_del; /* Default cost of a deleted character. */
+ int cost_ins; /* Default cost of an inserted character. */
+ int cost_del; /* Default cost of a deleted character. */
int cost_subst; /* Default cost of a substituted character. */
- int max_cost; /* Maximum allowed cost of a match. */
+ int max_cost; /* Maximum allowed cost of a match. */
- int max_ins; /* Maximum allowed number of inserts. */
- int max_del; /* Maximum allowed number of deletes. */
+ int max_ins; /* Maximum allowed number of inserts. */
+ int max_del; /* Maximum allowed number of deletes. */
int max_subst; /* Maximum allowed number of substitutes. */
- int max_err; /* Maximum allowed number of errors total. */
+ int max_err; /* Maximum allowed number of errors total. */
} regaparams_t;
/* Approximate matching result struct. */
typedef struct {
size_t nmatch; /* Length of pmatch[] array. */
regmatch_t *pmatch; /* Submatch data. */
- int cost; /* Cost of the match. */
- int num_ins; /* Number of inserts in the match. */
- int num_del; /* Number of deletes in the match. */
+ int cost; /* Cost of the match. */
+ int num_ins; /* Number of inserts in the match. */
+ int num_del; /* Number of deletes in the match. */
int num_subst; /* Number of substitutes in the match. */
} regamatch_t;
@@ -187,9 +200,28 @@ int regawnexec(const regex_t *preg, const wchar_t *string, size_t len,
void regaparams_default(regaparams_t *params);
#endif /* TRE_APPROX */
-/* Returns the version string. The returned string is static. */
+#ifdef TRE_WCHAR
+typedef wchar_t tre_char_t;
+#else /* !TRE_WCHAR */
+typedef unsigned char tre_char_t;
+#endif /* !TRE_WCHAR */
+
+typedef struct {
+ int (*get_next_char)(tre_char_t *c, unsigned int *pos_add, void *context);
+ void (*rewind)(size_t pos, void *context);
+ int (*compare)(size_t pos1, size_t pos2, size_t len, void *context);
+ void *context;
+} tre_str_source;
+
+int reguexec(const regex_t *preg, const tre_str_source *string,
+ size_t nmatch, regmatch_t pmatch[], int eflags);
+
+/* Returns the version string. The returned string is static. */
char *tre_version(void);
+/* Returns the value for a config parameter. The type to which `result'
+ must point to depends of the value of `query', see documentation for
+ more details. */
int tre_config(int query, void *result);
enum {
@@ -200,6 +232,13 @@ enum {
TRE_CONFIG_VERSION
};
+/* Returns 1 if the compiled pattern has back references, 0 if not. */
+int tre_have_backrefs(const regex_t *preg);
+
+/* Returns 1 if the compiled pattern uses approximate matching features,
+ 0 if not. */
+int tre_have_approx(const regex_t *preg);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/win32/tre-config.h b/include/win32/tre-config.h
index ab08344e1..0f9f42903 100644
--- a/include/win32/tre-config.h
+++ b/include/win32/tre-config.h
@@ -1,6 +1,16 @@
/* tre-config.h. This file defines all compile time definitions
that are needed in `regex.h' for Win32. */
+/* Define to 1 if you have `alloca', as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define to 1 if you have and it should be used (not on Ultrix).
+ */
+#define HAVE_ALLOCA_H 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_LIBUTF8_H */
+
/* Define to 1 if the system has the type `reg_errcode_t'. */
/* #undef HAVE_REG_ERRCODE_T */
@@ -16,11 +26,27 @@
/* Define to enable multibyte character set support. */
#undef TRE_MULTIBYTE
-/* Define to include the system regex.h from TRE regex.h */
-/* #undef TRE_USE_SYSTEM_REGEX_H */
-
/* Define to the absolute path to the system regex.h */
/* #undef TRE_SYSTEM_REGEX_H_PATH */
+/* Define if you want TRE to use alloca() instead of malloc() when allocating
+ memory needed for regexec operations. */
+#define TRE_USE_ALLOCA 1
+
+/* Define to include the system regex.h from TRE regex.h */
+/* #undef TRE_USE_SYSTEM_REGEX_H */
+
/* Define to enable wide character (wchar_t) support. */
#undef TRE_WCHAR
+
+/* TRE version string. */
+#define TRE_VERSION "0.7.0"
+
+/* TRE version level 1. */
+#define TRE_VERSION_1 0
+
+/* TRE version level 2. */
+#define TRE_VERSION_2 7
+
+/* TRE version level 3. */
+#define TRE_VERSION_3 0
diff --git a/makefile.win32 b/makefile.win32
index d5d3db274..b9e91a052 100644
--- a/makefile.win32
+++ b/makefile.win32
@@ -101,9 +101,9 @@ OPENSSL_LIB=/LIBPATH:"$(OPENSSL_LIB_DIR)"
!ENDIF
!IFDEF DEBUG
-DBGCFLAG=/MDd /Zi
+DBGCFLAG=/MD /Zi
DBGLFLAG=/debug /debugtype:BOTH
-MODDBGCFLAG=/LDd /MDd /Zi
+MODDBGCFLAG=/LDd /MD /Zi
!ELSE
DBGCFLAG=/MD /O2 /G5
MODDBGCFLAG=/LD /MD
@@ -138,10 +138,11 @@ EXP_OBJ_FILES=SRC/CHANNEL.OBJ SRC/SEND.OBJ SRC/SOCKET.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/RANDOM.OBJ SRC/EXTCMODES.OBJ SRC/MD5.OBJ \
+ SRC/RANDOM.OBJ SRC/EXTCMODES.OBJ SRC/MD5.OBJ SRC/API-ISUPPORT.OBJ SRC/API-COMMAND.OBJ \
SRC/EXTBANS.OBJ $(ZIPOBJ) $(CURLOBJ)
-OBJ_FILES=$(EXP_OBJ_FILES) SRC/WIN32GUI.OBJ SRC/SERVICE.OBJ SRC/DEBUG.OBJ
+OBJ_FILES=$(EXP_OBJ_FILES) SRC/GUI.OBJ SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RTF.OBJ \
+ SRC/EDITOR.OBJ SRC/WIN32.OBJ
MOD_FILES=SRC/MODULES/L_COMMANDS.C SRC/MODULES/M_CHGHOST.C SRC/MODULES/M_SDESC.C \
SRC/MODULES/M_SETIDENT.C SRC/MODULES/M_SETNAME.C SRC/MODULES/M_SETHOST.C \
@@ -170,7 +171,7 @@ MOD_FILES=SRC/MODULES/L_COMMANDS.C SRC/MODULES/M_CHGHOST.C SRC/MODULES/M_SDESC.C
SRC/MODULES/M_RULES.C SRC/MODULES/M_CLOSE.C SRC/MODULES/M_MAP.C SRC/MODULES/M_EOS.C \
SRC/MODULES/M_SERVER.C SRC/MODULES/M_STATS.C SRC/MODULES/M_SVSFLINE.C \
SRC/MODULES/M_DCCDENY.C SRC/MODULES/M_UNDCCDENY.C SRC/MODULES/M_WHOWAS.C \
- SRC/MODULES/M_CONNECT.C SRC/MODULES/M_DCCALLOW.C
+ SRC/MODULES/M_CONNECT.C SRC/MODULES/M_DCCALLOW.C SRC/MODULES/M_USERIP.C
DLL_FILES=SRC/MODULES/M_CHGHOST.DLL SRC/MODULES/M_SDESC.DLL SRC/MODULES/M_SETIDENT.DLL \
SRC/MODULES/M_SETNAME.DLL SRC/MODULES/M_SETHOST.DLL SRC/MODULES/M_CHGIDENT.DLL \
@@ -201,7 +202,7 @@ DLL_FILES=SRC/MODULES/M_CHGHOST.DLL SRC/MODULES/M_SDESC.DLL SRC/MODULES/M_SETIDE
SRC/MODULES/M_CLOSE.DLL SRC/MODULES/M_MAP.DLL SRC/MODULES/M_EOS.DLL \
SRC/MODULES/M_SERVER.DLL SRC/MODULES/M_STATS.DLL SRC/MODULES/M_SVSFLINE.DLL \
SRC/MODULES/M_DCCDENY.DLL SRC/MODULES/M_UNDCCDENY.DLL SRC/MODULES/M_WHOWAS.DLL \
- SRC/MODULES/M_CONNECT.DLL SRC/MODULES/M_DCCALLOW.DLL \
+ SRC/MODULES/M_CONNECT.DLL SRC/MODULES/M_DCCALLOW.DLL SRC/MODULES/M_USERIP.DLL \
SRC/MODULES/CLOAK.DLL SRC/MODULES/OLDCLOAK.DLL
@@ -362,18 +363,27 @@ src/hash.obj: src/hash.c $(INCLUDES) ./include/hash.h
src/crule.obj: src/crule.c $(INCLUDES)
$(CC) $(CFLAGS) src/crule.c
-src/win32gui.obj: src/win32/win32gui.c $(INCLUDES) ./include/resource.h
- $(CC) $(CFLAGS) src/win32/win32gui.c
+src/gui.obj: src/win32/gui.c $(INCLUDES) ./include/resource.h
+ $(CC) $(CFLAGS) src/win32/gui.c
+
+src/rtf.obj: src/win32/rtf.c $(INCLUDES) ./src/win32/win32.h
+ $(CC) $(CFLAGS) src/win32/rtf.c
+
+src/editor.obj: src/win32/editor.c $(INCLUDES) ./include/resource.h ./src/win32/win32.h
+ $(CC) $(CFLAGS) src/win32/editor.c
src/service.obj: src/win32/service.c $(INCLUDES)
$(CC) $(CFLAGS) src/win32/service.c
-src/unreal.obj: src/win32/unreal.c $(INCLUDES)
- $(CC) $(CFLAGS) src/win32/unreal.c
-
src/debug.obj: src/win32/debug.c $(INCLUDES)
$(CC) $(CFLAGS) src/win32/debug.c
+src/win32.obj: src/win32/win32.c $(INCLUDES)
+ $(CC) $(CFLAGS) src/win32/win32.c
+
+src/unreal.obj: src/win32/unreal.c $(INCLUDES)
+ $(CC) $(CFLAGS) src/win32/unreal.c
+
src/res_comp.obj: src/res_comp.c $(INCLUDES)
$(CC) $(CFLAGS) src/res_comp.c
@@ -413,6 +423,12 @@ src/url.obj: src/url.c $(INCLUDES) ./include/url.h
src/extbans.obj: src/extbans.c $(INCLUDES)
$(CC) $(CFLAGS) src/extbans.c
+src/api-isupport.obj: src/api-isupport.c $(INCLUDES)
+ $(CC) $(CFLAGS) src/api-isupport.c
+
+src/api-command.obj: src/api-command.c $(INCLUDES)
+ $(CC) $(CFLAGS) src/api-command.c
+
src/zip.obj: src/zip.c $(INCLUDES)
$(CC) $(CFLAGS) src/zip.c
@@ -713,6 +729,9 @@ src/modules/m_connect.dll: src/modules/m_connect.c $(INCLUDES)
src/modules/m_dccallow.dll: src/modules/m_dccallow.c $(INCLUDES)
$(CC) $(MODCFLAGS) src/modules/m_dccallow.c $(MODLFLAGS)
+src/modules/m_userip.dll: src/modules/m_userip.c $(INCLUDES)
+ $(CC) $(MODCFLAGS) src/modules/m_userip.c $(MODLFLAGS)
+
src/modules/cloak.dll: src/modules/cloak.c $(INCLUDES)
$(CC) $(MODCFLAGS) src/modules/cloak.c $(MODLFLAGS)
diff --git a/src/Makefile b/src/Makefile
index 97404e1c2..10507687f 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -29,7 +29,7 @@ OBJS=auth.o aln.o badwords.o channel.o cloak.o crule.o dbuf.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 extcmodes.o \
- extbans.o md5.o $(URL)
+ extbans.o md5.o api-isupport.o api-command.o $(URL)
SRC=$(OBJS:%.o=%.c)
@@ -250,6 +250,12 @@ extbans.o: extbans.c $(INCLUDES)
md5.o: md5.c $(INCLUDES)
$(CC) $(CFLAGS) -c md5.c
+api-command.o: api-command.c $(INCLUDES)
+ $(CC) $(CFLAGS) -c api-command.c
+
+api-isupport.o: api-isupport.c $(INCLUDES)
+ $(CC) $(CFLAGS) -c api-isupport.c
+
url.o: url.c $(INCLUDES) ../include/url.h
$(CC) $(CFLAGS) -c url.c
diff --git a/src/api-command.c b/src/api-command.c
new file mode 100644
index 000000000..acc1c7f76
--- /dev/null
+++ b/src/api-command.c
@@ -0,0 +1,149 @@
+/************************************************************************
+ * Unreal Internet Relay Chat Daemon, src/api-command.c
+ * Copyright (C) 2004 Dominick Meglio and The UnrealIRCd Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "struct.h"
+#include "common.h"
+#include "sys.h"
+#include "msg.h"
+#include "h.h"
+#include
+
+char *cmdstr = NULL;
+
+int CommandExists(char *name)
+{
+ aCommand *p;
+
+ for (p = CommandHash[toupper(*name)]; p; p = p->next)
+ {
+ if (!stricmp(p->cmd, name))
+ return 1;
+ }
+ for (p = TokenHash[*name]; p; p = p->next)
+ {
+ if (!strcmp(p->cmd, name))
+ return 1;
+ }
+ return 0;
+}
+
+Command *CommandAdd(Module *module, char *cmd, char *tok, int (*func)(), unsigned char params, int flags) {
+ Command *command;
+
+ if (find_Command_simple(cmd) || (tok && find_Command_simple(tok)))
+ {
+ if (module)
+ module->errorcode = MODERR_EXISTS;
+ return NULL;
+ }
+ command = MyMallocEx(sizeof(Command));
+ command->cmd = add_Command_backend(cmd,func,params, 0, flags);
+ command->tok = NULL;
+ command->cmd->owner = module;
+ if (tok) {
+ command->tok = add_Command_backend(tok,func,params,1,flags);
+ command->cmd->friend = command->tok;
+ command->tok->friend = command->cmd;
+ command->tok->owner = module;
+ }
+ else
+ command->cmd->friend = NULL;
+ if (module) {
+ ModuleObject *cmdobj = (ModuleObject *)MyMallocEx(sizeof(ModuleObject));
+ cmdobj->object.command = command;
+ cmdobj->type = MOBJ_COMMAND;
+ AddListItem(cmdobj, module->objects);
+ module->errorcode = MODERR_NOERROR;
+ }
+ if (flags & M_ANNOUNCE)
+ {
+ char *tmp;
+ if (cmdstr)
+ tmp = MyMallocEx(strlen(cmdstr)+strlen(cmd)+2);
+ else
+ tmp = MyMallocEx(strlen(cmd)+2);
+ if (cmdstr)
+ {
+ strcpy(tmp, cmdstr);
+ strcat(tmp, ",");
+ }
+ strcat(tmp, cmd);
+ if (cmdstr)
+ {
+ IsupportSetValue(IsupportFind("CMDS"), tmp);
+ free(cmdstr);
+ }
+ else
+ IsupportAdd(NULL, "CMDS", tmp);
+ cmdstr = tmp;
+ }
+ return command;
+}
+
+
+void CommandDel(Command *command) {
+ Cmdoverride *ovr, *ovrnext;
+
+ if (command->cmd->flags & M_ANNOUNCE)
+ {
+ char *tmp = MyMallocEx(strlen(cmdstr)+1);
+ char *tok;
+ for (tok = strtok(cmdstr, ","); tok; tok = strtok(NULL, ","))
+ {
+ if (!stricmp(tok, command->cmd->cmd))
+ continue;
+ if (tmp)
+ strcat(tmp, ",");
+ strcat(tmp, tok);
+ }
+ free(cmdstr);
+ if (!*tmp)
+ {
+ IsupportDel(IsupportFind("CMDS"));
+ cmdstr = NULL;
+ }
+ else
+ cmdstr = tmp;
+ }
+ DelListItem(command->cmd, CommandHash[toupper(*command->cmd->cmd)]);
+ if (command->tok)
+ DelListItem(command->tok, TokenHash[*command->tok->cmd]);
+ if (command->cmd->owner) {
+ ModuleObject *cmdobj;
+ for (cmdobj = command->cmd->owner->objects; cmdobj; cmdobj = (ModuleObject *)cmdobj->next) {
+ if (cmdobj->type == MOBJ_COMMAND && cmdobj->object.command == command) {
+ DelListItem(cmdobj,command->cmd->owner->objects);
+ MyFree(cmdobj);
+ break;
+ }
+ }
+ }
+ for (ovr = command->cmd->overriders; ovr; ovr = ovrnext)
+ {
+ ovrnext = ovr->next;
+ CmdoverrideDel(ovr);
+ }
+ MyFree(command->cmd->cmd);
+ MyFree(command->cmd);
+ if (command->tok) {
+ MyFree(command->tok->cmd);
+ MyFree(command->tok);
+ }
+ MyFree(command);
+}
diff --git a/src/api-isupport.c b/src/api-isupport.c
new file mode 100644
index 000000000..613ae2cef
--- /dev/null
+++ b/src/api-isupport.c
@@ -0,0 +1,271 @@
+/************************************************************************
+ * UnrealIRCd - Unreal Internet Relay Chat Daemon - src/api-isupport.c
+ * (c) 2004 Dominick Meglio 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.
+ *
+ * $Id$
+ */
+
+#include "struct.h"
+#include "common.h"
+#include "sys.h"
+#include "numeric.h"
+#include "msg.h"
+#include "channel.h"
+#include "version.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "h.h"
+#include "proto.h"
+
+Isupport *Isupports; /* List of ISUPPORT (005) tokens */
+char *IsupportStrings[5] = {0,0,0,0,0}; /* If we get more than 5 strings, God help us! */
+extern char *cmdstr;
+
+/**
+ * Builds isupport token strings.
+ * Respects both the 13 token limit and the 512 buffer limit.
+ */
+void make_isupportstrings(void)
+{
+ int i;
+ int bufsize = BUFSIZE-HOSTLEN-NICKLEN-39;
+ int tokcnt = 0, len = 0;
+ Isupport *isupport;
+ /* Clear out the old junk */
+ for (i = 0; IsupportStrings[i]; i++)
+ {
+ free(IsupportStrings[i]);
+ IsupportStrings[i] = NULL;
+ }
+
+ i = 0;
+ IsupportStrings[i] = MyMallocEx(bufsize);
+ for (isupport = Isupports; isupport; isupport = isupport->next)
+ {
+ int toklen;
+ /* Just a token */
+ if (!isupport->value)
+ {
+ toklen = strlen(isupport->token);
+ if (tokcnt == 13 || bufsize < len+toklen+1)
+ {
+ tokcnt = 0;
+ len = 0;
+ IsupportStrings[++i] = MyMallocEx(bufsize);
+ }
+ if (IsupportStrings[i][0])
+ {
+ strcat(IsupportStrings[i], " ");
+ toklen++;
+ }
+ strcat(IsupportStrings[i], isupport->token);
+ len += toklen;
+ tokcnt++;
+ }
+ else
+ {
+ toklen = strlen(isupport->token)+strlen(isupport->value)+1;
+ if (tokcnt == 13 || bufsize < len+toklen+1)
+ {
+ tokcnt = 0;
+ len = 0;
+ IsupportStrings[++i] = MyMallocEx(bufsize);
+ }
+ if (IsupportStrings[i][0])
+ {
+ strcat(IsupportStrings[i], " ");
+ toklen++;
+ }
+ strcat(IsupportStrings[i], isupport->token);
+ strcat(IsupportStrings[i], "=");
+ strcat(IsupportStrings[i], isupport->value);
+ len += toklen;
+ tokcnt++;
+ }
+ }
+}
+
+/**
+ * Initializes the builtin isupport tokens.
+ */
+void isupport_init(void)
+{
+ char tmpbuf[512];
+ IsupportAdd(NULL, "EXCEPTS", NULL);
+#ifdef PREFIX_AQ
+ IsupportAdd(NULL, "STATUSMSG", "~&@%+");
+#else
+ IsupportAdd(NULL, "STATUSMSG", "@%+");
+#endif
+ IsupportAdd(NULL, "ELIST", "MNUCT");
+ ircsprintf(tmpbuf, "~,%s", extbanstr);
+ IsupportAdd(NULL, "EXTBAN", tmpbuf);
+ IsupportAdd(NULL, "CASEMAPPING", "ascii");
+ IsupportAdd(NULL, "NETWORK", ircnet005);
+ ircsprintf(tmpbuf, CHPAR1 "%s," CHPAR2 "%s," CHPAR3 "%s," CHPAR4 "%s",
+ EXPAR1, EXPAR2, EXPAR3, EXPAR4);
+ IsupportAdd(NULL, "CHANMODES", tmpbuf);
+ IsupportAdd(NULL, "PREFIX", CHPFIX);
+ IsupportAdd(NULL, "CHANTYPES", "#");
+ IsupportAdd(NULL, "MODES", my_itoa(MAXMODEPARAMS));
+ IsupportAdd(NULL, "SILENCE", my_itoa(SILENCE_LIMIT));
+ IsupportAdd(NULL, "WATCH", my_itoa(MAXWATCH));
+ IsupportAdd(NULL, "WALLCHOPS", NULL);
+ IsupportAdd(NULL, "MAXTARGETS", my_itoa(MAXTARGETS));
+ IsupportAdd(NULL, "AWAYLEN", my_itoa(TOPICLEN));
+ IsupportAdd(NULL, "KICKLEN", my_itoa(TOPICLEN));
+ IsupportAdd(NULL, "TOPICLEN", my_itoa(TOPICLEN));
+ IsupportAdd(NULL, "CHANNELLEN", my_itoa(CHANNELLEN));
+ IsupportAdd(NULL, "NICKLEN", my_itoa(NICKLEN));
+ ircsprintf(tmpbuf, "b:%d,e:%d", MAXBANS, MAXBANS);
+ IsupportAdd(NULL, "MAXLIST", tmpbuf);
+ ircsprintf(tmpbuf, "#:%d", MAXCHANNELSPERUSER);
+ IsupportAdd(NULL, "CHANLIMIT", tmpbuf);
+ IsupportAdd(NULL, "MAXCHANNELS", my_itoa(MAXCHANNELSPERUSER));
+ IsupportAdd(NULL, "HCN", NULL);
+ IsupportAdd(NULL, "SAFELIST", NULL);
+ if (cmdstr)
+ IsupportAdd(NULL, "CMDS", cmdstr);
+}
+
+/**
+ * Sets or changes the value of an existing isupport token.
+ *
+ * @param isupport The pointer to the isupport handle.
+ * @param value The new value of the token (NULL indicates no value).
+ */
+void IsupportSetValue(Isupport *isupport, const char *value)
+{
+ if (isupport->value)
+ free(isupport->value);
+ if (value)
+ isupport->value = strdup(value);
+ else
+ isupport->value = NULL;
+
+ make_isupportstrings();
+}
+
+/**
+ * Returns an isupport handle based on the given token name.
+ *
+ * @param token The isupport token to search for.
+ * @return Returns the handle to the isupport token if it was found,
+ * otherwise NULL is returned.
+ */
+Isupport *IsupportFind(const char *token)
+{
+ Isupport *isupport;
+
+ for (isupport = Isupports; isupport; isupport = isupport->next)
+ {
+ if (!stricmp(token, isupport->token))
+ return isupport;
+ }
+ return NULL;
+}
+
+/**
+ * Adds a new isupport token.
+ *
+ * @param module The module which owns this token.
+ * @param token The name of the token to create.
+ * @param value The value of the token (NULL indicates no value).
+ * @return Returns the handle to the new token if successful, otherwise NULL.
+ * The module's error code contains specific information about the
+ * error.
+ */
+Isupport *IsupportAdd(Module *module, const char *token, const char *value)
+{
+ Isupport *isupport;
+ char *c;
+
+ if (IsupportFind(token))
+ {
+ if (module)
+ module->errorcode = MODERR_EXISTS;
+ return NULL;
+ }
+ /* draft-brocklesby-irc-isupport:
+ * token = a-zA-Z0-9 and 20 or less characters
+ * value = ASCII 0x21 - 0x7E
+ */
+ for (c = (char *)token; c && *c; c++)
+ {
+ if (!isalnum(*c))
+ {
+ if (module)
+ module->errorcode = MODERR_INVALID;
+ return NULL;
+ }
+ }
+ if (!token || !*token || c-token > 20)
+ {
+ if (module)
+ module->errorcode = MODERR_INVALID;
+ return NULL;
+ }
+ for (c = (char *)value; c && *c; c++)
+ {
+ if (*c < '!' || *c > '~')
+ {
+ if (module)
+ module->errorcode = MODERR_INVALID;
+ return NULL;
+ }
+ }
+
+ isupport = MyMallocEx(sizeof(Isupport));
+ isupport->owner = module;
+ isupport->token = strdup(token);
+ if (value)
+ isupport->value = strdup(value);
+ AddListItem(isupport, Isupports);
+ make_isupportstrings();
+ if (module)
+ {
+ ModuleObject *isupportobj = MyMallocEx(sizeof(ModuleObject));
+ isupportobj->object.isupport = isupport;
+ isupportobj->type = MOBJ_ISUPPORT;
+ AddListItem(isupportobj, module->objects);
+ module->errorcode = MODERR_NOERROR;
+ }
+ return isupport;
+}
+
+/**
+ * Removes the specified isupport token.
+ *
+ * @param isupport The token to remove.
+ */
+void IsupportDel(Isupport *isupport)
+{
+ DelListItem(isupport, Isupports);
+ free(isupport->token);
+ if (isupport->value)
+ free(isupport->value);
+ free(isupport);
+ make_isupportstrings();
+}
diff --git a/src/auth.c b/src/auth.c
index 58154e68c..a10370362 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -46,9 +46,7 @@ anAuthStruct MODVAR AuthTypes[] = {
{"crypt", AUTHTYPE_UNIXCRYPT},
{"unixcrypt", AUTHTYPE_UNIXCRYPT},
#endif
-#ifdef AUTHENABLE_MD5
{"md5", AUTHTYPE_MD5},
-#endif
#ifdef AUTHENABLE_SHA1
{"sha1", AUTHTYPE_SHA1},
#endif
@@ -174,6 +172,278 @@ void Auth_DeleteAuthStruct(anAuthStruct *as)
MyFree(as);
}
+/* Both values are pretty insane as of 2004, but... just in case. */
+#define MAXSALTLEN 127
+#define MAXHASHLEN 255
+
+/* RAW salt length (before b64_encode) to use in /MKPASSWD
+ * and REAL salt length (after b64_encode, including terminating nul),
+ * used for reserving memory.
+ */
+#define RAWSALTLEN 6
+#define REALSALTLEN 12
+
+/** Parses a password.
+ * This routine can parse a pass that has a salt (new as of unreal 3.2.1)
+ * and will set the 'salt' pointer and 'hash' accordingly.
+ * RETURN VALUES:
+ * 1 If succeeded, salt and hash can be used.
+ * 0 If it's a password without a salt ('old'), salt and hash are not touched.
+ */
+static int parsepass(char *str, char **salt, char **hash)
+{
+static char saltbuf[MAXSALTLEN+1], hashbuf[MAXHASHLEN+1];
+char *p;
+int max;
+
+ /* Syntax: $$ */
+ if (*str != '$')
+ return 0;
+ p = strchr(str+1, '$');
+ if (!p || (p == str+1) || !p[1])
+ return 0;
+
+ max = p - str;
+ if (max > sizeof(saltbuf))
+ max = sizeof(saltbuf);
+ strlcpy(saltbuf, str+1, max);
+ strlcpy(hashbuf, p+1, sizeof(hashbuf));
+ *salt = saltbuf;
+ *hash = hashbuf;
+ return 1;
+}
+
+static int authcheck_md5(aClient *cptr, anAuthStruct *as, char *para)
+{
+static char buf[512];
+int i, r;
+char *saltstr, *hashstr;
+
+ if (!para)
+ return -1;
+ r = parsepass(as->data, &saltstr, &hashstr);
+ if (r == 0) /* Old method without salt: b64(MD5()) */
+ {
+ char result[16];
+ MD5_CTX hash;
+
+ MD5_Init(&hash);
+ MD5_Update(&hash, para, strlen(para));
+ MD5_Final(result, &hash);
+
+ if ((i = b64_encode(result, sizeof(result), buf, sizeof(buf))))
+ {
+ if (!strcmp(buf, as->data))
+ return 2;
+ else
+ return -1;
+ } else
+ return -1;
+ } else {
+ /* New method with salt: b64(MD5(MD5()+salt)) */
+ char result1[MAXSALTLEN+16+1];
+ char result2[16];
+ char rsalt[MAXSALTLEN+1];
+ MD5_CTX hash;
+ int rsaltlen;
+
+ /* First, decode the salt to something real... */
+ rsaltlen = b64_decode(saltstr, rsalt, sizeof(rsalt));
+ if (rsaltlen <= 0)
+ return -1;
+
+ /* Then hash the password (1st round)... */
+ MD5_Init(&hash);
+ MD5_Update(&hash, para, strlen(para));
+ MD5_Final(result1, &hash);
+
+ /* Add salt to result */
+ memcpy(result1+16, rsalt, rsaltlen); /* b64_decode already made sure bounds are ok */
+
+ /* Then hash it all together again (2nd round)... */
+ MD5_Init(&hash);
+ MD5_Update(&hash, result1, rsaltlen+16);
+ MD5_Final(result2, &hash);
+
+ /* Then base64 encode it all and we are done... */
+ if ((i = b64_encode(result2, sizeof(result2), buf, sizeof(buf))))
+ {
+ if (!strcmp(buf, hashstr))
+ return 2;
+ else
+ return -1;
+ } else
+ return -1;
+ }
+ return -1; /* NOTREACHED */
+}
+
+#ifdef AUTHENABLE_SHA1
+static int authcheck_sha1(aClient *cptr, anAuthStruct *as, char *para)
+{
+char buf[512];
+int i, r;
+char *saltstr, *hashstr;
+
+ if (!para)
+ return -1;
+ r = parsepass(as->data, &saltstr, &hashstr);
+ if (r)
+ {
+ /* New method with salt: b64(SHA1(SHA1()+salt)) */
+ char result1[MAXSALTLEN+20+1];
+ char result2[20];
+ char rsalt[MAXSALTLEN+1];
+ int rsaltlen;
+#ifndef _WIN32
+ SHA_CTX hash;
+#else
+ HCRYPTPROV hProv;
+ HCRYPTHASH hHash;
+ DWORD size = 20;
+#endif
+
+ /* First, decode the salt to something real... */
+ rsaltlen = b64_decode(saltstr, rsalt, sizeof(rsalt));
+ if (rsaltlen <= 0)
+ return -1;
+
+#ifdef _WIN32
+ if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
+ return -1;
+#endif
+
+ /* Then hash the password (1st round)... */
+#ifndef _WIN32
+ SHA1_Init(&hash);
+ SHA1_Update(&hash, para, strlen(para));
+ SHA1_Final(result1, &hash);
+#else
+ if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return NULL;
+ if (!CryptHashData(hHash, para, strlen(para), 0)) return NULL;
+ if (!CryptGetHashParam(hHash, HP_HASHVAL, result1, &size, 0)) return NULL;
+ CryptDestroyHash(hHash);
+#endif
+ /* Add salt to result */
+ memcpy(result1+20, rsalt, rsaltlen); /* b64_decode already made sure bounds are ok */
+
+ /* Then hash it all together again (2nd round)... */
+#ifndef _WIN32
+ SHA1_Init(&hash);
+ SHA1_Update(&hash, result1, rsaltlen+20);
+ SHA1_Final(result2, &hash);
+#else
+ if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return NULL;
+ if (!CryptHashData(hHash, result1, 20+rsaltlen, 0)) return NULL;
+ if (!CryptGetHashParam(hHash, HP_HASHVAL, result2, &size, 0)) return NULL;
+ CryptDestroyHash(hHash);
+ CryptReleaseContext(hProv, 0);
+#endif
+ /* Then base64 encode it all and we are done... */
+ if ((i = b64_encode(result2, sizeof(result2), buf, sizeof(buf))))
+ {
+ if (!strcmp(buf, hashstr))
+ return 2;
+ else
+ return -1;
+ } else
+ return -1;
+ } else {
+ /* OLD auth */
+#ifndef _WIN32
+ if ((i = b64_encode(SHA1(para, strlen(para), NULL), 20, buf, sizeof(buf))))
+ {
+ if (!strcmp(buf, as->data))
+ return 2;
+ else
+ return -1;
+ } else
+ return -1;
+#else
+ HCRYPTPROV hProv;
+ HCRYPTHASH hHash;
+ char buf2[512];
+ DWORD size = 512;
+ if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT))
+ return -1;
+ if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
+ return -1;
+ if (!CryptHashData(hHash, para, strlen(para), 0))
+ return -1;
+ if (!CryptGetHashParam(hHash, HP_HASHVAL, buf, &size, 0))
+ return -1;
+ CryptDestroyHash(hHash);
+ CryptReleaseContext(hProv, 0);
+ b64_encode(buf, 20, buf2, sizeof(buf2));
+ if (!strcmp(buf2, as->data))
+ return 2;
+ else
+ return -1;
+#endif
+ }
+}
+#endif /* AUTHENABLE_SHA1 */
+
+#ifdef AUTHENABLE_RIPEMD160
+static int authcheck_ripemd160(aClient *cptr, anAuthStruct *as, char *para)
+{
+char buf[512];
+int i, r;
+char *saltstr, *hashstr;
+
+ if (!para)
+ return -1;
+ r = parsepass(as->data, &saltstr, &hashstr);
+ if (r)
+ {
+ /* New method with salt: b64(RIPEMD160(RIPEMD160()+salt)) */
+ char result1[MAXSALTLEN+20+1];
+ char result2[20];
+ char rsalt[MAXSALTLEN+1];
+ int rsaltlen;
+ RIPEMD160_CTX hash;
+
+ /* First, decode the salt to something real... */
+ rsaltlen = b64_decode(saltstr, rsalt, sizeof(rsalt));
+ if (rsaltlen <= 0)
+ return -1;
+
+ /* Then hash the password (1st round)... */
+ RIPEMD160_Init(&hash);
+ RIPEMD160_Update(&hash, para, strlen(para));
+ RIPEMD160_Final(result1, &hash);
+ /* Add salt to result */
+ memcpy(result1+20, rsalt, rsaltlen); /* b64_decode already made sure bounds are ok */
+
+ /* Then hash it all together again (2nd round)... */
+ RIPEMD160_Init(&hash);
+ RIPEMD160_Update(&hash, result1, rsaltlen+20);
+ RIPEMD160_Final(result2, &hash);
+ /* Then base64 encode it all and we are done... */
+ if ((i = b64_encode(result2, sizeof(result2), buf, sizeof(buf))))
+ {
+ if (!strcmp(buf, hashstr))
+ return 2;
+ else
+ return -1;
+ } else
+ return -1;
+ } else {
+ /* OLD auth */
+ if ((i = b64_encode(RIPEMD160(para, strlen(para), NULL), 20, buf, sizeof(buf))))
+ {
+ if (!strcmp(buf, as->data))
+ return 2;
+ else
+ return -1;
+ } else
+ return -1;
+ }
+}
+#endif /* AUTHENABLE_RIPEMD160 */
+
+
/*
* cptr MUST be a local client
* as is what it will be compared with
@@ -192,16 +462,13 @@ int Auth_Check(aClient *cptr, anAuthStruct *as, char *para)
#ifdef AUTHENABLE_UNIXCRYPT
extern char *crypt();
#endif
-#if defined(AUTHENABLE_MD5) || defined(AUTHENABLE_SHA1) || defined(AUTHENABLE_RIPEMD160)
- static char buf[512];
- int i;
-#endif
#ifdef AUTHENABLE_SSL_CLIENTCERT
X509 *x509_clientcert = NULL;
X509 *x509_filecert = NULL;
FILE *x509_f = NULL;
#endif
+
if (!as)
return 1;
@@ -229,108 +496,17 @@ int Auth_Check(aClient *cptr, anAuthStruct *as, char *para)
return -1;
break;
#endif
-#ifdef AUTHENABLE_MD5
case AUTHTYPE_MD5:
- if (!para)
- return -1;
-#ifndef _WIN32
- if ((i = b64_encode(MD5(para, strlen(para), NULL),
- MD5_DIGEST_LENGTH, buf, sizeof(buf))))
- {
- if (!strcmp(buf, as->data))
- return 2;
- else
- return -1;
- }
- else
- return -1;
- break;
-#else
- {
- HCRYPTPROV hProv;
- HCRYPTHASH hHash;
- char buf2[512];
- DWORD size = 512;
- if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT))
- return -1;
- if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
- return -1;
- if (!CryptHashData(hHash, para, strlen(para), 0))
- return -1;
- if (!CryptGetHashParam(hHash, HP_HASHVAL, buf, &size, 0))
- return -1;
- CryptDestroyHash(hHash);
- CryptReleaseContext(hProv, 0);
- b64_encode(buf, 16, buf2, sizeof(buf2));
- if (!strcmp(buf2, as->data))
- return 2;
- else
- return -1;
- }
+ return authcheck_md5(cptr, as, para);
break;
-
-#endif
-#endif
#ifdef AUTHENABLE_SHA1
case AUTHTYPE_SHA1:
- if (!para)
- return -1;
-#ifndef _WIN32
-
- if ((i = b64_encode(SHA1(para, strlen(para), NULL),
- SHA_DIGEST_LENGTH, buf, sizeof(buf))))
- {
- if (!strcmp(buf, as->data))
- return 2;
- else
- return -1;
- }
- else
- return -1;
- break;
-#else
- {
- HCRYPTPROV hProv;
- HCRYPTHASH hHash;
- char buf2[512];
- DWORD size = 512;
- if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT))
- return -1;
- if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
- return -1;
- if (!CryptHashData(hHash, para, strlen(para), 0))
- return -1;
- if (!CryptGetHashParam(hHash, HP_HASHVAL, buf, &size, 0))
- return -1;
- CryptDestroyHash(hHash);
- CryptReleaseContext(hProv, 0);
- b64_encode(buf, 20, buf2, sizeof(buf2));
- if (!strcmp(buf2, as->data))
- return 2;
- else
- return -1;
- }
+ return authcheck_sha1(cptr, as, para);
break;
#endif
-#endif
#ifdef AUTHENABLE_RIPEMD160
case AUTHTYPE_RIPEMD160:
- if (!para)
- return -1;
-
- if ((i = b64_encode(RIPEMD160(para, strlen(para), NULL),
- RIPEMD160_DIGEST_LENGTH, buf, sizeof(buf))))
- {
- if (!strcmp(buf, as->data))
- return 2;
- else
- return -1;
- }
- else
- return -1;
- break;
+ return authcheck_ripemd160(cptr, as, para);
#endif
#ifdef AUTHENABLE_SSL_CLIENTCERT
case AUTHTYPE_SSL_CLIENTCERT:
@@ -367,19 +543,202 @@ int Auth_Check(aClient *cptr, anAuthStruct *as, char *para)
return -1;
}
+static char *mkpass_md5(char *para)
+{
+static char buf[128];
+char result1[16+REALSALTLEN];
+char result2[16];
+char saltstr[REALSALTLEN]; /* b64 encoded printable string*/
+char saltraw[RAWSALTLEN]; /* raw binary */
+char xresult[64];
+MD5_CTX hash;
+int i;
+
+ if (!para) return NULL;
+
+ /* generate a random salt... */
+ for (i=0; i < RAWSALTLEN; i++)
+ saltraw[i] = getrandom8();
+
+ i = b64_encode(saltraw, RAWSALTLEN, saltstr, REALSALTLEN);
+ if (!i) return NULL;
+
+ /* b64(MD5(MD5()+salt))
+ * ^^^^^^^^^^^
+ * step 1
+ * ^^^^^^^^^^^^^^^^^^^^^
+ * step 2
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * step 3
+ */
+
+ /* STEP 1 */
+ MD5_Init(&hash);
+ MD5_Update(&hash, para, strlen(para));
+ MD5_Final(result1, &hash);
+
+ /* STEP 2 */
+ /* add salt to result */
+ memcpy(result1+16, saltraw, RAWSALTLEN);
+ /* Then hash it all together */
+ MD5_Init(&hash);
+ MD5_Update(&hash, result1, RAWSALTLEN+16);
+ MD5_Final(result2, &hash);
+
+ /* STEP 3 */
+ /* Then base64 encode it all together.. */
+ i = b64_encode(result2, sizeof(result2), xresult, sizeof(xresult));
+ if (!i) return NULL;
+
+ /* Good.. now create the whole string:
+ * $$
+ */
+ ircsprintf(buf, "$%s$%s", saltstr, xresult);
+ return buf;
+}
+
+#ifdef AUTHENABLE_SHA1
+static char *mkpass_sha1(char *para)
+{
+static char buf[128];
+char result1[20+REALSALTLEN];
+char result2[20];
+char saltstr[REALSALTLEN]; /* b64 encoded printable string*/
+char saltraw[RAWSALTLEN]; /* raw binary */
+char xresult[64];
+#ifndef _WIN32
+SHA_CTX hash;
+#else
+HCRYPTPROV hProv;
+HCRYPTHASH hHash;
+DWORD size = 20;
+#endif
+int i;
+
+ if (!para) return NULL;
+
+ /* generate a random salt... */
+ for (i=0; i < RAWSALTLEN; i++)
+ saltraw[i] = getrandom8();
+
+ i = b64_encode(saltraw, RAWSALTLEN, saltstr, REALSALTLEN);
+ if (!i) return NULL;
+
+#ifdef _WIN32
+ if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
+ return NULL;
+#endif
+
+ /* b64(SHA1(SHA1()+salt))
+ * ^^^^^^^^^^^
+ * step 1
+ * ^^^^^^^^^^^^^^^^^^^^^
+ * step 2
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * step 3
+ */
+
+ /* STEP 1 */
+#ifndef _WIN32
+ SHA1_Init(&hash);
+ SHA1_Update(&hash, para, strlen(para));
+ SHA1_Final(result1, &hash);
+#else
+ if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return NULL;
+ if (!CryptHashData(hHash, para, strlen(para), 0)) return NULL;
+ if (!CryptGetHashParam(hHash, HP_HASHVAL, result1, &size, 0)) return NULL;
+ CryptDestroyHash(hHash);
+#endif
+ /* STEP 2 */
+ /* add salt to result */
+ memcpy(result1+20, saltraw, RAWSALTLEN);
+ /* Then hash it all together */
+#ifndef _WIN32
+ SHA1_Init(&hash);
+ SHA1_Update(&hash, result1, RAWSALTLEN+20);
+ SHA1_Final(result2, &hash);
+#else
+ if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return NULL;
+ if (!CryptHashData(hHash, result1, RAWSALTLEN+20, 0)) return NULL;
+ if (!CryptGetHashParam(hHash, HP_HASHVAL, result2, &size, 0)) return NULL;
+ CryptDestroyHash(hHash);
+ CryptReleaseContext(hProv, 0);
+#endif
+ /* STEP 3 */
+ /* Then base64 encode it all together.. */
+ i = b64_encode(result2, sizeof(result2), xresult, sizeof(xresult));
+ if (!i) return NULL;
+
+ /* Good.. now create the whole string:
+ * $$
+ */
+ ircsprintf(buf, "$%s$%s", saltstr, xresult);
+ return buf;
+}
+#endif /* AUTHENABLE_SHA1 */
+
+#ifdef AUTHENABLE_RIPEMD160
+static char *mkpass_ripemd160(char *para)
+{
+static char buf[128];
+char result1[20+REALSALTLEN];
+char result2[20];
+char saltstr[REALSALTLEN]; /* b64 encoded printable string*/
+char saltraw[RAWSALTLEN]; /* raw binary */
+char xresult[64];
+RIPEMD160_CTX hash;
+int i;
+
+ if (!para) return NULL;
+
+ /* generate a random salt... */
+ for (i=0; i < RAWSALTLEN; i++)
+ saltraw[i] = getrandom8();
+
+ i = b64_encode(saltraw, RAWSALTLEN, saltstr, REALSALTLEN);
+ if (!i) return NULL;
+
+ /* b64(RIPEMD160(RIPEMD160()+salt))
+ * ^^^^^^^^^^^
+ * step 1
+ * ^^^^^^^^^^^^^^^^^^^^^
+ * step 2
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * step 3
+ */
+
+ /* STEP 1 */
+ RIPEMD160_Init(&hash);
+ RIPEMD160_Update(&hash, para, strlen(para));
+ RIPEMD160_Final(result1, &hash);
+
+ /* STEP 2 */
+ /* add salt to result */
+ memcpy(result1+20, saltraw, RAWSALTLEN);
+ /* Then hash it all together */
+ RIPEMD160_Init(&hash);
+ RIPEMD160_Update(&hash, result1, RAWSALTLEN+20);
+ RIPEMD160_Final(result2, &hash);
+
+ /* STEP 3 */
+ /* Then base64 encode it all together.. */
+ i = b64_encode(result2, sizeof(result2), xresult, sizeof(xresult));
+ if (!i) return NULL;
+
+ /* Good.. now create the whole string:
+ * $$
+ */
+ ircsprintf(buf, "$%s$%s", saltstr, xresult);
+ return buf;
+}
+#endif /* AUTHENABLE_RIPEMD160 */
+
char *Auth_Make(short type, char *para)
{
#ifdef AUTHENABLE_UNIXCRYPT
char salt[3];
extern char *crypt();
#endif
-#if defined(AUTHENABLE_MD5) || defined(AUTHENABLE_SHA1) || defined(AUTHENABLE_RIPEMD160)
- static char buf[512];
- int i;
-#endif
-#ifdef _WIN32
- static char buf2[512];
-#endif
switch (type)
{
@@ -397,92 +756,20 @@ char *Auth_Make(short type, char *para)
return(crypt(para, salt));
break;
#endif
-#ifdef AUTHENABLE_MD5
+
case AUTHTYPE_MD5:
- if (!para)
- return NULL;
-#ifndef _WIN32
-
- if ((i = b64_encode(MD5(para, strlen(para), NULL),
- MD5_DIGEST_LENGTH, buf, sizeof(buf))))
- {
- return (buf);
- }
- else
- return NULL;
- break;
-#else
- {
- HCRYPTPROV hProv;
- HCRYPTHASH hHash;
- DWORD size = 512;
- if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT))
- return NULL;
- if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
- return NULL;
- if (!CryptHashData(hHash, para, strlen(para), 0))
- return NULL;
- if (!CryptGetHashParam(hHash, HP_HASHVAL, buf, &size, 0))
- return NULL;
- CryptDestroyHash(hHash);
- CryptReleaseContext(hProv, 0);
- b64_encode(buf, 16, buf2, sizeof(buf2));
- return (buf2);
- }
- break;
-#endif
-#endif
+ return mkpass_md5(para);
+
#ifdef AUTHENABLE_SHA1
case AUTHTYPE_SHA1:
- if (!para)
- return NULL;
-#ifndef _WIN32
- if ((i = b64_encode(SHA1(para, strlen(para), NULL),
- SHA_DIGEST_LENGTH, buf, sizeof(buf))))
- {
- return (buf);
- }
- else
- return NULL;
- break;
-#else
- {
- HCRYPTPROV hProv;
- HCRYPTHASH hHash;
- DWORD size = 512;
- if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT))
- return NULL;
- if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
- return NULL;
- if (!CryptHashData(hHash, para, strlen(para), 0))
- return NULL;
- if (!CryptGetHashParam(hHash, HP_HASHVAL, buf, &size, 0))
- return NULL;
- CryptDestroyHash(hHash);
- CryptReleaseContext(hProv, 0);
- b64_encode(buf, 20, buf2, sizeof(buf2));
- return (buf2);
- }
- break;
+ return mkpass_sha1(para);
#endif
-#endif
#ifdef AUTHENABLE_RIPEMD160
case AUTHTYPE_RIPEMD160:
- if (!para)
- return NULL;
-
- if ((i = b64_encode(RIPEMD160(para, strlen(para), NULL),
- RIPEMD160_DIGEST_LENGTH, buf, sizeof(buf))))
- {
- return (buf);
- }
- else
- return NULL;
- break;
+ return mkpass_ripemd160(para);
#endif
+
default:
return (NULL);
}
diff --git a/src/badwords.c b/src/badwords.c
index 26d580099..19f1f3a06 100644
--- a/src/badwords.c
+++ b/src/badwords.c
@@ -185,7 +185,7 @@ char *stripbadwords(char *str, ConfigItem_badword *start_bw, int *blocked)
static char cleanstr[4096];
char buf[4096];
char *ptr;
- int matchlen, stringlen, cleaned;
+ int matchlen, m, stringlen, cleaned;
ConfigItem_badword *this_word;
*blocked = 0;
@@ -244,8 +244,11 @@ char *stripbadwords(char *str, ConfigItem_badword *start_bw, int *blocked)
{
if (pmatch[0].rm_so == -1)
break;
+ m = pmatch[0].rm_eo - pmatch[0].rm_so;
+ if (m == 0)
+ break; /* anti-loop */
cleaned = 1;
- matchlen += pmatch[0].rm_eo - pmatch[0].rm_so;
+ matchlen += m;
strlncat(buf, ptr, sizeof buf, pmatch[0].rm_so);
if (this_word->replace)
strlcat(buf, this_word->replace, sizeof buf);
diff --git a/src/channel.c b/src/channel.c
index 57962f92f..f525965a4 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -582,7 +582,7 @@ Ban *is_banned(aClient *sptr, aChannel *chptr, int type)
if (MyConnect(sptr)) {
mine = 1;
- s = make_nick_user_host(sptr->name, sptr->user->username, sptr->sockhost);
+ s = make_nick_user_host(sptr->name, sptr->user->username, GetIP(sptr));
strlcpy(nuip, s, sizeof nuip);
ban_ip = nuip;
}
@@ -864,8 +864,7 @@ int can_send(aClient *cptr, aChannel *chptr, char *msgtext, int notice)
(!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);
+ sendto_chmodemucrap(cptr, chptr, msgtext);
return (CANNOT_SEND_MODERATED);
}
}
@@ -2975,14 +2974,17 @@ void set_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[], u_int *pco
}
#endif
}
- if (found == 0)
+ if (found == 0) /* Mode char unknown */
{
- if (!MyClient(cptr))
- break;
- /* don't flood other servers */
- sendto_one(cptr,
- err_str(ERR_UNKNOWNMODE),
- me.name, cptr->name, *curchr);
+ /* temporary hack: eat parameters of certain future chanmodes.. */
+ if (*curchr == 'I')
+ paracount++;
+ if ((*curchr == 'j') && (what == MODE_ADD))
+ paracount++;
+
+ if (MyClient(cptr))
+ sendto_one(cptr, err_str(ERR_UNKNOWNMODE),
+ me.name, cptr->name, *curchr);
break;
}
@@ -3703,6 +3705,8 @@ void join_channel(aChannel *chptr, aClient *cptr, aClient *sptr, int flags)
parv[1] = chptr->chname;
(void)m_names(cptr, sptr, 2, parv);
RunHook4(HOOKTYPE_LOCAL_JOIN, cptr, sptr,chptr,parv);
+ } else {
+ RunHook4(HOOKTYPE_REMOTE_JOIN, cptr, sptr, chptr, parv); /* (rarely used) */
}
#ifdef NEWCHFLOODPROT
@@ -4130,6 +4134,8 @@ CMD_FUNC(m_part)
}
if (MyClient(sptr))
RunHook4(HOOKTYPE_LOCAL_PART, cptr, sptr, chptr, comment);
+ else
+ RunHook4(HOOKTYPE_REMOTE_PART, cptr, sptr, chptr, comment);
remove_user_from_channel(sptr, chptr);
}
diff --git a/src/cloak.c b/src/cloak.c
index 4fadc4731..d0dfab785 100644
--- a/src/cloak.c
+++ b/src/cloak.c
@@ -157,8 +157,8 @@ char host[256], *mask, *x, *p, *q;
if (!curr)
return NULL;
- strlcpy(host, curr, sizeof(curr));
- for (p = curr, q = host; *p; p++, q++)
+ /* Convert host to lowercase and cut off at 255 bytes just to be sure */
+ for (p = curr, q = host; *p && (q < host+sizeof(host)-1); p++, q++)
*q = tolower(*p);
*q = '\0';
diff --git a/src/extbans.c b/src/extbans.c
index ebc11c72a..d4205701d 100644
--- a/src/extbans.c
+++ b/src/extbans.c
@@ -76,6 +76,7 @@ Extban *ExtbanAdd(Module *module, ExtbanInfo req)
{
Extban *tmp;
int slot;
+char tmpbuf[512];
if (findmod_by_bantype(req.flag))
{
@@ -108,12 +109,18 @@ int slot;
module->errorcode = MODERR_NOERROR;
}
ExtBan_highest = slot;
- make_extbanstr();
+ if (loop.ircd_booted)
+ {
+ make_extbanstr();
+ ircsprintf(tmpbuf, "~,%s", extbanstr);
+ IsupportSetValue(IsupportFind("EXTBAN"), tmpbuf);
+ }
return &ExtBan_Table[slot];
}
void ExtbanDel(Extban *eb)
{
+char tmpbuf[512];
/* Just zero it all away.. */
if (eb->owner)
@@ -131,6 +138,8 @@ void ExtbanDel(Extban *eb)
}
memset(eb, 0, sizeof(Extban));
make_extbanstr();
+ ircsprintf(tmpbuf, "~,%s", extbanstr);
+ IsupportSetValue(IsupportFind("EXTBAN"), tmpbuf);
/* Hmm do we want to go trough all chans and remove the bans?
* I would say 'no' because perhaps we are just reloading,
* and else.. well... screw them?
@@ -195,6 +204,9 @@ char *ban = banin + 3;
if (type != BANCHK_NICK)
return 0;
+
+ if (has_voice(sptr, chptr))
+ return 0;
if ((ban_realhost && !match(ban, ban_realhost)) ||
(ban_virthost && !match(ban, ban_virthost)) ||
diff --git a/src/extcmodes.c b/src/extcmodes.c
index 03eba2438..0a4ce5056 100644
--- a/src/extcmodes.c
+++ b/src/extcmodes.c
@@ -115,6 +115,7 @@ void extcmode_init(void)
Cmode *CmodeAdd(Module *reserved, CmodeInfo req, Cmode_t *mode)
{
short i = 0, j = 0;
+ char tmpbuf[512];
while (i < EXTCMODETABLESZ)
{
@@ -150,21 +151,31 @@ Cmode *CmodeAdd(Module *reserved, CmodeInfo req, Cmode_t *mode)
if (Channelmode_Table[j].flag)
if (j > Channelmode_highest)
Channelmode_highest = j;
- make_cmodestr();
- make_extcmodestr();
if (reserved)
reserved->errorcode = MODERR_NOERROR;
+ if (loop.ircd_booted)
+ {
+ make_cmodestr();
+ make_extcmodestr();
+ ircsprintf(tmpbuf, CHPAR1 "%s," CHPAR2 "%s," CHPAR3 "%s," CHPAR4 "%s",
+ EXPAR1, EXPAR2, EXPAR3, EXPAR4);
+ IsupportSetValue(IsupportFind("CHANMODES"), tmpbuf);
+ }
return &(Channelmode_Table[i]);
}
void CmodeDel(Cmode *cmode)
{
+ char tmpbuf[512];
/* TODO: remove from all channel */
if (cmode)
cmode->flag = '\0';
make_cmodestr();
make_extcmodestr();
/* Not unloadable, so module object support is not needed (yet) */
+ ircsprintf(tmpbuf, CHPAR1 "%s," CHPAR2 "%s," CHPAR3 "%s," CHPAR4 "%s",
+ EXPAR1, EXPAR2, EXPAR3, EXPAR4);
+ IsupportSetValue(IsupportFind("CHANMODES"), tmpbuf);
}
/** searches in chptr extmode parameters and returns entry or NULL. */
diff --git a/src/ircd.c b/src/ircd.c
index 516db2bb8..af6288085 100644
--- a/src/ircd.c
+++ b/src/ircd.c
@@ -604,6 +604,17 @@ extern TS check_pings(TS currenttime)
}
}
+ /* Do spamfilter 'user' banchecks.. */
+ if (loop.do_bancheck_spamf_user && IsPerson(cptr))
+ {
+ if (find_spamfilter_user(cptr) == FLUSH_BUFFER)
+ continue;
+ }
+ if (loop.do_bancheck_spamf_away && IsPerson(cptr) && cptr->user->away)
+ {
+ if (dospamfilter(cptr, cptr->user->away, SPAMF_AWAY, NULL) == FLUSH_BUFFER)
+ continue;
+ }
/*
* We go into ping phase
*/
@@ -725,8 +736,7 @@ extern TS check_pings(TS currenttime)
* * - lucas
* *
*/
- if (loop.do_bancheck)
- loop.do_bancheck = 0;
+ loop.do_bancheck = loop.do_bancheck_spamf_user = loop.do_bancheck_spamf_away = 0;
Debug((DEBUG_NOTICE, "Next check_ping() call at: %s, %d %d %d",
myctime(currenttime+9), ping, currenttime+9, currenttime));
@@ -1253,6 +1263,8 @@ int InitwIRCD(int argc, char *argv[])
#ifdef EXTCMODE
make_extcmodestr();
#endif
+ make_extbanstr();
+ isupport_init();
if (!find_Command_simple("AWAY") /*|| !find_Command_simple("KILL") ||
!find_Command_simple("OPER") || !find_Command_simple("PING")*/)
{
diff --git a/src/ircsprintf.c b/src/ircsprintf.c
index ee400f352..23a961241 100644
--- a/src/ircsprintf.c
+++ b/src/ircsprintf.c
@@ -305,28 +305,6 @@ char *ircvsprintf(char *str, const char *format, va_list vl)
*str++ = '0';
continue;
}
- if (v1 < 6L)
- switch (v1)
- {
- case 0L:
- *str++ = '0';
- continue;
- case 1L:
- *str++ = '1';
- continue;
- case 2L:
- *str++ = '1';
- continue;
- case 3L:
- *str++ = '1';
- continue;
- case 4L:
- *str++ = '1';
- continue;
- case 5L:
- *str++ = '1';
- continue;
- }
if (v1 > 999999999L)
{
v2 = v1 / 1000000000;
diff --git a/src/md5.c b/src/md5.c
index 586de0c26..05949ca17 100644
--- a/src/md5.c
+++ b/src/md5.c
@@ -15,6 +15,7 @@
* and avoid compile-time configuration.
*/
+#include "config.h"
#if !defined(USE_SSL)
#include
diff --git a/src/modules.c b/src/modules.c
index b6ad47c23..ee4ceda57 100644
--- a/src/modules.c
+++ b/src/modules.c
@@ -61,6 +61,7 @@ Callback *Callbacks[MAXCALLBACKS]; /* Callback objects for modules, used for reh
Callback *RCallbacks[MAXCALLBACKS]; /* 'Real' callback function, used for callback function calls */
MODVAR Module *Modules = NULL;
MODVAR Versionflag *Versionflags = NULL;
+
int Module_Depend_Resolve(Module *p);
Module *Module_make(ModuleHeader *header,
#ifdef _WIN32
@@ -459,6 +460,9 @@ void Unload_all_loaded_modules(void)
else if (objs->type == MOBJ_CALLBACK) {
CallbackDel(objs->object.callback);
}
+ else if (objs->type == MOBJ_ISUPPORT) {
+ IsupportDel(objs->object.isupport);
+ }
}
for (child = mi->children; child; child = childnext)
{
@@ -519,6 +523,9 @@ void Unload_all_testing_modules(void)
else if (objs->type == MOBJ_CALLBACK) {
CallbackDel(objs->object.callback);
}
+ else if (objs->type == MOBJ_ISUPPORT) {
+ IsupportDel(objs->object.isupport);
+ }
}
for (child = mi->children; child; child = childnext)
{
@@ -585,6 +592,10 @@ int Module_free(Module *mod)
else if (objs->type == MOBJ_CALLBACK) {
CallbackDel(objs->object.callback);
}
+ else if (objs->type == MOBJ_ISUPPORT) {
+ IsupportDel(objs->object.isupport);
+ }
+
}
for (p = Modules; p; p = p->next)
{
@@ -1317,11 +1328,15 @@ static const char *module_error_str[] = {
"No error",
"Object already exists",
"No space available",
- "Invalid parameter(s)"
+ "Invalid parameter(s)",
+ "Object was not found"
};
const char *ModuleGetErrorStr(Module *module)
{
+ if (module->errorcode >= sizeof(module_error_str)/sizeof(module_error_str[0]))
+ return NULL;
+
return module_error_str[module->errorcode];
}
diff --git a/src/modules/Makefile.in b/src/modules/Makefile.in
index 59c3e3683..62e12dcdd 100644
--- a/src/modules/Makefile.in
+++ b/src/modules/Makefile.in
@@ -18,18 +18,22 @@
#*
#* $Id$
#*/
+# major edit from fez - to compile objects individually...
INCLUDES = ../include/struct.h ../include/config.h \
../include/sys.h ../include/common.h ../include/version.h \
../include/h.h ../include/numeric.h ../include/msg.h \
../include/dynconf.h ../include/modules.h ../include/setup.h
-R_MODULES=m_sethost.so m_chghost.so m_chgident.so m_setname.so \
- m_setident.so m_sdesc.so m_svsmode.so m_swhois.so\
- m_svsmotd.so m_svsnline.so m_who.so m_mkpasswd.so \
- m_away.so m_svsnoop.so m_svso.so m_svsnick.so \
+#just changing this to cloak.so oldcloak.so could be a ./Config option...
+#R_MODULES=cloak.so oldcloak.so
+R_MODULES= \
+ m_sethost.so m_chghost.so m_chgident.so m_setname.so \
+ m_setident.so m_sdesc.so m_svsmode.so m_swhois.so\
+ m_svsmotd.so m_svsnline.so m_who.so m_mkpasswd.so \
+ m_away.so m_svsnoop.so m_svso.so m_svsnick.so \
m_adminchat.so m_akill.so m_chgname.so m_guest.so m_htm.so m_kill.so \
- m_lag.so m_message.so m_nachat.so m_oper.so m_pingpong.so \
+ m_lag.so m_message.so m_nachat.so m_oper.so m_pingpong.so \
m_quit.so m_rakill.so m_rping.so m_sendumode.so m_sqline.so \
m_tsctl.so m_unkline.so m_unsqline.so m_unzline.so m_whois.so \
m_tkl.so m_vhost.so m_cycle.so m_svsjoin.so m_svspart.so \
@@ -42,26 +46,27 @@ R_MODULES=m_sethost.so m_chghost.so m_chgident.so m_setname.so \
m_trace.so m_netinfo.so m_links.so m_help.so m_rules.so \
m_close.so m_map.so m_eos.so m_server.so m_stats.so \
m_svsfline.so m_dccdeny.so m_undccdeny.so m_whowas.so \
- m_connect.so cloak.so oldcloak.so m_dccallow.so
+ m_connect.so m_dccallow.so m_userip.so cloak.so oldcloak.so
-COMMANDS=m_sethost.c m_chghost.c m_chgident.c m_setname.c m_setident.c \
- m_sdesc.c m_svsmode.c m_swhois.c m_svsmotd.c m_svsnline.c \
- m_who.c m_mkpasswd.c m_away.c m_svsnoop.c m_svso.c m_svsnick.c \
- m_adminchat.c m_akill.c m_chgname.c m_guest.c m_htm.c m_kill.c \
- m_lag.c m_message.c m_nachat.c m_oper.c m_pingpong.c \
- m_quit.c m_rakill.c m_rping.c m_sendumode.c m_sqline.c \
- m_tsctl.c m_unkline.c m_unsqline.c m_unzline.c m_whois.c \
- m_tkl.c m_vhost.c m_cycle.c m_svsjoin.c m_svspart.c \
- m_svslusers.c m_svswatch.c m_svssilence.c m_sendsno.c \
- m_svssno.c m_sajoin.c m_sapart.c m_samode.c m_kick.c m_topic.c \
- m_invite.c m_list.c m_time.c m_svskill.c m_sjoin.c \
- m_pass.c m_userhost.c m_ison.c m_silence.c m_knock.c m_umode2.c \
- m_squit.c m_protoctl.c m_addline.c m_addmotd.c m_addomotd.c \
- m_wallops.c m_admin.c m_globops.c m_locops.c m_chatops.c \
- m_trace.c m_netinfo.c m_links.c m_help.c m_rules.c \
- m_close.c m_map.c m_eos.c m_server.c m_stats.c \
- m_svsfline.c m_dccdeny.c m_undccdeny.c m_whowas.c \
- m_connect.c m_dccallow.c
+#note change of .c to .o
+COMMANDS=m_sethost.o m_chghost.o m_chgident.o m_setname.o m_setident.o \
+ m_sdesc.o m_svsmode.o m_swhois.o m_svsmotd.o m_svsnline.o \
+ m_who.o m_mkpasswd.o m_away.o m_svsnoop.o m_svso.o m_svsnick.o \
+ m_adminchat.o m_akill.o m_chgname.o m_guest.o m_htm.o m_kill.o \
+ m_lag.o m_message.o m_nachat.o m_oper.o m_pingpong.o \
+ m_quit.o m_rakill.o m_rping.o m_sendumode.o m_sqline.o \
+ m_tsctl.o m_unkline.o m_unsqline.o m_unzline.o m_whois.o \
+ m_tkl.o m_vhost.o m_cycle.o m_svsjoin.o m_svspart.o \
+ m_svslusers.o m_svswatch.o m_svssilence.o m_sendsno.o \
+ m_svssno.o m_sajoin.o m_sapart.o m_samode.o m_kick.o m_topic.o \
+ m_invite.o m_list.o m_time.o m_svskill.o m_sjoin.o \
+ m_pass.o m_userhost.o m_ison.o m_silence.o m_knock.o m_umode2.o \
+ m_squit.o m_protoctl.o m_addline.o m_addmotd.o m_addomotd.o \
+ m_wallops.o m_admin.o m_globops.o m_locops.o m_chatops.o \
+ m_trace.o m_netinfo.o m_links.o m_help.o m_rules.o \
+ m_close.o m_map.o m_eos.o m_server.o m_stats.o \
+ m_svsfline.o m_dccdeny.o m_undccdeny.o m_whowas.o \
+ m_connect.o m_dccallow.o m_userip.o
MODULES=commands.so $(R_MODULES)
@@ -79,6 +84,284 @@ commands.so: l_commands.c $(COMMANDS) $(INCLUDES)
$(CC) $(CFLAGS) $(MODULEFLAGS) -o commands.so l_commands.c \
$(COMMANDS)
+#############################################################################
+# commands.so's .o's section
+#############################################################################
+
+m_adminchat.o: m_adminchat.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_adminchat.c
+
+m_akill.o: m_akill.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_akill.c
+
+m_chgname.o: m_chgname.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_chgname.c
+
+m_guest.o: m_guest.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_guest.c
+
+m_htm.o: m_htm.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_htm.c
+
+m_kill.o: m_kill.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_kill.c
+
+m_lag.o: m_lag.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_lag.c
+
+m_message.o: m_message.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_message.c
+
+m_nachat.o: m_nachat.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_nachat.c
+
+m_oper.o: m_oper.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_oper.c
+
+m_pingpong.o: m_pingpong.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_pingpong.c
+
+m_quit.o: m_quit.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_quit.c
+
+m_rakill.o: m_rakill.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_rakill.c
+
+m_rping.o: m_rping.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_rping.c
+
+m_sendumode.o: m_sendumode.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_sendumode.c
+
+m_sqline.o: m_sqline.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_sqline.c
+
+m_tsctl.o: m_tsctl.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_tsctl.c
+
+m_unkline.o: m_unkline.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_unkline.c
+
+m_unsqline.o: m_unsqline.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_unsqline.c
+
+m_unzline.o: m_unzline.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_unzline.c
+
+m_whois.o: m_whois.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_whois.c
+
+m_sethost.o: m_sethost.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_sethost.c
+
+m_chghost.o: m_chghost.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_chghost.c
+
+m_chgident.o: m_chgident.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_chgident.c
+
+m_setident.o: m_setident.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_setident.c
+
+m_setname.o: m_setname.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_setname.c
+
+m_sdesc.o: m_sdesc.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_sdesc.c
+
+m_svsmode.o: m_svsmode.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_svsmode.c
+
+m_swhois.o: m_swhois.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_swhois.c
+
+m_svsmotd.o: m_svsmotd.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_svsmotd.c
+
+m_svsnline.o: m_svsnline.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_svsnline.c
+
+m_who.o: m_who.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_who.c
+
+m_mkpasswd.o: m_mkpasswd.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_mkpasswd.c
+
+m_away.o: m_away.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_away.c
+
+m_svsnoop.o: m_svsnoop.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_svsnoop.c
+
+m_svso.o: m_svso.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_svso.c
+
+m_svsnick.o: m_svsnick.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_svsnick.c
+
+m_tkl.o: m_tkl.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_tkl.c
+
+m_vhost.o: m_vhost.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_vhost.c
+
+m_cycle.o: m_cycle.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_cycle.c
+
+m_svsjoin.o: m_svsjoin.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_svsjoin.c
+
+m_svspart.o: m_svspart.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_svspart.c
+
+m_svslusers.o: m_svslusers.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_svslusers.c
+
+m_svswatch.o: m_svswatch.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_svswatch.c
+
+m_svssilence.o: m_svssilence.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_svssilence.c
+
+m_sendsno.o: m_sendsno.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_sendsno.c
+
+m_svssno.o: m_svssno.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_svssno.c
+
+m_sajoin.o: m_sajoin.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_sajoin.c
+
+m_sapart.o: m_sapart.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_sapart.c
+
+m_samode.o: m_samode.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_samode.c
+
+m_kick.o: m_kick.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_kick.c
+
+m_topic.o: m_topic.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_topic.c
+
+m_invite.o: m_invite.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_invite.c
+
+m_list.o: m_list.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_list.c
+
+m_time.o: m_time.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_time.c
+
+m_svskill.o: m_svskill.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_svskill.c
+
+m_sjoin.o: m_sjoin.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_sjoin.c
+
+m_pass.o: m_pass.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_pass.c
+
+m_userhost.o: m_userhost.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_userhost.c
+
+m_ison.o: m_ison.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_ison.c
+
+m_silence.o: m_silence.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_silence.c
+
+m_knock.o: m_knock.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_knock.c
+
+m_umode2.o: m_umode2.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_umode2.c
+
+m_squit.o: m_squit.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_squit.c
+
+m_protoctl.o: m_protoctl.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_protoctl.c
+
+m_addline.o: m_addline.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_addline.c
+
+m_addmotd.o: m_addmotd.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_addmotd.c
+
+m_addomotd.o: m_addomotd.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_addomotd.c
+
+m_wallops.o: m_wallops.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_wallops.c
+
+m_admin.o: m_admin.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_admin.c
+
+m_globops.o: m_globops.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_globops.c
+
+m_locops.o: m_locops.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_locops.c
+
+m_chatops.o: m_chatops.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_chatops.c
+
+m_trace.o: m_trace.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_trace.c
+
+m_netinfo.o: m_netinfo.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_netinfo.c
+
+m_links.o: m_links.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_links.c
+
+m_help.o: m_help.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_help.c
+
+m_rules.o: m_rules.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_rules.c
+
+m_close.o: m_close.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_close.c
+
+m_map.o: m_map.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_map.c
+
+m_eos.o: m_eos.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_eos.c
+
+m_server.o: m_server.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_server.c
+
+m_stats.o: m_stats.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_stats.c
+
+m_svsfline.o: m_svsfline.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_svsfline.c
+
+m_dccdeny.o: m_dccdeny.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_dccdeny.c
+
+m_undccdeny.o: m_undccdeny.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_undccdeny.c
+
+m_whowas.o: m_whowas.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_whowas.c
+
+m_connect.o: m_connect.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_connect.c
+
+m_dccallow.o: m_dccallow.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_dccallow.c
+
+m_userip.o: m_userip.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_userip.c
+
+#############################################################################
+# .so's section
+#############################################################################
+
m_adminchat.so: m_adminchat.c $(INCLUDES)
$(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \
-o m_adminchat.so m_adminchat.c
@@ -435,6 +718,13 @@ m_dccallow.so: m_dccallow.c $(INCLUDES)
$(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \
-o m_dccallow.so m_dccallow.c
+m_userip.so: m_userip.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(MODULEFLAGS) -c m_userip.c
+
+#############################################################################
+# and now the remaining modules...
+#############################################################################
+
cloak.so: cloak.c $(INCLUDES)
$(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \
-o cloak.so cloak.c
@@ -445,3 +735,5 @@ oldcloak.so: oldcloak.c $(INCLUDES)
clean:
$(RM) -f *.o *.so *~ core
+
+
diff --git a/src/modules/cloak.c b/src/modules/cloak.c
index 683470a6f..cd462c197 100644
--- a/src/modules/cloak.c
+++ b/src/modules/cloak.c
@@ -107,6 +107,12 @@ DLLFUNC int MOD_LOAD(cloak)(int module_load)
DLLFUNC int MOD_UNLOAD(cloak)(int module_unload)
{
+ if (cloak_key1)
+ {
+ MyFree(cloak_key1);
+ MyFree(cloak_key2);
+ MyFree(cloak_key3);
+ }
return MOD_SUCCESS;
}
diff --git a/src/modules/l_commands.c b/src/modules/l_commands.c
index 228246271..9cc537bc3 100644
--- a/src/modules/l_commands.c
+++ b/src/modules/l_commands.c
@@ -88,7 +88,7 @@ extern int m_lag_Init(ModuleInfo *modinfo), m_rping_Init(ModuleInfo *modinfo), m
extern int m_tsctl_Init(ModuleInfo *modinfo), m_htm_Init(ModuleInfo *modinfo), m_chgname_Init(ModuleInfo *modinfo);
extern int m_message_Init(ModuleInfo *modinfo), m_whois_Init(ModuleInfo *modinfo), m_quit_Init(ModuleInfo *modinfo);
extern int m_kill_Init(ModuleInfo *modinfo), m_pingpong_Init(ModuleInfo *modinfo), m_oper_Init(ModuleInfo *modinfo);
-extern int m_akill_Init(ModuleInfo *modinfo), m_rakill_Init(ModuleInfo *modinfo);
+extern int m_akill_Init(ModuleInfo *modinfo), m_rakill_Init(ModuleInfo *modinfo), m_userip_Init(ModuleInfo *modinfo);
extern int m_unzline_Init(ModuleInfo *modinfo), m_unkline_Init(ModuleInfo *modinfo);
extern int m_sqline_Init(ModuleInfo *modinfo), m_unsqline_Init(ModuleInfo *modinfo), m_tkl_Init(ModuleInfo *modinfo);
extern int m_vhost_Init(ModuleInfo *modinfo), m_cycle_Init(ModuleInfo *modinfo), m_svsjoin_Init(ModuleInfo *modinfo);
@@ -130,7 +130,7 @@ extern int m_lag_Load(int module_load), m_rping_Load(int module_load), m_sendumo
extern int m_tsctl_Load(int module_load), m_htm_Load(int module_load), m_chgname_Load(int module_load);
extern int m_message_Load(int module_load), m_whois_Load(int module_load), m_quit_Load(int module_load);
extern int m_kill_Load(int module_load), m_pingpong_Load(int module_load), m_oper_Load(int module_load);
-extern int m_akill_Load(int module_load), m_rakill_Load(int module_load);
+extern int m_akill_Load(int module_load), m_rakill_Load(int module_load), m_userip_Load(int unused);
extern int m_unzline_Load(int module_load), m_unkline_Load(int module_load);
extern int m_sqline_Load(int module_load), m_unsqline_Load(int module_load), m_tkl_Load(int module_load);
extern int m_vhost_Load(int module_load), m_cycle_Load(int module_load), m_svsjoin_Load(int module_load);
@@ -170,7 +170,7 @@ extern int m_adminchat_Unload(), m_nachat_Unload(), m_lag_Unload(), m_rping_Unlo
extern int m_sendumode_Unload(), m_tsctl_Unload(), m_htm_Unload(), m_chgname_Unload();
extern int m_message_Unload(), m_whois_Unload(), m_quit_Unload(), m_kill_Unload();
extern int m_pingpong_Unload(), m_oper_Unload(), m_akill_Unload(), m_rakill_Unload();
-extern int m_unzline_Unload(), m_unkline_Unload();
+extern int m_unzline_Unload(), m_unkline_Unload(), m_userip_Unload();
extern int m_sqline_Unload(), m_unsqline_Unload(), m_tkl_Unload(), m_vhost_Unload();
extern int m_cycle_Unload(), m_svsjoin_Unload(), m_svspart_Unload(), m_svslusers_Unload();
extern int m_svswatch_Unload(), m_svssilence_Unload(), m_svskill_Unload();
@@ -310,6 +310,7 @@ int l_commands_Init(ModuleInfo *modinfo)
m_whowas_Init(ModCmdsInfo);
m_connect_Init(ModCmdsInfo);
m_dccallow_Init(ModCmdsInfo);
+ m_userip_Init(ModCmdsInfo);
#ifdef GUEST
m_guest_Init(ModCmdsInfo);
#endif
@@ -410,6 +411,7 @@ int l_commands_Load(int module_load)
m_whowas_Load(module_load);
m_connect_Load(module_load);
m_dccallow_Load(module_load);
+ m_userip_Load(module_load);
#ifdef GUEST
m_guest_Load(module_load);
#endif
@@ -510,6 +512,7 @@ int l_commands_Unload(int module_unload)
m_whowas_Unload();
m_connect_Unload();
m_dccallow_Unload();
+ m_userip_Unload();
#ifdef GUEST
m_guest_Unload();
#endif
diff --git a/src/modules/m_away.c b/src/modules/m_away.c
index f1b5b5b73..c2d874dbf 100644
--- a/src/modules/m_away.c
+++ b/src/modules/m_away.c
@@ -97,8 +97,10 @@ DLLFUNC int MOD_UNLOAD(m_away)(int module_unload)
** parv[0] = sender prefix
** parv[1] = away message
*/
-int m_away(aClient *cptr, aClient *sptr, int parc, char *parv[]) {
- char *away, *awy2 = parv[1];
+int m_away(aClient *cptr, aClient *sptr, int parc, char *parv[])
+{
+char *away, *awy2 = parv[1];
+int n;
if (IsServer(sptr))
return 0;
@@ -120,6 +122,10 @@ int m_away(aClient *cptr, aClient *sptr, int parc, char *parv[]) {
return 0;
}
+ n = dospamfilter(sptr, parv[1], SPAMF_AWAY, NULL);
+ if (n < 0)
+ return n;
+
#ifdef NO_FLOOD_AWAY
if (MyClient(sptr) && AWAY_PERIOD && !IsAnOper(sptr))
{
diff --git a/src/modules/m_dccallow.c b/src/modules/m_dccallow.c
index 2ff341bd0..b50cc3a39 100644
--- a/src/modules/m_dccallow.c
+++ b/src/modules/m_dccallow.c
@@ -47,7 +47,6 @@
DLLFUNC int m_dccallow(aClient *cptr, aClient *sptr, int parc, char *parv[]);
#define MSG_DCCALLOW "DCCALLOW"
-#define TOK_DCCALLOW ""
ModuleHeader MOD_HEADER(m_dccallow)
= {
@@ -60,7 +59,7 @@ ModuleHeader MOD_HEADER(m_dccallow)
DLLFUNC int MOD_INIT(m_dccallow)(ModuleInfo *modinfo)
{
- add_Command(MSG_DCCALLOW, TOK_DCCALLOW, m_dccallow, 1);
+ CommandAdd(modinfo->handle, MSG_DCCALLOW, NULL, m_dccallow, 1, M_USER|M_ANNOUNCE);
MARK_AS_OFFICIAL_MODULE(modinfo);
return MOD_SUCCESS;
}
@@ -72,11 +71,6 @@ DLLFUNC int MOD_LOAD(m_dccallow)(int module_load)
DLLFUNC int MOD_UNLOAD(m_dccallow)(int module_unload)
{
- if (del_Command(MSG_DCCALLOW, TOK_DCCALLOW, m_dccallow) < 0)
- {
- sendto_realops("Failed to delete commands when unloading %s",
- MOD_HEADER(m_dccallow).name);
- }
return MOD_SUCCESS;
}
diff --git a/src/modules/m_kick.c b/src/modules/m_kick.c
index 424f4a6fb..11e252a05 100644
--- a/src/modules/m_kick.c
+++ b/src/modules/m_kick.c
@@ -293,6 +293,8 @@ CMD_FUNC(m_kick)
if (breakit)
continue;
RunHook5(HOOKTYPE_LOCAL_KICK, cptr,sptr,who,chptr,comment);
+ } else {
+ RunHook5(HOOKTYPE_REMOTE_KICK, cptr, sptr, who, chptr, comment);
}
if (lp)
{
diff --git a/src/modules/m_knock.c b/src/modules/m_knock.c
index 167b26d54..c7f5f5726 100644
--- a/src/modules/m_knock.c
+++ b/src/modules/m_knock.c
@@ -60,7 +60,7 @@ ModuleHeader MOD_HEADER(m_knock)
DLLFUNC int MOD_INIT(m_knock)(ModuleInfo *modinfo)
{
- add_Command(MSG_KNOCK, TOK_KNOCK, m_knock, 2);
+ CommandAdd(modinfo->handle, MSG_KNOCK, TOK_KNOCK, m_knock, 2, M_USER|M_ANNOUNCE);
MARK_AS_OFFICIAL_MODULE(modinfo);
return MOD_SUCCESS;
}
@@ -72,11 +72,6 @@ DLLFUNC int MOD_LOAD(m_knock)(int module_load)
DLLFUNC int MOD_UNLOAD(m_knock)(int module_unload)
{
- if (del_Command(MSG_KNOCK, TOK_KNOCK, m_knock) < 0)
- {
- sendto_realops("Failed to delete commands when unloading %s",
- MOD_HEADER(m_knock).name);
- }
return MOD_SUCCESS;
}
diff --git a/src/modules/m_map.c b/src/modules/m_map.c
index f388e7eab..faae76e03 100644
--- a/src/modules/m_map.c
+++ b/src/modules/m_map.c
@@ -60,7 +60,7 @@ ModuleHeader MOD_HEADER(m_map)
DLLFUNC int MOD_INIT(m_map)(ModuleInfo *modinfo)
{
- add_Command(MSG_MAP, TOK_MAP, m_map, MAXPARA);
+ CommandAdd(modinfo->handle, MSG_MAP, TOK_MAP, m_map, MAXPARA, M_USER|M_ANNOUNCE);
MARK_AS_OFFICIAL_MODULE(modinfo);
return MOD_SUCCESS;
}
@@ -72,11 +72,6 @@ DLLFUNC int MOD_LOAD(m_map)(int module_load)
DLLFUNC int MOD_UNLOAD(m_map)(int module_unload)
{
- if (del_Command(MSG_MAP, TOK_MAP, m_map) < 0)
- {
- sendto_realops("Failed to delete commands when unloading %s",
- MOD_HEADER(m_map).name);
- }
return MOD_SUCCESS;
}
diff --git a/src/modules/m_message.c b/src/modules/m_message.c
index 72273f919..73c797d6c 100644
--- a/src/modules/m_message.c
+++ b/src/modules/m_message.c
@@ -270,13 +270,13 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int
if (MyClient(sptr))
{
- ret = dospamfilter(sptr, text, newcmd == MSG_NOTICE ? SPAMF_USERNOTICE : SPAMF_USERMSG, acptr->name);
+ ret = dospamfilter(sptr, text, (notice ? SPAMF_USERNOTICE : SPAMF_USERMSG), acptr->name);
if (ret < 0)
return FLUSH_BUFFER;
}
for (tmphook = Hooks[HOOKTYPE_USERMSG]; tmphook; tmphook = tmphook->next) {
- text = (*(tmphook->func.pcharfunc))(cptr, sptr, acptr, text, (int)(newcmd == MSG_NOTICE ? 1 : 0) );
+ text = (*(tmphook->func.pcharfunc))(cptr, sptr, acptr, text, notice);
if (!text)
break;
}
@@ -373,6 +373,9 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int
abort();
strlcpy(pfixchan+1, p2, sizeof(pfixchan)-1);
nick = pfixchan;
+ } else {
+ strlcpy(pfixchan, p2, sizeof(pfixchan));
+ nick = pfixchan;
}
}
diff --git a/src/modules/m_oper.c b/src/modules/m_oper.c
index 1756fb646..8bbc8e9ac 100644
--- a/src/modules/m_oper.c
+++ b/src/modules/m_oper.c
@@ -252,7 +252,10 @@ DLLFUNC int m_oper(aClient *cptr, aClient *sptr, int parc, char *parv[]) {
/* new oper code */
- sptr->umodes |= OPER_MODES;
+ if (aconf->modes)
+ sptr->umodes |= aconf->modes;
+ else
+ sptr->umodes |= OPER_MODES;
/* handle oflags that trigger umodes */
@@ -270,7 +273,19 @@ DLLFUNC int m_oper(aClient *cptr, aClient *sptr, int parc, char *parv[]) {
sptr->oflag = aconf->oflags;
if ((aconf->oflags & OFLAG_HIDE) && iNAH && !BadPtr(host)) {
- iNAH_host(sptr, host);
+ char *c;
+ char *vhost = host;
+
+ if ((c = strchr(host, '@')))
+ {
+ vhost = c+1;
+ strncpy(sptr->user->username, host, c-host);
+ sptr->user->username[c-host] = 0;
+ sendto_serv_butone_token(NULL, sptr->name, MSG_SETIDENT,
+ TOK_SETIDENT, "%s",
+ sptr->user->username);
+ }
+ iNAH_host(sptr, vhost);
SetHidden(sptr);
} else
if (IsHidden(sptr) && !sptr->user->virthost) {
@@ -292,15 +307,14 @@ DLLFUNC int m_oper(aClient *cptr, aClient *sptr, int parc, char *parv[]) {
if (announce != NULL) {
- sendto_ops
- ("%s (%s@%s) [%s] %s",
+ sendto_snomask(SNO_OPER,
+ "%s (%s@%s) [%s] %s",
parv[0], sptr->user->username, GetHost(sptr),
parv[1], announce);
- sendto_serv_butone(&me,
- ":%s GLOBOPS :%s (%s@%s) [%s] %s",
- me.name, parv[0], sptr->user->username,
- GetHost(sptr), parv[1], announce);
-
+ sendto_serv_butone_token(NULL, me.name, MSG_SENDSNO, TOK_SENDSNO,
+ "o :%s (%s@%s) [%s] %s",
+ parv[0], sptr->user->username,
+ GetHost(sptr), parv[1], announce);
}
if (aconf->snomask)
set_snomask(sptr, aconf->snomask);
diff --git a/src/modules/m_sapart.c b/src/modules/m_sapart.c
index 7d5bdcc8e..557468210 100644
--- a/src/modules/m_sapart.c
+++ b/src/modules/m_sapart.c
@@ -60,7 +60,7 @@ ModuleHeader MOD_HEADER(m_sapart)
DLLFUNC int MOD_INIT(m_sapart)(ModuleInfo *modinfo)
{
- add_Command(MSG_SAPART, TOK_SAPART, m_sapart, MAXPARA);
+ add_Command(MSG_SAPART, TOK_SAPART, m_sapart, 3);
MARK_AS_OFFICIAL_MODULE(modinfo);
return MOD_SUCCESS;
}
@@ -87,10 +87,13 @@ DLLFUNC int MOD_UNLOAD(m_sapart)(int module_unload)
parv[0] - sender
parv[1] - nick to make part
parv[2] - channel(s) to part
+ parv[3] - comment
*/
DLLFUNC CMD_FUNC(m_sapart)
{
aClient *acptr;
+ char *comment = (parc > 3 && parv[3] ? parv[3] : NULL);
+ char commentx[512];
if (!IsSAdmin(sptr) && !IsULine(sptr))
{
sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
@@ -108,28 +111,51 @@ DLLFUNC CMD_FUNC(m_sapart)
sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], parv[1]);
return 0;
}
-
- sendto_realops("%s used SAPART to make %s part %s", sptr->name, parv[1],
- parv[2]);
-
-
- /* Logging function added by XeRXeS */
- ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s",
- sptr->name, parv[1], parv[2]);
+
+ if (comment)
+ {
+ sendto_realops("%s used SAPART to make %s part %s (%s)", sptr->name, parv[1],
+ parv[2], comment);
+ /* Logging function added by XeRXeS */
+ ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s (%s)",
+ sptr->name, parv[1], parv[2], comment);
+ strcpy(commentx, "SAPart: ");
+ strlcat(commentx, comment, 512);
+ }
+ else
+ {
+ sendto_realops("%s used SAPART to make %s part %s", sptr->name, parv[1],
+ parv[2]);
+ /* Logging function added by XeRXeS */
+ ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s",
+ sptr->name, parv[1], parv[2]);
+ }
if (MyClient(acptr))
{
parv[0] = parv[1];
parv[1] = parv[2];
- parv[2] = NULL;
- sendto_one(acptr,
- ":%s %s %s :*** You were forced to part %s", me.name,
- IsWebTV(acptr) ? "PRIVMSG" : "NOTICE", acptr->name, parv[1]);
- (void)m_part(acptr, acptr, 2, parv);
+ parv[2] = comment ? commentx : NULL;
+ if (comment)
+ sendto_one(acptr,
+ ":%s %s %s :*** You were forced to part %s (%s)", me.name,
+ IsWebTV(acptr) ? "PRIVMSG" : "NOTICE", acptr->name, parv[1],
+ commentx);
+ else
+ sendto_one(acptr,
+ ":%s %s %s :*** You were forced to part %s", me.name,
+ IsWebTV(acptr) ? "PRIVMSG" : "NOTICE", acptr->name, parv[1]);
+ (void)m_part(acptr, acptr, comment ? 3 : 2, parv);
}
else
- sendto_one(acptr, ":%s SAPART %s %s", parv[0],
- parv[1], parv[2]);
+ {
+ if (comment)
+ sendto_one(acptr, ":%s SAPART %s %s :%s", parv[0],
+ parv[1], parv[2], comment);
+ else
+ sendto_one(acptr, ":%s SAPART %s %s", parv[0], parv[1],
+ parv[2]);
+ }
return 0;
}
diff --git a/src/modules/m_sjoin.c b/src/modules/m_sjoin.c
index 9aafd01d5..48df6bec6 100644
--- a/src/modules/m_sjoin.c
+++ b/src/modules/m_sjoin.c
@@ -379,7 +379,7 @@ CMD_FUNC(m_sjoin)
while (
(*tp == '@') || (*tp == '+') || (*tp == '%')
|| (*tp == '*') || (*tp == '~') || (*tp == '&')
- || (*tp == '"'))
+ || (*tp == '"') || (*tp == '\''))
{
switch (*(tp++))
{
@@ -405,6 +405,8 @@ CMD_FUNC(m_sjoin)
modeflags |= CHFL_EXCEPT;
goto getnick;
break;
+ case '\'': /* future: invex chanmode (+I) */
+ goto docontinue;
}
}
getnick:
@@ -472,6 +474,7 @@ CMD_FUNC(m_sjoin)
#endif
} else {
add_user_to_channel(chptr, acptr, modeflags);
+ RunHook4(HOOKTYPE_REMOTE_JOIN, cptr, acptr, chptr, NULL);
if (chptr->mode.mode & MODE_AUDITORIUM)
{
if (modeflags & (CHFL_CHANOP|CHFL_CHANPROT|CHFL_CHANOWNER))
@@ -517,6 +520,8 @@ CMD_FUNC(m_sjoin)
}
}
}
+docontinue:
+ continue;
}
if (modebuf[1])
diff --git a/src/modules/m_svsjoin.c b/src/modules/m_svsjoin.c
index 5361868f1..c0c11895a 100644
--- a/src/modules/m_svsjoin.c
+++ b/src/modules/m_svsjoin.c
@@ -47,7 +47,7 @@ DLLFUNC int m_svsjoin(aClient *cptr, aClient *sptr, int parc, char *parv[]);
/* Place includes here */
#define MSG_SVSJOIN "SVSJOIN"
-#define TOK_SVSJOIN "BR"
+#define TOK_SVSJOIN "BX"
ModuleHeader MOD_HEADER(m_svsjoin)
= {
diff --git a/src/modules/m_svso.c b/src/modules/m_svso.c
index 7d1ce1e33..d63fb9d41 100644
--- a/src/modules/m_svso.c
+++ b/src/modules/m_svso.c
@@ -174,7 +174,7 @@ int m_svso(aClient *cptr, aClient *sptr, int parc, char *parv[])
acptr->umodes &=
~(UMODE_NETADMIN | UMODE_WHOIS);
acptr->umodes &=
- ~(UMODE_KIX | UMODE_DEAF | UMODE_HIDEOPER);
+ ~(UMODE_KIX | UMODE_DEAF | UMODE_HIDEOPER | UMODE_VICTIM);
acptr->oflag = 0;
remove_oper_snomasks(acptr);
RunHook2(HOOKTYPE_LOCAL_OPER, acptr, 0);
diff --git a/src/modules/m_svspart.c b/src/modules/m_svspart.c
index 8ba7d7fe1..1c77f93bd 100644
--- a/src/modules/m_svspart.c
+++ b/src/modules/m_svspart.c
@@ -64,7 +64,7 @@ DLLFUNC int MOD_INIT(m_svspart)(ModuleInfo *modinfo)
/*
* We call our add_Command crap here
*/
- add_Command(MSG_SVSPART, TOK_SVSPART, m_svspart, MAXPARA);
+ add_Command(MSG_SVSPART, TOK_SVSPART, m_svspart, 3);
MARK_AS_OFFICIAL_MODULE(modinfo);
return MOD_SUCCESS;
}
@@ -92,10 +92,12 @@ DLLFUNC int MOD_UNLOAD(m_svspart)(int module_unload)
parv[0] - sender
parv[1] - nick to make part
parv[2] - channel(s) to part
+ parv[3] - comment
*/
CMD_FUNC(m_svspart)
{
aClient *acptr;
+ char *comment = (parc > 3 && parv[3] ? parv[3] : NULL);
if (!IsULine(sptr))
return 0;
@@ -105,11 +107,18 @@ CMD_FUNC(m_svspart)
{
parv[0] = parv[1];
parv[1] = parv[2];
- (void)m_part(acptr, acptr, 2, parv);
+ parv[2] = comment;
+ (void)m_part(acptr, acptr, comment ? 3 : 2, parv);
}
else
- sendto_one(acptr, ":%s SVSPART %s %s", parv[0],
- parv[1], parv[2]);
+ {
+ if (comment)
+ sendto_one(acptr, ":%s SVSPART %s %s :%s", parv[0],
+ parv[1], parv[2], parv[3]);
+ else
+ sendto_one(acptr, ":%s SVSPART %s %s", parv[0],
+ parv[1], parv[2]);
+ }
return 0;
}
diff --git a/src/modules/m_svswatch.c b/src/modules/m_svswatch.c
index c8fc58d53..06ee8b98b 100644
--- a/src/modules/m_svswatch.c
+++ b/src/modules/m_svswatch.c
@@ -47,7 +47,7 @@ DLLFUNC int m_svswatch(aClient *cptr, aClient *sptr, int parc, char *parv[]);
/* Place includes here */
#define MSG_SVSWATCH "SVSWATCH"
-#define TOK_SVSWATCH "BW"
+#define TOK_SVSWATCH "Bw"
ModuleHeader MOD_HEADER(m_svswatch)
= {
diff --git a/src/modules/m_userip.c b/src/modules/m_userip.c
new file mode 100644
index 000000000..36f1f8a50
--- /dev/null
+++ b/src/modules/m_userip.c
@@ -0,0 +1,140 @@
+/*
+ * IRC - Internet Relay Chat, src/modules/m_userip.c
+ * (C) 2004 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 "config.h"
+#include "struct.h"
+#include "common.h"
+#include "sys.h"
+#include "numeric.h"
+#include "msg.h"
+#include "proto.h"
+#include "channel.h"
+#include
+#include
+#include
+#include
+#include
+#ifdef _WIN32
+#include
+#endif
+#include
+#include "h.h"
+#ifdef STRIPBADWORDS
+#include "badwords.h"
+#endif
+#ifdef _WIN32
+#include "version.h"
+#endif
+
+DLLFUNC int m_userip(aClient *cptr, aClient *sptr, int parc, char *parv[]);
+
+#define MSG_USERIP "USERIP"
+
+ModuleHeader MOD_HEADER(m_userip)
+ = {
+ "m_userip",
+ "$Id$",
+ "command /userip",
+ "3.2-b8-1",
+ NULL
+ };
+
+DLLFUNC int MOD_INIT(m_userip)(ModuleInfo *modinfo)
+{
+ CommandAdd(modinfo->handle, MSG_USERIP, NULL, m_userip, 1, M_USER|M_ANNOUNCE);
+ MARK_AS_OFFICIAL_MODULE(modinfo);
+ return MOD_SUCCESS;
+}
+
+DLLFUNC int MOD_LOAD(m_userip)(int module_load)
+{
+ return MOD_SUCCESS;
+}
+
+DLLFUNC int MOD_UNLOAD(m_userip)(int module_unload)
+{
+ return MOD_SUCCESS;
+}
+
+/*
+ * m_userip is based on m_userhost
+ * m_userhost added by Darren Reed 13/8/91 to aid clients and reduce
+ * the need for complicated requests like WHOIS. It returns user/host
+ * information only (no spurious AWAY labels or channels).
+ * Re-written by Dianora 1999
+ */
+DLLFUNC CMD_FUNC(m_userip)
+{
+
+ char *p; /* scratch end pointer */
+ char *cn; /* current name */
+ char *ip;
+ struct Client *acptr;
+ char response[5][NICKLEN * 2 + CHANNELLEN + USERLEN + HOSTLEN + 30];
+ int i; /* loop counter */
+
+ if (parc < 2)
+ {
+ sendto_one(sptr, rpl_str(ERR_NEEDMOREPARAMS),
+ me.name, parv[0], "USERHOST");
+ return 0;
+ }
+
+ /* The idea is to build up the response string out of pieces
+ * none of this strlen() nonsense.
+ * 5 * (NICKLEN*2+CHANNELLEN+USERLEN+HOSTLEN+30) is still << sizeof(buf)
+ * and our ircsprintf() truncates it to fit anyway. There is
+ * no danger of an overflow here. -Dianora
+ */
+ response[0][0] = response[1][0] = response[2][0] =
+ response[3][0] = response[4][0] = '\0';
+
+ cn = parv[1];
+
+ for (i = 0; (i < 5) && cn; i++)
+ {
+ if ((p = strchr(cn, ' ')))
+ *p = '\0';
+
+ if ((acptr = find_person(cn, NULL)))
+ {
+ if (!(ip = GetIP(acptr)))
+ ip = "";
+ if (sptr != acptr && !IsOper(sptr) && IsHidden(acptr))
+ ip = RCallbacks[CALLBACKTYPE_CLOAK]->func.pcharfunc(ip);
+
+ ircsprintf(response[i], "%s%s=%c%s@%s",
+ acptr->name,
+ (IsAnOper(acptr) && (!IsHideOper(acptr) || sptr == acptr || IsAnOper(sptr)))
+ ? "*" : "",
+ (acptr->user->away) ? '-' : '+',
+ acptr->user->username, ip);
+ }
+ if (p)
+ p++;
+ cn = p;
+ }
+
+ sendto_one(sptr, rpl_str(RPL_USERIP), me.name, parv[0],
+ response[0], response[1], response[2], response[3], response[4]);
+
+ return 0;
+}
diff --git a/src/modules/m_vhost.c b/src/modules/m_vhost.c
index 1a6075fcc..320ad5d43 100644
--- a/src/modules/m_vhost.c
+++ b/src/modules/m_vhost.c
@@ -175,12 +175,14 @@ int m_vhost(aClient *cptr, aClient *sptr, int parc, char *parv[])
if (vhost->virtuser) {
strcpy(olduser, sptr->user->username);
strlcpy(sptr->user->username, vhost->virtuser, USERLEN);
+ sendto_serv_butone_token(cptr, sptr->name, MSG_SETIDENT, TOK_SETIDENT,
+ "%s", sptr->user->username);
}
sptr->umodes |= UMODE_HIDE;
sptr->umodes |= UMODE_SETHOST;
sendto_serv_butone_token(cptr, sptr->name,
MSG_SETHOST, TOK_SETHOST,
- "%s", vhost->virthost);
+ "%s", sptr->user->virthost);
sendto_one(sptr, ":%s MODE %s :+tx",
sptr->name, sptr->name);
if (vhost->swhois) {
diff --git a/src/modules/m_who.c b/src/modules/m_who.c
index 30b8764d8..3704620d3 100644
--- a/src/modules/m_who.c
+++ b/src/modules/m_who.c
@@ -204,15 +204,15 @@ static void who_sendhelp(aClient *sptr)
"Flag a: user is away",
"Flag c : user is on ,",
" no wildcards accepted",
- "Flag h : user has string in their hostname,",
+ "Flag h : user has string in his/her hostname,",
" wildcards accepted",
- "Flag m : user has set on them,",
- " only O/o/C/A/a/N are allowed",
- "Flag n : user has string in their nickname,",
+ "Flag m : user has set, only",
+ " O/o/C/A/a/N are allowed",
+ "Flag n : user has string in his/her nickname,",
" wildcards accepted",
"Flag s : user is on server ,",
" wildcards not accepted",
- "Flag u : user has string in their username,",
+ "Flag u : user has string in his/her username,",
" wildcards accepted",
"Behavior flags:",
"Flag M: check for user in channels I am a member of",
@@ -227,23 +227,23 @@ static void who_sendhelp(aClient *sptr)
"Flag a: user is away",
"Flag c : user is on ,",
" no wildcards accepted",
- "Flag g : user has string in their GCOS,",
+ "Flag g : user has string in his/her GCOS,",
" wildcards accepted",
- "Flag h : user has string in their hostname,",
+ "Flag h : user has string in his/her hostname,",
" wildcards accepted",
- "Flag i : user has string in their hostname,",
+ "Flag i : user has string in his/her IP address,",
" wildcards accepted",
- "Flag m : user has set on them",
- "Flag n : user has string in their nickname,",
+ "Flag m : user has set",
+ "Flag n : user has string in his/her nickname,",
" wildcards accepted",
"Flag s : user is on server ,",
" wildcards not accepted",
- "Flag u : user has string in their username,",
+ "Flag u : user has string in his/her username,",
" wildcards accepted",
"Behavior flags:",
"Flag M: check for user in channels I am a member of",
"Flag R: show users' real hostnames",
- "Flag I: show user's IP address",
+ "Flag I: show users' IP addresses",
NULL
};
char **s;
@@ -544,10 +544,16 @@ char has_common_chan = 0;
else
{
/* a user/mask who */
+
+ /* If the common channel info hasn't been set, set it now */
+ if (!wfl.common_channels_only)
+ has_common_chan = has_common_channels(sptr, acptr);
+
if (IsInvisible(acptr) && !has_common_chan)
{
- /* don't show them unless it's an exact match */
- if ((who_flags & WF_WILDCARD))
+ /* don't show them unless it's an exact match
+ or it is the user requesting the /who */
+ if ((who_flags & WF_WILDCARD) && sptr != acptr)
break;
}
}
diff --git a/src/modules/m_whois.c b/src/modules/m_whois.c
index c889427b3..5edf8878a 100644
--- a/src/modules/m_whois.c
+++ b/src/modules/m_whois.c
@@ -175,12 +175,15 @@ DLLFUNC int m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
IsHidden(acptr) ? user->virthost : user->realhost,
acptr->info);
- if (IsEyes(sptr) && IsOper(sptr))
+ if (IsOper(sptr))
{
+ char sno[512];
+ strcpy(sno, get_sno_str(acptr));
+
/* send the target user's modes */
sendto_one(sptr, rpl_str(RPL_WHOISMODES),
me.name, parv[0], name,
- get_mode_str(acptr));
+ get_mode_str(acptr), sno[1] == 0 ? "" : sno);
}
if ((acptr == sptr) || IsAnOper(sptr))
{
@@ -238,18 +241,15 @@ DLLFUNC int m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
&& IsAnOper(sptr))
*(buf + len++) = '!';
access = get_access(acptr, chptr);
-#ifndef PREFIX_AQ
- if (access & CHFL_CHANOWNER)
- *(buf + len++) = '*';
- else if (access & CHFL_CHANPROT)
- *(buf + len++) = '^';
-#else
+#ifdef PREFIX_AQ
if (access & CHFL_CHANOWNER)
*(buf + len++) = '~';
else if (access & CHFL_CHANPROT)
+
*(buf + len++) = '&';
+ else
#endif
- else if (access & CHFL_CHANOP)
+ if (access & CHFL_CHANOP)
*(buf + len++) = '@';
else if (access & CHFL_HALFOP)
*(buf + len++) = '%';
diff --git a/src/packet.c b/src/packet.c
index d80724428..0917ecc07 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -289,85 +289,6 @@ aCommand *add_Command_backend(char *cmd, int (*func)(), unsigned char parameters
return newcmd;
}
-int CommandExists(char *name)
-{
- aCommand *p;
-
- for (p = CommandHash[toupper(*name)]; p; p = p->next)
- {
- if (!stricmp(p->cmd, name))
- return 1;
- }
- for (p = TokenHash[*name]; p; p = p->next)
- {
- if (!strcmp(p->cmd, name))
- return 1;
- }
- return 0;
-}
-
-Command *CommandAdd(Module *module, char *cmd, char *tok, int (*func)(), unsigned char params, int flags) {
- Command *command;
-
- if (find_Command_simple(cmd) || (tok && find_Command_simple(tok)))
- {
- if (module)
- module->errorcode = MODERR_EXISTS;
- return NULL;
- }
- command = MyMallocEx(sizeof(Command));
- command->cmd = add_Command_backend(cmd,func,params, 0, flags);
- command->tok = NULL;
- command->cmd->owner = module;
- if (tok) {
- command->tok = add_Command_backend(tok,func,params,1,flags);
- command->cmd->friend = command->tok;
- command->tok->friend = command->cmd;
- command->tok->owner = module;
- }
- else
- command->cmd->friend = NULL;
- if (module) {
- ModuleObject *cmdobj = (ModuleObject *)MyMallocEx(sizeof(ModuleObject));
- cmdobj->object.command = command;
- cmdobj->type = MOBJ_COMMAND;
- AddListItem(cmdobj, module->objects);
- module->errorcode = MODERR_NOERROR;
- }
- return command;
-}
-
-
-void CommandDel(Command *command) {
- Cmdoverride *ovr, *ovrnext;
-
- DelListItem(command->cmd, CommandHash[toupper(*command->cmd->cmd)]);
- if (command->tok)
- DelListItem(command->tok, TokenHash[*command->tok->cmd]);
- if (command->cmd->owner) {
- ModuleObject *cmdobj;
- for (cmdobj = command->cmd->owner->objects; cmdobj; cmdobj = (ModuleObject *)cmdobj->next) {
- if (cmdobj->type == MOBJ_COMMAND && cmdobj->object.command == command) {
- DelListItem(cmdobj,command->cmd->owner->objects);
- MyFree(cmdobj);
- break;
- }
- }
- }
- for (ovr = command->cmd->overriders; ovr; ovr = ovrnext)
- {
- ovrnext = ovr->next;
- CmdoverrideDel(ovr);
- }
- MyFree(command->cmd->cmd);
- MyFree(command->cmd);
- if (command->tok) {
- MyFree(command->tok->cmd);
- MyFree(command->tok);
- }
- MyFree(command);
-}
-
void add_Command(char *name, char *token, int (*func)(), unsigned char parameters)
{
aCommand *cmd, *tok;
diff --git a/src/res.c b/src/res.c
index a8699348f..7348836ed 100644
--- a/src/res.c
+++ b/src/res.c
@@ -51,6 +51,9 @@ static ResRQ *last, *first;
static void rem_cache(aCache *);
static void rem_request(ResRQ *);
static int do_query_name(Link *, char *, ResRQ *);
+/* revquery is used when looking up IP -> name -> IP to differentiate between
+ * IPv6 and IPv4, to make the proper request type --slePP */
+static int do_revquery_name(Link *, char *, ResRQ *, int is_ipv6_address);
static int do_query_number(Link *, struct IN_ADDR *, ResRQ *);
static void resend_query(ResRQ *);
static int proc_answer(ResRQ *, HEADER *, char *, char *);
@@ -127,13 +130,23 @@ int init_resolver(int op)
if (op & RES_INITSOCK)
{
int on = 0;
-
+ struct sockaddr_in sa; /* TODO: IPv6 */
+
#ifdef INET6
/* still IPv4 */
ret = resfd = socket(AF_INET, SOCK_DGRAM, 0);
#else
ret = resfd = socket(AF_INET, SOCK_DGRAM, 0);
#endif
+
+ /* TODO: IPv6 */
+ /* for FreeBSD jail we need to bind() explicitly.. */
+ bzero(&sa, sizeof(sa));
+ sa.sin_family = AF_INET;
+ sa.sin_port = 0;
+ sa.sin_addr.s_addr = INADDR_ANY;
+ bind(resfd, (struct sockaddr *) &sa, sizeof(sa));
+
(void)setsockopt(ret, SOL_SOCKET, SO_BROADCAST, &on, on);
}
#ifdef DEBUGMODE
@@ -304,6 +317,19 @@ void del_queries(char *cp)
}
}
+void del_async_connects(void)
+{
+ResRQ *rptr, *r2ptr;
+
+ for (rptr = first; rptr; rptr = r2ptr)
+ {
+ r2ptr = rptr->next;
+ if (rptr->cinfo.flags == ASYNC_CONNECT)
+ rem_request(rptr);
+ }
+}
+
+
/*
* sends msg to all nameservers found in the "ircd_res" structure.
* This should reflect /etc/resolv.conf. We will get responses
@@ -399,6 +425,7 @@ static ResRQ *find_id(int id)
return rptr;
}
+/* As of 2004-10-08 gethost_byname() is only used for outgoing connects to servers */
struct hostent *gethost_byname(char *name, Link *lp)
{
aCache *cp;
@@ -412,6 +439,20 @@ struct hostent *gethost_byname(char *name, Link *lp)
return NULL;
}
+/* This is identical to gethost_byname, except it includes is_ipv6_address
+ * See do_revquery_name() */
+struct hostent *gethost_byname_revquery(char *name, Link *lp, int is_ipv6_address)
+{
+ aCache *cp;
+ reinfo.re_na_look++;
+ if ((cp = find_cache_name(name)))
+ return (struct hostent *)&(cp->he);
+ if (!lp)
+ return NULL;
+ (void)do_revquery_name(lp, name, NULL, is_ipv6_address);
+ return NULL;
+}
+
struct hostent *gethost_byaddr(char *addr, Link *lp)
{
aCache *cp;
@@ -425,20 +466,19 @@ struct hostent *gethost_byaddr(char *addr, Link *lp)
return NULL;
}
+/* [2004-10-08/Syzop] used for outgoing connects to servers and
+ * also for repeated normal requests (in which case rptr is non-NULL).
+ */
static int do_query_name(Link *lp, char *name, ResRQ *rptr)
{
- char hname[HOSTLEN + 1];
- int len;
+char hname[HOSTLEN + 1];
- strncpyzt(hname, name, sizeof(hname));
- len = strlen(hname);
+ strlcpy(hname, name, sizeof(hname));
if (rptr && !index(hname, '.') && ircd_res.options & RES_DEFNAMES)
{
- (void)strncat(hname, dot, sizeof(hname) - len - 1);
- len++;
- (void)strncat(hname, ircd_res.defdname,
- sizeof(hname) - len - 1);
+ strlcat(hname, dot, sizeof(hname));
+ strlcat(hname, ircd_res.defdname, sizeof(hname));
}
/*
@@ -449,19 +489,57 @@ static int do_query_name(Link *lp, char *name, ResRQ *rptr)
{
rptr = make_request(lp);
#ifdef INET6
- rptr->type = T_ANY; /* Was T_AAAA: now using T_ANY so we fetch both A and AAAA -- Syzop */
+ rptr->type = T_AAAA; /* outgoing connect: try AAAA first, then A later */
#else
rptr->type = T_A;
#endif
- rptr->name = (char *)MyMalloc(strlen(name) + 1);
- (void)strcpy(rptr->name, name);
+ rptr->name = strdup(name);
}
Debug((DEBUG_DNS, "do_query_name(): %s ", hname));
-#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
+
+ /* We used 'type' here instead of 'rptr->type', but I don't see
+ * any reason not to use the latter. -- Syzop, 2004-10-08
+ */
+ return (query_name(hname, C_IN, rptr->type, rptr));
+}
+
+/* If is_ipv6_address is set, look for AAAA records, if not,
+ * go looking for A records. This fixes a bug when talking to
+ * servers that do not provide any non-authoritative information
+ * to an ANY query (ie. dnscache). --slePP */
+static int do_revquery_name(Link *lp, char *name, ResRQ *rptr, int is_ipv6_address)
+{
+char hname[HOSTLEN + 1];
+
+ Debug((DEBUG_DNS, "do_revquery_name: looking for %s", (is_ipv6_address?"IPv6":"IPv4")));
+
+ strncpyzt(hname, name, sizeof(hname));
+
+ if (rptr && !index(hname, '.') && ircd_res.options & RES_DEFNAMES)
+ {
+ strlcat(hname, dot, sizeof(hname));
+ strlcat(hname, ircd_res.defdname, sizeof(hname));
+ }
+
+ /*
+ * Store the name passed as the one to lookup and generate other host
+ * names to pass onto the nameserver(s) for lookups.
+ */
+ if (!rptr)
+ {
+ rptr = make_request(lp);
+ if(is_ipv6_address)
+ rptr->type = T_AAAA;
+ else
+ rptr->type = T_A;
+ rptr->name = strdup(name);
+ }
+ Debug((DEBUG_DNS, "do_revquery_name(): %s ", hname));
+
+ if(is_ipv6_address)
+ return (query_name(hname, C_IN, T_AAAA, rptr));
+ else
+ return (query_name(hname, C_IN, T_A, rptr));
}
/*
@@ -554,6 +632,7 @@ static int query_name(char *name, int class, int type, ResRQ *rptr)
return r;
}
hptr = (HEADER *) buf;
+ hptr->rd = 1;
do
{
hptr->id = htons(getrandom16());
@@ -900,6 +979,7 @@ struct hostent *get_res(char *lp)
if (a > 0 && rptr->type == T_PTR)
{
struct hostent *hp2 = NULL;
+ int is_ipv6_address = 0;
if (BadPtr(rptr->he.h_name)) /* Kludge! 960907/Vesa */
goto getres_err;
@@ -913,7 +993,11 @@ struct hostent *get_res(char *lp)
* type we automatically gain the use of the cache with no
* extra kludges.
*/
- if ((hp2 = gethost_byname(rptr->he.h_name, &rptr->cinfo)))
+ /* We add this IPv6 check to query for T_AAAA or T_A respectively.
+ * djbdns/dnscache doesn't return A or AAAA to a T_ANY (as it should)
+ * --slePP */
+ is_ipv6_address = (strchr(Inet_ia2p((struct IN_ADDR *)&rptr->he.h_addr), ':') != NULL);
+ if ((hp2 = gethost_byname_revquery(rptr->he.h_name, &rptr->cinfo, is_ipv6_address)))
if (lp)
bcopy((char *)&rptr->cinfo, lp, sizeof(Link));
/*
diff --git a/src/res_init.c b/src/res_init.c
index 24a4936e3..974d30869 100644
--- a/src/res_init.c
+++ b/src/res_init.c
@@ -272,6 +272,7 @@ int get_res_interfaces_nt(HKEY hKey, char *subkey, char *obuf, int *size)
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)
@@ -303,6 +304,8 @@ void get_res_from_reg_nt()
HKEY hKey, hInter;
char buf[BUFSIZ];
int key_len = BUFSIZ;
+ char no_interfaces = 0;
+
ircd_res.nscount = 0;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
@@ -311,7 +314,9 @@ void get_res_from_reg_nt()
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);
+ if (RegOpenKeyEx(hKey, "Interfaces", 0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS,
+ &hInter) != ERROR_SUCCESS)
+ no_interfaces = 1;
/* Retreive the Domain key */
if (!get_res_nt(hKey, "Domain", buf, &key_len))
@@ -324,7 +329,7 @@ void get_res_from_reg_nt()
if (!get_res_interfaces_nt(hInter, "Domain", buf, &key_len))
{
key_len = BUFSIZ;
- if (!get_res_interfaces_nt(hInter, "DhcpDomain", buf, &key_len))
+ if (!no_interfaces && !get_res_interfaces_nt(hInter, "DhcpDomain", buf, &key_len))
{
Debug((DEBUG_DNS, "get_res_from_reg_nt: RegQueryValueEx: Domain failed"));
}
@@ -343,7 +348,7 @@ void get_res_from_reg_nt()
if (!get_res_nt(hKey, "DhcpSearchList", buf, &key_len))
{
key_len = BUFSIZ;
- if (!get_res_interfaces_nt(hInter, "SearchList", buf, &key_len))
+ if (!no_interfaces && !get_res_interfaces_nt(hInter, "SearchList", buf, &key_len))
{
key_len = BUFSIZ;
if (!get_res_interfaces_nt(hInter, "DhcpSearchList", buf, &key_len))
@@ -380,8 +385,7 @@ void get_res_from_reg_nt()
++cp;
*cp = 0;
*pp++ = 0;
- }
-
+ }
/* Retreive the NameServer key */
key_len = BUFSIZ;
if (!get_res_nt(hKey, "NameServer", buf, &key_len))
@@ -391,7 +395,7 @@ void get_res_from_reg_nt()
if (!get_res_nt(hKey, "DhcpNameServer", buf, &key_len))
{
key_len = BUFSIZ;
- if (!get_res_interfaces_nt(hInter, "NameServer", buf, &key_len))
+ if (!no_interfaces && !get_res_interfaces_nt(hInter, "NameServer", buf, &key_len))
{
key_len = BUFSIZ;
if (!get_res_interfaces_nt(hInter, "DhcpNameServer", buf, &key_len))
@@ -429,7 +433,8 @@ void get_res_from_reg_nt()
} while (ircd_res.nscount <= MAXNS);
}
}
- RegCloseKey(hInter);
+ if (!no_interfaces)
+ RegCloseKey(hInter);
RegCloseKey(hKey);
}
#endif
diff --git a/src/s_bsd.c b/src/s_bsd.c
index e626de052..456abec49 100644
--- a/src/s_bsd.c
+++ b/src/s_bsd.c
@@ -2366,7 +2366,7 @@ int connect_server(ConfigItem_link *aconf, aClient *by, struct hostent *hp)
* If we dont know the IP# for this host and itis a hostname and
* not a ip# string, then try and find the appropriate host record.
*/
- if ((!aconf->ipnum.S_ADDR))
+ if (!WHOSTENTP(aconf->ipnum.S_ADDR))
{
Link lin;
@@ -2530,8 +2530,9 @@ static struct SOCKADDR *connect_inet(ConfigItem_link *aconf, aClient *cptr, int
* being present instead. If we dont know it, then the connect fails.
*/
#ifdef INET6
- if (!inet_pton(AF_INET6, aconf->hostname, aconf->ipnum.s6_addr))
- bcopy(minus_one, aconf->ipnum.s6_addr, IN6ADDRSZ);
+ if (!WHOSTENTP(aconf->ipnum.S_ADDR) &&
+ !inet_pton(AF_INET6, aconf->hostname, aconf->ipnum.s6_addr))
+ bcopy(minus_one, aconf->ipnum.s6_addr, IN6ADDRSZ); /* IP->struct failed: make invalid */
if (AND16(aconf->ipnum.s6_addr) == 255)
#else
if (isdigit(*aconf->hostname) && (aconf->ipnum.S_ADDR == -1))
diff --git a/src/s_conf.c b/src/s_conf.c
index b409345b7..ef61d19a3 100644
--- a/src/s_conf.c
+++ b/src/s_conf.c
@@ -23,6 +23,7 @@
#include "sys.h"
#include "numeric.h"
#include "channel.h"
+#include "macros.h"
#include
#ifndef _WIN32
#include
@@ -132,10 +133,6 @@ static int _test_set (ConfigFile *conf, ConfigEntry *ce);
static int _test_badword (ConfigFile *conf, ConfigEntry *ce);
#endif
static int _test_deny (ConfigFile *conf, ConfigEntry *ce);
-/* static int _test_deny_dcc (ConfigFile *conf, ConfigEntry *ce); ** TODO? */
-/* static int _test_deny_link (ConfigFile *conf, ConfigEntry *ce); ** TODO? */
-/* static int _test_deny_channel (ConfigFile *conf, ConfigEntry *ce); ** TODO? */
-/* static int _test_deny_version (ConfigFile *conf, ConfigEntry *ce); ** TODO? */
static int _test_allow_channel (ConfigFile *conf, ConfigEntry *ce);
static int _test_allow_dcc (ConfigFile *conf, ConfigEntry *ce);
static int _test_loadmodule (ConfigFile *conf, ConfigEntry *ce);
@@ -278,6 +275,15 @@ static OperFlag _LogFlags[] = {
{ LOG_TKL, "tkl" },
};
+/* This MUST be alphabetized */
+static OperFlag ExceptTklFlags[] = {
+ { TKL_GLOBAL|TKL_KILL, "gline" },
+ { TKL_GLOBAL|TKL_NICK, "gqline" },
+ { TKL_GLOBAL|TKL_ZAP, "gzline" },
+ { TKL_NICK, "qline" },
+ { TKL_GLOBAL|TKL_SHUN, "shun" }
+};
+
#ifdef USE_SSL
/* This MUST be alphabetized */
static OperFlag _SSLFlags[] = {
@@ -1362,7 +1368,7 @@ void config_progress(char *format, ...)
ConfigCommand *config_binary_search(char *cmd) {
int start = 0;
- int stop = sizeof(_ConfigCommands)/sizeof(_ConfigCommands[0])-1;
+ int stop = ARRAY_SIZEOF(_ConfigCommands)-1;
int mid;
while (start <= stop) {
mid = (start+stop)/2;
@@ -1532,6 +1538,7 @@ int init_conf(char *rootconf, int rehash)
if (rehash)
{
Hook *h;
+ del_async_connects();
config_rehash();
#ifndef STATIC_LINKING
Unload_all_loaded_modules();
@@ -2879,6 +2886,8 @@ int _test_me(ConfigFile *conf, ConfigEntry *ce)
if (cep->ce_vardata)
{
+ int valid = 0;
+ char *p;
if (strlen(cep->ce_vardata) > (REALLEN-1))
{
config_error("%s:%i: too long me::info, must be max. %i characters",
@@ -2886,6 +2895,19 @@ int _test_me(ConfigFile *conf, ConfigEntry *ce)
errors++;
}
+ /* Valid me::info? Any data except spaces is ok */
+ for (p=cep->ce_vardata; *p; p++)
+ if (*p != ' ')
+ {
+ valid = 1;
+ break;
+ }
+ if (!valid)
+ {
+ config_error("%s:%i: empty me::info, should be a server description.",
+ ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
+ errors++;
+ }
}
}
if (!(cep = config_find_entry(ce->ce_entries, "numeric")))
@@ -3008,7 +3030,7 @@ int _conf_oper(ConfigFile *conf, ConfigEntry *ce)
{
for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
{
- if ((ofp = config_binary_flags_search(_OperFlags, cepp->ce_varname, sizeof(_OperFlags)/sizeof(_OperFlags[0]))))
+ if ((ofp = config_binary_flags_search(_OperFlags, cepp->ce_varname, ARRAY_SIZEOF(_OperFlags))))
oper->oflags |= ofp->flag;
}
}
@@ -3020,6 +3042,10 @@ int _conf_oper(ConfigFile *conf, ConfigEntry *ce)
{
ircstrdup(oper->snomask, cep->ce_vardata);
}
+ if ((cep = config_find_entry(ce->ce_entries, "modes")))
+ {
+ oper->modes = set_usermode(cep->ce_vardata);
+ }
if ((cep = config_find_entry(ce->ce_entries, "maxlogins")))
{
oper->maxlogins = (int)config_checkval(cep->ce_vardata, CFG_TIME);
@@ -3083,6 +3109,8 @@ int _test_oper(ConfigFile *conf, ConfigEntry *ce)
}
else if (!strcmp(cep->ce_varname, "snomask")) {
}
+ else if (!strcmp(cep->ce_varname, "modes")) {
+ }
else if (!strcmp(cep->ce_varname, "maxlogins"))
{
long l = config_checkval(cep->ce_vardata, CFG_TIME);
@@ -3118,7 +3146,7 @@ int _test_oper(ConfigFile *conf, ConfigEntry *ce)
errors++;
continue;
}
- if (!config_binary_flags_search(_OperFlags, cepp->ce_varname, sizeof(_OperFlags)/sizeof(_OperFlags[0]))) {
+ if (!config_binary_flags_search(_OperFlags, cepp->ce_varname, ARRAY_SIZEOF(_OperFlags))) {
if (!strcmp(cepp->ce_varname, "can_stealth"))
{
config_status("%s:%i: unknown oper flag '%s' [feature no longer exists]",
@@ -3685,7 +3713,7 @@ int _conf_listen(ConfigFile *conf, ConfigEntry *ce)
{
for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
{
- if ((ofp = config_binary_flags_search(_ListenerFlags, cepp->ce_varname, sizeof(_ListenerFlags)/sizeof(_ListenerFlags[0]))))
+ if ((ofp = config_binary_flags_search(_ListenerFlags, cepp->ce_varname, ARRAY_SIZEOF(_ListenerFlags))))
tmpflags |= ofp->flag;
}
#ifndef USE_SSL
@@ -3830,7 +3858,7 @@ int _test_listen(ConfigFile *conf, ConfigEntry *ce)
cepp->ce_fileptr->cf_filename, cepp->ce_varlinenum);
errors++; continue;
}
- if (!config_binary_flags_search(_ListenerFlags, cepp->ce_varname, sizeof(_ListenerFlags)/sizeof(_ListenerFlags[0])))
+ if (!config_binary_flags_search(_ListenerFlags, cepp->ce_varname, ARRAY_SIZEOF(_ListenerFlags)))
{
config_error("%s:%i: unknown listen option '%s'",
cepp->ce_fileptr->cf_filename, cepp->ce_varlinenum,
@@ -4250,6 +4278,30 @@ int errors = 0, gotfilename=0;
return errors;
}
+void create_tkl_except(char *mask, char *type)
+{
+ ConfigItem_except *ca;
+ struct irc_netmask tmp;
+ OperFlag *opf;
+ ca = MyMallocEx(sizeof(ConfigItem_except));
+ ca->mask = strdup(mask);
+
+ opf = config_binary_flags_search(ExceptTklFlags, type, ARRAY_SIZEOF(ExceptTklFlags));
+ ca->type = opf->flag;
+
+ if (ca->type & TKL_KILL || ca->type & TKL_ZAP || ca->type & TKL_SHUN)
+ {
+ tmp.type = parse_netmask(ca->mask, &tmp);
+ if (tmp.type != HM_HOST)
+ {
+ ca->netmask = MyMallocEx(sizeof(struct irc_netmask));
+ bcopy(&tmp, ca->netmask, sizeof(struct irc_netmask));
+ }
+ }
+ ca->flag.type = CONF_EXCEPT_TKL;
+ AddListItem(ca, conf_except);
+}
+
int _conf_except(ConfigFile *conf, ConfigEntry *ce)
{
@@ -4302,32 +4354,14 @@ int _conf_except(ConfigFile *conf, ConfigEntry *ce)
else if (!strcmp(ce->ce_vardata, "tkl")) {
cep2 = config_find_entry(ce->ce_entries, "mask");
cep3 = config_find_entry(ce->ce_entries, "type");
- ca = MyMallocEx(sizeof(ConfigItem_except));
- ca->mask = strdup(cep2->ce_vardata);
- if (!strcmp(cep3->ce_vardata, "gline"))
- ca->type = TKL_KILL|TKL_GLOBAL;
- else if (!strcmp(cep3->ce_vardata, "qline"))
- ca->type = TKL_NICK;
- else if (!strcmp(cep3->ce_vardata, "gqline"))
- ca->type = TKL_NICK|TKL_GLOBAL;
- else if (!strcmp(cep3->ce_vardata, "gzline"))
- ca->type = TKL_ZAP|TKL_GLOBAL;
- else if (!strcmp(cep3->ce_vardata, "shun"))
- ca->type = TKL_SHUN|TKL_GLOBAL;
- else
- {}
-
- if (ca->type & TKL_KILL || ca->type & TKL_ZAP || ca->type & TKL_SHUN)
+ if (cep3->ce_vardata)
+ create_tkl_except(cep2->ce_vardata, cep3->ce_vardata);
+ else
{
- tmp.type = parse_netmask(ca->mask, &tmp);
- if (tmp.type != HM_HOST)
- {
- ca->netmask = MyMallocEx(sizeof(struct irc_netmask));
- bcopy(&tmp, ca->netmask, sizeof(struct irc_netmask));
- }
+ ConfigEntry *cepp;
+ for (cepp = cep3->ce_entries; cepp; cepp = cepp->ce_next)
+ create_tkl_except(cep2->ce_vardata, cepp->ce_varname);
}
- ca->flag.type = CONF_EXCEPT_TKL;
- AddListItem(ca, conf_except);
}
else {
int value;
@@ -4416,31 +4450,84 @@ int _test_except(ConfigFile *conf, ConfigEntry *ce)
}
#endif
else if (!strcmp(ce->ce_vardata, "tkl")) {
- if (!config_find_entry(ce->ce_entries, "mask"))
- {
- config_error("%s:%i: except tkl without mask item",
- ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
- return 1;
- }
- if (!(cep3 = config_find_entry(ce->ce_entries, "type")))
- {
- config_error("%s:%i: except tkl without type item",
- ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
- return 1;
- }
+ char has_mask = 0, has_type = 0;
+
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
{
- if (!cep->ce_vardata)
- {
- config_error("%s:%i: except tkl item without contents",
- cep->ce_fileptr->cf_filename, cep->ce_varlinenum);
- errors++;
- continue;
- }
if (!strcmp(cep->ce_varname, "mask"))
{
+ if (!cep->ce_vardata)
+ {
+ config_error("%s:%i: except tkl item without contents",
+ cep->ce_fileptr->cf_filename, cep->ce_varlinenum);
+ errors++;
+ continue;
+ }
+ has_mask = 1;
+ }
+ else if (!strcmp(cep->ce_varname, "type"))
+ {
+ if (cep->ce_vardata)
+ {
+ OperFlag *opf;
+ if (!strcmp(cep->ce_vardata, "tkline") ||
+ !strcmp(cep->ce_vardata, "tzline"))
+ {
+ config_error("%s:%i: except tkl of type %s is"
+ " deprecated. Use except ban {}"
+ " instead",
+ cep->ce_fileptr->cf_filename,
+ cep->ce_varlinenum,
+ cep->ce_vardata);
+ errors++;
+ }
+ if (!config_binary_flags_search(ExceptTklFlags,
+ cep->ce_vardata, ARRAY_SIZEOF(ExceptTklFlags)))
+ {
+ config_error("%s:%i: unknown except tkl type %s",
+ cep->ce_fileptr->cf_filename,
+ cep->ce_varlinenum,
+ cep->ce_vardata);
+ return 1;
+ }
+ }
+ else if (cep->ce_entries)
+ {
+ ConfigEntry *cepp;
+ for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
+ {
+ OperFlag *opf;
+ if (!strcmp(cepp->ce_varname, "tkline") ||
+ !strcmp(cepp->ce_varname, "tzline"))
+ {
+ config_error("%s:%i: except tkl of type %s is"
+ " deprecated. Use except ban {}"
+ " instead",
+ cepp->ce_fileptr->cf_filename,
+ cepp->ce_varlinenum,
+ cepp->ce_varname);
+ errors++;
+ }
+ if (!config_binary_flags_search(ExceptTklFlags,
+ cepp->ce_varname, ARRAY_SIZEOF(ExceptTklFlags)))
+ {
+ config_error("%s:%i: unknown except tkl type %s",
+ cepp->ce_fileptr->cf_filename,
+ cepp->ce_varlinenum,
+ cepp->ce_varname);
+ return 1;
+ }
+ }
+ }
+ else
+ {
+ config_error("%s:%i: except tkl item without contents",
+ cep->ce_fileptr->cf_filename, cep->ce_varlinenum);
+ errors++;
+ continue;
+ }
+ has_type = 1;
}
- else if (!strcmp(cep->ce_varname, "type")) {}
else
{
config_error("%s:%i: unknown except tkl directive %s",
@@ -4449,28 +4536,17 @@ int _test_except(ConfigFile *conf, ConfigEntry *ce)
continue;
}
}
- if (!strcmp(cep3->ce_vardata, "gline")) {}
- else if (!strcmp(cep3->ce_vardata, "qline")) {}
- else if (!strcmp(cep3->ce_vardata, "gqline")) {}
- else if (!strcmp(cep3->ce_vardata, "gzline")){}
- else if (!strcmp(cep3->ce_vardata, "shun")) {}
- else if (!strcmp(cep3->ce_vardata, "tkline")) {
- config_error("%s:%i: except tkl of type tkline is deprecated. Use except ban {} instead",
- cep3->ce_fileptr->cf_filename, cep3->ce_varlinenum);
- errors++;
- }
- else if (!strcmp(cep3->ce_vardata, "tzline")) {
- config_error("%s:%i: except tkl of type tzline is deprecated. Use except ban {} instead",
- cep3->ce_fileptr->cf_filename, cep3->ce_varlinenum);
- errors++;
- }
- else
+ if (!has_mask)
{
- config_error("%s:%i: unknown except tkl type %s",
- cep3->ce_fileptr->cf_filename, cep3->ce_varlinenum,
- cep3->ce_vardata);
+ config_error("%s:%i: except tkl without mask item",
+ ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
+ return 1;
+ }
+ if (!has_type)
+ {
+ config_error("%s:%i: except tkl without type item",
+ ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
return 1;
-
}
return errors;
}
@@ -4890,7 +4966,7 @@ int _test_badword(ConfigFile *conf, ConfigEntry *ce) {
}
else
{
- char *errbuf = unreal_checkregex(word->ce_vardata,1,0);
+ char *errbuf = unreal_checkregex(word->ce_vardata,1,1);
if (errbuf)
{
config_error("%s:%i: badword::%s contains an invalid regex: %s",
@@ -5185,7 +5261,7 @@ int _conf_log(ConfigFile *conf, ConfigEntry *ce)
else if (!strcmp(cep->ce_varname, "flags")) {
for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
{
- if ((ofp = config_binary_flags_search(_LogFlags, cepp->ce_varname, sizeof(_LogFlags)/sizeof(_LogFlags[0]))))
+ if ((ofp = config_binary_flags_search(_LogFlags, cepp->ce_varname, ARRAY_SIZEOF(_LogFlags))))
ca->flags |= ofp->flag;
}
}
@@ -5258,7 +5334,7 @@ int _test_log(ConfigFile *conf, ConfigEntry *ce) {
cepp->ce_fileptr->cf_filename, cepp->ce_varlinenum);
errors++; continue;
}
- if (!config_binary_flags_search(_LogFlags, cepp->ce_varname, sizeof(_LogFlags)/sizeof(_LogFlags[0]))) {
+ if (!config_binary_flags_search(_LogFlags, cepp->ce_varname, ARRAY_SIZEOF(_LogFlags))) {
config_error("%s:%i: unknown log flag '%s'",
cepp->ce_fileptr->cf_filename, cepp->ce_varlinenum,
cepp->ce_varname);
@@ -5313,7 +5389,7 @@ int _conf_link(ConfigFile *conf, ConfigEntry *ce)
cepp->ce_fileptr->cf_filename, cepp->ce_varlinenum);
continue;
}
- if ((ofp = config_binary_flags_search(_LinkFlags, cepp->ce_varname, sizeof(_LinkFlags)/sizeof(_LinkFlags[0]))))
+ if ((ofp = config_binary_flags_search(_LinkFlags, cepp->ce_varname, ARRAY_SIZEOF(_LinkFlags))))
link->options |= ofp->flag;
}
@@ -5465,7 +5541,7 @@ int _test_link(ConfigFile *conf, ConfigEntry *ce)
errors++;
continue;
}
- if (!(ofp = config_binary_flags_search(_LinkFlags, cepp->ce_varname, sizeof(_LinkFlags)/sizeof(_LinkFlags[0])))) {
+ if (!(ofp = config_binary_flags_search(_LinkFlags, cepp->ce_varname, ARRAY_SIZEOF(_LinkFlags)))) {
config_error("%s:%i: unknown link option '%s'",
cepp->ce_fileptr->cf_filename, cepp->ce_varlinenum,
cepp->ce_varname);
@@ -5728,6 +5804,8 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce)
}
else if (!strcmp(cep->ce_varname, "silence-limit")) {
tempiConf.silence_limit = atol(cep->ce_vardata);
+ if (loop.ircd_booted)
+ IsupportSetValue(IsupportFind("SILENCE"), cep->ce_vardata);
}
else if (!strcmp(cep->ce_varname, "auto-join")) {
ircstrdup(tempiConf.auto_join_chans, cep->ce_vardata);
@@ -5795,6 +5873,13 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce)
}
else if (!strcmp(cep->ce_varname, "maxchannelsperuser")) {
tempiConf.maxchannelsperuser = atoi(cep->ce_vardata);
+ if (loop.ircd_booted)
+ {
+ char tmpbuf[512];
+ IsupportSetValue(IsupportFind("MAXCHANNELS"), cep->ce_vardata);
+ ircsprintf(tmpbuf, "#:%s", cep->ce_vardata);
+ IsupportSetValue(IsupportFind("CHANLIMIT"), tmpbuf);
+ }
}
else if (!strcmp(cep->ce_varname, "maxdccallow")) {
tempiConf.maxdccallow = atoi(cep->ce_vardata);
@@ -5807,6 +5892,8 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce)
*cep->ce_vardata='-';
}
ircstrdup(tempiConf.network.x_ircnet005, tmp);
+ if (loop.ircd_booted)
+ IsupportSetValue(IsupportFind("NETWORK"), tmp);
cep->ce_vardata = tmp;
}
else if (!strcmp(cep->ce_varname, "default-server")) {
@@ -6489,6 +6576,7 @@ int _test_set(ConfigFile *conf, ConfigEntry *ce)
else if (!strcmp(cep->ce_varname, "hosts")) {
for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
{
+ char *c, *host;
if (!cepp->ce_vardata)
{
config_error("%s:%i: set::hosts item without value",
@@ -6526,6 +6614,60 @@ int _test_set(ConfigFile *conf, ConfigEntry *ce)
continue;
}
+ if ((c = strchr(cepp->ce_vardata, '@')))
+ {
+ char *tmp;
+ if (!(*(c+1)) || (c-cepp->ce_vardata) > USERLEN ||
+ c == cepp->ce_vardata)
+ {
+ config_error("%s:%i: illegal value for set::hosts::%s",
+ cepp->ce_fileptr->cf_filename,
+ cepp->ce_varlinenum,
+ cepp->ce_varname);
+ errors++;
+ continue;
+ }
+ for (tmp = cepp->ce_vardata; tmp != c; tmp++)
+ {
+ if (*tmp == '~' && tmp == cepp->ce_vardata)
+ continue;
+ if (!isallowed(*tmp))
+ break;
+ }
+ if (tmp != c)
+ {
+ config_error("%s:%i: illegal value for set::hosts::%s",
+ cepp->ce_fileptr->cf_filename,
+ cepp->ce_varlinenum,
+ cepp->ce_varname);
+ errors++;
+ continue;
+ }
+ host = c+1;
+ }
+ else
+ host = cepp->ce_vardata;
+ if (strlen(host) > HOSTLEN)
+ {
+ config_error("%s:%i: illegal value for set::hosts::%s",
+ cepp->ce_fileptr->cf_filename,
+ cepp->ce_varlinenum,
+ cepp->ce_varname);
+ errors++;
+ continue;
+ }
+ for (; *host; host++)
+ {
+ if (!isallowed(*host) && *host != ':')
+ {
+ config_error("%s:%i: illegal value for set::hosts::%s",
+ cepp->ce_fileptr->cf_filename,
+ cepp->ce_varlinenum,
+ cepp->ce_varname);
+ errors++;
+ continue;
+ }
+ }
}
}
else if (!strcmp(cep->ce_varname, "cloak-keys"))
@@ -6778,7 +6920,7 @@ int _conf_loadmodule(ConfigFile *conf, ConfigEntry *ce)
*(cSlash+1)=0;
}
hFind = FindFirstFile(ce->ce_vardata, &FindData);
- if (!FindData.cFileName) {
+ if (!FindData.cFileName || hFind == INVALID_HANDLE_VALUE) {
config_status("%s:%i: loadmodule %s: failed to load",
ce->ce_fileptr->cf_filename, ce->ce_varlinenum,
ce->ce_vardata);
@@ -6793,7 +6935,7 @@ int _conf_loadmodule(ConfigFile *conf, ConfigEntry *ce)
if ((ret = Module_Create(path))) {
config_status("%s:%i: loadmodule %s: failed to load: %s",
ce->ce_fileptr->cf_filename, ce->ce_varlinenum,
- FindData.cFileName, ret);
+ path, ret);
free(path);
return -1;
}
@@ -6987,7 +7129,8 @@ int _conf_alias(ConfigFile *conf, ConfigEntry *ce)
ircstrdup(format->format, cep->ce_vardata);
regcomp(&format->expr, cep->ce_vardata, REG_ICASE|REG_EXTENDED);
for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next) {
- if (!strcmp(cepp->ce_varname, "nick")) {
+ if (!strcmp(cepp->ce_varname, "nick") ||
+ !strcmp(cepp->ce_varname, "target")) {
ircstrdup(format->nick, cepp->ce_vardata);
}
else if (!strcmp(cepp->ce_varname, "parameters")) {
@@ -7000,12 +7143,15 @@ int _conf_alias(ConfigFile *conf, ConfigEntry *ce)
format->type = ALIAS_STATS;
else if (!strcmp(cepp->ce_vardata, "normal"))
format->type = ALIAS_NORMAL;
+ else if (!strcmp(cepp->ce_vardata, "channel"))
+ format->type = ALIAS_CHANNEL;
}
}
AddListItem(format, alias->format);
}
- else if (!strcmp(cep->ce_varname, "nick")) {
+ else if (!strcmp(cep->ce_varname, "nick") || !strcmp(cep->ce_varname, "target"))
+ {
ircstrdup(alias->nick, cep->ce_vardata);
}
else if (!strcmp(cep->ce_varname, "type")) {
@@ -7015,6 +7161,8 @@ int _conf_alias(ConfigFile *conf, ConfigEntry *ce)
alias->type = ALIAS_STATS;
else if (!strcmp(cep->ce_vardata, "normal"))
alias->type = ALIAS_NORMAL;
+ else if (!strcmp(cep->ce_vardata, "channel"))
+ alias->type = ALIAS_CHANNEL;
else if (!strcmp(cep->ce_vardata, "command"))
alias->type = ALIAS_COMMAND;
}
@@ -7096,9 +7244,9 @@ int _test_alias(ConfigFile *conf, ConfigEntry *ce) {
cep->ce_varlinenum);
errors++;
}
- if (!config_find_entry(cep->ce_entries, "nick"))
+ if (!config_find_entry(cep->ce_entries, "nick") && !config_find_entry(cep->ce_entries, "target"))
{
- config_error("%s:%i: alias::format::nick missing", cep->ce_fileptr->cf_filename,
+ config_error("%s:%i: alias::format::target missing", cep->ce_fileptr->cf_filename,
cep->ce_varlinenum);
errors++;
}
@@ -7111,7 +7259,8 @@ int _test_alias(ConfigFile *conf, ConfigEntry *ce) {
cepp->ce_varname);
errors++; continue;
}
- if (!strcmp(cepp->ce_varname, "nick"))
+ if (!strcmp(cepp->ce_varname, "nick") ||
+ !strcmp(cepp->ce_varname, "target"))
;
else if (!strcmp(cepp->ce_varname, "type"))
{
@@ -7121,6 +7270,8 @@ int _test_alias(ConfigFile *conf, ConfigEntry *ce) {
;
else if (!strcmp(cepp->ce_vardata, "normal"))
;
+ else if (!strcmp(cepp->ce_vardata, "channel"))
+ ;
else {
config_status("%s:%i: unknown alias type",
cepp->ce_fileptr->cf_filename, cepp->ce_varlinenum);
@@ -7136,7 +7287,7 @@ int _test_alias(ConfigFile *conf, ConfigEntry *ce) {
}
}
}
- else if (!strcmp(cep->ce_varname, "nick"))
+ else if (!strcmp(cep->ce_varname, "nick") || !strcmp(cep->ce_varname, "target"))
;
else if (!strcmp(cep->ce_varname, "type")) {
if (!strcmp(cep->ce_vardata, "services"))
@@ -7145,6 +7296,8 @@ int _test_alias(ConfigFile *conf, ConfigEntry *ce) {
;
else if (!strcmp(cep->ce_vardata, "normal"))
;
+ else if (!strcmp(cep->ce_vardata, "channel"))
+ ;
else if (!strcmp(cep->ce_vardata, "command"))
;
else {
diff --git a/src/s_err.c b/src/s_err.c
index 97ece99c7..bb0ee2421 100644
--- a/src/s_err.c
+++ b/src/s_err.c
@@ -34,7 +34,7 @@ static char *replies[] = {
/* 002 RPL_YOURHOST */ ":%s 002 %s :Your host is %s, running version %s",
/* 003 RPL_CREATED */ ":%s 003 %s :This server was created %s",
/* 004 RPL_MYINFO */ ":%s 004 %s %s %s %s %s",
-/* 005 RPL_PROTOCTL */ ":%s 005 %s",
+/* 005 RPL_ISUPPORT */ ":%s 005 %s %s :are supported by this server",
/* 006 RPL_MAP */ ":%s 006 %s :%s%-*s(%d) %s",
/* 007 RPL_MAPEND */ ":%s 007 %s :End of /MAP",
/* 008 RPL_SNOMASK */ ":%s 008 %s :Server notice mask (%s)",
@@ -134,7 +134,7 @@ static char *replies[] = {
/* 102 */ NULL,
/* 103 */ NULL,
/* 104 */ NULL,
-/* 105 RPL_REMOTEPROTOCTL */ ":%s 105 %s",
+/* 105 RPL_REMOTEISUPPORT */ ":%s 105 %s %s :are supported by this server",
/* 106 */ NULL,
/* 107 */ NULL,
/* 108 */ NULL,
@@ -377,7 +377,7 @@ static char *replies[] = {
/* 337 */ NULL,
/* 338 */ NULL, /* ircu, bahamut */
/* 339 */ NULL, /* Used */
-/* 340 */ NULL, /* ircu */
+/* 340 RPL_USERIP */ ":%s 340 %s :%s %s %s %s %s",
/* 341 RPL_INVITING */ ":%s 341 %s %s %s",
/* 342 RPL_SUMMONING */ ":%s 342 %s %s :User summoned to irc",
/* 343 */ NULL,
@@ -416,7 +416,7 @@ static char *replies[] = {
/* 376 RPL_ENDOFMOTD */ ":%s 376 %s :End of /MOTD command.",
/* 377 */ NULL, /* aircd, austhex */
/* 378 RPL_WHOISHOST */ ":%s 378 %s %s :is connecting from *@%s %s",
-/* 379 RPL_WHOISMODES */ ":%s 379 %s %s :is using modes %s",
+/* 379 RPL_WHOISMODES */ ":%s 379 %s %s :is using modes %s %s",
/* 380 */ NULL, /* aircd, austhex */
/* 381 RPL_YOUREOPER */ ":%s 381 %s :You are now an IRC Operator",
/* 382 RPL_REHASHING */ ":%s 382 %s %s :Rehashing",
diff --git a/src/s_kline.c b/src/s_kline.c
index a2b7aa1c6..13151a8d5 100644
--- a/src/s_kline.c
+++ b/src/s_kline.c
@@ -154,6 +154,10 @@ aTKline *tkl_add_line(int type, char *usermask, char *hostmask, char *reason, ch
nl->ptr.spamf->tkl_duration = spamf_tkl_duration;
nl->ptr.spamf->tkl_reason = strdup(spamf_tkl_reason); /* already encoded */
}
+ if (nl->subtype & SPAMF_USER)
+ loop.do_bancheck_spamf_user = 1;
+ if (nl->subtype & SPAMF_AWAY)
+ loop.do_bancheck_spamf_away = 1;
}
else if (type & TKL_KILL || type & TKL_ZAP || type & TKL_SHUN)
{
@@ -420,7 +424,7 @@ int find_tkline_match(aClient *cptr, int xx)
if (excepts->netmask)
{
- if (match_ip(cptr->ip, NULL, NULL, excepts->netmask))
+ if (match_ip(cptr->ip, host2, excepts->mask, excepts->netmask))
return 1;
} else
if (!match(excepts->mask, host) || !match(excepts->mask, host2))
@@ -552,6 +556,24 @@ int find_shun(aClient *cptr)
return 2;
}
+/** Checks if the user matches a spamfilter of type 'u' (user,
+ * nick!user@host:realname ban).
+ * Written by: Syzop
+ * Assumes: only call for clients, possible assume on local clients [?]
+ * Return values: see dospamfilter()
+ */
+int find_spamfilter_user(aClient *sptr)
+{
+char spamfilter_user[NICKLEN + USERLEN + HOSTLEN + REALLEN + 64]; /* n!u@h:r */
+
+ if (IsAnOper(sptr))
+ return 0;
+
+ ircsprintf(spamfilter_user, "%s!%s@%s:%s",
+ sptr->name, sptr->user->username, sptr->user->realhost, sptr->info);
+ return dospamfilter(sptr, spamfilter_user, SPAMF_USER, NULL);
+}
+
aTKline *find_qline(aClient *cptr, char *nick, int *ishold)
{
aTKline *lp;
@@ -586,7 +608,7 @@ aTKline *find_qline(aClient *cptr, char *nick, int *ishold)
return lp;
}
- chost = cptr->sockhost;
+ chost = cptr->user ? cptr->user->realhost : (MyConnect(cptr) ? cptr->sockhost : "unknown");
cname = cptr->user ? cptr->user->username : "unknown";
strcpy(host, make_user_host(cname, chost));
@@ -603,7 +625,7 @@ aTKline *find_qline(aClient *cptr, char *nick, int *ishold)
continue;
if (excepts->netmask)
{
- if (match_ip(cptr->ip, NULL, NULL, excepts->netmask))
+ if (MyConnect(cptr) && match_ip(cptr->ip, NULL, NULL, excepts->netmask))
return NULL;
} else
if (!match(excepts->mask, host) || (host2 && !match(excepts->mask, host2)))
@@ -1060,7 +1082,8 @@ int m_tkl(aClient *cptr, aClient *sptr, int parc, char *parv[])
parv[1], parv[2], parv[3], parv[4],
tk->setby, tk->expire_at, tk->set_at, tk->ptr.spamf->tkl_duration,
tk->ptr.spamf->tkl_reason, tk->reason);
- } else
+ }
+ else if (type & TKL_GLOBAL)
sendto_serv_butone(cptr,
":%s TKL %s %s %s %s %s %ld %ld :%s", sptr->name,
parv[1], parv[2], parv[3], parv[4],
@@ -1441,9 +1464,17 @@ int dospamfilter(aClient *sptr, char *str_in, int type, char *target)
{
aTKline *tk;
int n;
-char *str = (char *)StripControlCodes(str_in);
+char *str;
- if (!IsPerson(sptr) || IsAnOper(sptr) || IsULine(sptr))
+ if (type == SPAMF_USER)
+ str = str_in;
+ else
+ str = (char *)StripControlCodes(str_in);
+
+ /* (note: using sptr->user check here instead of IsPerson()
+ * due to SPAMF_USER where user isn't marked as client/person yet.
+ */
+ if (!sptr->user || IsAnOper(sptr) || IsULine(sptr))
return 0;
for (tk = tklines[tkl_hash('F')]; tk; tk = tk->next)
@@ -1494,6 +1525,16 @@ char *str = (char *)StripControlCodes(str_in);
sendnotice(sptr, "DCC to %s blocked: %s",
target, unreal_decodespace(tk->ptr.spamf->tkl_reason));
break;
+ case SPAMF_AWAY:
+ /* hack to deal with 'after-away-was-set-filters' */
+ if (sptr->user->away && !strcmp(str_in, sptr->user->away))
+ {
+ /* free away & broadcast the unset */
+ MyFree(sptr->user->away);
+ sptr->user->away = NULL;
+ sendto_serv_butone_token(sptr, sptr->name, MSG_AWAY, TOK_AWAY, "");
+ }
+ break;
default:
break;
}
diff --git a/src/s_misc.c b/src/s_misc.c
index 4ca6ba19b..71f77cadb 100644
--- a/src/s_misc.c
+++ b/src/s_misc.c
@@ -597,11 +597,8 @@ int exit_client(aClient *cptr, aClient *sptr, aClient *from, char *comment)
for (acptr = client; acptr; acptr = next)
{
next = acptr->next;
- if (IsServer(acptr) && acptr->srvptr == sptr) {
- exit_client(sptr, acptr, /* RECURSION */
- sptr, comment1);
- RunHook(HOOKTYPE_SERVER_QUIT, acptr);
- }
+ if (IsServer(acptr) && acptr->srvptr == sptr)
+ exit_client(sptr, acptr, sptr, comment1); /* RECURSION */
/*
* I am not masking SQUITS like I do QUITs. This
* is probobly something we could easily do, but
@@ -990,6 +987,8 @@ int flags = 0;
case 'P': flags |= SPAMF_PART; break;
case 'q': flags |= SPAMF_QUIT; break;
case 'd': flags |= SPAMF_DCC; break;
+ case 'u': flags |= SPAMF_USER; break;
+ case 'a': flags |= SPAMF_AWAY; break;
default:
if (sptr)
{
@@ -1020,6 +1019,10 @@ int flags = 0;
return SPAMF_QUIT;
if (!strcmp(s, "dcc"))
return SPAMF_DCC;
+ if (!strcmp(s, "user"))
+ return SPAMF_USER;
+ if (!strcmp(s, "away"))
+ return SPAMF_AWAY;
return 0;
}
@@ -1042,6 +1045,10 @@ char *p = buf;
*p++ = 'q';
if (v & SPAMF_DCC)
*p++ = 'd';
+ if (v & SPAMF_USER)
+ *p++ = 'u';
+ if (v & SPAMF_AWAY)
+ *p++ = 'a';
*p = '\0';
return buf;
}
@@ -1063,6 +1070,10 @@ char *spamfilter_inttostring_long(int v)
return "QUIT";
case SPAMF_DCC:
return "DCC";
+ case SPAMF_USER:
+ return "user";
+ case SPAMF_AWAY:
+ return "AWAY";
default:
return "UNKNOWN";
}
diff --git a/src/s_serv.c b/src/s_serv.c
index 75b47288f..60297faf1 100644
--- a/src/s_serv.c
+++ b/src/s_serv.c
@@ -138,6 +138,8 @@ extern fdlist serv_fdlist;
CMD_FUNC(m_version)
{
extern char serveropts[];
+ extern char *IsupportStrings[];
+ int reply, i;
/* Only allow remote VERSIONs if registered -- Syzop */
if (!IsPerson(sptr) && !IsServer(cptr))
@@ -163,15 +165,15 @@ CMD_FUNC(m_version)
if (IsAnOper(sptr))
sendto_one(sptr, ":%s NOTICE %s :%s", me.name, sptr->name, curl_version());
#endif
- if (MyClient(sptr)) {
+ if (MyClient(sptr))
normal:
- sendto_one(sptr, ":%s 005 %s " PROTOCTL_CLIENT_1, me.name, sptr->name, PROTOCTL_PARAMETERS_1);
- sendto_one(sptr, ":%s 005 %s " PROTOCTL_CLIENT_2, me.name, sptr->name, PROTOCTL_PARAMETERS_2);
- }
- else {
- sendto_one(sptr, ":%s 105 %s " PROTOCTL_CLIENT_1, me.name, sptr->name, PROTOCTL_PARAMETERS_1);
- sendto_one(sptr, ":%s 105 %s " PROTOCTL_CLIENT_2, me.name, sptr->name, PROTOCTL_PARAMETERS_2);
- }
+ reply = RPL_ISUPPORT;
+ else
+ reply = RPL_REMOTEISUPPORT;
+ /* Send the text */
+ for (i = 0; IsupportStrings[i]; i++)
+ sendto_one(sptr, rpl_str(reply), me.name, sptr->name,
+ IsupportStrings[i]);
}
return 0;
}
@@ -437,6 +439,8 @@ CMD_FUNC(m_watch)
*/
if (*s == '+')
{
+ if (!*(s+1))
+ continue;
if (do_nick_name(s + 1))
{
if (sptr->watches >= MAXWATCH)
@@ -461,6 +465,8 @@ CMD_FUNC(m_watch)
*/
if (*s == '-')
{
+ if (!*(s+1))
+ continue;
del_from_watch_hash_table(s + 1, sptr);
show_watch(sptr, s + 1, RPL_WATCHOFF, RPL_WATCHOFF);
diff --git a/src/s_svs.c b/src/s_svs.c
index 69b341254..6e4c70fde 100644
--- a/src/s_svs.c
+++ b/src/s_svs.c
@@ -220,17 +220,20 @@ void strrangetok(char *in, char *out, char tok, short first, short last) {
int m_alias(aClient *cptr, aClient *sptr, int parc, char *parv[], char *cmd) {
ConfigItem_alias *alias;
aClient *acptr;
- if (parc < 2 || *parv[1] == '\0') {
+ if (parc < 2 || *parv[1] == '\0')
+ {
sendto_one(sptr, err_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
return -1;
}
- if (!(alias = Find_alias(cmd))) {
+ if (!(alias = Find_alias(cmd)))
+ {
sendto_one(sptr, ":%s %d %s %s :Unknown command",
me.name, ERR_UNKNOWNCOMMAND, parv[0], cmd);
return 0;
}
- if (alias->type == ALIAS_SERVICES) {
+ if (alias->type == ALIAS_SERVICES)
+ {
if (SERVICES_NAME && (acptr = find_person(alias->nick, NULL)))
sendto_one(acptr, ":%s %s %s@%s :%s", parv[0],
IsToken(acptr->from) ? TOK_PRIVATE : MSG_PRIVATE,
@@ -239,7 +242,8 @@ int m_alias(aClient *cptr, aClient *sptr, int parc, char *parv[], char *cmd) {
sendto_one(sptr, err_str(ERR_SERVICESDOWN), me.name,
parv[0], alias->nick);
}
- else if (alias->type == ALIAS_STATS) {
+ else if (alias->type == ALIAS_STATS)
+ {
if (STATS_SERVER && (acptr = find_person(alias->nick, NULL)))
sendto_one(acptr, ":%s %s %s@%s :%s", parv[0],
IsToken(acptr->from) ? TOK_PRIVATE : MSG_PRIVATE,
@@ -248,11 +252,13 @@ int m_alias(aClient *cptr, aClient *sptr, int parc, char *parv[], char *cmd) {
sendto_one(sptr, err_str(ERR_SERVICESDOWN), me.name,
parv[0], alias->nick);
}
- else if (alias->type == ALIAS_NORMAL) {
- if ((acptr = find_person(alias->nick, NULL))) {
+ else if (alias->type == ALIAS_NORMAL)
+ {
+ if ((acptr = find_person(alias->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,
+ sptr->user->username, GetHost(sptr),
alias->nick, parv[1]);
else
sendto_one(acptr, ":%s %s %s :%s", parv[0],
@@ -263,11 +269,33 @@ int m_alias(aClient *cptr, aClient *sptr, int parc, char *parv[], char *cmd) {
sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name,
parv[0], alias->nick);
}
- else if (alias->type == ALIAS_COMMAND) {
+ else if (alias->type == ALIAS_CHANNEL)
+ {
+ aChannel *chptr;
+ if ((chptr = find_channel(alias->nick, NULL)))
+ {
+ if (!can_send(sptr, chptr, parv[1], 0))
+ {
+ sendto_channelprefix_butone_tok(sptr,
+ sptr, chptr,
+ PREFIX_ALL,
+ MSG_PRIVATE,
+ TOK_PRIVATE,
+ chptr->chname, parv[1], 0);
+ return 0;
+ }
+ }
+ sendto_one(sptr, err_str(ERR_CANNOTDOCOMMAND), me.name, parv[0],
+ cmd, "You may not use this command at this time");
+ }
+ else if (alias->type == ALIAS_COMMAND)
+ {
ConfigItem_alias_format *format;
char *ptr = parv[1];
- for (format = alias->format; format; format = (ConfigItem_alias_format *)format->next) {
- if (regexec(&format->expr, ptr, 0, NULL, 0) == 0) {
+ for (format = alias->format; format; format = (ConfigItem_alias_format *)format->next)
+ {
+ if (regexec(&format->expr, ptr, 0, NULL, 0) == 0)
+ {
/* Parse the parameters */
int i = 0, j = 0, k = 1;
char output[501];
@@ -275,13 +303,16 @@ int m_alias(aClient *cptr, aClient *sptr, int parc, char *parv[], char *cmd) {
char *current = MyMalloc(strlen(parv[1])+1);
bzero(current, strlen(parv[1])+1);
bzero(output, sizeof output);
- while(format->parameters[i] && j < 500) {
+ while(format->parameters[i] && j < 500)
+ {
k = 0;
- if (format->parameters[i] == '%') {
+ if (format->parameters[i] == '%')
+ {
i++;
if (format->parameters[i] == '%')
output[j++] = '%';
- else if (isdigit(format->parameters[i])) {
+ else if (isdigit(format->parameters[i]))
+ {
for(; isdigit(format->parameters[i]) && k < 2; i++, k++) {
nums[k] = format->parameters[i];
}
@@ -301,7 +332,14 @@ int m_alias(aClient *cptr, aClient *sptr, int parc, char *parv[], char *cmd) {
j += strlen(current);
}
- else {
+ else if (format->parameters[i] == 'n' ||
+ format->parameters[i] == 'N')
+ {
+ strlcat(output, parv[0], sizeof output);
+ j += strlen(parv[0]);
+ }
+ else
+ {
output[j++] = '%';
output[j++] = format->parameters[i];
}
@@ -311,7 +349,8 @@ int m_alias(aClient *cptr, aClient *sptr, int parc, char *parv[], char *cmd) {
output[j++] = format->parameters[i++];
}
output[j] = 0;
- if (format->type == ALIAS_SERVICES) {
+ 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,
@@ -320,7 +359,8 @@ int m_alias(aClient *cptr, aClient *sptr, int parc, char *parv[], char *cmd) {
sendto_one(sptr, err_str(ERR_SERVICESDOWN), me.name,
parv[0], format->nick);
}
- else if (format->type == ALIAS_STATS) {
+ 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,
@@ -329,8 +369,10 @@ int m_alias(aClient *cptr, aClient *sptr, int parc, char *parv[], char *cmd) {
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))) {
+ 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,
@@ -344,6 +386,25 @@ int m_alias(aClient *cptr, aClient *sptr, int parc, char *parv[], char *cmd) {
sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name,
parv[0], format->nick);
}
+ else if (format->type == ALIAS_CHANNEL)
+ {
+ aChannel *chptr;
+ if ((chptr = find_channel(alias->nick, NULL)))
+ {
+ if (!can_send(sptr, chptr, parv[1], 0))
+ {
+ sendto_channelprefix_butone_tok(sptr,
+ sptr, chptr,
+ PREFIX_ALL, MSG_PRIVATE,
+ TOK_PRIVATE, chptr->chname,
+ parv[1], 0);
+ return 0;
+ }
+ }
+ sendto_one(sptr, err_str(ERR_CANNOTDOCOMMAND), me.name,
+ parv[0], cmd,
+ "You may not use this command at this time");
+ }
free(current);
break;
}
diff --git a/src/s_user.c b/src/s_user.c
index 72f1a49a3..d002036ea 100644
--- a/src/s_user.c
+++ b/src/s_user.c
@@ -69,6 +69,10 @@ void iNAH_host(aClient *sptr, char *host)
{
if (!sptr->user)
return;
+
+ if (UHOST_ALLOWED == UHALLOW_REJOIN)
+ rejoin_doparts(sptr);
+
if (sptr->user->virthost)
{
MyFree(sptr->user->virthost);
@@ -79,6 +83,9 @@ void iNAH_host(aClient *sptr, char *host)
sendto_serv_butone_token(&me, sptr->name, MSG_SETHOST,
TOK_SETHOST, "%s", sptr->user->virthost);
sptr->umodes |= UMODE_SETHOST;
+
+ if (UHOST_ALLOWED == UHALLOW_REJOIN)
+ rejoin_dojoinandmode(sptr);
}
long set_usermode(char *umode)
@@ -602,7 +609,12 @@ int check_for_target_limit(aClient *sptr, void *target, const char *name)
** a change should be global, some confusion would
** result if only few servers allowed it...
*/
-#if defined(CHINESE_NICK) || defined(JAPANESE_NICK)
+
+#if defined(NICK_GB2312) || defined(NICK_GBK) || defined(NICK_GBK_JAP)
+#define NICK_MULTIBYTE
+#endif
+
+#ifdef NICK_MULTIBYTE
/* Chinese Nick Verification Code - Added by RexHsu on 08/09/00 (beta2)
* Now Support All GBK Words,Thanks to Mr.WebBar !
* Special Char Bugs Fixed by RexHsu 09/01/00 I dont know whether it is
@@ -619,34 +631,56 @@ int check_for_target_limit(aClient *sptr, void *target, const char *name)
* 6. ÈÕÎÄÆ½¼ÙÃû±àÂëÇø(a4a1-a4f3) -->work correctly?maybe...
* 7. ÈÕÎÄÆ¬¼ÙÃû±àÂëÇø(a5a1-a5f7) -->work correctly?maybe...
* 8. º«ÎıàÂëÇø(xxxx-yyyy)
+ *
+ * isvalidChinese() rewritten by Xuefer (2004-10-10),
+ * this will probably be the last time we do it this way,
+ * in 3.2.3 we are gonna try a more generic aproach. -- Syzop
*/
-int isvalidChinese(const unsigned char c1, const unsigned char c2)
+
+int isvalidChinese(const unsigned char c1, const unsigned char c2)
{
- const unsigned int GBK_S = 0xb0a1;
- const unsigned int GBK_E = 0xf7fe;
- const unsigned int GBK_2_S = 0x8140;
- const unsigned int GBK_2_E = 0xa0fe;
- const unsigned int GBK_3_S = 0xaa40;
- const unsigned int GBK_3_E = 0xfea0;
- const unsigned int JPN_PING_S = 0xa4a1;
- const unsigned int JPN_PING_E = 0xa4f3;
- const unsigned int JPN_PIAN_S = 0xa5a1;
- const unsigned int JPN_PIAN_E = 0xa5f7;
- unsigned int AWord = c1 * 256 + c2;
-#if defined(CHINESE_NICK) && defined(JAPANESE_NICK)
- return (AWord >= GBK_S && AWord <= GBK_E || AWord >= GBK_2_S
- && AWord <= GBK_2_E || AWord >= JPN_PING_S && AWord <= JPN_PING_E
- || AWord >= JPN_PIAN_S && AWord <= JPN_PIAN_E) ? 1 : 0;
+ unsigned int w = (((unsigned int)c1) << 8) | c2;
+
+/* rang of w/c1/c2 (rw never used) */
+#define rw(s, e) (w >= ((unsigned int )s) && w <= ((unsigned int )e))
+#define r1(s, e) (c1 >= ((unsigned char)s) && c1 <= ((unsigned char)e))
+#define r2(s, e) (c2 >= ((unsigned char)s) && c2 <= ((unsigned char)e))
+#define e1(e) (c1 == (unsigned char)e)
+
+#ifdef NICK_GBK_JAP
+ /* GBK/1 */
+ /* JIS_PIN part 1 */
+ if (e1(0xA4) && r2(0xA1, 0xF3)) return 1;
+ /* JIS_PIN part 2 */
+ if (e1(0xA5) && r2(0xA1, 0xF6)) return 1;
#endif
-#if defined(CHINESE_NICK) && !defined(JAPANESE_NICK)
- return (AWord >= GBK_S && AWord <= GBK_E || AWord >= GBK_2_S
- && AWord <= GBK_2_E ? 1 : 0);
-#endif
-#if !defined(CHINESE_NICK) && defined(JAPANESE_NICK)
- return (AWord >= JPN_PING_S && AWord <= JPN_PING_E
- || AWord >= JPN_PIAN_S && AWord <= JPN_PIAN_E) ? 1 : 0;
+#if defined(NICK_GB2312) || defined(NICK_GBK)
+ /* GBK/2 BC with GB2312 */
+ if (r2(0xA1, 0xFE))
+ {
+ /* Block 16-55, ordered by Chinese Spelling(PinYin) 3755 chars */
+ if (r1(0xB0, 0xD6)) return 1;
+ /* Block 55 is NOT full (w <= 0xd7f9) */
+ if (e1(0xD7) && c2 <= (unsigned char)0xF9 /* r2(0xA1, 0xF9)*/) return 1;
+ /* Block 56-87 is level 2 chars, ordered by writing 3008 chars */
+ if (r1(0xD8, 0xF7)) return 1;
+ }
#endif
+#ifdef NICK_GBK
+ /* GBK/3 */
+ if (r1(0x81, 0xA0) && r2(0x40, 0xFE)) return 1;
+ /* GBK/4 */
+ if (r2(0x40, 0xA0) && r1(0xAA, 0xFE)) return 1;
+#endif
+
+ /* all failed */
+ return 0;
+
+#undef rw
+#undef r1
+#undef r2
+#undef e1
}
/* Chinese Nick Supporting Code (Switch Mode) - Modified by RexHsu on 08/09/00 */
@@ -965,6 +999,9 @@ int register_user(aClient *cptr, aClient *sptr, char *nick, char *username, char
return xx;
}
find_shun(sptr);
+ xx = find_spamfilter_user(sptr);
+ if (xx < 0)
+ return xx;
RunHookReturnInt(HOOKTYPE_PRE_LOCAL_CONNECT, sptr, !=0);
}
else
@@ -1000,9 +1037,12 @@ int register_user(aClient *cptr, aClient *sptr, char *nick, char *username, char
sendto_one(sptr, ":%s 004 %s %s CR1.8.03-%s %s %s",
me.name, parv[0],
me.name, version, umodestring, cmodestring);
-
- sendto_one(sptr, ":%s 005 %s " PROTOCTL_CLIENT_1, me.name, nick, PROTOCTL_PARAMETERS_1);
- sendto_one(sptr, ":%s 005 %s " PROTOCTL_CLIENT_2, me.name, nick, PROTOCTL_PARAMETERS_2);
+ {
+ extern char *IsupportStrings[];
+ int i;
+ for (i = 0; IsupportStrings[i]; i++)
+ sendto_one(sptr, rpl_str(RPL_ISUPPORT), me.name, nick, IsupportStrings[i]);
+ }
#ifdef USE_SSL
if (sptr->flags & FLAGS_SSL)
if (sptr->ssl)
@@ -1319,7 +1359,7 @@ CMD_FUNC(m_nick)
}
if (!IsULine(sptr) && (tklban = find_qline(sptr, nick, &ishold)))
{
- if (IsServer(sptr) && !ishold)
+ if (IsServer(sptr) && !ishold) /* server introducing new client */
{
acptrs =
(aClient *)find_server_b64_or_real(sptr->user ==
@@ -1332,15 +1372,14 @@ CMD_FUNC(m_nick)
&& !IsServer(sptr) ? sptr->name : ""),
acptrs ? acptrs->name : "unknown server");
}
- else if (!ishold)
+
+ if (IsServer(cptr) && IsPerson(sptr)) /* remote user changing nick */
{
- sendto_snomask(SNO_QLINE, "Q:lined nick %s from %s on %s",
- nick,
- *sptr->name ? sptr->name : "",
- me.name);
+ sendto_snomask(SNO_QLINE, "Q:lined nick %s from %s on %s", nick,
+ sptr->name, sptr->srvptr ? sptr->srvptr->name : "");
}
- if (!IsServer(cptr))
+ if (!IsServer(cptr)) /* local */
{
if (ishold)
{
@@ -1351,6 +1390,7 @@ CMD_FUNC(m_nick)
}
if (!IsOper(cptr))
{
+ sptr->since += 4; /* lag them up */
sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME),
me.name, BadPtr(parv[0]) ? "*" : parv[0],
nick, tklban->reason);
@@ -1656,6 +1696,7 @@ CMD_FUNC(m_nick)
cptr->name, backupbuf);
sptr->lastnick = TStime();
}
+ newusr = 1;
}
else if (sptr->name[0] && IsPerson(sptr))
{
@@ -1670,7 +1711,7 @@ CMD_FUNC(m_nick)
{
for (mp = sptr->user->channel; mp; mp = mp->next)
{
- if (is_banned(sptr, mp->chptr, BANCHK_NICK) && !is_chanownprotop(sptr, mp->chptr))
+ if (!is_skochanop(sptr, mp->chptr) && is_banned(sptr, mp->chptr, BANCHK_NICK))
{
sendto_one(sptr,
err_str(ERR_BANNICKCHANGE),
diff --git a/src/send.c b/src/send.c
index d78645d3d..a10d5cb92 100644
--- a/src/send.c
+++ b/src/send.c
@@ -574,10 +574,11 @@ void sendto_chmodemucrap(aClient *from, aChannel *chptr, char *text)
Member *lp;
aClient *acptr;
int i;
+ int remote = MyClient(from) ? 0 : 1;
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 */
+ sprintf(xcmd, ":IRC!IRC@%s PRIVMSG %s :%s: %s", me.name, chptr->chname, from->name, text); /* local */
++sentalong_marker;
for (lp = chptr->members; lp; lp = lp->next)
@@ -588,6 +589,8 @@ void sendto_chmodemucrap(aClient *from, aChannel *chptr, char *text)
continue;
if (!(lp->flags & (CHFL_CHANOP|CHFL_CHANOWNER|CHFL_CHANPROT)))
continue;
+ if (remote && (acptr->from == from->from)) /* don't send it back to where it came from */
+ continue;
i = acptr->from->slot;
if (MyConnect(acptr) && IsRegisteredUser(acptr))
{
@@ -1137,7 +1140,7 @@ void sendto_common_channels(aClient *user, char *pattern, ...)
for (users = channels->chptr->members; users; users = users->next)
{
cptr = users->cptr;
- if (!MyConnect(cptr) || sentalong[cptr->slot] == sentalong_marker)
+ if (!MyConnect(cptr) || (cptr->slot < 0) || (sentalong[cptr->slot] == sentalong_marker))
continue;
if ((channels->chptr->mode.mode & MODE_AUDITORIUM) &&
!(is_chanownprotop(user, channels->chptr) || is_chanownprotop(cptr, channels->chptr)))
diff --git a/src/umodes.c b/src/umodes.c
index 6d80aa60a..d2ee92d18 100644
--- a/src/umodes.c
+++ b/src/umodes.c
@@ -91,6 +91,7 @@ long SNO_FNICKCHANGE = 0L;
long SNO_QLINE = 0L;
long SNO_SPAMF = 0L;
long SNO_SNOTICE = 0L;
+long SNO_OPER = 0L;
long AllUmodes; /* All umodes */
long SendUmodes; /* All umodes which are sent to other servers (global umodes) */
@@ -166,6 +167,7 @@ void umode_init(void)
SnomaskAdd(NULL, 'q', umode_allow_opers, &SNO_QLINE);
SnomaskAdd(NULL, 'S', umode_allow_opers, &SNO_SPAMF);
SnomaskAdd(NULL, 's', umode_allow_all, &SNO_SNOTICE);
+ SnomaskAdd(NULL, 'o', umode_allow_opers, &SNO_OPER);
}
void make_umodestr(void)
diff --git a/src/win32/Win32GUI.c b/src/win32/Win32GUI.c
deleted file mode 100644
index b88d52dd0..000000000
--- a/src/win32/Win32GUI.c
+++ /dev/null
@@ -1,2540 +0,0 @@
-/************************************************************************
- * IRC - Internet Relay Chat, Win32GUI.c
- * 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
- * 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.
- */
-
-#ifndef IRCDTOTALVERSION
-#define IRCDTOTALVERSION BASE_VERSION PATCH1 PATCH2 PATCH3 PATCH4 PATCH5 PATCH6 PATCH7 PATCH8 PATCH9
-#endif
-
-#define WIN32_VERSION BASE_VERSION PATCH1 PATCH2 PATCH3 PATCH4
-#include "resource.h"
-#include "version.h"
-#include "setup.h"
-#ifdef INET6
-#include
-#include
-#endif
-#include
-#include
-#include
-#include "struct.h"
-#include "common.h"
-#include "sys.h"
-#include "numeric.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include "h.h"
-#include
-#include
-
-#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) {\
- if (!IsWindow(handle)) { \
- handle = CreateDialog(inst, template, parent, (DLGPROC)proc); ShowWindow(handle, SW_SHOW); \
- }\
- else\
- SetForegroundWindow(handle);\
-}
-/* Comments:
- *
- * DrBin did a great job with the original GUI, but he has been gone a long time
- * in his absense it was decided it would be best to continue windows development.
- * The new code is based on his so it will be pretty much similar in features, my
- * main goal is to make it more stable. A lot of what I know about GUI coding
- * I learned from DrBin so thanks to him for teaching me :) -- codemastr
- */
-
-LRESULT CALLBACK MainDLG(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK LicenseDLG(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK CreditsDLG(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK DalDLG(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK HelpDLG(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK StatusDLG(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK ConfigErrorDLG(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK ColorDLG(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK FromVarDLG(HWND, UINT, WPARAM, LPARAM, unsigned char *, unsigned char **);
-LRESULT CALLBACK FromFileReadDLG(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK FromFileDLG(HWND, UINT, WPARAM, LPARAM);
-
-typedef struct {
- int *size;
- unsigned char **buffer;
-} StreamIO;
-
-extern void SocketLoop(void *dummy);
-int CountRTFSize(unsigned char *);
-void IRCToRTF(unsigned char *, unsigned char *);
-HINSTANCE hInst;
-NOTIFYICONDATA SysTray;
-void CleanUp(void);
-HTREEITEM AddItemToTree(HWND, LPSTR, int, short);
-void win_map(aClient *, HWND, short);
-extern Link *Servers;
-extern ircstats IRCstats;
-unsigned char *errors = NULL, *RTFBuf = NULL;
-extern aMotd *botmotd, *opermotd, *motd, *rules;
-extern VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
-extern BOOL IsService;
-void CleanUp(void)
-{
- Shell_NotifyIcon(NIM_DELETE ,&SysTray);
-}
-void CleanUpSegv(int sig)
-{
- Shell_NotifyIcon(NIM_DELETE ,&SysTray);
-}
-HWND hStatusWnd;
-HWND hwIRCDWnd=NULL;
-HWND hwTreeView;
-HWND hWndMod;
-HANDLE hMainThread = 0;
-UINT WM_TASKBARCREATED, WM_FINDMSGSTRING;
-FARPROC lpfnOldWndProc;
-HMENU hContext;
-OSVERSIONINFO VerInfo;
-char OSName[256];
-HWND hFind;
-#ifdef USE_LIBCURL
-extern char *find_loaded_remote_include(char *url);
-#endif
-
-void TaskBarCreated() {
- HICON hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON,16, 16, 0);
- SysTray.cbSize = sizeof(NOTIFYICONDATA);
- SysTray.hIcon = hIcon;
- SysTray.hWnd = hwIRCDWnd;
- SysTray.uCallbackMessage = WM_USER;
- SysTray.uFlags = NIF_ICON|NIF_TIP|NIF_MESSAGE;
- SysTray.uID = 0;
- lstrcpy(SysTray.szTip, WIN32_VERSION);
- Shell_NotifyIcon(NIM_ADD ,&SysTray);
-}
-
-LRESULT LinkSubClassFunc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
- static HCURSOR hCursor;
- if (!hCursor)
- hCursor = LoadCursor(hInst, MAKEINTRESOURCE(CUR_HAND));
- if (Message == WM_MOUSEMOVE || WM_LBUTTONUP)
- SetCursor(hCursor);
-
- return CallWindowProc((WNDPROC)lpfnOldWndProc, hWnd, Message, wParam, lParam);
-}
-
-
-
-LRESULT RESubClassFunc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
- POINT p;
- RECT r;
- DWORD start, end;
- unsigned char string[500];
-
- if (Message == WM_GETDLGCODE)
- return DLGC_WANTALLKEYS;
-
-
- if (Message == WM_CONTEXTMENU) {
- p.x = GET_X_LPARAM(lParam);
- p.y = GET_Y_LPARAM(lParam);
- if (GET_X_LPARAM(lParam) == -1 && GET_Y_LPARAM(lParam) == -1) {
- GetClientRect(hWnd, &r);
- p.x = (int)((r.left + r.right)/2);
- p.y = (int)((r.top + r.bottom)/2);
- ClientToScreen(hWnd,&p);
- }
- if (!SendMessage(hWnd, EM_CANUNDO, 0, 0))
- EnableMenuItem(hContext, IDM_UNDO, MF_BYCOMMAND|MF_GRAYED);
- else
- EnableMenuItem(hContext, IDM_UNDO, MF_BYCOMMAND|MF_ENABLED);
- if (!SendMessage(hWnd, EM_CANPASTE, 0, 0))
- EnableMenuItem(hContext, IDM_PASTE, MF_BYCOMMAND|MF_GRAYED);
- else
- EnableMenuItem(hContext, IDM_PASTE, MF_BYCOMMAND|MF_ENABLED);
- if (GetWindowLong(hWnd, GWL_STYLE) & ES_READONLY) {
- EnableMenuItem(hContext, IDM_CUT, MF_BYCOMMAND|MF_GRAYED);
- EnableMenuItem(hContext, IDM_DELETE, MF_BYCOMMAND|MF_GRAYED);
- }
- else {
- EnableMenuItem(hContext, IDM_CUT, MF_BYCOMMAND|MF_ENABLED);
- EnableMenuItem(hContext, IDM_DELETE, MF_BYCOMMAND|MF_ENABLED);
- }
- SendMessage(hWnd, EM_GETSEL, (WPARAM)&start, (LPARAM)&end);
- if (start == end)
- EnableMenuItem(hContext, IDM_COPY, MF_BYCOMMAND|MF_GRAYED);
- else
- EnableMenuItem(hContext, IDM_COPY, MF_BYCOMMAND|MF_ENABLED);
- TrackPopupMenu(hContext,TPM_LEFTALIGN|TPM_RIGHTBUTTON,p.x,p.y,0,GetParent(hWnd),NULL);
- return 0;
- }
-
- return CallWindowProc((WNDPROC)lpfnOldWndProc, hWnd, Message, wParam, lParam);
-}
-
-/* Somewhat respectable RTF to IRC parser
- * (c) 2001 codemastr
- */
-DWORD CALLBACK SplitIt(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) {
- StreamIO *stream = (StreamIO*)dwCookie;
- if (*stream->size == 0)
- {
- pcb = 0;
- *stream->buffer = 0;
- }
- else if (cb <= *stream->size) {
- memcpy(pbBuff, *stream->buffer, cb);
- *stream->buffer += cb;
- *stream->size -= cb;
- *pcb = cb;
-
- }
- else {
- memcpy(pbBuff, *stream->buffer, *stream->size);
- *pcb = *stream->size;
- *stream->size = 0;
- }
- return 0;
-}
-
-DWORD CALLBACK BufferIt(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) {
- unsigned char *buf2;
- static long size = 0;
- if (!RTFBuf)
- size = 0;
-
- buf2 = MyMalloc(size+cb+1);
-
- if (RTFBuf)
- memcpy(buf2,RTFBuf,size);
-
- memcpy(buf2+size,pbBuff,cb);
-
- size += cb;
- if (RTFBuf)
- MyFree(RTFBuf);
-
- RTFBuf = buf2;
-
- pcb = &cb;
- return 0;
-}
-
-#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 (iseol(*pbBuff) || *pbBuff == '{' || *pbBuff == '}')
- continue;
- else if (*pbBuff == '\\')
- {
- /* RTF control sequence */
- 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[2] = 0;
- ltr = strtoul(ultr,NULL,16);
- buffer[i++] = ltr;
- }
- 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++;
- 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;
- }
- else
- color[k++] = *pbBuff;
- }
- lastwascf = lastwascf0 = 0;
- }
- 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)
- {
- 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, "b"))
- {
- bold = 1;
- buffer[i++] = '\2';
- lastwascf = lastwascf0 = 0;
- }
- else if (!strcmp(cmd, "b0"))
- {
- bold = 0;
- buffer[i++] = '\2';
- lastwascf = lastwascf0 = 0;
- }
- else if (!strcmp(cmd, "ul"))
- {
- uline = 1;
- buffer[i++] = '\37';
- lastwascf = lastwascf0 = 0;
- }
- else if (!strcmp(cmd, "ulnone"))
- {
- uline = 0;
- buffer[i++] = '\37';
- lastwascf = lastwascf0 = 0;
- }
- else if (!strcmp(cmd, "cf0"))
- {
- lastwascf0 = 1;
- lastwascf = 0;
- }
- else if (!strcmp(cmd, "highlight0"))
- {
- inbg = 0;
- ColorPop(&BgColors);
- buffer[i++] = '\3';
- 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))
- {
- unsigned char number[3];
- int num;
- incolor = 1;
- strcpy(number, &cmd[2]);
- num = atoi(number);
- buffer[i++] = '\3';
- 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;
- }
- else
- lastwascf = lastwascf0 = 0;
-
- if (lastwascf0 && incolor)
- {
- incolor = 0;
- ColorPop(&TextColors);
- buffer[i++] = '\3';
- }
- }
- }
- else
- {
- lastwascf = lastwascf0 = 0;
- buffer[i++] = *pbBuff;
- }
-
- }
- write(fd, buffer, i);
- close(fd);
- ColorEmpty(&TextColors);
- ColorEmpty(&BgColors);
- return 0;
-}
-
-int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
-{
- MSG msg;
- unsigned char *s;
- HWND hWnd;
- WSADATA WSAData;
- HICON hIcon;
- SERVICE_TABLE_ENTRY DispatchTable[] = {
- { "UnrealIRCd", ServiceMain },
- { 0, 0 }
- };
- DWORD need;
-
- VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&VerInfo);
- if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- SC_HANDLE hService, hSCManager = OpenSCManager(NULL, NULL, GENERIC_EXECUTE);
- if ((hService = OpenService(hSCManager, "UnrealIRCd", GENERIC_EXECUTE))) {
- int save_err = 0;
- StartServiceCtrlDispatcher(DispatchTable);
- if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
- {
- 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);
- if (save_err != ERROR_SERVICE_DISABLED)
- exit(0);
- }
- }
- strcpy(OSName, "Windows ");
- if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
- if (VerInfo.dwMajorVersion == 4) {
- if (VerInfo.dwMinorVersion == 0) {
- strcat(OSName, "95 ");
- if (!strcmp(VerInfo.szCSDVersion," C"))
- strcat(OSName, "OSR2 ");
- }
- else if (VerInfo.dwMinorVersion == 10) {
- strcat(OSName, "98 ");
- if (!strcmp(VerInfo.szCSDVersion, " A"))
- strcat(OSName, "SE ");
- }
- else if (VerInfo.dwMinorVersion == 90)
- strcat(OSName, "Me ");
- }
- }
- else if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- if (VerInfo.dwMajorVersion == 3 && VerInfo.dwMinorVersion == 51)
- strcat(OSName, "NT 3.51 ");
- else if (VerInfo.dwMajorVersion == 4 && VerInfo.dwMinorVersion == 0)
- strcat(OSName, "NT 4.0 ");
- else if (VerInfo.dwMajorVersion == 5) {
- if (VerInfo.dwMinorVersion == 0)
- strcat(OSName, "2000 ");
- else if (VerInfo.dwMinorVersion == 1)
- strcat(OSName, "XP ");
- else if (VerInfo.dwMinorVersion == 2)
- strcat(OSName, "Server 2003 ");
- }
- strcat(OSName, VerInfo.szCSDVersion);
- }
- if (OSName[strlen(OSName)-1] == ' ')
- OSName[strlen(OSName)-1] = 0;
- InitCommonControls();
- WM_TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");
- WM_FINDMSGSTRING = RegisterWindowMessage(FINDMSGSTRING);
- atexit(CleanUp);
- if(!LoadLibrary("riched20.dll"))
- LoadLibrary("riched32.dll");
- InitDebug();
-
- if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
- {
- MessageBox(NULL, "Unable to initialize WinSock", "UnrealIRCD Initalization Error", MB_OK);
- return FALSE;
- }
- hInst = hInstance;
-
- hWnd = CreateDialog(hInstance, "WIRCD", 0, (DLGPROC)MainDLG);
- hwIRCDWnd = hWnd;
-
- TaskBarCreated();
-
- if (InitwIRCD(__argc, __argv) != 1)
- {
- MessageBox(NULL, "UnrealIRCd has failed to initialize in InitwIRCD()", "UnrealIRCD Initalization Error" ,MB_OK);
- return FALSE;
- }
- ShowWindow(hWnd, SW_SHOW);
- hMainThread = (HANDLE)_beginthread(SocketLoop, 0, NULL);
- while (GetMessage(&msg, NULL, 0, 0))
- {
- if (!IsWindow(hStatusWnd) || !IsDialogMessage(hStatusWnd, &msg)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- return FALSE;
-
-}
-
-LRESULT CALLBACK MainDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-static HCURSOR hCursor;
-static HMENU hRehash, hAbout, hConfig, hTray, hLogs;
-
- unsigned char *argv[3];
- aClient *paClient;
- unsigned char *msg;
- POINT p;
-
- if (message == WM_TASKBARCREATED){
- TaskBarCreated();
- return TRUE;
- }
-
- switch (message)
- {
- case WM_INITDIALOG: {
- ShowWindow(hDlg, SW_HIDE);
- hCursor = LoadCursor(hInst, MAKEINTRESOURCE(CUR_HAND));
- hContext = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_CONTEXT)),0);
- /* Rehash popup menu */
- hRehash = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_REHASH)),0);
- /* About popup menu */
- hAbout = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_ABOUT)),0);
- /* Systray popup menu set the items to point to the other menus*/
- hTray = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_SYSTRAY)),0);
- ModifyMenu(hTray, IDM_REHASH, MF_BYCOMMAND|MF_POPUP|MF_STRING, (UINT)hRehash, "&Rehash");
- ModifyMenu(hTray, IDM_ABOUT, MF_BYCOMMAND|MF_POPUP|MF_STRING, (UINT)hAbout, "&About");
-
- SetWindowText(hDlg, WIN32_VERSION);
- SendMessage(hDlg, WM_SETICON, (WPARAM)ICON_SMALL,
- (LPARAM)(HICON)LoadImage(hInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON,16, 16, 0));
- SendMessage(hDlg, WM_SETICON, (WPARAM)ICON_BIG,
- (LPARAM)(HICON)LoadImage(hInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON,32, 32, 0));
- return (TRUE);
- }
- case WM_SIZE: {
- if (wParam & SIZE_MINIMIZED) {
- ShowWindow(hDlg,SW_HIDE);
- }
- return 0;
- }
- case WM_CLOSE: {
- if (MessageBox(hDlg, "Close UnrealIRCd?", "Are you sure?", MB_YESNO|MB_ICONQUESTION) == IDNO)
- return 0;
- else {
- DestroyWindow(hDlg);
- exit(0);
- }
- }
-
- case WM_USER: {
- switch(LOWORD(lParam)) {
- case WM_LBUTTONDBLCLK:
- ShowWindow(hDlg, SW_SHOW);
- ShowWindow(hDlg,SW_RESTORE);
- SetForegroundWindow(hDlg);
- case WM_RBUTTONDOWN:
- SetForegroundWindow(hDlg);
- break;
- case WM_RBUTTONUP: {
- unsigned long i = 60000;
- GetCursorPos(&p);
- DestroyMenu(hConfig);
- hConfig = CreatePopupMenu();
- DestroyMenu(hLogs);
- hLogs = CreatePopupMenu();
- AppendMenu(hConfig, MF_STRING, IDM_CONF, CPATH);
- if (conf_log) {
- ConfigItem_log *logs;
- AppendMenu(hConfig, MF_POPUP|MF_STRING, (UINT)hLogs, "Logs");
- for (logs = conf_log; logs; logs = (ConfigItem_log *)logs->next) {
- AppendMenu(hLogs, MF_STRING, i++, logs->file);
- }
- }
- AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
- if (conf_include) {
- ConfigItem_include *inc;
- for (inc = conf_include; inc; inc = (ConfigItem_include *)inc->next) {
- if (inc->flag.type & INCLUDE_NOTLOADED)
- continue;
-#ifdef USE_LIBCURL
- if (inc->flag.type & INCLUDE_REMOTE)
- AppendMenu(hConfig, MF_STRING, i++, inc->url);
- else
-#endif
- AppendMenu(hConfig, MF_STRING, i++, inc->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);
-
- if (conf_tld) {
- ConfigItem_tld *tlds;
- AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
- for (tlds = conf_tld; tlds; tlds = (ConfigItem_tld *)tlds->next) {
- if (!tlds->flag.motdptr)
- 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_NEW, "New File");
- ModifyMenu(hTray, IDM_CONFIG, MF_BYCOMMAND|MF_POPUP|MF_STRING, (UINT)hConfig, "&Config");
- TrackPopupMenu(hTray, TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
- /* Kludge for a win bug */
- SendMessage(hDlg, WM_NULL, 0, 0);
- break;
- }
- }
- return 0;
- }
- case WM_DESTROY:
- return 0;
- case WM_MOUSEMOVE: {
- POINT p;
- p.x = LOWORD(lParam);
- p.y = HIWORD(lParam);
-
- if ((p.x >= 24) && (p.x <= 78) && (p.y >= 178) && (p.y <= 190))
- SetCursor(hCursor);
- else if ((p.x >= 85) && (p.x <= 132) && (p.y >= 178) && (p.y <= 190))
- SetCursor(hCursor);
- else if ((p.x >= 140) && (p.x <= 186) && (p.y >= 178) && (p.y <= 190))
- SetCursor(hCursor);
- else if ((p.x >= 194) && (p.x <= 237) && (p.y >= 178) && (p.y <= 190))
- SetCursor(hCursor);
- else if ((p.x >= 245) && (p.x <= 311) && (p.y >= 178) && (p.y <= 190))
- SetCursor(hCursor);
- return 0;
- }
- case WM_LBUTTONDOWN: {
- POINT p;
- p.x = LOWORD(lParam);
- p.y = HIWORD(lParam);
- if ((p.x >= 24) && (p.x <= 78) && (p.y >= 178) && (p.y <= 190))
- {
- ClientToScreen(hDlg,&p);
- TrackPopupMenu(hRehash,TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
- return 0;
- }
- else if ((p.x >= 85) && (p.x <= 132) && (p.y >= 178) && (p.y <= 190)) {
- ShowDialog(hStatusWnd, hInst, "Status", hDlg, StatusDLG);
- return 0;
- }
- else if ((p.x >= 140) && (p.x <= 186) && (p.y >= 178) && (p.y <= 190)) {
- unsigned long i = 60000;
- ClientToScreen(hDlg,&p);
- DestroyMenu(hConfig);
- hConfig = CreatePopupMenu();
- DestroyMenu(hLogs);
- hLogs = CreatePopupMenu();
-
- AppendMenu(hConfig, MF_STRING, IDM_CONF, CPATH);
- if (conf_log) {
- ConfigItem_log *logs;
- AppendMenu(hConfig, MF_POPUP|MF_STRING, (UINT)hLogs, "Logs");
- for (logs = conf_log; logs; logs = (ConfigItem_log *)logs->next) {
- AppendMenu(hLogs, MF_STRING, i++, logs->file);
- }
- }
- AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
-
- if (conf_include) {
- ConfigItem_include *inc;
- for (inc = conf_include; inc; inc = (ConfigItem_include *)inc->next) {
-#ifdef USE_LIBCURL
- if (inc->flag.type & INCLUDE_REMOTE)
- AppendMenu(hConfig, MF_STRING, i++, inc->url);
- else
-#endif
- AppendMenu(hConfig, MF_STRING, i++, inc->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);
-
- if (conf_tld) {
- ConfigItem_tld *tlds;
- AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
- for (tlds = conf_tld; tlds; tlds = (ConfigItem_tld *)tlds->next) {
- if (!tlds->flag.motdptr)
- 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_NEW, "New File");
- TrackPopupMenu(hConfig,TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
-
- return 0;
- }
- else if ((p.x >= 194) && (p.x <= 237) && (p.y >= 178) && (p.y <= 190)) {
- ClientToScreen(hDlg,&p);
- TrackPopupMenu(hAbout,TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
- return 0;
- }
- else if ((p.x >= 245) && (p.x <= 311) && (p.y >= 178) && (p.y <= 190)) {
- if (MessageBox(hDlg, "Close UnrealIRCd?", "Are you sure?", MB_YESNO|MB_ICONQUESTION) == IDNO)
- return 0;
- else {
- DestroyWindow(hDlg);
- exit(0);
- }
- }
- }
- case WM_COMMAND: {
- if (LOWORD(wParam) >= 60000 && HIWORD(wParam) == 0 && !lParam) {
- unsigned char path[MAX_PATH];
- if (GetMenuString(hLogs, LOWORD(wParam), path, MAX_PATH, MF_BYCOMMAND))
- DialogBoxParam(hInst, "FromVar", hDlg, (DLGPROC)FromFileReadDLG, (LPARAM)path);
-
- else
- {
- GetMenuString(hConfig,LOWORD(wParam), path, MAX_PATH, MF_BYCOMMAND);
-#ifdef USE_LIBCURL
- if (url_is_valid(path))
- {
- char *file = find_loaded_remote_include(path);
- DialogBoxParam(hInst, "FromVar", hDlg, (DLGPROC)FromFileReadDLG, (LPARAM)file);
- }
- else
-#endif
- DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG, (LPARAM)path);
- }
- return FALSE;
- }
-
- switch(LOWORD(wParam)) {
-
- case IDM_STATUS:
- ShowDialog(hStatusWnd, hInst, "Status", hDlg, StatusDLG);
- break;
- case IDM_SHUTDOWN:
- if (MessageBox(hDlg, "Close UnrealIRCd?", "Are you sure?", MB_YESNO|MB_ICONQUESTION) == IDNO)
- return 0;
- else {
- DestroyWindow(hDlg);
- exit(0);
- }
- break;
-
- case IDM_RHALL:
- MessageBox(NULL, "Rehashing all files", "Rehashing", MB_OK);
- sendto_realops("Rehashing all files via the console");
- rehash(&me,&me,0);
- reread_motdsandrules();
- break;
- case IDM_RHCONF:
- MessageBox(NULL, "Rehashing the Config file", "Rehashing", MB_OK);
- sendto_realops("Rehashing the Config file via the console");
- rehash(&me,&me,0);
- break;
- case IDM_RHMOTD: {
- ConfigItem_tld *tlds;
- aMotd *amotd;
- MessageBox(NULL, "Rehashing all MOTD and Rules files", "Rehashing", MB_OK);
- rehash_motdrules();
- sendto_realops("Rehashing all MOTD and Rules files via the console");
- break;
- }
- case IDM_RHOMOTD:
- MessageBox(NULL, "Rehashing the OperMOTD", "Rehashing", MB_OK);
- opermotd = (aMotd *) read_file(OPATH, &opermotd);
- sendto_realops("Rehashing the OperMOTD via the console");
- break;
- case IDM_RHBMOTD:
- MessageBox(NULL, "Rehashing the BotMOTD", "Rehashing", MB_OK);
- botmotd = (aMotd *) read_file(BPATH, &botmotd);
- sendto_realops("Rehashing the BotMOTD via the console");
- break;
- case IDM_LICENSE:
- DialogBox(hInst, "FromVar", hDlg, (DLGPROC)LicenseDLG);
- break;
- case IDM_CREDITS:
- DialogBox(hInst, "FromVar", hDlg, (DLGPROC)CreditsDLG);
- break;
- case IDM_DAL:
- DialogBox(hInst, "FromVar", hDlg, (DLGPROC)DalDLG);
- break;
- case IDM_HELP:
- DialogBox(hInst, "Help", hDlg, (DLGPROC)HelpDLG);
- break;
- case IDM_CONF:
- DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
- (LPARAM)CPATH);
- break;
- case IDM_MOTD:
- 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);
- break;
- case IDM_BOTMOTD:
- DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
- (LPARAM)BPATH);
- break;
- case IDM_RULES:
- DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
- (LPARAM)RPATH);
- break;
- case IDM_NEW:
- DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG, (LPARAM)NULL);
- break;
-
- }
- }
- }
- return (FALSE);
-}
-
-LRESULT CALLBACK LicenseDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
- return FromVarDLG(hDlg, message, wParam, lParam, "UnrealIRCd License", gnulicense);
-}
-
-LRESULT CALLBACK CreditsDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
- return FromVarDLG(hDlg, message, wParam, lParam, "UnrealIRCd Credits", unrealcredits);
-}
-
-LRESULT CALLBACK DalDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
- return FromVarDLG(hDlg, message, wParam, lParam, "UnrealIRCd DALnet Credits", dalinfotext);
-}
-
-LRESULT CALLBACK FromVarDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam,
-unsigned char *title, unsigned char **s) {
- HWND hWnd;
- switch (message) {
- case WM_INITDIALOG: {
- unsigned char String[16384];
- int size;
- unsigned char *RTFString;
- StreamIO *stream = malloc(sizeof(StreamIO));
- EDITSTREAM edit;
- SetWindowText(hDlg, title);
- bzero(String, 16384);
- lpfnOldWndProc = (FARPROC)SetWindowLong(GetDlgItem(hDlg, IDC_TEXT),
-GWL_WNDPROC, (DWORD)RESubClassFunc);
- while (*s) {
- strcat(String, *s++);
- if (*s)
- strcat(String, "\r\n");
- }
- size = CountRTFSize(String)+1;
- RTFString = malloc(size);
- bzero(RTFString, size);
- IRCToRTF(String,RTFString);
- RTFBuf = RTFString;
- size--;
- stream->size = &size;
- stream->buffer = &RTFBuf;
- edit.dwCookie = (UINT)stream;
- edit.pfnCallback = SplitIt;
- SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_STREAMIN,
-(WPARAM)SF_RTF|SFF_PLAINRTF, (LPARAM)&edit);
- free(RTFString);
- free(stream);
- return (TRUE);
- }
-
- case WM_COMMAND: {
- hWnd = GetDlgItem(hDlg, IDC_TEXT);
- if (LOWORD(wParam) == IDOK)
- return EndDialog(hDlg, TRUE);
- if (LOWORD(wParam) == IDM_COPY) {
- SendMessage(hWnd, WM_COPY, 0, 0);
- return 0;
- }
- if (LOWORD(wParam) == IDM_SELECTALL) {
- SendMessage(hWnd, EM_SETSEL, 0, -1);
- return 0;
- }
- if (LOWORD(wParam) == IDM_PASTE) {
- SendMessage(hWnd, WM_PASTE, 0, 0);
- return 0;
- }
- if (LOWORD(wParam) == IDM_CUT) {
- SendMessage(hWnd, WM_CUT, 0, 0);
- return 0;
- }
- if (LOWORD(wParam) == IDM_UNDO) {
- SendMessage(hWnd, EM_UNDO, 0, 0);
- return 0;
- }
- if (LOWORD(wParam) == IDM_DELETE) {
- SendMessage(hWnd, WM_CLEAR, 0, 0);
- return 0;
- }
-
-
- break;
- }
- case WM_CLOSE:
- EndDialog(hDlg, TRUE);
- break;
- case WM_DESTROY:
- break;
- }
- return (FALSE);
-}
-
-LRESULT CALLBACK FromFileReadDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
- HWND hWnd;
- switch (message) {
- case WM_INITDIALOG: {
- int fd,len;
- unsigned char *buffer = '\0', *string = '\0';
- EDITSTREAM edit;
- StreamIO *stream = malloc(sizeof(StreamIO));
- unsigned char szText[256];
- struct stat sb;
- HWND hWnd = GetDlgItem(hDlg, IDC_TEXT), hTip;
- wsprintf(szText, "UnrealIRCd Viewer - %s", (unsigned char *)lParam);
- SetWindowText(hDlg, szText);
- lpfnOldWndProc = (FARPROC)SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)RESubClassFunc);
- if ((fd = open((unsigned char *)lParam, _O_RDONLY|_O_BINARY)) != -1) {
- fstat(fd,&sb);
- /* Only allocate the amount we need */
- buffer = malloc(sb.st_size+1);
- buffer[0] = 0;
- len = read(fd, buffer, sb.st_size);
- buffer[len] = 0;
- len = CountRTFSize(buffer)+1;
- string = malloc(len);
- bzero(string,len);
- IRCToRTF(buffer,string);
- RTFBuf = string;
- len--;
- stream->size = &len;
- stream->buffer = &RTFBuf;
- edit.dwCookie = (UINT)stream;
- edit.pfnCallback = SplitIt;
- SendMessage(hWnd, EM_EXLIMITTEXT, 0, (LPARAM)0x7FFFFFFF);
- SendMessage(hWnd, EM_STREAMIN, (WPARAM)SF_RTF|SFF_PLAINRTF, (LPARAM)&edit);
- close(fd);
- RTFBuf = NULL;
- free(buffer);
- free(string);
- free(stream);
- }
- return (TRUE);
- }
- case WM_COMMAND: {
- hWnd = GetDlgItem(hDlg, IDC_TEXT);
- if (LOWORD(wParam) == IDOK)
- return EndDialog(hDlg, TRUE);
- if (LOWORD(wParam) == IDM_COPY) {
- SendMessage(hWnd, WM_COPY, 0, 0);
- return 0;
- }
- if (LOWORD(wParam) == IDM_SELECTALL) {
- SendMessage(hWnd, EM_SETSEL, 0, -1);
- return 0;
- }
- if (LOWORD(wParam) == IDM_PASTE) {
- SendMessage(hWnd, WM_PASTE, 0, 0);
- return 0;
- }
- if (LOWORD(wParam) == IDM_CUT) {
- SendMessage(hWnd, WM_CUT, 0, 0);
- return 0;
- }
- if (LOWORD(wParam) == IDM_UNDO) {
- SendMessage(hWnd, EM_UNDO, 0, 0);
- return 0;
- }
- if (LOWORD(wParam) == IDM_DELETE) {
- SendMessage(hWnd, WM_CLEAR, 0, 0);
- return 0;
- }
-
-
- break;
- }
- case WM_CLOSE:
- EndDialog(hDlg, TRUE);
- break;
- case WM_DESTROY:
- break;
- }
- return (FALSE);
-}
-
-
-LRESULT CALLBACK HelpDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
- static HFONT hFont;
- static HCURSOR hCursor;
- switch (message) {
- case WM_INITDIALOG:
- hCursor = LoadCursor(hInst, MAKEINTRESOURCE(CUR_HAND));
- hFont = CreateFont(8,0,0,0,0,0,1,0,ANSI_CHARSET,0,0,PROOF_QUALITY,0,"MS Sans Serif");
- SendMessage(GetDlgItem(hDlg, IDC_EMAIL), WM_SETFONT, (WPARAM)hFont,TRUE);
- SendMessage(GetDlgItem(hDlg, IDC_URL), WM_SETFONT, (WPARAM)hFont,TRUE);
- lpfnOldWndProc = (FARPROC)SetWindowLong(GetDlgItem(hDlg, IDC_EMAIL), GWL_WNDPROC, (DWORD)LinkSubClassFunc);
- SetWindowLong(GetDlgItem(hDlg, IDC_URL), GWL_WNDPROC, (DWORD)LinkSubClassFunc);
- return (TRUE);
-
- case WM_DRAWITEM: {
- LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
- unsigned char text[500];
- COLORREF oldtext;
- RECT focus;
- GetWindowText(lpdis->hwndItem, text, 500);
- if (wParam == IDC_URL || IDC_EMAIL) {
- FillRect(lpdis->hDC, &lpdis->rcItem, GetSysColorBrush(COLOR_3DFACE));
- oldtext = SetTextColor(lpdis->hDC, RGB(0,0,255));
- DrawText(lpdis->hDC, text, strlen(text), &lpdis->rcItem, DT_CENTER|DT_VCENTER);
- SetTextColor(lpdis->hDC, oldtext);
- if (lpdis->itemState & ODS_FOCUS) {
- CopyRect(&focus, &lpdis->rcItem);
- focus.left += 2;
- focus.right -= 2;
- focus.top += 1;
- focus.bottom -= 1;
- DrawFocusRect(lpdis->hDC, &focus);
- }
- return TRUE;
- }
- }
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK)
- EndDialog(hDlg, TRUE);
- if (HIWORD(wParam) == BN_DBLCLK) {
- if (LOWORD(wParam) == IDC_URL)
- ShellExecute(NULL, "open", "http://www.unrealircd.com", NULL, NULL,
- SW_MAXIMIZE);
- else if (LOWORD(wParam) == IDC_EMAIL)
- ShellExecute(NULL, "open", "mailto:unreal-users@lists.sourceforge.net", NULL, NULL,
- SW_MAXIMIZE);
- EndDialog(hDlg, TRUE);
- return 0;
- }
- break;
- case WM_CLOSE:
- EndDialog(hDlg, TRUE);
- break;
- case WM_DESTROY:
- DeleteObject(hFont);
- break;
-
- }
- return (FALSE);
-}
-
-HWND DrawToolbar(HWND hwndParent, UINT iID) {
- HWND hTool;
- TBADDBITMAP tbBit;
- int newidx;
- TBBUTTON tbButtons[10] = {
- { STD_FILENEW, IDM_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
- { STD_FILESAVE, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
- { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, 0},
- { STD_CUT, IDM_CUT, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
- { STD_COPY, IDM_COPY, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
- { STD_PASTE, IDM_PASTE, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
- { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, 0},
- { STD_UNDO, IDM_UNDO, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
- { STD_REDOW, IDM_REDO, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
- { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, 0}
- };
-
- 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},
- { 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)5, (LPARAM)&tbBit);
- tbAddButtons[0].iBitmap += newidx;
- tbAddButtons[1].iBitmap += newidx;
- tbAddButtons[2].iBitmap += newidx;
- tbAddButtons[3].iBitmap += newidx;
- tbAddButtons[5].iBitmap += newidx;
- SendMessage(hTool, TB_ADDBUTTONS, (WPARAM)7, (LPARAM)&tbAddButtons);
- return hTool;
-}
-
-HWND DrawStatusbar(HWND hwndParent, UINT iID) {
- HWND hStatus, hTip;
- TOOLINFO ti;
- RECT clrect;
- hStatus = CreateStatusWindow(WS_CHILD|WS_VISIBLE|SBT_TOOLTIPS, NULL, hwndParent, iID);
- hTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
- WS_POPUP|TTS_NOPREFIX|TTS_ALWAYSTIP, 0, 0, 0, 0, hwndParent, NULL, hInst, NULL);
- GetClientRect(hStatus, &clrect);
- ti.cbSize = sizeof(TOOLINFO);
- ti.uFlags = TTF_SUBCLASS;
- ti.hwnd = hStatus;
- ti.uId = 1;
- ti.hinst = hInst;
- ti.rect = clrect;
- ti.lpszText = "Go To";
- SendMessage(hTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
- return hStatus;
-
-}
-
-
-LRESULT CALLBACK GotoDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
- if (message == WM_COMMAND) {
- if (LOWORD(wParam) == IDCANCEL)
- EndDialog(hDlg, TRUE);
- if (LOWORD(wParam) == IDOK) {
- HWND hWnd = GetDlgItem(GetParent(hDlg),IDC_TEXT);
- int line = GetDlgItemInt(hDlg, IDC_GOTO, NULL, FALSE);
- int pos = SendMessage(hWnd, EM_LINEINDEX, (WPARAM)--line, 0);
- SendMessage(hWnd, EM_SETSEL, (WPARAM)pos, (LPARAM)pos);
- SendMessage(hWnd, EM_SCROLLCARET, 0, 0);
- EndDialog(hDlg, TRUE);
- }
- }
- return FALSE;
-}
-
-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;
- unsigned char *buffer = '\0', *string = '\0';
- EDITSTREAM edit;
- StreamIO *stream = malloc(sizeof(StreamIO));
- unsigned char szText[256];
- struct stat sb;
- HWND hWnd = GetDlgItem(hDlg, IDC_TEXT), hTip;
- file = (unsigned char *)lParam;
- if (file)
- wsprintf(szText, "UnrealIRCd Editor - %s", file);
- else
- strcpy(szText, "UnrealIRCd Editor - New File");
- SetWindowText(hDlg, szText);
- lpfnOldWndProc = (FARPROC)SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)RESubClassFunc);
- hTool = DrawToolbar(hDlg, IDC_TOOLBAR);
- hStatus = DrawStatusbar(hDlg, IDC_STATUS);
- SendMessage(hWnd, EM_SETEVENTMASK, 0, (LPARAM)ENM_SELCHANGE);
- chars.cbSize = sizeof(CHARFORMAT2);
- chars.dwMask = CFM_FACE;
- strcpy(chars.szFaceName,"Fixedsys");
- SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_ALL, (LPARAM)&chars);
- if ((fd = open(file, _O_RDONLY|_O_BINARY)) != -1) {
- fstat(fd,&sb);
- /* Only allocate the amount we need */
- buffer = malloc(sb.st_size+1);
- buffer[0] = 0;
- len = read(fd, buffer, sb.st_size);
- buffer[len] = 0;
- len = CountRTFSize(buffer)+1;
- string = malloc(len);
- bzero(string,len);
- IRCToRTF(buffer,string);
- RTFBuf = string;
- len--;
- stream->size = &len;
- stream->buffer = &RTFBuf;
- edit.dwCookie = (UINT)stream;
- edit.pfnCallback = SplitIt;
- SendMessage(hWnd, EM_EXLIMITTEXT, 0, (LPARAM)0x7FFFFFFF);
- SendMessage(hWnd, EM_STREAMIN, (WPARAM)SF_RTF|SFF_PLAINRTF, (LPARAM)&edit);
- SendMessage(hWnd, EM_SETMODIFY, (WPARAM)FALSE, 0);
- SendMessage(hWnd, EM_EMPTYUNDOBUFFER, 0, 0);
- close(fd);
- RTFBuf = NULL;
- free(buffer);
- free(string);
- free(stream);
- hClip = SetClipboardViewer(hDlg);
- if (SendMessage(hWnd, EM_CANPASTE, 0, 0))
- SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_PASTE, (LPARAM)MAKELONG(TRUE,0));
- else
- SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_PASTE, (LPARAM)MAKELONG(FALSE,0));
- SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_UNDO, (LPARAM)MAKELONG(FALSE,0));
- wsprintf(szText, "Line: 1");
- SetWindowText(hStatus, szText);
- }
- 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: {
- HWND hWnd = GetDlgItem(hDlg, IDC_TEXT);
- DWORD start, end, currline;
- static DWORD prevline = 0;
- unsigned char buffer[512];
- chars.cbSize = sizeof(CHARFORMAT2);
- SendMessage(hWnd, EM_GETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
- if (chars.dwMask & CFM_BOLD && chars.dwEffects & CFE_BOLD)
- SendMessage(hTool, TB_CHECKBUTTON, (WPARAM)IDC_BOLD, (LPARAM)MAKELONG(TRUE,0));
- else
- SendMessage(hTool, TB_CHECKBUTTON, (WPARAM)IDC_BOLD, (LPARAM)MAKELONG(FALSE,0));
- if (chars.dwMask & CFM_UNDERLINE && chars.dwEffects & CFE_UNDERLINE)
- SendMessage(hTool, TB_CHECKBUTTON, (WPARAM)IDC_UNDERLINE, (LPARAM)MAKELONG(TRUE,0));
- else
- SendMessage(hTool, TB_CHECKBUTTON, (WPARAM)IDC_UNDERLINE, (LPARAM)MAKELONG(FALSE,0));
- SendMessage(hWnd, EM_GETSEL,(WPARAM)&start, (LPARAM)&end);
- if (start == end) {
- SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_COPY, (LPARAM)MAKELONG(FALSE,0));
- SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_CUT, (LPARAM)MAKELONG(FALSE,0));
- }
- else {
- SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_COPY, (LPARAM)MAKELONG(TRUE,0));
- SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_CUT, (LPARAM)MAKELONG(TRUE,0));
- }
- if (SendMessage(hWnd, EM_CANUNDO, 0, 0))
- SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_UNDO, (LPARAM)MAKELONG(TRUE,0));
- else
- SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_UNDO, (LPARAM)MAKELONG(FALSE,0));
- if (SendMessage(hWnd, EM_CANREDO, 0, 0))
- SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_REDO, (LPARAM)MAKELONG(TRUE,0));
- else
- SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_REDO, (LPARAM)MAKELONG(FALSE,0));
- currline = SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)-1, 0);
- currline++;
- if (currline != prevline) {
- wsprintf(buffer, "Line: %d", currline);
- SetWindowText(hStatus, buffer);
- prevline = currline;
- }
- }
- return (TRUE);
-
- case TTN_GETDISPINFO: {
- LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT) lParam;
- lpttt->hinst = NULL;
- switch (lpttt->hdr.idFrom) {
- case IDM_NEW:
- strcpy(lpttt->szText, "New");
- break;
- case IDM_SAVE:
- strcpy(lpttt->szText, "Save");
- break;
- case IDM_CUT:
- strcpy(lpttt->szText, "Cut");
- break;
- case IDM_COPY:
- strcpy(lpttt->szText, "Copy");
- break;
- case IDM_PASTE:
- strcpy(lpttt->szText, "Paste");
- break;
- case IDM_UNDO:
- strcpy(lpttt->szText, "Undo");
- break;
- case IDM_REDO:
- strcpy(lpttt->szText, "Redo");
- break;
- case IDC_BOLD:
- strcpy(lpttt->szText, "Bold");
- break;
- case IDC_UNDERLINE:
- strcpy(lpttt->szText, "Underline");
- break;
- 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);
- }
- case NM_DBLCLK:
- DialogBox(hInst, "GOTO", hDlg, (DLGPROC)GotoDLG);
- return (TRUE);
- }
-
- return (TRUE);
- case WM_COMMAND:
- if (LOWORD(wParam) == IDC_BOLD) {
- hWnd = GetDlgItem(hDlg, IDC_TEXT);
- if (SendMessage(hTool, TB_ISBUTTONCHECKED, (WPARAM)IDC_BOLD, (LPARAM)0) != 0) {
- chars.cbSize = sizeof(CHARFORMAT2);
- chars.dwMask = CFM_BOLD;
- chars.dwEffects = CFE_BOLD;
- SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
- SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
- SetFocus(hWnd);
- }
- else {
- chars.cbSize = sizeof(CHARFORMAT2);
- chars.dwMask = CFM_BOLD;
- chars.dwEffects = 0;
- SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
- SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
- SetFocus(hWnd);
- }
- return TRUE;
- }
- else if (LOWORD(wParam) == IDC_UNDERLINE) {
- hWnd = GetDlgItem(hDlg, IDC_TEXT);
- if (SendMessage(hTool, TB_ISBUTTONCHECKED, (WPARAM)IDC_UNDERLINE, (LPARAM)0) != 0) {
- chars.cbSize = sizeof(CHARFORMAT2);
- chars.dwMask = CFM_UNDERLINETYPE;
- chars.bUnderlineType = CFU_UNDERLINE;
- SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
- SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
- SetFocus(hWnd);
- }
- else {
- chars.cbSize = sizeof(CHARFORMAT2);
- chars.dwMask = CFM_UNDERLINETYPE;
- chars.bUnderlineType = CFU_UNDERLINENONE;
- SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
- SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
- SetFocus(hWnd);
- }
- 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);
- return 0;
- }
- if (LOWORD(wParam) == IDM_SELECTALL) {
- SendMessage(hWnd, EM_SETSEL, 0, -1);
- return 0;
- }
- if (LOWORD(wParam) == IDM_PASTE) {
- SendMessage(hWnd, WM_PASTE, 0, 0);
- return 0;
- }
- if (LOWORD(wParam) == IDM_CUT) {
- SendMessage(hWnd, WM_CUT, 0, 0);
- return 0;
- }
- if (LOWORD(wParam) == IDM_UNDO) {
- SendMessage(hWnd, EM_UNDO, 0, 0);
- return 0;
- }
- if (LOWORD(wParam) == IDM_REDO) {
- SendMessage(hWnd, EM_REDO, 0, 0);
- return 0;
- }
- if (LOWORD(wParam) == IDM_DELETE) {
- SendMessage(hWnd, WM_CLEAR, 0, 0);
- return 0;
- }
- if (LOWORD(wParam) == IDM_SAVE) {
- int fd;
- EDITSTREAM edit;
- OPENFILENAME lpopen;
- if (!file) {
- unsigned char path[MAX_PATH];
- path[0] = '\0';
- bzero(&lpopen, sizeof(OPENFILENAME));
- lpopen.lStructSize = sizeof(OPENFILENAME);
- lpopen.hwndOwner = hDlg;
- lpopen.lpstrFilter = NULL;
- lpopen.lpstrCustomFilter = NULL;
- lpopen.nFilterIndex = 0;
- lpopen.lpstrFile = path;
- lpopen.nMaxFile = MAX_PATH;
- lpopen.lpstrFileTitle = NULL;
- lpopen.lpstrInitialDir = DPATH;
- lpopen.lpstrTitle = NULL;
- lpopen.Flags = (OFN_ENABLESIZING|OFN_NONETWORKBUTTON|
- OFN_OVERWRITEPROMPT);
- if (GetSaveFileName(&lpopen))
- file = path;
- else
- break;
- }
- fd = open(file, _O_TRUNC|_O_CREAT|_O_WRONLY|_O_BINARY,_S_IWRITE);
- edit.dwCookie = 0;
- edit.pfnCallback = BufferIt;
- SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_STREAMOUT, (WPARAM)SF_RTF|SFF_PLAINRTF, (LPARAM)&edit);
- RTFToIRC(fd, RTFBuf, strlen(RTFBuf));
- free(RTFBuf);
- RTFBuf = NULL;
- SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_SETMODIFY, (WPARAM)FALSE, 0);
-
- return 0;
- }
- if (LOWORD(wParam) == IDM_NEW) {
- unsigned char text[1024];
- BOOL newfile = FALSE;
- int ans;
- if (SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_GETMODIFY, 0, 0) != 0) {
- sprintf(text, "The text in the %s file has changed.\r\n\r\nDo you want to save the changes?", file ? file : "new");
- ans = MessageBox(hDlg, text, "UnrealIRCd", MB_YESNOCANCEL|MB_ICONWARNING);
- if (ans == IDNO)
- newfile = TRUE;
- if (ans == IDCANCEL)
- return TRUE;
- if (ans == IDYES) {
- SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDM_SAVE,0), 0);
- newfile = TRUE;
- }
- }
- else
- newfile = TRUE;
- if (newfile == TRUE) {
- unsigned char szText[256];
- file = NULL;
- strcpy(szText, "UnrealIRCd Editor - New File");
- SetWindowText(hDlg, szText);
- SetWindowText(GetDlgItem(hDlg, IDC_TEXT), NULL);
- }
-
- break;
- }
- break;
- case WM_USER+10: {
- HWND hWnd = GetDlgItem(hDlg, IDC_TEXT);
- EndDialog((HWND)lParam, TRUE);
- chars.cbSize = sizeof(CHARFORMAT2);
- chars.dwMask = CFM_COLOR;
- chars.crTextColor = (COLORREF)wParam;
- SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
- SendMessage(hWnd, EM_HIDESELECTION, 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
- SendMessage(hClip, WM_CHANGECBCHAIN, wParam, lParam);
- break;
- case WM_DRAWCLIPBOARD:
- if (SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_CANPASTE, 0, 0))
- SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_PASTE, (LPARAM)MAKELONG(TRUE,0));
- else
- SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_PASTE, (LPARAM)MAKELONG(FALSE,0));
- SendMessage(hClip, WM_DRAWCLIPBOARD, wParam, lParam);
- break;
- case WM_CLOSE: {
- unsigned char text[256];
- int ans;
- if (SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_GETMODIFY, 0, 0) != 0) {
- sprintf(text, "The text in the %s file has changed.\r\n\r\nDo you want to save the changes?", file ? file : "new");
- ans = MessageBox(hDlg, text, "UnrealIRCd", MB_YESNOCANCEL|MB_ICONWARNING);
- if (ans == IDNO)
- EndDialog(hDlg, TRUE);
- if (ans == IDCANCEL)
- return TRUE;
- if (ans == IDYES) {
- SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDM_SAVE,0), 0);
- EndDialog(hDlg, TRUE);
- }
- }
- else
- EndDialog(hDlg, TRUE);
- break;
- }
- case WM_DESTROY:
- ChangeClipboardChain(hDlg, hClip);
- break;
- }
-
- return (FALSE);
-}
-
-LRESULT CALLBACK StatusDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
- switch (message) {
- case WM_INITDIALOG: {
- hwTreeView = GetDlgItem(hDlg, IDC_TREE);
- win_map(&me, hwTreeView, 0);
- SetDlgItemInt(hDlg, IDC_CLIENTS, IRCstats.clients, FALSE);
- SetDlgItemInt(hDlg, IDC_SERVERS, IRCstats.servers, FALSE);
- SetDlgItemInt(hDlg, IDC_INVISO, IRCstats.invisible, FALSE);
- SetDlgItemInt(hDlg, IDC_UNKNOWN, IRCstats.unknown, FALSE);
- SetDlgItemInt(hDlg, IDC_OPERS, IRCstats.operators, FALSE);
- SetDlgItemInt(hDlg, IDC_CHANNELS, IRCstats.channels, FALSE);
- if (IRCstats.clients > IRCstats.global_max)
- IRCstats.global_max = IRCstats.clients;
- if (IRCstats.me_clients > IRCstats.me_max)
- IRCstats.me_max = IRCstats.me_clients;
- SetDlgItemInt(hDlg, IDC_MAXCLIENTS, IRCstats.global_max, FALSE);
- SetDlgItemInt(hDlg, IDC_LCLIENTS, IRCstats.me_clients, FALSE);
- SetDlgItemInt(hDlg, IDC_LSERVERS, IRCstats.me_servers, FALSE);
- SetDlgItemInt(hDlg, IDC_LMAXCLIENTS, IRCstats.me_max, FALSE);
- SetTimer(hDlg, 1, 5000, NULL);
- return (TRUE);
- }
- case WM_CLOSE:
- DestroyWindow(hDlg);
- return TRUE;
- case WM_TIMER:
- TreeView_DeleteAllItems(hwTreeView);
- win_map(&me, hwTreeView, 1);
- SetDlgItemInt(hDlg, IDC_CLIENTS, IRCstats.clients, FALSE);
- SetDlgItemInt(hDlg, IDC_SERVERS, IRCstats.servers, FALSE);
- SetDlgItemInt(hDlg, IDC_INVISO, IRCstats.invisible, FALSE);
- SetDlgItemInt(hDlg, IDC_INVISO, IRCstats.invisible, FALSE);
- SetDlgItemInt(hDlg, IDC_UNKNOWN, IRCstats.unknown, FALSE);
- SetDlgItemInt(hDlg, IDC_OPERS, IRCstats.operators, FALSE);
- SetDlgItemInt(hDlg, IDC_CHANNELS, IRCstats.channels, FALSE);
- if (IRCstats.clients > IRCstats.global_max)
- IRCstats.global_max = IRCstats.clients;
- if (IRCstats.me_clients > IRCstats.me_max)
- IRCstats.me_max = IRCstats.me_clients;
- SetDlgItemInt(hDlg, IDC_MAXCLIENTS, IRCstats.global_max, FALSE);
- SetDlgItemInt(hDlg, IDC_LCLIENTS, IRCstats.me_clients, FALSE);
- SetDlgItemInt(hDlg, IDC_LSERVERS, IRCstats.me_servers, FALSE);
- SetDlgItemInt(hDlg, IDC_LMAXCLIENTS, IRCstats.me_max, FALSE);
- SetTimer(hDlg, 1, 5000, NULL);
- return (TRUE);
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK) {
- DestroyWindow(hDlg);
- return TRUE;
- }
- break;
-
- }
- return (FALSE);
-}
-
-LRESULT CALLBACK ColorDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
- static HBRUSH hBrushWhite, hBrushBlack, hBrushDarkBlue, hBrushDarkGreen, hBrushRed,
- hBrushDarkRed, hBrushPurple, hBrushOrange, hBrushYellow, hBrushGreen, hBrushVDarkGreen,
- hBrushLightBlue, hBrushBlue, hBrushPink, hBrushDarkGray, hBrushGray;
- static UINT ResultMsg=0;
- switch (message) {
- case WM_INITDIALOG:
- hBrushWhite = CreateSolidBrush(RGB(255,255,255));
- hBrushBlack = CreateSolidBrush(RGB(0,0,0));
- hBrushDarkBlue = CreateSolidBrush(RGB(0,0,127));
- hBrushDarkGreen = CreateSolidBrush(RGB(0,147,0));
- hBrushRed = CreateSolidBrush(RGB(255,0,0));
- hBrushDarkRed = CreateSolidBrush(RGB(127,0,0));
- hBrushPurple = CreateSolidBrush(RGB(156,0,156));
- hBrushOrange = CreateSolidBrush(RGB(252,127,0));
- hBrushYellow = CreateSolidBrush(RGB(255,255,0));
- hBrushGreen = CreateSolidBrush(RGB(0,252,0));
- hBrushVDarkGreen = CreateSolidBrush(RGB(0,147,147));
- hBrushLightBlue = CreateSolidBrush(RGB(0,255,255));
- hBrushBlue = CreateSolidBrush(RGB(0,0,252));
- hBrushPink = CreateSolidBrush(RGB(255,0,255));
- hBrushDarkGray = CreateSolidBrush(RGB(127,127,127));
- hBrushGray = CreateSolidBrush(RGB(210,210,210));
- ResultMsg = (UINT)lParam;
- SetFocus(NULL);
- return (TRUE);
- case WM_DRAWITEM: {
- LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
- if (wParam == IDC_WHITE) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushWhite);
- }
- if (wParam == IDC_BLACK) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushBlack);
- }
- if (wParam == IDC_DARKBLUE) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushDarkBlue);
- }
- if (wParam == IDC_DARKGREEN) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushDarkGreen);
- }
- if (wParam == IDC_RED) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushRed);
- }
- if (wParam == IDC_DARKRED) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushDarkRed);
- }
- if (wParam == IDC_PURPLE) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushPurple);
- }
- if (wParam == IDC_ORANGE) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushOrange);
- }
- if (wParam == IDC_YELLOW) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushYellow);
- }
- if (wParam == IDC_GREEN) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushGreen);
- }
- if (wParam == IDC_VDARKGREEN) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushVDarkGreen);
- }
- if (wParam == IDC_LIGHTBLUE) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushLightBlue);
- }
- if (wParam == IDC_BLUE) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushBlue);
- }
- if (wParam == IDC_PINK) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushPink);
- }
- if (wParam == IDC_DARKGRAY) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushDarkGray);
- }
- if (wParam == IDC_GRAY) {
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrushGray);
- }
- DrawEdge(lpdis->hDC, &lpdis->rcItem, EDGE_SUNKEN, BF_RECT);
- return TRUE;
- }
- case WM_COMMAND: {
- COLORREF clrref;
- if (LOWORD(wParam) == IDC_WHITE)
- clrref = RGB(255,255,255);
- else if (LOWORD(wParam) == IDC_BLACK)
- clrref = RGB(0,0,0);
- else if (LOWORD(wParam) == IDC_DARKBLUE)
- clrref = RGB(0,0,127);
- else if (LOWORD(wParam) == IDC_DARKGREEN)
- clrref = RGB(0,147,0);
- else if (LOWORD(wParam) == IDC_RED)
- clrref = RGB(255,0,0);
- else if (LOWORD(wParam) == IDC_DARKRED)
- clrref = RGB(127,0,0);
- else if (LOWORD(wParam) == IDC_PURPLE)
- clrref = RGB(156,0,156);
- else if (LOWORD(wParam) == IDC_ORANGE)
- clrref = RGB(252,127,0);
- else if (LOWORD(wParam) == IDC_YELLOW)
- clrref = RGB(255,255,0);
- else if (LOWORD(wParam) == IDC_GREEN)
- clrref = RGB(0,252,0);
- else if (LOWORD(wParam) == IDC_VDARKGREEN)
- clrref = RGB(0,147,147);
- else if (LOWORD(wParam) == IDC_LIGHTBLUE)
- clrref = RGB(0,255,255);
- else if (LOWORD(wParam) == IDC_BLUE)
- clrref = RGB(0,0,252);
- else if (LOWORD(wParam) == IDC_PINK)
- clrref = RGB(255,0,255);
- else if (LOWORD(wParam) == IDC_DARKGRAY)
- clrref = RGB(127,127,127);
- else if (LOWORD(wParam) == IDC_GRAY)
- clrref = RGB(210,210,210);
- SendMessage(GetParent(hDlg), ResultMsg, (WPARAM)clrref, (LPARAM)hDlg);
- }
-
- break;
- case WM_CLOSE:
- EndDialog(hDlg, TRUE);
- case WM_DESTROY:
- DeleteObject(hBrushWhite);
- DeleteObject(hBrushBlack);
- DeleteObject(hBrushDarkBlue);
- DeleteObject(hBrushDarkGreen);
- DeleteObject(hBrushRed);
- DeleteObject(hBrushDarkRed);
- DeleteObject(hBrushPurple);
- DeleteObject(hBrushOrange);
- DeleteObject(hBrushYellow);
- DeleteObject(hBrushGreen);
- DeleteObject(hBrushVDarkGreen);
- DeleteObject(hBrushLightBlue);
- DeleteObject(hBrushBlue);
- DeleteObject(hBrushPink);
- DeleteObject(hBrushDarkGray);
- DeleteObject(hBrushGray);
- break;
- }
-
- return (FALSE);
-}
-
-
-/* find how big a buffer expansion we need for RTF transformation */
-int CountRTFSize(unsigned char *buffer) {
- int size = 0;
- char bold = 0, uline = 0, incolor = 0, inbg = 0, reverse = 0;
- char *buf = buffer;
-
- for (; *buf; buf++)
- {
- if (*buf == '{' || *buf == '}' || *buf == '\\')
- size++;
- 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;
- }
- }
- else if (*buf == '\n')
- {
- 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;
- }
- else if (*buf == '\2')
- {
- if (bold)
- size += 4;
- else
- size += 3;
- bold = !bold;
- continue;
- }
- 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 (*(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 (*(buf+1) && isdigit(*(buf+1)))
- color[1] = *(++buf);
- color[2] = 0;
- number = atoi(color);
- if (number == 99 || number == 1)
- size += 2;
- 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;
- }
- 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 += 17;
- reverse = !reverse;
- continue;
- }
- else if (*buf == '\37')
- {
- if (uline)
- size += 8;
- else
- size += 4;
- uline = !uline;
- continue;
- }
- 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;
- int i = 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 = strlen(string);
- for (tmp = buffer; *tmp; tmp++)
- {
- if (*tmp == '{')
- {
- strcat(string, "\\{");
- i+=2;
- continue;
- }
- else if (*tmp == '}')
- {
- strcat(string, "\\}");
- i+=2;
- continue;
- }
- else if (*tmp == '\\')
- {
- strcat(string, "\\\\");
- i+=2;
- continue;
- }
- 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 +=6;
- }
- else
- string[i++]='\r';
- continue;
- }
- else if (*tmp == '\n')
- {
- 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 +=6;
- continue;
- }
- else if (*tmp == '\2')
- {
- if (bold)
- {
- strcat(string, "\\b0 ");
- i+=4;
- }
- else
- {
- strcat(string, "\\b ");
- 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;
- }
- }
- }
- continue;
- }
- else if (*tmp == '\3' && !reverse)
- {
- strcat(string, "\\cf");
- i += 3;
- if (*(tmp+1) && !isdigit(*(tmp+1)))
- {
- incolor = 0;
- string[i++] = '0';
- if (inbg)
- {
- inbg = 0;
- strcat(string, "\\highlight0");
- i += 11;
- }
- }
- else if (*(tmp+1))
- {
- unsigned char color[3];
- int number;
- color[0] = *(++tmp);
- color[1] = 0;
- if (*(tmp+1) && isdigit(*(tmp+1)))
- color[1] = *(++tmp);
- color[2] = 0;
- number = atoi(color);
- if (number == 99 || number == 1)
- {
- strcat(string, "16");
- i += 2;
- }
- else if (number == 0)
- {
- strcat(string, "1");
- i++;
- }
- 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++] = ' ';
- continue;
- }
- else if (*tmp == '\17') {
- if (uline) {
- strcat(string, "\\ulnone");
- i += 7;
- }
- if (bold) {
- strcat(string, "\\b0");
- i += 3;
- }
- 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;
- }
-
- else if (*tmp == '\37') {
- if (uline) {
- strcat(string, "\\ulnone ");
- i += 8;
- }
- else {
- strcat(string, "\\ul ");
- i += 4;
- }
- uline = !uline;
- continue;
- }
- string[i++] = *tmp;
- }
- strcat(string, "}");
- return;
-}
-
-/* This was made by DrBin but I cleaned it up a bunch to make it work better */
-
-HTREEITEM AddItemToTree(HWND hWnd, LPSTR lpszItem, int nLevel, short remap)
-{
- TVITEM tvi;
- TVINSERTSTRUCT tvins;
- static HTREEITEM hPrev = (HTREEITEM)TVI_FIRST;
- static HTREEITEM hPrevLev[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
- HTREEITEM hti;
- if (remap) {
- hPrev = (HTREEITEM)TVI_FIRST;
- memset(hPrevLev, 0, sizeof(HTREEITEM)*10);
- }
-
- tvi.mask = TVIF_TEXT|TVIF_PARAM;
- tvi.pszText = lpszItem;
- tvi.cchTextMax = lstrlen(lpszItem);
- tvi.lParam = (LPARAM)nLevel;
- tvins.item = tvi;
- tvins.hInsertAfter = hPrev;
- if (nLevel == 1)
- tvins.hParent = TVI_ROOT;
- else
- tvins.hParent = hPrevLev[nLevel-1];
- hPrev = (HTREEITEM)SendMessage(hWnd, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT) &tvins);
- hPrevLev[nLevel] = hPrev;
- TreeView_EnsureVisible(hWnd,hPrev);
- if (nLevel > 1) {
- hti = TreeView_GetParent(hWnd, hPrev);
- tvi.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE;
- tvi.hItem = hti;
- TreeView_SetItem(hWnd, &tvi);
- }
- return hPrev;
-}
-
-/*
- * Now used to create list of servers for server list tree view -- David Flynn
- * Recoded by codemastr to be faster.
- * I removed the Potvin credit because it no longer uses any original code and I don't
- * even think Potvin actually made the original code
- */
-void win_map(aClient *server, HWND hwTreeView, short remap)
-{
- aClient *acptr;
- Link *lp;
- AddItemToTree(hwTreeView,server->name,server->hopcount+1, remap);
- for (lp = Servers; lp; lp = lp->next)
- {
- acptr = lp->value.cptr;
- if (acptr->srvptr != server)
- continue;
- win_map(acptr, hwTreeView, 0);
- }
-}
-
-/* ugly stuff, but hey it works -- codemastr */
-void win_log(unsigned char *format, ...) {
- va_list ap;
- unsigned char buf[2048];
- unsigned char *buf2;
- va_start(ap, format);
- ircvsprintf(buf, format, ap);
- if (!IsService) {
- strcat(buf, "\r\n");
- if (errors) {
- buf2 = MyMalloc(strlen(errors)+strlen(buf)+1);
- sprintf(buf2, "%s%s",errors,buf);
- MyFree(errors);
- errors = NULL;
- }
- else {
- buf2 = MyMalloc(strlen(buf)+1);
- sprintf(buf2, "%s",buf);
- }
- errors = buf2;
- }
- else {
- FILE *fd = fopen("service.log", "a");
- fprintf(fd, "%s\n", buf);
- fclose(fd);
- }
- va_end(ap);
-}
-
-void win_error() {
- if (errors && !IsService)
- DialogBox(hInst, "ConfigError", hwIRCDWnd, (DLGPROC)ConfigErrorDLG);
-}
-
-LRESULT CALLBACK ConfigErrorDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
- switch (message) {
- case WM_INITDIALOG:
- MessageBeep(MB_ICONEXCLAMATION);
- SetDlgItemText(hDlg, IDC_CONFIGERROR, errors);
- MyFree(errors);
- errors = NULL;
- return (TRUE);
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK)
- EndDialog(hDlg, TRUE);
- break;
- case WM_CLOSE:
- EndDialog(hDlg, TRUE);
- break;
- case WM_DESTROY:
- break;
-
- }
- return (FALSE);
-}
diff --git a/src/win32/debug.c b/src/win32/debug.c
index 6a6d45624..9c7a98eb9 100644
--- a/src/win32/debug.c
+++ b/src/win32/debug.c
@@ -1,6 +1,6 @@
/************************************************************************
* IRC - Internet Relay Chat, win32/debug.c
- * Copyright (C) 2002 Dominick Meglio (codemastr)
+ * Copyright (C) 2002-2004 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
@@ -33,16 +33,24 @@
#define IRCDTOTALVERSION BASE_VERSION PATCH1 PATCH2 PATCH3 PATCH4 PATCH5 PATCH6 PATCH7 PATCH8 PATCH9
#endif
#define BUFFERSIZE 0x200
+
extern OSVERSIONINFO VerInfo;
extern char OSName[256];
extern char backupbuf[8192];
extern char *buildid;
extern char serveropts[];
extern char *extraflags;
-void CleanUp(void);
extern BOOL IsService;
+void CleanUp(void);
-__inline char *StackTrace(EXCEPTION_POINTERS *e) {
+/* Runs a stack trace
+ * Parameters:
+ * e - The exception information
+ * Returns:
+ * The stack trace with function and line number information
+ */
+__inline char *StackTrace(EXCEPTION_POINTERS *e)
+{
static char buffer[5000];
char curmodule[32];
DWORD symOptions, dwDisp, frame;
@@ -51,6 +59,8 @@ __inline char *StackTrace(EXCEPTION_POINTERS *e) {
IMAGEHLP_LINE pLine;
IMAGEHLP_MODULE pMod;
STACKFRAME Stack;
+
+ /* Load the stack information */
Stack.AddrPC.Offset = e->ContextRecord->Eip;
Stack.AddrPC.Mode = AddrModeFlat;
Stack.AddrFrame.Offset = e->ContextRecord->Ebp;
@@ -60,6 +70,7 @@ __inline char *StackTrace(EXCEPTION_POINTERS *e) {
else
hProcess = GetCurrentProcess();
+ /* Initialize symbol retrieval system */
SymInitialize(hProcess, NULL, TRUE);
SymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_UNDNAME);
bzero(pSym, sizeof(IMAGEHLP_SYMBOL)+500);
@@ -69,69 +80,65 @@ __inline char *StackTrace(EXCEPTION_POINTERS *e) {
pLine.SizeOfStruct = sizeof(IMAGEHLP_LINE);
bzero(&pMod, sizeof(IMAGEHLP_MODULE));
pMod.SizeOfStruct = sizeof(IMAGEHLP_MODULE);
+
+ /* Retrieve the first module name */
SymGetModuleInfo(hProcess, Stack.AddrPC.Offset, &pMod);
strcpy(curmodule, pMod.ModuleName);
sprintf(buffer, "\tModule: %s\n", pMod.ModuleName);
- for (frame = 0; ; frame++) {
+
+ /* Walk through the stack */
+ for (frame = 0; ; frame++)
+ {
char buf[500];
if (!StackWalk(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(),
&Stack, NULL, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL))
break;
SymGetModuleInfo(hProcess, Stack.AddrPC.Offset, &pMod);
- if (strcmp(curmodule, pMod.ModuleName)) {
+ if (strcmp(curmodule, pMod.ModuleName))
+ {
strcpy(curmodule, pMod.ModuleName);
sprintf(buf, "\tModule: %s\n", pMod.ModuleName);
strcat(buffer, buf);
}
SymGetLineFromAddr(hProcess, Stack.AddrPC.Offset, &dwDisp, &pLine);
SymGetSymFromAddr(hProcess, Stack.AddrPC.Offset, &dwDisp, pSym);
- sprintf(buf, "\t\t#%d %s:%d: %s\n", frame, pLine.FileName, pLine.LineNumber, pSym->Name);
+ sprintf(buf, "\t\t#%d %s:%d: %s\n", frame, pLine.FileName, pLine.LineNumber,
+ pSym->Name);
strcat(buffer, buf);
}
return buffer;
}
-__inline char *GetRegisters(CONTEXT *context) {
+/* Retrieves the values of several registers
+ * Parameters:
+ * context - The CPU context
+ * Returns:
+ * The values of the EAX/EBX/ECX/EDX/ESI/EDI/EIP/EBP/ESP registers
+ */
+__inline char *GetRegisters(CONTEXT *context)
+{
static char buffer[1024];
+
sprintf(buffer, "\tEAX=0x%08x EBX=0x%08x ECX=0x%08x\n"
"\tEDX=0x%08x ESI=0x%08x EDI=0x%08x\n"
"\tEIP=0x%08x EBP=0x%08x ESP=0x%08x\n",
- context->Eax, context->Ebx, context->Ecx, context->Edx,
- context->Esi, context->Edi, context->Eip, context->Ebp,
- context->Esp);
+ context->Eax, context->Ebx, context->Ecx, context->Edx,
+ context->Esi, context->Edi, context->Eip, context->Ebp,
+ context->Esp);
return buffer;
}
-/*__inline char *GetCpuName() {
- static char cpuname[48];
- __try {
- _asm {
- mov eax,080000002h
- CPUID
- mov DWORD PTR [cpuname+0],eax
- mov DWORD PTR [cpuname+4],ebx
- mov DWORD PTR [cpuname+8],ecx
- mov DWORD PTR [cpuname+12],edx
- mov eax,080000003h
- CPUID
- mov DWORD PTR [cpuname+16],eax
- mov DWORD PTR [cpuname+20],ebx
- mov DWORD PTR [cpuname+24],ecx
- mov DWORD PTR [cpuname+28],edx
- mov eax,080000004h
- CPUID
- mov DWORD PTR [cpuname+32],eax
- mov DWORD PTR [cpuname+36],ebx
- mov DWORD PTR [cpuname+40],ecx
- mov DWORD PTR [cpuname+44],edx
- }
- } __except(EXCEPTION_EXECUTE_HANDLER) { return NULL; }
- return cpuname;
-}*/
-
-__inline char *GetException(DWORD code) {
- switch (code) {
+/* Convert the exception code to a human readable string
+ * Parameters:
+ * code - The exception code to convert
+ * Returns:
+ * The exception code represented as a string
+ */
+__inline char *GetException(DWORD code)
+{
+ switch (code)
+ {
case EXCEPTION_ACCESS_VIOLATION:
return "Access Violation";
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
@@ -172,46 +179,69 @@ __inline char *GetException(DWORD code) {
return "Single Step";
case EXCEPTION_STACK_OVERFLOW:
return "Stack Overflow";
+ default:
+ return "Unknown Exception";
}
- return "Unknown Exception";
}
-
-LONG __stdcall ExceptionFilter(EXCEPTION_POINTERS *e) {
+/* Callback for the exception handler
+ * Parameters:
+ * e - The exception information
+ * Returns:
+ * EXCEPTION_EXECUTE_HANDLER to terminate the process
+ * Side Effects:
+ * wircd.PID.core is created
+ * If not running in service mode, a message box is displayed,
+ * else output is written to service.log
+ */
+LONG __stdcall ExceptionFilter(EXCEPTION_POINTERS *e)
+{
MEMORYSTATUS memStats;
char file[512], text[1024];
FILE *fd;
time_t timet = time(NULL);
+
sprintf(file, "wircd.%d.core", getpid());
fd = fopen(file, "w");
GlobalMemoryStatus(&memStats);
- fprintf(fd, "Generated at %s\n%s (%d.%d.%d)\n%s[%s%s%s] (%s)\n-----------------\nMemory Information:\n"
- "\tPhysical: (Available:%ldMB/Total:%ldMB)\n\tVirtual: (Available:%ldMB/Total:%ldMB)\n"
- "-----------------\nException:\n\t%s\n-----------------\nBackup Buffer:\n\t%s\n"
- "-----------------\nRegisters:\n%s-----------------\nStack Trace:\n%s", asctime(gmtime(&timet)),
- OSName, VerInfo.dwMajorVersion, VerInfo.dwMinorVersion, VerInfo.dwBuildNumber,
- IRCDTOTALVERSION, serveropts, extraflags ? extraflags : "", tainted ? "3" : "",
- buildid, memStats.dwAvailPhys/1048576, memStats.dwTotalPhys/1048576,
- memStats.dwAvailVirtual/1048576, memStats.dwTotalVirtual/1048576,
- GetException(e->ExceptionRecord->ExceptionCode), backupbuf,
- GetRegisters(e->ContextRecord), StackTrace(e));
+ fprintf(fd, "Generated at %s\n%s (%d.%d.%d)\n%s[%s%s%s] (%s)\n"
+ "-----------------\nMemory Information:\n"
+ "\tPhysical: (Available:%ldMB/Total:%ldMB)\n"
+ "\tVirtual: (Available:%ldMB/Total:%ldMB)\n"
+ "-----------------\nException:\n\t%s\n-----------------\n"
+ "Backup Buffer:\n\t%s\n-----------------\nRegisters:\n"
+ "%s-----------------\nStack Trace:\n%s",
+ asctime(gmtime(&timet)), OSName, VerInfo.dwMajorVersion,
+ VerInfo.dwMinorVersion, VerInfo.dwBuildNumber, IRCDTOTALVERSION,
+ serveropts, extraflags ? extraflags : "", tainted ? "3" : "",
+ buildid, memStats.dwAvailPhys/1048576, memStats.dwTotalPhys/1048576,
+ memStats.dwAvailVirtual/1048576, memStats.dwTotalVirtual/1048576,
+ GetException(e->ExceptionRecord->ExceptionCode), backupbuf,
+ GetRegisters(e->ContextRecord), StackTrace(e));
+
sprintf(text, "UnrealIRCd has encountered a fatal error. Debugging information has"
- " been dumped to wircd.%d.core, please email this file to coders@lists.unrealircd.org.",
- getpid());
+ " been dumped to wircd.%d.core, please email this file to "
+ "coders@lists.unrealircd.org.", getpid());
fclose(fd);
+
if (!IsService)
MessageBox(NULL, text, "Fatal Error", MB_OK);
- else {
+ else
+ {
FILE *fd = fopen("service.log", "a");
- fprintf(fd, "UnrealIRCd has encountered a fatal error. Debugging information has"
- " been dumped to wircd.%d.core, please email this file to coders@lists.unrealircd.org.", getpid());
+
+ fprintf(fd, "UnrealIRCd has encountered a fatal error. Debugging information "
+ "has been dumped to wircd.%d.core, please email this file to "
+ "coders@lists.unrealircd.org.", getpid());
fclose(fd);
}
CleanUp();
return EXCEPTION_EXECUTE_HANDLER;
}
-void InitDebug(void) {
+/* Initializes the exception handler */
+void InitDebug(void)
+{
SetUnhandledExceptionFilter(&ExceptionFilter);
}
diff --git a/src/win32/editor.c b/src/win32/editor.c
new file mode 100644
index 000000000..9b9ee3656
--- /dev/null
+++ b/src/win32/editor.c
@@ -0,0 +1,777 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, win32/editor.c
+ * Copyright (C) 2004 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
+ * 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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "resource.h"
+#include "setup.h"
+#include "win32.h"
+#include "sys.h"
+
+LRESULT CALLBACK GotoDLG(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK ColorDLG(HWND, UINT, WPARAM, LPARAM);
+
+HWND hFind;
+
+/* Draws the statusbar for the editor
+ * Parameters:
+ * hInstance - The instance to create the statusbar in
+ * hwndParent - The parent of the statusbar
+ * iId - The message value used to send messages to the parent
+ * Returns:
+ * The handle to the statusbar
+ */
+HWND DrawStatusbar(HINSTANCE hInstance, HWND hwndParent, UINT iId)
+{
+ HWND hStatus, hTip;
+ TOOLINFO ti;
+ RECT clrect;
+ hStatus = CreateStatusWindow(WS_CHILD|WS_VISIBLE|SBT_TOOLTIPS, NULL, hwndParent, iId);
+ hTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
+ WS_POPUP|TTS_NOPREFIX|TTS_ALWAYSTIP, 0, 0, 0, 0, hwndParent, NULL, hInstance, NULL);
+ GetClientRect(hStatus, &clrect);
+ ti.cbSize = sizeof(TOOLINFO);
+ ti.uFlags = TTF_SUBCLASS;
+ ti.hwnd = hStatus;
+ ti.uId = 1;
+ ti.hinst = hInstance;
+ ti.rect = clrect;
+ ti.lpszText = "Go To";
+ SendMessage(hTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
+ return hStatus;
+}
+
+/* Draws the toolbar for the editor
+ * Parameters:
+ * hInstance - The instance to create the toolbar in
+ * hwndParent - The parent of the toolbar
+ * Returns:
+ * The handle to the toolbar
+ */
+HWND DrawToolbar(HINSTANCE hInstance, HWND hwndParent)
+{
+ HWND hTool;
+ TBADDBITMAP tbBit;
+ int newidx;
+ TBBUTTON tbButtons[10] = {
+ { STD_FILENEW, IDM_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
+ { STD_FILESAVE, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
+ { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, 0},
+ { STD_CUT, IDM_CUT, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
+ { STD_COPY, IDM_COPY, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
+ { STD_PASTE, IDM_PASTE, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
+ { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, 0},
+ { STD_UNDO, IDM_UNDO, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
+ { STD_REDOW, IDM_REDO, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
+ { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, 0}
+ };
+
+ 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},
+ { 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 = hInstance;
+ tbBit.nID = IDB_BITMAP1;
+ newidx = SendMessage(hTool, TB_ADDBITMAP, (WPARAM)5, (LPARAM)&tbBit);
+ tbAddButtons[0].iBitmap += newidx;
+ tbAddButtons[1].iBitmap += newidx;
+ tbAddButtons[2].iBitmap += newidx;
+ tbAddButtons[3].iBitmap += newidx;
+ tbAddButtons[5].iBitmap += newidx;
+ SendMessage(hTool, TB_ADDBUTTONS, (WPARAM)7, (LPARAM)&tbAddButtons);
+ return hTool;
+}
+
+/* Dialog procedure for the color selection dialog
+ * Parameters:
+ * hDlg - The dialog handle
+ * message - The message received
+ * wParam - The first message parameter
+ * lParam - The second message parameter
+ * Returns:
+ * TRUE if the message was processed, FALSE otherwise
+ */
+LRESULT CALLBACK ColorDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
+ static HBRUSH hBrushWhite, hBrushBlack, hBrushDarkBlue, hBrushDarkGreen, hBrushRed,
+ hBrushDarkRed, hBrushPurple, hBrushOrange, hBrushYellow, hBrushGreen, hBrushVDarkGreen,
+ hBrushLightBlue, hBrushBlue, hBrushPink, hBrushDarkGray, hBrushGray;
+ static UINT ResultMsg = 0;
+
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ hBrushWhite = CreateSolidBrush(RGB(255,255,255));
+ hBrushBlack = CreateSolidBrush(RGB(0,0,0));
+ hBrushDarkBlue = CreateSolidBrush(RGB(0,0,127));
+ hBrushDarkGreen = CreateSolidBrush(RGB(0,147,0));
+ hBrushRed = CreateSolidBrush(RGB(255,0,0));
+ hBrushDarkRed = CreateSolidBrush(RGB(127,0,0));
+ hBrushPurple = CreateSolidBrush(RGB(156,0,156));
+ hBrushOrange = CreateSolidBrush(RGB(252,127,0));
+ hBrushYellow = CreateSolidBrush(RGB(255,255,0));
+ hBrushGreen = CreateSolidBrush(RGB(0,252,0));
+ hBrushVDarkGreen = CreateSolidBrush(RGB(0,147,147));
+ hBrushLightBlue = CreateSolidBrush(RGB(0,255,255));
+ hBrushBlue = CreateSolidBrush(RGB(0,0,252));
+ hBrushPink = CreateSolidBrush(RGB(255,0,255));
+ hBrushDarkGray = CreateSolidBrush(RGB(127,127,127));
+ hBrushGray = CreateSolidBrush(RGB(210,210,210));
+ ResultMsg = (UINT)lParam;
+ SetFocus(NULL);
+ return TRUE;
+ case WM_DRAWITEM:
+ {
+ LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
+ if (wParam == IDC_WHITE)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushWhite);
+ if (wParam == IDC_BLACK)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushBlack);
+ if (wParam == IDC_DARKBLUE)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushDarkBlue);
+ if (wParam == IDC_DARKGREEN)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushDarkGreen);
+ if (wParam == IDC_RED)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushRed);
+ if (wParam == IDC_DARKRED)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushDarkRed);
+ if (wParam == IDC_PURPLE)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushPurple);
+ if (wParam == IDC_ORANGE)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushOrange);
+ if (wParam == IDC_YELLOW)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushYellow);
+ if (wParam == IDC_GREEN)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushGreen);
+ if (wParam == IDC_VDARKGREEN)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushVDarkGreen);
+ if (wParam == IDC_LIGHTBLUE)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushLightBlue);
+ if (wParam == IDC_BLUE)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushBlue);
+ if (wParam == IDC_PINK)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushPink);
+ if (wParam == IDC_DARKGRAY)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushDarkGray);
+ if (wParam == IDC_GRAY)
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrushGray);
+ DrawEdge(lpdis->hDC, &lpdis->rcItem, EDGE_SUNKEN, BF_RECT);
+ return TRUE;
+ }
+ case WM_COMMAND:
+ {
+ COLORREF clrref;
+ if (LOWORD(wParam) == IDC_WHITE)
+ clrref = RGB(255,255,255);
+ else if (LOWORD(wParam) == IDC_BLACK)
+ clrref = RGB(0,0,0);
+ else if (LOWORD(wParam) == IDC_DARKBLUE)
+ clrref = RGB(0,0,127);
+ else if (LOWORD(wParam) == IDC_DARKGREEN)
+ clrref = RGB(0,147,0);
+ else if (LOWORD(wParam) == IDC_RED)
+ clrref = RGB(255,0,0);
+ else if (LOWORD(wParam) == IDC_DARKRED)
+ clrref = RGB(127,0,0);
+ else if (LOWORD(wParam) == IDC_PURPLE)
+ clrref = RGB(156,0,156);
+ else if (LOWORD(wParam) == IDC_ORANGE)
+ clrref = RGB(252,127,0);
+ else if (LOWORD(wParam) == IDC_YELLOW)
+ clrref = RGB(255,255,0);
+ else if (LOWORD(wParam) == IDC_GREEN)
+ clrref = RGB(0,252,0);
+ else if (LOWORD(wParam) == IDC_VDARKGREEN)
+ clrref = RGB(0,147,147);
+ else if (LOWORD(wParam) == IDC_LIGHTBLUE)
+ clrref = RGB(0,255,255);
+ else if (LOWORD(wParam) == IDC_BLUE)
+ clrref = RGB(0,0,252);
+ else if (LOWORD(wParam) == IDC_PINK)
+ clrref = RGB(255,0,255);
+ else if (LOWORD(wParam) == IDC_DARKGRAY)
+ clrref = RGB(127,127,127);
+ else if (LOWORD(wParam) == IDC_GRAY)
+ clrref = RGB(210,210,210);
+ SendMessage(GetParent(hDlg), ResultMsg, (WPARAM)clrref, (LPARAM)hDlg);
+ break;
+ }
+ case WM_CLOSE:
+ EndDialog(hDlg, TRUE);
+ case WM_DESTROY:
+ DeleteObject(hBrushWhite);
+ DeleteObject(hBrushBlack);
+ DeleteObject(hBrushDarkBlue);
+ DeleteObject(hBrushDarkGreen);
+ DeleteObject(hBrushRed);
+ DeleteObject(hBrushDarkRed);
+ DeleteObject(hBrushPurple);
+ DeleteObject(hBrushOrange);
+ DeleteObject(hBrushYellow);
+ DeleteObject(hBrushGreen);
+ DeleteObject(hBrushVDarkGreen);
+ DeleteObject(hBrushLightBlue);
+ DeleteObject(hBrushBlue);
+ DeleteObject(hBrushPink);
+ DeleteObject(hBrushDarkGray);
+ DeleteObject(hBrushGray);
+ break;
+ }
+
+ return FALSE;
+}
+
+/* Dialog procedure for the goto dialog
+ * Parameters:
+ * hDlg - The dialog handle
+ * message - The message received
+ * wParam - The first message parameter
+ * lParam - The second message parameter
+ * Returns:
+ * TRUE if the message was processed, FALSE otherwise
+ */
+LRESULT CALLBACK GotoDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ if (message == WM_COMMAND)
+ {
+ if (LOWORD(wParam) == IDCANCEL)
+ EndDialog(hDlg, TRUE);
+ else if (LOWORD(wParam) == IDOK)
+ {
+ HWND hWnd = GetDlgItem(GetParent(hDlg),IDC_TEXT);
+ int line = GetDlgItemInt(hDlg, IDC_GOTO, NULL, FALSE);
+ int pos = SendMessage(hWnd, EM_LINEINDEX, (WPARAM)--line, 0);
+ SendMessage(hWnd, EM_SETSEL, (WPARAM)pos, (LPARAM)pos);
+ SendMessage(hWnd, EM_SCROLLCARET, 0, 0);
+ EndDialog(hDlg, TRUE);
+ }
+ }
+ return FALSE;
+}
+
+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;
+ unsigned char *buffer = '\0', *string = '\0';
+ EDITSTREAM edit;
+ StreamIO *stream = malloc(sizeof(StreamIO));
+ unsigned char szText[256];
+ struct stat sb;
+ HWND hWnd = GetDlgItem(hDlg, IDC_TEXT), hTip;
+ file = (unsigned char *)lParam;
+ if (file)
+ wsprintf(szText, "UnrealIRCd Editor - %s", file);
+ else
+ strcpy(szText, "UnrealIRCd Editor - New File");
+ SetWindowText(hDlg, szText);
+ lpfnOldWndProc = (FARPROC)SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)RESubClassFunc);
+ hTool = DrawToolbar(hInst, hDlg);
+ hStatus = DrawStatusbar(hInst, hDlg, IDC_STATUS);
+ SendMessage(hWnd, EM_SETEVENTMASK, 0, (LPARAM)ENM_SELCHANGE);
+ chars.cbSize = sizeof(CHARFORMAT2);
+ chars.dwMask = CFM_FACE;
+ strcpy(chars.szFaceName,"Fixedsys");
+ SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_ALL, (LPARAM)&chars);
+ if ((fd = open(file, _O_RDONLY|_O_BINARY)) != -1)
+ {
+ fstat(fd,&sb);
+ /* Only allocate the amount we need */
+ buffer = malloc(sb.st_size+1);
+ buffer[0] = 0;
+ len = read(fd, buffer, sb.st_size);
+ buffer[len] = 0;
+ len = CountRTFSize(buffer)+1;
+ string = malloc(len);
+ bzero(string,len);
+ IRCToRTF(buffer,string);
+ RTFBuf = string;
+ len--;
+ stream->size = &len;
+ stream->buffer = &RTFBuf;
+ edit.dwCookie = (UINT)stream;
+ edit.pfnCallback = SplitIt;
+ SendMessage(hWnd, EM_EXLIMITTEXT, 0, (LPARAM)0x7FFFFFFF);
+ SendMessage(hWnd, EM_STREAMIN, (WPARAM)SF_RTF|SFF_PLAINRTF, (LPARAM)&edit);
+ SendMessage(hWnd, EM_SETMODIFY, (WPARAM)FALSE, 0);
+ SendMessage(hWnd, EM_EMPTYUNDOBUFFER, 0, 0);
+ close(fd);
+ RTFBuf = NULL;
+ free(buffer);
+ free(string);
+ free(stream);
+ hClip = SetClipboardViewer(hDlg);
+ if (SendMessage(hWnd, EM_CANPASTE, 0, 0))
+ SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_PASTE, (LPARAM)MAKELONG(TRUE,0));
+ else
+ SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_PASTE, (LPARAM)MAKELONG(FALSE,0));
+ SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_UNDO, (LPARAM)MAKELONG(FALSE,0));
+ wsprintf(szText, "Line: 1");
+ SetWindowText(hStatus, szText);
+ }
+ 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:
+ {
+ HWND hWnd = GetDlgItem(hDlg, IDC_TEXT);
+ DWORD start, end, currline;
+ static DWORD prevline = 0;
+ unsigned char buffer[512];
+ chars.cbSize = sizeof(CHARFORMAT2);
+ SendMessage(hWnd, EM_GETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
+ if (chars.dwMask & CFM_BOLD && chars.dwEffects & CFE_BOLD)
+ SendMessage(hTool, TB_CHECKBUTTON, (WPARAM)IDC_BOLD, (LPARAM)MAKELONG(TRUE,0));
+ else
+ SendMessage(hTool, TB_CHECKBUTTON, (WPARAM)IDC_BOLD, (LPARAM)MAKELONG(FALSE,0));
+ if (chars.dwMask & CFM_UNDERLINE && chars.dwEffects & CFE_UNDERLINE)
+ SendMessage(hTool, TB_CHECKBUTTON, (WPARAM)IDC_UNDERLINE, (LPARAM)MAKELONG(TRUE,0));
+ else
+ SendMessage(hTool, TB_CHECKBUTTON, (WPARAM)IDC_UNDERLINE, (LPARAM)MAKELONG(FALSE,0));
+ SendMessage(hWnd, EM_GETSEL,(WPARAM)&start, (LPARAM)&end);
+ if (start == end)
+ {
+ SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_COPY, (LPARAM)MAKELONG(FALSE,0));
+ SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_CUT, (LPARAM)MAKELONG(FALSE,0));
+ }
+ else
+ {
+ SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_COPY, (LPARAM)MAKELONG(TRUE,0));
+ SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_CUT, (LPARAM)MAKELONG(TRUE,0));
+ }
+ if (SendMessage(hWnd, EM_CANUNDO, 0, 0))
+ SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_UNDO, (LPARAM)MAKELONG(TRUE,0));
+ else
+ SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_UNDO, (LPARAM)MAKELONG(FALSE,0));
+ if (SendMessage(hWnd, EM_CANREDO, 0, 0))
+ SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_REDO, (LPARAM)MAKELONG(TRUE,0));
+ else
+ SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_REDO, (LPARAM)MAKELONG(FALSE,0));
+ currline = SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)-1, 0);
+ currline++;
+ if (currline != prevline)
+ {
+ wsprintf(buffer, "Line: %d", currline);
+ SetWindowText(hStatus, buffer);
+ prevline = currline;
+ }
+ return TRUE;
+ }
+ case TTN_GETDISPINFO:
+ {
+ LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT) lParam;
+ lpttt->hinst = NULL;
+ switch (lpttt->hdr.idFrom)
+ {
+ case IDM_NEW:
+ strcpy(lpttt->szText, "New");
+ break;
+ case IDM_SAVE:
+ strcpy(lpttt->szText, "Save");
+ break;
+ case IDM_CUT:
+ strcpy(lpttt->szText, "Cut");
+ break;
+ case IDM_COPY:
+ strcpy(lpttt->szText, "Copy");
+ break;
+ case IDM_PASTE:
+ strcpy(lpttt->szText, "Paste");
+ break;
+ case IDM_UNDO:
+ strcpy(lpttt->szText, "Undo");
+ break;
+ case IDM_REDO:
+ strcpy(lpttt->szText, "Redo");
+ break;
+ case IDC_BOLD:
+ strcpy(lpttt->szText, "Bold");
+ break;
+ case IDC_UNDERLINE:
+ strcpy(lpttt->szText, "Underline");
+ break;
+ 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;
+ }
+ case NM_DBLCLK:
+ DialogBox(hInst, "GOTO", hDlg, (DLGPROC)GotoDLG);
+ return (TRUE);
+ }
+
+ return (TRUE);
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_BOLD)
+ {
+ hWnd = GetDlgItem(hDlg, IDC_TEXT);
+ if (SendMessage(hTool, TB_ISBUTTONCHECKED, (WPARAM)IDC_BOLD, (LPARAM)0) != 0)
+ {
+ chars.cbSize = sizeof(CHARFORMAT2);
+ chars.dwMask = CFM_BOLD;
+ chars.dwEffects = CFE_BOLD;
+ SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
+ SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
+ SetFocus(hWnd);
+ }
+ else
+ {
+ chars.cbSize = sizeof(CHARFORMAT2);
+ chars.dwMask = CFM_BOLD;
+ chars.dwEffects = 0;
+ SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
+ SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
+ SetFocus(hWnd);
+ }
+ return TRUE;
+ }
+ else if (LOWORD(wParam) == IDC_UNDERLINE)
+ {
+ hWnd = GetDlgItem(hDlg, IDC_TEXT);
+ if (SendMessage(hTool, TB_ISBUTTONCHECKED, (WPARAM)IDC_UNDERLINE, (LPARAM)0) != 0)
+ {
+ chars.cbSize = sizeof(CHARFORMAT2);
+ chars.dwMask = CFM_UNDERLINETYPE;
+ chars.bUnderlineType = CFU_UNDERLINE;
+ SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
+ SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
+ SetFocus(hWnd);
+ }
+ else
+ {
+ chars.cbSize = sizeof(CHARFORMAT2);
+ chars.dwMask = CFM_UNDERLINETYPE;
+ chars.bUnderlineType = CFU_UNDERLINENONE;
+ SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
+ SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
+ SetFocus(hWnd);
+ }
+ 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);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_SELECTALL)
+ {
+ SendMessage(hWnd, EM_SETSEL, 0, -1);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_PASTE)
+ {
+ SendMessage(hWnd, WM_PASTE, 0, 0);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_CUT)
+ {
+ SendMessage(hWnd, WM_CUT, 0, 0);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_UNDO)
+ {
+ SendMessage(hWnd, EM_UNDO, 0, 0);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_REDO)
+ {
+ SendMessage(hWnd, EM_REDO, 0, 0);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_DELETE)
+ {
+ SendMessage(hWnd, WM_CLEAR, 0, 0);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_SAVE)
+ {
+ int fd;
+ EDITSTREAM edit;
+ OPENFILENAME lpopen;
+ if (!file)
+ {
+ unsigned char path[MAX_PATH];
+ path[0] = '\0';
+ bzero(&lpopen, sizeof(OPENFILENAME));
+ lpopen.lStructSize = sizeof(OPENFILENAME);
+ lpopen.hwndOwner = hDlg;
+ lpopen.lpstrFilter = NULL;
+ lpopen.lpstrCustomFilter = NULL;
+ lpopen.nFilterIndex = 0;
+ lpopen.lpstrFile = path;
+ lpopen.nMaxFile = MAX_PATH;
+ lpopen.lpstrFileTitle = NULL;
+ lpopen.lpstrInitialDir = DPATH;
+ lpopen.lpstrTitle = NULL;
+ lpopen.Flags = (OFN_ENABLESIZING|OFN_NONETWORKBUTTON|
+ OFN_OVERWRITEPROMPT);
+ if (GetSaveFileName(&lpopen))
+ file = path;
+ else
+ break;
+ }
+ fd = open(file, _O_TRUNC|_O_CREAT|_O_WRONLY|_O_BINARY,_S_IWRITE);
+ edit.dwCookie = 0;
+ edit.pfnCallback = BufferIt;
+ SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_STREAMOUT, (WPARAM)SF_RTF|SFF_PLAINRTF, (LPARAM)&edit);
+ RTFToIRC(fd, RTFBuf, strlen(RTFBuf));
+ free(RTFBuf);
+ RTFBuf = NULL;
+ SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_SETMODIFY, (WPARAM)FALSE, 0);
+
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_NEW)
+ {
+ unsigned char text[1024];
+ BOOL newfile = FALSE;
+ int ans;
+ if (SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_GETMODIFY, 0, 0) != 0)
+ {
+ sprintf(text, "The text in the %s file has changed.\r\n\r\nDo you want to save the changes?", file ? file : "new");
+ ans = MessageBox(hDlg, text, "UnrealIRCd", MB_YESNOCANCEL|MB_ICONWARNING);
+ if (ans == IDNO)
+ newfile = TRUE;
+ if (ans == IDCANCEL)
+ return TRUE;
+ if (ans == IDYES)
+ {
+ SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDM_SAVE,0), 0);
+ newfile = TRUE;
+ }
+ }
+ else
+ newfile = TRUE;
+ if (newfile == TRUE)
+ {
+ unsigned char szText[256];
+ file = NULL;
+ strcpy(szText, "UnrealIRCd Editor - New File");
+ SetWindowText(hDlg, szText);
+ SetWindowText(GetDlgItem(hDlg, IDC_TEXT), NULL);
+ }
+ break;
+ }
+ break;
+ case WM_USER+10:
+ {
+ HWND hWnd = GetDlgItem(hDlg, IDC_TEXT);
+ EndDialog((HWND)lParam, TRUE);
+ chars.cbSize = sizeof(CHARFORMAT2);
+ chars.dwMask = CFM_COLOR;
+ chars.crTextColor = (COLORREF)wParam;
+ SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
+ SendMessage(hWnd, EM_HIDESELECTION, 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
+ SendMessage(hClip, WM_CHANGECBCHAIN, wParam, lParam);
+ break;
+ case WM_DRAWCLIPBOARD:
+ if (SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_CANPASTE, 0, 0))
+ SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_PASTE, (LPARAM)MAKELONG(TRUE,0));
+ else
+ SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_PASTE, (LPARAM)MAKELONG(FALSE,0));
+ SendMessage(hClip, WM_DRAWCLIPBOARD, wParam, lParam);
+ break;
+ case WM_CLOSE:
+ {
+ unsigned char text[256];
+ int ans;
+ if (SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_GETMODIFY, 0, 0) != 0)
+ {
+ sprintf(text, "The text in the %s file has changed.\r\n\r\nDo you want to save the changes?", file ? file : "new");
+ ans = MessageBox(hDlg, text, "UnrealIRCd", MB_YESNOCANCEL|MB_ICONWARNING);
+ if (ans == IDNO)
+ EndDialog(hDlg, TRUE);
+ if (ans == IDCANCEL)
+ return TRUE;
+ if (ans == IDYES)
+ {
+ SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDM_SAVE,0), 0);
+ EndDialog(hDlg, TRUE);
+ }
+ }
+ else
+ EndDialog(hDlg, TRUE);
+ break;
+ }
+ case WM_DESTROY:
+ ChangeClipboardChain(hDlg, hClip);
+ break;
+ }
+
+ return FALSE;
+}
diff --git a/src/win32/gui.c b/src/win32/gui.c
new file mode 100644
index 000000000..f90862d0c
--- /dev/null
+++ b/src/win32/gui.c
@@ -0,0 +1,1080 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, win32/gui.c
+ * Copyright (C) 2000-2004 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
+ * 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.
+ */
+
+#define WIN32_VERSION BASE_VERSION PATCH1 PATCH2 PATCH3 PATCH4
+#include "resource.h"
+#include "version.h"
+#include "setup.h"
+#ifdef INET6
+#include
+#include
+#endif
+#include
+#include
+#include
+#include "struct.h"
+#include "common.h"
+#include "sys.h"
+#include "numeric.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include "h.h"
+#include
+#include
+#include "win32.h"
+
+__inline void ShowDialog(HWND *handle, HINSTANCE inst, char *template, HWND parent,
+ DLGPROC proc)
+{
+ if (!IsWindow(*handle))
+ {
+ *handle = CreateDialog(inst, template, parent, (DLGPROC)proc);
+ ShowWindow(*handle, SW_SHOW);
+ }
+ else
+ SetForegroundWindow(*handle);
+}
+
+/* Comments:
+ *
+ * DrBin did a great job with the original GUI, but he has been gone a long time.
+ * In his absense, it was decided it would be best to continue windows development.
+ * The new code is based on his so it will be pretty much similar in features, my
+ * main goal is to make it more stable. A lot of what I know about GUI coding
+ * I learned from DrBin so thanks to him for teaching me :) -- codemastr
+ */
+
+LRESULT CALLBACK MainDLG(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK LicenseDLG(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK CreditsDLG(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK DalDLG(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK HelpDLG(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK StatusDLG(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK ConfigErrorDLG(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK FromVarDLG(HWND, UINT, WPARAM, LPARAM, unsigned char *, unsigned char **);
+LRESULT CALLBACK FromFileReadDLG(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK FromFileDLG(HWND, UINT, WPARAM, LPARAM);
+
+extern void SocketLoop(void *dummy);
+HINSTANCE hInst;
+NOTIFYICONDATA SysTray;
+void CleanUp(void);
+HTREEITEM AddItemToTree(HWND, LPSTR, int, short);
+void win_map(aClient *, HWND, short);
+extern Link *Servers;
+extern ircstats IRCstats;
+unsigned char *errors = NULL;
+extern aMotd *botmotd, *opermotd, *motd, *rules;
+extern VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
+extern BOOL IsService;
+void CleanUp(void)
+{
+ Shell_NotifyIcon(NIM_DELETE ,&SysTray);
+}
+void CleanUpSegv(int sig)
+{
+ Shell_NotifyIcon(NIM_DELETE ,&SysTray);
+}
+HWND hStatusWnd;
+HWND hwIRCDWnd=NULL;
+HWND hwTreeView;
+HWND hWndMod;
+HANDLE hMainThread = 0;
+UINT WM_TASKBARCREATED, WM_FINDMSGSTRING;
+FARPROC lpfnOldWndProc;
+HMENU hContext;
+OSVERSIONINFO VerInfo;
+char OSName[256];
+#ifdef USE_LIBCURL
+extern char *find_loaded_remote_include(char *url);
+#endif
+
+void TaskBarCreated()
+{
+ HICON hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON,16, 16, 0);
+ SysTray.cbSize = sizeof(NOTIFYICONDATA);
+ SysTray.hIcon = hIcon;
+ SysTray.hWnd = hwIRCDWnd;
+ SysTray.uCallbackMessage = WM_USER;
+ SysTray.uFlags = NIF_ICON|NIF_TIP|NIF_MESSAGE;
+ SysTray.uID = 0;
+ strcpy(SysTray.szTip, WIN32_VERSION);
+ Shell_NotifyIcon(NIM_ADD ,&SysTray);
+}
+
+LRESULT LinkSubClassFunc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
+{
+ static HCURSOR hCursor;
+ if (!hCursor)
+ hCursor = LoadCursor(hInst, MAKEINTRESOURCE(CUR_HAND));
+ if (Message == WM_MOUSEMOVE || Message == WM_LBUTTONDOWN)
+ SetCursor(hCursor);
+
+ return CallWindowProc((WNDPROC)lpfnOldWndProc, hWnd, Message, wParam, lParam);
+}
+
+
+
+LRESULT RESubClassFunc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
+{
+ POINT p;
+ RECT r;
+ DWORD start, end;
+ unsigned char string[500];
+
+ if (Message == WM_GETDLGCODE)
+ return DLGC_WANTALLKEYS;
+
+
+ if (Message == WM_CONTEXTMENU)
+ {
+ p.x = GET_X_LPARAM(lParam);
+ p.y = GET_Y_LPARAM(lParam);
+ if (GET_X_LPARAM(lParam) == -1 && GET_Y_LPARAM(lParam) == -1)
+ {
+ GetClientRect(hWnd, &r);
+ p.x = (int)((r.left + r.right)/2);
+ p.y = (int)((r.top + r.bottom)/2);
+ ClientToScreen(hWnd,&p);
+ }
+ if (!SendMessage(hWnd, EM_CANUNDO, 0, 0))
+ EnableMenuItem(hContext, IDM_UNDO, MF_BYCOMMAND|MF_GRAYED);
+ else
+ EnableMenuItem(hContext, IDM_UNDO, MF_BYCOMMAND|MF_ENABLED);
+ if (!SendMessage(hWnd, EM_CANPASTE, 0, 0))
+ EnableMenuItem(hContext, IDM_PASTE, MF_BYCOMMAND|MF_GRAYED);
+ else
+ EnableMenuItem(hContext, IDM_PASTE, MF_BYCOMMAND|MF_ENABLED);
+ if (GetWindowLong(hWnd, GWL_STYLE) & ES_READONLY)
+ {
+ EnableMenuItem(hContext, IDM_CUT, MF_BYCOMMAND|MF_GRAYED);
+ EnableMenuItem(hContext, IDM_DELETE, MF_BYCOMMAND|MF_GRAYED);
+ }
+ else
+ {
+ EnableMenuItem(hContext, IDM_CUT, MF_BYCOMMAND|MF_ENABLED);
+ EnableMenuItem(hContext, IDM_DELETE, MF_BYCOMMAND|MF_ENABLED);
+ }
+ SendMessage(hWnd, EM_GETSEL, (WPARAM)&start, (LPARAM)&end);
+ if (start == end)
+ EnableMenuItem(hContext, IDM_COPY, MF_BYCOMMAND|MF_GRAYED);
+ else
+ EnableMenuItem(hContext, IDM_COPY, MF_BYCOMMAND|MF_ENABLED);
+ TrackPopupMenu(hContext,TPM_LEFTALIGN|TPM_RIGHTBUTTON,p.x,p.y,0,GetParent(hWnd),NULL);
+ return 0;
+ }
+
+ return CallWindowProc((WNDPROC)lpfnOldWndProc, hWnd, Message, wParam, lParam);
+}
+
+int CloseUnreal(HWND hWnd)
+{
+ if (MessageBox(hWnd, "Close UnrealIRCd?", "Are you sure?", MB_YESNO|MB_ICONQUESTION)
+ == IDNO)
+ return 0;
+ else
+ {
+ DestroyWindow(hWnd);
+ exit(0);
+ }
+}
+
+int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
+{
+ MSG msg;
+ unsigned char *s;
+ HWND hWnd;
+ WSADATA WSAData;
+ HICON hIcon;
+ SERVICE_TABLE_ENTRY DispatchTable[] =
+ {
+ { "UnrealIRCd", ServiceMain },
+ { 0, 0 }
+ };
+ DWORD need;
+
+ VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&VerInfo);
+ GetOSName(VerInfo, OSName);
+ if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
+ {
+ SC_HANDLE hService, hSCManager = OpenSCManager(NULL, NULL, GENERIC_EXECUTE);
+ if ((hService = OpenService(hSCManager, "UnrealIRCd", GENERIC_EXECUTE)))
+ {
+ int save_err = 0;
+ StartServiceCtrlDispatcher(DispatchTable);
+ if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
+ {
+ 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);
+ if (save_err != ERROR_SERVICE_DISABLED)
+ exit(0);
+ } else {
+ CloseServiceHandle(hSCManager);
+ }
+ }
+ InitCommonControls();
+ WM_TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");
+ WM_FINDMSGSTRING = RegisterWindowMessage(FINDMSGSTRING);
+ atexit(CleanUp);
+ if(!LoadLibrary("riched20.dll"))
+ LoadLibrary("riched32.dll");
+ InitDebug();
+
+ if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
+ {
+ MessageBox(NULL, "Unable to initialize WinSock", "UnrealIRCD Initalization Error", MB_OK);
+ return FALSE;
+ }
+ hInst = hInstance;
+
+ hWnd = CreateDialog(hInstance, "WIRCD", 0, (DLGPROC)MainDLG);
+ hwIRCDWnd = hWnd;
+
+ TaskBarCreated();
+
+ if (InitwIRCD(__argc, __argv) != 1)
+ {
+ MessageBox(NULL, "UnrealIRCd has failed to initialize in InitwIRCD()", "UnrealIRCD Initalization Error" ,MB_OK);
+ return FALSE;
+ }
+ ShowWindow(hWnd, SW_SHOW);
+ hMainThread = (HANDLE)_beginthread(SocketLoop, 0, NULL);
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ if (!IsWindow(hStatusWnd) || !IsDialogMessage(hStatusWnd, &msg))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ return FALSE;
+
+}
+
+LRESULT CALLBACK MainDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static HCURSOR hCursor;
+ static HMENU hRehash, hAbout, hConfig, hTray, hLogs;
+
+ unsigned char *argv[3];
+ aClient *paClient;
+ unsigned char *msg;
+ POINT p;
+
+ if (message == WM_TASKBARCREATED)
+ {
+ TaskBarCreated();
+ return TRUE;
+ }
+
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ {
+ ShowWindow(hDlg, SW_HIDE);
+ hCursor = LoadCursor(hInst, MAKEINTRESOURCE(CUR_HAND));
+ hContext = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_CONTEXT)),0);
+ /* Rehash popup menu */
+ hRehash = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_REHASH)),0);
+ /* About popup menu */
+ hAbout = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_ABOUT)),0);
+ /* Systray popup menu set the items to point to the other menus*/
+ hTray = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_SYSTRAY)),0);
+ ModifyMenu(hTray, IDM_REHASH, MF_BYCOMMAND|MF_POPUP|MF_STRING, (UINT)hRehash, "&Rehash");
+ ModifyMenu(hTray, IDM_ABOUT, MF_BYCOMMAND|MF_POPUP|MF_STRING, (UINT)hAbout, "&About");
+
+ SetWindowText(hDlg, WIN32_VERSION);
+ SendMessage(hDlg, WM_SETICON, (WPARAM)ICON_SMALL,
+ (LPARAM)(HICON)LoadImage(hInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON,16, 16, 0));
+ SendMessage(hDlg, WM_SETICON, (WPARAM)ICON_BIG,
+ (LPARAM)(HICON)LoadImage(hInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON,32, 32, 0));
+ return TRUE;
+ }
+ case WM_SIZE:
+ {
+ if (wParam & SIZE_MINIMIZED)
+ ShowWindow(hDlg,SW_HIDE);
+ return 0;
+ }
+ case WM_CLOSE:
+ return CloseUnreal(hDlg);
+ case WM_USER:
+ {
+ switch(LOWORD(lParam))
+ {
+ case WM_LBUTTONDBLCLK:
+ ShowWindow(hDlg, SW_SHOW);
+ ShowWindow(hDlg,SW_RESTORE);
+ SetForegroundWindow(hDlg);
+ case WM_RBUTTONDOWN:
+ SetForegroundWindow(hDlg);
+ break;
+ case WM_RBUTTONUP:
+ {
+ unsigned long i = 60000;
+ GetCursorPos(&p);
+ DestroyMenu(hConfig);
+ hConfig = CreatePopupMenu();
+ DestroyMenu(hLogs);
+ hLogs = CreatePopupMenu();
+ AppendMenu(hConfig, MF_STRING, IDM_CONF, CPATH);
+ if (conf_log)
+ {
+ ConfigItem_log *logs;
+ AppendMenu(hConfig, MF_POPUP|MF_STRING, (UINT)hLogs, "Logs");
+ for (logs = conf_log; logs; logs = (ConfigItem_log *)logs->next)
+ {
+ AppendMenu(hLogs, MF_STRING, i++, logs->file);
+ }
+ }
+ AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
+ if (conf_include)
+ {
+ ConfigItem_include *inc;
+ for (inc = conf_include; inc; inc = (ConfigItem_include *)inc->next)
+ {
+ if (inc->flag.type & INCLUDE_NOTLOADED)
+ continue;
+#ifdef USE_LIBCURL
+ if (inc->flag.type & INCLUDE_REMOTE)
+ AppendMenu(hConfig, MF_STRING, i++, inc->url);
+ else
+#endif
+ AppendMenu(hConfig, MF_STRING, i++, inc->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);
+
+ if (conf_tld)
+ {
+ ConfigItem_tld *tlds;
+ AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
+ for (tlds = conf_tld; tlds; tlds = (ConfigItem_tld *)tlds->next)
+ {
+ if (!tlds->flag.motdptr)
+ 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_NEW, "New File");
+ ModifyMenu(hTray, IDM_CONFIG, MF_BYCOMMAND|MF_POPUP|MF_STRING, (UINT)hConfig, "&Config");
+ TrackPopupMenu(hTray, TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
+ /* Kludge for a win bug */
+ SendMessage(hDlg, WM_NULL, 0, 0);
+ break;
+ }
+ }
+ return 0;
+ }
+ case WM_DESTROY:
+ return 0;
+ case WM_MOUSEMOVE:
+ {
+ POINT p;
+ p.x = LOWORD(lParam);
+ p.y = HIWORD(lParam);
+ if ((p.x >= 24) && (p.x <= 78) && (p.y >= 178) && (p.y <= 190))
+ SetCursor(hCursor);
+ else if ((p.x >= 85) && (p.x <= 132) && (p.y >= 178) && (p.y <= 190))
+ SetCursor(hCursor);
+ else if ((p.x >= 140) && (p.x <= 186) && (p.y >= 178) && (p.y <= 190))
+ SetCursor(hCursor);
+ else if ((p.x >= 194) && (p.x <= 237) && (p.y >= 178) && (p.y <= 190))
+ SetCursor(hCursor);
+ else if ((p.x >= 245) && (p.x <= 311) && (p.y >= 178) && (p.y <= 190))
+ SetCursor(hCursor);
+ return 0;
+ }
+ case WM_LBUTTONDOWN:
+ {
+ POINT p;
+ p.x = LOWORD(lParam);
+ p.y = HIWORD(lParam);
+ if ((p.x >= 24) && (p.x <= 78) && (p.y >= 178) && (p.y <= 190))
+ {
+ ClientToScreen(hDlg,&p);
+ TrackPopupMenu(hRehash,TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
+ return 0;
+ }
+ else if ((p.x >= 85) && (p.x <= 132) && (p.y >= 178) && (p.y <= 190))
+ {
+ ShowDialog(&hStatusWnd, hInst, "Status", hDlg, StatusDLG);
+ return 0;
+ }
+ else if ((p.x >= 140) && (p.x <= 186) && (p.y >= 178) && (p.y <= 190))
+ {
+ unsigned long i = 60000;
+ ClientToScreen(hDlg,&p);
+ DestroyMenu(hConfig);
+ hConfig = CreatePopupMenu();
+ DestroyMenu(hLogs);
+ hLogs = CreatePopupMenu();
+
+ AppendMenu(hConfig, MF_STRING, IDM_CONF, CPATH);
+ if (conf_log)
+ {
+ ConfigItem_log *logs;
+ AppendMenu(hConfig, MF_POPUP|MF_STRING, (UINT)hLogs, "Logs");
+ for (logs = conf_log; logs; logs = (ConfigItem_log *)logs->next)
+ {
+ AppendMenu(hLogs, MF_STRING, i++, logs->file);
+ }
+ }
+ AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
+
+ if (conf_include)
+ {
+ ConfigItem_include *inc;
+ for (inc = conf_include; inc; inc = (ConfigItem_include *)inc->next)
+ {
+#ifdef USE_LIBCURL
+ if (inc->flag.type & INCLUDE_REMOTE)
+ AppendMenu(hConfig, MF_STRING, i++, inc->url);
+ else
+#endif
+ AppendMenu(hConfig, MF_STRING, i++, inc->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);
+
+ if (conf_tld)
+ {
+ ConfigItem_tld *tlds;
+ AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
+ for (tlds = conf_tld; tlds; tlds = (ConfigItem_tld *)tlds->next)
+ {
+ if (!tlds->flag.motdptr)
+ 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_NEW, "New File");
+ TrackPopupMenu(hConfig,TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
+
+ return 0;
+ }
+ else if ((p.x >= 194) && (p.x <= 237) && (p.y >= 178) && (p.y <= 190))
+ {
+ ClientToScreen(hDlg,&p);
+ TrackPopupMenu(hAbout,TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
+ return 0;
+ }
+ else if ((p.x >= 245) && (p.x <= 311) && (p.y >= 178) && (p.y <= 190))
+ return CloseUnreal(hDlg);
+ }
+ case WM_COMMAND:
+ {
+ if (LOWORD(wParam) >= 60000 && HIWORD(wParam) == 0 && !lParam)
+ {
+ unsigned char path[MAX_PATH];
+ if (GetMenuString(hLogs, LOWORD(wParam), path, MAX_PATH, MF_BYCOMMAND))
+ DialogBoxParam(hInst, "FromVar", hDlg, (DLGPROC)FromFileReadDLG, (LPARAM)path);
+
+ else
+ {
+ GetMenuString(hConfig,LOWORD(wParam), path, MAX_PATH, MF_BYCOMMAND);
+#ifdef USE_LIBCURL
+ if (url_is_valid(path))
+ {
+ char *file = find_loaded_remote_include(path);
+ DialogBoxParam(hInst, "FromVar", hDlg, (DLGPROC)FromFileReadDLG, (LPARAM)file);
+ }
+ else
+#endif
+ DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG, (LPARAM)path);
+ }
+ return FALSE;
+ }
+
+ switch(LOWORD(wParam))
+ {
+ case IDM_STATUS:
+ ShowDialog(&hStatusWnd, hInst, "Status", hDlg,StatusDLG);
+ break;
+ case IDM_SHUTDOWN:
+ return CloseUnreal(hDlg);
+ case IDM_RHALL:
+ MessageBox(NULL, "Rehashing all files", "Rehashing", MB_OK);
+ sendto_realops("Rehashing all files via the console");
+ rehash(&me,&me,0);
+ reread_motdsandrules();
+ break;
+ case IDM_RHCONF:
+ MessageBox(NULL, "Rehashing the Config file", "Rehashing", MB_OK);
+ sendto_realops("Rehashing the Config file via the console");
+ rehash(&me,&me,0);
+ break;
+ case IDM_RHMOTD:
+ {
+ ConfigItem_tld *tlds;
+ aMotd *amotd;
+ MessageBox(NULL, "Rehashing all MOTD and Rules files", "Rehashing", MB_OK);
+ rehash_motdrules();
+ sendto_realops("Rehashing all MOTD and Rules files via the console");
+ break;
+ }
+ case IDM_RHOMOTD:
+ MessageBox(NULL, "Rehashing the OperMOTD", "Rehashing", MB_OK);
+ opermotd = (aMotd *) read_file(OPATH, &opermotd);
+ sendto_realops("Rehashing the OperMOTD via the console");
+ break;
+ case IDM_RHBMOTD:
+ MessageBox(NULL, "Rehashing the BotMOTD", "Rehashing", MB_OK);
+ botmotd = (aMotd *) read_file(BPATH, &botmotd);
+ sendto_realops("Rehashing the BotMOTD via the console");
+ break;
+ case IDM_LICENSE:
+ DialogBox(hInst, "FromVar", hDlg, (DLGPROC)LicenseDLG);
+ break;
+ case IDM_CREDITS:
+ DialogBox(hInst, "FromVar", hDlg, (DLGPROC)CreditsDLG);
+ break;
+ case IDM_DAL:
+ DialogBox(hInst, "FromVar", hDlg, (DLGPROC)DalDLG);
+ break;
+ case IDM_HELP:
+ DialogBox(hInst, "Help", hDlg, (DLGPROC)HelpDLG);
+ break;
+ case IDM_CONF:
+ DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
+ (LPARAM)CPATH);
+ break;
+ case IDM_MOTD:
+ 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);
+ break;
+ case IDM_BOTMOTD:
+ DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
+ (LPARAM)BPATH);
+ break;
+ case IDM_RULES:
+ DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
+ (LPARAM)RPATH);
+ break;
+ case IDM_NEW:
+ DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG, (LPARAM)NULL);
+ break;
+ }
+ }
+ }
+ return FALSE;
+}
+
+LRESULT CALLBACK LicenseDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ return FromVarDLG(hDlg, message, wParam, lParam, "UnrealIRCd License", gnulicense);
+}
+
+LRESULT CALLBACK CreditsDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ return FromVarDLG(hDlg, message, wParam, lParam, "UnrealIRCd Credits", unrealcredits);
+}
+
+LRESULT CALLBACK DalDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ return FromVarDLG(hDlg, message, wParam, lParam, "UnrealIRCd DALnet Credits", dalinfotext);
+}
+
+LRESULT CALLBACK FromVarDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam,
+ unsigned char *title, unsigned char **s)
+{
+ HWND hWnd;
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ {
+ unsigned char String[16384];
+ int size;
+ unsigned char *RTFString;
+ StreamIO *stream = malloc(sizeof(StreamIO));
+ EDITSTREAM edit;
+ SetWindowText(hDlg, title);
+ bzero(String, 16384);
+ lpfnOldWndProc = (FARPROC)SetWindowLong(GetDlgItem(hDlg, IDC_TEXT), GWL_WNDPROC, (DWORD)RESubClassFunc);
+ while (*s)
+ {
+ strcat(String, *s++);
+ if (*s)
+ strcat(String, "\r\n");
+ }
+ size = CountRTFSize(String)+1;
+ RTFString = malloc(size);
+ bzero(RTFString, size);
+ IRCToRTF(String,RTFString);
+ RTFBuf = RTFString;
+ size--;
+ stream->size = &size;
+ stream->buffer = &RTFBuf;
+ edit.dwCookie = (UINT)stream;
+ edit.pfnCallback = SplitIt;
+ SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_STREAMIN, (WPARAM)SF_RTF|SFF_PLAINRTF, (LPARAM)&edit);
+ free(RTFString);
+ free(stream);
+ return TRUE;
+ }
+
+ case WM_COMMAND:
+ {
+ hWnd = GetDlgItem(hDlg, IDC_TEXT);
+ if (LOWORD(wParam) == IDOK)
+ return EndDialog(hDlg, TRUE);
+ if (LOWORD(wParam) == IDM_COPY)
+ {
+ SendMessage(hWnd, WM_COPY, 0, 0);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_SELECTALL)
+ {
+ SendMessage(hWnd, EM_SETSEL, 0, -1);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_PASTE)
+ {
+ SendMessage(hWnd, WM_PASTE, 0, 0);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_CUT)
+ {
+ SendMessage(hWnd, WM_CUT, 0, 0);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_UNDO)
+ {
+ SendMessage(hWnd, EM_UNDO, 0, 0);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_DELETE)
+ {
+ SendMessage(hWnd, WM_CLEAR, 0, 0);
+ return 0;
+ }
+ break;
+ }
+ case WM_CLOSE:
+ EndDialog(hDlg, TRUE);
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return (FALSE);
+}
+
+LRESULT CALLBACK FromFileReadDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ HWND hWnd;
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ {
+ int fd,len;
+ unsigned char *buffer = '\0', *string = '\0';
+ EDITSTREAM edit;
+ StreamIO *stream = malloc(sizeof(StreamIO));
+ unsigned char szText[256];
+ struct stat sb;
+ HWND hWnd = GetDlgItem(hDlg, IDC_TEXT), hTip;
+ wsprintf(szText, "UnrealIRCd Viewer - %s", (unsigned char *)lParam);
+ SetWindowText(hDlg, szText);
+ lpfnOldWndProc = (FARPROC)SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)RESubClassFunc);
+ if ((fd = open((unsigned char *)lParam, _O_RDONLY|_O_BINARY)) != -1)
+ {
+ fstat(fd,&sb);
+ /* Only allocate the amount we need */
+ buffer = malloc(sb.st_size+1);
+ buffer[0] = 0;
+ len = read(fd, buffer, sb.st_size);
+ buffer[len] = 0;
+ len = CountRTFSize(buffer)+1;
+ string = malloc(len);
+ bzero(string,len);
+ IRCToRTF(buffer,string);
+ RTFBuf = string;
+ len--;
+ stream->size = &len;
+ stream->buffer = &RTFBuf;
+ edit.dwCookie = (UINT)stream;
+ edit.pfnCallback = SplitIt;
+ SendMessage(hWnd, EM_EXLIMITTEXT, 0, (LPARAM)0x7FFFFFFF);
+ SendMessage(hWnd, EM_STREAMIN, (WPARAM)SF_RTF|SFF_PLAINRTF, (LPARAM)&edit);
+ close(fd);
+ RTFBuf = NULL;
+ free(buffer);
+ free(string);
+ free(stream);
+ }
+ return TRUE;
+ }
+ case WM_COMMAND:
+ {
+ hWnd = GetDlgItem(hDlg, IDC_TEXT);
+ if (LOWORD(wParam) == IDOK)
+ return EndDialog(hDlg, TRUE);
+ if (LOWORD(wParam) == IDM_COPY)
+ {
+ SendMessage(hWnd, WM_COPY, 0, 0);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_SELECTALL)
+ {
+ SendMessage(hWnd, EM_SETSEL, 0, -1);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_PASTE)
+ {
+ SendMessage(hWnd, WM_PASTE, 0, 0);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_CUT)
+ {
+ SendMessage(hWnd, WM_CUT, 0, 0);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_UNDO)
+ {
+ SendMessage(hWnd, EM_UNDO, 0, 0);
+ return 0;
+ }
+ if (LOWORD(wParam) == IDM_DELETE)
+ {
+ SendMessage(hWnd, WM_CLEAR, 0, 0);
+ return 0;
+ }
+ break;
+ }
+ case WM_CLOSE:
+ EndDialog(hDlg, TRUE);
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
+
+LRESULT CALLBACK HelpDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static HFONT hFont;
+ static HCURSOR hCursor;
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ hCursor = LoadCursor(hInst, MAKEINTRESOURCE(CUR_HAND));
+ hFont = CreateFont(8,0,0,0,0,0,1,0,ANSI_CHARSET,0,0,PROOF_QUALITY,0,"MS Sans Serif");
+ SendMessage(GetDlgItem(hDlg, IDC_EMAIL), WM_SETFONT, (WPARAM)hFont,TRUE);
+ SendMessage(GetDlgItem(hDlg, IDC_URL), WM_SETFONT, (WPARAM)hFont,TRUE);
+ lpfnOldWndProc = (FARPROC)SetWindowLong(GetDlgItem(hDlg, IDC_EMAIL), GWL_WNDPROC, (DWORD)LinkSubClassFunc);
+ SetWindowLong(GetDlgItem(hDlg, IDC_URL), GWL_WNDPROC, (DWORD)LinkSubClassFunc);
+ return TRUE;
+
+ case WM_DRAWITEM:
+ {
+ LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
+ unsigned char text[500];
+ COLORREF oldtext;
+ RECT focus;
+ GetWindowText(lpdis->hwndItem, text, 500);
+ if (wParam == IDC_URL || IDC_EMAIL)
+ {
+ FillRect(lpdis->hDC, &lpdis->rcItem, GetSysColorBrush(COLOR_3DFACE));
+ oldtext = SetTextColor(lpdis->hDC, RGB(0,0,255));
+ DrawText(lpdis->hDC, text, strlen(text), &lpdis->rcItem, DT_CENTER|DT_VCENTER);
+ SetTextColor(lpdis->hDC, oldtext);
+ if (lpdis->itemState & ODS_FOCUS)
+ {
+ CopyRect(&focus, &lpdis->rcItem);
+ focus.left += 2;
+ focus.right -= 2;
+ focus.top += 1;
+ focus.bottom -= 1;
+ DrawFocusRect(lpdis->hDC, &focus);
+ }
+ return TRUE;
+ }
+ }
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDOK)
+ EndDialog(hDlg, TRUE);
+ if (HIWORD(wParam) == BN_DBLCLK)
+ {
+ if (LOWORD(wParam) == IDC_URL)
+ ShellExecute(NULL, "open", "http://www.unrealircd.com", NULL, NULL,
+ SW_MAXIMIZE);
+ else if (LOWORD(wParam) == IDC_EMAIL)
+ ShellExecute(NULL, "open", "mailto:unreal-users@lists.sourceforge.net", NULL, NULL,
+ SW_MAXIMIZE);
+ EndDialog(hDlg, TRUE);
+ return 0;
+ }
+ break;
+ case WM_CLOSE:
+ EndDialog(hDlg, TRUE);
+ break;
+ case WM_DESTROY:
+ DeleteObject(hFont);
+ break;
+
+ }
+ return FALSE;
+}
+
+
+
+
+
+
+
+
+LRESULT CALLBACK StatusDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ {
+ hwTreeView = GetDlgItem(hDlg, IDC_TREE);
+ win_map(&me, hwTreeView, 0);
+ SetDlgItemInt(hDlg, IDC_CLIENTS, IRCstats.clients, FALSE);
+ SetDlgItemInt(hDlg, IDC_SERVERS, IRCstats.servers, FALSE);
+ SetDlgItemInt(hDlg, IDC_INVISO, IRCstats.invisible, FALSE);
+ SetDlgItemInt(hDlg, IDC_UNKNOWN, IRCstats.unknown, FALSE);
+ SetDlgItemInt(hDlg, IDC_OPERS, IRCstats.operators, FALSE);
+ SetDlgItemInt(hDlg, IDC_CHANNELS, IRCstats.channels, FALSE);
+ if (IRCstats.clients > IRCstats.global_max)
+ IRCstats.global_max = IRCstats.clients;
+ if (IRCstats.me_clients > IRCstats.me_max)
+ IRCstats.me_max = IRCstats.me_clients;
+ SetDlgItemInt(hDlg, IDC_MAXCLIENTS, IRCstats.global_max, FALSE);
+ SetDlgItemInt(hDlg, IDC_LCLIENTS, IRCstats.me_clients, FALSE);
+ SetDlgItemInt(hDlg, IDC_LSERVERS, IRCstats.me_servers, FALSE);
+ SetDlgItemInt(hDlg, IDC_LMAXCLIENTS, IRCstats.me_max, FALSE);
+ SetTimer(hDlg, 1, 5000, NULL);
+ return TRUE;
+ }
+ case WM_CLOSE:
+ DestroyWindow(hDlg);
+ return TRUE;
+ case WM_TIMER:
+ TreeView_DeleteAllItems(hwTreeView);
+ win_map(&me, hwTreeView, 1);
+ SetDlgItemInt(hDlg, IDC_CLIENTS, IRCstats.clients, FALSE);
+ SetDlgItemInt(hDlg, IDC_SERVERS, IRCstats.servers, FALSE);
+ SetDlgItemInt(hDlg, IDC_INVISO, IRCstats.invisible, FALSE);
+ SetDlgItemInt(hDlg, IDC_INVISO, IRCstats.invisible, FALSE);
+ SetDlgItemInt(hDlg, IDC_UNKNOWN, IRCstats.unknown, FALSE);
+ SetDlgItemInt(hDlg, IDC_OPERS, IRCstats.operators, FALSE);
+ SetDlgItemInt(hDlg, IDC_CHANNELS, IRCstats.channels, FALSE);
+ if (IRCstats.clients > IRCstats.global_max)
+ IRCstats.global_max = IRCstats.clients;
+ if (IRCstats.me_clients > IRCstats.me_max)
+ IRCstats.me_max = IRCstats.me_clients;
+ SetDlgItemInt(hDlg, IDC_MAXCLIENTS, IRCstats.global_max, FALSE);
+ SetDlgItemInt(hDlg, IDC_LCLIENTS, IRCstats.me_clients, FALSE);
+ SetDlgItemInt(hDlg, IDC_LSERVERS, IRCstats.me_servers, FALSE);
+ SetDlgItemInt(hDlg, IDC_LMAXCLIENTS, IRCstats.me_max, FALSE);
+ SetTimer(hDlg, 1, 5000, NULL);
+ return TRUE;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDOK)
+ {
+ DestroyWindow(hDlg);
+ return TRUE;
+ }
+ break;
+
+ }
+ return FALSE;
+}
+
+/* This was made by DrBin but I cleaned it up a bunch to make it work better */
+
+HTREEITEM AddItemToTree(HWND hWnd, LPSTR lpszItem, int nLevel, short remap)
+{
+ TVITEM tvi;
+ TVINSERTSTRUCT tvins;
+ static HTREEITEM hPrev = (HTREEITEM)TVI_FIRST;
+ static HTREEITEM hPrevLev[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+ HTREEITEM hti;
+
+ if (remap)
+ {
+ hPrev = (HTREEITEM)TVI_FIRST;
+ memset(hPrevLev, 0, sizeof(HTREEITEM)*10);
+ }
+
+ tvi.mask = TVIF_TEXT|TVIF_PARAM;
+ tvi.pszText = lpszItem;
+ tvi.cchTextMax = lstrlen(lpszItem);
+ tvi.lParam = (LPARAM)nLevel;
+ tvins.item = tvi;
+ tvins.hInsertAfter = hPrev;
+ if (nLevel == 1)
+ tvins.hParent = TVI_ROOT;
+ else
+ tvins.hParent = hPrevLev[nLevel-1];
+ hPrev = (HTREEITEM)SendMessage(hWnd, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT) &tvins);
+ hPrevLev[nLevel] = hPrev;
+ TreeView_EnsureVisible(hWnd,hPrev);
+ if (nLevel > 1)
+ {
+ hti = TreeView_GetParent(hWnd, hPrev);
+ tvi.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE;
+ tvi.hItem = hti;
+ TreeView_SetItem(hWnd, &tvi);
+ }
+ return hPrev;
+}
+
+/*
+ * Now used to create list of servers for server list tree view -- David Flynn
+ * Recoded by codemastr to be faster.
+ * I removed the Potvin credit because it no longer uses any original code and I don't
+ * even think Potvin actually made the original code
+ */
+void win_map(aClient *server, HWND hwTreeView, short remap)
+{
+ aClient *acptr;
+ Link *lp;
+
+ AddItemToTree(hwTreeView,server->name,server->hopcount+1, remap);
+
+ for (lp = Servers; lp; lp = lp->next)
+ {
+ acptr = lp->value.cptr;
+ if (acptr->srvptr != server)
+ continue;
+ win_map(acptr, hwTreeView, 0);
+ }
+}
+
+/* ugly stuff, but hey it works -- codemastr */
+void win_log(unsigned char *format, ...)
+{
+ va_list ap;
+ unsigned char buf[2048];
+ unsigned char *buf2;
+ va_start(ap, format);
+ ircvsprintf(buf, format, ap);
+ if (!IsService)
+ {
+ strcat(buf, "\r\n");
+ if (errors)
+ {
+ buf2 = MyMalloc(strlen(errors)+strlen(buf)+1);
+ sprintf(buf2, "%s%s",errors,buf);
+ MyFree(errors);
+ errors = NULL;
+ }
+ else
+ {
+ buf2 = MyMalloc(strlen(buf)+1);
+ sprintf(buf2, "%s",buf);
+ }
+ errors = buf2;
+ }
+ else
+ {
+ FILE *fd = fopen("service.log", "a");
+ fprintf(fd, "%s\n", buf);
+ fclose(fd);
+ }
+ va_end(ap);
+}
+
+void win_error()
+{
+ if (errors && !IsService)
+ DialogBox(hInst, "ConfigError", hwIRCDWnd, (DLGPROC)ConfigErrorDLG);
+}
+
+LRESULT CALLBACK ConfigErrorDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ MessageBeep(MB_ICONEXCLAMATION);
+ SetDlgItemText(hDlg, IDC_CONFIGERROR, errors);
+ MyFree(errors);
+ errors = NULL;
+ return (TRUE);
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDOK)
+ EndDialog(hDlg, TRUE);
+ break;
+ case WM_CLOSE:
+ EndDialog(hDlg, TRUE);
+ break;
+ case WM_DESTROY:
+ break;
+
+ }
+ return (FALSE);
+}
diff --git a/src/win32/rtf.c b/src/win32/rtf.c
new file mode 100644
index 000000000..230f0f34f
--- /dev/null
+++ b/src/win32/rtf.c
@@ -0,0 +1,883 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, win32/rtf.c
+ * Copyright (C) 2004 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
+ * 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
+#include "win32.h"
+#include "sys.h"
+#include "common.h"
+#include "struct.h"
+#include "h.h"
+
+unsigned char *RTFBuf;
+
+#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;}"
+
+/* Splits the file up for the EM_STREAMIN message
+ * Parameters:
+ * dwCookie - The file information to split
+ * pbBuff - The output buffer
+ * cb - The size of pbBuff
+ * pcb - The total bytes written to bpBuff
+ * Returns:
+ * Returns 0 to indicate success
+ */
+DWORD CALLBACK SplitIt(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
+{
+ StreamIO *stream = (StreamIO*)dwCookie;
+ if (*stream->size == 0)
+ {
+ pcb = 0;
+ *stream->buffer = 0;
+ }
+ else if (cb <= *stream->size)
+ {
+ memcpy(pbBuff, *stream->buffer, cb);
+ *stream->buffer += cb;
+ *stream->size -= cb;
+ *pcb = cb;
+
+ }
+ else
+ {
+ memcpy(pbBuff, *stream->buffer, *stream->size);
+ *pcb = *stream->size;
+ *stream->size = 0;
+ }
+ return 0;
+}
+
+/* Reassembles the RTF buffer from EM_STREAMOUT
+ * Parameters:
+ * dwCookie - Unused
+ * pbBuff - The input buffer
+ * cb - The length of the input buffer
+ * pcb - The total bytes read from pbBuff
+ * Returns:
+ * 0 to indicate success
+ * Side Effects:
+ * RTFBuf contains the assembled RTF buffer
+ */
+DWORD CALLBACK BufferIt(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
+{
+ unsigned char *buf2;
+ static long size = 0;
+ if (!RTFBuf)
+ size = 0;
+
+ buf2 = MyMalloc(size+cb+1);
+
+ if (RTFBuf)
+ memcpy(buf2,RTFBuf,size);
+
+ memcpy(buf2+size,pbBuff,cb);
+
+ size += cb;
+ if (RTFBuf)
+ MyFree(RTFBuf);
+
+ RTFBuf = buf2;
+
+ pcb = &cb;
+ return 0;
+}
+
+/* Pushes a color onto the stack
+ * Parameters:
+ * color - The color to add to the stack
+ * stack - The stack to add the color to
+ */
+void ColorPush(unsigned char *color, IRCColor **stack)
+{
+ IRCColor *t = MyMallocEx(sizeof(IRCColor));
+ t->color = strdup(color);
+ t->next = *stack;
+ (*stack) = t;
+}
+
+/* Pops a color off of the stack
+ * Parameters:
+ * stack - The stack to pop from
+ */
+void ColorPop(IRCColor **stack)
+{
+ IRCColor *p = *stack;
+ if (!(*stack))
+ return;
+ MyFree(p->color);
+
+ *stack = p->next;
+ MyFree(p);
+}
+
+/* Completely empties the color stack
+ * Parameters:
+ * stack - The stack to empty
+ */
+void ColorEmpty(IRCColor **stack)
+{
+ IRCColor *t, *next;
+ for (t = *stack; t; t = next)
+ {
+ next = t->next;
+ MyFree(t->color);
+ MyFree(t);
+ }
+}
+
+#define iseol(x) ((x) == '\r' || (x) == '\n')
+
+/* Converts a string in RTF format to IRC codes
+ * Parameters:
+ * fd - The file descriptor to write to
+ * pbBuff - The buffer containing the RTF text
+ * cb - The length of the RTF text
+ */
+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;
+
+ IRCColor *TextColors = NULL;
+ IRCColor *BgColors = NULL;
+
+ bzero(buffer, cb);
+
+ for (; *pbBuff; pbBuff++)
+ {
+ if (iseol(*pbBuff) || *pbBuff == '{' || *pbBuff == '}')
+ continue;
+ else if (*pbBuff == '\\')
+ {
+ /* RTF control sequence */
+ 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[2] = 0;
+ ltr = strtoul(ultr,NULL,16);
+ buffer[i++] = ltr;
+ }
+ 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++;
+ 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;
+ }
+ else
+ color[k++] = *pbBuff;
+ }
+ lastwascf = lastwascf0 = 0;
+ }
+ 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)
+ {
+ 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, "b"))
+ {
+ bold = 1;
+ buffer[i++] = '\2';
+ lastwascf = lastwascf0 = 0;
+ }
+ else if (!strcmp(cmd, "b0"))
+ {
+ bold = 0;
+ buffer[i++] = '\2';
+ lastwascf = lastwascf0 = 0;
+ }
+ else if (!strcmp(cmd, "ul"))
+ {
+ uline = 1;
+ buffer[i++] = '\37';
+ lastwascf = lastwascf0 = 0;
+ }
+ else if (!strcmp(cmd, "ulnone"))
+ {
+ uline = 0;
+ buffer[i++] = '\37';
+ lastwascf = lastwascf0 = 0;
+ }
+ else if (!strcmp(cmd, "cf0"))
+ {
+ lastwascf0 = 1;
+ lastwascf = 0;
+ }
+ else if (!strcmp(cmd, "highlight0"))
+ {
+ inbg = 0;
+ ColorPop(&BgColors);
+ buffer[i++] = '\3';
+ 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))
+ {
+ unsigned char number[3];
+ int num;
+ incolor = 1;
+ strcpy(number, &cmd[2]);
+ num = atoi(number);
+ buffer[i++] = '\3';
+ 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;
+ }
+ else
+ lastwascf = lastwascf0 = 0;
+
+ if (lastwascf0 && incolor)
+ {
+ incolor = 0;
+ ColorPop(&TextColors);
+ buffer[i++] = '\3';
+ }
+ }
+ }
+ else
+ {
+ lastwascf = lastwascf0 = 0;
+ buffer[i++] = *pbBuff;
+ }
+
+ }
+ write(fd, buffer, i);
+ close(fd);
+ ColorEmpty(&TextColors);
+ ColorEmpty(&BgColors);
+ return 0;
+}
+
+/* Determines the size of the buffer needed to convert IRC codes to RTF
+ * Parameters:
+ * buffer - The input buffer with IRC codes
+ * Returns:
+ * The lenght of the buffer needed to store the RTF translation
+ */
+int CountRTFSize(unsigned char *buffer) {
+ int size = 0;
+ char bold = 0, uline = 0, incolor = 0, inbg = 0, reverse = 0;
+ char *buf = buffer;
+
+ for (; *buf; buf++)
+ {
+ if (*buf == '{' || *buf == '}' || *buf == '\\')
+ size++;
+ 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;
+ }
+ }
+ else if (*buf == '\n')
+ {
+ 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;
+ }
+ else if (*buf == '\2')
+ {
+ if (bold)
+ size += 4;
+ else
+ size += 3;
+ bold = !bold;
+ continue;
+ }
+ 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 (*(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 (*(buf+1) && isdigit(*(buf+1)))
+ color[1] = *(++buf);
+ color[2] = 0;
+ number = atoi(color);
+ if (number == 99 || number == 1)
+ size += 2;
+ 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;
+ }
+ 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 += 17;
+ reverse = !reverse;
+ continue;
+ }
+ else if (*buf == '\37')
+ {
+ if (uline)
+ size += 8;
+ else
+ size += 4;
+ uline = !uline;
+ continue;
+ }
+ 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);
+}
+
+/* Converts a string containing IRC codes to RTF
+ * Parameters:
+ * buffer - The input buffer containing IRC codes
+ * string - The output buffer in RTF
+ */
+void IRCToRTF(unsigned char *buffer, unsigned char *string)
+{
+ unsigned char *tmp;
+ int i = 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 = strlen(string);
+ for (tmp = buffer; *tmp; tmp++)
+ {
+ if (*tmp == '{')
+ {
+ strcat(string, "\\{");
+ i+=2;
+ continue;
+ }
+ else if (*tmp == '}')
+ {
+ strcat(string, "\\}");
+ i+=2;
+ continue;
+ }
+ else if (*tmp == '\\')
+ {
+ strcat(string, "\\\\");
+ i+=2;
+ continue;
+ }
+ 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 +=6;
+ }
+ else
+ string[i++]='\r';
+ continue;
+ }
+ else if (*tmp == '\n')
+ {
+ 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 +=6;
+ continue;
+ }
+ else if (*tmp == '\2')
+ {
+ if (bold)
+ {
+ strcat(string, "\\b0 ");
+ i+=4;
+ }
+ else
+ {
+ strcat(string, "\\b ");
+ 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;
+ }
+ }
+ }
+ continue;
+ }
+ else if (*tmp == '\3' && !reverse)
+ {
+ strcat(string, "\\cf");
+ i += 3;
+ if (*(tmp+1) && !isdigit(*(tmp+1)))
+ {
+ incolor = 0;
+ string[i++] = '0';
+ if (inbg)
+ {
+ inbg = 0;
+ strcat(string, "\\highlight0");
+ i += 11;
+ }
+ }
+ else if (*(tmp+1))
+ {
+ unsigned char color[3];
+ int number;
+ color[0] = *(++tmp);
+ color[1] = 0;
+ if (*(tmp+1) && isdigit(*(tmp+1)))
+ color[1] = *(++tmp);
+ color[2] = 0;
+ number = atoi(color);
+ if (number == 99 || number == 1)
+ {
+ strcat(string, "16");
+ i += 2;
+ }
+ else if (number == 0)
+ {
+ strcat(string, "1");
+ i++;
+ }
+ 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++] = ' ';
+ continue;
+ }
+ else if (*tmp == '\17') {
+ if (uline) {
+ strcat(string, "\\ulnone");
+ i += 7;
+ }
+ if (bold) {
+ strcat(string, "\\b0");
+ i += 3;
+ }
+ 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;
+ }
+
+ else if (*tmp == '\37') {
+ if (uline) {
+ strcat(string, "\\ulnone ");
+ i += 8;
+ }
+ else {
+ strcat(string, "\\ul ");
+ i += 4;
+ }
+ uline = !uline;
+ continue;
+ }
+ string[i++] = *tmp;
+ }
+ strcat(string, "}");
+ return;
+}
diff --git a/src/win32/service.c b/src/win32/service.c
index 9e50220ff..3ac88858f 100644
--- a/src/win32/service.c
+++ b/src/win32/service.c
@@ -1,6 +1,6 @@
/************************************************************************
* IRC - Internet Relay Chat, win32/service.c
- * Copyright (C) 2002 Dominick Meglio (codemastr)
+ * Copyright (C) 2002-2004 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
@@ -27,22 +27,48 @@
#include
SERVICE_STATUS IRCDStatus;
-SERVICE_STATUS_HANDLE IRCDStatusHandle;
+SERVICE_STATUS_HANDLE IRCDStatusHandle;
+
+/* Signal to rehash */
#define IRCD_SERVICE_CONTROL_REHASH 128
BOOL IsService = FALSE;
extern OSVERSIONINFO VerInfo;
#define WIN32_VERSION BASE_VERSION PATCH1 PATCH2 PATCH3 PATCH4
-
-VOID WINAPI IRCDCtrlHandler(DWORD opcode) {
+
+/* Places the service in the STOPPED state
+ * Parameters:
+ * code - The error code (or 0)
+ */
+void SetServiceStop(int code)
+{
+ IRCDStatus.dwCurrentState = SERVICE_STOPPED;
+ IRCDStatus.dwCheckPoint = 0;
+ IRCDStatus.dwWaitHint = 0;
+ IRCDStatus.dwWin32ExitCode = code;
+ IRCDStatus.dwServiceSpecificExitCode = code;
+ SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
+}
+
+/* Handles the service messages
+ * Parameters:
+ * opcode - The message to process
+ */
+VOID WINAPI IRCDCtrlHandler(DWORD opcode)
+{
DWORD status;
int i;
aClient *acptr;
- if (opcode == SERVICE_CONTROL_STOP) {
+
+ /* Stopping */
+ if (opcode == SERVICE_CONTROL_STOP)
+ {
IRCDStatus.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
- for (i = 0; i <= LastSlot; i++) {
+
+ for (i = 0; i <= LastSlot; i++)
+ {
if (!(acptr = local[i]))
continue;
if (IsClient(acptr))
@@ -56,91 +82,66 @@ VOID WINAPI IRCDCtrlHandler(DWORD opcode) {
for (i = LastSlot; i >= 0; i--)
if ((acptr = local[i]) && DBufLength(&acptr->sendQ) > 0)
(void)send_queued(acptr);
- IRCDStatus.dwWin32ExitCode = 0;
- IRCDStatus.dwCurrentState = SERVICE_STOPPED;
- IRCDStatus.dwCheckPoint = 0;
- IRCDStatus.dwWaitHint = 0;
- SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
+ SetServiceStop(0);
}
- else if (opcode == IRCD_SERVICE_CONTROL_REHASH) {
+ /* Rehash */
+ else if (opcode == IRCD_SERVICE_CONTROL_REHASH)
rehash(&me,&me,0);
- }
- SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
+ SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
}
-VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
+/* Entry point function
+ * Parameters:
+ * dwArgc - Argument count
+ * lpszArgv - Arguments
+ */
+VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
+{
WSADATA WSAData;
DWORD error = 0;
char path[MAX_PATH], *folder;
+
IsService = TRUE;
+
+ /* Initialize the service structure */
IRCDStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
IRCDStatus.dwCurrentState = SERVICE_START_PENDING;
IRCDStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN;
IRCDStatus.dwWin32ExitCode = NO_ERROR;
IRCDStatus.dwServiceSpecificExitCode = 0;
IRCDStatus.dwCheckPoint = 0;
- IRCDStatus.dwWaitHint = 0;
+ IRCDStatus.dwWaitHint = 0;
+
GetModuleFileName(NULL,path,MAX_PATH);
folder = strrchr(path, '\\');
*folder = 0;
chdir(path);
- IRCDStatusHandle = RegisterServiceCtrlHandler("unreal", IRCDCtrlHandler);
+
+ /* Register the service controller */
+ IRCDStatusHandle = RegisterServiceCtrlHandler("UnrealIRCd", IRCDCtrlHandler);
+
VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&VerInfo);
- strcpy(OSName, "Windows ");
- if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
- if (VerInfo.dwMajorVersion == 4) {
- if (VerInfo.dwMinorVersion == 0) {
- strcat(OSName, "95 ");
- if (!strcmp(VerInfo.szCSDVersion," C"))
- strcat(OSName, "OSR2 ");
- }
- else if (VerInfo.dwMinorVersion == 10) {
- strcat(OSName, "98 ");
- if (!strcmp(VerInfo.szCSDVersion, " A"))
- strcat(OSName, "SE ");
- }
- else if (VerInfo.dwMinorVersion == 90)
- strcat(OSName, "Me ");
- }
- }
- else if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- if (VerInfo.dwMajorVersion == 3 && VerInfo.dwMinorVersion == 51)
- strcat(OSName, "NT 3.51 ");
- else if (VerInfo.dwMajorVersion == 4 && VerInfo.dwMinorVersion == 0)
- strcat(OSName, "NT 4.0 ");
- else if (VerInfo.dwMajorVersion == 5) {
- if (VerInfo.dwMinorVersion == 0)
- strcat(OSName, "2000 ");
- else if (VerInfo.dwMinorVersion == 1)
- strcat(OSName, "XP ");
- else if (VerInfo.dwMinorVersion == 2)
- strcat(OSName, "Server 2003 ");
- }
- strcat(OSName, VerInfo.szCSDVersion);
- }
- if (OSName[strlen(OSName)-1] == ' ')
- OSName[strlen(OSName)-1] = 0;
+ GetOSName(VerInfo, OSName);
+
InitDebug();
- if ((error = WSAStartup(MAKEWORD(1, 1), &WSAData)) != 0) {
- IRCDStatus.dwCurrentState = SERVICE_STOPPED;
- IRCDStatus.dwCheckPoint = 0;
- IRCDStatus.dwWaitHint = 0;
- IRCDStatus.dwWin32ExitCode = error;
- IRCDStatus.dwServiceSpecificExitCode = error;
- SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
+
+ /* Initialize Winsocks */
+ if ((error = WSAStartup(MAKEWORD(1, 1), &WSAData)) != 0)
+ {
+ SetServiceStop(error);
return;
}
- if ((error = InitwIRCD(dwArgc, lpszArgv)) != 1) {
- IRCDStatus.dwCurrentState = SERVICE_STOPPED;
- IRCDStatus.dwCheckPoint = 0;
- IRCDStatus.dwWaitHint = 0;
- IRCDStatus.dwWin32ExitCode = error;
- IRCDStatus.dwServiceSpecificExitCode = error;
- SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
+
+ /* Initialize the IRCd */
+ if ((error = InitwIRCD(dwArgc, lpszArgv)) != 1)
+ {
+ SetServiceStop(error);
return;
- }
+ }
+
+ /* Go into the running state */
IRCDStatus.dwCurrentState = SERVICE_RUNNING;
IRCDStatus.dwCheckPoint = 0;
IRCDStatus.dwWaitHint = 0;
diff --git a/src/win32/tre.dll b/src/win32/tre.dll
index 5843a53da..58e21da79 100644
Binary files a/src/win32/tre.dll and b/src/win32/tre.dll differ
diff --git a/src/win32/tre.lib b/src/win32/tre.lib
index 0831f5690..7ef5a8eae 100644
Binary files a/src/win32/tre.lib and b/src/win32/tre.lib differ
diff --git a/src/win32/unreal.c b/src/win32/unreal.c
index a75db6dd0..0e5aee14b 100644
--- a/src/win32/unreal.c
+++ b/src/win32/unreal.c
@@ -21,8 +21,10 @@
#include
#include
static OSVERSIONINFO VerInfo;
+typedef BOOL (*UCHANGESERVICECONFIG2)(SC_HANDLE, DWORD, LPVOID);
HMODULE hAdvapi;
-BOOL (*uChangeServiceConfig2)();
+UCHANGESERVICECONFIG2 uChangeServiceConfig2;
+
#define IRCD_SERVICE_CONTROL_REHASH 128
void show_usage() {
fprintf(stderr, "unreal start|stop|rehash|restart|install|uninstall|config