1
0
mirror of https://github.com/osmarks/ngircd.git synced 2025-09-19 18:54:04 +00:00

Compare commits

...

346 Commits

Author SHA1 Message Date
Alexander Barton
4b83a23d9d ngIRCd release 13 2008-12-25 23:18:29 +01:00
Florian Westphal
8a94ec9728 don't print pid_t type with %ld format specifier
Reported by Christoph Biedl:
ngircd[21581]: Running as user irc(39), group irc(39), with PID 140733193409613.

cast pid_t to long to avoid this.
While we are there, cast uid_t and gid_t, too.
2008-12-17 22:55:20 +01:00
Alexander Barton
e5fea5380d Update the date ("Dec 2008") of the manual pages. 2008-12-06 00:20:59 +01:00
Alexander Barton
9a82ca0d6b doc/Platforms.txt: added x86_64/unknown/linux-gnu 2008-12-05 22:35:23 +01:00
Alexander Barton
e573f54b0c doc/Platforms.txt: update list of tested platforms. 2008-12-05 18:11:50 +01:00
Alexander Barton
e070d93f64 doc/SSL.txt: enhance documentation. 2008-12-04 13:20:38 +01:00
Alexander Barton
1519afa391 doc/Services.txt: explain which IRC Services versions are compatible 2008-12-04 11:14:26 +01:00
Alexander Barton
85ce82e504 Testsuite start-server.sh: return correct exit code.
src/testsuite/start-server.sh returns 0 when no errors occurred and the
daemon has been startet and 1 on errors. Always returning 0 is wrong ...
2008-12-03 16:49:55 +01:00
Alexander Barton
83c699d5a5 Make testsuite (getpid.sh) work on OpenSolaris (i386/pc/solaris2.11). 2008-12-03 16:49:17 +01:00
Alexander Barton
56cf95278e doc/Services.txt: document using ngIRCd with IRC Services. 2008-12-02 15:41:57 +01:00
Alexander Barton
d0b2526a01 sample-ngircd.conf: remove now unused CVS "$Id$" 2008-11-22 14:47:01 +01:00
Alexander Barton
7cf9d93aee ngIRCd release 13~rc1 2008-11-21 22:08:23 +01:00
Alexander Barton
ffc5f93ef5 Fix double minus signs in manual pages
This patch fixes the following lintian(1) warning: "Manual page seems
to contain a hyphen where a minus sign was intended. '-' chars are
interpreted as hyphens (U+2010) by groff, not as minus signs (U+002D).
Since options to programs use minus signs (U+002D), this means for
example in UTF-8 locales that you cannot cut&paste options, nor search
for them easily. '-' must be escaped ('\-') to be interpreted as minus."
2008-11-21 21:37:03 +01:00
Alexander Barton
97d97ef5c4 Debian package ("make deb"): fix some lintian(1) warnings 2008-11-21 21:36:59 +01:00
Alexander Barton
2eb564ccaa Change formatting of some log messages
- Fix formatting of some log messages, mostly punctuation.
- cb_Connect_to_Server(): don't use string concatenation, because it
  is not supported by pre-ANSI C compilers ...
2008-11-20 23:50:26 +01:00
Alexander Barton
14baf64f41 Fix pem_passwd_cb(): unused variable "rwflag" (OpenSSL)
This patch fixes the following warning of GCC (version 4.3.2) in
function pem_passwd_cb() when compiling with OpenSSL support and
without debug code:

conn-ssl.c: In function 'pem_passwd_cb':
conn-ssl.c:122: warning: unused parameter 'rwflag'
2008-11-20 23:46:20 +01:00
Alexander Barton
4c113d8850 New configuration option "NoIdent" to disable IDENT lookups
The new configuration option "NoIdent" in ngircd.conf can be used to
disable IDENT lookups even when the ngIRCd daemon is compiled with IDENT
lookups enabled.
2008-11-19 19:11:39 +01:00
Alexander Barton
3243d9ee44 Implement the IRC command "SERVLIST"
The IRC command "SERVLIST" lists all the registered services, see RFC 2811, section 3.5.1.
The syntax is "SERVLIST [<mask> [<type>]]". The parameter <type> is not used by ngIRCd at
the moment, all registered services are of type 0 (which is the default when omitted).
2008-11-19 18:16:26 +01:00
Alexander Barton
672b391523 Updated NEWS and ChangeLog, using NEWS for news only :-) 2008-11-19 11:46:37 +01:00
Alexander Barton
0eda085f1e Create local &SERVER channel and log server messages to it
ngIRCd now creates a server-local channel &SERVER with channel modes
+mnPt (moderated, no messages from outside the channel, persistent and
with the topic locked) and logs all the messages to it that a user with
mode +s ("server messages") receives.

If an IRC operator withdraws the +P ("persistent") mode and the &SERVER
channel is freed because of no members, nothing special happens. The
channel can be recerated any time later and ngIRCd would begin logging
to it again.
2008-11-17 23:27:06 +01:00
Alexander Barton
2cc21caf32 Implement local channels (prefix "&")
This patch implements server-local channels, prefix "&", that are only
visible to users of the same local server and not in the network.

Patch written by Scott Perry (2008-06-04), see:
 - http://arthur.barton.de/cgi-bin/bugzilla/show_bug.cgi?id=87
 - http://arthur.barton.de/cgi-bin/bugzilla/attachment.cgi?id=24&action=view
2008-11-17 21:52:56 +01:00
Alexander Barton
7b69bc2ae8 Added some missing files of GIT tree to distribution archives
The following bits and bytes were not included in distribution archives:
 - contrib: ngindent, ngircd.sh
 - contrib/Debian: ngircd.postinst
 - contrib/MacOSX: preinstall.sh, postinstall.sh
 - doc/src: Doxyfile, header.inc.html, footer.inc.html, ngircd-doc.css
 - src/portab: splint.h
2008-11-13 23:17:32 +01:00
Alexander Barton
7ad167f4c4 Test suite: start two servers and test server-server links
I changed the test suite to start two test servers (on port 6789 and 6790),
so server-server links can be tested as well for which I included the new
test script "server-link-test.e".

In addition the documentation of the test suite (src/testsuite/README) has
been updated and is more complete now.
2008-11-13 22:46:06 +01:00
Alexander Barton
920d0636ff Add conf-ssl.h to "noinst_HEADERS"
conf-ssl.h must be listed in "noinst_HEADERS" so that it becomes included
in distribution archives generated by "make dist" and "make distcheck".
2008-11-13 00:22:25 +01:00
Alexander Barton
54e6a2dce5 Re-add CVE identifiers to ChangeLog.
I'm lame. My last commit removed all the CVE numbers recently added in
commit 598df0758 to the ChangeLog ... shame on me!

See all the CVE entries of ngIRCd at:
<http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=ngircd>
2008-11-13 00:01:07 +01:00
Alexander Barton
b01a9bd864 Updated NEWS and ChangeLog to include 0.12.1 and the development version 2008-11-12 22:34:51 +01:00
Alexander Barton
9f067a059d Connection counter: count outgoing connections as well.
This patch lets ngIRCd count outgoing connections as well as incoming
connections (up to now only outgoing connections have been counted). This
change is required because the Conn_Close() function doesn't know whether
it closes an outgoing connection or not and therefore would decrement the
counter below zero when an outgoing connection existed -- which would
trigger an assert() call ...

Please note that this patch changes the (so far undocumented but now fixed)
behaviour of the "MaxConnections" configuration option to account the sum
of the in- and outbound connections!
2008-11-12 01:26:04 +01:00
Alexander Barton
5a91d62100 Ignore numeric 020 ("please wait while we process your coinnection")
Some servers send the numeric 020 ("please wait while we process your
connection") when a client connects. This is no useful information for
this server, so we simply ignore it :-)
2008-11-11 23:11:49 +01:00
Alexander Barton
3a5b7b63ae GNUTLS: define new API types when installed library is too old
This patch enables ngIRCd to use GNUTLS in really old versions, tested
with version 1.0.16, that don't define the "new" data types ending in
xxx_t. LIBGNUTLS_VERSION_MAJOR isn't defined there as well, so we use
it to test if we must define the new types on our own.
2008-11-11 22:03:11 +01:00
Alexander Barton
9308541e6d Console log: output timestamp (seconds since start) for resolver, too 2008-11-11 22:01:27 +01:00
Alexander Barton
027cf22267 Console log: output timestamp (seconds since start of daemon) 2008-11-10 18:41:19 +01:00
Florian Westphal
125c05fba0 conn-ssl.c: work around gnutls API problems on 64 bit platforms
Alexander Barton reported a compiler warning on 64-bit platforms:
cc1: warnings being treated as errors
conn-ssl.c: In function 'ConnSSL_Init_SSL':
conn-ssl.c:403: error: cast to pointer from integer of
different size

Unfortunately, I couldn't find a real solution; the GNUTLS
API expects 'gnutls_transport_ptr_t' (which is void*),
but the default push/pull functions (send/recv) expect an int.

The only alternative solution is to pass in an address to the
file descriptor, then add send/recv wrappers that expect a pointer.

What a mess[tm].
2008-10-29 23:51:39 +01:00
Alexander Barton
fb19b05e1e GIT: don't ignore cvs-version.{h|new}, because it isn't used any more. 2008-10-29 22:33:03 +01:00
Alexander Barton
34b2f0085d Fix ForwardLookup(): "ISO C90 forbids specifying subobject to initialize"
This patch fixes the following warning of GCC (version 4.3.2) in
function ForwardLookup():

resolve.c: In function 'ForwardLookup':
resolve.c:282: warning: ISO C90 forbids specifying subobject to initialize
resolve.c:284: warning: ISO C90 forbids specifying subobject to initialize
resolve.c:285: warning: ISO C90 forbids specifying subobject to initialize
2008-10-19 20:07:35 +02:00
Alexander Barton
ce2541a826 Fix ConnSSL_LogCertInfo(): unused variable "cred" (GNUTLS)
This patch fixes the following warning of GCC (version 4.3.2) in
function ConnSSL_LogCertInfo() when compiling with GNUTLS support:

conn-ssl.c: In function 'ConnSSL_LogCertInfo':
conn-ssl.c:542: warning: unused variable 'cred'
2008-10-19 20:06:30 +02:00
Alexander Barton
d44a7dac26 Debian: build ngircd-full with support for GNU TLS and IPv6. 2008-10-03 16:45:09 +02:00
Alexander Barton
475ce1e93c Debian: make sure that /var/run/ircd is owned by user "irc". 2008-10-03 16:43:54 +02:00
Alexander Barton
0cba8f362a GIT: Ignore Debian-related generated files.
Added files that become generated while building Debian GNU/Linux
packages of ngIRCd to the .gitignore lists.
2008-10-03 15:50:35 +02:00
Alexander Barton
afd65bc728 Updated config.{guess|sub} to version 2008-01-16. 2008-10-03 15:35:43 +02:00
Alexander Barton
f92a614a35 Enable KICK to be handled from remote servers and from services. 2008-09-23 11:53:16 +02:00
Alexander Barton
ec0b405d9d Respect RFC 1459 compatibility mode when announcing channels (no NJOIN). 2008-09-23 11:53:16 +02:00
Alexander Barton
1d6dcb25c4 Document the server flag "S": SERVICE command is supported. 2008-09-23 11:53:16 +02:00
Alexander Barton
178f9cbdac Announce IRC services in the network.
This patch
 - introduces a new server flag "S" to indicate that the server can handle
   the SERVICE command (on server links),
 - implements the IRC command "SERVICE" for server-server links,
 - uses the "SERVICE" command to announce IRC services when a new
   server connects to it,
 - and fixes the Send_Message() function to let it send messages to
   services using a "target mask".

If the remote server doesn't indicate that it can handle the "SERVICE"
command (it has not set the "S" flag), services are announced as regular
users as before.
2008-09-23 11:53:16 +02:00
Alexander Barton
6356418ae5 Change Introduce_Client() to set the correct client type (user/service). 2008-09-23 11:53:16 +02:00
Alexander Barton
28e9888764 Convert SQUERY to PRIVMSG on RFC 1459 compliant links. 2008-09-23 11:53:16 +02:00
Alexander Barton
3afa0e0658 Don't allow SQUERY to send to "target masks" and channels; only services! 2008-09-23 11:53:16 +02:00
Alexander Barton
3913de3cff Fix PRIVMSG/NOTICE handler (II): keep command when forwarding to channels.
- new function ngt_UpperStr().
- change Channel_Write() to take command name and error flag.
- remove now unneeded function Channel_Notice().
2008-09-23 11:53:15 +02:00
Alexander Barton
91e87a3705 New function ngt_UpperStr() 2008-09-23 11:53:15 +02:00
Alexander Barton
71e9ac486f Fix PRIVMSG/NOTICE handler Send_Message(): don't forward NOTICE as PRIVMSG. 2008-09-23 11:53:15 +02:00
Alexander Barton
d93030ad27 Make real use of the CLIENT_SERVICE client type.
This patch enables ngIRCd to handle IRC services as real services, and not
as "fake users":

  - Set correct client type CLIENT_SERVICE for services,
  - Change log messages to include correct client type,
  - PRIVMSG: allow users to send messages to services,
  - Send services nick names to other servers (as users).

Please note that this patch doesn't announce services as services in the
network, but as regular users (as before). Only the local server knows
of services as services (see LUSERS command, for example). It is up to
one of the next patches to fix this and to introduce the SERVICE command
in server to server communication.

The propagation of services as regular users between servers doesn't limit
the functionality of the IRC services and will be the fallback for servers
that don't support "real" services propagation in the future.
2008-09-23 11:53:15 +02:00
Alexander Barton
4e125fb67c Allow IRC services to change their nick names. 2008-09-23 11:53:15 +02:00
Alexander Barton
33f32dbd67 New function Client_TypeText() and Destroy_UserOrService().
Client_TypeText() is used to get correct naming ("Client", "Service", ...)
for log messages, and Destroy_UserOrService() is used to correctly destroy
user and services clients.
2008-09-23 11:53:15 +02:00
Alexander Barton
74aac88dbf Send_Message(): really enforce target client type. 2008-09-23 11:53:14 +02:00
Alexander Barton
0337b1ac1e sample-ngircd.conf & ngircd.conf(5): document "ServiceMask" option. 2008-09-23 11:53:14 +02:00
Alexander Barton
02d7623074 Allow ngIRCd to detect services connected to an "virtual services server".
Introduce a new configuration variable "ServiceMask" in SERVER blocks to
define a mask matching nick names that should be treated as services.
Regular servers don't need this parameter (leave it empty, the default),
but you should set it to "*Serv" when connection ircservices, for example.

This patch allows ngIRCd to detect services, it doesn't change the
functionality: you only get different log messages ;-)
2008-09-23 11:51:16 +02:00
Alexander Barton
c5342fb467 Centralize logging functions in Introduce_Client(). 2008-09-23 11:47:17 +02:00
Alexander Barton
557be8c56b Get rid of INTRO_INFO structure again: we don't need it at all!
All the required information is already stored in the CLIENT structure
of new new connection, so pass this to Introduce_Client() and don't
invent an unneeded new structure ...
2008-09-23 11:47:17 +02:00
Alexander Barton
687784d276 Announce_User(): support RFC 1459 compatibility mode. 2008-09-23 11:47:17 +02:00
Alexander Barton
92603f7c80 Introduce_Client(): send MODES in RFC 1459 mode, too. 2008-09-23 11:47:17 +02:00
Alexander Barton
d070ec08ab numeric.c: whitespace fixes ... 2008-09-23 11:47:17 +02:00
Alexander Barton
a60465be3e Server links: detect RFC 1459 mode direct after SERVER command
This patch allows ngIRCd to detect right after receiving the SERVER command
from the peer whether the RFC 1459 compatibility mode must be used or not.
And it fixes the announcement of users during establishing new server links
with such peers.
2008-09-23 11:47:17 +02:00
Alexander Barton
14048c4717 Send and handle NICK+USER commands for user registration (RFC 1459).
This patch enables ngIRCd to deal with NICK and USER commands following
RFC 1459 to register new clients, and to send these commands instead of one
full NICK command as specified in RFC 2813 on connections that are in RFC
1459 compatibility mode.

Can be useful for e. g. IRC services that simulate a RFC 1459 server.
2008-09-23 11:47:17 +02:00
Alexander Barton
f199d63724 New function IRC_WriteStrServersPrefixFlag_CB() using a callback function. 2008-09-23 11:47:17 +02:00
Alexander Barton
4f759d8113 New function Introduce_Client() to announce new local and remote users. 2008-09-23 11:47:17 +02:00
Alexander Barton
6bc2d3d06e New connection option CONN_RFC1459.
This new connection option CONN_RFC1459 indicates that the peer on this
link only supports the IRC protocol as defined in RFC 1459 and that the
compatibility mode (e. g. for outgoing commands like NICK) should be used.
2008-09-23 11:47:17 +02:00
Alexander Barton
a5735f68d7 New global function Conn_SetOption(). 2008-09-23 11:47:16 +02:00
Alexander Barton
13f1d57e84 USER: servers and services can alter user information after registration.
This is required to do RFC 1459 style user registration on server links,
and is used by some services packages, too. See RFC 1459 section 4.1.3.
2008-09-23 11:47:16 +02:00
Alexander Barton
068d43352d NICK: allow servers and services to use RFC 1459 syntax (2 parameters).
This patch allows servers and services to call the NICK command using the
syntax defined in RFC 1459 to register new users, with only two parameters.
See section 4.1.2.

Useful for some services packages, which emulate this protocol.
2008-09-23 11:47:16 +02:00
Alexander Barton
e56bd8ff89 Whitespace fixes: remove trailing tabulator characters. 2008-09-23 11:47:16 +02:00
Florian Westphal
2fce881d96 conn-ssl.c: don't append a newline to ConnSSL_GetCipherInfo 2008-09-15 12:25:54 +02:00
Florian Westphal
ef3327d372 TLS/SSL support: code changes.
This adds the required code to enable ssl/tls support
during compile and run time, respectively.
2008-09-13 15:10:32 +02:00
Florian Westphal
ebf5edfd87 TLS/SSL support: documentation. 2008-09-13 15:10:08 +02:00
Florian Westphal
bdd44eb0ab TLS/SSL support: core files.
Contains support for both OpenSSL and GNU TLS.
Certificate Authentification is not yet supported.
2008-09-13 15:08:11 +02:00
Florian Westphal
c997e04325 Fix handling of MaxConnections option
Config option claimed to be 'number of connections' but in reality this
was treated as 'largest file descriptor allowed'.

This also fixes another bug in New_connection, where the
ng_ipaddr_tostr_r error path was missing a return statement.
2008-08-30 15:37:19 +02:00
Alexander Barton
2c2c93e311 Include "mcheck.h" when using mtrace(). 2008-08-18 23:27:56 +02:00
Alexander Barton
41a23d20e4 SECURITY: Fixed a message handling bug which could crash the daemon.
Some message targets could lead to a NULL pointer dereference and therefore
could crash the daemon (denial of service).
(cherry picked from commit e493ad2d30ff80bca2556cde2212e367cb006517)
2008-08-17 17:37:36 +02:00
Alexander Barton
c769cbecb6 Enable GNU libc "memory tracing" when compiled with debug code.
This patch lets ngIRCd activate "memory tracing" of the GNU libc when
compiled with debug code (configure: --enable-debug) and the functionality
is available on the system.
(http://www.gnu.org/software/libc/manual/html_node/Allocation-Debugging.html)
2008-08-13 16:00:57 +02:00
Alexander Barton
707cc42dec New make target: "osxpkg" to create an Mac OS X installer package.
This patch adds a new make target, "osxpkg", to the main Makefile which
gereates a Apple Mac OS X installer package of ngIRCd. The packagemaker(1)
project bundle is stored in contrib/MacOSX/ngIRCd.pmdoc.
2008-08-12 17:30:38 +02:00
Alexander Barton
30f1ed211d Clean up Mac OS X Xcode environment.
- Remove obsolete contrib/MacOSX/cvs-version.h
- Change SDK to 10.4
2008-08-11 17:39:26 +02:00
Alexander Barton
415ebc04a2 doc/Platforms.txt: added Debian GNU/Hurd, "i686/unknown/gnu0.3" 2008-08-10 18:08:09 +02:00
Alexander Barton
598df07584 Added CVE identifiers to ChangeLog.
see http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=ngircd
2008-08-10 14:26:51 +02:00
Alexander Barton
e4b4bb5e71 Remove de.barton.ngircd.plist on "make clean", its a generated file. 2008-08-06 19:47:53 +02:00
Alexander Barton
dfc3de131c Make ngIRCd compile and run on NeXTSTEP 3.3 and OPENSTEP 4.2
by Steven D. Blackford <kb7sqi@aol.com>:

"I wanted to let you know that I've done a quick port of ngircd-0.12.0 for
NEXTSTEP3.3/OPENSTEP4.2. There wasn't a lot of changes required to get it
to compile clean, but I did make the necessary changes so that I didn't
have to use -posix flag. The NeXT has a pretty buggy POSIX implementation
so I always try to work around it. :-)
Anway, here's the changes required to get it to compile."
2008-08-01 16:21:16 +02:00
Alexander Barton
338c643250 Merge branch 'master' of git://ngircd.barton.de/ngircd 2008-07-31 14:36:39 +02:00
Alexander Barton
5af91fc005 Install /Library/LaunchDaemons/de.barton.ngircd.plist into $(DESTDIR) 2008-07-31 14:35:22 +02:00
Florian Westphal
0ca8156efd FAQ: add entry about /OPER and OperCanUseMode 2008-07-31 14:13:06 +02:00
Alexander Barton
ccbbd7d1a5 GIT: added src/testsuite/message-test to ignore list. 2008-07-27 20:51:37 +02:00
Alexander Barton
e5cf73b9ee Fix Validate_Args(): unused parameter "Idx" and "Req"
This patch fixes the following error message of GCC (tested with version
4.3.0) when not compiling ngIRCd in "strict RFC" mode:

parse.c: In function "Validate_Args":
parse.c:341: error: unused parameter "Idx"
parse.c:341: error: unused parameter "Req"
2008-07-27 20:35:01 +02:00
Alexander Barton
5df56111c4 message-test: Disable two tests using "localhost" as host name
Some operating systems, for example OpenBSD and OpenSolaris, use
"localhost.<domain>" instead of just "localhost" for 127.0.0.1, so
the "message-test" using "localhost" failed on such systems.

Don't have an idee how to make this work on all platforms ... :-/

So I simply disabled the two affected tests to make the testsuite
run on OpenBSD and OpenSolaris again.
2008-07-27 18:03:13 +02:00
Alexander Barton
e5174c629c Fix Send_Message(): "lastCurrentTarget" may be used uninitialized
This patch fixes the following warning of GCC 4.3.1:

irc.c: In function "Send_Message":
irc.c:315: error: "lastCurrentTarget" may be used uninitialized in
this function
2008-07-27 17:16:41 +02:00
Alexander Barton
3358ad07d7 Fix t_diff(): declaration of 'div' shadows a global declaration
This patch fixes the following GCC warning message:
irc-info.c:422: warning: declaration of 'div' shadows a global declaration
2008-07-27 15:58:06 +02:00
Alexander Barton
318c8b238b Cosmetic whitespace and line length fixes, mostly in Send_Message(). 2008-07-27 15:50:51 +02:00
Alexander Barton
f8381aafb4 Added "message-test" to Makefile, so it is distrubuted and run. 2008-07-27 14:45:04 +02:00
Brandon Beresini
d4eb55c79f Cleaned up PRIVMSG and NOTICE patches. 2008-07-27 01:23:20 +02:00
Brandon Beresini
2546a13ad2 Cumulative Message Patch 2008-07-27 01:23:04 +02:00
Alexander Barton
b92a7627f3 Don't allow empty channel names ("#") in strict RFC mode.
This closes Bug #88.

Patch proposed by Eric <egrunow@ucsd.edu>, but with wrong length
comparision: please note that Channel_IsValidName() checks the name
INCLUDING the prefix, so the test must be length<=1!
2008-07-22 13:24:14 +02:00
Alexander Barton
258143897c Return 461 (syntax error) on "JOIN :" and "PART :"
Up to this patch ngIRCd did not return any result (GIT master) or a badly
formated 403 (":irc.server 403 test  :No such channel" [note the two
spaces!], branch-0-12-x) on the above commands, this patch changes the
behaviour to reflect ircd 2.11 which returns 461 in both cases.
2008-07-22 13:18:19 +02:00
Alexander Barton
477f2fd9e7 Channel_Join(): Code cleanup. 2008-07-22 13:07:57 +02:00
Alexander Barton
e37080400b Added more supported and tested platforms to doc/Platforms.txt. 2008-07-21 14:59:28 +02:00
Alexander Barton
3f01324160 Fixes to misc-test: accept "localhost.<domain>" as well as "localhost"
Some operating systems, for example OpenBSD, use "localhost.<domain>"
instead of "localhost", so the "who-test" expecting "localhost" failed
on such systems.

(Please see 149859c5fecc..., which fixes this for the who-test already)
2008-07-21 13:40:22 +02:00
Alexander Barton
4467d127c2 Revert "dpkg-shlibdeps: warning: dependency on libnsl.so.1 [..]"
- Solaris needs both -lsocket _and_ -lnsl
- A/UX needs -lUTIL

"... which totally sucks because we'd link libnsl on Linux, too
(where its not needed at all). So, we have to figure out how to tell
autocrap to NOT put -lnsl there unless it exports a symbol we need.
This also means that [...] has to be reverted (or done properly)."
					-- Florian Westphal @ #ngircd

This reverts commit 2b14234abc.
2008-07-09 18:36:40 +02:00
Florian Westphal
2b14234abc dpkg-shlibdeps: warning: dependency on libnsl.so.1 [..]
(they use none of its symbols).

So, rip out that AC_CHECK_LIB cruft, pointed out by Christoph Biedl.

If there are platforms that really need that we should
only link when we actually use these libraries.
2008-07-09 18:33:48 +02:00
Alexander Barton
b945726ac2 Merge autogen.sh changes
Merge commit 'alex/master'
2008-06-27 06:07:41 +02:00
Alexander Barton
da160d020e autogen.sh: Don't set AUTO{CONF|MAKE}_VERSION and WANT_AUTO{CONF|MAKE}
On some systems (for example Gentoo Linux, FreeBSD, and OpenBSD), these
variables are used to select which version of GNU automake and autoconf
to use, but we shouldn't depend on a specific version -- instead we
should use the "system default". So probably it is up to the user to
set these variables accordingly to set up some wrapper scripts of his
operating system distribution.
2008-06-27 05:55:45 +02:00
Alexander Barton
b95345731e autogen.sh: correctly test for and export ACLOCAL variable 2008-06-27 05:44:04 +02:00
Eric Grunow
71562ebe57 Translated comments from German to English 2008-06-16 13:58:56 +02:00
Alexander Barton
258e39e89f Fix GCC warnings for possibly uninitialized variables in IRC_JOIN
This patch fixes the following two warnings of GCC 4.2.4:

irc-channel.c: In function "IRC_JOIN":
irc-channel.c:185:
 warning: "lastkey" may be used uninitialized in this function
irc-channel.c:185:
 warning: "lastchan" may be used uninitialized in this function
2008-06-16 13:18:03 +02:00
Alexander Barton
e142c50ae6 GIT: added src/src/config.h.in~ to ignore list. 2008-06-11 16:02:06 +02:00
Alexander Barton
a84f7dcee5 Allow mixed line terminations (CR+LF/CR/LF) in non-RFC-compliant mode
Up to now ngIRCd accepted CR+LF as well as a single CR or LF in "non RFC
compliant" mode (the default). But ngIRCd became confused when it received
data containing mixed line endings (e. g. "111\r222\n333\r\n").

This patch enables ngIRCd (in "non RFC compliant" mode) to detect CR+LF,
CR, and LF as equally good line termination sequences and to always end the
command after the first one detected.

Some clients (for exmaple Trilian) are that ... broken to send such mixed
line terminations ...

First patch proposed by Scott Perry <scperry@ucsd.edu>,
Thanks to Ali Shemiran <ashemira@ucsd.edu> for testing!
2008-06-11 16:00:38 +02:00
Alexander Barton
8644cbf197 Don't allow stray \r or \n in command parameters
If ngircd receives an input line like "COMMAND arg\nIRRELEVANT\r\n",
"arg\nIRRELEVANT" is passed as an argument to COMMAND. This can lead
to output like:

:ngircd.test.server 322 nick #chan 1 :
topicwithprecedingnewline
:ngircd.test.server 322 nick #nxtchan 1 :
[..]

Worse, this allows clients to piggyback irc commands, e.g.
"TOPIC #a :test\n:fake!~a@nonexistant JOIN :#a\r\n", which
causes the client to receive a JOIN command during /LIST output.

Bug reported by Scott Perry, first patch by Florian Westphal.
2008-05-30 14:58:25 +02:00
Alexander Barton
4c121f277d GIT: ignore de.barton.ngircd.plist, it is a generated file. 2008-05-28 03:00:22 +02:00
Alexander Barton
12f5b0579b ngircd.init: use LSB logging functions, if available. 2008-05-28 01:50:18 +02:00
Alexander Barton
6f7b669bec --configtest: return non-zero exit code if there are errors 2008-05-28 00:31:20 +02:00
Alexander Barton
951314cb79 Handle_Buffer(): code cleanup.
Both callers ignore the return code of this function, so get rid of it,
but make sure that the client is disconnected on errors.
2008-05-26 23:38:32 +02:00
Alexander Barton
d360871394 Conn_Handler(): cleanup code, add/translate comments.
In addition, the "timeout" variable has been removed because it is
unnecessary today: Handle_Buffer() handles all the data it can handle,
and io_dispatch() returns immediately when new data is available. So
we don't have to double-check but better sleep. Pointed out by Florian.
2008-05-26 21:38:27 +02:00
Scott Perry
b90f71ca2a Use strtok_r instead of strchr in IRC_JOIN.
This patch does significant cleanup on the join code by using strtok_r
instead of mangling strchr to parse channel names and keys in parallel when
a JOIN command contains a list of channels and keys.

Also adds an strtok_r implementation to libportab.
2008-05-26 21:20:03 +02:00
Alexander Barton
d060e90de0 Mac OS X LaunchDaemon script: log messages to /Library/Logs/ngIRCd.log 2008-05-26 17:48:02 +02:00
Florian Westphal
73f7201ab3 configure.in: don't check for "obvious" standard functions.
Drop checks for the following C standard functions:
malloc, memmove, memset, realloc, strchr, strcspn, strerror, strstr.

Rationale: These are standard K&R/C89 functions, no point in
''making sure they exist''.
2008-05-25 20:16:25 +02:00
Alexander Barton
956bbe2c28 Reset client idle time on NICK, JOIN, and PART 2008-05-24 21:50:54 +02:00
Florian Westphal
e19f7a8c19 Remove ListenIPv4/ListenIPv6 options.
Use "Listen = list,of,addresses" instead.
2008-05-19 14:34:48 +02:00
Florian Westphal
4ed2cb1a02 make Listen parameter a comma-seperated list of addresses.
this also obsoletes ListenIPv4 and ListenIPv6 options.
If Listen is unset, it is treated as Listen="::,0.0.0.0".

Note: ListenIPv4 and ListenIPv6 options are still recognized,
but ngircd will print a warning if they are used in the config file.

Also, some plattforms require that ai_socktype
is set in the getaddrinfo() hints structure.
2008-05-19 14:27:35 +02:00
Jari Aalto
818a206a42 Add option aliases -V (for --version) and -h (for --help).
This patch adds -h and -V short options (to complement the usage).

It is based on a patch attached to Debian bug #466063, see
<http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=466063>.

Idea by Jari Aalto <jari.aalto@cante.net>,
patch adapted by Alexander Barton <alex@barton.de>.
2008-05-18 16:19:41 +02:00
Florian Westphal
1d9067b019 Add FAQ entry for 'Where is the log file'? 2008-05-15 15:41:23 +02:00
Brandon Beresini
5d87f6ba80 Add tests for MOTD, VERSION, TIME, USERHOST
The misc-test.e file is also somewhat reorganized and commented here.

Patch from Brandon Beresini, Bryan Caldwell and Dana Dahlstrom.
2008-05-15 11:13:45 +02:00
Alexander Barton
7cf187c09f Updated list of authors (AUTHORS file) 2008-05-13 16:21:14 +02:00
Alexander Barton
9486bc7465 Update master development branch
- use "dev" instead of "HEAD" as "version number",
- update ChangeLog and NEWS to reflect the 0.12.0 release.
2008-05-13 16:12:15 +02:00
Alexander Barton
d02b083543 Merge commit 'aad49bd260494878aed6795c7a897ad1d28c3082' 2008-05-13 12:14:14 +02:00
Scott Perry
70254a5553 This patch implements a (maybe) compliant WHOWAS command.
It is hard to test this in the test suite because we 1) shouldn't rely on
previous tests populating WHOWAS and 2) don't connect a user for more than 30
seconds.

Also makes WHOWAS return ERR_NONICKNAMEGIVEN_MSG as implied by RFC.
2008-05-12 18:56:31 +02:00
Florian Westphal
b1d38de4d2 If bind() fails, also print ip address and not just the port number. 2008-05-12 18:46:55 +02:00
Alexander Barton
aad49bd260 Update ngIRCd manual pages
- Update timestamp,
- enhance some phrasing,
- and fix "Passive" ([Server]) formatting.
2008-05-11 17:08:46 +02:00
Alexander Barton
d90cc7add0 GIT: ignore symbolic links to tests in testsuite directory
Added symbolic links to new tests (invite-test, join-test, and kick-test)
to .gitignore file.
2008-05-11 15:20:46 +02:00
Alexander Barton
149859c5fe Fixes to who-test: accept "localhost.<domain>" as well as "localhost"
Some operating systems, for example OpenBSD, use "localhost.<domain>"
instead of "localhost", so the "who-test" expecting "localhost" failed
on such systems.
2008-05-11 15:17:22 +02:00
Florian Westphal
d9c26f3aeb ng_ipaddr.h must include netinet/in.h.
compile on FreeBSD 5.4 failed with:
./../ipaddr/ng_ipaddr.h:34: error: field `sin4' has incomplete type

Reported and tested by Jefferson S Almeida.
2008-05-10 21:49:51 +02:00
Brandon Beresini
0510bbe958 Removed space after # so that Cygwin's version of expect recognizes comments. 2008-05-09 21:54:47 +02:00
Ali Shemiran
12cd554af1 Fix secret channel information leak
/who on a secret channel that the user is not a member of
now returns proper RPL_ENDOFWHO_MSG instead of nothing.
2008-05-09 21:47:31 +02:00
ashemira@ucsd.edu
5cf5ba31eb Added Cygwin uid kludge. (verified working) 2008-05-08 13:04:25 +02:00
Eric Grunow
75b719a0c8 Anglified and improved comments in channel.c and channel.h
[Dana Dahlstrom: repair tab/space conversion in patch]
2008-05-08 03:15:04 +02:00
Alexander Barton
4e56e5341f Implement IRC commands SERVICE, SERVLIST, and SQUERY as dummy functions
SERVICE, SERVLIST, and SQUERY are required by RFC 2812 (it states in
section 3 that "all commands described in this section MUST be implemented
by any server for this protocol." -- So we implement them without (much)
actual functionality ...
2008-05-05 18:06:43 +02:00
Florian Westphal
3895b42d1b Add invite-test.e to test suite. 2008-05-05 16:12:41 +02:00
Dana Dahlstrom
6c81ffaece Tests for the INVITE command. 2008-05-05 16:12:41 +02:00
Dana Dahlstrom
97cc58fb13 Invite: prefix last argument with colon when necessary. 2008-05-05 16:12:41 +02:00
Dana Dahlstrom
c63d8fd051 tests for JOIN and various replies
Brandon Beresini sent me a patch yesterday adding tests for JOIN under
various circumstances, which I believe he worked on with Bryan Caldwell
and Ali Shemiran. I made a few modifications; the result is below.
2008-05-05 16:12:41 +02:00
Bryan Caldwell
3d8eda9c86 Allow KICK to handle comma-delimited lists (of channels, nicks).
includes test cases.

[fw@strlen.de:
	- move code around to avoid duplication
	- use const where possible
	- integrate test case]
2008-05-05 16:12:41 +02:00
Florian Westphal
3283d275ba Invite: Send RPL_AWAY to client sending the invite if target is away. 2008-05-05 15:52:41 +02:00
Dana Dahlstrom
faf9b6ea16 Fixes to who-test: accept any ident, escape some '*' flags.
This prevents who-test.e from failing when ngircd
is performing ident lookups and an ident server is running.
2008-05-05 15:40:00 +02:00
Florian Westphal
452fb28394 IRC_INVITE: coding style cleanup. 2008-05-05 15:39:54 +02:00
Florian Westphal
0428a1c4ea Constify some of Channel_Kick()s arguments. 2008-05-05 15:38:47 +02:00
Florian Westphal
98a8ea105c constify Client_Search() argument. 2008-05-05 15:38:43 +02:00
Rolf Eike Beer
83bfdddf99 Allow IRC ops to ignore channel limits when joining
Allow IRC ops to ignore any channel limit (bans, invite only etc.) when they
want to join a channel.
2008-05-05 14:45:28 +02:00
Alexander Barton
2a790861a1 Handle 1-character messages terminated with CR or LF correctly
Code cleanup and fix for Bug #83, "ngIRCd chokes on 1-character messages" in
function Handle_Buffer(): the buffer is now correctly cleared when ngIRCd
receives 1-character messages terminated with either CR or LF (in violation
to RFC 2812, section 2.3 "Messages", 5th paragraph).
2008-05-02 02:14:15 +02:00
Alexander Barton
4e507881f3 On AIX (for example) socklen_t is defined in sys/socket.h
On AIX and probably other systems socklen_t is defined in sys/socket.h,
so we have to include it here explicitly (tested by Florian).
2008-05-01 20:25:39 +02:00
Florian Westphal
f7c2e8223f Always enable modeless channels.
Modeless channels (+channels) are described in RFC 2811;
so my modifications to
530112b114
('Add support for modeless channels')
to disable +channels for --strict-rfc configurations
were wrong. This reverts those changes.
2008-05-01 18:08:07 +02:00
Alexander Barton
60acc62af7 Prevent GIT to complain about opless-channel-test link 2008-05-01 16:31:13 +02:00
Ali Shemiran
530112b114 Add support for modeless channels
Add support for modeless channels (+channels).

[fw@strlen.de:
 - integrate test cases
 - don't support +channels when compiled with --strict-rfc
 - do not set +o mode for channel creator
 - force +nt mode when channel is created ]
2008-05-01 15:55:12 +02:00
Alexander Barton
6cfc56064e Updated NEWS and ChangeLog for ngIRCd 0.12.0-pre2. 2008-04-29 15:34:15 +02:00
Alexander Barton
4a81367dac --configtest: fix missing whitespace at "ConnectIPv4" option. 2008-04-29 15:27:44 +02:00
Alexander Barton
8c425945a2 --enable-ipv6: fix indentation in ./configure --help output. 2008-04-29 15:26:20 +02:00
Alexander Barton
bb6ee46892 Merge branch 'master' of git://git.breakpoint.cc/fw/ngircd-fw 2008-04-29 15:15:28 +02:00
Florian Westphal
9194319399 Testsuite: remove erroneous ConfUID setting in config file.
The config file for ngircds test suite contained obsolete
ConfUID/ConfGID settings, causing ngircd to needlesly complain when
started as non-root (which is hopefully the _normal_ case...)
2008-04-29 13:32:29 +02:00
Alexander Barton
33b1204349 Get rid of cvs-version.* and CVSDATE definition.
(cherry picked from commit b187fac244)
2008-04-25 00:14:11 +02:00
Alexander Barton
09968ee843 Documentation: get rid of some more references to CVS, switch to GIT.
(cherry picked from commit 6e9389b86c)
2008-04-25 00:13:07 +02:00
Alexander Barton
523a6fad09 Report ERR_NOTONCHANNEL when trying to part a channel one is not member of.
When trying to part a channel ("PART #channel") the client is not member of
the daemon now correctly reports the numeric ERR_NOTONCHANNEL (442) insted
of ERR_NOSUCHCHANNEL (403).
2008-04-24 23:52:54 +02:00
Alexander Barton
54b17fc201 Channel_Part(): Code and comment cleanup. 2008-04-24 23:47:33 +02:00
Alexander Barton
25f48a2a34 IRC_PART(): code and comment cleanup. 2008-04-24 23:46:59 +02:00
Florian Westphal
22fa782be7 IPv6: Add config options to disabe ipv4/ipv6 support.
This also enables ipv6-only setups.
2008-04-21 00:45:19 +02:00
Alexander Barton
2f6d7a649c Don't include doc/CVS.txt in distribution archive, use doc/GIT.txt now!
(cherry picked from commit a8e0eb62e9)
2008-04-20 17:37:21 +02:00
Alexander Barton
7df90846e1 Synchronized branch-0-12-x (ngIRCd 0.12.0-pre1) with master.
(cherry picked from commit 4ea2932967)
2008-04-20 16:20:53 +02:00
Alexander Barton
92a9092208 Updated NEWS and ChangeLog for upcoming 0.12.0-pre1 release. 2008-04-20 15:48:49 +02:00
Alexander Barton
a0efcdccfa Updated copyright notice to read "2001-2008". 2008-04-20 15:48:22 +02:00
Alexander Barton
012aeca32b Added make target "testsuite"
This make target runs the testsuite located in src/testsuite without running
alle the other tests that "make check" would run.
2008-04-20 14:52:00 +02:00
Alexander Barton
c4a505d3a8 Fixed "xcode" make target (used to build ngIRCd with Mac OS X Xcode) 2008-04-20 14:50:46 +02:00
Florian Westphal
8df445316a Channel_Mode: Remove duplicate code.
Incidentially, this doesn't even change the
generated code...
2008-04-19 16:58:00 +02:00
Florian Westphal
11af32466f Channel_Mode: change order of if (set) and if (client) check. 2008-04-19 16:51:42 +02:00
Florian Westphal
5538115537 Channel_Mode: Re-indent switch.
No functional changes were made.
2008-04-19 16:45:31 +02:00
Florian Westphal
b8643477ba Channel_Mode: check return type of Invite/Ban Add/Del function 2008-04-19 16:17:11 +02:00
Florian Westphal
796dcf6a62 Channel_Mode: unify 'b' and 'I' switch/case handling. 2008-04-19 14:16:17 +02:00
Florian Westphal
6b0c094809 Channel_Mode: Unify Del_Invite and Del_Ban handler 2008-04-19 14:12:06 +02:00
Florian Westphal
b36fc3b095 Constify Lists_MakeMask argument and return type. 2008-04-19 14:11:25 +02:00
Florian Westphal
2dd51a98e4 Channel_Mode: Unify Add_Invite and Add_Ban handler 2008-04-19 14:02:54 +02:00
Alexander Barton
761ae2b1a4 Enable more compiler warnings when using Xcode. 2008-04-13 23:43:12 +02:00
Alexander Barton
87cae1465b GIT should ignore user preferences files inside Xcode projects.
Added filter for GIT to ignore Xcode user preferences files (*.mode1v3 and
*.pbxuser) which are automatically generated inside the project bundle when
opened in Xcode.
2008-04-12 23:29:58 +02:00
Alexander Barton
b7135ea76a Updated Xcode project file. 2008-04-12 23:27:11 +02:00
Florian Westphal
248f8e0b70 Convert CVS commands to their git equivalents.
Also mention that patches should be sent to the mailing list.
2008-04-12 21:51:15 +02:00
Alexander Barton
7b33424c13 Added "portabtest" binary to .gitignore file in src/portabtest/. 2008-04-09 19:46:26 +02:00
Alexander Barton
7c82cc236b Include Mac OS X Xcode project in distribution archives. (Part 2)
I forgot to include the new Makefile.am in contrib/MacOSX/ngIRCd.xcodeproj/ ...
2008-04-09 19:24:22 +02:00
Alexander Barton
307f8abd74 Include Mac OS X Xcode project in distribution archives.
Oops, it has not been included since ... ages??
2008-04-09 19:09:23 +02:00
Alexander Barton
bc63064d5c Moved .cvsignore files to .gitignore
Since we are using GIT starting from now, I converted all the
.cvsignore files to .gitignore files.
2008-04-09 18:54:52 +02:00
Florian Westphal
be844d74d3 Fix client.c sparse warnings.
client.c:72:6: warning: symbol 'Max_Users' was not declared. Should it be static?
client.c:72:21: warning: symbol 'My_Max_Users' was not declared. Should it be static?
2008-04-04 23:22:06 +02:00
Florian Westphal
637d739285 io.c: kill select FD_SETSIZE sanity check in io_library_init.
We already have way too many.
2008-04-03 23:20:26 +02:00
Florian Westphal
66e68de16a io.c: fix select FD_SETSIZE check when using epoll as io backend 2008-04-03 23:20:22 +02:00
Florian Westphal
7f44a2ad1c io.c: try to cut down the number of ifdefs.
consolidate backend-specific helpers and
add empty statinc inle stubs in the ifndef case
to let the compiler remove the functions at compile time.
2008-03-27 16:53:39 +01:00
Florian Westphal
abb1abeb77 Do not exit unconditionally if config file cannot be opened
ngircd will exit if the config file cannot be opened. While
thats okay if ngircd starts up for the first time, it isn't
when we are re-reading the config file after a /REHASH or SIGHUP.
2008-03-26 21:31:13 +01:00
Alexander Barton
ab1f48a346 Fix #include's: search log.h locally, include string.h. The latter is required because we include conn.h, which includes resolve.h, which includes ng_ipaddr.h, which contains a macro using strlcpy() ... 2008-03-11 15:42:58 +01:00
Florian Westphal
feb31e4200 IPv6 support.
all references to struct sockaddr/in_addr have been
removed from src/ngircd.
libngipaddr (in src/ipaddr/) hides all the gory details.
See src/ipaddr/ng_ipaddr.h for API description.
2008-02-26 23:50:35 +01:00
Alexander Barton
c31ad221a6 Updated ChangeLog to include 0.11.1. 2008-02-26 23:49:33 +01:00
Rolf Eike Beer
44cdf1b1ca Fix sending of JOINs between servers.
This does hit only operators that join a channel with at least 2 servers active in the net
the server the oper connects to sends "channel^Go" to the other servers
the other server first searches for the channel and then strips the modes from the channel name
he has to do the other way round: first strip and then check the channel name.
2008-02-26 23:49:33 +01:00
Florian Westphal
e710e8ae37 Channel_Mode cleanups
- better indentation
- move answering request into seperate function.
2008-02-26 23:49:33 +01:00
Alexander Barton
89ba1bdcba LaunchDaemon plist for Mac OS X/Darwin launchd. 2008-02-26 23:49:33 +01:00
Alexander Barton
0250acc50b Install a LaunchDaemon script to start/stop ngIRCd on Mac OS X. 2008-02-26 23:49:33 +01:00
Alexander Barton
ec80cc99c6 Added new test files to Xcode project. 2008-02-26 23:49:33 +01:00
Alexander Barton
5147b675cb Removed the SQUIT test for now, actually we don't support it yet. 2008-02-26 23:49:33 +01:00
Alexander Barton
ddecfcd831 Implemented IRC commands INFO, USERS (dummy), and SUMMON (dummy). 2008-02-26 23:49:33 +01:00
Dana Dahlstrom
2f71fbb2a1 Include flags in RPL_WHOREPLY messages.
RPL_WHOREPLY messages generated by IRC_WHO don't include flags (*,@,+)
that should appear according to this description:

http://www.mishscript.de/reference/rawhelp3.htm#raw352

Other IRC servers do include the flags.

Modify who-test.e to expose missing flags,
modify ngircd-test.conf to accommodate who-test.e, and fix
irc-info.c to correct these problems.
2008-02-26 23:49:33 +01:00
Dana Dahlstrom
1784180bf3 Don't send trailing space in MODE messages
Under some circumstances ngIRCd currently issues a channel MODE message
with a trailing space after the last parameter, which isn't permitted by
the grammar in RFC 2812 section 2.3.1:

http://tools.ietf.org/html/rfc2812#section-2.3.1

The following patch modifies mode-test.e to expose this, and modifies
irc-mode.c to correct it.
2008-02-26 23:49:33 +01:00
Florian Westphal
634ef8c131 IRC_JOIN cleanups.
- put sending of mode and forwarding of JOIN to other clients
 into seperate function.
- put sending of topic/channel names into seperate function.
- put access check into seperate function.
- translate/remove remaining german comments.
- stop if JOIN to a channel in a list (JOIN #a,#,b,#c...) fails
(This doesn't change the behaviour: skip-to-next-channel-on-error
did never work as intended)
2008-02-26 23:49:33 +01:00
Florian Westphal
4d152b771e Make IRC_WHO also search username/servername/hostname.
Dana Dahlstrom reported that IRC_WHO did not follow
RFC 2812, Section 3.6.1. Specifically:

- IRC_WHO did not send "G" flag instead if "H" if client was away
- did not search username/servername/hostname etc. if argument
  was not a channel.

Fix all of the above and tidy things up a bit.
Also add IRC_WHO test script contributed by Dana.
2008-02-26 23:49:33 +01:00
Dana Dahlstrom
c634303765 Remove duplicate Channel_FirstChannelOf().
noticed there's a way to make the loop
slightly more elegant.

[fw@strlen.de: Extra () to silence gcc.]
2008-02-26 23:49:33 +01:00
Florian Westphal
cb0d594e61 Make Channel_Part name and reason parameters 'const'. 2008-02-26 23:49:33 +01:00
Florian Westphal
000a227a74 Updated NEWS to reflect ChangeLog. 2008-02-26 23:49:33 +01:00
Dana Dahlstrom
6bd35bf090 Implement RFC 2812 handling of "0" argument to JOIN
The students in my software-engineering class are writing IRC clients in
Java, and I'm running ngIRCd as a sandbox for them to play in. We
noticed ngIRCd doesn't obey the "JOIN 0" command specified in RFC 2812:

   JOIN 0             ; Leave all currently joined
                      channels.

http://tools.ietf.org/html/rfc2812#section-3.2.1
I believe the following patch addresses this. Cheers!

[fw@strlen.de: put it into a seperate function]
2008-02-26 23:49:33 +01:00
Florian Westphal
3022d7cff3 Don't use Client_Type after command has been processed.
This caused a read from already free'd memory, if the processed
command (IRC_QUIT) calls Client_Destroy.
2008-02-26 23:49:33 +01:00
Alexander Barton
f86ce17f1c Updated NEWS to reflect ChangeLog. 2008-02-26 23:49:33 +01:00
Florian Westphal
42db159d26 Fix wrong strncpy usage if CVSDATE defined
Hello_User() used strncpy with overlapping src/dest.
Use memmove instead.
2008-02-26 23:49:33 +01:00
Florian Westphal
59b19ea6a3 This adds support for sending NOTICEs to a channel.
[also see Bug #70 in ngircd bugzilla].

Based on a patch by Fabian Schlager <fabian.schlager@gmail.com>.
2008-02-26 23:49:33 +01:00
Florian Westphal
4add9c29ed [Parser]: Fix minor sparse warnings
parse.c:56:9: warning: symbol 'My_Commands' was not declared. Should it be static?
parse.c:107:9: warning: symbol 'My_Numerics' was not declared. Should it be static?

Also move handling of numerics into a seperate helper function.
2008-01-13 16:12:49 +00:00
Alexander Barton
d1364ab488 Updated ChangeLog to reflect changes in 0.10.x and 0.11.x branches. 2008-01-07 23:08:14 +00:00
Alexander Barton
56256535c5 Updated Debian changelog [from 0.10.x; 0.11.x] 2008-01-07 23:06:24 +00:00
Alexander Barton
35b6f3997c Document NoDNS configuration option. 2008-01-07 23:02:29 +00:00
Florian Westphal
463c5cb7c5 IRC_PART could reference invalid memory. 2008-01-07 11:42:00 +00:00
Alexander Barton
7548aa089c Remove entry about ngircd failing on Linux 2.4:
ngircd can now fall back to select. [from 0.11.x]
2008-01-02 22:47:58 +00:00
Alexander Barton
478a8c01f9 Updated NEWS and ChangeLog files. 2008-01-02 11:31:48 +00:00
Florian Westphal
61e6b5c0aa [Resolver]: Use dotted-decimal IP address if hostname is >= 64 2008-01-02 11:03:29 +00:00
Florian Westphal
91a6fffaa0 io_event_disable: return if event-to-disable is already off 2008-01-02 10:29:51 +00:00
Florian Westphal
2ce5b734bd kqueue: check for EV_ERROR in .flags
if kevent() returns events, check for EV_ERROR in event flags, too.
2007-12-27 18:25:26 +00:00
Florian Westphal
f99f9a8f02 Fix format arg: ListenAddress was printed instead of Bind address. 2007-12-13 01:30:16 +00:00
Florian Westphal
4715ccf9ca Fix format string in error path: didn't print strerror(errno) 2007-12-13 01:05:01 +00:00
Florian Westphal
8974e90552 implement '/STAT u' (uptime) 2007-12-11 11:29:43 +00:00
Florian Westphal
2fe13f0a45 Fix fmt string: int, not long 2007-12-07 21:19:01 +00:00
Florian Westphal
20ce56cc5b include <arpa/inet.h> inside tool.h
In file included from hash.c:24:
../tool/tool.h:27: warning: `struct in_addr' declared inside parameter list
2007-11-25 18:42:37 +00:00
Florian Westphal
47a0379e2b remove ip-string from Conf_Server struct
struct Conf_Server stored the ip address to connect to
in dotted-decimal notation; but we only need this for connect()
so long-time storage isn't necessary.
2007-11-23 16:28:37 +00:00
Florian Westphal
37563537a9 document new "Bind" server config option in changelog. 2007-11-23 16:28:05 +00:00
Florian Westphal
82d32ffb28 bind ListenAddress for outgoing connections
ngircd would always use INADDR_ANY for outgoing connections;
which might not be desirable. Added new [Server] option
"Bind" to set source ip.
2007-11-23 16:26:03 +00:00
Alexander Barton
024588dbe7 Funktions to handle numerics sent to the server. 2007-11-21 12:20:32 +00:00
Alexander Barton
47ca178a21 Introduce option to configure the maximum nick name lenth in ngircd.conf
- New configuration option "MaxNickLength" to specify the allowed maximum
  length of user nick names. Note: must be unique in an IRC network!
- Enhanced the IRC+ protocol to support an enhanced "server handshake" and
  enable server to recognice numeric 005 (ISUPPORT) and 376 (ENDOFMOTD).
  See doc/Protocol.txt for details.
2007-11-21 12:16:33 +00:00
Alexander Barton
12db0bdc4f Re-added doc/SSL.txt to distribution -- got lost somewhere!? 2007-11-20 21:39:35 +00:00
Alexander Barton
53b98fd7e9 Fixes the wrong logging output when nested servers are introduced
to the network as well as the wrong output of the LINKS command.
2007-11-20 20:02:40 +00:00
Alexander Barton
c7d4d85666 Remove some bogus files from project ... 2007-11-19 23:38:59 +00:00
Alexander Barton
4659dae6eb Update Mac OS X Xcode project file for Xcode 3.
Allow building of ngIRCd using Xcode 3 without running ./configure.
2007-11-19 22:11:36 +00:00
Alexander Barton
68f896eee0 Adjust test suite to be usable on HP/UX 11.11 :-) 2007-11-18 15:07:16 +00:00
Alexander Barton
06bfb3adfb Fix code to compile using K&R C compiler and ansi2kr again. 2007-11-18 15:05:35 +00:00
Florian Westphal
2f305331a1 add tiny note about ngircd using syslog(3) by default. 2007-11-15 01:03:29 +00:00
Florian Westphal
ad7361dfe0 if ngircd doesn't run chrooted, it tries to chdir
to the users working directory (as returned by getpwuid()).
Failing to chdir to that directory isn't an error; so
log with LOG_INFO and prefix the message with "Notice".
2007-11-15 01:03:01 +00:00
Florian Westphal
e47c9d750f Document NoDNS Option in changelog 2007-10-25 11:03:02 +00:00
Florian Westphal
001c00b273 New config option NoDNS: disables all DNS queries. 2007-10-25 11:01:19 +00:00
Florian Westphal
b861f536b2 configtest would still print "-1" for MaxConnections, MaxConnectionsIP and MaxJoins
if any of those values was set to 0.
2007-10-24 00:48:41 +00:00
Alexander Barton
877bcc55f2 Updates NEWS to reflect changes in CVS HEAD 2007-10-14 14:17:32 +00:00
Alexander Barton
8f162f4e17 Fixed propagation of channel mode 'P' on server links. 2007-10-14 12:08:57 +00:00
Alexander Barton
089ca21b3d Xcode project: include manual page template files, not generated pages. 2007-10-14 11:25:45 +00:00
Alexander Barton
137a139112 Updated Mac OS X project file for Xcode. 2007-10-14 10:37:20 +00:00
Florian Westphal
b160f574de fix doc and manpage wrt. MaxConnections, MaxConnectionsIP and MaxJoins values 2007-10-13 20:45:11 +00:00
Florian Westphal
d223b587e4 accoring to comments in the code, MaxConnections, MaxConnectionsIP and MaxJoins
options allow setting values < 0 -- this isn't the case. Comments adjusted.
2007-10-13 19:11:06 +00:00
Alexander Barton
77939c382d Updated preferred automake version to 1.9. Only set preferences if not
already defined by some environment variables.
2007-10-07 13:02:15 +00:00
Alexander Barton
f586052f2b Made pointer to the mailing list more prominent. 2007-10-04 15:18:48 +00:00
Alexander Barton
d4ed056147 Numeric 317: implemented "signon time" (displayed in WHOIS result). 2007-10-04 15:03:55 +00:00
Alexander Barton
9021ea2070 Updated documentation ("Passive" option, for example). 2007-10-04 10:14:52 +00:00
Florian Westphal
640367e886 we now support /WALLOPS 2007-08-02 10:16:28 +00:00
Florian Westphal
4b9e52eb4d implement /WALLOPS as described in RFC 2812, section 4.7. 2007-08-02 10:14:26 +00:00
Alexander Barton
69081851ac SECURITY: Fixed a severe bug in handling JOIN commands, which could
cause the server to crash. Thanks to Sebastian Vesper, <net@veoson.net>.
2007-07-31 18:56:13 +00:00
Florian Westphal
efcca62a35 last fix accidentially broke reconnect timer. 2007-07-21 18:46:28 +00:00
Florian Westphal
cd65e0a56e Don't connect to a server if a connection to another server within the same group
is in progress.
2007-06-28 15:13:38 +00:00
Florian Westphal
2275add327 Add new server config option to disable automatic connect. (Tassilo Schweyer) 2007-06-28 05:15:12 +00:00
Alexander Barton
fd1091541b Updated documentation to include changes of ngIRCd 0.10.2. 2007-06-13 14:32:13 +00:00
Florian Westphal
5675be4cd9 fix compile /w gcc 2.95 (reported by Tassilo Schweyer) 2007-06-11 20:06:46 +00:00
Alexander Barton
f1486e6a53 Updated config.guess and config.sub. 2007-05-26 10:44:12 +00:00
Alexander Barton
22a9ed6694 Add note to INSTALL document. 2007-05-20 22:37:05 +00:00
Alexander Barton
ddf56cbe5f Updated ChangeLog. 2007-05-17 23:38:14 +00:00
Alexander Barton
255edf7eab Reworked read and write buffer handling, introduced WRITEBUFFER_SLINK_LEN. 2007-05-17 23:34:24 +00:00
Alexander Barton
5930a29197 Zip_Flush(): close the connection in all error cases. 2007-05-17 15:16:47 +00:00
Florian Westphal
07d8da60de array_start() cannot legally return NULL if array_length() > 0 --> use assert(). 2007-05-17 14:46:14 +00:00
Alexander Barton
44afe042d1 Make Zip_Flush() more graceful. 2007-05-17 13:49:49 +00:00
Florian Westphal
a073bc89c4 there is no need to treat servers differently than clients on the read side. 2007-05-17 12:39:25 +00:00
Florian Westphal
63e89ceb21 make needlesly global function Conn_Write static. 2007-05-09 13:21:11 +00:00
Florian Westphal
09416f36bf remove ZBUFFER constants and increase max buffer size of server links 2007-05-09 08:55:14 +00:00
Florian Westphal
508b55126f fix compressed server links 2007-05-02 12:34:30 +00:00
Alexander Barton
9f65979979 2007 :-) 2007-04-09 01:24:05 +00:00
Alexander Barton
2e34ddae53 Updated documentation. 2007-04-08 11:39:08 +00:00
Florian Westphal
09deb857ce - change return type of Conn_InitListeners to unsigned
- remove minor whitespace damage
2007-04-04 21:52:12 +00:00
Florian Westphal
8c14d397ba put parentheses around argument 2007-04-03 22:08:10 +00:00
Florian Westphal
99eab1e216 if we can't bind a socket we now Log the port number, too. 2007-02-21 11:06:06 +00:00
Florian Westphal
c93d089736 return false instead of NULL in error path 2007-01-29 21:13:26 +00:00
Alexander Barton
429f85b77a Remove Client_DestroyNow() to keep semantik "every CONNECTON has a CLIENT". 2007-01-23 16:07:19 +00:00
Florian Westphal
ea2a4b3370 fix broken IO_DEBUG build 2007-01-19 13:52:54 +00:00
Florian Westphal
f9b9850662 io_event_add: return if eventtype is already registered. 2007-01-18 00:25:26 +00:00
Florian Westphal
1b852fce72 add support for predefined-channel configuration of k and l modes 2006-12-29 14:09:48 +00:00
Alexander Barton
82aaffe55d Added "html" directory to CVS ignore list (it is generated by doxygen). 2006-12-28 14:12:45 +00:00
Alexander Barton
40199e0b56 distclean: remove "html" folder. 2006-12-28 14:04:28 +00:00
Alexander Barton
95b7dbcc18 Updated documentation, refer to all the supported IO APIs. 2006-12-28 13:53:19 +00:00
Alexander Barton
43f8d149bb added "portabtest" binary to list of files to ignore. 2006-12-28 13:34:43 +00:00
Alexander Barton
949a4ef793 Added .cvsignore files to hide generated files from CVS. 2006-12-28 13:20:07 +00:00
Alexander Barton
f74781647a array_free(): enable debug code only when DEBUG_ARRAY is #define'd. 2006-12-28 12:53:41 +00:00
Alexander Barton
5c78230283 New configure option "--without-select"; when usin epoll() IO API include
support for select() as well by default and fall back on runtime when needed.
2006-12-26 16:00:45 +00:00
Alexander Barton
ee568cc444 Only "fiddle" with /etc/ngircd in "configure" stage. 2006-12-26 14:44:40 +00:00
Alexander Barton
2d9a3ec484 Added LSB compliant header. 2006-12-26 14:43:46 +00:00
Alexander Barton
262d945284 Fixed typo in #ifdef which tests if this header is already included or not. 2006-12-25 22:53:52 +00:00
Alexander Barton
f6ce2d557a Customize manual pages to reflect the actual installation location of files. 2006-12-25 16:13:26 +00:00
Florian Westphal
4243cae985 register io handler before creating new local client structure 2006-12-25 01:11:12 +00:00
Florian Westphal
40226d26b2 revert to last good revision again 8-/ 2006-12-17 23:04:45 +00:00
Florian Westphal
d2f7d3087d do not call Conn_Close when io_event_create fails 2006-12-17 22:55:07 +00:00
Florian Westphal
3f1e03edd9 fix possibe buffer-off-by one 2006-12-17 22:52:43 +00:00
Florian Westphal
23e7f7f0dd don't call Resolve_Shutdown() when io_event_create fails 2006-12-17 22:50:51 +00:00
Alexander Barton
f36746a4d0 Updated ChangeLog/NEWS to reflect release of ngIRCd 0.10.1. 2006-12-17 21:00:30 +00:00
Florian Westphal
8cb0e3af68 removed errouneous FD_SETSIZE limit when not using select() 2006-12-16 22:48:34 +00:00
Florian Westphal
eb3ddace46 add PredefChannelsOnly option to man page 2006-12-11 22:07:09 +00:00
Florian Westphal
5040d56489 minor cleanup 2006-12-07 22:24:14 +00:00
Florian Westphal
fb0fbe908d remove unused function Channel_PCount 2006-12-07 22:23:39 +00:00
Florian Westphal
fa7bb2790a moved invite/ban lists to channel structure 2006-12-07 17:57:20 +00:00
Florian Westphal
5877bca4bc fix RPL_LOCALUSERS_MSG (%ld -> %lu) 2006-12-02 14:24:36 +00:00
Florian Westphal
37602d1523 Log(LOG_DEBUG, .. -> LogDebug() 2006-12-02 14:10:48 +00:00
Florian Westphal
a09034563a predefined channels MUST start with '#', but this is not very intuitive,
since # is also used as a comment character in ngircd.conf. Thus
we prefix the name with '#' if it is missing.
2006-11-20 19:32:07 +00:00
Alexander Barton
5b35b101f2 Fixed validation of server names containing digits. 2006-11-10 10:05:00 +00:00
Florian Westphal
058d3085a9 New configuration option "PredefChannelsOnly": if set, make
all JOINs to-non existants channel return ERR_BANNEDFROMCHAN_MSG,
restricting users to those channels defined in the config file.
2006-11-05 13:03:46 +00:00
Alexander Barton
74883f57da Added OpenBSD/ppc to list of tested platforms. 2006-10-08 14:09:16 +00:00
Florian Westphal
018e351630 -Whitespace Damage; Client_OperCount(), Client_UnknownCount(), Client_MyServerCount() return unsigned long 2006-10-07 10:40:52 +00:00
Florian Westphal
6e105bf87e channel maxusers now unsigned long 2006-10-06 21:32:58 +00:00
Florian Westphal
61966a6088 add const qualifier to Hash() and Matche() Arguments 2006-10-06 21:23:47 +00:00
Florian Westphal
27c96632f1 Client_IsValidNick: no need to strcpy. 2006-10-06 19:57:56 +00:00
Florian Westphal
4108e16be6 Channel_Join was severely broken. 2006-10-05 18:26:54 +00:00
Alexander Barton
4e02bdc322 Update info text of local server after re-reading configuration. 2006-10-03 10:59:40 +00:00
Alexander Barton
ca5e09865e Removed an unused variable -- but where did it come from!? Strange ... 2006-10-03 10:28:38 +00:00
Florian Westphal
fb0c7ad252 add test for strcspn. 2006-10-02 21:57:13 +00:00
Florian Westphal
d8950c5dd0 cleaned up Channel_IsValidName (now uses strcspn()) 2006-10-02 21:55:49 +00:00
Alexander Barton
257312b102 Changed Numerics 265 and 266 to follow ircd 2.11.x "standards". 2006-10-01 19:13:32 +00:00
Alexander Barton
27d947fb7d Allow PASS syntax defined in RFC 1459 for server links, too.
Removed client status CLIENT_GOTPASSSERVER.
2006-10-01 19:05:00 +00:00
Alexander Barton
bed98979dc Enhanced ISUPPORT message (numeric 005). 2006-10-01 19:03:05 +00:00
Alexander Barton
bddb4914b4 Updated files from ngIRCd 0.10.0. 2006-10-01 17:23:36 +00:00
Florian Westphal
4c6c6ecf0e array_get: no need to multiply again. remove unneeded checks. remove array_free_wipe(). 2006-09-30 21:49:46 +00:00
Florian Westphal
a2f5a05ff8 io_close_poll()s closing brace mysteriously disappeared... fixed. 2006-09-19 18:21:30 +00:00
Florian Westphal
639eb40035 Added support for the /dev/poll i/o interface. 2006-09-17 10:41:06 +00:00
Florian Westphal
0d6f9d4e3e simplify io_library_init* 2006-09-16 16:47:27 +00:00
Florian Westphal
147de9dfa9 add support for the poll() interface 2006-09-16 15:00:09 +00:00
Florian Westphal
f6e729443e cleanup 2006-09-16 14:49:26 +00:00
Florian Westphal
e426c131c7 fix embarassing fileptr leak 2006-09-16 12:22:09 +00:00
Alexander Barton
b9661ae65d Updated autoconf helper scripts to version as of 2006-07-02. 2006-09-11 18:19:29 +00:00
Florian Westphal
035f7fb2fe only test for stack smashing protector if we are using gcc;
use -fstack-protector-all for the test to make sure the guard variable is added.
2006-09-09 17:07:39 +00:00
Alexander Barton
1b2c228de5 Updated documentation. 2006-08-29 23:59:35 +00:00
Florian Westphal
4d7d1d23be fix gcc 4.1 -fstack-protector detection. 2006-08-13 18:11:18 +00:00
Florian Westphal
e2aacff7d4 s/Log(LOG_DEBUG/LogDebug(/ , translated comments, etc. 2006-08-12 11:58:21 +00:00
Florian Westphal
0eccdbc137 -whitespace damage 2006-08-12 11:56:24 +00:00
Florian Westphal
939ee6a39b simplify Resolve_Read(). 2006-08-12 11:54:23 +00:00
Alexander Barton
8423b89996 Updated platform list once more ... 2006-08-07 07:45:45 +00:00
Alexander Barton
7d87318b04 Updated platform list. 2006-08-07 07:29:30 +00:00
Florian Westphal
83caef4598 if compiling without -DDEBUG, make LogDebug 'static inline' so gcc optimizes it away. 2006-08-05 09:16:21 +00:00
Florian Westphal
7378860aea check if compiler supports inline keyword. 2006-08-05 08:58:16 +00:00
Alexander Barton
6eb3f3055d Added support for Solaris 11. 2006-08-05 00:15:28 +00:00
Alexander Barton
c888c81adf Synchronized documentation with branch-0-10-x ... 2006-08-03 14:37:29 +00:00
Alexander Barton
fac4682212 Updated debian changelog. 2006-08-02 09:53:54 +00:00
137 changed files with 10554 additions and 4444 deletions

19
.gitignore vendored Normal file
View File

@@ -0,0 +1,19 @@
Makefile
Makefile.in
aclocal.m4
ansi2knr.1
ansi2knr.c
ansi2knr.h
autom4te.cache
config.log
config.status
configure
configure.lineno
depcomp
install-sh
missing
.deps
*.a
*.o
debian
build-stamp-ngircd*

25
AUTHORS
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2005 Alexander Barton,
(c)2001-2007 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -10,18 +10,31 @@
-- AUTHORS and CONTRIBUTORS --
Note: If you have critics, patches or something else, please feel free to
post a mail to the ngIRCd mailing list: <ngircd-ml@arthur.ath.cx> (please see
<http://ngircd.barton.de/#ml> for details). Don't mail the contributors
directly, if possible!
Main Authors
~~~~~~~~~~~~
Alexander Barton, <alex@barton.de> (alex)
Florian Westphal, <westphal@foo.fh-furtwangen.de> (fw)
Contributors
~~~~~~~~~~~~
Goetz Hoffart, <goetz@hoffart.de> (goetz)
Ilja Osthoff, <i.osthoff@gmx.net> (ilja)
Ali Shemiran, <ashemira@ucsd.edu>
Benjamin Pineau, <ben@zouh.org>
Brandon Beresini, <beresini@google.com>
Bryan Caldwell, <bcaldwel@ucsd.edu>
Dana Dahlstrom, <dana+ngIRCd@cs.ucsd.edu>
Eric Grunow, <egrunow@ucsd.edu>
Goetz Hoffart, <goetz@hoffart.de>
Ilja Osthoff, <i.osthoff@gmx.net>
Rolf Eike Beer, <eike@sf-mail.de>
Scott Perry, <scperry@ucsd.edu>
Sean Reifschneider, <jafo-rpms@tummy.com>
Florian Westphal, <westphal@foo.fh-furtwangen.de> (fw)
Code snippets
@@ -29,7 +42,3 @@ Code snippets
J. Kercheval: pattern matching functions
Patrick Powell, <papowell@astart.com>: snprintf()-function
Andrew Tridgell & Martin Pool: strl{cpy|cat}()-functions
--
$Id: AUTHORS,v 1.11 2005/03/19 14:24:52 alex Exp $

179
ChangeLog
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2005 Alexander Barton,
(c)2001-2008 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -10,8 +10,175 @@
-- ChangeLog --
ngIRCd CVSHEAD
ngIRCd Release 13 (2008-12-25)
- Updated documentation, especially doc/Services.txt and doc/SSL.txt.
- Make the test suite work on OpenSolaris.
ngIRCd 13~rc1 (2008-11-21):
- New version numer scheme :-)
- Initial support for IRC services, using a RFC1459 styel interface,
tested with IRCServices (http://www.ircservices.za.net/) version 5.1.13.
For this to work, ngIRCd now supports server-server links conforming
to RFC 1459. New ngircd.conf(5) option: ServiceMask.
- Support for SSL-encrypted server-server and client-server links using
OpenSSL (configure: --with-openssl) or GNUTLS (configure: --with-gnutls).
New ngircd.conf(5) options: SSLPorts, SSLKeyFile, SSLKeyFilePassword,
SSLCertFile, SSLDHFile, and SSLConnect.
- Server local channels have been implemented, prefix "&", that are only
visible to users of the same server and are not visible in the network.
In addition ngIRCd creates a "special" channel &SERVER on startup and logs
all the messages to it that a user with mode +s receives.
- New make target "osxpkg" to build a Mac OS X installer package.
- Debug mode: enable support for GNU libc memory tracing (see mtrace(3)).
- SysV init script: use LSB logging functions, if available.
- Added some more FAQ entries (regarding logging and IRC operators).
- Allow IRC operators to overwrite channel limits.
- Support for enhanced PRIVMSG and NOTICE message targets.
- More tests have been added to the test-suite ("make check"), and two
servers are started for testing server-server linking.
- Added a timestamp to log messages to the console.
- New configuration option "NoIdent" to disable IDENT lookups even if the
daemon is compiled with IDENT support.
ngIRCd 0.12.1 (2008-07-09)
- Allow mixed line terminations (CR+LF/CR/LF) in non-RFC-compliant mode
- Don't allow stray \r or \n in command parameters
- --configtest: return non-zero exit code if there are errors
- Update ngIRCd manual pages
- Add option aliases -V (for --version) and -h (for --help).
- Fix 'no-ipv6' compile error.
- Make Listen parameter a comma-seperated list of addresses. This also
obsoletes ListenIPv4 and ListenIPv6 options. If Listen is unset, it
is treated as Listen="::,0.0.0.0".
Note: ListenIPv4 and ListenIPv6 options are still recognized,
but ngircd will print a warning if they are used in the config file.
ngIRCd 0.12.0 (2008-05-13)
- Fix Bug: 85: "WHO #SecretChannel" that user is not a member of now returns
proper RPL_ENDOFWHO_MSG instead of nothing. (Ali Shemiran)
- Fix complie on FreeBSD 5.4 and AIX.
- If bind() fails, also print ip address and not just the port number.
ngIRCd 0.12.0-pre2 (2008-04-29)
- IPv6: Add config options to disabe ipv4/ipv6 support.
- Don't include doc/CVS.txt in distribution archive, use doc/GIT.txt now!
- Documentation: get rid of some more references to CVS, switch to GIT.
- Get rid of cvs-version.* and CVSDATE definition.
- Report ERR_NOTONCHANNEL when trying to part a channel one is not member of.
- Testsuite: remove erroneous ConfUID setting in config file.
ngIRCd 0.12.0-pre1 (2008-04-20)
- Include Mac OS X Xcode project in distribution archives.
- Do not exit on SIGHUP or /REHASH if the config file cannot opened.
- Add IPv6 support.
- Install a LaunchDaemon script to start/stop ngIRCd on Mac OS X.
- Implemented IRC commands INFO, SUMMON (dummy), and USERS (dummy) and
enhanced test suite to check these commands. (Dana Dahlstrom)
- RPL_WHOREPLY messages generated by IRC_WHO didn't include flags (*,@,+).
(Dana Dahlstrom)
- IRC_WHO now supports search patterns and will test this against user
nickname/servername/hostname, etc. as required by RFC 2812, Section 3.6.1.
(reported by Dana Dahlstrom)
- Add test cases for "WHO" command. (Dana Dahlstrom)
- Implement RFC 2812 handling of "0" argument to 'JOIN': must be treated
as if the user had sent PART commands for all channels the user is a
member of. (Dana Dahlstrom)
- Allow NOTICEs to be sent to a channel. (Fabian Schlager)
ngIRCd 0.11.1 (2008-02-26)
- Fix sending of JOIN commands between servers when remote server appended
mode flags. (Rolf Eike Beer) [from HEAD]
- Send "G" instead of "H" flag in WHO replies. (reported by Dana Dahlstrom)
- Under some circumstances ngIRCd issued channel MODE message with a
trailing space. (Dana Dahlstrom) [from HEAD]
ngIRCd 0.11.0 (2008-01-15)
ngIRCd 0.11.0-pre2 (2008-01-07)
- SECURITY: IRC_PART could reference invalid memory, causing
ngircd to crash [from HEAD]. (CVE-2008-0285)
ngIRCd 0.11.0-pre1 (2008-01-02)
- Use dotted-decimal IP address if hostname is >= 64.
- Add support for /STAT u (server uptime) command.
- New [Server] configuration Option "Bind" allows to specify
the source ip adress to use when connecting to remote server.
- New configuration option "MaxNickLength" to specify the allowed maximum
length of user nick names. Note: must be unique in an IRC network!
- Enhanced the IRC+ protocol to support an enhanced "server handshake" and
enable server to recognice numeric 005 (ISUPPORT) and 376 (ENDOFMOTD).
See doc/Protocol.txt for details.
- Re-added doc/SSL.txt to distribution -- got lost somewhere!?
- Fixes the wrong logging output when nested servers are introduced
to the network as well as the wrong output of the LINKS command.
- Update Mac OS X Xcode project file for Xcode 3.
- Adjust test suite to be usable on HP/UX 11.11 :-)
- Fix code to compile using K&R C compiler and ansi2kr again.
- New config option NoDNS: Disables DNS lookups when clients connect.
- Fixed propagation of channel mode 'P' on server links.
- Numeric 317: implemented "signon time" (displayed in WHOIS result).
- Fixed code that prevented GCC 2.95 to compile ngIRCd.
- Adjust path names in manual pages according to "./configure" settings.
- Added new server configuration option "Passive" for "Server" blocks to
disable automatic outgoing connections (similar to -p option to ngircd,
but only for the specified server). (Tassilo Schweyer)
- Don't connect to a server if a connection to another server within the
same group is already in progress.
- Added support for the WALLOPS command. Usage is restricted to IRC
operators.
ngIRCd 0.10.4 (2008-01-07)
- SECURITY: IRC_PART could reference invalid memory, causing
ngircd to crash [from HEAD]. (CVE-2008-0285)
ngIRCd 0.10.3 (2007-08-01)
- SECURITY: Fixed a severe bug in handling JOIN commands, which could
cause the server to crash. Thanks to Sebastian Vesper, <net@veoson.net>.
(CVE-2007-6062)
ngIRCd 0.10.2 (2007-06-08)
ngIRCd 0.10.2-pre2 (2007-05-19)
- Server links are allowed to use larger write buffers now (up to 50 KB).
ngIRCd 0.10.2-pre1 (2007-05-05)
- Fix compressed server links (broken since 0.10.0).
- Predefined Channel configuration now allows specification of channel key
(mode k) and maximum user count (mode l).
- When using epoll() IO interface, compile in the select() interface as
well and fall back to it when epoll() isn't available on runtime.
- New configure option "--without-select" to disable select() IO API
(even when using epoll(), see above).
- Added support for IO APIs "poll()" and "/dev/poll".
- Reorganized internal handling of invite and ban lists.
ngIRCd 0.10.1 (2006-12-17)
- Fixed validation of server names containing digits.
- Update the "info text" of the local server after re-reading configuration.
- Changed Numerics 265 and 266 to follow ircd 2.11.x "standards".
- Allow PASS syntax defined in RFC 1459 for server links, too.
- Enhanced ISUPPORT message (005 numeric).
- New configuration option "PredefChannelsOnly": if set, clients can only
join predefined channels.
- Code cleanups: use "LogDebug(...)" instead of "Log(LOG_DEBUG, ...)", use
"strcspn()", unsigned vs. signed, use "const", fix whitespaces, ...
ngIRCd 0.10.0 (2006-10-01)
- Fixed file handle leak when daemon is not able to send MOTD to a client.
ngIRCd 0.10.0-pre2 (2006-09-09)
- Fixed build problems with GCC option -fstack-protector.
- Minor documentation updates.
ngIRCd 0.10.0-pre1 (2006-08-02)
- Validate "ServerName" (see RFC 2812, section 2.3.1).
- Enhanced DIE to accept a single parameter ("comment text") which is sent
to all locally connected clients before the server goes down.
@@ -108,13 +275,13 @@ ngIRCd 0.8.3 (2005-02-03)
- Fixed a bug that could case a root exploit when the daemon is compiled
to do IDENT lookups and is logging to syslog. Bug discovered by CoKi,
<coki@nosystem.com.ar>, thanks a lot!
(http://www.nosystem.com.ar/advisories/advisory-11.txt)
(CVE-2005-0226; http://www.nosystem.com.ar/advisories/advisory-11.txt)
ngIRCd 0.8.2 (2005-01-26)
- Added doc/SSL.txt to distribution.
- Fixed a buffer overflow that could cause the daemon to crash. Bug found
by Florian Westphal, <westphal@foo.fh-furtwangen.de>.
by Florian Westphal, <westphal@foo.fh-furtwangen.de>. (CVE-2005-0199)
- Fixed a possible buffer underrun when reading the MOTD file. Thanks
to Florian Westphal, <westphal@foo.fh-furtwangen.de>.
- Fixed detection of IRC lines which are too long to send. Detected by
@@ -651,7 +818,3 @@ ngIRCd 0.0.2, 06.01.2002
ngIRCd 0.0.1, 31.12.2001
- erste oeffentliche Version von ngIRCd als "public preview" :-)
--
$Id: ChangeLog,v 1.302 2006/07/23 16:42:45 alex Exp $

24
INSTALL
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2004 by Alexander Barton,
(c)2001-2007 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -51,9 +51,9 @@ on modern UNIX-like systems that are supported by GNU autoconf and GNU
automake ("configure") should be no problem.
The normal installation procedure after getting (and expanding) the source
files (using a distribution archive or CVS) is as following:
files (using a distribution archive or GIT) is as following:
1) ./autogen.sh [only necessary when using CVS]
1) ./autogen.sh [only necessary when using GIT]
2) ./configure
3) make
4) make install
@@ -77,7 +77,7 @@ doc/ directory: sample-ngircd.conf.
The first step, autogen.sh, is only necessary if the configure-script isn't
already generated. This never happens in official ("stable") releases in
tar.gz-archives, but when using CVS.
tar.gz-archives, but when using GIT.
This step is therefore only interesting for developers.
@@ -149,14 +149,20 @@ standard locations.
The Z compression library ("libz") is required for this option.
* IO Backend (autodetected by default):
--with-select[=<path>] / --without-select
--with-poll[=<path>] / --without-poll
--with-devpoll[=<path>] / --without-devpoll
--with-epoll[=<path>] / --without-epoll
--with-kqueue[=<path>] / --without-kqueue
ngIRCd can use three different IO "backends": the "old school" select()
ngIRCd can use different IO "backends": the "old school" select() and poll()
API which should be supported by most UNIX-like operating systems, or the
more efficient and flexible epoll() (Linux 2.6) or kqueue() (BSD) APIs.
more efficient and flexible epoll() (Linux >=2.6), kqueue() (BSD) and
/dev/poll APIs.
By default the IO backend is autodetected, but you can use "--without-xxx"
to disable a more enhanced API and force the daemon to use select().
to disable a more enhanced API.
When using the epoll() API, support for select() is compiled in as well by
default to enable the binary to run on older Linux kernels (<2.6), too.
* IDENT-Support:
--with-ident[=<path>]
@@ -238,7 +244,3 @@ These parameters could be passed to the ngIRCd:
Use "--help" to see a short help text describing all available parameters
the server understands, with "--version" the ngIRCd shows its version
number. In both cases the server exits after the output.
--
$Id: INSTALL,v 1.23 2005/12/30 22:43:23 alex Exp $

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -8,8 +8,6 @@
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
# $Id: Makefile.am,v 1.17 2005/07/22 21:01:52 alex Exp $
#
AUTOMAKE_OPTIONS = gnu
@@ -17,6 +15,7 @@ SUBDIRS = doc src man contrib
clean-local:
rm -f build-stamp*
rm -rf ngircd.dest
maintainer-clean-local:
rm -rf autom4te.cache
@@ -24,6 +23,9 @@ maintainer-clean-local:
rm -f mkinstalldirs missing depcomp install-sh
rm -f config.log debian
testsuite:
make -C src/testsuite check
lint:
make -C src/ngircd lint
@@ -31,9 +33,10 @@ srcdoc:
make -C doc srcdoc
xcode:
@xcodebuild -project contrib/MacOSX/ngIRCd.xcode -list >/dev/null 2>&1 \
@xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -list \
>/dev/null 2>&1 \
|| ( echo; echo "Error: \"xcodebuild\" not found!"; echo; exit 1 )
xcodebuild -project contrib/MacOSX/ngIRCd.xcode -alltargets \
xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -alltargets \
-buildstyle Development
rpm: distcheck
@@ -41,6 +44,29 @@ rpm: distcheck
deb:
[ -f debian/rules ] || ln -s contrib/Debian debian
dpkg-buildpackage -rfakeroot
dpkg-buildpackage -rfakeroot -i
osxpkg:
@packagemaker >/dev/null 2>&1; [ $$? -ge 1 ] \
|| ( echo; echo "Error: \"packagemaker\" not found!"; echo; exit 2)
make clean
./configure --prefix=/opt/ngircd
make xcode
make -C contrib/MacOSX de.barton.ngircd.plist
mkdir -p ngircd.dest/opt/ngircd/sbin
DESTDIR="$$PWD/ngircd.dest" make -C doc install
DESTDIR="$$PWD/ngircd.dest" make -C contrib install
DESTDIR="$$PWD/ngircd.dest" make -C man install
cp contrib/MacOSX/build/Default/ngIRCd \
ngircd.dest/opt/ngircd/sbin/ngircd
rm ngircd.dest/opt/ngircd/etc/ngircd.conf
echo "Have a nice day IRCing!" >ngircd.dest/opt/ngircd/etc/ngircd.motd
chmod -R a-s,og-w,a+rX ngircd.dest
cd contrib/MacOSX && packagemaker \
--doc ngIRCd.pmdoc \
--out ../../$(distdir).mpkg
rm -f $(distdir).mpkg.zip
zip -ro9 $(distdir).mpkg.zip $(distdir).mpkg
rm -rf ngircd.dest $(distdir).mpkg
# -eof-

94
NEWS
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2005 Alexander Barton,
(c)2001-2008 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -10,6 +10,96 @@
-- NEWS --
ngIRCd Release 13 (2008-12-25)
ngIRCd 13~rc1 (2008-11-21):
- New version numer scheme :-)
- Initial support for IRC services, using a RFC1459 styel interface,
tested with IRCServices (http://www.ircservices.za.net/) version 5.1.13.
For this to work, ngIRCd now supports server-server links conforming
to RFC 1459. New ngircd.conf(5) option: ServiceMask.
- Support for SSL-encrypted server-server and client-server links using
OpenSSL (configure: --with-openssl) or GNUTLS (configure: --with-gnutls).
New ngircd.conf(5) options: SSLPorts, SSLKeyFile, SSLKeyFilePassword,
SSLCertFile, SSLDHFile, and SSLConnect.
- Server local channels have been implemented, prefix "&", that are only
visible to users of the same server and are not visible in the network.
In addition ngIRCd creates a "special" channel &SERVER on startup and logs
all the messages to it that a user with mode +s receives.
- New make target "osxpkg" to build a Mac OS X installer package.
- New configuration option "NoIdent" to disable IDENT lookups even if the
daemon is compiled with IDENT support.
ngIRCd 0.12.1 (2008-07-09)
- Add option aliases -V (for --version) and -h (for --help).
- Make Listen parameter a comma-seperated list of addresses. This also
obsoletes ListenIPv4 and ListenIPv6 options. If Listen is unset, it
is treated as Listen="::,0.0.0.0".
Note: ListenIPv4 and ListenIPv6 options are still recognized,
but ngircd will print a warning if they are used in the config file.
ngIRCd 0.12.0 (2008-05-13)
ngIRCd 0.12.0-pre2 (2008-04-29)
- IPv6: Add config options to disabe ipv4/ipv6 support.
ngIRCd 0.12.0-pre1 (2008-04-20)
- Add IPv6 support.
- Install a LaunchDaemon script to start/stop ngIRCd on Mac OS X.
- Implemented IRC commands INFO, SUMMON (dummy), and USERS (dummy) and
enhanced test suite to check these commands. (Dana Dahlstrom)
- IRC_WHO now supports search patterns and will test this against user
nickname/servername/hostname, etc. as required by RFC 2812, Section 3.6.1.
(reported by Dana Dahlstrom)
- Implement RFC 2812 handling of "0" argument to 'JOIN': must be treated
as if the user had sent PART commands for all channels the user is a
member of. (Dana Dahlstrom)
- Allow NOTICEs to be sent to a channel. (Fabian Schlager)
ngIRCd 0.11.0 (2008-01-15)
- Add support for /STAT u (server uptime) command.
- New [Server] configuration Option "Bind" allows to specify
the source ip adress to use when connecting to remote server.
- New configuration option "MaxNickLength" to specify the allowed maximum
length of user nick names. Note: must be unique in an IRC network!
- Numeric 317: implemented "signon time" (displayed in WHOIS result).
- Added new server configuration option "Passive" for "Server" blocks to
disable automatic outgoing connections (similar to -p option to ngircd,
but only for the specified server). (Tassilo Schweyer)
- Added support for the WALLOPS command. Usage is restricted to IRC
operators.
ngIRCd 0.10.2 (2007-06-08)
- Predefined channel configuration now allows specification of channel key
(mode k) and maximum user count (mode l): variables "Key" and "MaxUsers".
- When using the epoll() IO interface, compile in the select() interface as
well and fall back to it when epoll() isn't available on runtime.
- Added support for IO APIs "poll()" and "/dev/poll".
ngIRCd 0.10.1 (2006-12-17)
- Allow PASS syntax defined in RFC 1459 for server links, too.
- New configuration option "PredefChannelsOnly": if set, clients can only
join predefined channels.
ngIRCd 0.10.0 (2006-10-01)
ngIRCd 0.10.0-pre1 (2006-08-02)
- Enhanced DIE to accept a single parameter ("comment text") which is sent
to all locally connected clients before the server goes down.
- JOIN now supports more than one channel key at a time.
- Implemented numeric "333": Time and user name who set a channel topic.
- Channel topics are no longer limited to 127 characters: now the only limit
is the maximum length of an IRC command, i. e. 512 bytes (in practice, this
limits the topic to about 490 characters due to protocol overhead).
- Reverse DNS lookup code now checks the result by doing an additional
lookup to prevent spoofing.
- Added new IO layer which (optionally) supports epoll() and kqueue() in
addition to the select() interface.
ngIRCd 0.9.0 (2005-07-24)
- Never run with root privileges but always switch the user ID.
@@ -208,4 +298,4 @@ ngIRCd 0.0.1, 31.12.2001
--
$Id: NEWS,v 1.75 2005/07/26 19:41:49 alex Exp $
$Id: NEWS,v 1.88 2008/02/26 22:05:42 fw Exp $

20
README
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2005 Alexander Barton,
(c)2001-2007 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -19,6 +19,8 @@ Licence (URL: http://www.gnu.org/licenses/gpl.html). ngIRCd means "next
generation IRC daemon", it's written from scratch and not deduced from the
"grandfather of IRC daemons", the daemon of the IRCNet.
Please see the INSTALL document for installation and upgrade information!
II. Status
~~~~~~~~~~~
@@ -35,7 +37,8 @@ Implemented IRC-commands are:
ADMIN, AWAY, CHANINFO, CONNECT, DIE, DISCONNECT, ERROR, HELP, INVITE, ISON,
JOIN, KICK, KILL, LINKS, LIST, LUSERS, MODE, MOTD, NAMES, NICK, NJOIN, NOTICE,
OPER, PART, PASS, PING, PONG, PRIVMSG, QUIT, REHASH, RESTART, SERVER, SQUIT,
STATS, TIME, TOPIC, TRACE, USER, USERHOST, VERSION, WHO, WHOIS, WHOWAS.
STATS, TIME, TOPIC, TRACE, USER, USERHOST, VERSION, WALLOPS, WHO, WHOIS,
WHOWAS.
III. Features (or: why use ngIRCd?)
@@ -64,9 +67,9 @@ the newest information about the ngIRCd and the most recent ("stable")
releases there.
If you are interested in the latest development versions (which are not
always stable), then please read the section "CVS" on the homepage and
the file "doc/CVS.txt" which describes the use of CVS, the "Concurrent
Versioning System".
always stable), then please read the section about "GIT" on the homepage and
the file "doc/GIT.txt" which describes the use of GIT, the version control
system used by ngIRCd (homepage: http://git.or.cz/).
VI. Bugs
@@ -80,8 +83,5 @@ them at the following URL:
There you can read about known bugs and limitations, too.
If you have critics, patches or something else, please feel free to post a
mail to <alex@barton.de>.
--
$Id: README,v 1.21 2005/07/09 14:39:42 alex Exp $
mail to the ngIRCd mailing list: <ngircd-ml@arthur.ath.cx> (please see
<http://ngircd.barton.de/#ml> for details).

View File

@@ -1,7 +1,7 @@
#!/bin/sh
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2004 Alexander Barton <alex@barton.de>
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -9,11 +9,8 @@
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
# $Id: autogen.sh,v 1.14 2005/02/21 15:23:23 alex Exp $
#
#
# Usage: [VAR=<value>] ./autogen.sh [<configure-args>]
# Usage:
# [VAR=<value>] ./autogen.sh [<configure-args>]
#
# This script generates the ./configure script using GNU automake and
# GNU autoconf. It tries to be smart in finding the correct/usable/available
@@ -124,17 +121,8 @@ if [ -z "$EXIST" ]; then
fi
[ "$VERBOSE" = "1" ] && echo "Using \"$EXIST\" to test for tools."
# We want to use GNU automake 1.7, if available (WANT_AUTOMAKE is used by
# the wrapper scripts of Gentoo Linux, AUTOMAKE_VERSION is used by OpenBSD);
# same applies for GNU autoconf, we want to use version 2.59.
AUTOMAKE_VERSION=1.7
AUTOCONF_VERSION=2.59
export AUTOMAKE_VERSION AUTOCONF_VERSION
WANT_AUTOMAKE=1.7
export WANT_AUTOMAKE
# Try to detect the needed tools when no environment variable already
# spezifies one:
# specifies one:
echo "Searching tools ..."
[ -z "$ACLOCAL" ] && ACLOCAL=`Search aclocal 1`
[ "$VERBOSE" = "1" ] && echo "ACLOCAL=$ACLOCAL"
@@ -150,12 +138,12 @@ echo "Searching tools ..."
[ -z "$GO" -a $# -gt 0 ] && GO=1
# Verify that all tools have been found
[ -z "$AUTOCONF" ] && Notfound autoconf
[ -z "$ACLOCAL" ] && Notfound aclocal
[ -z "$AUTOHEADER" ] && Notfound autoheader
[ -z "$AUTOMAKE" ] && Notfound automake
[ -z "$AUTOCONF" ] && Notfound autoconf
export AUTOCONF AUTOHEADER AUTOMAKE AUTOCONF
export ACLOCAL AUTOHEADER AUTOMAKE AUTOCONF
# Generate files
echo "Generating files ..."

69
config.guess vendored
View File

@@ -1,9 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
timestamp='2006-02-23'
timestamp='2008-01-23'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -55,8 +56,8 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -160,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
@@ -210,7 +212,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
exit ;;
macppc:MirBSD:*:*)
echo powerppc-unknown-mirbsd${UNAME_RELEASE}
echo powerpc-unknown-mirbsd${UNAME_RELEASE}
exit ;;
*:MirBSD:*:*)
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
@@ -328,7 +330,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
i86pc:SunOS:5.*:*)
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
@@ -530,7 +532,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
*:AIX:*:[45])
*:AIX:*:[456])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@@ -770,6 +772,8 @@ EOF
case ${UNAME_MACHINE} in
pc98)
echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
@@ -777,10 +781,7 @@ EOF
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
i*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:MSYS_NT-*:*:*)
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:windows32*:*)
@@ -790,12 +791,18 @@ EOF
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
x86:Interix*:[345]*)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
EM64T:Interix*:[345]*)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
*:Interix*:[3456]*)
case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
EM64T | authenticamd)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
IA64)
echo ia64-unknown-interix${UNAME_RELEASE}
exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
@@ -829,6 +836,16 @@ EOF
echo ${UNAME_MACHINE}-pc-minix
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
echo ${UNAME_MACHINE}-unknown-linux-gnu
else
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
cris:Linux:*:*)
@@ -947,6 +964,9 @@ EOF
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
@@ -989,7 +1009,7 @@ EOF
LIBC=gnulibc1
# endif
#else
#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun)
#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
LIBC=gnu
#else
LIBC=gnuaout
@@ -1205,6 +1225,15 @@ EOF
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit ;;
SX-7:SUPER-UX:*:*)
echo sx7-nec-superux${UNAME_RELEASE}
exit ;;
SX-8:SUPER-UX:*:*)
echo sx8-nec-superux${UNAME_RELEASE}
exit ;;
SX-8R:SUPER-UX:*:*)
echo sx8r-nec-superux${UNAME_RELEASE}
exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
@@ -1455,9 +1484,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be

112
config.sub vendored
View File

@@ -1,9 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
timestamp='2006-02-23'
timestamp='2008-01-16'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -71,8 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -240,15 +241,16 @@ case $basic_machine in
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| fr30 | frv \
| fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
@@ -274,21 +276,19 @@ case $basic_machine in
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
| score \
| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b \
| strongarm \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
| z8k)
basic_machine=$basic_machine-unknown
;;
m32c)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12.
basic_machine=$basic_machine-unknown
@@ -318,18 +318,18 @@ case $basic_machine in
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* \
| avr-* | avr32-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| m32r-* | m32rle-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
@@ -358,22 +358,24 @@ case $basic_machine in
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
| xstormy16-* | xtensa-* \
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
| xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-*)
;;
m32c-*)
# Recognize the basic CPU types without company name, with glob match.
xtensa*)
basic_machine=$basic_machine-unknown
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -445,6 +447,14 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
blackfin)
basic_machine=bfin-unknown
os=-linux
;;
blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
c90)
basic_machine=c90-cray
os=-unicos
@@ -477,8 +487,8 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
cr16c)
basic_machine=cr16c-unknown
cr16)
basic_machine=cr16-unknown
os=-elf
;;
crds | unos)
@@ -670,6 +680,14 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
;;
m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -685,6 +703,10 @@ case $basic_machine in
basic_machine=i386-pc
os=-mingw32
;;
mingw32ce)
basic_machine=arm-unknown
os=-mingw32ce
;;
miniframe)
basic_machine=m68000-convergent
;;
@@ -811,6 +833,14 @@ case $basic_machine in
basic_machine=i860-intel
os=-osf
;;
parisc)
basic_machine=hppa-unknown
os=-linux
;;
parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
pbd)
basic_machine=sparc-tti
;;
@@ -912,6 +942,10 @@ case $basic_machine in
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sde)
basic_machine=mipsisa32-sde
os=-elf
;;
sei)
basic_machine=mips-sei
os=-seiux
@@ -923,6 +957,9 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sh5el)
basic_machine=sh5le-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
@@ -1012,6 +1049,10 @@ case $basic_machine in
basic_machine=tic6x-unknown
os=-coff
;;
tile*)
basic_machine=tile-unknown
os=-linux-gnu
;;
tx39)
basic_machine=mipstx39-unknown
;;
@@ -1128,7 +1169,7 @@ case $basic_machine in
sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b)
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
basic_machine=sparc-sun
;;
cydra)
@@ -1217,7 +1258,7 @@ case $os in
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos*)
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1369,6 +1410,12 @@ else
# system, and we'll never get to this point.
case $basic_machine in
score-*)
os=-elf
;;
spu-*)
os=-elf
;;
*-acorn)
os=-riscix1.2
;;
@@ -1378,9 +1425,9 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
;;
c4x-* | tic4x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
@@ -1406,6 +1453,9 @@ case $basic_machine in
m68*-cisco)
os=-aout
;;
mep-*)
os=-elf
;;
mips*-cisco)
os=-elf
;;

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2005 Alexander Barton <alex@barton.de>
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -8,13 +8,11 @@
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
# $Id: configure.in,v 1.118 2006/05/17 16:44:14 alex Exp $
#
# -- Initialisation --
AC_PREREQ(2.50)
AC_INIT(ngircd, CVSHEAD)
AC_INIT(ngircd, 13)
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE(1.6)
@@ -30,6 +28,7 @@ AH_TEMPLATE([SYSLOG], [Define if syslog should be used for logging])
AH_TEMPLATE([ZLIB], [Define if zlib compression should be enabled])
AH_TEMPLATE([TCPWRAP], [Define if TCP wrappers should be used])
AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used])
AH_TEMPLATE([WANT_IPV6], [Define if IPV6 protocol should be enabled])
AH_TEMPLATE([ZEROCONF], [Define if support for Zeroconf should be included])
AH_TEMPLATE([IDENTAUTH], [Define if the server should do IDENT requests])
@@ -53,33 +52,33 @@ AC_PROG_RANLIB
AM_C_PROTOTYPES
AC_C_CONST
AC_C_INLINE
# -- Hard coded system and compiler dependencies/features/options ... --
AC_DEFUN([GCC_STACK_PROTECT_CC],[
ssp_cc=yes
# we use -fstack-protector-all for the test to enfoce the use of the guard variable
AC_MSG_CHECKING([whether ${CC} accepts -fstack-protector])
ssp_old_cflags="$CFLAGS"
CFLAGS="$CFLAGS -fstack-protector-all"
AC_TRY_LINK(,,, ssp_cc=no)
echo $ssp_cc
CFLAGS="$ssp_old_cflags"
if test "X$ssp_cc" = "Xyes"; then
CFLAGS="$CFLAGS -fstack-protector"
AC_DEFINE([ENABLE_SSP_CC], 1, [Define if SSP C support is enabled.])
fi
])
if test "$GCC" = "yes"; then
# We are using the GNU C compiler. Good!
CFLAGS="$CFLAGS -pipe -W -Wall -Wpointer-arith -Wstrict-prototypes"
GCC_STACK_PROTECT_CC
fi
AC_DEFUN([GCC_STACK_PROTECT_CC],[
ssp_cc=yes
if test "X$CC" != "X"; then
AC_MSG_CHECKING([whether ${CC} accepts -fstack-protector])
ssp_old_cflags="$CFLAGS"
CFLAGS="$CFLAGS -fstack-protector"
AC_TRY_COMPILE(,,, ssp_cc=no)
echo $ssp_cc
if test "X$ssp_cc" = "Xno"; then
CFLAGS="$ssp_old_cflags"
else
AC_DEFINE([ENABLE_SSP_CC], 1, [Define if SSP C support is enabled.])
fi
fi
])
GCC_STACK_PROTECT_CC
case "$target_os" in
hpux*)
# This is HP/UX, we need to define _XOPEN_SOURCE_EXTENDED
@@ -137,18 +136,15 @@ AC_FUNC_FORK
AC_FUNC_STRFTIME
AC_CHECK_FUNCS([ \
bind gethostbyaddr gethostbyname gethostname inet_ntoa malloc memmove \
memset realloc setsid setsockopt socket strcasecmp strchr strerror \
strstr waitpid],,AC_MSG_ERROR([required function missing!]))
bind gethostbyaddr gethostbyname gethostname inet_ntoa \
setsid setsockopt socket strcasecmp waitpid],,AC_MSG_ERROR([required function missing!]))
AC_CHECK_FUNCS(inet_aton isdigit sigaction snprintf vsnprintf strdup strlcpy strlcat)
AC_CHECK_FUNCS(select,[AC_CHECK_HEADERS(sys/select.h)],
AC_MSG_ERROR([required function select() is missing!])
)
AC_CHECK_FUNCS(inet_aton isdigit sigaction snprintf vsnprintf strdup strlcpy strlcat strtok_r)
# -- Configuration options --
# use syslog?
x_syslog_on=no
AC_ARG_WITH(syslog,
[ --without-syslog disable syslog (autodetected by default)],
@@ -174,6 +170,8 @@ if test "$x_syslog_on" = "yes"; then
AC_CHECK_HEADERS(syslog.h,,AC_MSG_ERROR([required C header missing!]))
fi
# use zlib compression?
x_zlib_on=no
AC_ARG_WITH(zlib,
[ --without-zlib disable zlib compression (autodetected by default)],
@@ -198,44 +196,166 @@ if test "$x_zlib_on" = "yes"; then
AC_CHECK_HEADERS(zlib.h,,AC_MSG_ERROR([required C header missing!]))
fi
# detect which IO API to use:
x_io_backend=select
AC_ARG_WITH(epoll,
[ --without-epoll disable epoll support (autodetected by default)],
x_io_backend=none
AC_ARG_WITH(select,
[ --without-select disable select IO support (autodetected by default)],
[ if test "$withval" != "no"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS"
fi
AC_CHECK_FUNCS(epoll_create, x_io_backend=epoll,
AC_MSG_ERROR([Can't enable epoll support!])
AC_CHECK_FUNCS(select, x_io_select=yes,
AC_MSG_ERROR([Can't enable select IO support!])
)
fi
],
[
AC_CHECK_FUNCS(epoll_create, x_io_backend=epoll)
AC_CHECK_FUNCS(select, x_io_select=yes)
]
)
AC_ARG_WITH(poll,
[ --without-poll disable poll support (autodetected by default)],
[ if test "$withval" != "no"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS"
fi
AC_CHECK_FUNCS(poll, x_io_backend=poll\(\),
AC_MSG_ERROR([Can't enable poll IO support!])
)
fi
],
[
AC_CHECK_FUNCS(poll, x_io_backend=poll\(\))
]
)
AC_ARG_WITH(devpoll,
[ --without-devpoll disable /dev/poll IO support (autodetected by default)],
[ if test "$withval" != "no"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS"
fi
AC_CHECK_HEADERS(sys/devpoll.h,,AC_MSG_ERROR([required C header missing!]))
fi
],
[
AC_CHECK_HEADERS(sys/devpoll.h, x_io_backend=/dev/poll)
]
)
AC_ARG_WITH(epoll,
[ --without-epoll disable epoll IO support (autodetected by default)],
[ if test "$withval" != "no"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS"
fi
AC_CHECK_FUNCS(epoll_create, x_io_epoll=yes,
AC_MSG_ERROR([Can't enable epoll IO support!])
)
fi
],
[
AC_CHECK_FUNCS(epoll_create, x_io_epoll=yes)
]
)
AC_ARG_WITH(kqueue,
[ --without-kqueue disable kqueue support (autodetected by default)],
[ --without-kqueue disable kqueue IO support (autodetected by default)],
[ if test "$withval" != "no"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS"
fi
AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue,
AC_MSG_ERROR([Can't enable kqueue support!])
AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue\(\),
AC_MSG_ERROR([Can't enable kqueue IO support!])
)
fi
],
[
AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue)
AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue\(\))
]
)
if test "$x_io_epoll" = "yes" -a "$x_io_select" = "yes"; then
# when epoll() and select() are available, we'll use both!
x_io_backend="epoll(), select()"
else
if test "$x_io_epoll" = "yes"; then
# we prefere epoll() if it is available
x_io_backend="epoll()"
else
if test "$x_io_select" = "yes" -a "$x_io_backend" = "none"; then
# we'll use select, when available and no "better"
# interface has been detected ...
x_io_backend="select()"
fi
fi
fi
if test "$x_io_backend" = "none"; then
AC_MSG_ERROR([No useabe IO API activated/found!?])
fi
# use SSL?
AC_ARG_WITH(openssl,
[ --with-openssl enable SSL support using OpenSSL],
[ if test "$withval" = "yes"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS"
fi
AC_CHECK_LIB(crypto, BIO_s_mem)
AC_CHECK_LIB(ssl, SSL_library_init)
AC_CHECK_FUNCS(SSL_library_init, x_ssl_openssl=yes,
AC_MSG_ERROR([Can't enable openssl])
)
fi
]
)
AC_ARG_WITH(gnutls,
[ --with-gnutls enable SSL support using gnutls],
[ if test "$withval" = "yes"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS"
fi
AC_CHECK_LIB(gnutls, gnutls_global_init)
AC_CHECK_FUNCS(gnutls_global_init, x_ssl_gnutls=yes,
AC_MSG_ERROR([Can't enable gnutls])
)
fi
]
)
x_ssl_lib="no"
if test "$x_ssl_gnutls" = "yes"; then
if test "$x_ssl_openssl" = "yes";then
AC_MSG_ERROR([Cannot enable both gnutls and openssl])
fi
x_ssl_lib=gnutls
fi
if test "$x_ssl_openssl" = "yes"; then
x_ssl_lib=openssl
fi
# use TCP wrappers?
x_tcpwrap_on=no
AC_ARG_WITH(tcp-wrappers,
@@ -266,6 +386,8 @@ int deny_severity = 0;
]
)
# include support for "zeroconf"?
x_zeroconf_on=no
AC_ARG_WITH(zeroconf,
[ --with-zeroconf enable support for "Zeroconf"],
@@ -314,6 +436,8 @@ if test "$x_zeroconf_on" = "howl"; then
AC_DEFINE(ZEROCONF, 1)
fi
# do IDENT requests using libident?
x_identauth_on=no
AC_ARG_WITH(ident,
[ --with-ident enable "IDENT" ("AUTH") protocol support],
@@ -335,6 +459,8 @@ if test "$x_identauth_on" = "yes"; then
AC_CHECK_HEADERS(ident.h,,AC_MSG_ERROR([required C header missing!]))
fi
# compile in IRC+ protocol support?
x_ircplus_on=yes
AC_ARG_ENABLE(ircplus,
[ --disable-ircplus disable IRC+ protocol],
@@ -344,6 +470,21 @@ if test "$x_ircplus_on" = "yes"; then
AC_DEFINE(IRCPLUS, 1)
fi
# enable support for IPv6?
x_ipv6_on=no
AC_ARG_ENABLE(ipv6,
[ --enable-ipv6 enable IPv6 protocol support],
if test "$enableval" = "yes"; then x_ipv6_on=yes; fi
)
if test "$x_ipv6_on" = "yes"; then
AC_CHECK_FUNCS([ \
getaddrinfo getnameinfo \
],,AC_MSG_ERROR([required function missing for IPv6 support!]))
AC_DEFINE(WANT_IPV6, 1)
fi
# compile in IRC "sniffer"?
x_sniffer_on=no; x_debug_on=no
AC_ARG_ENABLE(sniffer,
[ --enable-sniffer enable IRC traffic sniffer (enables debug mode)],
@@ -353,6 +494,8 @@ AC_ARG_ENABLE(sniffer,
fi
)
# enable additional debugging code?
AC_ARG_ENABLE(debug,
[ --enable-debug show additional debug output],
if test "$enableval" = "yes"; then x_debug_on=yes; fi
@@ -360,8 +503,11 @@ AC_ARG_ENABLE(debug,
if test "$x_debug_on" = "yes"; then
AC_DEFINE(DEBUG, 1)
test "$GCC" = "yes" && CFLAGS="-pedantic $CFLAGS"
AC_CHECK_FUNCS(mtrace)
fi
# enable "strict RFC rules"?
x_strict_rfc_on=no
AC_ARG_ENABLE(strict-rfc,
[ --enable-strict-rfc strict RFC conformance -- may break clients!],
@@ -389,6 +535,7 @@ AC_OUTPUT([ \
doc/src/Makefile \
src/Makefile \
src/portab/Makefile \
src/ipaddr/Makefile \
src/tool/Makefile \
src/ngircd/Makefile \
src/testsuite/Makefile \
@@ -396,6 +543,8 @@ AC_OUTPUT([ \
contrib/Makefile \
contrib/Debian/Makefile \
contrib/MacOSX/Makefile \
contrib/MacOSX/ngIRCd.xcodeproj/Makefile \
contrib/MacOSX/ngIRCd.pmdoc/Makefile \
])
type dpkg >/dev/null 2>&1
@@ -482,7 +631,13 @@ test "$x_identauth_on" = "yes" \
&& echo $ECHO_N "yes $ECHO_C" \
|| echo $ECHO_N "no $ECHO_C"
echo $ECHO_N " I/O backend: $ECHO_C"
echo "\"$x_io_backend()\""
echo "\"$x_io_backend\""
echo $ECHO_N " IPv6 protocol: $ECHO_C"
echo $ECHO_N "$x_ipv6_on $ECHO_C"
echo $ECHO_N " SSL support: $ECHO_C"
echo "$x_ssl_lib"
echo

9
contrib/Debian/.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
*.log
*.debhelper
*.substvars
files
ngircd/
ngircd-full/
ngircd-full.default
ngircd-full.init
ngircd-full.postinst

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -8,11 +8,9 @@
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
# $Id: Makefile.am,v 1.4 2004/05/11 00:32:31 alex Exp $
#
EXTRA_DIST = rules changelog compat control copyright \
ngircd.init ngircd.postinst
ngircd.init ngircd.default ngircd.postinst
maintainer-clean-local:
rm -f Makefile Makefile.in

View File

@@ -1,3 +1,103 @@
ngircd (13-0ab1) unstable; urgency=low
* New "upstream" release: ngIRCd 13.
-- Alexander Barton <alex@barton.de> Thu, 25 Dec 2008 23:09:58 +0100
ngircd (13~rc1-0ab1) unstable; urgency=low
* New "upstream" release candidate 1 for ngIRCd Release 13.
-- Alexander Barton <alex@barton.de> Fri, 21 Nov 2008 22:04:41 +0100
ngircd (0.12.1-0ab1+dev) unstable; urgency=low
* Update package for testing the new "upstream" features:
- Support for IRC services (see http://www.ircservices.za.net),
- Encrypted connections using GNU TLS (ngircd-full),
- Support for the IPv6 protocol (ngircd-full).
-- Alexander Barton <alex@barton.de> Fri, 03 Oct 2008 16:22:55 +0200
ngircd (0.12.1-0ab1) unstable; urgency=low
* New "upstream" release ngIRCd 0.12.1.
-- Alexander Barton <alex@barton.de> Wed, 9 Jul 2008 11:27:00 +0200
ngircd (0.12.0-0ab1) unstable; urgency=low
* New "upstream" release ngIRCd 0.12.0.
-- Alexander Barton <alex@barton.de> Tue, 13 May 2008 12:30:31 +0200
ngircd (0.12.0-0ab0-pre2) unstable; urgency=low
* Second prerelease of upcoming new "upstrem" release 0.12.0-pre1.
-- Alexander Barton <alex@barton.de> Tue, 29 Apr 2008 23:06:14 +0200
ngircd (0.12.0-0ab0-pre1) unstable; urgency=low
* Prereloease of upcoming new "upstrem" release 0.12.0-pre1.
-- Alexander Barton <alex@barton.de> Sun, 20 Apr 2008 15:43:34 +0200
ngircd (0.11.0-0ab0-pre2) unstable; urgency=low
* Second prerelease of upcoming new "upstream release".
-- Alexander Barton <alex@barton.de> Mon, 7 Jan 2008 15:32:42 +0100
ngircd (0.11.0-0ab0-pre1) unstable; urgency=low
* Prerelease of upcoming new "upstream release".
-- Alexander Barton <alex@barton.de> Wed, 2 Jan 2008 21:33:15 +0100
ngircd (0.10.4-0ab1) unstable; urgency=high
* New "upstream" release: 0.10.4 - fixing a security bug.
-- Alexander Barton <alex@barton.de> Mon, 7 Jan 2008 22:04:44 +0100
ngircd (0.10.0-0ab1) unstable; urgency=low
* New "upstream" release: 0.10.0
-- Alexander Barton <alex@barton.de> Sun, 1 Oct 2006 18:14:21 +0200
ngircd (0.10.0-0ab0-pre2-1) unstable; urgency=low
* Bumped standards version to 3.7.2.1.
* Added "Provides: ircd" to Debian control file.
-- Alexander Barton <alex@barton.de> Sun, 1 Oct 2006 16:25:33 +0200
ngircd (0.10.0-0ab0-pre2) unstable; urgency=low
* Second "upstream" prerelease of upcoming 0.10.0 release.
-- Alexander Barton <alex@barton.de> Sat, 9 Sep 2006 20:57:52 +0200
ngircd (0.10.0-0ab0-pre1) unstable; urgency=low
* Prerelease of upcoming new "upstream release".
-- Alexander Barton <alex@barton.de> Wed, 2 Aug 2006 12:01:07 +0200
ngircd (0.9.2-0ab1) unstable; urgency=low
* New "upstream release" fixing a few bugs in 0.9.1.
-- Alexander Barton <alex@barton.de> Sat, 15 Oct 2005 14:10:34 +0200
ngircd (0.9.1-0ab1) unstable; urgency=medium
* New "upstream release" addressing two problems in ngIRCd 0.9.0.
-- Alexander Barton <alex@barton.de> Wed, 3 Aug 2005 15:10:41 +0200
ngircd (0.9.0-0ab2) unstable; urgency=medium
* Init script: fixed a problem with symbolic links in runlevel directories

View File

@@ -2,19 +2,22 @@ Source: ngircd
Section: net
Priority: optional
Maintainer: Alexander Barton <alex@barton.de>
Build-Depends: debhelper (>> 4.0.0), libz-dev, libwrap-dev, libident-dev
Standards-Version: 3.5.8
Build-Depends: debhelper (>> 4.0.0), libz-dev, libwrap0-dev, libident-dev, libgnutls-dev
Standards-Version: 3.8.0
Package: ngircd
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: ircd
Description: A lightweight daemon for the Internet Relay Chat (IRC)
ngIRCd is a free open source daemon for the Internet Relay Chat (IRC)
network. It is written from scratch and is not based upon the original
IRCd like many others.
.
This package contains the "standard distribution", including support for
syslog logging and compressed server-links using zlib.
syslog logging and compressed server-links using zlib. Please have a look
at the "ngircd-full" package if you need advanced functionality like support
for IPv6 or SSL.
.
Advantages of ngIRCd:
- no problems with servers using changing/non-static IP addresses.
@@ -28,14 +31,16 @@ Description: A lightweight daemon for the Internet Relay Chat (IRC)
Package: ngircd-full
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: ircd
Conflicts: ngircd
Description: A lightweight daemon for the Internet Relay Chat (IRC)
ngIRCd is a free open source daemon for the Internet Relay Chat (IRC)
network. It is written from scratch and is not based upon the original
IRCd like many others.
.
This package includes support for TCP wrappers and IDENT requests in
addition to the features of the "standard package".
In addition to the features of the "standard package", this package
includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
SSL encrypted client and server links.
.
Advantages of ngIRCd:
- no problems with servers using changing/non-static IP addresses.

View File

@@ -1,9 +1,19 @@
#!/bin/sh
#
# ngIRCd start and stop script for Debian-based systems
# Copyright 2008 Alexander Barton <alex@barton.de>
#
# $Id: ngircd.init,v 1.6 2005/07/26 19:37:18 alex Exp $
#
### BEGIN INIT INFO
# Provides: ircd
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Should-Start: $syslog
# Should-Stop: $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Next Generation IRC Server
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/ngircd
@@ -14,54 +24,76 @@ PARAMS=""
test -h "$0" && me=`readlink $0` || me="$0"
BASENAME=`basename $me`
test -f /etc/default/$BASENAME && . /etc/default/$BASENAME
test -r /etc/default/$BASENAME && . /etc/default/$BASENAME
test -x $DAEMON || exit 0
Check_Config()
{
$DAEMON --configtest >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Configuration of $NAME is not valide, won't (re)start!"
echo "Please run \"$DAEMON --configtest\" manually and fix it up ..."
exit 1
fi
# LSB compatibility functions that become used if there is no local
# include file available.
log_daemon_msg() {
echo -n "$*"
}
log_end_msg() {
[ "$1" == "0" ] && echo "." || echo " failed!"
}
log_failure_msg() {
echo "$*"
}
Try_Start()
# Include LSB functions, if available:
test -r /lib/lsb/init-functions && . /lib/lsb/init-functions
Check_Config()
{
[ ! -d /var/run/ircd ] || chown irc:irc /var/run/ircd
start-stop-daemon --start --quiet --exec $DAEMON -- $PARAMS
# Make sure that the configuration of ngIRCd is valid:
$DAEMON --configtest >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "$NAME failed!"
log_failure_msg "Configuration of $NAME is not valid, won't (re)start!"
log_failure_msg "Run \"$DAEMON --configtest\" and fix it up ..."
exit 1
fi
echo "$NAME."
# Make sure the PID file directory exists and is writable:
if [ ! -d /var/run/ircd ]; then
mkdir -p /var/run/ircd
fi
chown irc:irc /var/run/ircd
}
case "$1" in
start)
Check_Config
echo -n "Starting $DESC: "
Try_Start
log_daemon_msg "Starting $DESC" "$NAME"
start-stop-daemon --start \
--quiet --exec $DAEMON -- $PARAMS
log_end_msg $?
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --quiet --pidfile /var/run/ircd/ngircd.pid --exec $DAEMON \
&& echo "$NAME." \
|| echo "(none running)"
log_daemon_msg "Stopping $DESC" "$NAME"
[ -r /var/run/ircd/ngircd.pid ] \
&& PIDFILE="--pidfile /var/run/ircd/ngircd.pid" \
|| PIDFILE=""
start-stop-daemon --stop \
--quiet --oknodo --exec $DAEMON $PIDFILE
log_end_msg $?
;;
reload|force-reload)
Check_Config
echo "Reloading $DESC configuration files."
log_daemon_msg "Reloading $DESC" "$NAME"
start-stop-daemon --stop --signal 1 --quiet --exec $DAEMON
log_end_msg $?
;;
restart)
Check_Config
echo -n "Restarting $DESC: "
start-stop-daemon --stop --quiet --oknodo --exec $DAEMON
log_daemon_msg "Restarting $DESC" "$NAME"
[ -r /var/run/ircd/ngircd.pid ] \
&& PIDFILE="--pidfile /var/run/ircd/ngircd.pid" \
|| PIDFILE=""
start-stop-daemon --stop \
--quiet --oknodo --exec $DAEMON $PIDFILE
sleep 1
Try_Start
start-stop-daemon --start \
--quiet --exec $DAEMON -- $PARAMS
log_end_msg $?
;;
*)
N=/etc/init.d/$NAME

View File

@@ -1,13 +1,20 @@
#!/bin/sh
#
# Debian post-installation script
# $Id: ngircd.postinst,v 1.1 2003/12/31 17:20:11 alex Exp $
# $Id: ngircd.postinst,v 1.2 2006/12/26 14:44:40 alex Exp $
#
if [ -f /etc/ngircd/ngircd.conf ]; then
# make sure that configuration file is not world readable
chmod o= /etc/ngircd/ngircd.conf
fi
set -e
case "$1" in
configure)
if [ -f /etc/ngircd/ngircd.conf ]; then
# make sure that the configuration file is not
# world-readable, it contains passwords!
chmod o= /etc/ngircd/ngircd.conf
fi
;;
esac
#DEBHELPER#

View File

@@ -1,7 +1,7 @@
#!/usr/bin/make -f
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -11,8 +11,6 @@
#
# debian/rules for ngIRCd
#
# $Id: rules,v 1.3 2005/02/07 23:09:31 alex Exp $
#
# Based on the sample debian/rules that uses debhelper,
# GNU copyright 1997 to 1999 by Joey Hess.
#
@@ -54,7 +52,9 @@ configure-ngircd-full: configure
--prefix=/usr \
--sysconfdir=/etc/ngircd \
--mandir=\$${prefix}/share/man \
--with-syslog --with-zlib --with-tcp-wrappers --with-ident
--with-syslog --with-zlib \
--with-gnutls --with-ident --with-tcp-wrappers \
--enable-ipv6
build:
dh_clean -k
@@ -88,7 +88,7 @@ clean:
rm -f $(CURDIR)/debian/ngircd-full.postinst
# Add here commands to clean up after the build process:
-$(MAKE) clean
[ ! -f Makefile ] || $(MAKE) distclean
ifneq "$(wildcard /usr/share/misc/config.sub)" ""
cp -f /usr/share/misc/config.sub config.sub

2
contrib/MacOSX/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
build
de.barton.ngircd.plist

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2004 Alexander Barton <alex@barton.de>
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -8,11 +8,43 @@
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
# $Id: Makefile.am,v 1.2 2004/05/11 00:34:26 alex Exp $
#
SUBDIRS = ngIRCd.xcodeproj ngIRCd.pmdoc
EXTRA_DIST = de.barton.ngircd.plist.tmpl config.h preinstall.sh postinstall.sh
SUFFIXES = .tmpl .
.tmpl:
sed \
-e s@:SBINDIR:@${sbindir}@ \
<$< >$@
install-data-local:
[ `uname -s` != "Darwin" ] || make install-sys-darwin
install-sys-darwin:
@if [ `id -u` -eq 0 ]; then \
make install-sys-darwin-root; \
else \
echo; \
echo " ** NOTE: Not installing with root privileges, so the LaunchDaemon script"; \
echo " ** \"/Library/LaunchDaemons/de.barton.ngircd.plist\" can't be installed/updated!"; \
echo; \
fi
install-sys-darwin-root: de.barton.ngircd.plist
install -d -m 755 -o root -g wheel $(DESTDIR)/Library/LaunchDaemons
install -c -m 644 -b -o root -g wheel de.barton.ngircd.plist \
$(DESTDIR)/Library/LaunchDaemons/de.barton.ngircd.plist
@echo
@echo " ** \"/Library/LaunchDaemons/de.barton.ngircd.plist\" has been installed,"
@echo " ** but is disabled. Use launchctl(8) to enable/run ngIRCd on Darwin/Mac OS X."
@echo
clean-local:
rm -rf build
rm -f de.barton.ngircd.plist
maintainer-clean-local:
rm -f Makefile Makefile.in

92
contrib/MacOSX/config.h Normal file
View File

@@ -0,0 +1,92 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2007 Alexander Barton (alex@barton.de).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: config.h,v 1.1 2007/11/19 22:11:36 alex Exp $
*
* Static configuration file for Mac OS X Xcode project
*/
#define PACKAGE_NAME "ngircd"
#define VERSION "??"
#define SYSCONFDIR "/etc/ngircd"
/* -- Build options -- */
/* Define if debug-mode should be enabled */
#define DEBUG 1
/* Define if the server should do IDENT requests */
/*#define IDENTAUTH 1*/
/* Define if IRC+ protocol should be used */
#define IRCPLUS 1
/* Define if IRC sniffer should be enabled */
/*#define SNIFFER 1*/
/* Define if syslog should be used for logging */
#define SYSLOG 1
/* Define if TCP wrappers should be used */
/*#define TCPWRAP 1*/
/* Define if support for Zeroconf should be included */
/*#define ZEROCONF 1*/
/* Define if zlib compression should be enabled */
#define ZLIB 1
/* -- Supported features -- */
/* Define if SSP C support is enabled. */
#define ENABLE_SSP_CC 1
/* Define to 1 if the C compiler supports function prototypes. */
#define PROTOTYPES 1
/* Define like PROTOTYPES; this can be used by system headers. */
#define __PROTOTYPES 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <stddef.h> header file. */
#define HAVE_STDDEF_H 1
/* Define to 1 if you have the <stdbool.h> header file. */
#define HAVE_STDBOOL_H 1
/* Define to 1 if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define to 1 if you have the `kqueue' function. */
#define HAVE_KQUEUE 1
/* Define to 1 if you have the `inet_ntoa' function. */
#define HAVE_INET_NTOA 1
/* Define to 1 if you have the `snprintf' function. */
#define HAVE_SNPRINTF 1
/* Define to 1 if you have the `strlcat' function. */
#define HAVE_STRLCAT 1
/* Define to 1 if you have the `strlcpy' function. */
#define HAVE_STRLCPY 1
/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1
/* Define to 1 if you have the `vsnprintf' function. */
#define HAVE_VSNPRINTF 1
/* Define if socklen_t exists */
#define HAVE_socklen_t 1
#ifdef ZEROCONF
/* Define to 1 if you have the <DNSServiceDiscovery/DNSServiceDiscovery.h> header file. */
#define HAVE_DNSSERVICEDISCOVERY_DNSSERVICEDISCOVERY_H 1
/* Define to 1 if you have the `DNSServiceRegistrationCreate' function. */
#define HAVE_DNSSERVICEREGISTRATIONCREATE 1
#endif
/* -eof- */

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>de.barton.ngIRCd</string>
<key>ProgramArguments</key>
<array>
<string>:SBINDIR:/ngircd</string>
<string>--nodaemon</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/Library/Logs/ngIRCd.log</string>
<key>StandardOutPath</key>
<string>/Library/Logs/ngIRCd.log</string>
</dict>
</plist>

View File

@@ -0,0 +1 @@
<pkg-contents spec="1.12"/>

View File

@@ -0,0 +1 @@
<pkgref spec="1.12" uuid="6AF4DF80-E7DE-45E7-8B40-890A10AE51D0"><config><identifier>de.barton.ngircd.daemon.pkg</identifier><version>1</version><description></description><post-install type="none"/><requireAuthorization/><installFrom relative="true">../../ngircd.dest</installFrom><installTo>/</installTo><flags><followSymbolicLinks/></flags><packageStore type="internal"></packageStore><mod>parent</mod><mod>scripts.postinstall.path</mod><mod>scripts.postinstall.isRelativeType</mod><mod>scripts.preupgrade.path</mod><mod>installFrom.isRelativeType</mod><mod>version</mod><mod>scripts.preinstall.isRelativeType</mod><mod>identifier</mod><mod>installTo</mod></config><scripts><preinstall relative="true" mod="true">preinstall.sh</preinstall><preupgrade relative="true" mod="true">preinstall.sh</preupgrade></scripts></pkgref>

View File

@@ -0,0 +1 @@
<pkg-contents spec="1.12"/>

View File

@@ -0,0 +1 @@
<pkgref spec="1.12" uuid="F0954DA7-0607-4277-AE10-D882AC7C38CA"><config><identifier>de.barton.ngircd.launchscript.pkg</identifier><version>1</version><description></description><post-install type="none"/><requireAuthorization/><installFrom relative="true">de.barton.ngircd.plist</installFrom><installTo mod="true">/Library/LaunchDaemons</installTo><flags><followSymbolicLinks/></flags><packageStore type="internal"></packageStore><mod>parent</mod><mod>scripts.postinstall.path</mod><mod>scripts.postupgrade.path</mod><mod>installFrom.isRelativeType</mod><mod>installTo.path</mod><mod>installTo</mod><mod>identifier</mod></config><scripts><postinstall relative="true" mod="true">postinstall.sh</postinstall><postupgrade relative="true" mod="true">postinstall.sh</postupgrade></scripts></pkgref>

View File

@@ -0,0 +1,18 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
EXTRA_DIST = index.xml \
01ngircd-contents.xml 01ngircd.xml 02de-contents.xml 02de.xml
maintainer-clean-local:
rm -f Makefile Makefile.in
# -eof-

View File

@@ -0,0 +1,188 @@
<pkmkdoc spec="1.12"><properties><title>ngIRCd</title><build>/Users/alex/Desktop/ngIRCd.mpkg</build><organization>de.barton.ngircd</organization><userSees ui="both"/><min-target os="2"/><domain anywhere="true"/></properties><distribution><versions min-spec="1.000000"/><scripts></scripts></distribution><description>ngIRCd next generation IRC (Internet Relay Chat) server daemon</description><contents><choice title="ngIRCd daemon" id="choicengircd" tooltip="ngIRCd daemon, documentation and manual pages" description="Binaries, documentation and manual pages of the ngIRCd, the next generation IRC (Internet Relay Chat) daemon. This package will be installed into /opt/ngircd." starts_selected="true" starts_enabled="true" starts_hidden="false"><customLoc>/</customLoc><pkgref id="de.barton.ngircd.daemon.pkg"/></choice><choice title="Start and stop script" id="choicelaunchscript" tooltip="LaunchDaemon start and stop script" description="Installs the ngIRCd start and stop script for the &quot;launch daemon&quot;. If this is an update/upgrade, and ngIRCd is already running, it will be automatically restarted." starts_selected="true" starts_enabled="true" starts_hidden="false"><customLoc>/Library/LaunchDaemons</customLoc><pkgref id="de.barton.ngircd.launchscript.pkg"/></choice></contents><resources bg-scale="none" bg-align="topleft"><locale lang="en"><resource mime-type="text/rtf" kind="embedded" type="license"><![CDATA[{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
\f0\i\fs24 \cf0 ngIRCd -- The Next Generation IRC Daemon\
Copyright (c)2001-2008 Alexander Barton and Contributors.\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\i0 \cf0 \
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. \
\
Please see below and read the file COPYING, README and AUTHORS for more information.\
\
\
\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
\b \cf0 GNU GENERAL PUBLIC LICENSE\
Version 2, June 1991\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\b0 \cf0 \
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
\cf0 Copyright (C) 1989, 1991 Free Software Foundation, Inc.\
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
Everyone is permitted to copy and distribute verbatim copies\
of this license document, but changing it is not allowed.\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\cf0 \
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
\b \cf0 Preamble\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\b0 \cf0 \
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.\
\
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.\
\
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.\
\
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.\
\
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.\
\
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.\
\
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.\
\
The precise terms and conditions for copying, distribution and modification follow.\
\page \
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
\b \cf0 GNU GENERAL PUBLIC LICENSE\
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION\
AND MODIFICATION\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\b0 \cf0 \
0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law:\
that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".\
\
Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the\
Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.\
\
1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.\
\
You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.\
\
2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1above, provided that you also meet all of these conditions:\
\
a) You must cause the modified files to carry prominent notices\
stating that you changed the files and the date of any change.\
\
b) You must cause any work that you distribute or publish, that in\
whole or in part contains or is derived from the Program or any\
part thereof, to be licensed as a whole at no charge to all third\
parties under the terms of this License.\
\
c) If the modified program normally reads commands interactively\
when run, you must cause it, when started running for such\
interactive use in the most ordinary way, to print or display an\
announcement including an appropriate copyright notice and a\
notice that there is no warranty (or else, saying that you provide\
a warranty) and that users may redistribute the program under\
these conditions, and telling the user how to view a copy of this\
License. (Exception: if the Program itself is interactive but\
does not normally print such an announcement, your work based on\
the Program is not required to print an announcement.)\
\page \
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.\
\
Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.\
\
In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.\
\
3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:\
\
a) Accompany it with the complete corresponding machine-readable\
source code, which must be distributed under the terms of Sections\
1 and 2 above on a medium customarily used for software\
interchange; or,\
\
b) Accompany it with a written offer, valid for at least three\
years, to give any third party, for a charge no more than your\
cost of physically performing source distribution, a complete\
machine-readable copy of the corresponding source code, to be\
distributed under the terms of Sections 1 and 2 above on a medium\
customarily used for software interchange; or,\
\
c) Accompany it with the information you received as to the offer\
to distribute corresponding source code. (This alternative is\
allowed only for noncommercial distribution and only if you\
received the program in object code or executable form with such\
an offer, in accord with Subsection b above.)\
\
The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.\
\
If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not\
compelled to copy the source along with the object code.\
\
4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.\
\
5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.\
\
6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.\
\
7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.\
\
If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.\
\
It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.\
\
This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.\
\page \
8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.\
\
9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.\
\
Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.\
\
10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.\
\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
\b \cf0 NO WARRANTY
\b0 \
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\cf0 \
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\
\
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\
}]]></resource><resource mime-type="text/rtf" kind="embedded" type="welcome"><![CDATA[{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330
{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\f0\fs26 \cf0 ngIRCd is a free open source daemon for the Internet Relay Chat (IRC) protocol, developed under the GNU General Public License (GPL). It's written from scratch, is quite portable and is not based upon the original IRCd like many others.\
\
Homepage: http://ngircd.barton.de\
\
You will be guided through all steps necessary to install this software.}]]></resource><resource mime-type="text/rtf" kind="embedded" type="conclusion"><![CDATA[{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330
{\fonttbl\f0\fnil\fcharset0 LucidaGrande;\f1\fnil\fcharset0 Monaco;}
{\colortbl;\red255\green255\blue255;}
{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid1}
{\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid2}}
{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\f0\fs26 \cf0 ngIRCd has been successfully installed/upgraded, and has been restarted if it was already running before and you have installed the LaunchDaemon start and stop script (which is the default).\
\
If you installed ngIRCd the first time (or had the LaunchDaemon script disabled before), you can start ngIRCd using the following terminal command:\
\
\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\ql\qnatural\pardirnatural
\ls1\ilvl0
\f1\fs24 \cf0 sudo launchctl load -w \\\
/Library/LaunchDaemons/de.barton.ngircd.plist\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\f0\fs26 \cf0 \
To disable automatic starting of ngIRCd, use this command:\
\
\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\ql\qnatural\pardirnatural
\ls2\ilvl0
\f1\fs24 \cf0 sudo launchctl unload -w \\\
/Library/LaunchDaemons/de.barton.ngircd.plist\
}]]></resource></locale></resources><flags/><item type="file">01ngircd.xml</item><item type="file">02de.xml</item><mod>properties.customizeOption</mod><mod>properties.title</mod><mod>description</mod><mod>properties.anywhereDomain</mod><mod>properties.systemDomain</mod></pkmkdoc>

View File

@@ -0,0 +1,2 @@
*.mode1v3
*.pbxuser

View File

@@ -0,0 +1,17 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
EXTRA_DIST = project.pbxproj
maintainer-clean-local:
rm -f Makefile Makefile.in
# -eof-

File diff suppressed because it is too large Load Diff

42
contrib/MacOSX/postinstall.sh Executable file
View File

@@ -0,0 +1,42 @@
#!/bin/sh
# ngIRCd Mac OS X postinstall/postupgrade script
LDPLIST="/Library/LaunchDaemons/de.barton.ngircd.plist"
if [ ! -e /etc/ngircd ]; then
echo "Creating symlink: /opt/ngircd/etc -> /etc/ngircd"
ln -s /opt/ngircd/etc /etc/ngircd || exit 1
else
echo "/etc/ngircd already exists. Don't create symlink."
fi
if [ ! -e /opt/ngircd/etc/ngircd.conf ]; then
echo "Creating default configuration: /opt/ngircd/etc/ngircd.conf"
cp /opt/ngircd/share/doc/ngircd/sample-ngircd.conf \
/opt/ngircd/etc/ngircd.conf || exit 1
else
echo "/opt/ngircd/etc/ngircd.conf exists. Don't copy sample file."
fi
chmod o-rwx /opt/ngircd/etc/ngircd.conf
if [ -f "$LDPLIST" ]; then
echo "Fixing ownership and permissions of LaunchDaemon script ..."
chown root:wheel "$LDPLIST" || exit 1
chmod 644 "$LDPLIST" || exit 1
fi
if [ -f /tmp/ngircd_needs_restart ]; then
echo "ngIRCd should be (re-)started ..."
if [ -r "$LDPLIST" ]; then
echo "LaunchDaemon script found, starting daemon ..."
launchctl load -w "$LDPLIST" || exit 1
echo "OK, LaunchDaemon script loaded successfully."
else
echo "LaunchDaemon script not installed. Can't start daemon."
fi
else
echo "Not loading LaunchDaemon script."
fi
rm -f /tmp/ngircd_needs_restart
# -eof-

25
contrib/MacOSX/preinstall.sh Executable file
View File

@@ -0,0 +1,25 @@
#!/bin/sh
# ngIRCd Mac OS X preinstall/preupgrade script
LDPLIST="/Library/LaunchDaemons/de.barton.ngircd.plist"
rm -f /tmp/ngircd_needs_restart || exit 1
if [ -r "$LDPLIST" ]; then
echo "LaunchDaemon script found, checking status ..."
launchctl list | fgrep "de.barton.ngIRCd" >/dev/null 2>&1
if [ $? -eq 0 ]; then
# ngIRCd is already running; stop it and touch a
# "stamp file" so that we know that we have to
# restart it after installation/upgrade.
echo "ngIRCd is already running; stop it ..."
launchctl unload "$LDPLIST" || exit 1
echo "Daemon has been stopped."
touch /tmp/ngircd_needs_restart || exit 1
else
echo "ngIRCd is not running."
fi
else
echo "LaunchDaemon script not found."
fi
# -eof-

View File

@@ -1,20 +1,17 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2004 Alexander Barton <alex@barton.de>
# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
#
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
# der GNU General Public License (GPL), wie von der Free Software Foundation
# herausgegeben, weitergeben und/oder modifizieren, entweder unter Version 2
# der Lizenz oder (wenn Sie es wuenschen) jeder spaeteren Version.
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
#
# $Id: Makefile.am,v 1.4 2004/04/28 12:18:02 alex Exp $
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
SUBDIRS = Debian MacOSX
EXTRA_DIST = README ngircd.spec systrace.policy
EXTRA_DIST = README ngircd.spec systrace.policy ngindent ngircd.sh
maintainer-clean-local:
rm -f Makefile Makefile.in

View File

@@ -1,5 +1,5 @@
%define name ngircd
%define version CVSHEAD
%define version 13
%define release 1
%define prefix %{_prefix}

View File

@@ -1,57 +0,0 @@
ngIRCd - Next Generation IRC Server
(c)2001-2003 by Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- CVS.txt --
The source code of ngIRCd is maintained using the "Concurrent Versions
System" (CVS). Thereby several developers can work with the source tree at
the same time.
I. Anonymous read-only Access
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To access the source tree anonymously in read-only mode, follow these steps:
Login to the CVS server:
$ cvs -d:pserver:anonymous@ngircd.barton.de:/srv/cvs/ngircd login
Use "anonymous" as user name and no password (just hit Return). Now you can
check out the sources:
$ cvs -d:pserver:anonymous@ngircd.barton.de:/srv/cvs/ngircd checkout ngircd
Thereby a new folder "ngircd" will be created containing all the individual
source files. (Substitute the last "ngircd" with "website" to check out all
the files of the homepage of ngIRCd.)
The newly created folder ("ngircd" or "website") is the "working folder", all
CVS commands will be executed from within this folder in the future.
Please note: When checking out a fresh copy of ngIRCd from CVS, the
configure script doesn't exist; you have to run the autogen.sh shell script
(which is included in the source tree) to generate it. This requires you to
have GNU automake and GNU autoconf installed on your system.
Updating the CVS tree:
$ cvs update -d -P [<filename>]
You can update a single file or the complete source tree.
III. Write Access
~~~~~~~~~~~~~~~~~
If you want to contribute a couple of patches and write access to the CVS
repository would be handy, please contact Alex Barton, <alex@barton.de>.
--
$Id: CVS.txt,v 1.8 2006/07/23 12:43:15 alex Exp $

View File

@@ -54,6 +54,10 @@ A: Most probably you are using version 1.5 of GNU automake which seems to be
III. Runtime
~~~~~~~~~~~~
Q: Where is the log file located?
A: ngIRCd does not write its own log file. Instead, ngIRCd uses
syslog(3). Check the files in /var/log/ and/or consult the
documentation for your system logger daemon.
Q: I cannot connect to remote peers when I use the chroot option, the
following is logged: "Can't resolve example.com: unknown error!".
A: On Linux/glibc with chroot enabled you need to put some libraries inside
@@ -61,16 +65,14 @@ A: On Linux/glibc with chroot enabled you need to put some libraries inside
linking ngircd statically does not help this. The only known workaround
is to either disable chroot support or to link against dietlibc instead
of glibc. (tnx to Sebastian Siewior)
Q: I am running Linux and ngircd dies on startup with the follwing errors:
IO subsystem: epoll (hint size 100, initial maxfd 100, masterfd -1).
Cannot initialize IO routines: Function not implemented
Server isn't listening on a single port!
ngircd exiting due to fatal errors!
A: epoll is only supported on 2.6 Linux kernels. Either use a 2.6 kernel, or
re-run configure with the --without-epoll parameter. After configure
completed, you should see select() being listed as IO backend:
'(I/O backend: "select()"').
Q: I have added an [Oper] section, how do i log on as IRC operator?
A: You can use the /OPER command in your IRC client to become an IRC operator.
ngIRCd will also log all OPER requests (using syslog), if OPER fails you
can look there to determine why it did not work (bad password, unauthorized
host mask, etc.)
Q: I am an IRC operator, but MODE doesn't work!
A: You need to set 'OperCanUseMode = yes' in ngircd.conf to enable MODE for IRC
operators.
IV. Bugs!?
~~~~~~~~~~
@@ -85,4 +87,4 @@ A: Please file a bug report at <http://ngircd.barton.de/bugzilla/index.cgi>!
--
$Id: FAQ.txt,v 1.11 2005/12/09 21:14:56 fw Exp $
$Id: FAQ.txt,v 1.12 2008/01/02 22:47:58 alex Exp $

45
doc/GIT.txt Normal file
View File

@@ -0,0 +1,45 @@
ngIRCd - Next Generation IRC Server
-- GIT.txt --
The source code of ngIRCd is maintained using git, the stupid content
tracker.
I. Getting the source code
~~~~~~~~~~~~~~~~~~~~~~~~~~
To access the source tree anonymously, run:
$ git clone git://ngircd.barton.de/ngircd.git
Thereby a new folder "ngircd" will be created containing all the individual
source files.
The newly created directory ("ngircd") is the "working directory", all
git commands will be executed from within this directory in the future.
Please note: When checking out a fresh copy of ngIRCd using git, the
configure script doesn't exist; you have to run the autogen.sh shell script
(which is included in the source tree) to generate it. This requires you to
have GNU automake and GNU autoconf installed on your system.
To update the git tree:
$ git pull
This retrieves all changes and merges them into the current branch.
II. Contributing
~~~~~~~~~~~~~~~~
Patches should be sent to the ngircd mailing list. List homepage:
http://arthur.barton.de/mailman/listinfo/ngircd-ml
If you do not want to send them to the list, you can also mail them
to Alex Barton, <alex@barton.de>.
III. Write Access
~~~~~~~~~~~~~~~~~
If you want to contribute a couple of patches and write access to the git
repository would be handy, please contact Alex Barton, <alex@barton.de>.

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
#
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
# der GNU General Public License (GPL), wie von der Free Software Foundation
@@ -9,13 +9,12 @@
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
#
# $Id: Makefile.am,v 1.21 2005/11/29 20:59:57 alex Exp $
#
SUBDIRS = src
EXTRA_DIST = CVS.txt FAQ.txt Protocol.txt Platforms.txt README-AUX.txt \
README-BeOS.txt RFC.txt Zeroconf.txt sample-ngircd.conf
EXTRA_DIST = FAQ.txt GIT.txt Protocol.txt Platforms.txt README-AUX.txt \
README-BeOS.txt RFC.txt Services.txt SSL.txt Zeroconf.txt \
sample-ngircd.conf
maintainer-clean-local:
rm -f Makefile Makefile.in

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2004 Alexander Barton
(c)2001-2008 Alexander Barton
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -26,41 +26,61 @@ list can be updated. Thanks for your help!
| | | |
Platform Compiler ngIRCd Date Tester C M T R See
--------------------------- ------------ ---------- -------- ------ - - - - ---
alpha/unknown/netbsd3.0 gcc 3.3.3 CVSHEAD 06-05-07 fw Y Y Y Y (3)
alpha/unknown/netbsd3.0 gcc 3.3.3 CVSHEAD 06-05-07 fw Y Y Y Y (3)
hppa/unknown/openbsd3.5 gcc 2.95.3 CVSHEAD 04-05-25 alex Y Y Y Y
hppa1.1/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
hppa2.0/unknown/linux-gnu gcc 3.3.5 13~rc1 08-12-02 alex Y Y Y Y
i386/apple/darwin9.5.1 gcc 4.0.1 13~rc1 08-12-02 alex Y Y Y Y (3)
i386/pc/solaris2.9 gcc 3.2.2 CVSHEAD 04-02-24 alex Y Y Y Y
i386/pc/solaris2.11 gcc 3.4.3 13~rc1 08-12-03 alex Y Y Y Y (4)
i386/unknown/freebsd5.2.1 gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
i386/unknown/freebsd6.1 gcc 3.4.4 CVSHEAD 06-05-07 fw Y Y Y Y (4)
i386/unknown/freebsd6.0 gcc 3.4.4 0.10.0-p1 06-08-04 alex Y Y Y Y (3)
i386/unknown/freebsd6.1 gcc 3.4.4 CVSHEAD 06-05-07 fw Y Y Y Y (3)
i386/unknown/freebsd6.2 gcc 3.4.6 13~rc1 08-12-04 alex Y Y Y Y (3)
i386/unknown/freebsd7.0 gcc 4.2.1 13~rc1 08-12-04 alex Y Y Y Y (3)
i386/unknown/gnu0.3 gcc 3.3.3 0.8.0 04-05-30 alex Y Y n Y
i686/unknown/gnu0.3 gcc 4.3.1 13~rc1 08-12-05 alex Y Y Y Y
i386/unknown/netbsdelf1.6.1 gcc 2.95.3 CVSHEAD 04-02-24 alex Y Y Y Y
i386/unknown/netbsdelf3.0.1 gcc 3.3.3 0.10.0-p1 06-08-30 alex Y Y Y Y (3)
i386/unknown/netbsdelf4.0 gcc 4.1.2 13~rc1 08-12-05 alex Y Y Y Y (3)
i386/unknown/openbsd3.9 gcc 3.3.5 0.10.0-p1 06-08-30 alex Y Y Y Y (3)
i386/unknown/openbsd4.1 gcc 3.3.5 13~rc1 08-12-05 alex Y Y Y Y (3)
i686/pc/cygwin gcc 3.3.1 0.8.0 04-05-30 alex Y Y n Y
i686/pc/linux-gnu gcc 2.95.4 0.8.0 04-05-30 alex Y Y Y Y (1)
i686/pc/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y (1)
i686/pc/linux-gnu gcc 3.3.5 13~rc1 08-12-05 alex Y Y Y Y (1)
i386/pc/linux-gnu gcc 4.1.2 13~rc1 08-12-05 alex Y Y Y Y (1)
i386/pc/linux-gnu gcc 4.3.2 13~rc1 08-12-05 alex Y Y Y Y (1)
m68k/apple/aux3.1.1 Orig. A/UX 0.7.x-CVS 03-04-22 alex Y Y Y Y (2)
m68k/hp/hp-ux9.10 Orig. HPUX 0.7.x-CVS 03-04-30 goetz Y Y Y Y
m88k/dg/dgux5.4R3.10 gcc 2.5.8 CVSHEAD 04-03-15 alex Y Y ? ?
powerpc/apple/darwin6.5 gcc 3.1 0.7.x-CVS 03-04-23 alex Y Y Y Y
powerpc/apple/darwin7.4.0 gcc 3.3 0.8.0 04-05-30 alex Y Y Y Y
powerpc/apple/darwin7.9.0 gcc 3.3 CVSHEAD 06-05-07 fw Y Y Y Y (3)
powerpc/apple/darwin8.1.0 gcc 4.0 0.9.x-CVS 05-06-27 alex Y Y Y Y
powerpc/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
powerpc/unknown/openbsd3.6 gcc 2.95.3 0.10.0 06-10-08 alex Y Y n Y
sparc/sun/solaris2.6 gcc 2.95.3 0.7.x-CVS 03-04-22 alex Y Y Y Y
sparc/sun/solaris2.7 gcc 3.3 0.8.0 04-05-30 alex Y Y Y Y
sparc/unkn./netbsdelf1.6.1 gcc 2.95.3 0.8.0 04-05-30 alex Y Y Y Y
x86_64/unknown/linux-gnu 4.3.2 13~rc1 08-12-05 alex Y Y Y Y (5)
Notes
~~~~~
(1) i686/pc/linux-gnu:
ngIRCd has been tested with various Linux distributions, such as SuSE,
RedHat, Debian, and Gentoo using Kernels 2.2.x, 2.4.x and 2.6.x with
various versions of the GNU C compiler (2.95.3, 3.0, 3.2, and 3.3). The
eldest glibc used was glibc-2.0.7. ngIRCd compiled and run on all these
systems without problems.
various versions of the GNU C compiler (starting with 2.95.x and up to
version 4.3.x). The eldest glibc used was glibc-2.0.7. ngIRCd compiled
and run on all these systems without problems.
Actual Linux kernels (2.6.x) and glic's support the epoll() IO interface.
(2) This compiler is an pre-ANSI C compiler, therefore the source code is
automatically converted using the included ansi2knr tool while building.
(3) kqueue io backend
(4) 6.1-PRERELEASE
--
$Id: Platforms.txt,v 1.14 2006/05/07 11:07:13 fw Exp $
(3) Using the kqueue() IO interface.
(4) Using the /dev/poll IO interface.
(5) Using the epoll() IO interface.

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2003 by Alexander Barton,
(c)2001-2008 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -79,9 +79,14 @@ The following <serverflags> are defined at the moment:
peer understands this flag, it will send "MODE +I" and "MODE +b"
commands after the server link has been established.
- H: The server supports the "enhanced server handshake", see section II.2
for a detailed description.
- o: IRC operators are allowed to change channel- and channel-user-modes
even if they aren't channel-operator of the affected channel.
- S: The server supports the SERVICE command (on this link).
- Z: Compressed server links are supported by the server.
Example for a complete <flags> string: "ngircd|0.7.5:CZ".
@@ -90,7 +95,50 @@ The optional parameter <options> is used to propagate server options as
defined in RFC 2813, section 4.1.1.
II.2 Exchange channel-modes, topics, and persistent channels
II.2 Enhanced Server Handshake
The "enhanced server handshake" is used when both servers support this IRC+
extension, which is indicated by the 'H' flag in the <serverflags> sent with
the PASS command, see section II.1.
It basically means, that after exchanging the PASS and SERVER commands the
server is not registered in the network (as usual), but that IRC numerics
are exchanged until the numeric 376 (ENDOFMOTD) is received. Afterwards the
peer is registered in the network as with the regular IRC protocol.
A server implementing the enhanced server handshake (and indicating this
using 'H' in the <serverflags>) MUST ignore all unknown numerics to it
silently.
In addition, such a server should at least send the numeric 005 (ISUPPORT)
to its peer, containing the following information. Syntax: <key>=<value>,
one token per IRC parameter. If the server has to send more than 12 token
it must send separate ISUPPORT numerics (this is a limitation of the IRC
protocol which allows at max 15 arguments per command).
- NICKLEN: Maximum nickname length. Default: 9.
- CASEMAPPING: Case mapping used for nick- and channel name comparing.
Default: "ascii", the chars [a-z] are lowercase of [A-Z].
- PREFIX: List of channel modes a person can get and the respective prefix
a channel or nickname will get in case the person has it. The order of the
modes goes from most powerful to least powerful. Default: "(ov)@+"
- CHANTYPES: Supported channel prefixes. Default: "#".
- CHANMODES: List of channel modes for 4 types, separated by comma (","):
Mode that adds or removes a nick or address to a list, mode that changes
a setting (both have always has a parameter), mode that changes a setting
and only has a parameter when set, and mode that changes a setting and
never has a parameter. For example "bI,k,l,imnPst".
- CHANLIMIT: Maximum number of channels allowed to join by channel prefix,
for example "#:10".
Please see <http://www.irc.org/tech_docs/005.html> for details.
The information exchanged using ISUPPORT can be used to detect configuration
incompatibilities (different maximum nick name length, for example) and
therefore to disconnect the peer prior to registering it in the network.
II.3 Exchange channel-modes, topics, and persistent channels
Command: CHANINFO
Parameters: <channel> +<modes> <key> <limit> [<topic>]
@@ -113,6 +161,3 @@ and therefore can't be omitted. The parameter <limit> must be ignored when
a channel has no user limit (the parameter <modes> doesn't list the "l"
channel mode). In this case <limit> should be "0".
--
$Id: Protocol.txt,v 1.13 2005/08/27 19:00:06 alex Exp $

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2004 by Alexander Barton,
(c)2001-2008 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -10,17 +10,70 @@
-- SSL.txt --
ngIRCd actually doesn't support secure connections for client-server or
server-server links using SSL, the Secure Socket Layer, by itself. But you can
use the stunnel(8) command to make this work.
ngIRCd supports SSL/TLSv1 encrypted connections using the OpenSSL or GnuTLS
libraries. Both encrypted server-server links as well as client-server links
are supported.
SSL is a compile-time option which is disabled by default. Use one of these
options of the ./configure script to enable it:
--with-openssl enable SSL support using OpenSSL
--with-gnutls enable SSL support using GnuTLS
You need a SSL certificate, see below for how to create a self-signed one.
Configuration
~~~~~~~~~~~~~
To enable SSL connections a separate port must be configured: it is NOT
possible to handle unencrypted and encrypted connections on the same port!
This is a limitation of the IRC protocol ...
You have to set (at least) the following configuration variables in the
[GLOBAL] section of ngircd.conf(5): SSLPorts, SSLKeyFile, and SSLCertFile.
Now IRC clients are able to connect using SSL on the configured port(s).
(Using port 6697 for encrypted connections is common.)
To enable encrypted server-server links, you have to additionally set
SSLConnect to "yes" in the corresponding [SERVER] section.
Creating a self-signed certificate
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OpenSSL:
Creating a self-signed certificate and key:
$ openssl req -newkey rsa:2048 -x509 -keyout server-key.pem \
-out server-cert.pem -days 1461
Create DH parameters (optional):
$ openssl dhparam -2 -out dhparams.pem 2048
GnuTLS:
Creating a self-signed certificate and key:
$ certtool --generate-privkey --bits 2048 --outfile server-key.pem
$ certtool --generate-self-signed --load-privkey server-key.pem \
--outfile server-cert.pem
Create DH parameters (optional):
$ certtool --generate-dh-params --bits 2048 --outfile dhparams.pem
Alternate approach using stunnel(1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Alternatively (or if you are using ngIRCd without compiled without support
for GnuTLS/OpenSSL), you can use external programs/tools like stunnel(1) to
get SSL encrypted connections:
<http://stunnel.mirt.net/>
<http://www.stunnel.org/>
Stefan Sperling (stefan at binarchy dot net) mailed me the following text as a
Stefan Sperling (stefan at binarchy dot net) mailed the following text as a
short "how-to", thanks Stefan!
=== snip ===
! This guide applies to stunnel 4.x !
@@ -49,10 +102,3 @@ short "how-to", thanks Stefan!
That's it.
Don't forget to activate ssl support in your irc client ;)
=== snip ===
Probably ngIRCd will include support for SSL in the future ...
--
$Id: SSL.txt,v 1.2 2004/12/27 01:11:40 alex Exp $

70
doc/Services.txt Normal file
View File

@@ -0,0 +1,70 @@
ngIRCd - Next Generation IRC Server
(c)2001-2008 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- Services.txt --
At the moment, ngIRCd doesn't implement a "special IRC services interface".
But services acting as a "regular server" are supported, either using the IRC
protocol defined in RFC 1459 or RFC 2812.
Services have been tested using "IRC Services" version 5.x by Andrew Church,
homepage: <http://www.ircservices.za.net/>. This document describes setting up
ngIRCd and these services.
Setting up ngIRCd
~~~~~~~~~~~~~~~~~
The "pseudo server" handling the IRC services is configured as a regular
remote server in the ngircd.conf(5). In addition the variable "ServiceMask"
should be set, enabling this ngIRCd to recognize the "pseudo users" as IRC
services instead of regular IRC users.
Example:
[SERVER]
Name = services.irc.net
MyPassword = 123abc
PeerPassword = 123abc
ServiceMask = *Serv
Setting up IRC Services 5.1.x
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
IRC Services 5.1.3 and above can be used with ngIRCd using the "rfc1459"
protocol module.
Please note that versions up to and including 5.1.3 contain a bug that
sometimes causes IRC Services to hang on startup. There are two workarounds:
a) send the services process a HUP signal ("killall -HUP ircservices")
b) apply this patch to the IRC Services source tree:
<ftp://ngircd.barton.de/ngircd/contrib/IRCServices513-FlushBuffer.patch>
At least the following settings have to be tweaked, in addition to all the
settings marked as required by IRC Services:
In ircservices.conf:
Variable Example value
RemoteServer server.irc.net 6667 "123abc"
ServerName "services.irc.net"
LoadModule protocol/rfc1459
In modules.conf:
Module protocol/rfc1459
The documentation of IRC Services can be found here:
<http://www.ircservices.za.net/docs/>
Please let us know if you are successfully using other IRC service packages or
which problems you encounter, thanks!

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2005 Alexander Barton
(c)2001-2006 Alexander Barton
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -16,7 +16,8 @@ with DNS Service Discovery (DNS-SD[3]).
To use this features you can use one of two APIs:
a) Apple "Bonjour" API as used by Mac OS X,
b) the Howl[4] Zeroconf library.
b) the Howl[4] Zeroconf library or the Howl compatibility layer
of the newer Avahi[5] library.
When calling the configure script using the "--with-zeroconf" switch the
avalable API will be autodetected and the required additional libraries will
@@ -32,7 +33,8 @@ Links:
[2] http://www.multicastdns.org/
[3] http://www.dns-sd.org/
[4] http://www.porchdogsoft.com/products/howl/
[5] http://avahi.org/
--
$Id: Zeroconf.txt,v 1.1 2005/07/08 16:19:03 alex Exp $
$Id: Zeroconf.txt,v 1.2 2006/08/03 14:37:29 alex Exp $

View File

@@ -1,14 +1,19 @@
# $Id: sample-ngircd.conf,v 1.37 2006/04/09 12:27:23 alex Exp $
#
# This is a sample configuration file for the ngIRCd, which must be adepted
# to the local preferences and needs.
# This is a sample configuration file for the ngIRCd IRC daemon, which must
# be customized to the local preferences and needs.
#
# Comments are started with "#" or ";".
#
# A lot of configuration options in this file start with a ";". You have
# to remove the ";" in front of each variable to actually set a value!
# The disabled variables are shown with example values for completeness only
# and the daemon is using compiled-in default settings.
#
# Use "ngircd --configtest" (see manual page ngircd(8)) to validate that the
# server interprets the configuration file as expected!
#
# Please see ngircd.conf(5) for a complete list of configuration options.
#
[Global]
# The [Global] section of this file is used to define the main
@@ -36,9 +41,26 @@
# one port, separated with ",". (Default: 6667)
;Ports = 6667, 6668, 6669
# IP address on which the server should listen. (Default: empty,
# so the server listens on all IP addresses of the system)
;Listen = 1.2.3.4
# Additional Listen Ports that expect SSL/TLS encrypted connections
;SSLPorts = 9999,6668
# SSL Server Key
;SSLKeyFile = /usr/local/etc/ngircd/ssl/server-key.pem
# password to decrypt SSLKeyFile (OpenSSL only)
;SSLKeyFilePassword = secret
# SSL Server Key Certificate
;SSLCertFile = /usr/local/etc/ngircd/ssl/server-cert.pem
# Diffie-Hellman parameters
;SSLDHFile = /usr/local/etc/ngircd/ssl/dhparams.pem
# comma seperated list of IP addresses on which the server should
# listen. Default values are:
# "0.0.0.0" or (if compiled with IPv6 support) "::,0.0.0.0"
# so the server listens on all IP addresses of the system by default.
;Listen = 127.0.0.1,192.168.0.1
# Text file with the "message of the day" (MOTD). This message will
# be shown to all users connecting to the server:
@@ -93,17 +115,36 @@
# server? (This is a compatibility hack for ircd-irc2 servers)
;OperServerMode = no
# Maximum number of simultaneous connection the server is allowed
# to accept (<=0: unlimited):
;MaxConnections = -1
# Allow Pre-Defined Channels only (see Section [Channels])
;PredefChannelsOnly = no
# Don't do any DNS lookups when a client connects to the server.
;NoDNS = no
# Don't do any IDENT lookups, even if ngIRCd has been compiled
# with support for it.
;NoIdent = no
# try to connect to other irc servers using ipv4 and ipv6, if possible
;ConnectIPv6 = yes
;ConnectIPv4 = yes
# Maximum number of simultaneous in- and outbound connections the
# server is allowed to accept (0: unlimited):
;MaxConnections = 0
# Maximum number of simultaneous connections from a single IP address
# the server will accept (<=0: unlimited):
# the server will accept (0: unlimited):
;MaxConnectionsIP = 5
# Maximum number of channels a user can be member of (<=0: no limit):
# Maximum number of channels a user can be member of (0: no limit):
;MaxJoins = 10
# Maximum length of an user nick name (Default: 9, as in RFC 2812).
# Please note that all servers in an IRC network MUST use the same
# maximum nick name length!
;MaxNickLength = 9
[Operator]
# [Operator] sections are used to define IRC Operators. There may be
# more than one [Operator] block, one for each local operator.
@@ -137,11 +178,15 @@
# IRC name of the remote server, must match the "Name" variable in
# the [Global] section of the other server (when using ngIRCd).
;Name = irc2.the.net
# Internet host name or IP address of the peer (only required when
# this server should establish the connection).
;Host = connect-to-host.the.net
# IP address to use as _source_ address for the connection. if
# unspecified, ngircd will let the operating system pick an address.
;Bind = 10.0.0.1
# Port of the server to which the ngIRCd should connect. If you
# assign no port the ngIRCd waits for incoming connections.
;Port = 6667
@@ -157,6 +202,26 @@
# Group of this server (optional)
;Group = 123
# Set the "Passive" option to "yes" if you don't want this ngIRCd to
# connect to the configured peer (same as leaving the "Port" variable
# empty). The advantage of this option is that you can actually
# configure a port an use the IRC command CONNECT more easily to
# manually connect this specific server later.
;Passive = no
# Connect to the remote server using TLS/SSL (Default: false)
;SSLConnect = yes
# Define a (case insensitive) mask matching nick names that sould be
# treated as IRC services when introduced via this remote server.
# REGULAR SERVERS DON'T NEED this parameter, so leave it empty
# (which is the default).
# When you are connecting IRC services which mask as a IRC server
# and which use "virtual users" to communicate with, for example
# "NickServ" amd "ChanServ", you should set this parameter to
# something like "*Serv".
;ServiceMask = *Serv
[Server]
# More [Server] sections, if you like ...
@@ -175,7 +240,13 @@
;Topic = a great topic
# Initial channel modes
;Modes = tn
;Modes = tnk
# initial channel password (mode k)
;Key = Secret
# maximum users per channel (mode l)
;MaxUsers = 23
[Channel]
# More [Channel] sections, if you like ...

1
doc/src/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
html

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2006 Alexander Barton (alex@barton.de)
# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -8,14 +8,14 @@
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
# $Id: Makefile.am,v 1.2 2006/04/08 16:35:03 alex Exp $
#
EXTRA_DIST = Doxyfile header.inc.html footer.inc.html ngircd-doc.css
maintainer-clean-local:
rm -f Makefile Makefile.in
distclean-local:
rm -f html
rm -rf html
srcdoc:
@doxygen --version >/dev/null 2>&1 \

2
man/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
ngircd.8
ngircd.conf.5

View File

@@ -9,12 +9,25 @@
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
#
# $Id: Makefile.am,v 1.5 2002/04/04 13:02:41 alex Exp $
# $Id: Makefile.am,v 1.6 2006/12/25 16:13:26 alex Exp $
#
TEMPLATE_MANS = ngircd.conf.5.tmpl ngircd.8.tmpl
SUFFIXES = .tmpl .
.tmpl:
sed \
-e s@:SBINDIR:@${sbindir}@ \
-e s@:BINDIR:@${bindir}@ \
-e s@:ETCDIR:@${sysconfdir}@ \
<$< >$@
man_MANS = ngircd.conf.5 ngircd.8
EXTRA_DIST = $(man_MANS)
CLEANFILES = $(man_MANS)
EXTRA_DIST = $(TEMPLATE_MANS)
maintainer-clean-local:
rm -f Makefile Makefile.in

View File

@@ -1,7 +1,7 @@
.\"
.\" $Id: ngircd.8,v 1.11 2005/08/12 13:20:54 alex Exp $
.\" ngircd(8) manual page template
.\"
.TH ngircd 8 "August 2005" ngircd "ngIRCd Manual"
.TH ngircd 8 "Dec 2008" ngircd "ngIRCd Manual"
.SH NAME
ngIRCd \- the next generation IRC daemon
.SH SYNOPSIS
@@ -23,7 +23,8 @@ Linux, Mac OS X, NetBSD, OpenBSD, Solaris, and Windows with Cygwin.
.PP
As ngIRCd relies on UNIX standards and uses GNU automake and GNU autoconf
there are good chances that it also supports other UNIX-based operating
systems as well.
systems as well. By default, ngIRCd writes diagnostic and informational messages using
the syslog mechanism.
.SH OPTIONS
The default behaviour of
.BR ngircd
@@ -49,17 +50,17 @@ CONNECT later on as IRC Operator to link this ngIRCd to other servers.
\fB\-t\fR, \fB\-\-configtest\fR
Read, validate and display the configuration; then exit.
.TP
\fB\-\-version\fR
\fB\-V\fR, \fB\-\-version\fR
Output version information and exit.
.TP
\fB\-\-help\fR
\fB\-h\fR, \fB\-\-help\fR
Display a brief help text and exit.
.SH FILES
.I /usr/local/etc/ngircd.conf
.I :ETCDIR:/ngircd.conf
.RS
The system wide default configuration file.
.RE
.I /usr/local/etc/ngircd.motd
.I :ETCDIR:/ngircd.motd
.RS
Default "message of the day" (MOTD).
.RE

View File

@@ -1,11 +1,11 @@
.\"
.\" $Id: ngircd.conf.5,v 1.20 2005/09/02 14:39:00 fw Exp $
.\" ngircd.conf(5) manual page template
.\"
.TH ngircd.conf 5 "August 2005" ngircd "ngIRCd Manual"
.TH ngircd.conf 5 "Dec 2008" ngircd "ngIRCd Manual"
.SH NAME
ngircd.conf \- configuration file of ngIRCd
.SH SYNOPSIS
.B /usr/local/etc/ngircd.conf
.B :ETCDIR:/ngircd.conf
.SH DESCRIPTION
.BR ngircd.conf
is the configuration file of the
@@ -26,19 +26,20 @@ Sections contain parameters of the form
.RE
.PP
Empty lines and any line beginning with a semicolon (';') or a hash ('#')
character is treated as a comment and will be ignored.
character are treated as a comment and will be ignored. Leading and trailing
whitespaces are trimmed before any processing takes place.
.PP
The file format is line-based - that means, each newline-terminated line
represents either a comment, a section name or a parameter.
The file format is line-based - that means, each non-empty newline-terminated
line represents either a comment, a section name, or a parameter.
.PP
Section and parameter names are not case sensitive.
.SH "SECTION OVERVIEW"
The file can contain blocks of four types: [Global], [Operator], [Server],
and [Channel].
.PP
In the
The main configuration of the server is stored in the
.I [Global]
section, there is the main configuration like the server name and the
section, like the server name, administrative information and the
ports on which the server should be listening. IRC operators of this
server are defined in
.I [Operator]
@@ -57,7 +58,7 @@ section is used to define the server main configuration, like the server
name and the ports on which the server should be listening.
.TP
\fBName\fR
Server name in the IRC network
Server name in the IRC network, must contain at least one dot (".").
.TP
\fBInfo\fR
Info text of the server. This will be shown by WHOIS and LINKS requests for
@@ -71,9 +72,33 @@ command.
Ports on which the server should listen. There may be more than one port,
separated with ','. Default: 6667.
.TP
\fBSSLPorts\fR
Same as \fBPorts\fR , except that ngircd will expect incoming connections
to be SSL/TLS encrypted. Default: None
.TP
\fBSSLKeyFile\fR
Filename of SSL Server Key to be used for SSL connections. This is required for
SSL/TLS support.
.TP
\fBSSLKeyFilePassword\fR
(OpenSSL only:) Password to decrypt private key.
.TP
\fBSSLCertFile\fR
Certificate of the private key
.TP
\fBSSLDHFile\fR
Name of the Diffie-Hellman Parameter file. Can be created with gnutls
"certtool \-\-generate-dh-params" or "openssl dhparam".
If this file is not present, it will be generated on startup when ngircd
was compiled with gnutls support (this may take some time). If ngircd
was compiled with OpenSSL, then (Ephemeral)-Diffie-Hellman Key Exchanges and several
Cipher Suites will not be available.
.TP
\fBListen\fR
The IP address on which the server should listen. Default is empty, so
the server listens on all configured IP addresses and interfaces.
A comma seperated list of IP address on which the server should listen.
If unset, the defaults value is "0.0.0.0", or, if ngircd was compiled
with IPv6 support, "::,0.0.0.0", so the server listens on all configured
IP addresses and interfaces by default.
.TP
\fBMotdFile\fR
Text file with the "message of the day" (MOTD). This message will be shown
@@ -81,7 +106,8 @@ to all users connecting to the server.
.TP
\fBMotdPhrase\fR
A simple Phrase (<256 chars) if you don't want to use a MOTD file.
If it is set no MotdFile will be read at all.
If it is set no MotdFile will be read at all which can be handy if the
daemon should run inside a chroot directory.
.TP
\fBServerUID\fR
User ID under which the server should run; you can use the name of the user
@@ -146,18 +172,51 @@ If OperCanUseMode is enabled, this may lead the compatibility problems with
Servers that run the ircd-irc2 Software. This Option "masks" mode requests
by non-chanops as if they were coming from the server. Default: no.
.TP
\fBPredefChannelsOnly\fR
If enabled, no new channels can be created. Useful if
you do not want to have channels other than those defined in
the config file.
Default: No.
.TP
\fBNoDNS\fR
If set to true, ngircd will not make DNS lookups when clients connect.
If you configure ngircd to connect to other servers, ngircd may still
perform a DNS lookup if required.
Default: false.
.TP
\fBNoIdent\fR
If ngircd is compiled with IDENT support this can be used to disable IDENT
lookups at run time.
Default: false.
.TP
\fBConnectIPv4\fR
Set this to no if you do not want ngircd to connect to other irc servers using ipv4.
This allows use of ngircd in ipv6-only setups.
Default: Yes.
.TP
\fBConnectIPv6\fR
Set this to no if you do not want ngircd to connect to other irc servers using ipv6.
Default: Yes.
.TP
\fBMaxConnections\fR
Maximum number of simultaneous connection the server is allowed to accept
(<=0: unlimited). Default: -1.
Maximum number of simultaneous in- and outbound connections the server is
allowed to accept (0: unlimited). Default: 0.
.TP
\fBMaxConnectionsIP\fR
Maximum number of simultaneous connections from a single IP address that
the server will accept (<=0: unlimited). This configuration options lowers
the server will accept (0: unlimited). This configuration options lowers
the risk of denial of service attacks (DoS). Default: 5.
.TP
\fBMaxJoins\fR
Maximum number of channels a user can be member of (<=0: no limit).
Maximum number of channels a user can be member of (0: no limit).
Default: 10.
.TP
\fBMaxNickLength\fR
Maximum length of an user nick name (Default: 9, as in RFC 2812). Please
note that all servers in an IRC network MUST use the same maximum nick name
length!
\fBSSLConnect\fR
Connect to the remote server using TLS/SSL (Default: false)
.SH [OPERATOR]
.I [Operator]
sections are used to define IRC Operators. There may be more than one
@@ -177,27 +236,34 @@ Example: nick!ident@*.example.com
Other servers are configured in
.I [Server]
sections. If you configure a port for the connection, then this ngIRCd
tries to connect to to the other server on the given port; if not, it waits
for the other server to connect.
tries to connect to to the other server on the given port (active);
if not, it waits for the other server to connect (passive).
.PP
The ngIRCd allows "server groups": You can assign an "ID" to every server
with which you want this ngIRCd to link. If a server of a group won't
answer, the ngIRCd tries to connect to the next server in the given group.
But ngIRCd never tries to connect to two servers with the same group ID.
ngIRCd supports "server groups": You can assign an "ID" to every server
with which you want this ngIRCd to link, and the daemon ensures that at
any given time only one direct link exists to servers with the same ID.
So if a server of a group won't answer, ngIRCd tries to connect to the next
server in the given group (="with the same ID"), but never tries to connect
to more than one server of this group simultaneously.
.PP
There may be more than one
.I [Server]
block.
.TP
\fBName\fR
IRC name of the server
IRC name of the remote server.
.TP
\fBHost\fR
Internet host name of the peer
Internet host name (or IP address) of the peer.
.TP
\fBBind\fR
IP address to use as source IP for the outgoing connection. Default ist
to let the operating system decide.
.TP
\fBPort\fR
Port of the server to which the ngIRCd should connect. If you assign no port
the ngIRCd waits for incoming connections.
Port of the remote server to which ngIRCd should connect (active).
If no port is assigned to a configured server, the daemon only waits for
incoming connections (passive).
.TP
\fBMyPassword\fR
Own password for this connection. This password has to be configured as
@@ -209,6 +275,20 @@ Foreign password for this connection. This password has to be configured as
.TP
\fBGroup\fR
Group of this server (optional).
.TP
\fBPassive\fR
Disable automatic connection even if port value is specified. Default: false.
You can use the IRC Operator command CONNECT later on to create the link.
.TP
\fBServiceMask\fR
Define a (case insensitive) mask matching nick names that sould be treated as
IRC services when introduced via this remote server. REGULAR SERVERS DON'T NEED
this parameter, so leave it empty (which is the default).
.PP
.RS
When you are connecting IRC services which mask as a IRC server and which use
"virtual users" to communicate with, for example "NickServ" amd "ChanServ",
you should set this parameter to something like "*Serv".
.SH [CHANNEL]
Pre-defined channels can be configured in
.I [Channel]
@@ -223,15 +303,21 @@ There may be more than one
block.
.TP
\fBName\fR
Name of the channel
Name of the channel, including channel prefix ("#").
.TP
\fBTopic\fR
Topic for this channel
Topic for this channel.
.TP
\fBModes\fR
Initial channel modes.
.TP
\fBKey\fR
Sets initial channel key (only relevant if mode k is set).
.TP
\fBMaxUsers\fR
Set maximum user limit for this channel (only relevant if mode l is set).
.SH HINTS
It's wise to use "ngircd --configtest" to validate the configuration file
It's wise to use "ngircd \-\-configtest" to validate the configuration file
after changing it. See
.BR ngircd (8)
for details.

4
src/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
config.h
config.h.in
config.h.in~
stamp-h1

View File

@@ -8,10 +8,10 @@
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
# $Id: Makefile.am,v 1.7 2005/07/22 21:01:03 alex Exp $
# $Id: Makefile.am,v 1.8 2008/02/26 22:04:15 fw Exp $
#
SUBDIRS = portab tool ngircd testsuite
SUBDIRS = portab tool ipaddr ngircd testsuite
maintainer-clean-local:
rm -f Makefile Makefile.in config.h config.h.in stamp-h.in

14
src/ipaddr/Makefile.am Normal file
View File

@@ -0,0 +1,14 @@
AUTOMAKE_OPTIONS = ansi2knr
INCLUDES = -I$(srcdir)/../portab
noinst_LIBRARIES = libngipaddr.a
libngipaddr_a_SOURCES = ng_ipaddr.c
noinst_HEADERS = ng_ipaddr.h
maintainer-clean-local:
rm -f Makefile Makefile.in
# -eof-

167
src/ipaddr/ng_ipaddr.c Normal file
View File

@@ -0,0 +1,167 @@
/*
* Functions for AF_ agnostic ipv4/ipv6 handling.
*
* (c) 2008 Florian Westphal <fw@strlen.de>, public domain.
*/
#include "portab.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_GETADDRINFO
#include <netdb.h>
#include <sys/types.h>
#endif
#include "ng_ipaddr.h"
GLOBAL bool
ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
{
#ifdef HAVE_GETADDRINFO
int ret;
char portstr[64];
struct addrinfo *res0;
struct addrinfo hints;
assert(ip_str);
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICHOST;
/* some getaddrinfo implementations require that ai_socktype is set. */
hints.ai_socktype = SOCK_STREAM;
/* silly, but ngircd stores UINT16 in server config, not string */
snprintf(portstr, sizeof(portstr), "%u", (unsigned int) port);
ret = getaddrinfo(ip_str, portstr, &hints, &res0);
assert(ret == 0);
if (ret != 0)
return false;
assert(sizeof(*addr) >= res0->ai_addrlen);
if (sizeof(*addr) >= res0->ai_addrlen)
memcpy(addr, res0->ai_addr, res0->ai_addrlen);
else
ret = -1;
freeaddrinfo(res0);
return ret == 0;
#else /* HAVE_GETADDRINFO */
assert(ip_str);
addr->sin4.sin_family = AF_INET;
# ifdef HAVE_INET_ATON
if (inet_aton(ip_str, &addr->sin4.sin_addr) == 0)
return false;
# else
addr->sin4.sin_addr.s_addr = inet_addr(ip_str);
if (addr->sin4.sin_addr.s_addr == (unsigned) -1)
return false;
# endif
ng_ipaddr_setport(addr, port);
return true;
#endif /* HAVE_GETADDRINFO */
}
GLOBAL void
ng_ipaddr_setport(ng_ipaddr_t *a, UINT16 port)
{
#ifdef WANT_IPV6
int af;
assert(a != NULL);
af = a->sa.sa_family;
assert(af == AF_INET || af == AF_INET6);
switch (af) {
case AF_INET:
a->sin4.sin_port = htons(port);
break;
case AF_INET6:
a->sin6.sin6_port = htons(port);
break;
}
#else /* WANT_IPV6 */
assert(a != NULL);
assert(a->sin4.sin_family == AF_INET);
a->sin4.sin_port = htons(port);
#endif /* WANT_IPV6 */
}
GLOBAL bool
ng_ipaddr_ipequal(const ng_ipaddr_t *a, const ng_ipaddr_t *b)
{
assert(a != NULL);
assert(b != NULL);
#ifdef WANT_IPV6
if (a->sa.sa_family != b->sa.sa_family)
return false;
assert(ng_ipaddr_salen(a) == ng_ipaddr_salen(b));
switch (a->sa.sa_family) {
case AF_INET6:
return IN6_ARE_ADDR_EQUAL(&a->sin6.sin6_addr, &b->sin6.sin6_addr);
case AF_INET:
return memcmp(&a->sin4.sin_addr, &b->sin4.sin_addr, sizeof(a->sin4.sin_addr)) == 0;
}
return false;
#else
assert(a->sin4.sin_family == AF_INET);
assert(b->sin4.sin_family == AF_INET);
return memcmp(&a->sin4.sin_addr, &b->sin4.sin_addr, sizeof(a->sin4.sin_addr)) == 0;
#endif
}
#ifdef WANT_IPV6
GLOBAL const char *
ng_ipaddr_tostr(const ng_ipaddr_t *addr)
{
static char strbuf[NG_INET_ADDRSTRLEN];
strbuf[0] = 0;
ng_ipaddr_tostr_r(addr, strbuf);
return strbuf;
}
/* str must be at least NG_INET_ADDRSTRLEN bytes long */
GLOBAL bool
ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *str)
{
#ifdef HAVE_GETNAMEINFO
const struct sockaddr *sa = (const struct sockaddr *) addr;
int ret;
*str = 0;
ret = getnameinfo(sa, ng_ipaddr_salen(addr),
str, NG_INET_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
/*
* avoid leading ':'.
* causes mis-interpretation of client host in e.g. /WHOIS
*/
if (*str == ':') {
char tmp[NG_INET_ADDRSTRLEN] = "0";
ret = getnameinfo(sa, ng_ipaddr_salen(addr),
tmp+1, sizeof(tmp) -1, NULL, 0, NI_NUMERICHOST);
if (ret == 0)
strlcpy(str, tmp, NG_INET_ADDRSTRLEN);
}
assert (ret == 0);
return ret == 0;
#else
abort(); /* WANT_IPV6 depends on HAVE_GETNAMEINFO */
#endif
}
#endif /* WANT_IPV6 */
/* -eof- */

118
src/ipaddr/ng_ipaddr.h Normal file
View File

@@ -0,0 +1,118 @@
/*
* Functions for AF_ agnostic ipv4/ipv6 handling.
*
* (c) 2008 Florian Westphal <fw@strlen.de>, public domain.
*/
#ifndef NG_IPADDR_HDR
#define NG_IPADDR_HDR
#include "portab.h"
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#else
# define PF_INET AF_INET
#endif
#ifdef WANT_IPV6
#define NG_INET_ADDRSTRLEN INET6_ADDRSTRLEN
#else
#define NG_INET_ADDRSTRLEN 16
#endif
#ifdef WANT_IPV6
typedef union {
struct sockaddr sa;
struct sockaddr_in sin4;
struct sockaddr_in6 sin6;
} ng_ipaddr_t;
#else
/* assume compiler can't deal with typedef struct {... */
struct NG_IP_ADDR_DONTUSE {
struct sockaddr_in sin4;
};
typedef struct NG_IP_ADDR_DONTUSE ng_ipaddr_t;
#endif
static inline int
ng_ipaddr_af(const ng_ipaddr_t *a)
{
#ifdef WANT_IPV6
return a->sa.sa_family;
#else
assert(a->sin4.sin_family == 0 || a->sin4.sin_family == AF_INET);
return a->sin4.sin_family;
#endif
}
static inline socklen_t
ng_ipaddr_salen(const ng_ipaddr_t *a)
{
#ifdef WANT_IPV6
assert(a->sa.sa_family == AF_INET || a->sa.sa_family == AF_INET6);
if (a->sa.sa_family == AF_INET6)
return sizeof(a->sin6);
#endif
assert(a->sin4.sin_family == AF_INET);
return sizeof(a->sin4);
}
static inline UINT16
ng_ipaddr_getport(const ng_ipaddr_t *a)
{
#ifdef WANT_IPV6
int af = a->sa.sa_family;
assert(af == AF_INET || af == AF_INET6);
if (af == AF_INET6)
return ntohs(a->sin6.sin6_port);
#endif /* WANT_IPV6 */
assert(a->sin4.sin_family == AF_INET);
return ntohs(a->sin4.sin_port);
}
/*
* init a ng_ipaddr_t object.
* @param addr: pointer to ng_ipaddr_t to initialize.
* @param ip_str: ip address in dotted-decimal (ipv4) or hexadecimal (ipv6) notation
* @param port: transport layer port number to use.
*/
GLOBAL bool ng_ipaddr_init PARAMS((ng_ipaddr_t *addr, const char *ip_str, UINT16 port));
/* set sin4/sin6_port, depending on a->sa_family */
GLOBAL void ng_ipaddr_setport PARAMS((ng_ipaddr_t *a, UINT16 port));
/* return true if a and b have the same IP address. If a and b have different AF, return false. */
GLOBAL bool ng_ipaddr_ipequal PARAMS((const ng_ipaddr_t *a, const ng_ipaddr_t *b));
#ifdef WANT_IPV6
/* convert struct sockaddr to string, returns pointer to static buffer */
GLOBAL const char *ng_ipaddr_tostr PARAMS((const ng_ipaddr_t *addr));
/* convert struct sockaddr to string. dest must be NG_INET_ADDRSTRLEN bytes long */
GLOBAL bool ng_ipaddr_tostr_r PARAMS((const ng_ipaddr_t *addr, char *dest));
#else
static inline const char *
ng_ipaddr_tostr(const ng_ipaddr_t *addr) { return inet_ntoa(addr->sin4.sin_addr); }
static inline bool
ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *d)
{
strlcpy(d, inet_ntoa(addr->sin4.sin_addr), NG_INET_ADDRSTRLEN);
return true;
}
#endif
#endif
/* -eof- */

3
src/ngircd/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
check-help
check-version
ngircd

View File

@@ -8,12 +8,12 @@
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
# $Id: Makefile.am,v 1.49 2006/03/11 01:48:50 alex Exp $
# $Id: Makefile.am,v 1.51 2008/02/26 22:04:17 fw Exp $
#
AUTOMAKE_OPTIONS = ../portab/ansi2knr
INCLUDES = -I$(srcdir)/../portab -I$(srcdir)/../tool
INCLUDES = -I$(srcdir)/../portab -I$(srcdir)/../tool -I$(srcdir)/../ipaddr
LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN \
-varuse -retvalother -emptyret -unrecog
@@ -21,22 +21,22 @@ LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN \
sbin_PROGRAMS = ngircd
ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.c \
conn-zip.c hash.c io.c irc.c irc-channel.c irc-info.c irc-login.c \
conn-ssl.c conn-zip.c hash.c io.c irc.c irc-channel.c irc-info.c irc-login.c \
irc-mode.c irc-op.c irc-oper.c irc-server.c irc-write.c lists.c log.c \
match.c parse.c rendezvous.c resolve.c
match.c numeric.c parse.c rendezvous.c resolve.c
ngircd_LDFLAGS = -L../portab -L../tool
ngircd_LDFLAGS = -L../portab -L../tool -L../ipaddr
ngircd_LDADD = -lngportab -lngtool
ngircd_LDADD = -lngportab -lngtool -lngipaddr
noinst_HEADERS = ngircd.h array.h channel.h client.h conf.h conn.h conn-func.h \
conn-zip.h hash.h io.h irc.h irc-channel.h irc-info.h irc-login.h \
irc-mode.h irc-op.h irc-oper.h irc-server.h irc-write.h lists.h log.h \
match.h parse.h rendezvous.h resolve.h \
defines.h messages.h
noinst_HEADERS = ngircd.h array.h channel.h client.h conf.h conf-ssl.h conn.h \
conn-func.h conn-ssl.h conn-zip.h hash.h io.h irc.h irc-channel.h \
irc-info.h irc-login.h irc-mode.h irc-op.h irc-oper.h irc-server.h \
irc-write.h lists.h log.h match.h numeric.h parse.h rendezvous.h \
resolve.h defines.h messages.h
clean-local:
rm -f check-version check-help lint.out cvs-version.*
rm -f check-version check-help lint.out
maintainer-clean-local:
rm -f Makefile Makefile.in
@@ -77,23 +77,6 @@ lint:
|| echo "Result: no warnings found."; \
echo; [ $$warnings -gt 0 ] && exit 1
ngircd.c: cvs-version.h
irc-login.c: cvs-version.h
irc-info.c: cvs-version.h
cvs-version.h: cvs-date
cvs-date:
grep VERSION ../config.h | grep "CVS" \
&& echo "#define CVSDATE \"$$( grep "\$$Id" $(srcdir)/*.c \
| $(AWK) "{ print \$$9 }" | sort | tail -1 \
| sed -e "s/\//-/g" )\"" > cvs-version.new \
|| echo "" > cvs-version.new
diff cvs-version.h cvs-version.new 2>/dev/null \
|| cp cvs-version.new cvs-version.h
TESTS = check-version check-help
# -eof-

View File

@@ -12,7 +12,7 @@
#include "array.h"
static char UNUSED id[] = "$Id: array.c,v 1.11 2006/07/01 22:11:48 fw Exp $";
static char UNUSED id[] = "$Id: array.c,v 1.15 2007/11/18 15:05:35 alex Exp $";
#include <assert.h>
@@ -28,9 +28,9 @@ static char UNUSED id[] = "$Id: array.c,v 1.11 2006/07/01 22:11:48 fw Exp $";
#define array_UNUSABLE(x) ( !(x)->mem || (0 == (x)->allocated) )
#define ALIGN_32U(x) (((x)+31U ) & ~(31U))
#define ALIGN_1024U(x) (((x)+1023U) & ~(1023U))
#define ALIGN_4096U(x) (((x)+4095U) & ~(4095U))
#define ALIGN_32U(x) (((x)+(unsigned)31 ) & ~((unsigned)31))
#define ALIGN_1024U(x) (((x)+(unsigned)1023) & ~((unsigned)1023))
#define ALIGN_4096U(x) (((x)+(unsigned)4095) & ~((unsigned)4095))
static bool
@@ -66,10 +66,7 @@ array_alloc(array * a, size_t size, size_t pos)
assert(size > 0);
if (pos_plus1 < pos)
return NULL;
if (!safemult_sizet(size, pos_plus1, &alloc))
if (pos_plus1 == 0 || !safemult_sizet(size, pos_plus1, &alloc))
return NULL;
if (a->allocated < alloc) {
@@ -250,20 +247,22 @@ void *
array_get(array * a, size_t membersize, size_t pos)
{
size_t totalsize;
size_t posplus1 = pos + 1;
assert(membersize > 0);
assert(a != NULL);
if (array_UNUSABLE(a))
if (!posplus1 || array_UNUSABLE(a))
return NULL;
if (!safemult_sizet(pos, membersize, &totalsize))
if (!safemult_sizet(posplus1, membersize, &totalsize))
return NULL;
if (a->allocated < totalsize)
return NULL;
return a->mem + pos * membersize;
totalsize = pos * membersize;
return a->mem + totalsize;
}
@@ -271,7 +270,7 @@ void
array_free(array * a)
{
assert(a != NULL);
#ifdef DEBUG
#ifdef DEBUG_ARRAY
Log(LOG_DEBUG,
"array_free(): %u bytes free'd (%u bytes still used at time of free()).",
a->allocated, a->used);
@@ -282,17 +281,15 @@ array_free(array * a)
a->used = 0;
}
void
array_free_wipe(array * a)
array_free_wipe(array *a)
{
if (!array_UNUSABLE(a))
memset(a->mem, 0, a->allocated);
size_t bytes = a->allocated;
if (bytes)
memset(a->mem, 0, bytes);
array_free(a);
}
void *
array_start(const array * const a)
{
@@ -331,9 +328,6 @@ array_moveleft(array * a, size_t membersize, size_t pos)
assert(a != NULL);
assert(membersize > 0);
if (!pos)
return;
if (!safemult_sizet(membersize, pos, &bytepos)) {
a->used = 0;
return;

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2005 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 by Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,8 +17,6 @@
#include "portab.h"
static char UNUSED id[] = "$Id: channel.c,v 1.56 2006/07/24 22:54:09 alex Exp $";
#include "imp.h"
#include <assert.h>
#include <stdlib.h>
@@ -56,7 +54,7 @@ static CL2CHAN *My_Cl2Chan;
static CL2CHAN *Get_Cl2Chan PARAMS(( CHANNEL *Chan, CLIENT *Client ));
static CL2CHAN *Add_Client PARAMS(( CHANNEL *Chan, CLIENT *Client ));
static bool Remove_Client PARAMS(( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, char *Reason, bool InformServer ));
static bool Remove_Client PARAMS(( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const char *Reason, bool InformServer ));
static CL2CHAN *Get_First_Cl2Chan PARAMS(( CLIENT *Client, CHANNEL *Chan ));
static CL2CHAN *Get_Next_Cl2Chan PARAMS(( CL2CHAN *Start, CLIENT *Client, CHANNEL *Chan ));
static bool Delete_Channel PARAMS(( CHANNEL *Chan ));
@@ -65,26 +63,50 @@ static bool Delete_Channel PARAMS(( CHANNEL *Chan ));
GLOBAL void
Channel_Init( void )
{
CHANNEL *sc;
My_Channels = NULL;
My_Cl2Chan = NULL;
sc = Channel_Create("&SERVER");
if (sc) {
Channel_SetModes(sc, "mnPt");
Channel_SetTopic(sc, Client_ThisServer(), "Server Messages");
}
} /* Channel_Init */
GLOBAL struct list_head *
Channel_GetListBans(CHANNEL *c)
{
assert(c != NULL);
return &c->list_bans;
}
GLOBAL struct list_head *
Channel_GetListInvites(CHANNEL *c)
{
assert(c != NULL);
return &c->list_invites;
}
GLOBAL void
Channel_InitPredefined( void )
{
/* Vordefinierte persistente Channels erzeugen */
/* Generate predefined persistent channels */
CHANNEL *chan;
char *c;
unsigned int i;
for( i = 0; i < Conf_Channel_Count; i++ )
{
/* Ist ein Name konfiguriert? */
/* Check for Name configuration */
if( ! Conf_Channel[i].name[0] ) continue;
/* Gueltiger Channel-Name? */
/* Check for invalid channel name */
if( ! Channel_IsValidName( Conf_Channel[i].name ))
{
Log( LOG_ERR, "Can't create pre-defined channel: invalid name: \"%s\"!", Conf_Channel[i].name );
@@ -92,7 +114,7 @@ Channel_InitPredefined( void )
continue;
}
/* Gibt es den Channel bereits? */
/* Check if the channel name is already in use */
chan = Channel_Search( Conf_Channel[i].name );
if( chan )
{
@@ -114,7 +136,10 @@ Channel_InitPredefined( void )
c = Conf_Channel[i].modes;
while (*c)
Channel_ModeAdd(chan, *c++);
Channel_SetKey(chan, Conf_Channel[i].key);
Channel_SetMaxUsers(chan, Conf_Channel[i].maxusers);
Log(LOG_INFO, "Created pre-defined channel \"%s\".",
Conf_Channel[i].name );
}
@@ -129,8 +154,8 @@ Channel_Exit( void )
{
CHANNEL *c, *c_next;
CL2CHAN *cl2chan, *cl2chan_next;
/* Channel-Strukturen freigeben */
/* free struct Channel */
c = My_Channels;
while( c )
{
@@ -140,7 +165,7 @@ Channel_Exit( void )
c = c_next;
}
/* Channel-Zuordnungstabelle freigeben */
/* Free Channel allocation table */
cl2chan = My_Cl2Chan;
while( c )
{
@@ -151,70 +176,105 @@ Channel_Exit( void )
} /* Channel_Exit */
/**
* Join Channel
* This function lets a client join a channel. First, the function
* checks that the specified channel name is valid and that the client
* isn't already a member. If the specified channel doesn't exist,
* a new channel is created. Client is added to channel by function
* Add_Client().
*/
GLOBAL bool
Channel_Join( CLIENT *Client, char *Name )
{
CHANNEL *chan;
assert( Client != NULL );
assert( Name != NULL );
if( ! Channel_IsValidName( Name )) {
IRC_WriteStrClient( Client, ERR_NOSUCHCHANNEL_MSG, Client_ID( Client ), Name );
assert(Client != NULL);
assert(Name != NULL);
/* Check that the channel name is valid */
if (! Channel_IsValidName(Name)) {
IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG,
Client_ID(Client), Name);
return false;
}
chan = Channel_Search( Name );
if( chan ) {
/* Ist der Client bereits Mitglied? */
if( Get_Cl2Chan( chan, Client )) return false;
}
else
{
/* Gibt es noch nicht? Dann neu anlegen: */
chan = Channel_Create( Name );
if( ! chan ) return false;
chan = Channel_Search(Name);
if(chan) {
/* Check if the client is already in the channel */
if (Get_Cl2Chan(chan, Client))
return false;
} else {
/* If the specified channel does not exist, the channel
* is now created */
chan = Channel_Create(Name);
if (!chan)
return false;
}
/* User dem Channel hinzufuegen */
if( ! Add_Client( chan, Client )) return false;
else return true;
/* Add user to Channel */
if (! Add_Client(chan, Client))
return false;
return true;
} /* Channel_Join */
/**
* Part client from channel.
* This function lets a client part from a channel. First, the function checks
* if the channel exists and the client is a member of it and sends out
* appropriate error messages if not. The real work is done by the function
* Remove_Client().
*/
GLOBAL bool
Channel_Part( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason )
Channel_Part(CLIENT * Client, CLIENT * Origin, const char *Name, const char *Reason)
{
CHANNEL *chan;
assert( Client != NULL );
assert( Name != NULL );
assert( Reason != NULL );
assert(Client != NULL);
assert(Name != NULL);
assert(Reason != NULL);
chan = Channel_Search( Name );
if(( ! chan ) || ( ! Get_Cl2Chan( chan, Client )))
{
IRC_WriteStrClient( Client, ERR_NOSUCHCHANNEL_MSG, Client_ID( Client ), Name );
/* Check that specified channel exists */
chan = Channel_Search(Name);
if (!chan) {
IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG,
Client_ID(Client), Name);
return false;
}
/* User aus Channel entfernen */
if( ! Remove_Client( REMOVE_PART, chan, Client, Origin, Reason, true)) return false;
else return true;
/* Check that the client is in the channel */
if (!Get_Cl2Chan(chan, Client)) {
IRC_WriteStrClient(Client, ERR_NOTONCHANNEL_MSG,
Client_ID(Client), Name);
return false;
}
/* Part client from channel */
if (!Remove_Client(REMOVE_PART, chan, Client, Origin, Reason, true))
return false;
else
return true;
} /* Channel_Part */
/**
* Kick user from Channel
*/
GLOBAL void
Channel_Kick( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason )
Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
const char *Reason )
{
CHANNEL *chan;
assert( Client != NULL );
assert( Origin != NULL );
assert( Name != NULL );
assert( Reason != NULL );
assert(Peer != NULL);
assert(Target != NULL);
assert(Origin != NULL);
assert(Name != NULL);
assert(Reason != NULL);
/* Channel suchen */
/* Check that channel exists */
chan = Channel_Search( Name );
if( ! chan )
{
@@ -222,27 +282,32 @@ Channel_Kick( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason )
return;
}
if( ! Channel_IsMemberOf( chan, Origin ))
{
IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG, Client_ID( Origin ), Name );
if (Client_Type(Peer) != CLIENT_SERVER &&
Client_Type(Origin) != CLIENT_SERVICE) {
/* Check that user is on the specified channel */
if (!Channel_IsMemberOf(chan, Origin)) {
IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG,
Client_ID(Origin), Name);
return;
}
/* Check if user has operator status */
if (!strchr(Channel_UserModes(chan, Origin), 'o')) {
IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin), Name);
return;
}
}
/* Check that the client to be kicked is on the specified channel */
if (!Channel_IsMemberOf(chan, Target)) {
IRC_WriteStrClient(Origin, ERR_USERNOTINCHANNEL_MSG,
Client_ID(Origin), Client_ID(Target), Name );
return;
}
/* Is User Channel-Operator? */
if( ! strchr( Channel_UserModes( chan, Origin ), 'o' ))
{
IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Name);
return;
}
/* Ist the kickED User member of channel? */
if( ! Channel_IsMemberOf( chan, Client ))
{
IRC_WriteStrClient( Origin, ERR_USERNOTINCHANNEL_MSG, Client_ID( Origin ), Client_ID( Client ), Name );
return;
}
Remove_Client( REMOVE_KICK, chan, Client, Origin, Reason, true);
/* Kick Client from channel */
Remove_Client( REMOVE_KICK, chan, Target, Origin, Reason, true);
} /* Channel_Kick */
@@ -266,12 +331,12 @@ Channel_Quit( CLIENT *Client, char *Reason )
} /* Channel_Quit */
GLOBAL long
GLOBAL unsigned long
Channel_Count( void )
{
CHANNEL *c;
long count = 0;
unsigned long count = 0;
c = My_Channels;
while( c )
{
@@ -282,11 +347,11 @@ Channel_Count( void )
} /* Channel_Count */
GLOBAL long
GLOBAL unsigned long
Channel_MemberCount( CHANNEL *Chan )
{
CL2CHAN *cl2chan;
long count = 0;
unsigned long count = 0;
assert( Chan != NULL );
@@ -307,9 +372,9 @@ Channel_CountForUser( CLIENT *Client )
CL2CHAN *cl2chan;
int count = 0;
assert( Client != NULL );
cl2chan = My_Cl2Chan;
while( cl2chan )
{
@@ -321,27 +386,8 @@ Channel_CountForUser( CLIENT *Client )
} /* Channel_CountForUser */
GLOBAL int
Channel_PCount( void )
{
/* Count the number of persistent (mode 'P') channels */
CHANNEL *chan;
int count = 0;
chan = My_Channels;
while( chan )
{
if( strchr( chan->modes, 'P' )) count++;
chan = chan->next;
}
return count;
} /* Channel_PCount */
GLOBAL char *
Channel_Name( CHANNEL *Chan )
GLOBAL const char *
Channel_Name( const CHANNEL *Chan )
{
assert( Chan != NULL );
return Chan->name;
@@ -364,7 +410,7 @@ Channel_Key( CHANNEL *Chan )
} /* Channel_Key */
GLOBAL long
GLOBAL unsigned long
Channel_MaxUsers( CHANNEL *Chan )
{
assert( Chan != NULL );
@@ -388,10 +434,10 @@ Channel_Next( CHANNEL *Chan )
GLOBAL CHANNEL *
Channel_Search( char *Name )
Channel_Search( const char *Name )
{
/* Channel-Struktur suchen */
/* Search channel structure */
CHANNEL *c;
UINT32 search_hash;
@@ -403,7 +449,7 @@ Channel_Search( char *Name )
{
if( search_hash == c->hash )
{
/* lt. Hash-Wert: Treffer! */
/* hash hit */
if( strcasecmp( Name, c->name ) == 0 ) return c;
}
c = c->next;
@@ -463,25 +509,20 @@ Channel_GetChannel( CL2CHAN *Cl2Chan )
GLOBAL bool
Channel_IsValidName( char *Name )
Channel_IsValidName( const char *Name )
{
/* Pruefen, ob Name als Channelname gueltig */
char *ptr, badchars[10];
assert( Name != NULL );
if(( Name[0] != '#' ) || ( strlen( Name ) >= CHANNEL_NAME_LEN )) return false;
#ifdef STRICT_RFC
if (strlen(Name) <= 1)
return false;
#endif
if (strchr("#&+", Name[0]) == NULL)
return false;
if (strlen(Name) >= CHANNEL_NAME_LEN)
return false;
ptr = Name;
strcpy( badchars, " ,:\007" );
while( *ptr )
{
if( strchr( badchars, *ptr )) return false;
ptr++;
}
return true;
return Name[strcspn(Name, " ,:\007")] == 0;
} /* Channel_IsValidName */
@@ -548,7 +589,7 @@ Channel_UserModeAdd( CHANNEL *Chan, CLIENT *Client, char Mode )
cl2chan = Get_Cl2Chan( Chan, Client );
assert( cl2chan != NULL );
x[0] = Mode; x[1] = '\0';
if( ! strchr( cl2chan->modes, x[0] ))
{
@@ -594,7 +635,7 @@ GLOBAL char *
Channel_UserModes( CHANNEL *Chan, CLIENT *Client )
{
/* return Users' Channel-Modes */
CL2CHAN *cl2chan;
assert( Chan != NULL );
@@ -614,9 +655,7 @@ Channel_IsMemberOf( CHANNEL *Chan, CLIENT *Client )
assert( Chan != NULL );
assert( Client != NULL );
if( Get_Cl2Chan( Chan, Client )) return true;
else return false;
return Get_Cl2Chan(Chan, Client) != NULL;
} /* Channel_IsMemberOf */
@@ -629,7 +668,7 @@ Channel_Topic( CHANNEL *Chan )
return ret ? ret : "";
} /* Channel_Topic */
#ifndef STRICT_RFC
GLOBAL unsigned int
@@ -661,12 +700,9 @@ Channel_SetTopic(CHANNEL *Chan, CLIENT *Client, char *Topic)
if (len < array_bytes(&Chan->topic))
array_free(&Chan->topic);
if (!array_copyb(&Chan->topic, Topic, len))
if (len >= COMMAND_LEN || !array_copyb(&Chan->topic, Topic, len+1))
Log(LOG_WARNING, "could not set new Topic \"%s\" on %s: %s",
Topic, Chan->name, strerror(errno));
array_cat0(&Chan->topic);
#ifndef STRICT_RFC
Chan->topic_time = time(NULL);
if (Client != NULL && Client_Type(Client) != CLIENT_SERVER)
@@ -698,52 +734,75 @@ Channel_SetKey( CHANNEL *Chan, char *Key )
assert( Key != NULL );
strlcpy( Chan->key, Key, sizeof( Chan->key ));
Log( LOG_DEBUG, "Channel %s: Key is now \"%s\".", Chan->name, Chan->key );
LogDebug("Channel %s: Key is now \"%s\".", Chan->name, Chan->key );
} /* Channel_SetKey */
GLOBAL void
Channel_SetMaxUsers( CHANNEL *Chan, long Count )
Channel_SetMaxUsers(CHANNEL *Chan, unsigned long Count)
{
assert( Chan != NULL );
Chan->maxusers = Count;
Log( LOG_DEBUG, "Channel %s: Member limit is now %ld.", Chan->name, Chan->maxusers );
LogDebug("Channel %s: Member limit is now %lu.", Chan->name, Chan->maxusers );
} /* Channel_SetMaxUsers */
GLOBAL bool
Channel_Write( CHANNEL *Chan, CLIENT *From, CLIENT *Client, char *Text )
static bool
Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
{
bool is_member, has_voice, is_op, ok;
bool is_member, has_voice, is_op;
/* Okay, target is a channel */
is_member = has_voice = is_op = false;
if( Channel_IsMemberOf( Chan, From ))
{
/* The server itself always can send messages :-) */
if (Client_ThisServer() == From)
return true;
if (Channel_IsMemberOf(Chan, From)) {
is_member = true;
if( strchr( Channel_UserModes( Chan, From ), 'v' )) has_voice = true;
if( strchr( Channel_UserModes( Chan, From ), 'o' )) is_op = true;
if (strchr(Channel_UserModes(Chan, From), 'v'))
has_voice = true;
if (strchr(Channel_UserModes(Chan, From), 'o'))
is_op = true;
}
/* Is the client allowed to write to channel? */
ok = true;
if( strchr( Channel_Modes( Chan ), 'n' ) && ( ! is_member )) ok = false;
if( strchr( Channel_Modes( Chan ), 'm' ) && ( ! is_op ) && ( ! has_voice )) ok = false;
/* Is the client banned? */
if( Lists_CheckBanned( From, Chan ))
{
/* Client is banned, but is he channel operator or has voice? */
if(( ! has_voice ) && ( ! is_op )) ok = false;
/*
* Is the client allowed to write to channel?
*
* If channel mode n set: non-members cannot send to channel.
* If channel mode m set: need voice.
*/
if (strchr(Channel_Modes(Chan), 'n') && !is_member)
return false;
if (is_op || has_voice)
return true;
if (strchr(Channel_Modes(Chan), 'm'))
return false;
return !Lists_Check(&Chan->list_bans, From);
}
GLOBAL bool
Channel_Write(CHANNEL *Chan, CLIENT *From, CLIENT *Client, const char *Command,
bool SendErrors, const char *Text)
{
if (!Can_Send_To_Channel(Chan, From)) {
if (! SendErrors)
return CONNECTED; /* no error, see RFC 2812 */
return IRC_WriteStrClient(From, ERR_CANNOTSENDTOCHAN_MSG,
Client_ID(From), Channel_Name(Chan));
}
if( ! ok ) return IRC_WriteStrClient( From, ERR_CANNOTSENDTOCHAN_MSG, Client_ID( From ), Channel_Name( Chan ));
if (Client_Conn(From) > NONE)
Conn_UpdateIdle(Client_Conn(From));
/* Send text */
if( Client_Conn( From ) > NONE ) Conn_UpdateIdle( Client_Conn( From ));
return IRC_WriteStrChannelPrefix( Client, Chan, From, true, "PRIVMSG %s :%s", Channel_Name( Chan ), Text );
} /* Channel_Write */
return IRC_WriteStrChannelPrefix(Client, Chan, From, true,
"%s %s :%s", Command, Channel_Name(Chan), Text);
}
GLOBAL CHANNEL *
@@ -753,7 +812,7 @@ Channel_Create( char *Name )
CHANNEL *c;
assert( Name != NULL );
c = (CHANNEL *)malloc( sizeof( CHANNEL ));
if( ! c )
{
@@ -765,9 +824,7 @@ Channel_Create( char *Name )
c->hash = Hash( c->name );
c->next = My_Channels;
My_Channels = c;
#ifdef DEBUG
Log( LOG_DEBUG, "Created new channel structure for \"%s\".", Name );
#endif
LogDebug("Created new channel structure for \"%s\".", Name);
return c;
} /* Channel_Create */
@@ -798,7 +855,7 @@ Add_Client( CHANNEL *Chan, CLIENT *Client )
assert( Chan != NULL );
assert( Client != NULL );
/* neue CL2CHAN-Struktur anlegen */
/* Create new CL2CHAN structure */
cl2chan = (CL2CHAN *)malloc( sizeof( CL2CHAN ));
if( ! cl2chan )
{
@@ -809,7 +866,7 @@ Add_Client( CHANNEL *Chan, CLIENT *Client )
cl2chan->client = Client;
strcpy( cl2chan->modes, "" );
/* Verketten */
/* concatenate */
cl2chan->next = My_Cl2Chan;
My_Cl2Chan = cl2chan;
@@ -820,16 +877,21 @@ Add_Client( CHANNEL *Chan, CLIENT *Client )
static bool
Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, char *Reason, bool InformServer )
Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const char *Reason, bool InformServer )
{
CL2CHAN *cl2chan, *last_cl2chan;
CHANNEL *c;
assert( Chan != NULL );
assert( Client != NULL );
assert( Origin != NULL );
assert( Reason != NULL );
/* Do not inform other servers if the channel is local to this server,
* regardless of what the caller requested! */
if(InformServer)
InformServer = !Channel_IsLocal(Chan);
last_cl2chan = NULL;
cl2chan = My_Cl2Chan;
while( cl2chan )
@@ -843,7 +905,7 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, char *Re
c = cl2chan->channel;
assert( c != NULL );
/* Aus Verkettung loesen und freigeben */
/* maintain cl2chan list */
if( last_cl2chan ) last_cl2chan->next = cl2chan->next;
else My_Cl2Chan = cl2chan->next;
free( cl2chan );
@@ -851,37 +913,138 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, char *Re
switch( Type )
{
case REMOVE_QUIT:
/* QUIT: andere Server wurden bereits informiert, vgl. Client_Destroy();
* hier also "nur" noch alle User in betroffenen Channeln infomieren */
/* QUIT: other servers have already been notified,
* see Client_Destroy(); so only inform other clients
* in same channel. */
assert( InformServer == false );
Log( LOG_DEBUG, "User \"%s\" left channel \"%s\" (%s).", Client_Mask( Client ), c->name, Reason );
LogDebug("User \"%s\" left channel \"%s\" (%s).",
Client_Mask( Client ), c->name, Reason );
break;
case REMOVE_KICK:
/* User wurde geKICKed: ggf. andere Server sowie alle betroffenen User
* im entsprechenden Channel informieren */
if( InformServer ) IRC_WriteStrServersPrefix( Client_NextHop( Origin ), Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason );
IRC_WriteStrChannelPrefix( Client, c, Origin, false, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason );
if(( Client_Conn( Client ) > NONE ) && ( Client_Type( Client ) == CLIENT_USER )) IRC_WriteStrClientPrefix( Client, Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason );
Log( LOG_DEBUG, "User \"%s\" has been kicked of \"%s\" by \"%s\": %s.", Client_Mask( Client ), c->name, Client_ID( Origin ), Reason );
/* User was KICKed: inform other servers (public
* channels) and all users in the channel */
if( InformServer )
IRC_WriteStrServersPrefix( Client_NextHop( Origin ),
Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason);
IRC_WriteStrChannelPrefix(Client, c, Origin, false, "KICK %s %s :%s",
c->name, Client_ID( Client ), Reason );
if ((Client_Conn(Client) > NONE) &&
(Client_Type(Client) == CLIENT_USER))
{
IRC_WriteStrClientPrefix(Client, Origin, "KICK %s %s :%s",
c->name, Client_ID( Client ), Reason);
}
LogDebug("User \"%s\" has been kicked off \"%s\" by \"%s\": %s.",
Client_Mask( Client ), c->name, Client_ID(Origin), Reason);
break;
default:
/* PART */
if( InformServer ) IRC_WriteStrServersPrefix( Origin, Client, "PART %s :%s", c->name, Reason );
IRC_WriteStrChannelPrefix( Origin, c, Client, false, "PART %s :%s", c->name, Reason );
if(( Client_Conn( Origin ) > NONE ) && ( Client_Type( Origin ) == CLIENT_USER )) IRC_WriteStrClientPrefix( Origin, Client, "PART %s :%s", c->name, Reason );
Log( LOG_DEBUG, "User \"%s\" left channel \"%s\" (%s).", Client_Mask( Client ), c->name, Reason );
default: /* PART */
if (InformServer)
IRC_WriteStrServersPrefix(Origin, Client, "PART %s :%s", c->name, Reason);
IRC_WriteStrChannelPrefix(Origin, c, Client, false, "PART %s :%s",
c->name, Reason);
if ((Client_Conn(Origin) > NONE) &&
(Client_Type(Origin) == CLIENT_USER))
{
IRC_WriteStrClientPrefix( Origin, Client, "PART %s :%s", c->name, Reason);
LogDebug("User \"%s\" left channel \"%s\" (%s).",
Client_Mask(Client), c->name, Reason);
}
}
/* Wenn Channel nun leer und nicht pre-defined: loeschen */
/* When channel is empty and is not pre-defined, delete */
if( ! strchr( Channel_Modes( Chan ), 'P' ))
{
if( ! Get_First_Cl2Chan( NULL, Chan )) Delete_Channel( Chan );
}
return true;
} /* Remove_Client */
GLOBAL bool
Channel_AddBan(CHANNEL *c, const char *mask )
{
struct list_head *h = Channel_GetListBans(c);
return Lists_Add(h, mask, false);
}
GLOBAL bool
Channel_AddInvite(CHANNEL *c, const char *mask, bool onlyonce)
{
struct list_head *h = Channel_GetListInvites(c);
return Lists_Add(h, mask, onlyonce);
}
static bool
ShowInvitesBans(struct list_head *head, CLIENT *Client, CHANNEL *Channel, bool invite)
{
struct list_elem *e;
char *msg = invite ? RPL_INVITELIST_MSG : RPL_BANLIST_MSG;
char *msg_end;
assert( Client != NULL );
assert( Channel != NULL );
e = Lists_GetFirst(head);
while (e) {
if( ! IRC_WriteStrClient( Client, msg, Client_ID( Client ),
Channel_Name( Channel ), Lists_GetMask(e) )) return DISCONNECTED;
e = Lists_GetNext(e);
}
msg_end = invite ? RPL_ENDOFINVITELIST_MSG : RPL_ENDOFBANLIST_MSG;
return IRC_WriteStrClient( Client, msg_end, Client_ID( Client ), Channel_Name( Channel ));
}
GLOBAL bool
Channel_ShowBans( CLIENT *Client, CHANNEL *Channel )
{
struct list_head *h;
assert( Channel != NULL );
h = Channel_GetListBans(Channel);
return ShowInvitesBans(h, Client, Channel, false);
}
GLOBAL bool
Channel_ShowInvites( CLIENT *Client, CHANNEL *Channel )
{
struct list_head *h;
assert( Channel != NULL );
h = Channel_GetListInvites(Channel);
return ShowInvitesBans(h, Client, Channel, true);
}
/**
* Log a message to the local &SERVER channel, if it exists.
*/
GLOBAL void
Channel_LogServer(char *msg)
{
CHANNEL *sc;
CLIENT *c;
assert(msg != NULL);
sc = Channel_Search("&SERVER");
if (!sc)
return;
c = Client_ThisServer();
Channel_Write(sc, c, c, "PRIVMSG", false, msg);
} /* Channel_LogServer */
static CL2CHAN *
Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan )
{
@@ -895,7 +1058,7 @@ Get_Next_Cl2Chan( CL2CHAN *Start, CLIENT *Client, CHANNEL *Channel )
CL2CHAN *cl2chan;
assert( Client != NULL || Channel != NULL );
cl2chan = Start;
while( cl2chan )
{
@@ -910,8 +1073,8 @@ Get_Next_Cl2Chan( CL2CHAN *Start, CLIENT *Client, CHANNEL *Channel )
static bool
Delete_Channel( CHANNEL *Chan )
{
/* Channel-Struktur loeschen */
/* delete channel structure */
CHANNEL *chan, *last_chan;
last_chan = NULL;
@@ -926,16 +1089,16 @@ Delete_Channel( CHANNEL *Chan )
Log( LOG_DEBUG, "Freed channel structure for \"%s\".", Chan->name );
/* Invite- und Ban-Lists aufraeumen */
Lists_DeleteChannel( chan );
/* free invite and ban lists */
Lists_Free( &chan->list_bans );
Lists_Free( &chan->list_invites );
/* Neu verketten und freigeben */
/* maintain channel list */
if( last_chan ) last_chan->next = chan->next;
else My_Channels = chan->next;
free( chan );
return true;
} /* Delete_Channel */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 by Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -8,8 +8,6 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: channel.h,v 1.29 2005/09/02 12:50:25 alex Exp $
*
* Channel management (header)
*/
@@ -20,6 +18,7 @@
#if defined(__channel_c__) | defined(S_SPLINT_S)
#include "lists.h"
#include "defines.h"
#include "array.h"
@@ -35,7 +34,9 @@ typedef struct _CHANNEL
char topic_who[CLIENT_NICK_LEN];/* Nickname of user that set topic */
#endif
char key[CLIENT_PASS_LEN]; /* Channel key ("password", mode "k" ) */
long maxusers; /* Maximum number of members (mode "l") */
unsigned long maxusers; /* Maximum number of members (mode "l") */
struct list_head list_bans; /* list head of banned users */
struct list_head list_invites; /* list head of invited users */
} CHANNEL;
typedef struct _CLIENT2CHAN
@@ -43,7 +44,7 @@ typedef struct _CLIENT2CHAN
struct _CLIENT2CHAN *next;
CLIENT *client;
CHANNEL *channel;
char modes[CHANNEL_MODE_LEN]; /* User-Modes in dem Channel */
char modes[CHANNEL_MODE_LEN]; /* User-Modes in Channel */
} CL2CHAN;
#else
@@ -53,35 +54,37 @@ typedef POINTER CL2CHAN;
#endif
GLOBAL struct list_head *Channel_GetListBans PARAMS((CHANNEL *c));
GLOBAL struct list_head *Channel_GetListInvites PARAMS((CHANNEL *c));
GLOBAL void Channel_Init PARAMS(( void ));
GLOBAL void Channel_InitPredefined PARAMS(( void ));
GLOBAL void Channel_Exit PARAMS(( void ));
GLOBAL bool Channel_Join PARAMS(( CLIENT *Client, char *Name ));
GLOBAL bool Channel_Part PARAMS(( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason ));
GLOBAL bool Channel_Part PARAMS(( CLIENT *Client, CLIENT *Origin, const char *Name, const char *Reason ));
GLOBAL void Channel_Quit PARAMS(( CLIENT *Client, char *Reason ));
GLOBAL void Channel_Kick PARAMS(( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason ));
GLOBAL void Channel_Kick PARAMS((CLIENT *Peer, CLIENT *Target, CLIENT *Origin,
const char *Name, const char *Reason));
GLOBAL long Channel_Count PARAMS(( void ));
GLOBAL long Channel_MemberCount PARAMS(( CHANNEL *Chan ));
GLOBAL unsigned long Channel_Count PARAMS(( void ));
GLOBAL unsigned long Channel_MemberCount PARAMS(( CHANNEL *Chan ));
GLOBAL int Channel_CountForUser PARAMS(( CLIENT *Client ));
GLOBAL int Channel_PCount PARAMS(( void ));
GLOBAL char *Channel_Name PARAMS(( CHANNEL *Chan ));
GLOBAL const char *Channel_Name PARAMS(( const CHANNEL *Chan ));
GLOBAL char *Channel_Modes PARAMS(( CHANNEL *Chan ));
GLOBAL char *Channel_Topic PARAMS(( CHANNEL *Chan ));
GLOBAL char *Channel_Key PARAMS(( CHANNEL *Chan ));
GLOBAL long Channel_MaxUsers PARAMS(( CHANNEL *Chan ));
GLOBAL unsigned long Channel_MaxUsers PARAMS(( CHANNEL *Chan ));
GLOBAL void Channel_SetTopic PARAMS(( CHANNEL *Chan, CLIENT *Client, char *Topic ));
GLOBAL void Channel_SetModes PARAMS(( CHANNEL *Chan, char *Modes ));
GLOBAL void Channel_SetKey PARAMS(( CHANNEL *Chan, char *Key ));
GLOBAL void Channel_SetMaxUsers PARAMS(( CHANNEL *Chan, long Count ));
GLOBAL void Channel_SetMaxUsers PARAMS(( CHANNEL *Chan, unsigned long Count ));
GLOBAL CHANNEL *Channel_Search PARAMS(( char *Name ));
GLOBAL CHANNEL *Channel_Search PARAMS(( const char *Name ));
GLOBAL CHANNEL *Channel_First PARAMS(( void ));
GLOBAL CHANNEL *Channel_Next PARAMS(( CHANNEL *Chan ));
@@ -94,7 +97,7 @@ GLOBAL CL2CHAN *Channel_NextChannelOf PARAMS(( CLIENT *Client, CL2CHAN *Cl2Chan
GLOBAL CLIENT *Channel_GetClient PARAMS(( CL2CHAN *Cl2Chan ));
GLOBAL CHANNEL *Channel_GetChannel PARAMS(( CL2CHAN *Cl2Chan ));
GLOBAL bool Channel_IsValidName PARAMS(( char *Name ));
GLOBAL bool Channel_IsValidName PARAMS(( const char *Name ));
GLOBAL bool Channel_ModeAdd PARAMS(( CHANNEL *Chan, char Mode ));
GLOBAL bool Channel_ModeDel PARAMS(( CHANNEL *Chan, char Mode ));
@@ -105,7 +108,9 @@ GLOBAL char *Channel_UserModes PARAMS(( CHANNEL *Chan, CLIENT *Client ));
GLOBAL bool Channel_IsMemberOf PARAMS(( CHANNEL *Chan, CLIENT *Client ));
GLOBAL bool Channel_Write PARAMS(( CHANNEL *Chan, CLIENT *From, CLIENT *Client, char *Text ));
GLOBAL bool Channel_Write PARAMS((CHANNEL *Chan, CLIENT *From, CLIENT *Client,
const char *Command, bool SendErrors,
const char *Text));
GLOBAL CHANNEL *Channel_Create PARAMS(( char *Name ));
@@ -114,8 +119,17 @@ GLOBAL unsigned int Channel_TopicTime PARAMS(( CHANNEL *Chan ));
GLOBAL char *Channel_TopicWho PARAMS(( CHANNEL *Chan ));
#endif
GLOBAL bool Channel_AddInvite PARAMS((CHANNEL *c, const char *Mask, bool OnlyOnce ));
GLOBAL bool Channel_AddBan PARAMS((CHANNEL *c, const char *Mask ));
GLOBAL bool Channel_ShowBans PARAMS((CLIENT *client, CHANNEL *c));
GLOBAL bool Channel_ShowInvites PARAMS((CLIENT *client, CHANNEL *c));
GLOBAL void Channel_LogServer PARAMS((char *msg));
#define Channel_IsLocal(c) (Channel_Name(c)[0] == '&')
#endif
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2005 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,8 +17,6 @@
#include "portab.h"
static char UNUSED id[] = "$Id: client.c,v 1.91 2006/04/23 10:37:27 fw Exp $";
#include "imp.h"
#include <assert.h>
#include <unistd.h>
@@ -55,25 +53,24 @@ static char GetID_Buffer[GETID_LEN];
static WHOWAS My_Whowas[MAX_WHOWAS];
static int Last_Whowas = -1;
static long Max_Users, My_Max_Users;
static long Count PARAMS(( CLIENT_TYPE Type ));
static long MyCount PARAMS(( CLIENT_TYPE Type ));
static unsigned long Count PARAMS(( CLIENT_TYPE Type ));
static unsigned long MyCount PARAMS(( CLIENT_TYPE Type ));
static CLIENT *New_Client_Struct PARAMS(( void ));
static void Generate_MyToken PARAMS(( CLIENT *Client ));
static void Adjust_Counters PARAMS(( CLIENT *Client ));
static CLIENT *Init_New_Client PARAMS((CONN_ID Idx, CLIENT *Introducer,
CLIENT *TopServer, int Type, char *ID, char *User, char *Hostname,
char *Info, int Hops, int Token, char *Modes, bool Idented));
CLIENT *TopServer, int Type, char *ID,
char *User, char *Hostname, char *Info,
int Hops, int Token, char *Modes,
bool Idented));
#ifndef Client_DestroyNow
GLOBAL void Client_DestroyNow PARAMS((CLIENT *Client ));
#endif
long Max_Users = 0, My_Max_Users = 0;
static void Destroy_UserOrService PARAMS((CLIENT *Client, char *Txt, char *FwdMsg,
bool SendQuit));
GLOBAL void
@@ -98,9 +95,10 @@ Client_Init( void )
This_Server->hops = 0;
gethostname( This_Server->host, CLIENT_HOST_LEN );
h = gethostbyname( This_Server->host );
if( h ) strlcpy( This_Server->host, h->h_name, sizeof( This_Server->host ));
if (!Conf_NoDNS) {
h = gethostbyname( This_Server->host );
if (h) strlcpy(This_Server->host, h->h_name, sizeof(This_Server->host));
}
Client_SetID( This_Server, Conf_ServerName );
Client_SetInfo( This_Server, Conf_ServerInfo );
@@ -211,8 +209,8 @@ Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer,
if( Modes ) Client_SetModes( client, Modes );
if( Type == CLIENT_SERVER ) Generate_MyToken( client );
/* ist der User away? */
if( strchr( client->modes, 'a' )) strlcpy( client->away, DEFAULT_AWAY_MSG, sizeof( client->away ));
if( strchr( client->modes, 'a' ))
strlcpy( client->away, DEFAULT_AWAY_MSG, sizeof( client->away ));
/* Verketten */
client->next = (POINTER *)My_Clients;
@@ -265,41 +263,8 @@ Client_Destroy( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit )
if( last ) last->next = c->next;
else My_Clients = (CLIENT *)c->next;
if( c->type == CLIENT_USER )
{
if( c->conn_id != NONE )
{
/* Ein lokaler User */
Log( LOG_NOTICE, "User \"%s\" unregistered (connection %d): %s", Client_Mask( c ), c->conn_id, txt );
if( SendQuit )
{
/* Alle andere Server informieren! */
if( FwdMsg ) IRC_WriteStrServersPrefix( NULL, c, "QUIT :%s", FwdMsg );
else IRC_WriteStrServersPrefix( NULL, c, "QUIT :" );
}
}
else
{
/* Remote User */
Log( LOG_DEBUG, "User \"%s\" unregistered: %s", Client_Mask( c ), txt );
if( SendQuit )
{
/* Andere Server informieren, ausser denen, die "in
* Richtung dem liegen", auf dem der User registriert
* ist. Von denen haben wir das QUIT ja wohl bekommen. */
if( FwdMsg ) IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "QUIT :%s", FwdMsg );
else IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "QUIT :" );
}
}
/* Unregister client from channels */
Channel_Quit( c, FwdMsg ? FwdMsg : c->id );
/* Register client in My_Whowas structure */
Client_RegisterWhowas( c );
}
if(c->type == CLIENT_USER || c->type == CLIENT_SERVICE)
Destroy_UserOrService(c, txt, FwdMsg, SendQuit);
else if( c->type == CLIENT_SERVER )
{
if( c != This_Server )
@@ -336,43 +301,14 @@ Client_Destroy( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit )
} /* Client_Destroy */
GLOBAL void
Client_DestroyNow( CLIENT *Client )
{
/* Destroy client structure immediately. This function is only
* intended for the connection layer to remove client structures
* of connections that can't be established! */
CLIENT *last, *c;
assert( Client != NULL );
last = NULL;
c = My_Clients;
while( c )
{
if( c == Client )
{
/* Wir haben den Client gefunden: entfernen */
if( last ) last->next = c->next;
else My_Clients = (CLIENT *)c->next;
free( c );
break;
}
last = c;
c = (CLIENT *)c->next;
}
} /* Client_DestroyNow */
GLOBAL void
Client_SetHostname( CLIENT *Client, char *Hostname )
{
/* Hostname eines Clients setzen */
assert( Client != NULL );
assert( Hostname != NULL );
strlcpy( Client->host, Hostname, sizeof( Client->host ));
} /* Client_SetHostname */
@@ -399,7 +335,7 @@ Client_SetUser( CLIENT *Client, char *User, bool Idented )
assert( Client != NULL );
assert( User != NULL );
if( Idented ) strlcpy( Client->user, User, sizeof( Client->user ));
else
{
@@ -416,7 +352,7 @@ Client_SetInfo( CLIENT *Client, char *Info )
assert( Client != NULL );
assert( Info != NULL );
strlcpy( Client->info, Info, sizeof( Client->info ));
} /* Client_SetInfo */
@@ -452,7 +388,7 @@ Client_SetPassword( CLIENT *Client, char *Pwd )
assert( Client != NULL );
assert( Pwd != NULL );
strlcpy( Client->pwd, Pwd, sizeof( Client->pwd ));
} /* Client_SetPassword */
@@ -466,7 +402,8 @@ Client_SetAway( CLIENT *Client, char *Txt )
assert( Txt != NULL );
strlcpy( Client->away, Txt, sizeof( Client->away ));
Log( LOG_DEBUG, "User \"%s\" is away: %s", Client_Mask( Client ), Txt );
LogDebug("%s \"%s\" is away: %s", Client_TypeText(Client),
Client_Mask(Client), Txt);
} /* Client_SetAway */
@@ -522,7 +459,7 @@ Client_ModeAdd( CLIENT *Client, char Mode )
*/
char x[2];
assert( Client != NULL );
x[0] = Mode; x[1] = '\0';
@@ -564,7 +501,7 @@ Client_ModeDel( CLIENT *Client, char Mode )
GLOBAL CLIENT *
Client_Search( char *Nick )
Client_Search( const char *Nick )
{
/* return Client-Structure that has the corresponding Nick.
* If none is found, return NULL.
@@ -641,7 +578,8 @@ Client_ID( CLIENT *Client )
assert( Client != NULL );
#ifdef DEBUG
if( Client->type == CLIENT_USER ) assert( strlen( Client->id ) < CLIENT_NICK_LEN );
if(Client->type == CLIENT_USER)
assert(strlen(Client->id) < Conf_MaxNickLength);
#endif
if( Client->id[0] ) return Client->id;
@@ -661,8 +599,7 @@ GLOBAL char *
Client_User( CLIENT *Client )
{
assert( Client != NULL );
if( Client->user[0] ) return Client->user;
else return "~";
return Client->user[0] ? Client->user : "~";
} /* Client_User */
@@ -734,11 +671,13 @@ GLOBAL CLIENT *
Client_NextHop( CLIENT *Client )
{
CLIENT *c;
assert( Client != NULL );
c = Client;
while( c->introducer && ( c->introducer != c ) && ( c->introducer != This_Server )) c = c->introducer;
while( c->introducer && ( c->introducer != c ) && ( c->introducer != This_Server ))
c = c->introducer;
return c;
} /* Client_NextHop */
@@ -750,7 +689,7 @@ Client_Mask( CLIENT *Client )
* Prefixe benoetigt wird. */
assert( Client != NULL );
if( Client->type == CLIENT_SERVER ) return Client->id;
snprintf( GetID_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user, Client->host );
@@ -795,12 +734,9 @@ Client_Away( CLIENT *Client )
GLOBAL bool
Client_CheckNick( CLIENT *Client, char *Nick )
{
/* Nick ueberpruefen */
assert( Client != NULL );
assert( Nick != NULL );
/* Nick ungueltig? */
if( ! Client_IsValidNick( Nick ))
{
IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), Nick );
@@ -913,13 +849,12 @@ Client_MyServiceCount( void )
} /* Client_MyServiceCount */
GLOBAL long
GLOBAL unsigned long
Client_MyServerCount( void )
{
CLIENT *c;
long cnt;
unsigned long cnt = 0;
cnt = 0;
c = My_Clients;
while( c )
{
@@ -930,13 +865,12 @@ Client_MyServerCount( void )
} /* Client_MyServerCount */
GLOBAL long
GLOBAL unsigned long
Client_OperCount( void )
{
CLIENT *c;
long cnt;
unsigned long cnt = 0;
cnt = 0;
c = My_Clients;
while( c )
{
@@ -947,19 +881,19 @@ Client_OperCount( void )
} /* Client_OperCount */
GLOBAL long
GLOBAL unsigned long
Client_UnknownCount( void )
{
CLIENT *c;
long cnt;
unsigned long cnt = 0;
cnt = 0;
c = My_Clients;
while( c )
{
if( c && ( c->type != CLIENT_USER ) && ( c->type != CLIENT_SERVICE ) && ( c->type != CLIENT_SERVER )) cnt++;
c = (CLIENT *)c->next;
}
return cnt;
} /* Client_UnknownCount */
@@ -979,28 +913,25 @@ Client_MyMaxUserCount( void )
GLOBAL bool
Client_IsValidNick( char *Nick )
Client_IsValidNick( const char *Nick )
{
/* Ist der Nick gueltig? */
const char *ptr;
static const char goodchars[] = ";0123456789-";
char *ptr, goodchars[20];
assert( Nick != NULL );
strcpy( goodchars, ";0123456789-" );
if( Nick[0] == '#' ) return false;
if( strchr( goodchars, Nick[0] )) return false;
if( strlen( Nick ) >= CLIENT_NICK_LEN ) return false;
if( strlen( Nick ) >= Conf_MaxNickLength) return false;
ptr = Nick;
while( *ptr )
{
if(( *ptr < 'A' ) && ( ! strchr( goodchars, *ptr ))) return false;
if(( *ptr > '}' ) && ( ! strchr( goodchars, *ptr ))) return false;
if (( *ptr < 'A' ) && ( ! strchr( goodchars, *ptr ))) return false;
if ( *ptr > '}' ) return false;
ptr++;
}
return true;
} /* Client_IsValidNick */
@@ -1037,13 +968,12 @@ Client_StartTime(CLIENT *Client)
} /* Client_Uptime */
static long
static unsigned long
Count( CLIENT_TYPE Type )
{
CLIENT *c;
long cnt;
unsigned long cnt = 0;
cnt = 0;
c = My_Clients;
while( c )
{
@@ -1054,13 +984,12 @@ Count( CLIENT_TYPE Type )
} /* Count */
static long
static unsigned long
MyCount( CLIENT_TYPE Type )
{
CLIENT *c;
long cnt;
unsigned long cnt = 0;
cnt = 0;
c = My_Clients;
while( c )
{
@@ -1075,9 +1004,9 @@ static CLIENT *
New_Client_Struct( void )
{
/* Neue CLIENT-Struktur pre-initialisieren */
CLIENT *c;
c = (CLIENT *)malloc( sizeof( CLIENT ));
if( ! c )
{
@@ -1130,7 +1059,7 @@ Adjust_Counters( CLIENT *Client )
assert( Client != NULL );
if( Client->type != CLIENT_USER ) return;
if( Client->conn_id != NONE )
{
/* Local connection */
@@ -1153,7 +1082,7 @@ Client_RegisterWhowas( CLIENT *Client )
{
int slot;
time_t now;
assert( Client != NULL );
now = time(NULL);
@@ -1167,7 +1096,7 @@ Client_RegisterWhowas( CLIENT *Client )
#ifdef DEBUG
Log( LOG_DEBUG, "Saving WHOWAS information to slot %d ...", slot );
#endif
My_Whowas[slot].time = now;
strlcpy( My_Whowas[slot].id, Client_ID( Client ),
sizeof( My_Whowas[slot].id ));
@@ -1179,9 +1108,76 @@ Client_RegisterWhowas( CLIENT *Client )
sizeof( My_Whowas[slot].info ));
strlcpy( My_Whowas[slot].server, Client_ID( Client_Introducer( Client )),
sizeof( My_Whowas[slot].server ));
Last_Whowas = slot;
} /* Client_RegisterWhowas */
GLOBAL char *
Client_TypeText(CLIENT *Client)
{
assert(Client != NULL);
switch (Client_Type(Client)) {
case CLIENT_USER:
return "User";
break;
case CLIENT_SERVICE:
return "Service";
break;
case CLIENT_SERVER:
return "Server";
break;
default:
return "Client";
}
} /* Client_TypeText */
/**
* Destroy user or service client.
*/
static void
Destroy_UserOrService(CLIENT *Client, char *Txt, char *FwdMsg, bool SendQuit)
{
if(Client->conn_id != NONE) {
/* Local (directly connected) client */
Log(LOG_NOTICE,
"%s \"%s\" unregistered (connection %d): %s",
Client_TypeText(Client), Client_Mask(Client),
Client->conn_id, Txt);
if (SendQuit) {
/* Inforam all the other servers */
if (FwdMsg)
IRC_WriteStrServersPrefix(NULL,
Client, "QUIT :%s", FwdMsg );
else
IRC_WriteStrServersPrefix(NULL,
Client, "QUIT :");
}
} else {
/* Remote client */
LogDebug("%s \"%s\" unregistered: %s",
Client_TypeText(Client), Client_Mask(Client), Txt);
if(SendQuit) {
/* Inform all the other servers, but the ones in the
* direction we got the QUIT from */
if(FwdMsg)
IRC_WriteStrServersPrefix(Client_NextHop(Client),
Client, "QUIT :%s", FwdMsg );
else
IRC_WriteStrServersPrefix(Client_NextHop(Client),
Client, "QUIT :" );
}
}
/* Unregister client from channels */
Channel_Quit(Client, FwdMsg ? FwdMsg : Client->id);
/* Register client in My_Whowas structure */
Client_RegisterWhowas(Client);
} /* Destroy_UserOrService */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -8,25 +8,21 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: client.h,v 1.42 2006/04/23 10:37:27 fw Exp $
*
* Client management (header)
*/
#ifndef __client_h__
#define __client_h__
#define CLIENT_UNKNOWN 1 /* connection of unknown type */
#define CLIENT_GOTPASS 2 /* client did send PASS */
#define CLIENT_GOTNICK 4 /* client did send NICK */
#define CLIENT_GOTUSER 8 /* client did send USER */
#define CLIENT_USER 16 /* client is an IRC user */
#define CLIENT_UNKNOWNSERVER 32 /* unregistered server connection */
#define CLIENT_GOTPASSSERVER 64 /* client did send PASS in "server style" */
#define CLIENT_SERVER 128 /* client is a server */
#define CLIENT_SERVICE 256 /* client is a service */
#define CLIENT_SERVER 32 /* client is a server */
#define CLIENT_SERVICE 64 /* client is a service */
#define CLIENT_UNKNOWNSERVER 128 /* unregistered server connection */
#define CLIENT_GOTPASS_2813 256 /* client did send PASS, RFC 2813 style */
#define CLIENT_TYPE int
@@ -81,15 +77,12 @@ GLOBAL CLIENT *Client_NewRemoteServer PARAMS(( CLIENT *Introducer, char *Hostnam
GLOBAL CLIENT *Client_NewRemoteUser PARAMS(( CLIENT *Introducer, char *Nick, int Hops, char *User, char *Hostname, int Token, char *Modes, char *Info, bool Idented ));
GLOBAL void Client_Destroy PARAMS(( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit ));
#ifdef CONN_MODULE
GLOBAL void Client_DestroyNow PARAMS(( CLIENT *Client ));
#endif
GLOBAL CLIENT *Client_ThisServer PARAMS(( void ));
GLOBAL CLIENT *Client_GetFromToken PARAMS(( CLIENT *Client, int Token ));
GLOBAL CLIENT *Client_Search PARAMS(( char *ID ));
GLOBAL CLIENT *Client_Search PARAMS(( const char *ID ));
GLOBAL CLIENT *Client_First PARAMS(( void ));
GLOBAL CLIENT *Client_Next PARAMS(( CLIENT *c ));
@@ -138,23 +131,23 @@ GLOBAL bool Client_CheckID PARAMS(( CLIENT *Client, char *ID ));
GLOBAL long Client_UserCount PARAMS(( void ));
GLOBAL long Client_ServiceCount PARAMS(( void ));
GLOBAL long Client_ServerCount PARAMS(( void ));
GLOBAL long Client_OperCount PARAMS(( void ));
GLOBAL long Client_UnknownCount PARAMS(( void ));
GLOBAL unsigned long Client_OperCount PARAMS(( void ));
GLOBAL unsigned long Client_UnknownCount PARAMS(( void ));
GLOBAL long Client_MyUserCount PARAMS(( void ));
GLOBAL long Client_MyServiceCount PARAMS(( void ));
GLOBAL long Client_MyServerCount PARAMS(( void ));
GLOBAL unsigned long Client_MyServerCount PARAMS(( void ));
GLOBAL long Client_MaxUserCount PARAMS(( void ));
GLOBAL long Client_MyMaxUserCount PARAMS(( void ));
GLOBAL bool Client_IsValidNick PARAMS(( char *Nick ));
GLOBAL bool Client_IsValidNick PARAMS(( const char *Nick ));
GLOBAL WHOWAS *Client_GetWhowas PARAMS(( void ));
GLOBAL int Client_GetLastWhowasIndex PARAMS(( void ));
GLOBAL void Client_RegisterWhowas PARAMS(( CLIENT *Client ));
GLOBAL char * Client_TypeText PARAMS((CLIENT *Client));
#endif
/* -eof- */

47
src/ngircd/conf-ssl.h Normal file
View File

@@ -0,0 +1,47 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* SSL defines.
*/
#ifndef conf_ssl_h
#define conf_ssl_h
#ifdef HAVE_LIBSSL
#define SSL_SUPPORT
#include <openssl/ssl.h>
#endif
#ifdef HAVE_LIBGNUTLS
#define SSL_SUPPORT
#include <gnutls/gnutls.h>
#ifndef LIBGNUTLS_VERSION_MAJOR
#define gnutls_certificate_credentials_t gnutls_certificate_credentials
#define gnutls_cipher_algorithm_t gnutls_cipher_algorithm
#define gnutls_datum_t gnutls_datum
#define gnutls_dh_params_t gnutls_dh_params
#define gnutls_session_t gnutls_session
#define gnutls_transport_ptr_t gnutls_transport_ptr
#endif
#endif
#ifdef SSL_SUPPORT
struct ConnSSL_State {
#ifdef HAVE_LIBSSL
SSL *ssl;
#endif
#ifdef HAVE_LIBGNUTLS
gnutls_session gnutls_session;
void *cookie; /* pointer to server configuration structure
(for outgoing connections), or NULL. */
#endif
};
bool
ConnSSL_InitLibrary(void);
#else
static inline bool
ConnSSL_InitLibrary(void) { return true; }
#endif /* SSL_SUPPORT */
#endif /* conf_ssl_h */
/* -eof- */

View File

@@ -14,8 +14,6 @@
#include "portab.h"
static char UNUSED id[] = "$Id: conf.c,v 1.92 2006/07/23 16:42:45 alex Exp $";
#include "imp.h"
#include <assert.h>
#include <errno.h>
@@ -44,6 +42,7 @@ static char UNUSED id[] = "$Id: conf.c,v 1.92 2006/07/23 16:42:45 alex Exp $";
#include "client.h"
#include "defines.h"
#include "log.h"
#include "match.h"
#include "resolve.h"
#include "tool.h"
@@ -57,8 +56,8 @@ static int New_Server_Idx;
static void Set_Defaults PARAMS(( bool InitServers ));
static void Read_Config PARAMS(( void ));
static void Validate_Config PARAMS(( bool TestOnly, bool Rehash ));
static bool Read_Config PARAMS(( bool ngircd_starting ));
static bool Validate_Config PARAMS(( bool TestOnly, bool Rehash ));
static void Handle_GLOBAL PARAMS(( int Line, char *Var, char *Arg ));
static void Handle_OPERATOR PARAMS(( int Line, char *Var, char *Arg ));
@@ -72,6 +71,44 @@ static void Config_Error_TooLong PARAMS(( const int LINE, const char *Value ));
static void Init_Server_Struct PARAMS(( CONF_SERVER *Server ));
#ifdef WANT_IPV6
#define DEFAULT_LISTEN_ADDRSTR "::,0.0.0.0"
#else
#define DEFAULT_LISTEN_ADDRSTR "0.0.0.0"
#endif
#ifdef SSL_SUPPORT
struct SSLOptions Conf_SSLOptions;
static void
ConfSSL_Init(void)
{
free(Conf_SSLOptions.KeyFile);
Conf_SSLOptions.KeyFile = NULL;
free(Conf_SSLOptions.CertFile);
Conf_SSLOptions.CertFile = NULL;
free(Conf_SSLOptions.DHFile);
Conf_SSLOptions.DHFile = NULL;
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
}
static void
ConfSSL_Puts(void)
{
if (Conf_SSLOptions.KeyFile)
printf( " SSLKeyFile = %s\n", Conf_SSLOptions.KeyFile);
if (Conf_SSLOptions.CertFile)
printf( " SSLCertFile = %s\n", Conf_SSLOptions.CertFile);
if (Conf_SSLOptions.DHFile)
printf( " SSLDHFile = %s\n", Conf_SSLOptions.DHFile);
if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
puts(" SSLKeyFilePassword = <secret>" );
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
}
#endif
static char *
strdup_warn(const char *str)
@@ -134,21 +171,33 @@ ports_parse(array *a, int Line, char *Arg)
GLOBAL void
Conf_Init( void )
{
Set_Defaults( true );
Read_Config( );
Read_Config( true );
Validate_Config(false, false);
} /* Config_Init */
GLOBAL void
GLOBAL bool
Conf_Rehash( void )
{
Set_Defaults( false );
Read_Config( );
if (!Read_Config(false))
return false;
Validate_Config(false, true);
/* Update CLIENT structure of local server */
Client_SetInfo(Client_ThisServer(), Conf_ServerInfo);
return true;
} /* Config_Rehash */
static const char*
yesno_to_str(int boolean_value)
{
if (boolean_value)
return "yes";
return "no";
}
GLOBAL int
Conf_Test( void )
{
@@ -158,12 +207,14 @@ Conf_Test( void )
struct group *grp;
unsigned int i;
char *topic;
bool config_valid;
Use_Log = false;
Set_Defaults( true );
Read_Config( );
Validate_Config(true, false);
if (! Read_Config(true))
return 1;
config_valid = Validate_Config(true, false);
/* If stdin and stdout ("you can read our nice message and we can
* read in your keypress") are valid tty's, wait for a key: */
@@ -185,11 +236,16 @@ Conf_Test( void )
printf( " MotdPhrase = %s\n", Conf_MotdPhrase );
printf( " ChrootDir = %s\n", Conf_Chroot );
printf( " PidFile = %s\n", Conf_PidFile);
printf(" Listen = %s\n", Conf_ListenAddress);
fputs(" Ports = ", stdout);
ports_puts(&Conf_ListenPorts);
#ifdef SSL_SUPPORT
fputs(" SSLPorts = ", stdout);
ports_puts(&Conf_SSLOptions.ListenPorts);
ConfSSL_Puts();
#endif
printf( " Listen = %s\n", Conf_ListenAddress );
pwd = getpwuid( Conf_UID );
if( pwd ) printf( " ServerUID = %s\n", pwd->pw_name );
else printf( " ServerUID = %ld\n", (long)Conf_UID );
@@ -199,15 +255,24 @@ Conf_Test( void )
printf( " PingTimeout = %d\n", Conf_PingTimeout );
printf( " PongTimeout = %d\n", Conf_PongTimeout );
printf( " ConnectRetry = %d\n", Conf_ConnectRetry );
printf( " OperCanUseMode = %s\n", Conf_OperCanMode == true? "yes" : "no" );
printf( " OperServerMode = %s\n", Conf_OperServerMode == true? "yes" : "no" );
printf( " MaxConnections = %ld\n", Conf_MaxConnections>0 ? Conf_MaxConnections : -1);
printf( " MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP>0 ? Conf_MaxConnectionsIP : -1);
printf( " MaxJoins = %d\n\n", Conf_MaxJoins>0 ? Conf_MaxJoins : -1);
printf( " OperCanUseMode = %s\n", yesno_to_str(Conf_OperCanMode));
printf( " OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode));
printf( " PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly));
printf( " NoDNS = %s\n", yesno_to_str(Conf_NoDNS));
printf( " NoIdent = %s\n", yesno_to_str(Conf_NoIdent));
#ifdef WANT_IPV6
printf(" ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
printf(" ConnectIPv6 = %s\n", yesno_to_str(Conf_ConnectIPv4));
#endif
printf( " MaxConnections = %ld\n", Conf_MaxConnections);
printf( " MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP);
printf( " MaxJoins = %d\n", Conf_MaxJoins>0 ? Conf_MaxJoins : -1);
printf( " MaxNickLength = %u\n\n", Conf_MaxNickLength - 1);
for( i = 0; i < Conf_Oper_Count; i++ ) {
if( ! Conf_Oper[i].name[0] ) continue;
/* Valid "Operator" section */
puts( "[OPERATOR]" );
printf( " Name = %s\n", Conf_Oper[i].name );
@@ -218,30 +283,37 @@ Conf_Test( void )
for( i = 0; i < MAX_SERVERS; i++ ) {
if( ! Conf_Server[i].name[0] ) continue;
/* Valid "Server" section */
puts( "[SERVER]" );
printf( " Name = %s\n", Conf_Server[i].name );
printf( " Host = %s\n", Conf_Server[i].host );
printf( " Port = %u\n", (unsigned int)Conf_Server[i].port );
#ifdef SSL_SUPPORT
printf( " SSLConnect = %s\n", Conf_Server[i].SSLConnect?"yes":"no");
#endif
printf( " MyPassword = %s\n", Conf_Server[i].pwd_in );
printf( " PeerPassword = %s\n", Conf_Server[i].pwd_out );
printf( " Group = %d\n\n", Conf_Server[i].group );
printf( " ServiceMask = %s\n", Conf_Server[i].svs_mask);
printf( " Group = %d\n", Conf_Server[i].group );
printf( " Passive = %s\n\n", Conf_Server[i].flags & CONF_SFLAG_DISABLED ? "yes" : "no");
}
for( i = 0; i < Conf_Channel_Count; i++ ) {
if( ! Conf_Channel[i].name[0] ) continue;
/* Valid "Channel" section */
puts( "[CHANNEL]" );
printf( " Name = %s\n", Conf_Channel[i].name );
printf( " Modes = %s\n", Conf_Channel[i].modes );
printf( " Key = %s\n", Conf_Channel[i].key );
printf( " MaxUsers = %lu\n", Conf_Channel[i].maxusers );
topic = (char*)array_start(&Conf_Channel[i].topic);
printf( " Topic = %s\n\n", topic ? topic : "");
}
return 0;
return (config_valid ? 0 : 1);
} /* Conf_Test */
@@ -268,14 +340,14 @@ Conf_UnsetServer( CONN_ID Idx )
Init_Server_Struct( &Conf_Server[i] );
} else {
/* Set time for next connect attempt */
t = time(NULL);
if (Conf_Server[i].lasttry < t - Conf_ConnectRetry) {
/* The connection has been "long", so we don't
* require the next attempt to be delayed. */
Conf_Server[i].lasttry =
t - Conf_ConnectRetry + RECONNECT_DELAY;
} else
Conf_Server[i].lasttry = t;
t = time(NULL);
if (Conf_Server[i].lasttry < t - Conf_ConnectRetry) {
/* The connection has been "long", so we don't
* require the next attempt to be delayed. */
Conf_Server[i].lasttry =
t - Conf_ConnectRetry + RECONNECT_DELAY;
} else
Conf_Server[i].lasttry = t;
}
}
} /* Conf_UnsetServer */
@@ -297,9 +369,9 @@ GLOBAL int
Conf_GetServer( CONN_ID Idx )
{
/* Get index of server in configuration structure */
int i = 0;
assert( Idx > NONE );
for( i = 0; i < MAX_SERVERS; i++ ) {
@@ -330,6 +402,24 @@ Conf_EnableServer( char *Name, UINT16 Port )
} /* Conf_EnableServer */
GLOBAL bool
Conf_EnablePassiveServer(const char *Name)
{
/* Enable specified server */
int i;
assert( Name != NULL );
for (i = 0; i < MAX_SERVERS; i++) {
if ((strcasecmp( Conf_Server[i].name, Name ) == 0) && (Conf_Server[i].port > 0)) {
/* BINGO! Enable server */
Conf_Server[i].flags &= ~CONF_SFLAG_DISABLED;
return true;
}
}
return false;
} /* Conf_EnablePassiveServer */
GLOBAL bool
Conf_DisableServer( char *Name )
{
@@ -377,11 +467,21 @@ Conf_AddServer( char *Name, UINT16 Port, char *Host, char *MyPwd, char *PeerPwd
strlcpy( Conf_Server[i].pwd_in, PeerPwd, sizeof( Conf_Server[i].pwd_in ));
Conf_Server[i].port = Port;
Conf_Server[i].flags = CONF_SFLAG_ONCE;
return true;
} /* Conf_AddServer */
/**
* Check if the given nick name is an service
*/
GLOBAL bool
Conf_IsService(int ConfServer, char *Nick)
{
return MatchCaseInsensitive(Conf_Server[ConfServer].svs_mask, Nick);
} /* Conf_IsService */
static void
Set_Defaults( bool InitServers )
{
@@ -406,10 +506,10 @@ Set_Defaults( bool InitServers )
strlcpy( Conf_PidFile, PID_FILE, sizeof( Conf_PidFile ));
strcpy( Conf_ListenAddress, "" );
free(Conf_ListenAddress);
Conf_ListenAddress = NULL;
Conf_UID = Conf_GID = 0;
Conf_PingTimeout = 120;
Conf_PongTimeout = 20;
@@ -419,19 +519,26 @@ Set_Defaults( bool InitServers )
Conf_Channel_Count = 0;
Conf_OperCanMode = false;
Conf_NoDNS = false;
Conf_NoIdent = false;
Conf_PredefChannelsOnly = false;
Conf_OperServerMode = false;
Conf_MaxConnections = -1;
Conf_ConnectIPv4 = true;
Conf_ConnectIPv6 = true;
Conf_MaxConnections = 0;
Conf_MaxConnectionsIP = 5;
Conf_MaxJoins = 10;
Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
/* Initialize server configuration structures */
if( InitServers ) for( i = 0; i < MAX_SERVERS; Init_Server_Struct( &Conf_Server[i++] ));
} /* Set_Defaults */
static void
Read_Config( void )
static bool
Read_Config( bool ngircd_starting )
{
/* Read configuration file. */
@@ -446,10 +553,14 @@ Read_Config( void )
/* No configuration file found! */
Config_Error( LOG_ALERT, "Can't read configuration \"%s\": %s",
NGIRCd_ConfFile, strerror( errno ));
if (!ngircd_starting)
return false;
Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME );
exit( 1 );
}
Set_Defaults( ngircd_starting );
Config_Error( LOG_INFO, "Reading configuration from \"%s\" ...", NGIRCd_ConfFile );
/* Clean up server configuration structure: mark all already
@@ -488,7 +599,9 @@ Read_Config( void )
strcpy( section, "" );
Init_Server_Struct( &New_Server );
New_Server_Idx = NONE;
#ifdef SSL_SUPPORT
ConfSSL_Init();
#endif
/* Read configuration file */
while( true ) {
if( ! fgets( str, LINE_LEN, fd )) break;
@@ -550,6 +663,8 @@ Read_Config( void )
/* Initialize new channel structure */
strcpy( Conf_Channel[Conf_Channel_Count].name, "" );
strcpy( Conf_Channel[Conf_Channel_Count].modes, "" );
strcpy( Conf_Channel[Conf_Channel_Count].key, "" );
Conf_Channel[Conf_Channel_Count].maxusers = 0;
array_free(&Conf_Channel[Conf_Channel_Count].topic);
Conf_Channel_Count++;
}
@@ -594,6 +709,15 @@ Read_Config( void )
exit( 1 );
}
}
if (!Conf_ListenAddress)
Conf_ListenAddress = strdup_warn(DEFAULT_LISTEN_ADDRSTR);
if (!Conf_ListenAddress) {
Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME);
exit(1);
}
return true;
} /* Read_Config */
@@ -608,6 +732,27 @@ Check_ArgIsTrue( const char *Arg )
} /* Check_ArgIsTrue */
static unsigned int Handle_MaxNickLength(int Line, const char *Arg)
{
unsigned new;
new = (unsigned) atoi(Arg) + 1;
if (new > CLIENT_NICK_LEN) {
Config_Error(LOG_WARNING,
"%s, line %d: Value of \"MaxNickLength\" exceeds %u!",
NGIRCd_ConfFile, Line, CLIENT_NICK_LEN - 1);
return CLIENT_NICK_LEN;
}
if (new < 2) {
Config_Error(LOG_WARNING,
"%s, line %d: Value of \"MaxNickLength\" must be at least 1!",
NGIRCd_ConfFile, Line);
return 2;
}
return new;
} /* Handle_MaxNickLength */
static void
Handle_GLOBAL( int Line, char *Var, char *Arg )
{
@@ -750,6 +895,43 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
}
return;
}
if( strcasecmp( Var, "PredefChannelsOnly" ) == 0 ) {
/* Should we only allow pre-defined-channels? (i.e. users cannot create their own channels) */
Conf_PredefChannelsOnly = Check_ArgIsTrue( Arg );
return;
}
if( strcasecmp( Var, "NoDNS" ) == 0 ) {
/* don't do reverse dns lookups when clients connect? */
Conf_NoDNS = Check_ArgIsTrue( Arg );
return;
}
if (strcasecmp(Var, "NoIdent") == 0) {
/* don't do IDENT lookups when clients connect? */
Conf_NoIdent = Check_ArgIsTrue(Arg);
#ifndef IDENTAUTH
if (!Conf_NoIdent) {
/* user has enabled ident lookups explicitly, but ... */
Config_Error(LOG_WARNING,
"%s: line %d: NoIdent=False, but ngircd was built without IDENT support",
NGIRCd_ConfFile, Line);
}
#endif
return;
}
#ifdef WANT_IPV6
/* the default setting for all the WANT_IPV6 special options is 'true' */
if( strcasecmp( Var, "ConnectIPv6" ) == 0 ) {
/* connect to other hosts using ipv6, if they have an AAAA record? */
Conf_ConnectIPv6 = Check_ArgIsTrue( Arg );
return;
}
if( strcasecmp( Var, "ConnectIPv4" ) == 0 ) {
/* connect to other hosts using ipv4.
* again, this can be used for ipv6-only setups */
Conf_ConnectIPv4 = Check_ArgIsTrue( Arg );
return;
}
#endif
if( strcasecmp( Var, "OperCanUseMode" ) == 0 ) {
/* Are IRC operators allowed to use MODE in channels they aren't Op in? */
Conf_OperCanMode = Check_ArgIsTrue( Arg );
@@ -761,7 +943,7 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
return;
}
if( strcasecmp( Var, "MaxConnections" ) == 0 ) {
/* Maximum number of connections. Values <= 0 are equal to "no limit". */
/* Maximum number of connections. 0 -> "no limit". */
#ifdef HAVE_ISDIGIT
if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var);
else
@@ -770,7 +952,7 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
return;
}
if( strcasecmp( Var, "MaxConnectionsIP" ) == 0 ) {
/* Maximum number of simultaneous connections from one IP. Values <= 0 -> "no limit" */
/* Maximum number of simultaneous connections from one IP. 0 -> "no limit" */
#ifdef HAVE_ISDIGIT
if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var );
else
@@ -779,7 +961,7 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
return;
}
if( strcasecmp( Var, "MaxJoins" ) == 0 ) {
/* Maximum number of channels a user can join. Values <= 0 are equal to "no limit". */
/* Maximum number of channels a user can join. 0 -> "no limit". */
#ifdef HAVE_ISDIGIT
if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var );
else
@@ -787,16 +969,64 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
Conf_MaxJoins = atoi( Arg );
return;
}
if( strcasecmp( Var, "Listen" ) == 0 ) {
/* IP-Address to bind sockets */
len = strlcpy( Conf_ListenAddress, Arg, sizeof( Conf_ListenAddress ));
if (len >= sizeof( Conf_ListenAddress ))
Config_Error_TooLong( Line, Var );
if( strcasecmp( Var, "MaxNickLength" ) == 0 ) {
/* Maximum length of a nick name; must be same on all servers
* within the IRC network! */
Conf_MaxNickLength = Handle_MaxNickLength(Line, Arg);
return;
}
Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!",
NGIRCd_ConfFile, Line, Var );
if( strcasecmp( Var, "Listen" ) == 0 ) {
/* IP-Address to bind sockets */
if (Conf_ListenAddress) {
Config_Error(LOG_ERR, "Multiple Listen= options, ignoring: %s", Arg);
return;
}
Conf_ListenAddress = strdup_warn(Arg);
/*
* if allocation fails, we're in trouble:
* we cannot ignore the error -- otherwise ngircd
* would listen on all interfaces.
*/
if (!Conf_ListenAddress) {
Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME);
exit(1);
}
return;
}
#ifdef SSL_SUPPORT
if( strcasecmp( Var, "SSLPorts" ) == 0 ) {
ports_parse(&Conf_SSLOptions.ListenPorts, Line, Arg);
return;
}
if( strcasecmp( Var, "SSLKeyFile" ) == 0 ) {
assert(Conf_SSLOptions.KeyFile == NULL );
Conf_SSLOptions.KeyFile = strdup_warn(Arg);
return;
}
if( strcasecmp( Var, "SSLCertFile" ) == 0 ) {
assert(Conf_SSLOptions.CertFile == NULL );
Conf_SSLOptions.CertFile = strdup_warn(Arg);
return;
}
if( strcasecmp( Var, "SSLKeyFilePassword" ) == 0 ) {
assert(array_bytes(&Conf_SSLOptions.KeyFilePassword) == 0);
if (!array_copys(&Conf_SSLOptions.KeyFilePassword, Arg))
Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Could not copy %s: %s!",
NGIRCd_ConfFile, Line, Var, strerror(errno));
return;
}
if( strcasecmp( Var, "SSLDHFile" ) == 0 ) {
assert(Conf_SSLOptions.DHFile == NULL);
Conf_SSLOptions.DHFile = strdup_warn( Arg );
return;
}
#endif
Config_Error(LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!",
NGIRCd_ConfFile, Line, Var);
} /* Handle_GLOBAL */
@@ -867,6 +1097,14 @@ Handle_SERVER( int Line, char *Var, char *Arg )
Config_Error_TooLong( Line, Var );
return;
}
if (strcasecmp(Var, "Bind") == 0) {
if (ng_ipaddr_init(&New_Server.bind_addr, Arg, 0))
return;
Config_Error(LOG_ERR, "%s, line %d (section \"Server\"): Can't parse IP address \"%s\"",
NGIRCd_ConfFile, Line, Arg);
return;
}
if( strcasecmp( Var, "MyPassword" ) == 0 ) {
/* Password of this server which is sent to the peer */
if (*Arg == ':') {
@@ -896,6 +1134,12 @@ Handle_SERVER( int Line, char *Var, char *Arg )
NGIRCd_ConfFile, Line, port );
return;
}
#ifdef SSL_SUPPORT
if( strcasecmp( Var, "SSLConnect" ) == 0 ) {
New_Server.SSLConnect = Check_ArgIsTrue(Arg);
return;
}
#endif
if( strcasecmp( Var, "Group" ) == 0 ) {
/* Server group */
#ifdef HAVE_ISDIGIT
@@ -906,12 +1150,39 @@ Handle_SERVER( int Line, char *Var, char *Arg )
New_Server.group = atoi( Arg );
return;
}
if( strcasecmp( Var, "Passive" ) == 0 ) {
if (Check_ArgIsTrue(Arg))
New_Server.flags |= CONF_SFLAG_DISABLED;
return;
}
if (strcasecmp(Var, "ServiceMask") == 0) {
len = strlcpy(New_Server.svs_mask, ngt_LowerStr(Arg),
sizeof(New_Server.svs_mask));
if (len >= sizeof(New_Server.svs_mask))
Config_Error_TooLong(Line, Var);
return;
}
Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Unknown variable \"%s\"!",
NGIRCd_ConfFile, Line, Var );
} /* Handle_SERVER */
static bool
Handle_Channelname(size_t chancount, const char *name)
{
size_t size = sizeof( Conf_Channel[chancount].name );
char *dest = Conf_Channel[chancount].name;
if (*name && *name != '#') {
*dest = '#';
--size;
++dest;
}
return size > strlcpy(dest, name, size);
}
static void
Handle_CHANNEL( int Line, char *Var, char *Arg )
{
@@ -925,9 +1196,7 @@ Handle_CHANNEL( int Line, char *Var, char *Arg )
chancount = Conf_Channel_Count - 1;
if( strcasecmp( Var, "Name" ) == 0 ) {
/* Name of the channel */
len = strlcpy( Conf_Channel[chancount].name, Arg, sizeof( Conf_Channel[chancount].name ));
if (len >= sizeof( Conf_Channel[chancount].name ))
if (!Handle_Channelname(chancount, Arg))
Config_Error_TooLong( Line, Var );
return;
}
@@ -945,12 +1214,28 @@ Handle_CHANNEL( int Line, char *Var, char *Arg )
return;
}
if( strcasecmp( Var, "Key" ) == 0 ) {
/* Initial Channel Key (mode k) */
len = strlcpy(Conf_Channel[chancount].key, Arg, sizeof(Conf_Channel[chancount].key));
if (len >= sizeof( Conf_Channel[chancount].key ))
Config_Error_TooLong(Line, Var);
return;
}
if( strcasecmp( Var, "MaxUsers" ) == 0 ) {
/* maximum user limit, mode l */
Conf_Channel[chancount].maxusers = (unsigned long) atol(Arg);
if (Conf_Channel[chancount].maxusers == 0)
Config_Error_NaN(Line, Var);
return;
}
Config_Error( LOG_ERR, "%s, line %d (section \"Channel\"): Unknown variable \"%s\"!",
NGIRCd_ConfFile, Line, Var );
} /* Handle_CHANNEL */
static void
static bool
Validate_Config(bool Configtest, bool Rehash)
{
/* Validate configuration settings. */
@@ -958,6 +1243,7 @@ Validate_Config(bool Configtest, bool Rehash)
#ifdef DEBUG
int i, servers, servers_once;
#endif
bool config_valid = true;
char *ptr;
/* Validate configured server name, see RFC 2812 section 2.3.1 */
@@ -965,7 +1251,7 @@ Validate_Config(bool Configtest, bool Rehash)
do {
if (*ptr >= 'a' && *ptr <= 'z') continue;
if (*ptr >= 'A' && *ptr <= 'Z') continue;
if (*ptr >= '1' && *ptr <= '0') continue;
if (*ptr >= '0' && *ptr <= '9') continue;
if (ptr > Conf_ServerName) {
if (*ptr == '.' || *ptr == '-')
continue;
@@ -976,6 +1262,7 @@ Validate_Config(bool Configtest, bool Rehash)
if (!Conf_ServerName[0]) {
/* No server name configured! */
config_valid = false;
Config_Error(LOG_ALERT,
"No (valid) server name configured in \"%s\" (section 'Global': 'Name')!",
NGIRCd_ConfFile);
@@ -989,6 +1276,7 @@ Validate_Config(bool Configtest, bool Rehash)
if (Conf_ServerName[0] && !strchr(Conf_ServerName, '.')) {
/* No dot in server name! */
config_valid = false;
Config_Error(LOG_ALERT,
"Invalid server name configured in \"%s\" (section 'Global': 'Name'): Dot missing!",
NGIRCd_ConfFile);
@@ -1003,6 +1291,7 @@ Validate_Config(bool Configtest, bool Rehash)
#ifdef STRICT_RFC
if (!Conf_ServerAdminMail[0]) {
/* No administrative contact configured! */
config_valid = false;
Config_Error(LOG_ALERT,
"No administrator email address configured in \"%s\" ('AdminEMail')!",
NGIRCd_ConfFile);
@@ -1035,6 +1324,8 @@ Validate_Config(bool Configtest, bool Rehash)
"Configuration: Operators=%d, Servers=%d[%d], Channels=%d",
Conf_Oper_Count, servers, servers_once, Conf_Channel_Count);
#endif
return config_valid;
} /* Validate_Config */
@@ -1101,6 +1392,7 @@ Init_Server_Struct( CONF_SERVER *Server )
Resolve_Init(&Server->res_stat);
Server->conn_id = NONE;
memset(&Server->bind_addr, 0, sizeof(&Server->bind_addr));
} /* Init_Server_Struct */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -8,8 +8,6 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: conf.h,v 1.40 2006/05/10 21:24:01 alex Exp $
*
* Configuration management (header)
*/
@@ -22,6 +20,11 @@
#include "defines.h"
#include "array.h"
#include "portab.h"
#include "tool.h"
#include "ng_ipaddr.h"
#include "resolve.h"
#include "conf-ssl.h"
typedef struct _Conf_Oper
{
@@ -33,7 +36,6 @@ typedef struct _Conf_Oper
typedef struct _Conf_Server
{
char host[HOST_LEN]; /* Hostname */
char ip[16]; /* IP address (Resolver) */
char name[CLIENT_ID_LEN]; /* IRC-Client-ID */
char pwd_in[CLIENT_PASS_LEN]; /* Password which must be received */
char pwd_out[CLIENT_PASS_LEN]; /* Password to send to peer */
@@ -43,12 +45,34 @@ typedef struct _Conf_Server
RES_STAT res_stat; /* Status of the resolver */
int flags; /* Flags */
CONN_ID conn_id; /* ID of server connection or NONE */
ng_ipaddr_t bind_addr; /* source address to use for outgoing
connections */
ng_ipaddr_t dst_addr[2]; /* list of addresses to connect to */
#ifdef SSL_SUPPORT
bool SSLConnect; /* connect() using SSL? */
#endif
char svs_mask[CLIENT_ID_LEN]; /* Mask of nick names that are
services */
} CONF_SERVER;
#ifdef SSL_SUPPORT
struct SSLOptions {
char *KeyFile;
char *CertFile;
char *DHFile;
array ListenPorts;
array KeyFilePassword;
};
#endif
typedef struct _Conf_Channel
{
char name[CHANNEL_NAME_LEN]; /* Name of the channel */
char modes[CHANNEL_MODE_LEN]; /* Initial channel modes */
char key[CLIENT_PASS_LEN]; /* Channel key ("password", mode "k" ) */
unsigned long maxusers; /* maximum usercount for this channel, mode "l" */
array topic; /* Initial topic */
} CONF_CHANNEL;
@@ -81,7 +105,7 @@ GLOBAL char Conf_MotdPhrase[LINE_LEN];
GLOBAL array Conf_ListenPorts;
/* Address to which the socket should be bound or empty (=all) */
GLOBAL char Conf_ListenAddress[16];
GLOBAL char *Conf_ListenAddress;
/* User and group ID the server should run with */
GLOBAL uid_t Conf_UID;
@@ -110,10 +134,27 @@ GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS];
/* Pre-defined channels */
GLOBAL CONF_CHANNEL Conf_Channel[MAX_DEFCHANNELS];
GLOBAL unsigned int Conf_Channel_Count;
/* Pre-defined channels only */
GLOBAL bool Conf_PredefChannelsOnly;
/* Are IRC operators allowed to always use MODE? */
GLOBAL bool Conf_OperCanMode;
/* Disable all DNS functions? */
GLOBAL bool Conf_NoDNS;
/* Disable IDENT lookups, even when compiled with support for it */
GLOBAL bool Conf_NoIdent;
/*
* try to connect to remote systems using the ipv6 protocol,
* if they have an ipv6 address? (default yes)
*/
GLOBAL bool Conf_ConnectIPv6;
/* same as above, but for ipv4 hosts, default: yes */
GLOBAL bool Conf_ConnectIPv4;
/* If an IRC op gives chanop privileges without being a chanop,
* ircd2 will ignore the command. This enables a workaround:
* It masks the command as coming from the server */
@@ -128,9 +169,11 @@ GLOBAL int Conf_MaxJoins;
/* Maximum number of connections per IP address */
GLOBAL int Conf_MaxConnectionsIP;
/* Maximum length of a nick name */
GLOBAL unsigned int Conf_MaxNickLength;
GLOBAL void Conf_Init PARAMS((void));
GLOBAL void Conf_Rehash PARAMS((void));
GLOBAL bool Conf_Rehash PARAMS((void));
GLOBAL int Conf_Test PARAMS((void));
GLOBAL void Conf_UnsetServer PARAMS(( CONN_ID Idx ));
@@ -138,9 +181,12 @@ GLOBAL void Conf_SetServer PARAMS(( int ConfServer, CONN_ID Idx ));
GLOBAL int Conf_GetServer PARAMS(( CONN_ID Idx ));
GLOBAL bool Conf_EnableServer PARAMS(( char *Name, UINT16 Port ));
GLOBAL bool Conf_EnablePassiveServer PARAMS((const char *Name));
GLOBAL bool Conf_DisableServer PARAMS(( char *Name ));
GLOBAL bool Conf_AddServer PARAMS(( char *Name, UINT16 Port, char *Host, char *MyPwd, char *PeerPwd ));
GLOBAL bool Conf_IsService PARAMS((int ConfServer, char *Nick));
#endif

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,11 +16,12 @@
#include "portab.h"
static char UNUSED id[] = "$Id: conn-func.c,v 1.10 2006/05/10 21:24:01 alex Exp $";
static char UNUSED id[] = "$Id: conn-func.c,v 1.12 2008/03/11 14:05:27 alex Exp $";
#include "imp.h"
#include <assert.h>
#include <log.h>
#include <string.h>
#include "log.h"
#include "conn.h"
#include "client.h"
@@ -39,6 +40,16 @@ Conn_UpdateIdle( CONN_ID Idx )
}
/*
* Get signon time of a connection.
*/
GLOBAL time_t
Conn_GetSignon(CONN_ID Idx)
{
assert(Idx > NONE);
return My_Connections[Idx].signon;
}
GLOBAL time_t
Conn_GetIdle( CONN_ID Idx )
{
@@ -164,6 +175,17 @@ Conn_Options( CONN_ID Idx )
} /* Conn_Options */
/**
* Set connection option.
*/
GLOBAL void
Conn_SetOption(CONN_ID Idx, int Option)
{
assert(Idx > NONE);
Conn_OPTION_ADD(&My_Connections[Idx], Option);
} /* Conn_SetOption */
/**
* Get the start time of the connection.
* The result is the start time in seconds since 1970-01-01, as reported

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -8,8 +8,6 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: conn-func.h,v 1.5 2006/05/10 21:24:01 alex Exp $
*
* Connection management: Global functions (header)
*/
@@ -22,11 +20,16 @@
* containing connection handling functions. So other modules must only
* include this conn-func.h header. */
#ifndef CONN_MODULE
# include "conn.h"
#include "conn.h"
#else
#define Conn_OPTION_ADD( x, opt ) ( (x)->options |= (opt) )
#define Conn_OPTION_DEL( x, opt ) ( (x)->options &= ~(opt) )
#define Conn_OPTION_ISSET( x, opt ) ( ((x)->options & (opt)) != 0)
#endif
GLOBAL void Conn_UpdateIdle PARAMS(( CONN_ID Idx ));
GLOBAL time_t Conn_GetSignon PARAMS((CONN_ID Idx));
GLOBAL time_t Conn_GetIdle PARAMS(( CONN_ID Idx ));
GLOBAL time_t Conn_LastPing PARAMS(( CONN_ID Idx ));
GLOBAL time_t Conn_StartTime PARAMS(( CONN_ID Idx ));
@@ -48,14 +51,11 @@ GLOBAL CONN_ID Conn_First PARAMS(( void ));
GLOBAL CONN_ID Conn_Next PARAMS(( CONN_ID Idx ));
GLOBAL UINT16 Conn_Options PARAMS(( CONN_ID Idx ));
GLOBAL void Conn_SetOption PARAMS(( CONN_ID Idx, int Option ));
GLOBAL void Conn_ResetWCounter PARAMS(( void ));
GLOBAL long Conn_WCounter PARAMS(( void ));
#define Conn_OPTION_ADD( x, opt ) ( (x)->options |= opt )
#define Conn_OPTION_DEL( x, opt ) ( (x)->options &= ~opt )
#define Conn_OPTION_ISSET( x, opt ) ( (x)->options & opt )
#endif

727
src/ngircd/conn-ssl.c Normal file
View File

@@ -0,0 +1,727 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
*
* SSL wrapper functions.
* Copyright (c) 2005-2008 Florian Westphal <fw@strlen.de>
*/
#include "portab.h"
#include "imp.h"
#include "conf-ssl.h"
#ifdef SSL_SUPPORT
#include "io.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define CONN_MODULE
#include "conn.h"
#include "conf.h"
#include "conn-func.h"
#include "conn-ssl.h"
#include "log.h"
#include "exp.h"
#include "defines.h"
extern struct SSLOptions Conf_SSLOptions;
#ifdef HAVE_LIBSSL
#include <openssl/err.h>
#include <openssl/rand.h>
static SSL_CTX * ssl_ctx;
static DH *dh_params;
static bool ConnSSL_LoadServerKey_openssl PARAMS(( SSL_CTX *c ));
#endif
#ifdef HAVE_LIBGNUTLS
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <gnutls/x509.h>
#define DH_BITS 1024
static gnutls_certificate_credentials_t x509_cred;
static gnutls_dh_params_t dh_params;
static bool ConnSSL_LoadServerKey_gnutls PARAMS(( void ));
#endif
static bool ConnSSL_Init_SSL PARAMS(( CONNECTION *c ));
static int ConnectAccept PARAMS(( CONNECTION *c, bool connect ));
static int ConnSSL_HandleError PARAMS(( CONNECTION *c, const int code, const char *fname ));
#ifdef HAVE_LIBGNUTLS
static char * openreadclose(const char *name, size_t *len)
{
char *buf = NULL;
struct stat s;
ssize_t br;
int fd = open(name, O_RDONLY);
if (fd < 0) {
Log(LOG_ERR, "Could not open %s: %s", name, strerror(errno));
return NULL;
}
if (fstat(fd, &s)) {
Log(LOG_ERR, "Could not fstat %s: %s", name, strerror(errno));
goto out;
}
if (!S_ISREG(s.st_mode)) {
Log(LOG_ERR, "%s: Not a regular file", name);
goto out;
}
if (s.st_size <= 0) {
Log(LOG_ERR, "%s: invalid file length (size %ld <= 0)", name, (long) s.st_size);
goto out;
}
buf = malloc(s.st_size);
if (!buf) {
Log(LOG_ERR, "Could not malloc %lu bytes for file %s: %s", s.st_size, name, strerror(errno));
goto out;
}
br = read(fd, buf, s.st_size);
if (br != (ssize_t)s.st_size) {
Log(LOG_ERR, "Could not read file %s: read returned %ld, expected %ld: %s",
name, (long) br, (long) s.st_size, br == -1 ? strerror(errno):"short read?!");
memset(buf, 0, s.st_size);
free(buf);
buf = NULL;
} else {
*len = br;
}
out:
close(fd);
return buf;
}
#endif
#ifdef HAVE_LIBSSL
static void
LogOpenSSLError( const char *msg, const char *msg2 )
{
unsigned long err = ERR_get_error();
char * errmsg = err ? ERR_error_string(err, NULL) : "Unable to determine error";
if (!msg) msg = "SSL Error";
if (msg2)
Log( LOG_ERR, "%s: %s: %s", msg, msg2, errmsg);
else
Log( LOG_ERR, "%s: %s", msg, errmsg);
}
static int
pem_passwd_cb(char *buf, int size, int rwflag, void *password)
{
array *pass = password;
int passlen;
(void)rwflag; /* rwflag is unused if DEBUG is not set. */
assert(rwflag == 0); /* 0 -> callback used for decryption.
* See SSL_CTX_set_default_passwd_cb(3) */
passlen = (int) array_bytes(pass);
LogDebug("pem_passwd_cb buf size %d, array size %d", size, passlen);
assert(passlen >= 0);
if (passlen <= 0) {
Log(LOG_ERR, "pem_passwd_cb: password required, but not set");
return 0;
}
size = passlen > size ? size : passlen;
memcpy(buf, (char *)(array_start(pass)), size);
return size;
}
#endif
static bool
Load_DH_params(void)
{
#ifdef HAVE_LIBSSL
FILE *fp;
bool ret = true;
if (!Conf_SSLOptions.DHFile) {
Log(LOG_NOTICE, "Configuration option \"SSLDHFile\" not set!");
return false;
}
fp = fopen(Conf_SSLOptions.DHFile, "r");
if (!fp) {
Log(LOG_ERR, "%s: %s", Conf_SSLOptions.DHFile, strerror(errno));
return false;
}
dh_params = PEM_read_DHparams(fp, NULL, NULL, NULL);
if (!dh_params) {
Log(LOG_ERR, "%s: PEM_read_DHparams failed!",
Conf_SSLOptions.DHFile);
ret = false;
}
fclose(fp);
return ret;
#endif
#ifdef HAVE_LIBGNUTLS
bool need_dhgenerate = true;
int err;
gnutls_dh_params_t tmp_dh_params;
err = gnutls_dh_params_init(&tmp_dh_params);
if (err < 0) {
Log(LOG_ERR, "gnutls_dh_params_init: %s", gnutls_strerror(err));
return false;
}
if (Conf_SSLOptions.DHFile) {
gnutls_datum_t dhparms;
size_t size;
dhparms.data = (unsigned char *) openreadclose(Conf_SSLOptions.DHFile, &size);
if (dhparms.data) {
dhparms.size = size;
err = gnutls_dh_params_import_pkcs3(tmp_dh_params, &dhparms, GNUTLS_X509_FMT_PEM);
if (err == 0)
need_dhgenerate = false;
else
Log(LOG_ERR, "gnutls_dh_params_init: %s", gnutls_strerror(err));
memset(dhparms.data, 0, size);
free(dhparms.data);
}
}
if (need_dhgenerate) {
Log(LOG_WARNING,
"SSLDHFile not set, generating %u bit DH parameters. This may take a while ...",
DH_BITS);
err = gnutls_dh_params_generate2(tmp_dh_params, DH_BITS);
if (err < 0) {
Log(LOG_ERR, "gnutls_dh_params_generate2: %s", gnutls_strerror(err));
return false;
}
}
dh_params = tmp_dh_params;
return true;
#endif
}
void ConnSSL_Free(CONNECTION *c)
{
#ifdef HAVE_LIBSSL
SSL *ssl = c->ssl_state.ssl;
if (ssl) {
SSL_shutdown(ssl);
SSL_free(ssl);
c->ssl_state.ssl = NULL;
}
#endif
#ifdef HAVE_LIBGNUTLS
gnutls_session_t sess = c->ssl_state.gnutls_session;
if (Conn_OPTION_ISSET(c, CONN_SSL)) {
gnutls_bye(sess, GNUTLS_SHUT_RDWR);
gnutls_deinit(sess);
}
#endif
assert(Conn_OPTION_ISSET(c, CONN_SSL));
Conn_OPTION_DEL(c, (CONN_SSL_CONNECT|CONN_SSL|CONN_SSL_WANT_WRITE));
}
bool
ConnSSL_InitLibrary( void )
{
#ifdef HAVE_LIBSSL
SSL_CTX *newctx;
if (!ssl_ctx) {
SSL_library_init();
SSL_load_error_strings();
}
if (!RAND_status()) {
Log(LOG_ERR, "OpenSSL PRNG not seeded: /dev/urandom missing?");
/*
* it is probably best to fail and let the user install EGD or a similar program if no kernel random device is available.
* According to OpenSSL RAND_egd(3): "The automatic query of /var/run/egd-pool et al was added in OpenSSL 0.9.7";
* so it makes little sense to deal with PRNGD seeding ourselves.
*/
return false;
}
newctx = SSL_CTX_new(SSLv23_method());
if (!newctx) {
LogOpenSSLError("SSL_CTX_new()", NULL);
return false;
}
if (!ConnSSL_LoadServerKey_openssl(newctx))
goto out;
SSL_CTX_set_options(newctx, SSL_OP_SINGLE_DH_USE|SSL_OP_NO_SSLv2);
SSL_CTX_set_mode(newctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
SSL_CTX_free(ssl_ctx);
ssl_ctx = newctx;
Log(LOG_INFO, "%s initialized.", SSLeay_version(SSLEAY_VERSION));
return true;
out:
SSL_CTX_free(newctx);
return false;
#endif
#ifdef HAVE_LIBGNUTLS
int err;
static bool initialized;
if (initialized) /* TODO: cannot reload gnutls keys: can't simply free x509 context -- it may still be in use */
return false;
err = gnutls_global_init();
if (err) {
Log(LOG_ERR, "gnutls_global_init(): %s", gnutls_strerror(err));
return false;
}
if (!ConnSSL_LoadServerKey_gnutls())
return false;
Log(LOG_INFO, "gnutls %s initialized.", gnutls_check_version(NULL));
initialized = true;
return true;
#endif
}
#ifdef HAVE_LIBGNUTLS
static bool
ConnSSL_LoadServerKey_gnutls(void)
{
int err;
const char *cert_file;
err = gnutls_certificate_allocate_credentials(&x509_cred);
if (err < 0) {
Log(LOG_ERR, "gnutls_certificate_allocate_credentials: %s", gnutls_strerror(err));
return false;
}
cert_file = Conf_SSLOptions.CertFile ? Conf_SSLOptions.CertFile:Conf_SSLOptions.KeyFile;
if (!cert_file) {
Log(LOG_NOTICE, "No SSL server key configured, SSL disabled.");
return false;
}
if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
Log(LOG_WARNING,
"Ignoring KeyFilePassword: Not supported by GNUTLS.");
if (!Load_DH_params())
return false;
gnutls_certificate_set_dh_params(x509_cred, dh_params);
err = gnutls_certificate_set_x509_key_file(x509_cred, cert_file, Conf_SSLOptions.KeyFile, GNUTLS_X509_FMT_PEM);
if (err < 0) {
Log(LOG_ERR, "gnutls_certificate_set_x509_key_file (cert %s, key %s): %s",
cert_file, Conf_SSLOptions.KeyFile ? Conf_SSLOptions.KeyFile : "(NULL)", gnutls_strerror(err));
return false;
}
return true;
}
#endif
#ifdef HAVE_LIBSSL
static bool
ConnSSL_LoadServerKey_openssl(SSL_CTX *ctx)
{
char *cert_key;
assert(ctx);
if (!Conf_SSLOptions.KeyFile) {
Log(LOG_NOTICE, "No SSL server key configured, SSL disabled.");
return false;
}
SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
SSL_CTX_set_default_passwd_cb_userdata(ctx, &Conf_SSLOptions.KeyFilePassword);
if (SSL_CTX_use_PrivateKey_file(ctx, Conf_SSLOptions.KeyFile, SSL_FILETYPE_PEM) != 1) {
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
LogOpenSSLError("SSL_CTX_use_PrivateKey_file", Conf_SSLOptions.KeyFile);
return false;
}
cert_key = Conf_SSLOptions.CertFile ? Conf_SSLOptions.CertFile:Conf_SSLOptions.KeyFile;
if (SSL_CTX_use_certificate_chain_file(ctx, cert_key) != 1) {
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
LogOpenSSLError("SSL_CTX_use_certificate_file", cert_key);
return false;
}
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
if (!SSL_CTX_check_private_key(ctx)) {
LogOpenSSLError("Server Private Key does not match certificate", NULL);
return false;
}
if (Load_DH_params()) {
if (SSL_CTX_set_tmp_dh(ctx, dh_params) != 1)
LogOpenSSLError("Error setting DH Parameters", Conf_SSLOptions.DHFile);
/* don't return false here: the non-DH modes will still work */
DH_free(dh_params);
dh_params = NULL;
}
return true;
}
#endif
static bool
ConnSSL_Init_SSL(CONNECTION *c)
{
int ret;
assert(c != NULL);
#ifdef HAVE_LIBSSL
assert(ssl_ctx);
if (!ssl_ctx) /* NULL when library initialization failed */
return false;
assert(c->ssl_state.ssl == NULL);
c->ssl_state.ssl = SSL_new(ssl_ctx);
if (!c->ssl_state.ssl) {
LogOpenSSLError("SSL_new()", NULL);
return false;
}
ret = SSL_set_fd(c->ssl_state.ssl, c->sock);
if (ret != 1) {
LogOpenSSLError("SSL_set_fd()", NULL);
ConnSSL_Free(c);
return false;
}
#endif
#ifdef HAVE_LIBGNUTLS
ret = gnutls_set_default_priority(c->ssl_state.gnutls_session);
if (ret < 0) {
Log(LOG_ERR, "gnutls_set_default_priority: %s", gnutls_strerror(ret));
ConnSSL_Free(c);
}
/*
* The intermediate (long) cast is here to avoid a warning like:
* "cast to pointer from integer of different size" on 64-bit platforms.
* There doesn't seem to be an alternate GNUTLS API we could use instead, see e.g.
* http://www.mail-archive.com/help-gnutls@gnu.org/msg00286.html
*/
gnutls_transport_set_ptr(c->ssl_state.gnutls_session, (gnutls_transport_ptr_t) (long) c->sock);
ret = gnutls_credentials_set(c->ssl_state.gnutls_session, GNUTLS_CRD_CERTIFICATE, x509_cred);
if (ret < 0) {
Log(LOG_ERR, "gnutls_credentials_set: %s", gnutls_strerror(ret));
ConnSSL_Free(c);
}
gnutls_dh_set_prime_bits(c->ssl_state.gnutls_session, DH_BITS);
#endif
Conn_OPTION_ADD(c, CONN_SSL);
return true;
}
bool
ConnSSL_PrepareConnect(CONNECTION *c, UNUSED CONF_SERVER *s)
{
bool ret;
#ifdef HAVE_LIBGNUTLS
int err;
#endif
assert(c != NULL);
assert(s != NULL);
#ifdef HAVE_LIBGNUTLS
err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_CLIENT);
if (err) {
Log(LOG_ERR, "gnutls_init: %s", gnutls_strerror(err));
return false;
}
#endif
ret = ConnSSL_Init_SSL(c);
if (!ret)
return false;
Conn_OPTION_ADD(c, CONN_SSL_CONNECT);
#ifdef HAVE_LIBSSL
assert(c->ssl_state.ssl);
SSL_set_verify(c->ssl_state.ssl, SSL_VERIFY_NONE, NULL);
#endif
return true;
}
/*
Check an Handle Error return code after failed calls to ssl/tls functions.
OpenSSL:
SSL_connect(), SSL_accept(), SSL_do_handshake(), SSL_read(), SSL_peek(), or SSL_write() on ssl.
GNUTLS:
gnutlsssl_read(), gnutls_write() or gnutls_handshake().
Return: -1 on fatal error, 0 if we can try again later.
*/
static int
ConnSSL_HandleError( CONNECTION *c, const int code, const char *fname )
{
#ifdef HAVE_LIBSSL
int ret = SSL_ERROR_SYSCALL;
unsigned long sslerr;
int real_errno = errno;
assert( fname );
ret = SSL_get_error(c->ssl_state.ssl, code);
switch (ret) {
case SSL_ERROR_WANT_READ:
io_event_del(c->sock, IO_WANTWRITE);
Conn_OPTION_ADD(c, CONN_SSL_WANT_READ);
return 0; /* try again later */
case SSL_ERROR_WANT_WRITE:
io_event_del(c->sock, IO_WANTREAD);
Conn_OPTION_ADD(c, CONN_SSL_WANT_WRITE); /* fall through */
case SSL_ERROR_NONE:
return 0; /* try again later */
case SSL_ERROR_ZERO_RETURN: /* TLS/SSL Connection was shut down */
LogOpenSSLError("TLS/SSL Connection shutdown", fname);
break;
/*
SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT, SSL_ERROR_WANT_X509_LOOKUP
*/
case SSL_ERROR_SYSCALL:
sslerr = ERR_get_error();
if (sslerr) {
Log( LOG_ERR, "%s: %s", fname, ERR_error_string(sslerr, NULL ));
} else {
switch (code) { /* EOF that violated protocol */
case 0:
Log(LOG_ERR, "%s: Client Disconnected", fname );
break;
case -1: /* low level socket I/O error, check errno */
Log(LOG_ERR, "%s: %s", fname, strerror(real_errno));
}
}
break;
case SSL_ERROR_SSL:
LogOpenSSLError("TLS/SSL Protocol Error", fname);
break;
default:
Log( LOG_ERR, "%s: Unknown error %d!", fname, ret);
}
ConnSSL_Free(c);
return -1;
#endif
#ifdef HAVE_LIBGNUTLS
switch (code) {
case GNUTLS_E_AGAIN:
case GNUTLS_E_INTERRUPTED:
if (gnutls_record_get_direction(c->ssl_state.gnutls_session)) { /* need write */
io_event_del(c->sock, IO_WANTREAD);
Conn_OPTION_ADD(c, CONN_SSL_WANT_WRITE); /* fall through */
break;
} else { /* need read */
io_event_del(c->sock, IO_WANTWRITE);
Conn_OPTION_ADD(c, CONN_SSL_WANT_READ);
break;
}
default:
assert(code < 0);
if (gnutls_error_is_fatal(code)) {
Log(LOG_ERR, "%s: %s", fname, gnutls_strerror(code));
ConnSSL_Free(c);
return -1;
}
}
return 0;
#endif
}
static void
ConnSSL_LogCertInfo( CONNECTION *c )
{
#ifdef HAVE_LIBSSL
SSL *ssl = c->ssl_state.ssl;
assert( c );
assert( ssl );
Log(LOG_INFO, "New %s connection using cipher %s on socket %d.",
SSL_get_version(ssl), SSL_get_cipher(ssl), c->sock);
#endif
#ifdef HAVE_LIBGNUTLS
gnutls_session_t sess = c->ssl_state.gnutls_session;
gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(sess);
Log(LOG_INFO, "New %s connection using cipher %s-%s on socket %d.",
gnutls_protocol_get_name(gnutls_protocol_get_version(sess)),
gnutls_cipher_get_name(cipher),
gnutls_mac_get_name(gnutls_mac_get(sess)), c->sock);
#endif
}
/*
Accept incoming SSL connection.
Return Values:
1: SSL Connection established
0: try again
-1: SSL Connection not established due to fatal error.
*/
int
ConnSSL_Accept( CONNECTION *c )
{
assert(c != NULL);
#ifdef HAVE_LIBSSL
if (!c->ssl_state.ssl) {
#endif
#ifdef HAVE_LIBGNUTLS
if (!Conn_OPTION_ISSET(c, CONN_SSL)) {
int err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_SERVER);
if (err) {
Log(LOG_ERR, "gnutls_init: %s", gnutls_strerror(err));
return false;
}
#endif
LogDebug("ConnSSL_Accept: Initializing SSL data");
if (!ConnSSL_Init_SSL(c))
return -1;
}
return ConnectAccept(c, false );
}
int
ConnSSL_Connect( CONNECTION *c )
{
assert(c != NULL);
#ifdef HAVE_LIBSSL
assert(c->ssl_state.ssl);
#endif
#ifdef HAVE_LIBGNUTLS
assert(Conn_OPTION_ISSET(c, CONN_SSL));
#endif
return ConnectAccept(c, true);
}
/* accept/connect wrapper. if connect is true, connect to peer, otherwise wait for incoming connection */
static int
ConnectAccept( CONNECTION *c, bool connect)
{
int ret;
#ifdef HAVE_LIBSSL
SSL *ssl = c->ssl_state.ssl;
assert(ssl != NULL);
ret = connect ? SSL_connect(ssl) : SSL_accept(ssl);
if (1 != ret)
return ConnSSL_HandleError(c, ret, connect ? "SSL_connect": "SSL_accept");
#endif
#ifdef HAVE_LIBGNUTLS
(void) connect;
assert(Conn_OPTION_ISSET(c, CONN_SSL));
ret = gnutls_handshake(c->ssl_state.gnutls_session);
if (ret)
return ConnSSL_HandleError(c, ret, "gnutls_handshake");
#endif /* _GNUTLS */
Conn_OPTION_DEL(c, (CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ|CONN_SSL_CONNECT));
ConnSSL_LogCertInfo(c);
return 1;
}
ssize_t
ConnSSL_Write(CONNECTION *c, const void *buf, size_t count)
{
ssize_t bw;
Conn_OPTION_DEL(c, CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ);
assert(count > 0);
#ifdef HAVE_LIBSSL
bw = (ssize_t) SSL_write(c->ssl_state.ssl, buf, count);
#endif
#ifdef HAVE_LIBGNUTLS
bw = gnutls_write(c->ssl_state.gnutls_session, buf, count);
#endif
if ( bw > 0 ) return bw;
if (ConnSSL_HandleError( c, bw, "ConnSSL_Write") == 0)
errno = EAGAIN; /* try again */
return -1;
}
ssize_t
ConnSSL_Read(CONNECTION *c, void * buf, size_t count)
{
ssize_t br;
Conn_OPTION_DEL(c, CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ);
#ifdef HAVE_LIBSSL
br = (ssize_t) SSL_read(c->ssl_state.ssl, buf, count);
if (br > 0) /* on EOF we have to call ConnSSL_HandleError(), see SSL_read(3) */
return br;
#endif
#ifdef HAVE_LIBGNUTLS
br = gnutls_read(c->ssl_state.gnutls_session, buf, count);
if (br >= 0) /* on EOF we must _not_ call ConnSSL_HandleError, see gnutls_record_recv(3) */
return br;
#endif
/* error on read: switch ConnSSL_HandleError() return values -> 0 is "try again", so return -1 and set EAGAIN */
if (ConnSSL_HandleError(c, br, "ConnSSL_Read") == 0) {
errno = EAGAIN;
return -1;
}
return 0;
}
bool
ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len)
{
#ifdef HAVE_LIBSSL
char *nl;
SSL *ssl;
assert(c != NULL);
assert(len >= 128);
ssl = c->ssl_state.ssl;
if (!ssl)
return false;
*buf = 0;
SSL_CIPHER_description(SSL_get_current_cipher(ssl), buf, len);
nl = strchr(buf, '\n');
if (nl)
*nl = 0;
return true;
#endif
#ifdef HAVE_LIBGNUTLS
assert(c != NULL);
assert(len >= 128);
if (Conn_OPTION_ISSET(c, CONN_SSL)) {
const char *name_cipher, *name_mac, *name_proto, *name_keyexchange;
unsigned keysize;
gnutls_session_t sess = c->ssl_state.gnutls_session;
gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(sess);
name_cipher = gnutls_cipher_get_name(cipher);
name_mac = gnutls_mac_get_name(gnutls_mac_get(sess));
keysize = gnutls_cipher_get_key_size(cipher) * 8;
name_proto = gnutls_protocol_get_name(gnutls_protocol_get_version(sess));
name_keyexchange = gnutls_kx_get_name(gnutls_kx_get(sess));
return snprintf(buf, len, "%s-%s%15s Kx=%s Enc=%s(%u) Mac=%s",
name_cipher, name_mac, name_proto, name_keyexchange, name_cipher, keysize, name_mac) > 0;
}
return false;
#endif
}
#endif /* SSL_SUPPORT */
/* -eof- */

28
src/ngircd/conn-ssl.h Normal file
View File

@@ -0,0 +1,28 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* SSL wrapper functions. (header)
*/
#ifndef conn_ssl_h
#define conn_ssl_h
#include "conf-ssl.h"
#include "conn.h"
#include "conf.h"
#ifdef SSL_SUPPORT
GLOBAL void ConnSSL_Free PARAMS(( CONNECTION *c ));
GLOBAL bool ConnSSL_PrepareConnect PARAMS(( CONNECTION *c, CONF_SERVER *s ));
GLOBAL int ConnSSL_Accept PARAMS(( CONNECTION *c ));
GLOBAL int ConnSSL_Connect PARAMS(( CONNECTION *c ));
GLOBAL ssize_t ConnSSL_Write PARAMS(( CONNECTION *c, const void *buf, size_t count));
GLOBAL ssize_t ConnSSL_Read PARAMS(( CONNECTION *c, void *buf, size_t count));
GLOBAL bool ConnSSL_GetCipherInfo PARAMS(( CONNECTION *c, char *buf, size_t len ));
#endif /* SSL_SUPPORT */
#endif /* conn_ssl_h */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2006 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2007 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
/* enable more zlib related debug messages: */
/* #define DEBUG_ZLIB */
static char UNUSED id[] = "$Id: conn-zip.c,v 1.11 2006/07/23 15:19:20 alex Exp $";
static char UNUSED id[] = "$Id: conn-zip.c,v 1.16 2007/05/17 23:34:24 alex Exp $";
#include "imp.h"
#include <assert.h>
@@ -82,47 +82,63 @@ Zip_InitConn( CONN_ID Idx )
} /* Zip_InitConn */
/**
* Copy data to the compression buffer of a connection. We do collect
* some data there until it's full so that we can achieve better
* compression ratios.
* If the (pre-)compression buffer is full, we try to flush it ("actually
* compress some data") and to add the new (uncompressed) data afterwards.
* @param Idx Connection handle.
* @param Data Pointer to the data.
* @param Len Length of the data to add.
* @return true on success, false otherwise. */
GLOBAL bool
Zip_Buffer( CONN_ID Idx, char *Data, size_t Len )
{
/* Daten zum Komprimieren im "Kompressions-Puffer" sammeln.
* Es wird true bei Erfolg, sonst false geliefert. */
size_t buflen;
assert( Idx > NONE );
assert( Data != NULL );
assert( Len > 0 );
assert( Len <= ZWRITEBUFFER_LEN );
if (Len > ZWRITEBUFFER_LEN)
return false;
if ( array_bytes( &My_Connections[Idx].zip.wbuf ) >= ZWRITEBUFFER_LEN ) {
buflen = array_bytes(&My_Connections[Idx].zip.wbuf);
if (buflen + Len >= WRITEBUFFER_SLINK_LEN) {
/* compression buffer is full, flush */
if( ! Zip_Flush( Idx )) return false;
}
/* check again; if zip buf is still too large do not append data:
* otherwise the zip wbuf would grow too large */
buflen = array_bytes(&My_Connections[Idx].zip.wbuf);
if (buflen + Len >= WRITEBUFFER_SLINK_LEN)
return false;
return array_catb(&My_Connections[Idx].zip.wbuf, Data, Len);
} /* Zip_Buffer */
/**
* Compress data in ZIP buffer and move result to the write buffer of
* the connection.
* @param Idx Connection handle.
* @retrun true on success, false otherwise.
*/
GLOBAL bool
Zip_Flush( CONN_ID Idx )
{
/* Daten komprimieren und in Schreibpuffer kopieren.
* Es wird true bei Erfolg, sonst false geliefert. */
int result;
unsigned char zipbuf[WRITEBUFFER_LEN];
unsigned char zipbuf[WRITEBUFFER_SLINK_LEN];
int zipbuf_used = 0;
z_stream *out;
out = &My_Connections[Idx].zip.out;
out->next_in = array_start(&My_Connections[Idx].zip.wbuf);
if (!out->next_in)
return false;
out->avail_in = (uInt)array_bytes(&My_Connections[Idx].zip.wbuf);
if (!out->avail_in)
return true; /* nothing to do. */
out->next_in = array_start(&My_Connections[Idx].zip.wbuf);
assert(out->next_in != NULL);
out->next_out = zipbuf;
out->avail_out = (uInt)sizeof zipbuf;
@@ -139,14 +155,26 @@ Zip_Flush( CONN_ID Idx )
return false;
}
assert(out->avail_out <= WRITEBUFFER_LEN);
zipbuf_used = WRITEBUFFER_LEN - out->avail_out;
if (out->avail_out <= 0) {
/* Not all data was compressed, because data became
* bigger while compressing it. */
Log (LOG_ALERT, "Compression error: buffer overvlow!?");
Conn_Close(Idx, "Compression error!", NULL, false);
return false;
}
assert(out->avail_out <= WRITEBUFFER_SLINK_LEN);
zipbuf_used = WRITEBUFFER_SLINK_LEN - out->avail_out;
#ifdef DEBUG_ZIP
Log(LOG_DEBUG, "zipbuf_used: %d", zipbuf_used);
#endif
if (!array_catb(&My_Connections[Idx].wbuf,
(char *)zipbuf, (size_t) zipbuf_used))
(char *)zipbuf, (size_t) zipbuf_used)) {
Log (LOG_ALERT, "Compression error: can't copy data!?");
Conn_Close(Idx, "Compression error!", NULL, false);
return false;
}
My_Connections[Idx].bytes_out += zipbuf_used;
My_Connections[Idx].zip.bytes_out += array_bytes(&My_Connections[Idx].zip.wbuf);
@@ -178,10 +206,9 @@ Unzip_Buffer( CONN_ID Idx )
return true;
in = &My_Connections[Idx].zip.in;
in->next_in = array_start(&My_Connections[Idx].zip.rbuf);
if (!in->next_in)
return false;
assert(in->next_in != NULL);
in->avail_in = z_rdatalen;
in->next_out = unzipbuf;

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 by Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -8,8 +8,6 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: conn.h,v 1.42 2006/05/10 21:24:01 alex Exp $
*
* Connection management (header)
*/
@@ -23,12 +21,19 @@
#define CONN_ISCLOSING 1 /* Conn_Close() already called */
#define CONN_ISCONNECTING 2 /* connect() in progress */
#define CONN_RFC1459 4 /* RFC 1459 compatibility mode */
#ifdef ZLIB
#define CONN_ZIP 4 /* zlib compressed link */
#define CONN_ZIP 8 /* zlib compressed link */
#endif
#include "conf-ssl.h"
#ifdef SSL_SUPPORT
#define CONN_SSL_CONNECT 8 /* wait for ssl connect to finish */
#define CONN_SSL 16 /* this connection is SSL encrypted */
#define CONN_SSL_WANT_WRITE 32 /* SSL/TLS library needs to write protocol data */
#define CONN_SSL_WANT_READ 64 /* SSL/TLS library needs to read protocol data */
#endif
typedef int CONN_ID;
#include "client.h"
@@ -38,6 +43,8 @@ typedef int CONN_ID;
#include "defines.h"
#include "resolve.h"
#include "array.h"
#include "tool.h"
#include "ng_ipaddr.h"
#ifdef ZLIB
#include <zlib.h>
@@ -54,11 +61,12 @@ typedef struct _ZipData
typedef struct _Connection
{
int sock; /* Socket handle */
struct sockaddr_in addr; /* Client address */
ng_ipaddr_t addr; /* Client address */
RES_STAT res_stat; /* Status of resolver process */
char host[HOST_LEN]; /* Hostname */
array rbuf; /* Read buffer */
array wbuf; /* Write buffer */
time_t signon; /* Signon ("connect") time */
time_t lastdata; /* Last activity */
time_t lastping; /* Last PING */
time_t lastprivmsg; /* Last PRIVMSG */
@@ -71,6 +79,9 @@ typedef struct _Connection
#ifdef ZLIB
ZIPDATA zip; /* Compression information */
#endif /* ZLIB */
#ifdef SSL_SUPPORT
struct ConnSSL_State ssl_state; /* SSL/GNUTLS state information */
#endif
} CONNECTION;
GLOBAL CONNECTION *My_Connections;
@@ -83,12 +94,11 @@ GLOBAL long WCounter;
GLOBAL void Conn_Init PARAMS((void ));
GLOBAL void Conn_Exit PARAMS(( void ));
GLOBAL int Conn_InitListeners PARAMS(( void ));
GLOBAL unsigned int Conn_InitListeners PARAMS(( void ));
GLOBAL void Conn_ExitListeners PARAMS(( void ));
GLOBAL void Conn_Handler PARAMS(( void ));
GLOBAL bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, char *Format, ... ));
GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, char *LogMsg, char *FwdMsg, bool InformClient ));
@@ -96,6 +106,12 @@ GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, char *LogMsg, char *FwdMsg, bool In
GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
GLOBAL CLIENT* Conn_GetClient PARAMS((CONN_ID i));
#ifdef SSL_SUPPORT
GLOBAL bool Conn_GetCipherInfo PARAMS((CONN_ID Idx, char *buf, size_t len));
GLOBAL bool Conn_UsesSSL PARAMS((CONN_ID Idx));
#else
static inline bool Conn_UsesSSL(UNUSED CONN_ID Idx) { return false; }
#endif
#endif
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2005 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2007 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -8,7 +8,7 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: defines.h,v 1.58 2006/06/15 20:28:15 alex Exp $
* $Id: defines.h,v 1.62 2007/11/21 12:16:36 alex Exp $
*/
@@ -47,14 +47,15 @@
#define CLIENT_ID_LEN 64 /* Max. length of an IRC ID; see RFC
RFC 2812 section 1.1 and 1.2.1 */
#define CLIENT_NICK_LEN 10 /* Max. nick length, see. RFC 2812
section 1.2.1 */
#define CLIENT_NICK_LEN_DEFAULT 10 /* Default nick length, see. RFC 2812
* section 1.2.1 */
#define CLIENT_NICK_LEN 32 /* Maximum nick name length */
#define CLIENT_PASS_LEN 21 /* Max. password length */
#define CLIENT_USER_LEN 10 /* Max. length of user name ("login")
see RFC 2812, section 1.2.1 */
#define CLIENT_NAME_LEN 32 /* Max. length of "real names" */
#define CLIENT_HOST_LEN 64 /* Max. host name length */
#define CLIENT_MODE_LEN 8 /* Max. lenth of all client modes */
#define CLIENT_MODE_LEN 9 /* Max. lenth of all client modes */
#define CLIENT_INFO_LEN 64 /* Max. length of server info texts */
#define CLIENT_AWAY_LEN 128 /* Max. length of away messages */
#define CLIENT_FLAGS_LEN 100 /* Max. length of client flags */
@@ -70,13 +71,8 @@
connection in bytes. */
#define WRITEBUFFER_LEN 4096 /* Size of the write buffer of a
connection in bytes. */
#ifdef ZLIB
#define ZREADBUFFER_LEN 1024 /* Size of the compressed read buffer
of a connection in bytes. */
#define ZWRITEBUFFER_LEN 4096 /* Size of the compressed write buffer
of a connection in bytes. */
#endif
#define WRITEBUFFER_SLINK_LEN 51200 /* Size of the write buffer of a
server link connection in bytes. */
#define PROTOVER "0210" /* Implemented IRC protocol version,
see RFC 2813 section 4.1.1. */
@@ -86,7 +82,7 @@
protocol, see doc/Protocol.txt */
#ifdef IRCPLUS
# define IRCPLUSFLAGS "CL" /* Standard IRC+ flags */
# define IRCPLUSFLAGS "CHLS" /* Standard IRC+ flags */
#endif
#define STARTUP_DELAY 1 /* Delay outgoing connections n seconds

View File

@@ -14,7 +14,7 @@
#include "portab.h"
static char UNUSED id[] = "$Id: hash.c,v 1.12 2005/07/31 20:13:08 alex Exp $";
static char UNUSED id[] = "$Id: hash.c,v 1.13 2006/10/06 21:23:47 fw Exp $";
#include "imp.h"
#include <assert.h>
@@ -31,7 +31,7 @@ static UINT32 jenkins_hash PARAMS(( register UINT8 *k, register UINT32 length, r
GLOBAL UINT32
Hash( char *String )
Hash( const char *String )
{
/* Hash-Wert ueber String berechnen */

View File

@@ -8,7 +8,7 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: hash.h,v 1.5 2005/03/19 18:43:48 fw Exp $
* $Id: hash.h,v 1.6 2006/10/06 21:23:47 fw Exp $
*
* Hash calculation (header)
*/
@@ -17,8 +17,7 @@
#ifndef __hash_h__
#define __hash_h__
GLOBAL UINT32 Hash PARAMS((char *String ));
GLOBAL UINT32 Hash PARAMS((const char *String ));
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -7,10 +7,10 @@
*
* I/O abstraction interface header
*
* $Id: io.h,v 1.3 2005/07/14 09:15:58 alex Exp $
* $Id: io.h,v 1.4 2006/12/25 22:53:52 alex Exp $
*/
#ifndef io_H_inclucded
#ifndef io_H_included
#define io_H_included
#include "portab.h"

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,8 +14,6 @@
#include "portab.h"
static char UNUSED id[] = "$Id: irc-channel.c,v 1.35 2006/03/16 20:14:16 fw Exp $";
#include "imp.h"
#include <assert.h>
#include <stdlib.h>
@@ -26,6 +24,7 @@ static char UNUSED id[] = "$Id: irc-channel.c,v 1.35 2006/03/16 20:14:16 fw Exp
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "conn-func.h"
#include "lists.h"
#include "log.h"
#include "match.h"
@@ -40,246 +39,337 @@ static char UNUSED id[] = "$Id: irc-channel.c,v 1.35 2006/03/16 20:14:16 fw Exp
#include "irc-channel.h"
/*
* RFC 2812, (3.2.1 Join message Command):
* Note that this message
* accepts a special argument ("0"), which is a special request to leave all
* channels the user is currently a member of. The server will process this
* message as if the user had sent a PART command (See Section 3.2.2) for
* each channel he is a member of.
*/
static bool
part_from_all_channels(CLIENT* client, CLIENT *target)
{
CL2CHAN *cl2chan;
CHANNEL *chan;
while ((cl2chan = Channel_FirstChannelOf(target))) {
chan = Channel_GetChannel(cl2chan);
assert( chan != NULL );
Channel_Part(target, client, Channel_Name(chan), Client_ID(target));
}
return CONNECTED;
}
static bool
join_allowed(CLIENT *Client, CLIENT *target, CHANNEL *chan,
const char *channame, const char *key)
{
bool is_invited, is_banned;
const char *channel_modes;
/* Allow IRC operators to overwrite channel limits */
if (strchr(Client_Modes(Client), 'o'))
return true;
is_banned = Lists_Check(Channel_GetListBans(chan), target);
is_invited = Lists_Check(Channel_GetListInvites(chan), target);
if (is_banned && !is_invited) {
IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG, Client_ID(Client), channame);
return false;
}
channel_modes = Channel_Modes(chan);
if ((strchr(channel_modes, 'i')) && !is_invited) {
/* Channel is "invite-only" (and Client wasn't invited) */
IRC_WriteStrClient(Client, ERR_INVITEONLYCHAN_MSG, Client_ID(Client), channame);
return false;
}
/* Is the channel protected by a key? */
if (strchr(channel_modes, 'k') &&
strcmp(Channel_Key(chan), key ? key : ""))
{
IRC_WriteStrClient(Client, ERR_BADCHANNELKEY_MSG, Client_ID(Client), channame);
return false;
}
/* Are there already too many members? */
if ((strchr(channel_modes, 'l')) && (Channel_MaxUsers(chan) <= Channel_MemberCount(chan))) {
IRC_WriteStrClient(Client, ERR_CHANNELISFULL_MSG, Client_ID(Client), channame);
return false;
}
return true;
}
static void
join_set_channelmodes(CHANNEL *chan, CLIENT *target, const char *flags)
{
if (flags) {
while (*flags) {
Channel_UserModeAdd(chan, target, *flags);
flags++;
}
}
/* If channel persistent and client is ircop: make client chanop */
if (strchr(Channel_Modes(chan), 'P') && strchr(Client_Modes(target), 'o'))
Channel_UserModeAdd(chan, target, 'o');
}
static void
cb_join_forward(CLIENT *To, CLIENT *Prefix, void *Data)
{
CONN_ID conn;
char str[COMMAND_LEN], *ptr = NULL;
strlcpy(str, (char *)Data, sizeof(str));
conn = Client_Conn(To);
if (Conn_Options(conn) & CONN_RFC1459) {
/* RFC 1459 compatibility mode, appended modes are NOT
* supported, so strip them off! */
ptr = strchr(str, 0x7);
if (ptr)
*ptr++ = '\0';
}
IRC_WriteStrClientPrefix(To, Prefix, "JOIN %s", str);
if (ptr && *ptr)
IRC_WriteStrClientPrefix(To, Prefix, "MODE %s +%s %s", str, ptr,
Client_ID(Prefix));
} /* cb_join_forward */
static void
join_forward(CLIENT *Client, CLIENT *target, CHANNEL *chan,
const char *channame)
{
char modes[CHANNEL_MODE_LEN], str[COMMAND_LEN];
strlcpy(&modes[1], Channel_UserModes(chan, target), sizeof(modes) - 1);
if (modes[1])
modes[0] = 0x7;
else
modes[0] = '\0';
/* forward to other servers (if it is not a local channel) */
if (!Channel_IsLocal(chan)) {
snprintf(str, sizeof(str), "%s%s", channame, modes);
IRC_WriteStrServersPrefixFlag_CB(Client, target, '\0',
cb_join_forward, str);
}
/* tell users in this channel about the new client */
IRC_WriteStrChannelPrefix(Client, chan, target, false,
"JOIN :%s", channame);
/* syncronize channel modes */
if (modes[1]) {
IRC_WriteStrChannelPrefix(Client, chan, target, false,
"MODE %s +%s %s", channame,
&modes[1], Client_ID(target));
}
} /* join_forward */
static bool
join_send_topic(CLIENT *Client, CLIENT *target, CHANNEL *chan,
const char *channame)
{
const char *topic;
if (Client_Type(Client) != CLIENT_USER)
return true;
/* acknowledge join */
if (!IRC_WriteStrClientPrefix(Client, target, "JOIN :%s", channame))
return false;
/* Send topic to client, if any */
topic = Channel_Topic(chan);
assert(topic != NULL);
if (*topic) {
if (!IRC_WriteStrClient(Client, RPL_TOPIC_MSG,
Client_ID(Client), channame, topic))
return false;
#ifndef STRICT_RFC
if (!IRC_WriteStrClient(Client, RPL_TOPICSETBY_MSG,
Client_ID(Client), channame,
Channel_TopicWho(chan),
Channel_TopicTime(chan)))
return false;
#endif
}
/* send list of channel members to client */
if (!IRC_Send_NAMES(Client, chan))
return false;
return IRC_WriteStrClient(Client, RPL_ENDOFNAMES_MSG, Client_ID(Client), Channel_Name(chan));
}
GLOBAL bool
IRC_JOIN( CLIENT *Client, REQUEST *Req )
{
char *channame, *channame_ptr, *key, *key_ptr, *flags, *topic, modes[8];
bool is_new_chan, is_invited, is_banned;
char *channame, *key = NULL, *flags, *lastkey = NULL, *lastchan = NULL;
CLIENT *target;
CHANNEL *chan;
assert( Client != NULL );
assert( Req != NULL );
/* Bad number of arguments? */
if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if (Req->argc < 1 || Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* Who is the sender? */
if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
else target = Client;
if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
if (Client_Type(Client) == CLIENT_SERVER)
target = Client_Search(Req->prefix);
else
target = Client;
if (!target)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix);
/* Is argument "0"? */
if (Req->argc == 1 && !strncmp("0", Req->argv[0], 2))
return part_from_all_channels(Client, target);
/* Are channel keys given? */
if (Req->argc > 1) {
key = Req->argv[1];
key_ptr = strchr(key, ',');
if (key_ptr) *key_ptr = '\0';
}
else
key = key_ptr = NULL;
if (Req->argc > 1)
key = strtok_r(Req->argv[1], ",", &lastkey);
channame = Req->argv[0];
channame_ptr = strchr(channame, ',');
if (channame_ptr) *channame_ptr = '\0';
channame = strtok_r(channame, ",", &lastchan);
/* Channel-Namen durchgehen */
while (channame)
{
chan = NULL; flags = NULL;
/* Make sure that "channame" is not the empty string ("JOIN :") */
if (! channame)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* wird der Channel neu angelegt? */
if( Channel_Search( channame )) is_new_chan = false;
else is_new_chan = true;
while (channame) {
flags = NULL;
/* Hat ein Server Channel-User-Modes uebergeben? */
if( Client_Type( Client ) == CLIENT_SERVER )
{
/* Channel-Flags extrahieren */
flags = strchr( channame, 0x7 );
if( flags )
{
/* Did the server include channel-user-modes? */
if (Client_Type(Client) == CLIENT_SERVER) {
flags = strchr(channame, 0x7);
if (flags) {
*flags = '\0';
flags++;
}
}
/* Local client? */
if( Client_Type( Client ) == CLIENT_USER )
{
/* Test if the user has reached his maximum channel count */
if(( Conf_MaxJoins > 0 ) && ( Channel_CountForUser( Client ) >= Conf_MaxJoins ))
return IRC_WriteStrClient( Client, ERR_TOOMANYCHANNELS_MSG,
Client_ID( Client ), channame );
/* Existiert der Channel bereits, oder wird er im Moment neu erzeugt? */
if( is_new_chan )
{
/* Erster User im Channel: Operator-Flag setzen */
flags = "o";
}
else
{
/* Existierenden Channel suchen */
chan = Channel_Search( channame );
assert( chan != NULL );
is_banned = Lists_CheckBanned( target, chan );
is_invited = Lists_CheckInvited( target, chan );
/* Testen, ob Client gebanned ist */
if(( is_banned == true) && ( is_invited == false ))
{
/* Client ist gebanned (und nicht invited): */
IRC_WriteStrClient( Client, ERR_BANNEDFROMCHAN_MSG, Client_ID( Client ), channame );
/* Try next name, if any */
channame = strtok( NULL, "," );
continue;
}
/* Ist der Channel "invite-only"? */
if(( strchr( Channel_Modes( chan ), 'i' )) && ( is_invited == false ))
{
/* Channel ist "invite-only" und Client wurde nicht invited: */
IRC_WriteStrClient( Client, ERR_INVITEONLYCHAN_MSG, Client_ID( Client ), channame );
/* Try next name, if any */
channame = strtok( NULL, "," );
continue;
}
/* Is the channel protected by a key? */
if(( strchr( Channel_Modes( chan ), 'k' )) && ( strcmp( Channel_Key( chan ), key ? key : "" ) != 0 ))
{
/* Bad channel key! */
IRC_WriteStrClient( Client, ERR_BADCHANNELKEY_MSG, Client_ID( Client ), channame );
/* Try next name, if any */
channame = strtok( NULL, "," );
continue;
}
/* Are there already too many members? */
if(( strchr( Channel_Modes( chan ), 'l' )) && ( Channel_MaxUsers( chan ) <= Channel_MemberCount( chan )))
{
/* Bad channel key! */
IRC_WriteStrClient( Client, ERR_CHANNELISFULL_MSG, Client_ID( Client ), channame );
/* Try next name, if any */
channame = strtok( NULL, "," );
continue;
}
}
chan = Channel_Search(channame);
if (!chan && Conf_PredefChannelsOnly) {
/* channel must be created, but server does not allow this */
IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG, Client_ID(Client), channame);
break;
}
else
{
/* Local client? */
if (Client_Type(Client) == CLIENT_USER) {
/* Test if the user has reached his maximum channel count */
if ((Conf_MaxJoins > 0) && (Channel_CountForUser(Client) >= Conf_MaxJoins))
return IRC_WriteStrClient(Client, ERR_TOOMANYCHANNELS_MSG,
Client_ID(Client), channame);
if (!chan) {
/*
* New Channel: first user will be channel operator
* unless this is a modeless channel.
*/
if (*channame != '+')
flags = "o";
} else
if (!join_allowed(Client, target, chan, channame, key))
break;
/* Local client: update idle time */
Conn_UpdateIdle(Client_Conn(Client));
} else {
/* Remote server: we don't need to know whether the
* client is invited or not, but we have to make sure
* that the "one shot" entries (generated by INVITE
* commands) in this list become deleted when a user
* joins a channel this way. */
chan = Channel_Search( channame );
if( chan != NULL ) (void)Lists_CheckInvited( target, chan );
if (chan) (void)Lists_Check(Channel_GetListInvites(chan), target);
}
/* Channel joinen (und ggf. anlegen) */
if( ! Channel_Join( target, channame ))
{
/* naechsten Namen ermitteln */
channame = strtok( NULL, "," );
continue;
}
if( ! chan ) chan = Channel_Search( channame );
assert( chan != NULL );
/* Join channel (and create channel if it doesn't exist) */
if (!Channel_Join(target, channame))
break;
/* Modes setzen (wenn vorhanden) */
while( flags && *flags )
{
Channel_UserModeAdd( chan, target, *flags );
flags++;
}
/* Wenn persistenter Channel und IRC-Operator: zum Channel-OP machen */
if(( strchr( Channel_Modes( chan ), 'P' )) && ( strchr( Client_Modes( target ), 'o' ))) Channel_UserModeAdd( chan, target, 'o' );
/* Muessen Modes an andere Server gemeldet werden? */
strlcpy( &modes[1], Channel_UserModes( chan, target ), sizeof( modes ) - 1 );
if( modes[1] ) modes[0] = 0x7;
else modes[0] = '\0';
/* An andere Server weiterleiten */
IRC_WriteStrServersPrefix( Client, target, "JOIN :%s%s", channame, modes );
/* im Channel bekannt machen */
IRC_WriteStrChannelPrefix( Client, chan, target, false, "JOIN :%s", channame );
if( modes[1] )
{
/* Modes im Channel bekannt machen */
IRC_WriteStrChannelPrefix( Client, chan, target, false, "MODE %s +%s %s", channame, &modes[1], Client_ID( target ));
}
if( Client_Type( Client ) == CLIENT_USER )
{
/* an Client bestaetigen */
IRC_WriteStrClientPrefix( Client, target, "JOIN :%s", channame );
/* Send topic to client, if any */
topic = Channel_Topic(chan);
if (*topic) {
IRC_WriteStrClient(Client, RPL_TOPIC_MSG,
Client_ID(Client), channame, topic);
#ifndef STRICT_RFC
IRC_WriteStrClient(Client, RPL_TOPICSETBY_MSG,
Client_ID(Client), channame,
Channel_TopicWho(chan),
Channel_TopicTime(chan));
#endif
if (!chan) { /* channel is new; it has been created above */
chan = Channel_Search(channame);
assert(chan != NULL);
if (*channame == '+') { /* modeless channel... */
Channel_ModeAdd(chan, 't'); /* /TOPIC not allowed */
Channel_ModeAdd(chan, 'n'); /* no external msgs */
}
/* Mitglieder an Client Melden */
IRC_Send_NAMES( Client, chan );
IRC_WriteStrClient( Client, RPL_ENDOFNAMES_MSG, Client_ID( Client ), Channel_Name( chan ));
}
assert(chan != NULL);
join_set_channelmodes(chan, target, flags);
join_forward(Client, target, chan, channame);
if (!join_send_topic(Client, target, chan, channame))
break; /* write error */
/* next channel? */
channame = channame_ptr;
if (channame) {
channame++;
channame_ptr = strchr(channame, ',');
if (channame_ptr) *channame_ptr = '\0';
if (key_ptr) {
key = ++key_ptr;
key_ptr = strchr(key, ',');
if (key_ptr) *key_ptr = '\0';
}
}
channame = strtok_r(NULL, ",", &lastchan);
if (channame && key)
key = strtok_r(NULL, ",", &lastkey);
}
return CONNECTED;
} /* IRC_JOIN */
/**
* Handler for the IRC "PART" command.
*/
GLOBAL bool
IRC_PART( CLIENT *Client, REQUEST *Req )
IRC_PART(CLIENT * Client, REQUEST * Req)
{
CLIENT *target;
char *chan;
assert( Client != NULL );
assert( Req != NULL );
assert(Client != NULL);
assert(Req != NULL);
/* Falsche Anzahl Parameter? */
if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if (Req->argc < 1 || Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* Wer ist der Absender? */
if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
else target = Client;
if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
/* Get the sender */
if (Client_Type(Client) == CLIENT_SERVER)
target = Client_Search(Req->prefix);
else
target = Client;
if (!target)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
/* Channel-Namen durchgehen */
chan = strtok( Req->argv[0], "," );
while( chan )
{
if( ! Channel_Part( target, Client, chan, Req->argc > 1 ? Req->argv[1] : Client_ID( target )))
{
/* naechsten Namen ermitteln */
chan = strtok( NULL, "," );
continue;
}
/* Loop over all the given channel names */
chan = strtok(Req->argv[0], ",");
/* naechsten Namen ermitteln */
chan = strtok( NULL, "," );
/* Make sure that "chan" is not the empty string ("PART :") */
if (! chan)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
while (chan) {
Channel_Part(target, Client, chan,
Req->argc > 1 ? Req->argv[1] : Client_ID(target));
chan = strtok(NULL, ",");
}
/* Update idle time, if local client */
if (Client_Conn(Client) > NONE)
Conn_UpdateIdle(Client_Conn(Client));
return CONNECTED;
} /* IRC_PART */
@@ -295,8 +385,8 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
/* Falsche Anzahl Parameter? */
if(( Req->argc < 1 ) || ( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if ((Req->argc < 1) || (Req->argc > 2))
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
else from = Client;
@@ -337,16 +427,22 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
/* Set new topic */
Channel_SetTopic(chan, from, Req->argv[1]);
Log(LOG_DEBUG, "User \"%s\" set topic on \"%s\": %s",
Client_Mask(from), Channel_Name(chan),
Req->argv[1][0] ? Req->argv[1] : "<none>");
LogDebug("%s \"%s\" set topic on \"%s\": %s",
Client_TypeText(from), Client_Mask(from), Channel_Name(chan),
Req->argv[1][0] ? Req->argv[1] : "<none>");
/* im Channel bekannt machen und an Server weiterleiten */
IRC_WriteStrServersPrefix( Client, from, "TOPIC %s :%s", Req->argv[0], Req->argv[1] );
IRC_WriteStrChannelPrefix( Client, chan, from, false, "TOPIC %s :%s", Req->argv[0], Req->argv[1] );
/* Update channel and forward new topic to other servers */
if (!Channel_IsLocal(chan))
IRC_WriteStrServersPrefix(Client, from, "TOPIC %s :%s",
Req->argv[0], Req->argv[1]);
IRC_WriteStrChannelPrefix(Client, chan, from, false, "TOPIC %s :%s",
Req->argv[0], Req->argv[1]);
if( Client_Type( Client ) == CLIENT_USER ) return IRC_WriteStrClientPrefix( Client, Client, "TOPIC %s :%s", Req->argv[0], Req->argv[1] );
else return CONNECTED;
if (Client_Type(Client) == CLIENT_USER)
return IRC_WriteStrClientPrefix(Client, Client, "TOPIC %s :%s",
Req->argv[0], Req->argv[1]);
else
return CONNECTED;
} /* IRC_TOPIC */
@@ -401,7 +497,7 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
Req->argv[1] );
}
}
while( pattern )
{
/* Loop through all the channels */
@@ -425,14 +521,14 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
}
chan = Channel_Next( chan );
}
/* Get next name ... */
if( Req->argc > 0 )
pattern = strtok( NULL, "," );
else
pattern = NULL;
}
return IRC_WriteStrClient( from, RPL_LISTEND_MSG, Client_ID( from ));
} /* IRC_LIST */
@@ -491,7 +587,7 @@ IRC_CHANINFO( CLIENT *Client, REQUEST *Req )
{
if( *ptr == 'l' )
{
snprintf( l, sizeof( l ), " %ld", Channel_MaxUsers( chan ));
snprintf( l, sizeof( l ), " %lu", Channel_MaxUsers( chan ));
strlcat( modes_add, l, sizeof( modes_add ));
}
if( *ptr == 'k' )
@@ -501,7 +597,7 @@ IRC_CHANINFO( CLIENT *Client, REQUEST *Req )
}
ptr++;
}
/* Inform members of this channel */
IRC_WriteStrChannelPrefix( Client, chan, from, false, "MODE %s +%s%s", Req->argv[0], Channel_Modes( chan ), modes_add );
}

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: irc-info.h,v 1.3 2005/03/19 18:43:48 fw Exp $
* $Id: irc-info.h,v 1.6 2008/02/17 13:26:42 alex Exp $
*
* IRC info commands (header)
*/
@@ -19,14 +19,18 @@
GLOBAL bool IRC_ADMIN PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_INFO PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_ISON PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_LINKS PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_LUSERS PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_MOTD PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_NAMES PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_STATS PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_SUMMON PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_TIME PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_USERHOST PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_USERS PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_SERVLIST PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_VERSION PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_WHO PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_WHOIS PARAMS(( CLIENT *Client, REQUEST *Req ));
@@ -35,7 +39,7 @@ GLOBAL bool IRC_WHOWAS PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_Send_LUSERS PARAMS(( CLIENT *Client ));
GLOBAL bool IRC_Send_NAMES PARAMS(( CLIENT *Client, CHANNEL *Chan ));
GLOBAL bool IRC_Show_MOTD PARAMS(( CLIENT *Client ));
GLOBAL bool IRC_Send_WHO PARAMS(( CLIENT *Client, CHANNEL *Chan, bool OnlyOps ));
GLOBAL bool IRC_Send_ISUPPORT PARAMS(( CLIENT *Client ));
#endif

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,8 +14,6 @@
#include "portab.h"
static char UNUSED id[] = "$Id: irc-login.c,v 1.49 2005/09/01 10:51:24 alex Exp $";
#include "imp.h"
#include <assert.h>
#include <stdio.h>
@@ -35,7 +33,6 @@ static char UNUSED id[] = "$Id: irc-login.c,v 1.49 2005/09/01 10:51:24 alex Exp
#include "irc.h"
#include "irc-info.h"
#include "irc-write.h"
#include "cvs-version.h"
#include "exp.h"
#include "irc-login.h"
@@ -43,103 +40,127 @@ static char UNUSED id[] = "$Id: irc-login.c,v 1.49 2005/09/01 10:51:24 alex Exp
static bool Hello_User PARAMS(( CLIENT *Client ));
static void Kill_Nick PARAMS(( char *Nick, char *Reason ));
static void Introduce_Client PARAMS((CLIENT *To, CLIENT *Client, int Type));
static void cb_introduceClient PARAMS((CLIENT *Client, CLIENT *Prefix,
void *i));
/**
* Handler for the IRC command "PASS".
* See RFC 2813 section 4.1.1, and RFC 2812 section 3.1.1.
*/
GLOBAL bool
IRC_PASS( CLIENT *Client, REQUEST *Req )
{
char *type, *orig_flags;
int protohigh, protolow;
assert( Client != NULL );
assert( Req != NULL );
/* Fehler liefern, wenn kein lokaler Client */
if( Client_Conn( Client ) <= NONE ) return IRC_WriteStrClient( Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( Client ), Req->command );
if(( Client_Type( Client ) == CLIENT_UNKNOWN ) && ( Req->argc == 1))
{
/* noch nicht registrierte unbekannte Verbindung */
Log( LOG_DEBUG, "Connection %d: got PASS command ...", Client_Conn( Client ));
/* Return an error if this is not a local client */
if (Client_Conn(Client) <= NONE)
return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG,
Client_ID(Client), Req->command);
/* Passwort speichern */
Client_SetPassword( Client, Req->argv[0] );
Client_SetType( Client, CLIENT_GOTPASS );
return CONNECTED;
if (Client_Type(Client) == CLIENT_UNKNOWN && Req->argc == 1) {
/* Not yet registered "unknown" connection, PASS with one
* argument: either a regular client, service, or server
* using the old RFC 1459 section 4.1.1 syntax. */
LogDebug("Connection %d: got PASS command (RFC 1459) ...",
Client_Conn(Client));
} else if ((Client_Type(Client) == CLIENT_UNKNOWN ||
Client_Type(Client) == CLIENT_UNKNOWNSERVER) &&
(Req->argc == 3 || Req->argc == 4)) {
/* Not yet registered "unknown" connection or outgoing server
* link, PASS with three or four argument: server using the
* RFC 2813 section 4.1.1 syntax. */
LogDebug("Connection %d: got PASS command (RFC 2813, new server link) ...",
Client_Conn(Client));
} else if (Client_Type(Client) == CLIENT_UNKNOWN ||
Client_Type(Client) == CLIENT_UNKNOWNSERVER) {
/* Unregistered connection, but wrong number of arguments: */
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
} else {
/* Registered connection, PASS command is not allowed! */
return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG,
Client_ID(Client));
}
else if((( Client_Type( Client ) == CLIENT_UNKNOWN ) || ( Client_Type( Client ) == CLIENT_UNKNOWNSERVER )) && (( Req->argc == 3 ) || ( Req->argc == 4 )))
{
char c2, c4, *type, *impl, *serverver, *flags, *ptr, *ircflags;
int protohigh, protolow;
/* noch nicht registrierte Server-Verbindung */
Log( LOG_DEBUG, "Connection %d: got PASS command (new server link) ...", Client_Conn( Client ));
Client_SetPassword(Client, Req->argv[0]);
/* Passwort speichern */
Client_SetPassword( Client, Req->argv[0] );
/* Protocol version */
if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) {
int c2, c4;
/* Protokollversion ermitteln */
if( strlen( Req->argv[1] ) >= 4 )
{
c2 = Req->argv[1][2];
c4 = Req->argv[1][4];
c2 = Req->argv[1][2];
c4 = Req->argv[1][4];
Req->argv[1][4] = '\0';
protolow = atoi( &Req->argv[1][2] );
Req->argv[1][2] = '\0';
protohigh = atoi( Req->argv[1] );
Req->argv[1][2] = c2;
Req->argv[1][4] = c4;
}
else protohigh = protolow = 0;
Req->argv[1][4] = '\0';
protolow = atoi(&Req->argv[1][2]);
Req->argv[1][2] = '\0';
protohigh = atoi(Req->argv[1]);
/* Protokoll-Typ */
if( strlen( Req->argv[1] ) > 4 ) type = &Req->argv[1][4];
else type = NULL;
Req->argv[1][2] = c2;
Req->argv[1][4] = c4;
/* IRC-Flags (nach RFC 2813) */
if( Req->argc >= 4 ) ircflags = Req->argv[3];
else ircflags = "";
Client_SetType(Client, CLIENT_GOTPASS_2813);
} else {
protohigh = protolow = 0;
Client_SetType(Client, CLIENT_GOTPASS);
}
/* Protocol type, see doc/Protocol.txt */
if (Req->argc >= 2 && strlen(Req->argv[1]) > 4)
type = &Req->argv[1][4];
else
type = NULL;
/* Protocol flags/options */
if (Req->argc >= 4)
orig_flags = Req->argv[3];
else
orig_flags = "";
/* Implementation, version and IRC+ flags */
if (Req->argc >= 3) {
char *impl, *ptr, *serverver, *flags;
/* Implementation, Version und ngIRCd-Flags */
impl = Req->argv[2];
ptr = strchr( impl, '|' );
if( ptr ) *ptr = '\0';
ptr = strchr(impl, '|');
if (ptr)
*ptr = '\0';
if( type && ( strcmp( type, PROTOIRCPLUS ) == 0 ))
{
/* auf der anderen Seite laeuft ein Server, der
* ebenfalls das IRC+-Protokoll versteht */
if (type && strcmp(type, PROTOIRCPLUS) == 0) {
/* The peer seems to be a server which supports the
* IRC+ protocol (see doc/Protocol.txt). */
serverver = ptr + 1;
flags = strchr( serverver, ':' );
if( flags )
{
flags = strchr(serverver, ':');
if (flags) {
*flags = '\0';
flags++;
}
else flags = "";
Log( LOG_INFO, "Peer announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").", impl, serverver, protohigh, protolow, flags );
}
else
{
/* auf der anderen Seite laeuft ein Server, der
* nur das Originalprotokoll unterstuetzt */
} else
flags = "";
Log(LOG_INFO,
"Peer announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").",
impl, serverver, protohigh, protolow, flags);
} else {
/* The peer seems to be a server supporting the
* "original" IRC protocol (RFC 2813). */
serverver = "";
if( strchr( ircflags, 'Z' )) flags = "Z";
else flags = "";
Log( LOG_INFO, "Peer announces itself as \"%s\" using protocol %d.%d (flags: \"%s\").", impl, protohigh, protolow, flags );
if (strchr(orig_flags, 'Z'))
flags = "Z";
else
flags = "";
Log(LOG_INFO,
"Peer announces itself as \"%s\" using protocol %d.%d (flags: \"%s\").",
impl, protohigh, protolow, flags);
}
Client_SetType( Client, CLIENT_GOTPASSSERVER );
Client_SetFlags( Client, flags );
return CONNECTED;
Client_SetFlags(Client, flags);
}
else if(( Client_Type( Client ) == CLIENT_UNKNOWN ) || ( Client_Type( Client ) == CLIENT_UNKNOWNSERVER ))
{
/* Falsche Anzahl Parameter? */
return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
}
else return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
return CONNECTED;
} /* IRC_PASS */
@@ -153,27 +174,23 @@ GLOBAL bool
IRC_NICK( CLIENT *Client, REQUEST *Req )
{
CLIENT *intr_c, *target, *c;
char *modes;
char *nick, *user, *hostname, *modes, *info;
int token, hops;
assert( Client != NULL );
assert( Req != NULL );
#ifndef STRICT_RFC
/* Some IRC clients, for example BitchX, send the NICK and USER
* commands in the wrong order ... */
if( Client_Type( Client ) == CLIENT_UNKNOWN
|| Client_Type( Client ) == CLIENT_GOTPASS
|| Client_Type( Client ) == CLIENT_GOTNICK
|| Client_Type( Client ) == CLIENT_GOTUSER
|| Client_Type( Client ) == CLIENT_USER
|| ( Client_Type( Client ) == CLIENT_SERVER && Req->argc == 1 ))
#else
if( Client_Type( Client ) == CLIENT_UNKNOWN
|| Client_Type( Client ) == CLIENT_GOTPASS
|| Client_Type( Client ) == CLIENT_GOTNICK
|| Client_Type( Client ) == CLIENT_USER
|| ( Client_Type( Client ) == CLIENT_SERVER && Req->argc == 1 ))
if(Client_Type(Client) == CLIENT_UNKNOWN
|| Client_Type(Client) == CLIENT_GOTPASS
|| Client_Type(Client) == CLIENT_GOTNICK
#ifndef STRICT_RFC
|| Client_Type(Client) == CLIENT_GOTUSER
#endif
|| Client_Type(Client) == CLIENT_USER
|| Client_Type(Client) == CLIENT_SERVICE
|| (Client_Type(Client) == CLIENT_SERVER && Req->argc == 1))
{
/* User registration or change of nickname */
@@ -221,9 +238,9 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
return CONNECTED;
}
if(( Client_Type( target ) != CLIENT_USER )
&& ( Client_Type( target ) != CLIENT_SERVER ))
{
if (Client_Type(target) != CLIENT_USER &&
Client_Type(target) != CLIENT_SERVICE &&
Client_Type(target) != CLIENT_SERVER) {
/* New client */
Log( LOG_DEBUG, "Connection %d: got valid NICK command ...",
Client_Conn( Client ));
@@ -237,25 +254,22 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
return Hello_User( Client );
else
Client_SetType( Client, CLIENT_GOTNICK );
}
else
{
} else {
/* Nickname change */
if( Client_Conn( target ) > NONE )
{
if (Client_Conn(target) > NONE) {
/* Local client */
Log( LOG_INFO,
"User \"%s\" changed nick (connection %d): \"%s\" -> \"%s\".",
Client_Mask( target ), Client_Conn( target ),
Client_ID( target ), Req->argv[0] );
}
else
{
Log(LOG_INFO,
"%s \"%s\" changed nick (connection %d): \"%s\" -> \"%s\".",
Client_TypeText(target), Client_Mask(target),
Client_Conn(target), Client_ID(target),
Req->argv[0]);
Conn_UpdateIdle(Client_Conn(target));
} else {
/* Remote client */
Log( LOG_DEBUG,
"User \"%s\" changed nick: \"%s\" -> \"%s\".",
Client_Mask( target ), Client_ID( target ),
Req->argv[0] );
LogDebug("%s \"%s\" changed nick: \"%s\" -> \"%s\".",
Client_TypeText(target),
Client_Mask(target), Client_ID(target),
Req->argv[0]);
}
/* Inform all users and servers (which have to know)
@@ -268,29 +282,49 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
"NICK :%s", Req->argv[0] );
IRC_WriteStrRelatedPrefix( target, target, false,
"NICK :%s", Req->argv[0] );
/* Register old nickname for WHOWAS queries */
Client_RegisterWhowas( target );
/* Save new nickname */
Client_SetID( target, Req->argv[0] );
IRC_SetPenalty( target, 2 );
}
return CONNECTED;
}
else if( Client_Type( Client ) == CLIENT_SERVER )
{
/* Server introduces new client */
} else if(Client_Type(Client) == CLIENT_SERVER ||
Client_Type(Client) == CLIENT_SERVICE) {
/* Server or service introduces new client */
/* Falsche Anzahl Parameter? */
if( Req->argc != 7 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* Bad number of parameters? */
if (Req->argc != 2 && Req->argc != 7)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (Req->argc >= 7) {
/* RFC 2813 compatible syntax */
nick = Req->argv[0];
hops = atoi(Req->argv[1]);
user = Req->argv[2];
hostname = Req->argv[3];
token = atoi(Req->argv[4]);
modes = Req->argv[5] + 1;
info = Req->argv[6];
} else {
/* RFC 1459 compatible syntax */
nick = Req->argv[0];
hops = 1;
user = Req->argv[0];
hostname = Client_ID(Client);
token = atoi(Req->argv[1]);
modes = "";
info = Req->argv[0];
}
/* Nick ueberpruefen */
c = Client_Search( Req->argv[0] );
if( c )
{
c = Client_Search(nick);
if(c) {
/* Der neue Nick ist auf diesem Server bereits registriert:
* sowohl der neue, als auch der alte Client muessen nun
* disconnectiert werden. */
@@ -300,7 +334,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
}
/* Server, zu dem der Client connectiert ist, suchen */
intr_c = Client_GetFromToken( Client, atoi( Req->argv[4] ));
intr_c = Client_GetFromToken(Client, token);
if( ! intr_c )
{
Log( LOG_ERR, "Server %s introduces nick \"%s\" on unknown server!?", Client_ID( Client ), Req->argv[0] );
@@ -309,7 +343,8 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
}
/* Neue Client-Struktur anlegen */
c = Client_NewRemoteUser( intr_c, Req->argv[0], atoi( Req->argv[1] ), Req->argv[2], Req->argv[3], atoi( Req->argv[4] ), Req->argv[5] + 1, Req->argv[6], true);
c = Client_NewRemoteUser(intr_c, nick, hops, user, hostname,
token, modes, info, true);
if( ! c )
{
/* Eine neue Client-Struktur konnte nicht angelegt werden.
@@ -320,12 +355,16 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
return CONNECTED;
}
modes = Client_Modes( c );
if( *modes ) Log( LOG_DEBUG, "User \"%s\" (+%s) registered (via %s, on %s, %d hop%s).", Client_Mask( c ), modes, Client_ID( Client ), Client_ID( intr_c ), Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
else Log( LOG_DEBUG, "User \"%s\" registered (via %s, on %s, %d hop%s).", Client_Mask( c ), Client_ID( Client ), Client_ID( intr_c ), Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
/* Andere Server, ausser dem Introducer, informieren */
IRC_WriteStrServersPrefix( Client, Client, "NICK %s %d %s %s %d %s :%s", Req->argv[0], atoi( Req->argv[1] ) + 1, Req->argv[2], Req->argv[3], Client_MyToken( intr_c ), Req->argv[5], Req->argv[6] );
/* RFC 2813: client is now fully registered, inform all the
* other servers about the new user.
* RFC 1459: announce the new client only after receiving the
* USER command, first we need more information! */
if (Req->argc < 7) {
LogDebug("Client \"%s\" is beeing registered (RFC 1459) ...",
Client_Mask(c));
Client_SetType(c, CLIENT_GOTNICK);
} else
Introduce_Client(Client, c, CLIENT_USER);
return CONNECTED;
}
@@ -333,49 +372,193 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
} /* IRC_NICK */
/**
* Handler for the IRC command "USER".
*/
GLOBAL bool
IRC_USER( CLIENT *Client, REQUEST *Req )
IRC_USER(CLIENT * Client, REQUEST * Req)
{
CLIENT *c;
#ifdef IDENTAUTH
char *ptr;
#endif
assert( Client != NULL );
assert( Req != NULL );
assert(Client != NULL);
assert(Req != NULL);
if (Client_Type(Client) == CLIENT_GOTNICK ||
#ifndef STRICT_RFC
if( Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTPASS || Client_Type( Client ) == CLIENT_UNKNOWN )
#else
if( Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTPASS )
Client_Type(Client) == CLIENT_UNKNOWN ||
#endif
Client_Type(Client) == CLIENT_GOTPASS)
{
/* Wrong number of parameters? */
if( Req->argc != 4 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* New connection */
if (Req->argc != 4)
return IRC_WriteStrClient(Client,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client),
Req->command);
/* User name */
#ifdef IDENTAUTH
ptr = Client_User( Client );
if( ! ptr || ! *ptr || *ptr == '~' ) Client_SetUser( Client, Req->argv[0], false );
ptr = Client_User(Client);
if (!ptr || !*ptr || *ptr == '~')
Client_SetUser(Client, Req->argv[0], false);
#else
Client_SetUser( Client, Req->argv[0], false );
Client_SetUser(Client, Req->argv[0], false);
#endif
/* "Real name" or user info text: Don't set it to the empty string, the original ircd
* can't deal with such "real names" (e. g. "USER user * * :") ... */
if( *Req->argv[3] ) Client_SetInfo( Client, Req->argv[3] );
else Client_SetInfo( Client, "-" );
/* "Real name" or user info text: Don't set it to the empty
* string, the original ircd can't deal with such "real names"
* (e. g. "USER user * * :") ... */
if (*Req->argv[3])
Client_SetInfo(Client, Req->argv[3]);
else
Client_SetInfo(Client, "-");
Log( LOG_DEBUG, "Connection %d: got valid USER command ...", Client_Conn( Client ));
if( Client_Type( Client ) == CLIENT_GOTNICK ) return Hello_User( Client );
else Client_SetType( Client, CLIENT_GOTUSER );
LogDebug("Connection %d: got valid USER command ...",
Client_Conn(Client));
if (Client_Type(Client) == CLIENT_GOTNICK)
return Hello_User(Client);
else
Client_SetType(Client, CLIENT_GOTUSER);
return CONNECTED;
} else if (Client_Type(Client) == CLIENT_SERVER ||
Client_Type(Client) == CLIENT_SERVICE) {
/* Server/service updating an user */
if (Req->argc != 4)
return IRC_WriteStrClient(Client,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client),
Req->command);
c = Client_Search(Req->prefix);
if (!c)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client),
Req->prefix);
Client_SetUser(c, Req->argv[0], true);
Client_SetHostname(c, Req->argv[1]);
Client_SetInfo(c, Req->argv[3]);
LogDebug("Connection %d: got valid USER command for \"%s\".",
Client_Conn(Client), Client_Mask(c));
/* RFC 1459 style user registration?
* Introduce client to network: */
if (Client_Type(c) == CLIENT_GOTNICK)
Introduce_Client(Client, c, CLIENT_USER);
return CONNECTED;
} else if (Client_Type(Client) == CLIENT_USER) {
/* Already registered connection */
return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG,
Client_ID(Client));
} else {
/* Unexpected/invalid connection state? */
return IRC_WriteStrClient(Client, ERR_NOTREGISTERED_MSG,
Client_ID(Client));
}
} /* IRC_USER */
/**
* Handler for the IRC command "SERVICE".
* This function implements IRC Services registration using the SERVICE command
* defined in RFC 2812 3.1.6 and RFC 2813 4.1.4.
* At the moment ngIRCd doesn't support directly linked services, so this
* function returns ERR_ERRONEUSNICKNAME when the SERVICE command has not been
* received from a peer server.
*/
GLOBAL bool
IRC_SERVICE(CLIENT *Client, REQUEST *Req)
{
CLIENT *c, *intr_c;
char *nick, *user, *host, *info, *modes, *ptr;
int token, hops;
assert(Client != NULL);
assert(Req != NULL);
if (Client_Type(Client) != CLIENT_GOTPASS &&
Client_Type(Client) != CLIENT_SERVER)
return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG,
Client_ID(Client));
if (Req->argc != 6)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (Client_Type(Client) != CLIENT_SERVER)
return IRC_WriteStrClient(Client, ERR_ERRONEUSNICKNAME_MSG,
Client_ID(Client), Req->argv[0]);
/* Bad number of parameters? */
if (Req->argc != 6)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
nick = Req->argv[0];
user = NULL; host = NULL;
token = atoi(Req->argv[1]);
hops = atoi(Req->argv[4]);
info = Req->argv[5];
/* Validate service name ("nick name") */
c = Client_Search(nick);
if(c) {
/* Nick name collission: disconnect (KILL) both clients! */
Log(LOG_ERR, "Server %s introduces already registered service \"%s\"!",
Client_ID(Client), nick);
Kill_Nick(nick, "Nick collision");
return CONNECTED;
}
else if( Client_Type( Client ) == CLIENT_USER || Client_Type( Client ) == CLIENT_SERVER || Client_Type( Client ) == CLIENT_SERVICE )
{
return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
/* Get the server to which the service is connected */
intr_c = Client_GetFromToken(Client, token);
if (! intr_c) {
Log(LOG_ERR, "Server %s introduces service \"%s\" on unknown server!?",
Client_ID(Client), nick);
Kill_Nick(nick, "Unknown server");
return CONNECTED;
}
else return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
} /* IRC_USER */
/* Get user and host name */
ptr = strchr(nick, '@');
if (ptr) {
*ptr = '\0';
host = ++ptr;
}
if (!host)
host = Client_Hostname(intr_c);
ptr = strchr(nick, '!');
if (ptr) {
*ptr = '\0';
user = ++ptr;
}
if (!user)
user = nick;
/* According to RFC 2812/2813 parameter 4 <type> "is currently reserved
* for future usage"; but we use it to transfer the modes and check
* that the first character is a '+' sign and ignore it otherwise. */
modes = (Req->argv[3][0] == '+') ? ++Req->argv[3] : "";
c = Client_NewRemoteUser(intr_c, nick, hops, user, host,
token, modes, info, true);
if (! c) {
/* Couldn't create client structure, so KILL the service to
* keep network status consistent ... */
Log(LOG_ALERT, "Can't create client structure! (on connection %d)",
Client_Conn(Client));
Kill_Nick(nick, "Server error");
return CONNECTED;
}
Introduce_Client(Client, c, CLIENT_SERVICE);
return CONNECTED;
} /* IRC_SERVICE */
GLOBAL bool
@@ -383,10 +566,10 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
{
CLIENT *target;
char quitmsg[LINE_LEN];
assert( Client != NULL );
assert( Req != NULL );
/* Wrong number of arguments? */
if( Req->argc > 1 )
return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
@@ -420,7 +603,7 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
/* User, Service, oder noch nicht registriert */
Conn_Close( Client_Conn( Client ), "Got QUIT command.", Req->argc == 1 ? quitmsg : NULL, true);
return DISCONNECTED;
}
} /* IRC_QUIT */
@@ -489,7 +672,7 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
Client_ID(from), Client_ID(Client));
#else
/* Some clients depend on the argument being returned in the PONG
* reply (not mentioned in any RFC, though) */
* reply (not mentioned in any RFC, though) */
return IRC_WriteStrClient(Client, "PONG %s :%s",
Client_ID(from), Req->argv[0]);
#endif
@@ -555,60 +738,51 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
static bool
Hello_User( CLIENT *Client )
Hello_User(CLIENT * Client)
{
#ifdef CVSDATE
char ver[12], vertxt[30];
#endif
assert( Client != NULL );
assert(Client != NULL);
/* Check password ... */
if( strcmp( Client_Password( Client ), Conf_ServerPwd ) != 0 )
{
if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
/* Bad password! */
Log( LOG_ERR, "User \"%s\" rejected (connection %d): Bad password!", Client_Mask( Client ), Client_Conn( Client ));
Conn_Close( Client_Conn( Client ), NULL, "Bad password", true);
Log(LOG_ERR,
"Client \"%s\" rejected (connection %d): Bad password!",
Client_Mask(Client), Client_Conn(Client));
Conn_Close(Client_Conn(Client), NULL, "Bad password", true);
return DISCONNECTED;
}
Log( LOG_NOTICE, "User \"%s\" registered (connection %d).", Client_Mask( Client ), Client_Conn( Client ));
Introduce_Client(NULL, Client, CLIENT_USER);
/* Inform other servers */
IRC_WriteStrServers( NULL, "NICK %s 1 %s %s 1 +%s :%s", Client_ID( Client ), Client_User( Client ), Client_Hostname( Client ), Client_Modes( Client ), Client_Info( Client ));
if (!IRC_WriteStrClient
(Client, RPL_WELCOME_MSG, Client_ID(Client), Client_Mask(Client)))
return false;
if (!IRC_WriteStrClient
(Client, RPL_YOURHOST_MSG, Client_ID(Client),
Client_ID(Client_ThisServer()), PACKAGE_VERSION, TARGET_CPU,
TARGET_VENDOR, TARGET_OS))
return false;
if (!IRC_WriteStrClient
(Client, RPL_CREATED_MSG, Client_ID(Client), NGIRCd_StartStr))
return false;
if (!IRC_WriteStrClient
(Client, RPL_MYINFO_MSG, Client_ID(Client),
Client_ID(Client_ThisServer()), PACKAGE_VERSION, USERMODES,
CHANMODES))
return false;
/* Welcome :-) */
if( ! IRC_WriteStrClient( Client, RPL_WELCOME_MSG, Client_ID( Client ), Client_Mask( Client ))) return false;
/* Features supported by this server (005 numeric, ISUPPORT),
* see <http://www.irc.org/tech_docs/005.html> for details. */
if (!IRC_Send_ISUPPORT(Client))
return DISCONNECTED;
/* Version and system type */
#ifdef CVSDATE
strlcpy( ver, CVSDATE, sizeof( ver ));
strncpy( ver + 4, ver + 5, 2 );
strncpy( ver + 6, ver + 8, 3 );
snprintf( vertxt, sizeof( vertxt ), "%s(%s)", PACKAGE_VERSION, ver );
if( ! IRC_WriteStrClient( Client, RPL_YOURHOST_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), vertxt, TARGET_CPU, TARGET_VENDOR, TARGET_OS )) return false;
#else
if( ! IRC_WriteStrClient( Client, RPL_YOURHOST_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), PACKAGE_VERSION, TARGET_CPU, TARGET_VENDOR, TARGET_OS )) return false;
#endif
if( ! IRC_WriteStrClient( Client, RPL_CREATED_MSG, Client_ID( Client ), NGIRCd_StartStr )) return false;
#ifdef CVSDATE
if( ! IRC_WriteStrClient( Client, RPL_MYINFO_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), vertxt, USERMODES, CHANMODES )) return false;
#else
if( ! IRC_WriteStrClient( Client, RPL_MYINFO_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), PACKAGE_VERSION, USERMODES, CHANMODES )) return false;
#endif
/* Features */
if( ! IRC_WriteStrClient( Client, RPL_ISUPPORT_MSG, Client_ID( Client ), CLIENT_NICK_LEN - 1,
COMMAND_LEN - 23, CLIENT_AWAY_LEN - 1, Conf_MaxJoins )) return DISCONNECTED;
Client_SetType( Client, CLIENT_USER );
if( ! IRC_Send_LUSERS( Client )) return DISCONNECTED;
if( ! IRC_Show_MOTD( Client )) return DISCONNECTED;
if (!IRC_Send_LUSERS(Client))
return DISCONNECTED;
if (!IRC_Show_MOTD(Client))
return DISCONNECTED;
/* Suspend the client for a second ... */
IRC_SetPenalty( Client, 1 );
IRC_SetPenalty(Client, 1);
return CONNECTED;
} /* Hello_User */
@@ -632,4 +806,74 @@ Kill_Nick( char *Nick, char *Reason )
} /* Kill_Nick */
static void
Introduce_Client(CLIENT *From, CLIENT *Client, int Type)
{
/* Set client type (user or service) */
Client_SetType(Client, Type);
if (From) {
if (Conf_IsService(Conf_GetServer(Client_Conn(From)),
Client_ID(Client)))
Client_SetType(Client, CLIENT_SERVICE);
LogDebug("%s \"%s\" (+%s) registered (via %s, on %s, %d hop%s).",
Client_TypeText(Client), Client_Mask(Client),
Client_Modes(Client), Client_ID(From),
Client_ID(Client_Introducer(Client)),
Client_Hops(Client), Client_Hops(Client) > 1 ? "s": "");
} else
Log(LOG_NOTICE, "%s \"%s\" registered (connection %d).",
Client_TypeText(Client), Client_Mask(Client),
Client_Conn(Client));
/* Inform other servers */
IRC_WriteStrServersPrefixFlag_CB(From,
From != NULL ? From : Client_ThisServer(),
'\0', cb_introduceClient, (void *)Client);
} /* Introduce_Client */
static void
cb_introduceClient(CLIENT *To, CLIENT *Prefix, void *data)
{
CLIENT *c = (CLIENT *)data;
CONN_ID conn;
char *modes, *user, *host;
modes = Client_Modes(c);
user = Client_User(c) ? Client_User(c) : "-";
host = Client_Hostname(c) ? Client_Hostname(c) : "-";
conn = Client_Conn(To);
if (Conn_Options(conn) & CONN_RFC1459) {
/* RFC 1459 mode: separate NICK and USER commands */
Conn_WriteStr(conn, "NICK %s :%d", Client_ID(c),
Client_Hops(c) + 1);
Conn_WriteStr(conn, ":%s USER %s %s %s :%s",
Client_ID(c), user, host,
Client_ID(Client_Introducer(c)), Client_Info(c));
if (modes[0])
Conn_WriteStr(conn, ":%s MODE %s +%s",
Client_ID(c), Client_ID(c), modes);
} else {
/* RFC 2813 mode: one combined NICK or SERVICE command */
if (Client_Type(c) == CLIENT_SERVICE
&& strchr(Client_Flags(To), 'S'))
IRC_WriteStrClientPrefix(To, Prefix,
"SERVICE %s %d * +%s %d :%s",
Client_Mask(c),
Client_MyToken(Client_Introducer(c)),
Client_Modes(c), Client_Hops(c) + 1,
Client_Info(c));
else
IRC_WriteStrClientPrefix(To, Prefix,
"NICK %s %d %s %s %d +%s :%s",
Client_ID(c), Client_Hops(c) + 1,
user, host,
Client_MyToken(Client_Introducer(c)),
modes, Client_Info(c));
}
} /* cb_introduceClient */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -8,8 +8,6 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: irc-login.h,v 1.6 2005/03/19 18:43:48 fw Exp $
*
* Login and logout (header)
*/
@@ -17,14 +15,13 @@
#ifndef __irc_login_h__
#define __irc_login_h__
GLOBAL bool IRC_PASS PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_NICK PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_USER PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_PING PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_PONG PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_QUIT PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_PASS PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_NICK PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_USER PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_SERVICE PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_PING PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_PONG PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_QUIT PARAMS((CLIENT *Client, REQUEST *Req));
#endif

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2005 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,8 +14,6 @@
#include "portab.h"
static char UNUSED id[] = "$Id: irc-mode.c,v 1.45 2006/05/10 21:24:01 alex Exp $";
#include "imp.h"
#include <assert.h>
#include <stdio.h>
@@ -41,13 +39,10 @@ static char UNUSED id[] = "$Id: irc-mode.c,v 1.45 2006/05/10 21:24:01 alex Exp $
static bool Client_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ));
static bool Channel_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ));
static bool Add_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
static bool Add_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
static bool Add_Ban_Invite PARAMS((int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Pattern));
static bool Del_Ban_Invite PARAMS((int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Pattern));
static bool Del_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
static bool Del_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
static bool Send_ListChange PARAMS(( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Mask ));
static bool Send_ListChange PARAMS(( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Mask ));
GLOBAL bool
@@ -69,7 +64,7 @@ IRC_MODE( CLIENT *Client, REQUEST *Req )
if( ! origin ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
}
else origin = Client;
/* Channel or user mode? */
cl = NULL; chan = NULL;
if (Client_IsValidNick(Req->argv[0]))
@@ -164,6 +159,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
{
case 'i': /* Invisible */
case 's': /* Server messages */
case 'w': /* Wallops messages */
x[0] = *mode_ptr;
break;
@@ -233,7 +229,9 @@ client_exit:
ok = IRC_WriteStrClientPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes );
IRC_WriteStrServersPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes );
}
Log( LOG_DEBUG, "User \"%s\": Mode change, now \"%s\".", Client_Mask( Target ), Client_Modes( Target ));
LogDebug("%s \"%s\": Mode change, now \"%s\".",
Client_TypeText(Target), Client_Mask(Target),
Client_Modes(Target));
}
IRC_SetPenalty( Client, 1 );
@@ -241,123 +239,145 @@ client_exit:
} /* Client_Mode */
static bool
Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel)
{
char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], argadd[CLIENT_PASS_LEN];
const char *mode_ptr;
/* Member or not? -- That's the question! */
if (!Channel_IsMemberOf(Channel, Origin))
return IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG,
Client_ID(Origin), Channel_Name(Channel), Channel_Modes(Channel));
/* The sender is a member: generate extended reply */
strlcpy(the_modes, Channel_Modes(Channel), sizeof(the_modes));
mode_ptr = the_modes;
the_args[0] = '\0';
while(*mode_ptr) {
switch(*mode_ptr) {
case 'l':
snprintf(argadd, sizeof(argadd), " %lu", Channel_MaxUsers(Channel));
strlcat(the_args, argadd, sizeof(the_args));
break;
case 'k':
strlcat(the_args, " ", sizeof(the_args));
strlcat(the_args, Channel_Key(Channel), sizeof(the_args));
break;
}
mode_ptr++;
}
if (the_args[0])
strlcat(the_modes, the_args, sizeof(the_modes));
return IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG,
Client_ID(Origin), Channel_Name(Channel), the_modes);
}
static bool
Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
{
/* Handle channel and channel-user modes */
char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2], argadd[CLIENT_PASS_LEN], *mode_ptr;
bool ok, set, modeok = false, skiponce, use_servermode = false;
bool ok, set, modeok = true, skiponce, use_servermode = false, retval;
int mode_arg, arg_arg;
CLIENT *client;
long l;
size_t len;
/* Are modes allowed on channel? */
if (Channel_Name(Channel)[0] == '+')
return IRC_WriteStrClient(Client, ERR_NOCHANMODES_MSG,
Client_ID(Client), Channel_Name(Channel));
/* Mode request: let's answer it :-) */
if( Req->argc == 1 )
{
/* Member or not? -- That's the question! */
if( ! Channel_IsMemberOf( Channel, Origin )) return IRC_WriteStrClient( Origin, RPL_CHANNELMODEIS_MSG, Client_ID( Origin ), Channel_Name( Channel ), Channel_Modes( Channel ));
/* The sender is a member: generate extended reply */
strlcpy( the_modes, Channel_Modes( Channel ), sizeof( the_modes ));
mode_ptr = the_modes;
the_args[0] = '\0';
while( *mode_ptr )
{
switch( *mode_ptr )
{
case 'l':
snprintf( argadd, sizeof( argadd ), " %ld", Channel_MaxUsers( Channel ));
strlcat( the_args, argadd, sizeof( the_args ));
break;
case 'k':
strlcat( the_args, " ", sizeof( the_args ));
strlcat( the_args, Channel_Key( Channel ), sizeof( the_args ));
break;
}
mode_ptr++;
}
if( the_args[0] ) strlcat( the_modes, the_args, sizeof( the_modes ));
return IRC_WriteStrClient( Origin, RPL_CHANNELMODEIS_MSG, Client_ID( Origin ), Channel_Name( Channel ), the_modes );
}
if (Req->argc <= 1)
return Channel_Mode_Answer_Request(Origin, Channel);
/* Is the user allowed to change modes? */
if( Client_Type( Client ) == CLIENT_USER )
{
if (Client_Type(Client) == CLIENT_USER) {
/* Is the originating user on that channel? */
if( ! Channel_IsMemberOf( Channel, Origin )) return IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG, Client_ID( Origin ), Channel_Name( Channel ));
/* Is he channel operator? */
if( strchr( Channel_UserModes( Channel, Origin ), 'o' )) modeok = true;
else if( Conf_OperCanMode )
{
if (!Channel_IsMemberOf(Channel, Origin))
return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG,
Client_ID(Origin), Channel_Name(Channel));
modeok = false;
/* channel operator? */
if (strchr(Channel_UserModes(Channel, Origin), 'o'))
modeok = true;
else if(Conf_OperCanMode) {
/* IRC-Operators can use MODE as well */
if( Client_OperByMe( Origin )) {
if (Client_OperByMe(Origin)) {
modeok = true;
if ( Conf_OperServerMode ) use_servermode = true; /* Change Origin to Server */
if (Conf_OperServerMode)
use_servermode = true; /* Change Origin to Server */
}
}
}
else modeok = true;
mode_arg = 1;
mode_ptr = Req->argv[mode_arg];
if( Req->argc > mode_arg + 1 ) arg_arg = mode_arg + 1;
else arg_arg = -1;
if (Req->argc > mode_arg + 1)
arg_arg = mode_arg + 1;
else
arg_arg = -1;
/* Initial state: set or unset modes? */
skiponce = false;
if( *mode_ptr == '-' ) set = false;
else if( *mode_ptr == '+' ) set = true;
else set = skiponce = true;
switch (*mode_ptr) {
case '-': set = false; break;
case '+': set = true; break;
default:
set = true;
skiponce = true;
}
/* Prepare reply string */
if( set ) strcpy( the_modes, "+" );
else strcpy( the_modes, "-" );
strcpy( the_args, " " );
strcpy(the_modes, set ? "+" : "-");
the_args[0] = '\0';
x[1] = '\0';
ok = CONNECTED;
while( mode_ptr )
{
if( ! skiponce ) mode_ptr++;
if( ! *mode_ptr )
{
while (mode_ptr) {
if (! skiponce)
mode_ptr++;
if (!*mode_ptr) {
/* Try next argument if there's any */
if( arg_arg > mode_arg ) mode_arg = arg_arg;
else mode_arg++;
if( mode_arg < Req->argc ) mode_ptr = Req->argv[mode_arg];
else break;
if( Req->argc > mode_arg + 1 ) arg_arg = mode_arg + 1;
else arg_arg = -1;
if (arg_arg > mode_arg)
mode_arg = arg_arg;
else
mode_arg++;
if (mode_arg >= Req->argc)
break;
mode_ptr = Req->argv[mode_arg];
if (Req->argc > mode_arg + 1)
arg_arg = mode_arg + 1;
else
arg_arg = -1;
}
skiponce = false;
switch( *mode_ptr )
{
case '+':
case '-':
if((( *mode_ptr == '+' ) && ( ! set )) || (( *mode_ptr == '-' ) && ( set )))
{
/* Action modifier ("+"/"-") must be changed ... */
len = strlen( the_modes ) - 1;
if(( the_modes[len] == '+' ) || ( the_modes[len] == '-' ))
{
/* Adjust last action modifier in result */
the_modes[len] = *mode_ptr;
}
else
{
/* Append modifier character to result string */
x[0] = *mode_ptr;
strlcat( the_modes, x, sizeof( the_modes ));
}
if( *mode_ptr == '+' ) set = true;
else set = false;
switch (*mode_ptr) {
case '+':
case '-':
if (((*mode_ptr == '+') && !set) || ((*mode_ptr == '-') && set)) {
/* Action modifier ("+"/"-") must be changed ... */
len = strlen( the_modes ) - 1;
if ((the_modes[len] == '+') || (the_modes[len] == '-')) {
/* Adjust last action modifier in result */
the_modes[len] = *mode_ptr;
} else {
/* Append modifier character to result string */
x[0] = *mode_ptr;
strlcat(the_modes, x, sizeof(the_modes));
}
continue;
set = *mode_ptr == '+';
}
continue;
}
/* Are there arguments left? */
@@ -367,240 +387,206 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
x[0] = '\0';
argadd[0] = '\0';
client = NULL;
switch( *mode_ptr )
{
/* --- Channel modes --- */
case 'i': /* Invite only */
case 'm': /* Moderated */
case 'n': /* Only members can write */
case 's': /* Secret channel */
case 't': /* Topic locked */
if( modeok ) x[0] = *mode_ptr;
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
switch (*mode_ptr) {
/* --- Channel modes --- */
case 'i': /* Invite only */
case 'm': /* Moderated */
case 'n': /* Only members can write */
case 's': /* Secret channel */
case 't': /* Topic locked */
if (modeok)
x[0] = *mode_ptr;
else
ok = IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID(Origin), Channel_Name(Channel));
break;
case 'k': /* Channel key */
if (! set) {
if (modeok)
x[0] = *mode_ptr;
else
ok = IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID(Origin), Channel_Name(Channel));
break;
case 'k': /* Channel key */
if( ! set )
{
if( modeok ) x[0] = *mode_ptr;
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
break;
}
if (arg_arg > mode_arg) {
if (modeok) {
Channel_ModeDel(Channel, 'k');
Channel_SetKey(Channel, Req->argv[arg_arg]);
strlcpy(argadd, Channel_Key(Channel), sizeof(argadd));
x[0] = *mode_ptr;
} else {
ok = IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID(Origin), Channel_Name(Channel));
}
if( arg_arg > mode_arg )
{
if( modeok )
{
Channel_ModeDel( Channel, 'k' );
Channel_SetKey( Channel, Req->argv[arg_arg] );
strlcpy( argadd, Channel_Key( Channel ), sizeof( argadd ));
Req->argv[arg_arg][0] = '\0';
arg_arg++;
} else {
ok = IRC_WriteStrClient(Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID(Origin), Req->command);
}
break;
case 'l': /* Member limit */
if (!set) {
if (modeok)
x[0] = *mode_ptr;
else
ok = IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID(Origin), Channel_Name(Channel));
break;
}
if (arg_arg > mode_arg) {
if (modeok) {
l = atol(Req->argv[arg_arg]);
if (l > 0 && l < 0xFFFF) {
Channel_ModeDel(Channel, 'l');
Channel_SetMaxUsers(Channel, l);
snprintf(argadd, sizeof(argadd), "%ld", l);
x[0] = *mode_ptr;
}
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
Req->argv[arg_arg][0] = '\0';
arg_arg++;
} else {
ok = IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID(Origin), Channel_Name(Channel));
}
else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command );
break;
case 'l': /* Member limit */
if( ! set )
{
if( modeok ) x[0] = *mode_ptr;
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
break;
Req->argv[arg_arg][0] = '\0';
arg_arg++;
} else {
ok = IRC_WriteStrClient(Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID(Origin), Req->command);
}
break;
case 'P': /* Persistent channel */
if (modeok) {
/* Only IRC operators are allowed to
* set the 'P' channel mode! */
if (set && !(Client_OperByMe(Client) || Client_Type(Client) == CLIENT_SERVER))
ok = IRC_WriteStrClient(Origin, ERR_NOPRIVILEGES_MSG, Client_ID(Origin));
else
x[0] = 'P';
} else
ok = IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID(Origin), Channel_Name(Channel));
break;
/* --- Channel user modes --- */
case 'o': /* Channel operator */
case 'v': /* Voice */
if (arg_arg > mode_arg) {
if (modeok) {
client = Client_Search(Req->argv[arg_arg]);
if (client)
x[0] = *mode_ptr;
else
ok = IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->argv[arg_arg]);
} else {
ok = IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID(Origin), Channel_Name(Channel));
}
if( arg_arg > mode_arg )
{
if( modeok )
{
l = atol( Req->argv[arg_arg] );
if( l > 0 && l < 0xFFFF )
{
Channel_ModeDel( Channel, 'l' );
Channel_SetMaxUsers( Channel, l );
snprintf( argadd, sizeof( argadd ), "%ld", l );
x[0] = *mode_ptr;
}
}
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
Req->argv[arg_arg][0] = '\0';
arg_arg++;
Req->argv[arg_arg][0] = '\0';
arg_arg++;
} else {
ok = IRC_WriteStrClient(Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID(Origin), Req->command);
}
break;
/* --- Channel lists --- */
case 'I': /* Invite lists */
case 'b': /* Ban lists */
if (arg_arg > mode_arg) {
/* modify list */
if (modeok) {
ok = set ? Add_Ban_Invite(*mode_ptr, Origin, Client, Channel, Req->argv[arg_arg])
: Del_Ban_Invite(*mode_ptr, Origin, Client, Channel, Req->argv[arg_arg]);
} else {
ok = IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin), Channel_Name(Channel));
}
else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command );
break;
Req->argv[arg_arg][0] = '\0';
arg_arg++;
} else {
if (*mode_ptr == 'I')
Channel_ShowInvites(Origin, Channel);
else
Channel_ShowBans(Origin, Channel);
}
break;
default:
Log(LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\" on %s!?",
set ? '+' : '-', *mode_ptr, Client_ID(Origin), Channel_Name(Channel));
if (Client_Type(Client) != CLIENT_SERVER)
ok = IRC_WriteStrClient(Origin, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID(Origin), set ? '+' : '-', *mode_ptr);
x[0] = '\0';
goto chan_exit;
} /* switch() */
case 'P': /* Persistent channel */
if( modeok )
{
if( set && ( ! Client_OperByMe( Client )))
{
/* Only IRC operators are allowed to set P mode */
ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin ));
}
else x[0] = 'P';
}
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
break;
/* --- Channel user modes --- */
case 'o': /* Channel operator */
case 'v': /* Voice */
if( arg_arg > mode_arg )
{
if( modeok )
{
client = Client_Search( Req->argv[arg_arg] );
if( client ) x[0] = *mode_ptr;
else ok = IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[arg_arg] );
}
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
Req->argv[arg_arg][0] = '\0';
arg_arg++;
}
else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command );
break;
/* --- Channel lists --- */
case 'I': /* Invite lists */
if( arg_arg > mode_arg )
{
/* modify list */
if( modeok )
{
if( set ) Add_Invite( Origin, Client, Channel, Req->argv[arg_arg] );
else Del_Invite( Origin, Client, Channel, Req->argv[arg_arg] );
}
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
Req->argv[arg_arg][0] = '\0';
arg_arg++;
}
else Lists_ShowInvites( Origin, Channel );
break;
case 'b': /* Ban lists */
if( arg_arg > mode_arg )
{
/* modify list */
if( modeok )
{
if( set ) Add_Ban( Origin, Client, Channel, Req->argv[arg_arg] );
else Del_Ban( Origin, Client, Channel, Req->argv[arg_arg] );
}
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
Req->argv[arg_arg][0] = '\0';
arg_arg++;
}
else Lists_ShowBans( Origin, Channel );
break;
default:
Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\" on %s!?", set ? '+' : '-', *mode_ptr, Client_ID( Origin ), Channel_Name( Channel ));
if( Client_Type( Client ) != CLIENT_SERVER ) ok = IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Origin ), set ? '+' : '-', *mode_ptr );
x[0] = '\0';
goto chan_exit;
}
if( ! ok ) break;
if (!ok)
break;
/* Is there a valid mode change? */
if( ! x[0] ) continue;
if (!x[0])
continue;
/* Validate target client */
if( client && ( ! Channel_IsMemberOf( Channel, client )))
{
if( ! IRC_WriteStrClient( Origin, ERR_USERNOTINCHANNEL_MSG, Client_ID( Origin ), Client_ID( client ), Channel_Name( Channel ))) break;
if (client && (!Channel_IsMemberOf(Channel, client))) {
if (!IRC_WriteStrClient(Origin, ERR_USERNOTINCHANNEL_MSG,
Client_ID(Origin), Client_ID(client), Channel_Name(Channel)))
break;
continue;
}
if( set )
{
/* Set mode */
if( client )
{
/* Channel-User-Mode */
if( Channel_UserModeAdd( Channel, client, x[0] ))
{
strlcat( the_args, Client_ID( client ), sizeof( the_args ));
strlcat( the_args, " ", sizeof( the_args ));
strlcat( the_modes, x, sizeof( the_modes ));
Log( LOG_DEBUG, "User \"%s\": Mode change on %s, now \"%s\"", Client_Mask( client ), Channel_Name( Channel ), Channel_UserModes( Channel, client ));
}
if (client) {
/* Channel-User-Mode */
retval = set ? Channel_UserModeAdd(Channel, client, x[0]) : Channel_UserModeDel(Channel, client, x[0]);
if (retval) {
strlcat(the_args, " ", sizeof(the_args));
strlcat(the_args, Client_ID(client), sizeof(the_args));
strlcat(the_modes, x, sizeof(the_modes));
Log(LOG_DEBUG, "User \"%s\": Mode change on %s, now \"%s\"",
Client_Mask(client), Channel_Name(Channel), Channel_UserModes(Channel, client));
}
else
{
/* Channel-Mode */
if( Channel_ModeAdd( Channel, x[0] ))
{
strlcat( the_modes, x, sizeof( the_modes ));
Log( LOG_DEBUG, "Channel %s: Mode change, now \"%s\".", Channel_Name( Channel ), Channel_Modes( Channel ));
}
}
}
else
{
/* Unset mode */
if( client )
{
/* Channel-User-Mode */
if( Channel_UserModeDel( Channel, client, x[0] ))
{
strlcat( the_args, Client_ID( client ), sizeof( the_args ));
strlcat( the_args, " ", sizeof( the_args ));
strlcat( the_modes, x, sizeof( the_modes ));
Log( LOG_DEBUG, "User \"%s\": Mode change on %s, now \"%s\"", Client_Mask( client ), Channel_Name( Channel ), Channel_UserModes( Channel, client ));
}
}
else
{
/* Channel-Mode */
if( Channel_ModeDel( Channel, x[0] ))
{
strlcat( the_modes, x, sizeof( the_modes ));
Log( LOG_DEBUG, "Channel %s: Mode change, now \"%s\".", Channel_Name( Channel ), Channel_Modes( Channel ));
}
} else {
/* Channel-Mode */
retval = set ? Channel_ModeAdd(Channel, x[0]) : Channel_ModeDel(Channel, x[0]);
if (retval) {
strlcat(the_modes, x, sizeof(the_modes));
Log(LOG_DEBUG, "Channel %s: Mode change, now \"%s\".", Channel_Name(Channel), Channel_Modes(Channel));
}
}
/* Are there additional arguments to add? */
if( argadd[0] )
{
len = strlen( the_args ) - 1;
if( the_args[len] != ' ' ) strlcat( the_args, " ", sizeof( the_args ));
strlcat( the_args, argadd, sizeof( the_args ));
if (argadd[0]) {
strlcat(the_args, " ", sizeof(the_args));
strlcat(the_args, argadd, sizeof(the_args));
}
}
chan_exit:
/* Are there changed modes? */
if( the_modes[1] )
{
if (the_modes[1]) {
/* Clean up mode string */
len = strlen( the_modes ) - 1;
if(( the_modes[len] == '+' ) || ( the_modes[len] == '-' )) the_modes[len] = '\0';
len = strlen(the_modes) - 1;
if ((the_modes[len] == '+') || (the_modes[len] == '-'))
the_modes[len] = '\0';
/* Clean up argument string if there are none */
if( ! the_args[1] ) the_args[0] = '\0';
if( Client_Type( Client ) == CLIENT_SERVER )
{
/* Forward mode changes to channel users and other servers */
IRC_WriteStrServersPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
IRC_WriteStrChannelPrefix( Client, Channel, Origin, false, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
}
else
{
if ( use_servermode ) Origin = Client_ThisServer();
if (Client_Type(Client) == CLIENT_SERVER) {
/* MODE requests for local channels from other servers
* are definitely invalid! */
if (Channel_IsLocal(Channel)) {
Log(LOG_ALERT, "Got remote MODE command for local channel!? Ignored.");
return CONNECTED;
}
/* Forward mode changes to channel users and all the
* other remote servers: */
IRC_WriteStrServersPrefix(Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args);
IRC_WriteStrChannelPrefix(Client, Channel, Origin, false, "MODE %s %s%s", Channel_Name(Channel), the_modes, the_args);
} else {
if (use_servermode)
Origin = Client_ThisServer();
/* Send reply to client and inform other servers and channel users */
ok = IRC_WriteStrClientPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
IRC_WriteStrServersPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
IRC_WriteStrChannelPrefix( Client, Channel, Origin, false, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
ok = IRC_WriteStrClientPrefix(Client, Origin, "MODE %s %s%s",
Channel_Name(Channel), the_modes, the_args);
/* Only forward requests for non-local channels */
if (!Channel_IsLocal(Channel))
IRC_WriteStrServersPrefix(Client, Origin,
"MODE %s %s%s", Channel_Name(Channel),
the_modes, the_args);
IRC_WriteStrChannelPrefix(Client, Channel, Origin,
false, "MODE %s %s%s", Channel_Name(Channel),
the_modes, the_args);
}
}
IRC_SetPenalty( Client, 1 );
IRC_SetPenalty(Client, 1);
return CONNECTED;
} /* Channel_Mode */
@@ -633,81 +619,64 @@ IRC_AWAY( CLIENT *Client, REQUEST *Req )
static bool
Add_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
Add_Ban_Invite(int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Pattern)
{
char *mask;
const char *mask;
bool already;
bool ret;
assert( Client != NULL );
assert( Channel != NULL );
assert( Pattern != NULL );
assert(what == 'I' || what == 'b');
mask = Lists_MakeMask( Pattern );
mask = Lists_MakeMask(Pattern);
already = Lists_IsInviteEntry( mask, Channel );
if( ! Lists_AddInvited( mask, Channel, false )) return CONNECTED;
if(( Client_Type( Prefix ) == CLIENT_SERVER ) && ( already == true)) return CONNECTED;
already = Lists_CheckDupeMask(Channel_GetListInvites(Channel), mask);
if (!already) {
if (what == 'I')
ret = Channel_AddInvite(Channel, mask, false);
else
ret = Channel_AddBan(Channel, mask);
if (!ret)
return CONNECTED;
}
if (already && (Client_Type(Prefix) == CLIENT_SERVER))
return CONNECTED;
return Send_ListChange( "+I", Prefix, Client, Channel, mask );
} /* Add_Invite */
if (what == 'I')
return Send_ListChange("+I", Prefix, Client, Channel, mask);
return Send_ListChange("+b", Prefix, Client, Channel, mask);
}
static bool
Add_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
Del_Ban_Invite(int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Pattern)
{
char *mask;
bool already;
const char *mask;
struct list_head *list;
assert( Client != NULL );
assert( Channel != NULL );
assert( Pattern != NULL );
assert(what == 'I' || what == 'b');
mask = Lists_MakeMask( Pattern );
already = Lists_IsBanEntry( mask, Channel );
if (what == 'I')
list = Channel_GetListInvites(Channel);
else
list = Channel_GetListBans(Channel);
if( ! Lists_AddBanned( mask, Channel )) return CONNECTED;
if(( Client_Type( Prefix ) == CLIENT_SERVER ) && ( already == true)) return CONNECTED;
return Send_ListChange( "+b", Prefix, Client, Channel, mask );
} /* Add_Ban */
static bool
Del_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
{
char *mask;
assert( Client != NULL );
assert( Channel != NULL );
assert( Pattern != NULL );
mask = Lists_MakeMask( Pattern );
Lists_DelInvited( mask, Channel );
return Send_ListChange( "-I", Prefix, Client, Channel, mask );
} /* Del_Invite */
static bool
Del_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
{
char *mask;
assert( Client != NULL );
assert( Channel != NULL );
assert( Pattern != NULL );
mask = Lists_MakeMask( Pattern );
Lists_DelBanned( mask, Channel );
Lists_Del(list, mask);
if (what == 'I')
return Send_ListChange( "-I", Prefix, Client, Channel, mask );
return Send_ListChange( "-b", Prefix, Client, Channel, mask );
} /* Del_Ban */
}
static bool
Send_ListChange( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Mask )
Send_ListChange( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Mask )
{
/* Bestaetigung an Client schicken & andere Server sowie Channel-User informieren */

View File

@@ -14,8 +14,6 @@
#include "portab.h"
static char UNUSED id[] = "$Id: irc-op.c,v 1.15 2005/04/27 07:39:18 alex Exp $";
#include "imp.h"
#include <assert.h>
#include <string.h>
@@ -35,90 +33,187 @@ static char UNUSED id[] = "$Id: irc-op.c,v 1.15 2005/04/27 07:39:18 alex Exp $";
#include "irc-op.h"
GLOBAL bool
IRC_KICK( CLIENT *Client, REQUEST *Req )
static bool
try_kick(CLIENT *peer, CLIENT* from, const char *nick, const char *channel,
const char *reason)
{
CLIENT *target, *from;
CLIENT *target = Client_Search(nick);
if (!target)
return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG, Client_ID(from), nick);
Channel_Kick(peer, target, from, channel, reason);
return true;
}
GLOBAL bool
IRC_KICK(CLIENT *Client, REQUEST *Req)
{
CLIENT *from;
char *itemList = Req->argv[0];
const char* currentNick, *currentChannel, *reason;
unsigned int channelCount = 1;
unsigned int nickCount = 1;
assert( Client != NULL );
assert( Req != NULL );
/* Falsche Anzahl Parameter? */
if(( Req->argc < 2) || ( Req->argc > 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if ((Req->argc < 2) || (Req->argc > 3))
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
else from = Client;
if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
/* Ziel-User suchen */
target = Client_Search( Req->argv[1] );
if( ! target ) return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( from ), Req->argv[1] );
while (*itemList) {
if (*itemList == ',') {
*itemList = '\0';
channelCount++;
}
itemList++;
}
Channel_Kick( target, from, Req->argv[0], Req->argc == 3 ? Req->argv[2] : Client_ID( from ));
return CONNECTED;
} /* IRC_KICK */
itemList = Req->argv[1];
while (*itemList) {
if (*itemList == ',') {
*itemList = '\0';
nickCount++;
}
itemList++;
}
if (Client_Type(Client) == CLIENT_SERVER)
from = Client_Search(Req->prefix);
else
from = Client;
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
reason = Req->argc == 3 ? Req->argv[2] : Client_ID(from);
currentNick = Req->argv[1];
currentChannel = Req->argv[0];
if (channelCount == 1) {
while (nickCount > 0) {
if (!try_kick(Client, from, currentNick,
currentChannel, reason))
return false;
while (*currentNick)
currentNick++;
currentNick++;
nickCount--;
}
} else if (channelCount == nickCount) {
while (nickCount > 0) {
if (!try_kick(Client, from, currentNick,
currentChannel, reason))
return false;
while (*currentNick)
currentNick++;
while (*currentChannel)
currentChannel++;
currentNick++;
currentChannel++;
nickCount--;
}
} else {
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
return true;
} /* IRC_KICK */
GLOBAL bool
IRC_INVITE( CLIENT *Client, REQUEST *Req )
IRC_INVITE(CLIENT *Client, REQUEST *Req)
{
CHANNEL *chan;
CLIENT *target, *from;
const char *colon_if_necessary;
bool remember = false;
assert( Client != NULL );
assert( Req != NULL );
/* Wrong number of parameters? */
if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if (Req->argc != 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (Client_Type(Client) == CLIENT_SERVER)
from = Client_Search(Req->prefix);
else
from = Client;
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
else from = Client;
if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
/* Search user */
target = Client_Search( Req->argv[0] );
if(( ! target ) || ( Client_Type( target ) != CLIENT_USER )) return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] );
target = Client_Search(Req->argv[0]);
if (!target || (Client_Type(target) != CLIENT_USER))
return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->argv[0]);
chan = Channel_Search( Req->argv[1] );
if( chan )
{
chan = Channel_Search(Req->argv[1]);
if (chan) {
/* Channel exists. Is the user a valid member of the channel? */
if( ! Channel_IsMemberOf( chan, from )) return IRC_WriteStrClient( from, ERR_NOTONCHANNEL_MSG, Client_ID( Client ), Req->argv[1] );
if (!Channel_IsMemberOf(chan, from))
return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG, Client_ID(Client), Req->argv[1]);
/* Is the channel "invite-only"? */
if( strchr( Channel_Modes( chan ), 'i' ))
{
if (strchr(Channel_Modes(chan), 'i')) {
/* Yes. The user must be channel operator! */
if( ! strchr( Channel_UserModes( chan, from ), 'o' )) return IRC_WriteStrClient( from, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( from ), Channel_Name( chan ));
if (!strchr(Channel_UserModes(chan, from), 'o'))
return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(from), Channel_Name(chan));
remember = true;
}
/* Is the target user already member of the channel? */
if( Channel_IsMemberOf( chan, target )) return IRC_WriteStrClient( from, ERR_USERONCHANNEL_MSG, Client_ID( from ), Req->argv[0], Req->argv[1] );
if (Channel_IsMemberOf(chan, target))
return IRC_WriteStrClient(from, ERR_USERONCHANNEL_MSG,
Client_ID(from), Req->argv[0], Req->argv[1]);
/* If the target user is banned on that channel: remember invite */
if( Lists_CheckBanned( target, chan )) remember = true;
if (Lists_Check(Channel_GetListBans(chan), target))
remember = true;
if( remember )
{
/* We must memember this invite */
if( ! Lists_AddInvited( Client_Mask( target ), chan, true)) return CONNECTED;
if (remember) {
/* We must remember this invite */
if (!Channel_AddInvite(chan, Client_Mask(target), true))
return CONNECTED;
}
}
Log( LOG_DEBUG, "User \"%s\" invites \"%s\" to \"%s\" ...", Client_Mask( from ), Req->argv[0], Req->argv[1] );
/* Inform target client */
IRC_WriteStrClientPrefix( target, from, "INVITE %s %s", Req->argv[0], Req->argv[1] );
LogDebug("User \"%s\" invites \"%s\" to \"%s\" ...", Client_Mask(from), Req->argv[0], Req->argv[1]);
if( Client_Conn( target ) > NONE )
{
/*
* RFC 2812 says:
* 'There is no requirement that the channel [..] must exist or be a valid channel'
* The problem with this is that this allows the "channel" to contain spaces,
* in which case we must prefix its name with a colon to make it clear that
* it is only a single argument.
*/
colon_if_necessary = strchr(Req->argv[1], ' ') ? ":":"";
/* Inform target client */
IRC_WriteStrClientPrefix(target, from, "INVITE %s %s%s", Req->argv[0],
colon_if_necessary, Req->argv[1]);
if (Client_Conn(target) > NONE) {
/* The target user is local, so we have to send the status code */
if( ! IRC_WriteStrClientPrefix( from, target, RPL_INVITING_MSG, Client_ID( from ), Req->argv[0], Req->argv[1] )) return DISCONNECTED;
if (!IRC_WriteStrClientPrefix(from, target, RPL_INVITING_MSG,
Client_ID(from), Req->argv[0], colon_if_necessary, Req->argv[1]))
return DISCONNECTED;
if (strchr(Client_Modes(target), 'a') &&
!IRC_WriteStrClient(from, RPL_AWAY_MSG, Client_ID(from),
Client_ID(target), Client_Away(target)))
return DISCONNECTED;
}
return CONNECTED;
} /* IRC_INVITE */

View File

@@ -14,7 +14,7 @@
#include "portab.h"
static char UNUSED id[] = "$Id: irc-oper.c,v 1.27 2006/07/23 15:43:18 alex Exp $";
static char UNUSED id[] = "$Id: irc-oper.c,v 1.29 2007/08/02 10:14:26 fw Exp $";
#include "imp.h"
#include <assert.h>
@@ -191,12 +191,12 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
Client_ID(Client));
/* Bad number of parameters? */
if ((Req->argc != 2) && (Req->argc != 5))
if ((Req->argc != 1) && (Req->argc != 2) && (Req->argc != 5))
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* Invalid port number? */
if (atoi(Req->argv[1]) < 1)
if ((Req->argc > 1) && atoi(Req->argv[1]) < 1)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
@@ -204,14 +204,22 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
"Got CONNECT command from \"%s\" for \"%s\".", Client_Mask(Client),
Req->argv[0]);
if (Req->argc == 2) {
switch (Req->argc) {
case 1:
if (!Conf_EnablePassiveServer(Req->argv[0]))
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client),
Req->argv[0]);
break;
case 2:
/* Connect configured server */
if (!Conf_EnableServer
(Req->argv[0], (UINT16) atoi(Req->argv[1])))
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client),
Req->argv[0]);
} else {
break;
default:
/* Add server */
if (!Conf_AddServer
(Req->argv[0], (UINT16) atoi(Req->argv[1]), Req->argv[2],
@@ -255,4 +263,54 @@ IRC_DISCONNECT(CLIENT *Client, REQUEST *Req )
} /* IRC_CONNECT */
GLOBAL bool
IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
{
CLIENT *to, *from;
int client_type;
assert( Client != NULL );
assert( Req != NULL );
if (Req->argc != 1)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
client_type = Client_Type(Client);
switch (client_type) {
case CLIENT_USER:
if (!Client_OperByMe(Client))
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG, Client_ID(Client));
from = Client;
break;
case CLIENT_SERVER:
from = Client_Search(Req->prefix);
break;
default:
return CONNECTED;
}
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix);
for (to=Client_First(); to != NULL; to=Client_Next(to)) {
if (Client_Conn(to) < 0) /* no local connection or WALLOPS origin */
continue;
client_type = Client_Type(to);
switch (client_type) {
case CLIENT_USER:
if (Client_HasMode(to, 'w'))
IRC_WriteStrClientPrefix(to, from, "WALLOPS :%s", Req->argv[0]);
break;
case CLIENT_SERVER:
if (to != Client)
IRC_WriteStrClientPrefix(to, from, "WALLOPS :%s", Req->argv[0]);
break;
}
}
return CONNECTED;
}
/* -eof- */

View File

@@ -8,7 +8,7 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: irc-oper.h,v 1.11 2005/03/19 18:43:48 fw Exp $
* $Id: irc-oper.h,v 1.12 2007/08/02 10:14:26 fw Exp $
*
* IRC operator commands (header)
*/
@@ -24,6 +24,7 @@ GLOBAL bool IRC_REHASH PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_RESTART PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_CONNECT PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_DISCONNECT PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_WALLOPS PARAMS(( CLIENT *Client, REQUEST *Req ));
#endif

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2006 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2007 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,8 +14,6 @@
#include "portab.h"
static char UNUSED id[] = "$Id: irc-server.c,v 1.39 2006/04/30 21:31:43 alex Exp $";
#include "imp.h"
#include <assert.h>
#include <stdio.h>
@@ -26,6 +24,7 @@ static char UNUSED id[] = "$Id: irc-server.c,v 1.39 2006/04/30 21:31:43 alex Exp
#include "defines.h"
#include "resolve.h"
#include "conn.h"
#include "conn-func.h"
#include "conn-zip.h"
#include "conf.h"
#include "client.h"
@@ -35,33 +34,41 @@ static char UNUSED id[] = "$Id: irc-server.c,v 1.39 2006/04/30 21:31:43 alex Exp
#include "log.h"
#include "messages.h"
#include "parse.h"
#include "numeric.h"
#include "ngircd.h"
#include "irc-info.h"
#include "exp.h"
#include "irc-server.h"
/**
* Handler for the IRC command "SERVER".
* See RFC 2813 section 4.1.2.
*/
GLOBAL bool
IRC_SERVER( CLIENT *Client, REQUEST *Req )
{
char str[LINE_LEN], *ptr, *modes, *topic;
CLIENT *from, *c, *cl;
CL2CHAN *cl2chan;
int max_hops, i;
CHANNEL *chan;
char str[LINE_LEN], *ptr;
CLIENT *from, *c;
bool ok;
int i;
CONN_ID con;
assert( Client != NULL );
assert( Req != NULL );
/* Fehler liefern, wenn kein lokaler Client */
if( Client_Conn( Client ) <= NONE ) return IRC_WriteStrClient( Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( Client ), Req->command );
/* Return an error if this is not a local client */
if (Client_Conn(Client) <= NONE)
return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG,
Client_ID(Client), Req->command);
if( Client_Type( Client ) == CLIENT_GOTPASSSERVER )
{
/* Verbindung soll als Server-Server-Verbindung registriert werden */
Log( LOG_DEBUG, "Connection %d: got SERVER command (new server link) ...", Client_Conn( Client ));
if (Client_Type(Client) == CLIENT_GOTPASS ||
Client_Type(Client) == CLIENT_GOTPASS_2813) {
/* We got a PASS command from the peer, and now a SERVER
* command: the peer tries to register itself as a server. */
LogDebug("Connection %d: got SERVER command (new server link) ...",
Client_Conn(Client));
/* Falsche Anzahl Parameter? */
if(( Req->argc != 2 ) && ( Req->argc != 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
@@ -115,10 +122,21 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
Client_SetToken( Client, atoi( Req->argv[1] ));
}
Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" registered (connection %d, 1 hop - direct link).", Client_ID( Client ), con );
/* Mark this connection as belonging to an configured server */
Conf_SetServer(i, con);
Client_SetType( Client, CLIENT_SERVER );
Conf_SetServer( i, con );
/* Check protocol level */
if (Client_Type(Client) == CLIENT_GOTPASS) {
/* We got a "simple" PASS command, so the peer is
* using the protocol as defined in RFC 1459. */
if (! (Conn_Options(con) & CONN_RFC1459))
Log(LOG_INFO,
"Switching connection %d (\"%s\") to RFC 1459 compatibility mode.",
con, Client_ID(Client));
Conn_SetOption(con, CONN_RFC1459);
}
Client_SetType(Client, CLIENT_UNKNOWNSERVER);
#ifdef ZLIB
/* Kompression initialisieren, wenn erforderlich */
@@ -133,136 +151,23 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
}
#endif
/* maximalen Hop Count ermitteln */
max_hops = 0;
c = Client_First( );
while( c )
{
if( Client_Hops( c ) > max_hops ) max_hops = Client_Hops( c );
c = Client_Next( c );
}
/* Alle bisherigen Server dem neuen Server bekannt machen,
* die bisherigen Server ueber den neuen informierenn */
for( i = 0; i < ( max_hops + 1 ); i++ )
{
c = Client_First( );
while( c )
{
if(( Client_Type( c ) == CLIENT_SERVER ) && ( c != Client ) && ( c != Client_ThisServer( )) && ( Client_Hops( c ) == i ))
{
if( Client_Conn( c ) > NONE )
{
/* Dem gefundenen Server gleich den neuen
* Server bekannt machen */
if( ! IRC_WriteStrClient( c, "SERVER %s %d %d :%s", Client_ID( Client ), Client_Hops( Client ) + 1, Client_MyToken( Client ), Client_Info( Client ))) return DISCONNECTED;
}
/* Den neuen Server ueber den alten informieren */
if( ! IRC_WriteStrClientPrefix( Client, Client_Hops( c ) == 1 ? Client_ThisServer( ) : Client_Introducer( c ), "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ))) return DISCONNECTED;
}
c = Client_Next( c );
}
}
/* alle User dem neuen Server bekannt machen */
c = Client_First( );
while( c )
{
if( Client_Type( c ) == CLIENT_USER )
{
/* User an neuen Server melden */
if( ! IRC_WriteStrClient( Client, "NICK %s %d %s %s %d +%s :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_User( c ), Client_Hostname( c ), Client_MyToken( Client_Introducer( c )), Client_Modes( c ), Client_Info( c ))) return DISCONNECTED;
}
c = Client_Next( c );
}
/* Channels dem neuen Server bekannt machen */
chan = Channel_First( );
while( chan )
{
#ifdef IRCPLUS
/* Send CHANINFO if the peer supports it */
if( strchr( Client_Flags( Client ), 'C' ))
{
#ifdef DEBUG
Log( LOG_DEBUG, "Sending CHANINFO commands ..." );
if (strchr(Client_Flags(Client), 'H')) {
LogDebug("Peer supports IRC+ extended server handshake ...");
if (!IRC_Send_ISUPPORT(Client))
return DISCONNECTED;
return IRC_WriteStrClient(Client, RPL_ENDOFMOTD_MSG,
Client_ID(Client));
} else {
#endif
modes = Channel_Modes( chan );
topic = Channel_Topic( chan );
if( *modes || *topic )
{
/* send CHANINFO */
if(( ! strchr( Channel_Modes( chan ), 'k' )) && ( ! strchr( Channel_Modes( chan ), 'l' )) && ( ! *topic ))
{
/* "CHANINFO <chan> +<modes>" */
if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s", Channel_Name( chan ), modes )) return DISCONNECTED;
}
else if(( ! strchr( Channel_Modes( chan ), 'k' )) && ( ! strchr( Channel_Modes( chan ), 'l' )))
{
/* "CHANINFO <chan> +<modes> :<topic>" */
if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s :%s", Channel_Name( chan ), modes, topic )) return DISCONNECTED;
}
else
{
/* "CHANINFO <chan> +<modes> <key> <limit> :<topic>" */
if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s %s %ld :%s", Channel_Name( chan ), modes, strchr( Channel_Modes( chan ), 'k' ) ? Channel_Key( chan ) : "*", strchr( Channel_Modes( chan ), 'l' ) ? Channel_MaxUsers( chan ) : 0L, topic )) return DISCONNECTED;
}
}
}
#endif
/* alle Member suchen */
cl2chan = Channel_FirstMember( chan );
snprintf( str, sizeof( str ), "NJOIN %s :", Channel_Name( chan ));
while( cl2chan )
{
cl = Channel_GetClient( cl2chan );
assert( cl != NULL );
/* Nick, ggf. mit Modes, anhaengen */
if( str[strlen( str ) - 1] != ':' ) strlcat( str, ",", sizeof( str ));
if( strchr( Channel_UserModes( chan, cl ), 'v' )) strlcat( str, "+", sizeof( str ));
if( strchr( Channel_UserModes( chan, cl ), 'o' )) strlcat( str, "@", sizeof( str ));
strlcat( str, Client_ID( cl ), sizeof( str ));
if( strlen( str ) > ( LINE_LEN - CLIENT_NICK_LEN - 8 ))
{
/* Zeile senden */
if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
snprintf( str, sizeof( str ), "NJOIN %s :", Channel_Name( chan ));
}
cl2chan = Channel_NextMember( chan, cl2chan );
}
/* noch Daten da? */
if( str[strlen( str ) - 1] != ':')
{
/* Ja; Also senden ... */
if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
}
/* Get next channel ... */
chan = Channel_Next(chan);
}
if (Conf_MaxNickLength != CLIENT_NICK_LEN_DEFAULT)
Log(LOG_CRIT,
"Attention: this server uses a non-standard nick length, but the peer doesn't support the IRC+ extended server handshake!");
#ifdef IRCPLUS
if (strchr(Client_Flags(Client), 'L')) {
#ifdef DEBUG
Log(LOG_DEBUG,
"Synchronizing INVITE- and BAN-lists ...");
#endif
/* Synchronize INVITE- and BAN-lists */
if (! Lists_SendInvites(Client))
return DISCONNECTED;
if (! Lists_SendBans(Client))
return DISCONNECTED;
}
#endif
return CONNECTED;
return IRC_Num_ENDOFMOTD(Client, Req);
}
else if( Client_Type( Client ) == CLIENT_SERVER )
{
@@ -306,8 +211,9 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
IRC_WriteStrServersPrefix( Client, from, "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ));
return CONNECTED;
}
else return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
} else
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
} /* IRC_SERVER */

View File

@@ -8,7 +8,7 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: irc-server.h,v 1.5 2005/03/19 18:43:49 fw Exp $
* $Id: irc-server.h,v 1.6 2007/11/21 12:16:36 alex Exp $
*
* IRC commands for server links (header)
*/
@@ -22,6 +22,8 @@ GLOBAL bool IRC_SERVER PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_NJOIN PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_SQUIT PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_ENDOFMOTD_Server PARAMS((CLIENT *Client));
#endif

View File

@@ -14,7 +14,7 @@
#include "portab.h"
static char UNUSED id[] = "$Id: irc-write.c,v 1.20 2006/05/10 21:24:01 alex Exp $";
static char UNUSED id[] = "$Id: irc-write.c,v 1.21 2006/08/12 11:56:24 fw Exp $";
#include "imp.h"
#include <assert.h>
@@ -39,7 +39,9 @@ static char UNUSED id[] = "$Id: irc-write.c,v 1.20 2006/05/10 21:24:01 alex Exp
#define SEND_TO_SERVER 2
static char *Get_Prefix PARAMS(( CLIENT *Target, CLIENT *Client ));
static char *Get_Prefix PARAMS((CLIENT *Target, CLIENT *Client));
static void cb_writeStrServersPrefixFlag PARAMS((CLIENT *Client,
CLIENT *Prefix, void *Buffer));
#ifdef PROTOTYPES
@@ -187,7 +189,7 @@ va_dcl
else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
}
if( c ) c = Client_NextHop( c );
if( c && ( c != Client ))
{
/* Ok, anderer Client */
@@ -272,7 +274,7 @@ va_dcl
IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, '\0', "%s", buffer );
} /* IRC_WriteStrServersPrefix */
#ifdef PROTOTYPES
GLOBAL void
@@ -288,9 +290,8 @@ va_dcl
#endif
{
char buffer[1000];
CLIENT *c;
va_list ap;
assert( Format != NULL );
assert( Prefix != NULL );
@@ -301,16 +302,27 @@ va_dcl
#endif
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
c = Client_First( );
while( c )
{
if(( Client_Type( c ) == CLIENT_SERVER ) && ( Client_Conn( c ) > NONE ) && ( c != Client_ThisServer( )) && ( c != ExceptOf ))
{
/* Ziel-Server gefunden. Nun noch pruefen, ob Flags stimmen */
if(( Flag == '\0' ) || ( strchr( Client_Flags( c ), Flag ) != NULL )) IRC_WriteStrClientPrefix( c, Prefix, "%s", buffer );
IRC_WriteStrServersPrefixFlag_CB(ExceptOf, Prefix, Flag,
cb_writeStrServersPrefixFlag, buffer);
} /* IRC_WriteStrServersPrefixFlag */
GLOBAL void
IRC_WriteStrServersPrefixFlag_CB(CLIENT *ExceptOf, CLIENT *Prefix, char Flag,
void (*callback)(CLIENT *, CLIENT *, void *), void *cb_data)
{
CLIENT *c;
c = Client_First();
while(c) {
if (Client_Type(c) == CLIENT_SERVER && Client_Conn(c) > NONE &&
c != Client_ThisServer() && c != ExceptOf) {
/* Found a target server, do the flags match? */
if (Flag == '\0' || strchr(Client_Flags(c), Flag))
callback(c, Prefix, cb_data);
}
c = Client_Next( c );
c = Client_Next(c);
}
} /* IRC_WriteStrServersPrefixFlag */
@@ -378,7 +390,7 @@ va_dcl
}
cl2chan = Channel_NextMember( chan, cl2chan );
}
/* naechsten Channel */
chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan );
}
@@ -403,12 +415,12 @@ GLOBAL void
IRC_SetPenalty( CLIENT *Client, time_t Seconds )
{
CONN_ID c;
assert( Client != NULL );
assert( Seconds > 0 );
if( Client_Type( Client ) == CLIENT_SERVER ) return;
c = Client_Conn( Client );
if (c > NONE)
Conn_SetPenalty(c, Seconds);
@@ -426,4 +438,11 @@ Get_Prefix( CLIENT *Target, CLIENT *Client )
} /* Get_Prefix */
static void
cb_writeStrServersPrefixFlag(CLIENT *Client, CLIENT *Prefix, void *Buffer)
{
IRC_WriteStrClientPrefix(Client, Prefix, "%s", Buffer);
} /* cb_writeStrServersPrefixFlag */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -8,32 +8,35 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: irc-write.h,v 1.8 2006/05/10 21:24:01 alex Exp $
*
* Sending IRC commands over the network (header)
*/
#ifndef __irc_write_h__
#define __irc_write_h__
GLOBAL bool IRC_WriteStrClient PARAMS((CLIENT *Client, char *Format, ...));
GLOBAL bool IRC_WriteStrClientPrefix PARAMS((CLIENT *Client, CLIENT *Prefix,
char *Format, ...));
GLOBAL bool IRC_WriteStrClient PARAMS(( CLIENT *Client, char *Format, ... ));
GLOBAL bool IRC_WriteStrClientPrefix PARAMS(( CLIENT *Client, CLIENT *Prefix, char *Format, ... ));
GLOBAL bool IRC_WriteStrChannel PARAMS((CLIENT *Client, CHANNEL *Chan,
bool Remote, char *Format, ...));
GLOBAL bool IRC_WriteStrChannelPrefix PARAMS((CLIENT *Client, CHANNEL *Chan,
CLIENT *Prefix, bool Remote, char *Format, ...));
GLOBAL bool IRC_WriteStrChannel PARAMS(( CLIENT *Client, CHANNEL *Chan, bool Remote, char *Format, ... ));
GLOBAL bool IRC_WriteStrChannelPrefix PARAMS(( CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, bool Remote, char *Format, ... ));
GLOBAL void IRC_WriteStrServers PARAMS((CLIENT *ExceptOf, char *Format, ...));
GLOBAL void IRC_WriteStrServersPrefix PARAMS((CLIENT *ExceptOf, CLIENT *Prefix,
char *Format, ...));
GLOBAL void IRC_WriteStrServersPrefixFlag PARAMS((CLIENT *ExceptOf,
CLIENT *Prefix, char Flag, char *Format, ...));
GLOBAL void IRC_WriteStrServersPrefixFlag_CB PARAMS((CLIENT *ExceptOf,
CLIENT *Prefix, char Flag,
void (*callback)(CLIENT *, CLIENT *, void *), void *cb_data));
GLOBAL void IRC_WriteStrServers PARAMS(( CLIENT *ExceptOf, char *Format, ... ));
GLOBAL void IRC_WriteStrServersPrefix PARAMS(( CLIENT *ExceptOf, CLIENT *Prefix, char *Format, ... ));
GLOBAL void IRC_WriteStrServersPrefixFlag PARAMS(( CLIENT *ExceptOf, CLIENT *Prefix, char Flag, char *Format, ... ));
GLOBAL bool IRC_WriteStrRelatedPrefix PARAMS(( CLIENT *Client, CLIENT *Prefix, bool Remote, char *Format, ... ));
GLOBAL void IRC_SetPenalty PARAMS(( CLIENT *Client, time_t Seconds ));
GLOBAL bool IRC_WriteStrRelatedPrefix PARAMS((CLIENT *Client, CLIENT *Prefix,
bool Remote, char *Format, ...));
GLOBAL void IRC_SetPenalty PARAMS((CLIENT *Client, time_t Seconds));
#endif
/* -eof- */

View File

@@ -14,7 +14,7 @@
#include "portab.h"
static char UNUSED id[] = "$Id: irc.c,v 1.131 2006/07/23 14:55:40 alex Exp $";
static char UNUSED id[] = "$Id: irc.c,v 1.132 2008/01/15 22:28:14 fw Exp $";
#include "imp.h"
#include <assert.h>
@@ -30,14 +30,21 @@ static char UNUSED id[] = "$Id: irc.c,v 1.131 2006/07/23 14:55:40 alex Exp $";
#include "defines.h"
#include "irc-write.h"
#include "log.h"
#include "match.h"
#include "messages.h"
#include "parse.h"
#include "tool.h"
#include "exp.h"
#include "irc.h"
static char *Option_String PARAMS(( CONN_ID Idx ));
static char *Option_String PARAMS((CONN_ID Idx));
static bool Send_Message PARAMS((CLIENT *Client, REQUEST *Req, int ForceType,
bool SendErrors));
static bool Send_Message_Mask PARAMS((CLIENT *from, char *command,
char *targetMask, char *message,
bool SendErrors));
GLOBAL bool
@@ -166,76 +173,36 @@ IRC_KILL( CLIENT *Client, REQUEST *Req )
} /* IRC_KILL */
/**
* Handler for the IRC command NOTICE.
*/
GLOBAL bool
IRC_NOTICE( CLIENT *Client, REQUEST *Req )
IRC_NOTICE(CLIENT *Client, REQUEST *Req)
{
CLIENT *to, *from;
assert( Client != NULL );
assert( Req != NULL );
if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return CONNECTED;
/* Falsche Anzahl Parameter? */
if( Req->argc != 2 ) return CONNECTED;
if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
else from = Client;
if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
to = Client_Search( Req->argv[0] );
if(( to ) && ( Client_Type( to ) == CLIENT_USER ))
{
/* Okay, Ziel ist ein User */
return IRC_WriteStrClientPrefix( to, from, "NOTICE %s :%s", Client_ID( to ), Req->argv[1] );
}
else return CONNECTED;
return Send_Message(Client, Req, CLIENT_USER, false);
} /* IRC_NOTICE */
/**
* Handler for the IRC command PRIVMSG.
*/
GLOBAL bool
IRC_PRIVMSG( CLIENT *Client, REQUEST *Req )
IRC_PRIVMSG(CLIENT *Client, REQUEST *Req)
{
CLIENT *cl, *from;
CHANNEL *chan;
assert( Client != NULL );
assert( Req != NULL );
/* Falsche Anzahl Parameter? */
if( Req->argc == 0 ) return IRC_WriteStrClient( Client, ERR_NORECIPIENT_MSG, Client_ID( Client ), Req->command );
if( Req->argc == 1 ) return IRC_WriteStrClient( Client, ERR_NOTEXTTOSEND_MSG, Client_ID( Client ));
if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
else from = Client;
if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
cl = Client_Search( Req->argv[0] );
if( cl )
{
/* Okay, Ziel ist ein Client. Aber ist es auch ein User? */
if( Client_Type( cl ) != CLIENT_USER ) return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( from ), Req->argv[0] );
/* Okay, Ziel ist ein User */
if(( Client_Type( Client ) != CLIENT_SERVER ) && ( strchr( Client_Modes( cl ), 'a' )))
{
/* Ziel-User ist AWAY: Meldung verschicken */
if( ! IRC_WriteStrClient( from, RPL_AWAY_MSG, Client_ID( from ), Client_ID( cl ), Client_Away( cl ))) return DISCONNECTED;
}
/* Text senden */
if( Client_Conn( from ) > NONE ) Conn_UpdateIdle( Client_Conn( from ));
return IRC_WriteStrClientPrefix( cl, from, "PRIVMSG %s :%s", Client_ID( cl ), Req->argv[1] );
}
chan = Channel_Search( Req->argv[0] );
if( chan ) return Channel_Write( chan, from, Client, Req->argv[1] );
return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( from ), Req->argv[0] );
return Send_Message(Client, Req, CLIENT_USER, true);
} /* IRC_PRIVMSG */
/**
* Handler for the IRC command SQUERY.
*/
GLOBAL bool
IRC_SQUERY(CLIENT *Client, REQUEST *Req)
{
return Send_Message(Client, Req, CLIENT_SERVICE, true);
} /* IRC_SQUERY */
GLOBAL bool
IRC_TRACE( CLIENT *Client, REQUEST *Req )
{
@@ -343,4 +310,231 @@ Option_String( CONN_ID Idx )
} /* Option_String */
static bool
Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
{
CLIENT *cl, *from;
CHANNEL *chan;
char *currentTarget = Req->argv[0];
char *lastCurrentTarget = NULL;
assert(Client != NULL);
assert(Req != NULL);
if (Req->argc == 0) {
if (!SendErrors)
return CONNECTED;
return IRC_WriteStrClient(Client, ERR_NORECIPIENT_MSG,
Client_ID(Client), Req->command);
}
if (Req->argc == 1) {
if (!SendErrors)
return CONNECTED;
return IRC_WriteStrClient(Client, ERR_NOTEXTTOSEND_MSG,
Client_ID(Client));
}
if (Req->argc > 2) {
if (!SendErrors)
return CONNECTED;
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
if (Client_Type(Client) == CLIENT_SERVER)
from = Client_Search(Req->prefix);
else
from = Client;
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
/* handle msgtarget = msgto *("," msgto) */
currentTarget = strtok_r(currentTarget, ",", &lastCurrentTarget);
ngt_UpperStr(Req->command);
while (currentTarget) {
/* Check for and handle valid <msgto> of form:
* RFC 2812 2.3.1:
* msgto = channel / ( user [ "%" host ] "@" servername )
* msgto =/ ( user "%" host ) / targetmask
* msgto =/ nickname / ( nickname "!" user "@" host )
*/
if (strchr(currentTarget, '!') == NULL)
/* nickname */
cl = Client_Search(currentTarget);
else
cl = NULL;
if (cl == NULL) {
/* If currentTarget isn't a nickname check for:
* user ["%" host] "@" servername
* user "%" host
* nickname "!" user "@" host
*/
char target[COMMAND_LEN];
char * nick = NULL;
char * user = NULL;
char * host = NULL;
char * server = NULL;
strlcpy(target, currentTarget, COMMAND_LEN);
server = strchr(target, '@');
if (server) {
*server = '\0';
server++;
}
host = strchr(target, '%');
if (host) {
*host = '\0';
host++;
}
user = strchr(target, '!');
if (user) {
/* msgto form: nick!user@host */
*user = '\0';
user++;
nick = target;
host = server; /* not "@server" but "@host" */
} else {
user = target;
}
for (cl = Client_First(); cl != NULL; cl = Client_Next(cl)) {
if (Client_Type(cl) != CLIENT_USER &&
Client_Type(cl) != CLIENT_SERVICE)
continue;
if (nick != NULL && host != NULL) {
if (strcmp(nick, Client_ID(cl)) == 0 &&
strcmp(user, Client_User(cl)) == 0 &&
strcasecmp(host, Client_Hostname(cl)) == 0)
break;
else
continue;
}
if (strcasecmp(user, Client_User(cl)) != 0)
continue;
if (host != NULL && strcasecmp(host,
Client_Hostname(cl)) != 0)
continue;
if (server != NULL && strcasecmp(server,
Client_ID(Client_Introducer(cl))) != 0)
continue;
break;
}
}
if (cl) {
/* Target is a user, enforce type */
#ifndef STRICT_RFC
if (Client_Type(cl) != ForceType &&
!(ForceType == CLIENT_USER &&
(Client_Type(cl) == CLIENT_USER ||
Client_Type(cl) == CLIENT_SERVICE))) {
#else
if (Client_Type(cl) != ForceType) {
#endif
if (!SendErrors)
return CONNECTED;
return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
Client_ID(from),
currentTarget);
}
#ifndef STRICT_RFC
if (ForceType == CLIENT_SERVICE &&
(Conn_Options(Client_Conn(Client_NextHop(cl)))
& CONN_RFC1459)) {
/* SQUERY command but RFC 1459 link: convert
* request to PRIVMSG command */
Req->command = "PRIVMSG";
}
#endif
if (SendErrors && (Client_Type(Client) != CLIENT_SERVER)
&& strchr(Client_Modes(cl), 'a')) {
/* Target is away */
if (!IRC_WriteStrClient(from, RPL_AWAY_MSG,
Client_ID(from),
Client_ID(cl),
Client_Away(cl)))
return DISCONNECTED;
}
if (Client_Conn(from) > NONE) {
Conn_UpdateIdle(Client_Conn(from));
}
if (!IRC_WriteStrClientPrefix(cl, from, "%s %s :%s",
Req->command, Client_ID(cl),
Req->argv[1]))
return DISCONNECTED;
} else if (ForceType != CLIENT_SERVICE
&& strchr("$#", currentTarget[0])
&& strchr(currentTarget, '.')) {
/* targetmask */
if (!Send_Message_Mask(from, Req->command, currentTarget,
Req->argv[1], SendErrors))
return DISCONNECTED;
} else if (ForceType != CLIENT_SERVICE
&& (chan = Channel_Search(currentTarget))) {
/* channel */
if (!Channel_Write(chan, from, Client, Req->command,
SendErrors, Req->argv[1]))
return DISCONNECTED;
} else {
if (!SendErrors)
return CONNECTED;
if (!IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
Client_ID(from), currentTarget))
return DISCONNECTED;
}
currentTarget = strtok_r(NULL, ",", &lastCurrentTarget);
}
return CONNECTED;
} /* Send_Message */
static bool
Send_Message_Mask(CLIENT * from, char * command, char * targetMask,
char * message, bool SendErrors)
{
CLIENT *cl;
bool client_match;
char *mask = targetMask + 1;
cl = NULL;
if (strchr(Client_Modes(from), 'o') == NULL) {
if (!SendErrors)
return true;
return IRC_WriteStrClient(from, ERR_NOPRIVILEGES_MSG,
Client_ID(from));
}
if (targetMask[0] == '#') {
for (cl = Client_First(); cl != NULL; cl = Client_Next(cl)) {
if (Client_Type(cl) != CLIENT_USER)
continue;
client_match = MatchCaseInsensitive(mask, Client_Hostname(cl));
if (client_match)
if (!IRC_WriteStrClientPrefix(cl, from, "%s %s :%s",
command, Client_ID(cl), message))
return false;
}
} else {
for (cl = Client_First(); cl != NULL; cl = Client_Next(cl)) {
if (Client_Type(cl) != CLIENT_USER)
continue;
client_match = MatchCaseInsensitive(mask,
Client_ID(Client_Introducer(cl)));
if (client_match)
if (!IRC_WriteStrClientPrefix(cl, from, "%s %s :%s",
command, Client_ID(cl), message))
return false;
}
}
return CONNECTED;
} /* Send_Message_Mask */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -8,25 +8,20 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: irc.h,v 1.39 2005/03/19 18:43:49 fw Exp $
*
* IRC commands (header)
*/
#ifndef __irc_h__
#define __irc_h__
GLOBAL bool IRC_ERROR PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_KILL PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_NOTICE PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_PRIVMSG PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_TRACE PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_HELP PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_ERROR PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_KILL PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_NOTICE PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_PRIVMSG PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_SQUERY PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_TRACE PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_HELP PARAMS((CLIENT *Client, REQUEST *Req));
#endif
/* -eof- */

View File

@@ -14,8 +14,6 @@
#include "portab.h"
static char UNUSED id[] = "$Id: lists.c,v 1.18 2005/07/31 20:13:08 alex Exp $";
#include "imp.h"
#include <assert.h>
@@ -35,330 +33,135 @@ static char UNUSED id[] = "$Id: lists.c,v 1.18 2005/07/31 20:13:08 alex Exp $";
#include "exp.h"
#include "lists.h"
#define MASK_LEN (2*CLIENT_HOST_LEN)
#define MASK_LEN 2*CLIENT_HOST_LEN
typedef struct _C2C
{
struct _C2C *next;
struct list_elem {
struct list_elem *next;
char mask[MASK_LEN];
CHANNEL *channel;
bool onlyonce;
} C2C;
};
static C2C *My_Invites, *My_Bans;
static C2C *New_C2C PARAMS(( char *Mask, CHANNEL *Chan, bool OnlyOnce ));
static bool Check_List PARAMS(( C2C **Cl2Chan, CLIENT *Client, CHANNEL *Chan ));
static bool Already_Registered PARAMS(( C2C *Cl2Chan, char *Mask, CHANNEL *Chan ));
GLOBAL void
Lists_Init( void )
GLOBAL const char *
Lists_GetMask(const struct list_elem *e)
{
/* Modul initialisieren */
My_Invites = My_Bans = NULL;
} /* Lists_Init */
return e->mask;
}
GLOBAL void
Lists_Exit( void )
GLOBAL struct list_elem*
Lists_GetFirst(const struct list_head *h)
{
/* Modul abmelden */
C2C *c2c, *next;
/* Invite-Lists freigeben */
c2c = My_Invites;
while( c2c )
{
next = c2c->next;
free( c2c );
c2c = next;
}
/* Ban-Lists freigeben */
c2c = My_Bans;
while( c2c )
{
next = c2c->next;
free( c2c );
c2c = next;
}
} /* Lists_Exit */
return h->first;
}
GLOBAL bool
Lists_CheckInvited( CLIENT *Client, CHANNEL *Chan )
GLOBAL struct list_elem*
Lists_GetNext(const struct list_elem *e)
{
return Check_List( &My_Invites, Client, Chan );
} /* Lists_CheckInvited */
return e->next;
}
GLOBAL bool
Lists_IsInviteEntry( char *Mask, CHANNEL *Chan )
bool
Lists_Add(struct list_head *header, const char *Mask, bool OnlyOnce )
{
struct list_elem *e, *newelem;
assert( header != NULL );
assert( Mask != NULL );
assert( Chan != NULL );
return Already_Registered( My_Invites, Mask, Chan );
} /* Lists_IsInviteEntry */
if (Lists_CheckDupeMask(header, Mask )) return true;
GLOBAL bool
Lists_AddInvited( char *Mask, CHANNEL *Chan, bool OnlyOnce )
{
C2C *c2c;
e = Lists_GetFirst(header);
assert( Mask != NULL );
assert( Chan != NULL );
if( Already_Registered( My_Invites, Mask, Chan )) return true;
c2c = New_C2C( Mask, Chan, OnlyOnce );
if( ! c2c )
{
Log( LOG_ERR, "Can't add new invite list entry!" );
newelem = malloc(sizeof(struct list_elem));
if( ! newelem ) {
Log( LOG_EMERG, "Can't allocate memory for new Ban/Invite entry!" );
return false;
}
/* verketten */
c2c->next = My_Invites;
My_Invites = c2c;
strlcpy( newelem->mask, Mask, sizeof( newelem->mask ));
newelem->onlyonce = OnlyOnce;
newelem->next = e;
header->first = newelem;
Log( LOG_DEBUG, "Added \"%s\" to invite list for \"%s\".", Mask, Channel_Name( Chan ));
LogDebug("Added \"%s\" to invite list", Mask);
return true;
} /* Lists_AddInvited */
}
static void
Lists_Unlink(struct list_head *header, struct list_elem *p, struct list_elem *victim)
{
assert(victim != NULL);
assert(header != NULL);
if (p) p->next = victim->next;
else header->first = victim->next;
free(victim);
}
GLOBAL void
Lists_DelInvited( char *Mask, CHANNEL *Chan )
Lists_Del(struct list_head *header, const char *Mask)
{
C2C *c2c, *last, *next;
struct list_elem *e, *last, *victim;
assert( header != NULL );
assert( Mask != NULL );
assert( Chan != NULL );
last = NULL;
c2c = My_Invites;
while( c2c )
{
next = c2c->next;
if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 ))
{
/* dieser Eintrag muss geloescht werden */
Log( LOG_DEBUG, "Deleted \"%s\" from invite list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
if( last ) last->next = next;
else My_Invites = next;
free( c2c );
e = Lists_GetFirst(header);
while( e ) {
if(strcasecmp( e->mask, Mask ) == 0 ) {
LogDebug("Deleted \"%s\" from list", e->mask);
victim = e;
e = victim->next;
Lists_Unlink(header, last, victim);
continue;
}
else last = c2c;
c2c = next;
last = e;
e = e->next;
}
} /* Lists_DelInvited */
GLOBAL bool
Lists_ShowInvites( CLIENT *Client, CHANNEL *Channel )
{
C2C *c2c;
assert( Client != NULL );
assert( Channel != NULL );
c2c = My_Invites;
while( c2c )
{
if( c2c->channel == Channel )
{
/* Eintrag fuer Channel gefunden; ausgeben: */
if( ! IRC_WriteStrClient( Client, RPL_INVITELIST_MSG, Client_ID( Client ), Channel_Name( Channel ), c2c->mask )) return DISCONNECTED;
}
c2c = c2c->next;
}
return IRC_WriteStrClient( Client, RPL_ENDOFINVITELIST_MSG, Client_ID( Client ), Channel_Name( Channel ));
} /* Lists_ShowInvites */
GLOBAL bool
Lists_SendInvites( CLIENT *Client )
{
C2C *c2c;
assert( Client != NULL );
c2c = My_Invites;
while( c2c )
{
if( ! IRC_WriteStrClient( Client, "MODE %s +I %s", Channel_Name( c2c->channel ), c2c->mask )) return DISCONNECTED;
c2c = c2c->next;
}
return CONNECTED;
} /* Lists_SendInvites */
GLOBAL bool
Lists_SendBans( CLIENT *Client )
{
C2C *c2c;
assert( Client != NULL );
c2c = My_Bans;
while( c2c )
{
if( ! IRC_WriteStrClient( Client, "MODE %s +b %s", Channel_Name( c2c->channel ), c2c->mask )) return DISCONNECTED;
c2c = c2c->next;
}
return CONNECTED;
} /* Lists_SendBans */
GLOBAL bool
Lists_CheckBanned( CLIENT *Client, CHANNEL *Chan )
{
return Check_List( &My_Bans, Client, Chan );
} /* Lists_CheckBanned */
GLOBAL bool
Lists_IsBanEntry( char *Mask, CHANNEL *Chan )
{
assert( Mask != NULL );
assert( Chan != NULL );
return Already_Registered( My_Bans, Mask, Chan );
} /* Lists_IsBanEntry */
GLOBAL bool
Lists_AddBanned( char *Mask, CHANNEL *Chan )
{
C2C *c2c;
assert( Mask != NULL );
assert( Chan != NULL );
if( Already_Registered( My_Bans, Mask, Chan )) return true;
c2c = New_C2C( Mask, Chan, false );
if( ! c2c )
{
Log( LOG_ERR, "Can't add new ban list entry!" );
return false;
}
/* verketten */
c2c->next = My_Bans;
My_Bans = c2c;
Log( LOG_DEBUG, "Added \"%s\" to ban list for \"%s\".", Mask, Channel_Name( Chan ));
return true;
} /* Lists_AddBanned */
}
GLOBAL void
Lists_DelBanned( char *Mask, CHANNEL *Chan )
Lists_Free(struct list_head *head)
{
C2C *c2c, *last, *next;
struct list_elem *e, *victim;
assert( Mask != NULL );
assert( Chan != NULL );
assert(head != NULL);
last = NULL;
c2c = My_Bans;
while( c2c )
{
next = c2c->next;
if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 ))
{
/* dieser Eintrag muss geloescht werden */
Log( LOG_DEBUG, "Deleted \"%s\" from ban list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
if( last ) last->next = next;
else My_Bans = next;
free( c2c );
}
else last = c2c;
c2c = next;
e = head->first;
head->first = NULL;
while (e) {
LogDebug("Deleted \"%s\" from invite list" , e->mask);
victim = e;
e = e->next;
free( victim );
}
} /* Lists_DelBanned */
}
GLOBAL bool
Lists_ShowBans( CLIENT *Client, CHANNEL *Channel )
Lists_CheckDupeMask(const struct list_head *h, const char *Mask )
{
C2C *c2c;
assert( Client != NULL );
assert( Channel != NULL );
c2c = My_Bans;
while( c2c )
{
if( c2c->channel == Channel )
{
/* Eintrag fuer Channel gefunden; ausgeben: */
if( ! IRC_WriteStrClient( Client, RPL_BANLIST_MSG, Client_ID( Client ), Channel_Name( Channel ), c2c->mask )) return DISCONNECTED;
}
c2c = c2c->next;
struct list_elem *e;
e = h->first;
while (e) {
if (strcasecmp( e->mask, Mask ) == 0 )
return true;
e = e->next;
}
return IRC_WriteStrClient( Client, RPL_ENDOFBANLIST_MSG, Client_ID( Client ), Channel_Name( Channel ));
} /* Lists_ShowBans */
return false;
}
GLOBAL void
Lists_DeleteChannel( CHANNEL *Chan )
{
/* Channel wurde geloescht, Invite- und Ban-Lists aufraeumen */
C2C *c2c, *last, *next;
/* Invite-List */
last = NULL;
c2c = My_Invites;
while( c2c )
{
next = c2c->next;
if( c2c->channel == Chan )
{
/* dieser Eintrag muss geloescht werden */
Log( LOG_DEBUG, "Deleted \"%s\" from invite list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
if( last ) last->next = next;
else My_Invites = next;
free( c2c );
}
else last = c2c;
c2c = next;
}
/* Ban-List */
last = NULL;
c2c = My_Bans;
while( c2c )
{
next = c2c->next;
if( c2c->channel == Chan )
{
/* dieser Eintrag muss geloescht werden */
Log( LOG_DEBUG, "Deleted \"%s\" from ban list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
if( last ) last->next = next;
else My_Bans = next;
free( c2c );
}
else last = c2c;
c2c = next;
}
} /* Lists_DeleteChannel */
GLOBAL char *
Lists_MakeMask( char *Pattern )
GLOBAL const char *
Lists_MakeMask(const char *Pattern)
{
/* This function generats a valid IRC mask of "any" string. This
* mask is only valid until the next call to Lists_MakeMask(),
@@ -407,82 +210,30 @@ Lists_MakeMask( char *Pattern )
} /* Lists_MakeMask */
static C2C *
New_C2C( char *Mask, CHANNEL *Chan, bool OnlyOnce )
bool
Lists_Check( struct list_head *header, CLIENT *Client)
{
C2C *c2c;
assert( Mask != NULL );
assert( Chan != NULL );
struct list_elem *e, *last;
/* Speicher fuer Eintrag anfordern */
c2c = (C2C *)malloc( sizeof( C2C ));
if( ! c2c )
{
Log( LOG_EMERG, "Can't allocate memory! [New_C2C]" );
return NULL;
}
assert( header != NULL );
strlcpy( c2c->mask, Mask, sizeof( c2c->mask ));
c2c->channel = Chan;
c2c->onlyonce = OnlyOnce;
return c2c;
} /* New_C2C */
static bool
Check_List( C2C **Cl2Chan, CLIENT *Client, CHANNEL *Chan )
{
C2C *c2c, *last;
assert( Cl2Chan != NULL );
assert( Client != NULL );
assert( Chan != NULL );
c2c = *Cl2Chan;
e = header->first;
last = NULL;
while( c2c )
{
if( c2c->channel == Chan )
{
/* Ok, richtiger Channel. Passt die Maske? */
if( Match( c2c->mask, Client_Mask( Client )))
{
/* Treffer! */
if( c2c->onlyonce )
{
/* Eintrag loeschen */
Log( LOG_DEBUG, "Deleted \"%s\" from %s list for \"%s\".", c2c->mask, *Cl2Chan == My_Invites ? "invite" : "ban", Channel_Name( Chan ));
if( last ) last->next = c2c->next;
else *Cl2Chan = c2c->next;
free( c2c );
}
return true;
while( e ) {
if( Match( e->mask, Client_Mask( Client ))) {
if( e->onlyonce ) { /* delete entry */
LogDebug("Deleted \"%s\" from list", e->mask);
Lists_Unlink(header, last, e);
}
return true;
}
last = c2c;
c2c = c2c->next;
last = e;
e = e->next;
}
return false;
} /* Check_List */
static bool
Already_Registered( C2C *List, char *Mask, CHANNEL *Chan )
{
C2C *c2c;
c2c = List;
while( c2c )
{
if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 )) return true;
c2c = c2c->next;
}
return false;
} /* Already_Registered */
}
/* -eof- */

View File

@@ -8,39 +8,37 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: lists.h,v 1.12 2005/03/19 18:43:49 fw Exp $
*
* Management of IRC lists: ban, invite, ... (header)
*/
#ifndef __lists_h__
#define __lists_h__
#include "portab.h"
#include "client.h"
struct list_elem;
struct list_head {
struct list_elem *first;
};
GLOBAL void Lists_Init PARAMS(( void ));
GLOBAL void Lists_Exit PARAMS(( void ));
GLOBAL struct list_elem *Lists_GetFirst PARAMS((const struct list_head *));
GLOBAL struct list_elem *Lists_GetNext PARAMS((const struct list_elem *));
GLOBAL bool Lists_CheckInvited PARAMS(( CLIENT *Client, CHANNEL *Chan ));
GLOBAL bool Lists_AddInvited PARAMS(( char *Mask, CHANNEL *Chan, bool OnlyOnce ));
GLOBAL void Lists_DelInvited PARAMS(( char *Mask, CHANNEL *Chan ));
GLOBAL bool Lists_ShowInvites PARAMS(( CLIENT *Client, CHANNEL *Channel ));
GLOBAL bool Lists_SendInvites PARAMS(( CLIENT *Client ));
GLOBAL bool Lists_IsInviteEntry PARAMS(( char *Mask, CHANNEL *Chan ));
GLOBAL bool Lists_Check PARAMS((struct list_head *head, CLIENT *client ));
GLOBAL bool Lists_CheckDupeMask PARAMS((const struct list_head *head, const char *mask ));
GLOBAL bool Lists_CheckBanned PARAMS(( CLIENT *Client, CHANNEL *Chan ));
GLOBAL bool Lists_AddBanned PARAMS(( char *Mask, CHANNEL *Chan ));
GLOBAL void Lists_DelBanned PARAMS(( char *Mask, CHANNEL *Chan ));
GLOBAL bool Lists_ShowBans PARAMS(( CLIENT *Client, CHANNEL *Channel ));
GLOBAL bool Lists_SendBans PARAMS(( CLIENT *Client ));
GLOBAL bool Lists_IsBanEntry PARAMS(( char *Mask, CHANNEL *Chan ));
GLOBAL bool Lists_Add PARAMS((struct list_head *header, const char *Mask, bool OnlyOnce ));
GLOBAL void Lists_Del PARAMS((struct list_head *head, const char *Mask ));
GLOBAL void Lists_DeleteChannel PARAMS(( CHANNEL *Chan ));
GLOBAL bool Lists_AlreadyRegistered PARAMS(( const struct list_head *head, const char *Mask));
GLOBAL char *Lists_MakeMask PARAMS(( char *Pattern ));
GLOBAL void Lists_Free PARAMS(( struct list_head *head ));
GLOBAL const char *Lists_MakeMask PARAMS((const char *Pattern));
GLOBAL const char *Lists_GetMask PARAMS(( const struct list_elem *e ));
#endif
/* -eof- */

View File

@@ -14,7 +14,7 @@
#include "portab.h"
static char UNUSED id[] = "$Id: log.c,v 1.61 2006/07/23 23:23:45 alex Exp $";
static char UNUSED id[] = "$Id: log.c,v 1.62 2006/08/05 09:16:21 fw Exp $";
#include "imp.h"
#include <assert.h>
@@ -61,7 +61,7 @@ Log_Init( bool Daemon_Mode )
Is_Daemon = Daemon_Mode;
#ifdef SYSLOG
#ifndef LOG_CONS /* Kludge: mips-dec-ultrix4.5 has no LOG_CONS/LOG_LOCAL5 */
#ifndef LOG_CONS /* Kludge: mips-dec-ultrix4.5 has no LOG_CONS/LOG_LOCAL5 */
#define LOG_CONS 0
#endif
#ifndef LOG_LOCAL5
@@ -166,25 +166,21 @@ Log_Exit( void )
* Log function for debug messages.
* This function is only functional when the program is compiled with debug
* code enabled; otherwise it is an empty function which the compiler will
* hopefully mangle down to "nothing". Therefore you should use LogDebug(...)
* in favor to Log(LOG_DEBUG, ...).
* hopefully mangle down to "nothing" (see log.h). Therefore you should use
* LogDebug(...) in favor to Log(LOG_DEBUG, ...).
* @param Format Format string like printf().
* @param ... Further arguments.
*/
#ifdef DEBUG
# ifdef PROTOTYPES
GLOBAL void
#ifdef DEBUG
LogDebug( const char *Format, ... )
#else
LogDebug( UNUSED const char *Format, ... )
#endif /* DEBUG */
# else
GLOBAL void
LogDebug( Format, va_alist )
const char *Format;
va_dcl
# endif /* PROTOTYPES */
#ifdef DEBUG
{
char msg[MAX_LOG_MSG_LEN];
va_list ap;
@@ -199,18 +195,15 @@ va_dcl
va_end( ap );
Log(LOG_DEBUG, "%s", msg);
}
#else
{
/* Do nothing.
* The compiler should optimize this out, please ;-) */
}
#endif /* DEBUG */
/**
* Logging function of ngIRCd.
* This function logs messages to the console and/or syslog, whichever is
* suitable for the mode ngIRCd is running in (daemon vs. non-daemon).
* If LOG_snotice is set, the log messages goes to all user with the mode +s
* set and the local &SERVER channel, too.
* Please note: you sould use LogDebug(...) for debug messages!
* @param Level syslog level (LOG_xxx)
* @param Format Format string like printf().
@@ -227,7 +220,6 @@ const char *Format;
va_dcl
#endif
{
/* Eintrag in Logfile(s) schreiben */
char msg[MAX_LOG_MSG_LEN];
bool snotice;
va_list ap;
@@ -248,7 +240,6 @@ va_dcl
if( Level == LOG_DEBUG ) return;
#endif
/* String mit variablen Argumenten zusammenbauen ... */
#ifdef PROTOTYPES
va_start( ap, Format );
#else
@@ -257,11 +248,11 @@ va_dcl
vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
va_end( ap );
if( ! Is_Daemon )
{
/* auf Konsole ausgeben */
fprintf( stdout, "[%d:%d] %s\n", (int)getpid( ), Level, msg );
fflush( stdout );
if (!Is_Daemon) {
/* log to console */
fprintf(stdout, "[%d:%d %4ld] %s\n", (int)getpid( ), Level,
time(NULL) - NGIRCd_Start, msg);
fflush(stdout);
}
#ifdef SYSLOG
else
@@ -278,10 +269,11 @@ va_dcl
fflush( stderr );
}
if( snotice )
{
/* NOTICE an lokale User mit "s"-Mode */
Wall_ServerNotice( msg );
if (snotice) {
/* Send NOTICE to all local users with mode +s and to the
* local &SERVER channel */
Wall_ServerNotice(msg);
Channel_LogServer(msg);
}
} /* Log */
@@ -343,11 +335,11 @@ va_dcl
vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
va_end( ap );
if( ! Is_Daemon )
{
if (!Is_Daemon) {
/* Output to console */
fprintf( stdout, "[%d:%d] %s\n", (int)getpid( ), Level, msg );
fflush( stdout );
fprintf(stdout, "[%d:%d %4ld] %s\n", (int)getpid( ), Level,
time(NULL) - NGIRCd_Start, msg);
fflush(stdout);
}
#ifdef SYSLOG
else syslog( Level, "%s", msg );

View File

@@ -8,7 +8,7 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: log.h,v 1.19 2006/02/08 17:33:28 fw Exp $
* $Id: log.h,v 1.20 2006/08/05 09:16:21 fw Exp $
*
* Logging functions (header)
*/
@@ -39,7 +39,13 @@ GLOBAL void Log_Init PARAMS(( bool Daemon_Mode ));
GLOBAL void Log_Exit PARAMS(( void ));
GLOBAL void Log PARAMS(( int Level, const char *Format, ... ));
#ifdef DEBUG
GLOBAL void LogDebug PARAMS(( const char *Format, ... ));
#else
static inline void LogDebug PARAMS(( UNUSED const char *Format, ... )){/* Do nothing. The compiler should optimize this out, please ;-) */}
#endif
GLOBAL void Log_Init_Resolver PARAMS(( void ));
GLOBAL void Log_Exit_Resolver PARAMS(( void ));

View File

@@ -14,7 +14,7 @@
#include "portab.h"
static char UNUSED id[] = "$Id: match.c,v 1.4 2005/07/31 20:13:08 alex Exp $";
static char UNUSED id[] = "$Id: match.c,v 1.5 2006/10/06 21:23:47 fw Exp $";
#include "imp.h"
#include <assert.h>
@@ -22,6 +22,8 @@ static char UNUSED id[] = "$Id: match.c,v 1.4 2005/07/31 20:13:08 alex Exp $";
#include "exp.h"
#include "match.h"
#include "defines.h"
#include "tool.h"
/*
@@ -32,8 +34,8 @@ static char UNUSED id[] = "$Id: match.c,v 1.4 2005/07/31 20:13:08 alex Exp $";
*/
static int Matche PARAMS(( char *p, char *t ));
static int Matche_After_Star PARAMS(( char *p, char *t ));
static int Matche PARAMS(( const char *p, const char *t ));
static int Matche_After_Star PARAMS(( const char *p, const char *t ));
#define MATCH_PATTERN 6 /* bad pattern */
@@ -45,7 +47,7 @@ static int Matche_After_Star PARAMS(( char *p, char *t ));
GLOBAL bool
Match( char *Pattern, char *String )
Match( const char *Pattern, const char *String )
{
/* Pattern mit String vergleichen */
if( Matche( Pattern, String ) == MATCH_VALID ) return true;
@@ -53,8 +55,18 @@ Match( char *Pattern, char *String )
} /* Match */
GLOBAL bool
MatchCaseInsensitive(const char *pattern, const char *searchme)
{
char haystack[COMMAND_LEN];
strlcpy(haystack, searchme, sizeof(haystack));
return Match(pattern, ngt_LowerStr(haystack));
} /* MatchCaseInsensitive */
static int
Matche( char *p, char *t )
Matche( const char *p, const char *t )
{
register char range_start, range_end;
bool invert;
@@ -201,7 +213,7 @@ Matche( char *p, char *t )
static int
Matche_After_Star( char *p, char *t )
Matche_After_Star( const char *p, const char *t )
{
register int nextp, match = 0;

View File

@@ -8,7 +8,7 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: match.h,v 1.3 2005/03/19 18:43:49 fw Exp $
* $Id: match.h,v 1.4 2006/10/06 21:23:47 fw Exp $
*
* Wildcard pattern matching (header)
*/
@@ -18,7 +18,8 @@
#define __match_h__
GLOBAL bool Match PARAMS(( char *Pattern, char *String ));
GLOBAL bool Match PARAMS(( const char *Pattern, const char *String ));
GLOBAL bool MatchCaseInsensitive PARAMS(( const char *Pattern, const char *searchme ));
#endif

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2004 Alexander Barton <alex@barton.de>
* Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -8,8 +8,6 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: messages.h,v 1.67 2005/09/02 12:50:25 alex Exp $
*
* IRC numerics (Header)
*/
@@ -22,7 +20,8 @@
#define RPL_YOURHOST_MSG "002 %s :Your host is %s, running version ngircd-%s (%s/%s/%s)"
#define RPL_CREATED_MSG "003 %s :This server has been started %s"
#define RPL_MYINFO_MSG "004 %s %s ngircd-%s %s %s"
#define RPL_ISUPPORT_MSG "005 %s NICKLEN=%d TOPICLEN=%d AWAYLEN=%d MAXCHANNELS=%d :are supported on this server"
#define RPL_ISUPPORT1_MSG "005 %s RFC2812 CASEMAPPING=ascii PREFIX=(ov)@+ CHANTYPES=#&+ CHANMODES=bI,k,l,imnPst CHANLIMIT=#&+:%d :are supported on this server"
#define RPL_ISUPPORT2_MSG "005 %s CHANNELLEN=%d NICKLEN=%d TOPICLEN=%d AWAYLEN=%d KICKLEN=%d PENALTY :are supported on this server"
#define RPL_TRACELINK_MSG "200 %s Link %s-%s %s %s V%s %ld %d %d"
#define RPL_TRACEOPERATOR_MSG "204 %s Oper 2 :%s"
@@ -31,18 +30,22 @@
#define RPL_STATSCOMMANDS_MSG "212 %s %s %ld %ld %ld"
#define RPL_ENDOFSTATS_MSG "219 %s %c :End of STATS report"
#define RPL_UMODEIS_MSG "221 %s +%s"
#define RPL_SERVLIST_MSG "234 %s %s %s %s %d %d :%s"
#define RPL_SERVLISTEND_MSG "235 %s %s %s :End of service listing"
#define RPL_STATSUPTIME "242 %s :Server Up %u days %u:%02u:%02u"
#define RPL_LUSERCLIENT_MSG "251 %s :There are %ld users and %ld services on %ld servers"
#define RPL_LUSEROP_MSG "252 %s %ld :operator(s) online"
#define RPL_LUSERUNKNOWN_MSG "253 %s %ld :unknown connection(s)"
#define RPL_LUSERCHANNELS_MSG "254 %s %ld :channels formed"
#define RPL_LUSERME_MSG "255 %s :I have %ld users, %ld services and %ld servers"
#define RPL_LUSEROP_MSG "252 %s %lu :operator(s) online"
#define RPL_LUSERUNKNOWN_MSG "253 %s %lu :unknown connection(s)"
#define RPL_LUSERCHANNELS_MSG "254 %s %lu :channels formed"
#define RPL_LUSERME_MSG "255 %s :I have %lu users, %lu services and %lu servers"
#define RPL_ADMINME_MSG "256 %s %s :Administrative info"
#define RPL_ADMINLOC1_MSG "257 %s :%s"
#define RPL_ADMINLOC2_MSG "258 %s :%s"
#define RPL_ADMINEMAIL_MSG "259 %s :%s"
#define RPL_TRACEEND_MSG "262 %s %s %s-%s.%s :End of TRACE"
#define RPL_LOCALUSERS_MSG "265 %s :Current local users: %ld, Max: %ld"
#define RPL_NETUSERS_MSG "266 %s :Current global users: %ld, Max: %ld"
#define RPL_LOCALUSERS_MSG "265 %s %lu %lu :Current local users: %lu, Max: %lu"
#define RPL_NETUSERS_MSG "266 %s %lu %lu :Current global users: %lu, Max: %lu"
#define RPL_AWAY_MSG "301 %s %s :%s"
#define RPL_USERHOST_MSG "302 %s :"
@@ -54,7 +57,7 @@
#define RPL_WHOISOPERATOR_MSG "313 %s %s :is an IRC operator"
#define RPL_WHOWASUSER_MSG "314 %s %s %s %s * :%s"
#define RPL_ENDOFWHO_MSG "315 %s %s :End of WHO list"
#define RPL_WHOISIDLE_MSG "317 %s %s %ld :seconds idle"
#define RPL_WHOISIDLE_MSG "317 %s %s %lu %lu :seconds idle, signon time"
#define RPL_ENDOFWHOIS_MSG "318 %s %s :End of WHOIS list"
#define RPL_WHOISCHANNELS_MSG "319 %s %s :"
#define RPL_LIST_MSG "322 %s %s %ld :%s"
@@ -63,7 +66,7 @@
#define RPL_NOTOPIC_MSG "331 %s %s :No topic is set"
#define RPL_TOPIC_MSG "332 %s %s :%s"
#define RPL_TOPICSETBY_MSG "333 %s %s %s %u"
#define RPL_INVITING_MSG "341 %s %s %s"
#define RPL_INVITING_MSG "341 %s %s %s%s"
#define RPL_INVITELIST_MSG "346 %s %s %s"
#define RPL_ENDOFINVITELIST_MSG "347 %s %s :End of channel invite list"
#define RPL_VERSION_MSG "351 %s %s-%s.%s %s :%s"
@@ -75,6 +78,8 @@
#define RPL_BANLIST_MSG "367 %s %s %s"
#define RPL_ENDOFBANLIST_MSG "368 %s %s :End of channel ban list"
#define RPL_ENDOFWHOWAS_MSG "369 %s %s :End of WHOWAS list"
#define RPL_INFO_MSG "371 %s :%s"
#define RPL_ENDOFINFO_MSG "374 %s :End of INFO list"
#define RPL_MOTD_MSG "372 %s :- %s"
#define RPL_MOTDSTART_MSG "375 %s :- %s message of the day"
#define RPL_ENDOFMOTD_MSG "376 %s :End of MOTD command"
@@ -93,11 +98,14 @@
#define ERR_NOTEXTTOSEND_MSG "412 %s :No text to send"
#define ERR_UNKNOWNCOMMAND_MSG "421 %s %s :Unknown command"
#define ERR_NOMOTD_MSG "422 %s :MOTD file is missing"
#define ERR_NONICKNAMEGIVEN_MSG "431 %s :No nickname given"
#define ERR_ERRONEUSNICKNAME_MSG "432 %s %s :Erroneous nickname"
#define ERR_NICKNAMEINUSE_MSG "433 %s %s :Nickname already in use"
#define ERR_USERNOTINCHANNEL_MSG "441 %s %s %s :They aren't on that channel"
#define ERR_NOTONCHANNEL_MSG "442 %s %s :You are not on that channel"
#define ERR_USERONCHANNEL_MSG "443 %s %s %s :is already on channel"
#define ERR_SUMMONDISABLED_MSG "445 %s %s :SUMMON has been disabled"
#define ERR_USERSDISABLED_MSG "446 %s %s :USERS has been disabled"
#define ERR_NOTREGISTERED_MSG "451 %s :Connection not registered"
#define ERR_NOTREGISTEREDSERVER_MSG "451 %s :Connection not registered as server link"
#define ERR_NEEDMOREPARAMS_MSG "461 %s %s :Syntax error"
@@ -108,6 +116,7 @@
#define ERR_INVITEONLYCHAN_MSG "473 %s %s :Cannot join channel (+i)"
#define ERR_BANNEDFROMCHAN_MSG "474 %s %s :Cannot join channel (+b)"
#define ERR_BADCHANNELKEY_MSG "475 %s %s :Cannot join channel (+k)"
#define ERR_NOCHANMODES_MSG "477 %s %s :Channel doesn't support modes"
#define ERR_NOPRIVILEGES_MSG "481 %s :Permission denied"
#define ERR_CHANOPRIVSNEEDED_MSG "482 %s %s :You are not channel operator"
#define ERR_CANTKILLSERVER_MSG "483 %s :You can't kill a server!"

Some files were not shown because too many files have changed in this diff Show More