1
0
mirror of https://github.com/osmarks/ngircd.git synced 2025-09-25 05:24:04 +00:00

Compare commits

...

280 Commits

Author SHA1 Message Date
Alexander Barton
d00a0f1e7c ngIRCd release 17~rc1 2010-10-11 23:25:48 +02:00
Alexander Barton
a988bbc86a New configuration option "NoZeroConf" to disable ZeroConf registration
If ngIRCd is compiled to register its services using ZeroConf (e.g. using
Howl, Avahi or on Mac OS X) this parameter can be used to disable service
registration at runtime.
2010-10-11 16:54:49 +02:00
Alexander Barton
4226db873f Xcode: only build current architecture in "Debug" target 2010-10-09 20:13:54 +02:00
Alexander Barton
f579043671 doc/Platforms.txt: added NetBSD 5.0.2 2010-10-07 13:20:30 +02:00
Alexander Barton
50cb321bb1 Updated doc/Platforms.txt 2010-10-05 23:19:54 +02:00
Alexander Barton
ade8902b88 Make sure sighandlers.h is listed in noinst_HEADERS
... because it must be included in the distribution archive :-)
2010-10-05 21:57:01 +02:00
Alexander Barton
3a826b774a const'ify ngt_SyslogFacilityName() function
This fixes the following gcc compiler warning:

tool.c: In function 'ngt_SyslogFacilityName':
tool.c:195: warning: return discards qualifiers from pointer target type
2010-10-05 20:16:35 +02:00
Alexander Barton
c51cc88eb0 Debian packages: build "-full" and "-full-dbg" with support for PAM 2010-10-03 15:06:07 +02:00
Alexander Barton
5e82a91d13 New configuration option "SyslogFacility"
The new option "SyslogFacility" deines the syslog "facility" to which
ngIRCd should send log messages.

Possible values are system dependant, but most probably "auth", "daemon",
"user" and "local1" through "local7" are possible values; see syslog(3).
Default is "local5" for historical reasons.
2010-09-24 17:39:11 +02:00
Alexander Barton
4943bbb066 New functions ngt_SyslogFacilityName() and ngt_SyslogFacilityID()
These both functions translate syslog facility names to ID numbers
and vice versa. On systems that don't define the facilitynames[] array
in syslog.h, we try to build one ourself.
2010-09-24 16:29:55 +02:00
Alexander Barton
e2ba7e08b4 Explicitly cast return value of read(2) to "int"
This fixes the following gcc warning, emitted by Xcode:

src/ngircd/sighandlers.c: In function 'Signal_Callback':
src/ngircd/sighandlers.c:239: warning: implicit conversion shortens 64-bit value into a 32-bit value
2010-09-22 14:15:46 +02:00
Alexander Barton
b1a117cd98 Add sighandlers.{c|h} to Xcode project
And update static Mac OS X config.h used by the Xcode project.
2010-09-22 14:11:30 +02:00
Alexander Barton
4a770e8e2d Don't call sigaction() if it is not available on the system 2010-09-22 14:10:09 +02:00
Florian Westphal
ba720fcbae Fix signalpipe file descriptor leak on RESTART
Signals_Init() must only be called once.
This does not affect any ngircd release version.

Earlier version of this patch moved the io and sighandler
initialization before the while() loop, but as Alexander
Barton noticed that broke all systems without builtin select
support in io.c...
2010-09-14 23:53:59 +02:00
Alexander Barton
b3cfbc3d28 sighandlers.{c|h}: Code cleanup
- declare signals_catch[] array not between the function implementations.
 - rename now local function NGIRCd_Rehash() to Rehash().
 - remove empty and therefore not used "catch SIGHUP; break;".
2010-09-14 00:30:45 +02:00
Alexander Barton
74578890b7 Make sighandlers.{c|h} compatible with ansi2knr 2010-09-14 00:29:34 +02:00
Alexander Barton
212311efc5 Updated ChangeLog to include signal handler changes 2010-09-14 00:18:20 +02:00
Alexander Barton
fe5c7cb22d Bump version number to "17-dev" 2010-09-14 00:05:31 +02:00
Alexander Barton
cdae82413d Update ChangeLog and NEWS: include SIGUSR1/SIGUSR2 changes 2010-09-14 00:05:31 +02:00
Alexander Barton
3600dc60fc Output connection status when dumping the internal server state 2010-09-14 00:05:31 +02:00
Alexander Barton
cd954ee7e9 Reformat "server state" debug messages a little bit 2010-09-14 00:04:04 +02:00
Alexander Barton
355828e64f Enable the daemon to dump its internal state in debug-mode.
This patch allows ngIRCd to dump its internal state (connected clients,
actual configuration) when compiled with --enable-debug. The daemon
catches two more signals:

 - SIGUSR1: toggle debug mode (on/off),
 - SIGUSR2: dump internal state to console/syslog.
2010-09-14 00:02:02 +02:00
Florian Westphal
755f54b150 signalhandlers: add fallback to deprecated sysv API 2010-09-11 11:36:12 +02:00
Florian Westphal
ef3dbf96eb remove NGIRCd_SignalRehash
now that the main signal handling is done from the dispatcher
loop we can call NGIRCD_Rehash() directly.

the /REHASH handler can queue the Rehash() function for
execution by sending a SIGHUP.  It will be run when we
return back to the dispatch loop.
2010-09-11 11:36:12 +02:00
Florian Westphal
1fe17e246c Add new 'delayed' signal handlers.
Allows to defer/queue signal processing for execution on the next
event dispatch call, i.e. we can perform any signal action in
normal, non-signal context.

Example uses:
- Reload everything on HUP without writing a global "SIGHUP_received"
  variable
- Dump status of internal Lists on SIGUSR1, etc.
2010-09-11 11:36:12 +02:00
Florian Westphal
c135d0dded io: add io_cloexec to set close-on-exec flag. 2010-09-11 11:36:12 +02:00
Florian Westphal
1e281a8baa ng_ipaddr.h: include assert.h
We use assert() in this header, so we should include assert.h.
2010-09-11 11:35:01 +02:00
Alexander Barton
6349ec8bb3 Conn_SyncServerStruct(): test all connections; and work case insensitive
Fix synchronization of established connections and configured server
structures after a configuration update:

 - Not only test servers that already have a connection, but also check
   and update configured servers to which a new connection is beeing
   established (SERVER_WAIT state).

 - And do the server name comparision case-insensitive.
2010-09-08 02:02:01 +02:00
Alexander Barton
8d68fe3f86 Check_Servers(): skip servers already beeing connected
Let CheckServers() not only skip servers that already have a
connection, but also skip servers to which a new connection is
already beeing established (SERVER_WAIT state).
2010-09-08 00:45:23 +02:00
Alexander Barton
4f6c19712e Check_Servers(): Code cleanup 2010-09-08 00:42:57 +02:00
Alexander Barton
4833f9e5c8 Update ChangeLog and NEWS in preparation for the next release ... 2010-08-29 18:10:49 +02:00
Alexander Barton
90a186158b Fix linebreak in INSTALL text to fit in 80 columns 2010-08-29 18:09:57 +02:00
Alexander Barton
b52d5e2a78 configure: correctly indent IPv6 yes/no summary output 2010-08-25 00:02:06 +02:00
Alexander Barton
04e38f17ae Don't reset My_Connections[Idx].lastping when reading data
This fixes PING-PONG lag calculation (which resulted in "0" before).

The "lastping" time is still reset it if a time shift backwards has
been detected to prevent the daemon from miscalculating ping timeouts.
2010-08-19 15:58:55 +02:00
Alexander Barton
32188d821b write_whoreply(): respect hostname cloaking 2010-08-18 00:01:14 +02:00
Alexander Barton
6f4a348b75 IRC_USERHOST(): respect hostname cloaking 2010-08-17 23:56:36 +02:00
Alexander Barton
a51670005f IRC_USERHOST(): Code cleanup & some documentation 2010-08-17 23:55:40 +02:00
Alexander Barton
0263fa4c66 Send_Message(): respect hostname cloaking 2010-08-17 21:16:46 +02:00
Alexander Barton
31ea0f8ee9 IRC_WriteStrClientPrefix() / Get_Prefix(): respect hostname cloaking 2010-08-17 21:14:51 +02:00
Alexander Barton
fd4dfccc30 Refactor IRC_WriteStr{Channel|Related}Prefix(); support cloaking
Move common code to new local function Send_Marked_Connections()
and respect hostname cloaking.
2010-08-17 21:11:37 +02:00
Alexander Barton
2a4bf67aac Implement user mode "x": hostname cloaking (closes: #102)
When a client has user mode "x" set, its real hostname is cloaked
by substituting it with the server name (as configured in ngircd.conf).

Restricted clients (user mode "r") aren't allowed to change mode "x".

Please note that hostname cloaking is only in effect in server-client
communication! The server still uses the real hostname for its own
logging and for all server-server communication -- therefore all servers
in the network must support user mode "x" to prevent older servers
from leaking the real hostname of a cloaked client!
2010-08-17 21:05:06 +02:00
Alexander Barton
575485eb82 WHOWAS: respect hostname cloaking
Store cloaked hostname if user mode "x" is set when the client
disconnects from the server.
2010-08-17 21:02:39 +02:00
Alexander Barton
3fd4f320b7 WHOIS: respect hostname cloaking 2010-08-17 21:00:47 +02:00
Alexander Barton
6fdd3479f1 Implement Client_HostnameCloaked() and Client_MaskCloaked()
These two functions return the cloaked hostname, if the client has
enabled hostname cloaking indicated by the -- still to implement --
user mode "x". See furter patches :-)
2010-08-17 20:54:33 +02:00
Alexander Barton
617640e0a3 Clean up an document Client_Hostname() and Client_Mask() 2010-08-17 20:51:14 +02:00
Alexander Barton
f72e22d361 Make configure switch "--docdir" work (closes: #108) 2010-08-17 15:59:54 +02:00
Alexander Barton
c65bf5d2ce Reformat and update FAQ.txt a little bit 2010-08-13 15:53:24 +02:00
Florian Westphal
9c6230e177 INSTALL: mention SSL and IPv6 2010-08-12 21:46:51 +02:00
Florian Westphal
479a43b1c6 INSTALL: mention changed handling of MotdFile. 2010-08-12 21:46:51 +02:00
Florian Westphal
056de78e31 ngircd: change MOTD file handling
previously, the given MotdFile file was read whenever a client
requested it.

Change handling to read the MotdFile contents into memory once
during config file parsing.

Two side effects:
- changes to the MOTD file do not have any effect until ngircds
  configuration is reloaded
- MOTD file does no longer have to reside in the chroot directory
  (the MOTD contents will then not be re-read on reload in that case)
2010-08-12 21:46:47 +02:00
Florian Westphal
a02bc9cc6f startup: open /dev/null before chroot
before people had to create a /dev/null inside the chroot to make
redirection work.
2010-08-01 00:07:33 +02:00
Alexander Barton
01e40f4b55 Allow IRC ops to change channel modes even without OperServerMode set 2010-07-25 16:44:38 +02:00
Florian Westphal
acb66d6463 Allow IRC operators to use MODE command on any channel (closes: #100)
This allows IRC operators to change channel modes of ANY channel,
even without joining these channels first.
2010-07-25 16:18:25 +02:00
Alexander Barton
63a304755a Added mailmap file for git-[short]log and git-blame 2010-07-25 15:13:50 +02:00
Alexander Barton
6ebb31ab35 Remove Proc_Kill(), use timeout to kill child processes
This avoids a race and potentionally killing the wrong process on
systems that use randomized process IDs; now the child itself is
responsible to exit in a timely manner using SIGALRM.
2010-07-14 10:29:05 +02:00
Alexander Barton
cf93881dfb New function Conn_CloseAllSockets() to close all open sockets
This is useful in forked child processes, for example, to make sure that
they don't hold connections open that the main process wants to close.
2010-07-14 10:27:55 +02:00
Alexander Barton
560492a4a4 Authenticated users should be registered without the "~" mark 2010-07-13 23:18:54 +02:00
Alexander Barton
9cd3494de9 Don't Proc_Kill() childs after Proc_Read(): done there already. 2010-07-13 22:29:06 +02:00
Alexander Barton
6131822af6 Don't even fork a PAM-subprocess if "NoPAM" option is set 2010-07-13 22:14:53 +02:00
Alexander Barton
57a2faf4a7 Use Proc_GenericSignalHandler() as handler for SIGTERM by default 2010-07-13 22:04:35 +02:00
Alexander Barton
41034950d9 Mark some variables as "unused" to prevent compiler warnings
Some variables are only used when compiling with IDENT or PAM support
or when the debug code is enabled. Mark them as "unused" so that gcc
doesn't generate warnings when neither of these options is enabled.
2010-07-13 16:50:00 +02:00
Alexander Barton
6faf44bc6d Set NoPAM=yes in configuration files used for the testsuite 2010-07-13 16:48:24 +02:00
Alexander Barton
f369177617 New configuration option "NoPAM" to disable PAM
When the "NoPAM" configuration option is set and ngIRCd is compiled
with support for PAM, ngIRCd will not call any PAM functions: all
connection attemps without password will succeed instead and all
connection attemps with password will fail.

If ngIRCd is compiled without PAM support, this option is a dummy
option and nothing changes: the global server password will still be
in effect.
2010-07-13 16:47:01 +02:00
Alexander Barton
37ee0a3313 io.c: Include conn.h when using the select() API 2010-07-12 13:24:45 +02:00
Alexander Barton
03457135b7 Use correct preprocessor syntax when testing for PAM and IDENTAUTH 2010-07-12 13:22:48 +02:00
Alexander Barton
28424d013d Make sure signal.h is #include'd when needed 2010-07-12 13:22:19 +02:00
Alexander Barton
583c50476b Initial documentation for using PAM with ngIRCd 2010-07-12 13:07:07 +02:00
Alexander Barton
808d4f6e85 Implement asynchronous user authentication using PAM
For each client connection a child process is forked which handles the
actual PAM authentication and reports the result back to the master
process using a pipe for communication.

While the PAM authentication is in process the daemon does not block.
2010-07-12 12:56:33 +02:00
Alexander Barton
fb4b5acfb8 Add new pam.{c|h} module to Xcode project
Adjust Xcode project and Mac OS X static config.h header to use PAM.
2010-07-12 12:54:01 +02:00
Alexander Barton
77870ddf2d Add pam.{c|h} to project and implement PAM_Authenticate() function 2010-07-12 12:53:08 +02:00
Alexander Barton
1995af0ed6 New functions Client_[Set]OrigUser() to get/set user specified by peer
The Client_SetOrigUser() function is used to store the peer-provided
user name (see USER command) in its original form, not changed by
IDENT results, for example.
2010-07-11 17:03:43 +02:00
Alexander Barton
761b2284b9 Detect PAM libraries 2010-07-11 17:01:45 +02:00
Alexander Barton
79be1c477e Refactor Resolve_Read() into generic Proc_Read() function 2010-07-11 16:58:30 +02:00
Alexander Barton
7b5e2fe38e Make Proc_Kill() more fault-tolerant 2010-07-11 16:54:44 +02:00
Alexander Barton
bf8b646304 New function Conn_GetProcStat()
Get PROC_STAT sub-process structure of a given connection.
2010-07-11 15:15:23 +02:00
Alexander Barton
e4ffcd00bd Code cleanup: don't reset penalty time on DNS resolver result
See commit d4632a727f: it's not necessary any more!
2010-07-11 15:12:17 +02:00
Alexander Barton
4cc4c29e38 New function Proc_GenericSignalHandler() 2010-07-01 00:39:35 +02:00
Alexander Barton
0db9a31e50 Rename Log_[{Init|Exit}_]Resolver to Log_[{Init|Exit}_]Subprocess
Rename Log_Init_Resolver, Log_Exit_Resolver, and Log_Resolver to
Log_Init_Subprocess, Log_Exit_Subprocess, and Log_Subprocess and
make it more generic thereby.
2010-07-01 00:34:56 +02:00
Alexander Barton
5462c6c50f Don't #include client.h when conn.h/conn-func.h is already included
conn.h and cinn-func.h both already #include client.h, so it is
not needed to do it twice.
2010-06-30 23:49:52 +02:00
Alexander Barton
3d49fa5bff New function Conn_GetFromProc() to get CONN_ID of a subprocess
Get CONN_ID from file descriptor associated to a subprocess structure.
2010-06-29 23:38:39 +02:00
Alexander Barton
2d4ea28835 Resolver: Implement signal handler and catch TERM signal 2010-06-29 22:55:27 +02:00
Alexander Barton
d4632a727f Don't set a penalty time when doing DNS lookups
The logic isn't as described in the source and intended by this code:
ngIRCd doesn't wait for the asynchronous resolver process until the set
penalty time is over, but until the forked process terminates or the
initial connection timeout (= PongTimeout) triggers.

So don't set the penalty time at all and remove the wrong comment.
2010-06-29 22:55:27 +02:00
Alexander Barton
60f5dd5b29 Update comments: subprocesses not only can be resolver processes 2010-06-29 22:55:27 +02:00
Alexander Barton
89e73ad4b4 Refactoring: Rename CONNECTION.res_stat to .proc_stat
We want to use this process status variable not only for the
resolver subprocesses but other asynchronous tasks as well;
so let's name it more generic.
2010-06-29 22:55:27 +02:00
Alexander Barton
54e67ea9ee New "module" proc.c/proc.h for generic process handling
The new "module" proc.c is used for functions dealing with child
processes. At the moment, it is only used by the asynchronous resolver.

All the functions already implemented habe been migrated from the
resolver code base, and the rest of the ngIRCd source code has been
adepted to the new namespace and calling conventions.

The goal is to develop "generic" process handling functions that can
be used for other purposes as well, e.g. running processes on client
connects etc.
2010-06-29 22:55:27 +02:00
Alexander Barton
cc336b7558 Only #include resolve.h if it is really needed 2010-06-29 22:55:27 +02:00
Alexander Barton
ae55d4f500 Fix redundant redeclaration of Conn_Count*() functions
The wrongly placed #endif lead to the following compiler warnings:

conn.h:125: warning: redundant redeclaration of ‘Conn_Count’
conn.h:125: warning: previous declaration of ‘Conn_Count’ was here
conn.h:126: warning: redundant redeclaration of ‘Conn_CountMax’
conn.h:126: warning: previous declaration of ‘Conn_CountMax’ was here
conn.h:127: warning: redundant redeclaration of ‘Conn_CountAccepted’
conn.h:127: warning: previous declaration of ‘Conn_CountAccepted’ was here
2010-06-26 00:45:11 +02:00
Alexander Barton
edfa215481 const'ify Conn_WriteStr() function 2010-06-26 00:44:37 +02:00
Alexander Barton
c6742192a6 const'ify Send_ListChange() function in irc-mode.c 2010-06-26 00:42:12 +02:00
Alexander Barton
0c0d4af55a const'ify IRC_WriteStrXXX() and Get_Prefix() functions 2010-06-26 00:38:20 +02:00
Alexander Barton
8605e9c0fe const'ify command name variable in _COMMAND strcuture 2010-06-26 00:37:06 +02:00
Alexander Barton
a68103771c const'ify Client_TypeText() 2010-06-26 00:31:08 +02:00
Alexander Barton
8ad1c23ae4 Add some documentation for using BOPM with ngIRCd 2010-06-25 15:19:39 +02:00
Alexander Barton
f76e0a1db6 Implement user mode "c": receive connect/disconnect NOTICEs
Users having the user mode "c" set receive NOTICE messages on each
new client connection to the local server as well as disconnects.
Only IRC operators (users having the mode "o" set) are allowed to
set the 'c' user mode.

These connect/disconnect messages can be useful for open proxy
scanners -- BOPM (http://wiki.blitzed.org/BOPM) is now functional
with ngIRCd, for example.
2010-06-25 00:33:01 +02:00
Alexander Barton
51ed742054 Refactor Wall_ServerNotice() into more generic Log_ServerNotice()
Log_ServerNotice() sends a messages to all users having a given
user mode set.
2010-06-25 00:33:00 +02:00
Alexander Barton
60eac5e952 New function Conn_IPA(): get client IP address as string 2010-06-25 00:33:00 +02:00
Alexander Barton
139d6303e7 ngircd.init: require $network $remote_fs when stopping ngircd 2010-06-25 00:10:56 +02:00
Neale Pickett
28f8b50174 Show SSL status in WHOIS, numeric 275
"I've been wanting this for years and finally took the 5 minutes to
patch it in. I took the response code (275) from whatever's running
OFTC's IRC network."
  -- Neale Pickett <neale@woozle.org>, Fri, 11 Jun 2010 17:32:41 -0500

(OFTC is running Hybrid ircd.)
2010-06-23 11:00:09 +02:00
Alexander Barton
e2930f3f5e Include correct header files when testing for arpa/inet.h (Closes: #105)
Tested on OpenBSD 4.7, OpenBSD 4.1, FreeBSD 8, Linux and Mac OS X.
Thanks to rck <dev.rck@gmail.com> for reporting and testing!
2010-06-09 12:03:08 +02:00
Florian Westphal
059e707249 Revert "configure: make implicit declarations fatal"
This reverts commit b3a6c33da0b12ba74dc395979b677813d4bc2c0f.

apparently not all gcc versions support this 8-(
2010-06-09 12:03:00 +02:00
Florian Westphal
b849e63fbf configure: make implicit declarations fatal
from bugzilla #105:
"ngircd-16 works great under openbsd4.7/i386, but it segfaults on
openbsd4.7/amd64."

Caused by missing function prototypes and the resulting truncation of
pointer to int.

Lets try to catch these bugs during compilation instead of SIGSEGV.
2010-06-09 11:49:57 +02:00
Alexander Barton
55190f2d3d Don't access already freed memory in IRC_KILL()
It is not possible to call Conn_Close() after Client_Destroy() has been
called, because Conn_Close wants to access the CLIENT structure which
then has been freed already.

Fix IRC_KILL to use Conn_Close() for local clients and Client_Destroy()
for remote clients only (and never both).
2010-05-22 17:03:54 +02:00
Florian Westphal
6dc80bd195 fix "beeing" typo
reported by Fabio Scotoni via bugzilla #101.
2010-05-14 19:43:08 +02:00
Florian Westphal
df359835d1 SSL/TLS: fix bogus 'socket closed' error message
When we get there then the ssl handshake has failed, or
we could not create a ssl context because ssl library
initialization failed on startup.

Reflect that in the log message.
2010-05-07 23:25:59 +02:00
Alexander Barton
defd7e09af ngIRCd release 16 2010-05-02 15:25:35 +02:00
Florian Westphal
29d448ed63 doc/SSL: remove line continuation marker
some people got confused by the '\' line continuation marker,
thus put everything in a single line, even if the line gets overly long.
2010-05-01 20:29:18 +02:00
Alexander Barton
bdec5ac1f3 ngIRCd release 16~rc2 2010-04-25 13:13:11 +02:00
Alexander Barton
73fd26e9fa Don't reset counters on RESTART
When ngIRCd restarts, all the connection counters are preserved now,
as well as the command counters for example.

It's unclear if resetting or not resetting is the "correct" behaviour,
but it's quite clear that the behaviour should be consistent for all the
counters ngIRCd uses ...

And initializing "WCounter", the global but temporary write counter,
is not necessarry at all: it is initialized (reset) before its use in
the command parser (see parse.c).
2010-04-25 12:54:13 +02:00
Alexander Barton
79e1ec2b1e New numeric RPL_STATSCONN (250): display connection statistics
The RPL_STATSCONN numeric (250) displays information about the
highest simoultaneous connection count and the number of all
accepted connections since the daemon started up.

Used by ircd-Hybrid, Bahamut, and Unreal for example.
2010-04-23 23:30:14 +02:00
Alexander Barton
615d09459e Display total number of served connections on daemon shutdown 2010-04-23 23:29:22 +02:00
Alexander Barton
1338ade650 Enhace connection statistics counters
This patch enables ngIRCd to count the highest maximum simultaneous
connections and all the connections accepted since startup.

New functions:
- Conn_Count(): get current connections
- Conn_CountMax(): maximum simultaneous connections
- Conn_CountAccepted(): number of connections accepted
2010-04-23 23:25:34 +02:00
Alexander Barton
21140500f1 Conn_Init: code cleanup 2010-04-23 22:23:51 +02:00
Alexander Barton
77ceb9f8ab Updated doc/Platforms.txt 2010-04-23 11:04:39 +02:00
Alexander Barton
b042363e88 Only include <netinet/in_systm.h> if it exists 2010-04-23 11:04:15 +02:00
Alexander Barton
6b0bb665c3 Include netinet/{in.h, in_systm.h} when checking for netinet/ip.h
This solves warning messages of autoconf on e.g. FreeBSD 8:

configure: WARNING: netinet/ip.h: present but cannot be compiled
configure: WARNING: netinet/ip.h:   check for missing prerequisite headers?
2010-04-23 10:55:50 +02:00
Alexander Barton
1caa3fb94b Include netinet/in_systm.h alongside netinet/ip.h
This fixes the following error when compiling on e.g. FreeBSD 6.x:

In file included from conn.c:40:
/usr/include/netinet/ip.h:160: error: syntax error before "n_long"
/usr/include/netinet/ip.h:163: error: syntax error before "n_long"
2010-04-11 16:58:29 +00:00
Alexander Barton
025342fe46 Fix gcc warning "ignoring return value of ..."
This patch fixes two warnings of gcc 4.4.3 when used with eglibc 2.11.1:

ngircd.c: In function ‘NGIRCd_Init’:
ngircd.c:801: warning: ignoring return value of ‘chdir’, declared with
 attribute warn_unused_result
conn.c: In function ‘Simple_Message’:
conn.c:2041: warning: ignoring return value of ‘write’, declared with
 attribute warn_unused_result

The first by checking the return code and an appropriate error message,
the second by "better" ignoring it (which is correct there!) ...
2010-04-09 20:14:11 +02:00
Alexander Barton
628c6c962b Only compile in Get_Error() if really needed
This fixes "resolve.c:150: warning: ‘Get_Error’ defined but not used".
2010-04-09 20:06:44 +02:00
Alexander Barton
1ed49de83a Updated some more copyright notices, it's 2010 already (part 2)
Silly me forgot the most important place, the program output itself ...
2010-04-02 14:22:07 +02:00
Alexander Barton
bb914b93e9 Updated some more copyright notices, it's 2010 already :-) 2010-04-02 14:19:36 +02:00
Alexander Barton
50e8a62c5c ngIRCd release 16~rc1 2010-03-25 15:57:11 +01:00
Alexander Barton
aa32fec1b6 Updated NEWS and ChangeLog file for ngIRCd 16-rc1 2010-03-25 14:55:31 +01:00
Alexander Barton
cbe41ec875 Don't use port 6668 as example for both "Ports" and "SSLPorts" 2010-03-16 16:16:03 +01:00
Florian Westphal
20276f7cc9 configure.in: only add -lnsl when needed
dpkg-shlibdeps: warning: dependency on libnsl.so.1 [..]
(they use none of its symbols).

As shown via commit 2b14234abc
(dpkg-shlibdeps: warning: dependency on libnsl.so.1) and the
following revert of that commit, we cannot simply drop
the AC_CHECK_LIB(nsl). Although -lnsl is indeed unneeded
when glibc is used, some platforms (e.g. Solaris) need it.

Use AC_SEARCH_LIBS instead to only link when the library exports
a particular symbol.
2010-02-17 22:25:30 +01:00
Alexander Barton
6e8cf51bb2 Implement WEBIRC command
The WEBIRC command is used by some Web-to-IRC gateways to set the correct
user name and host name of users instead of their own.

Syntax: WEBIRC <password> <username> <hostname> <ip-address>

The <password> must be set using the new configuration variable "WebircPassword" in the [Global] section of ngircd.conf.

Please note that the <ip-address> is currently not used by ngIRCd (we don't store it in the CLIENT structure, only the resolved hostname).
2010-02-11 00:01:53 +01:00
Alexander Barton
53fc0ebff6 ngircd.conf.5: Document missing "Password" variable 2010-02-10 23:47:05 +01:00
Alexander Barton
9b3e143a26 Re-format Init_New_Client() function 2010-02-10 23:40:03 +01:00
Alexander Barton
f1bbc92b39 New README-Interix.txt for running ngIRCd on MS SFU and MS SUA 2010-02-05 00:24:33 +01:00
Alexander Barton
1da3e25e65 Added "i586/pc/interix3.5" (MS Services for UNIX) to Platforms.txt 2010-01-22 18:26:26 +01:00
Alexander Barton
e1de769ab9 Quote received messages of ERROR commands in log output 2010-01-19 19:20:56 +01:00
Alexander Barton
9f58418765 Implemented new "secure clients only" channel mode: +z
Only clients using a SSL encrypted connection to the server are
allowed to join such a channel.

But please note three things:

a) already joined clients are not checked when setting this mode,
b) IRC operators are always allowed to join every channel, and
c) remote clients using a server not supporting this mode are not
   checked either and therefore always allowed to join.
2010-01-17 14:20:07 +01:00
Alexander Barton
ef157715a0 Clean up and document IRC_STATS() function 2010-01-16 23:24:19 +01:00
Alexander Barton
ecad9f32c8 Clean up and document IRC_JOIN() and join_allowed() functions 2010-01-16 22:30:55 +01:00
Alexander Barton
f58c8b94d9 Show our name (IRCD=ngIRCd) in ISUPPORT (005) numeric
Inspired by Hyperion IRC daemon.
2010-01-16 14:59:07 +01:00
Alexander Barton
3a2ac66f7f Added missing modes to USERMODES #define
Now the numeric 004 correctly reports all the supported user and channel
modes (user modes "r" and "w" were missing), e. g.:

  :a.irc.net 004 a a.irc.net ngircd-15 aiorsw biIklmnoPstv
2010-01-16 14:07:27 +01:00
Alexander Barton
cf05bf31a7 Updated links to ngIRCd homepage (bug tracker, mailing list) 2010-01-01 18:58:56 +01:00
Alexander Barton
a4d7c6f145 setsockopt(): use IPPROTO_IP instead of SOL_IP to set IPTOS_LOWDELAY 2009-12-31 00:57:02 +01:00
Alexander Barton
1ddc74f13e Really test for netinet/ip.h and set HAVE_NETINET_IP_H 2009-12-31 00:38:47 +01:00
Alexander Barton
75dabcaae5 ReverseLookup(): fix documentation comment 2009-12-30 23:45:02 +01:00
Alexander Barton
1b73e68e6e Move NewConnection handling from callbacks to New_Connection() 2009-12-30 23:42:43 +01:00
Alexander Barton
03cde2efd3 Connection functions: add some more documentation comments 2009-12-30 23:35:17 +01:00
Alexander Barton
cb6faed61c Clean up conn.{c|h} a little bit 2009-12-30 23:32:47 +01:00
Alexander Barton
c62c2d349b Xcode: fix "-Wuninitialized is not supported without -O"
Fix Apple Xcode warning "cc1: warning: -Wuninitialized is not supported
without -O" when using the "Debug" build target:

Detection of uninitialized automatic variable requires data flow analsys
that is only enabled during optimized compilation.
2009-12-27 17:21:37 +01:00
Alexander Barton
60137a7139 Added i686/unknown/kfreebsd7.2-gnu 2009-12-02 22:22:35 +01:00
Alexander Barton
513a75c919 platformtest.sh: Only show latest commit
Only show latest GIT commuit ID as version number,
even when the last commit has been a merge.
2009-11-15 18:25:36 +01:00
Alexander Barton
4f1b5400e9 Merge commit 'cade80dcf516f40e7d53124bc98526e6e5b3fb66'
* commit 'cade80dcf516f40e7d53124bc98526e6e5b3fb66':
  Added missing contrib/platformtest.sh to distribution
2009-11-07 21:51:36 +01:00
Alexander Barton
cade80dcf5 Added missing contrib/platformtest.sh to distribution 2009-11-07 21:06:30 +01:00
Florian Westphal
28ca31e576 Remove limit on max number of configured irc operators. 2009-11-07 17:42:54 +01:00
Alexander Barton
c414d0bd3a ngIRCd release 15 2009-11-07 13:57:15 +01:00
Florian Westphal
bc88b2cb06 configtest: print ssl config options even when unset
Print "SSLOptionVar =" instead of omitting the option when
running --configtest with ssl enabled.
This better matches the behaviour of other options, e.g.  ChrootDir.
2009-10-17 15:35:26 +02:00
Alexander Barton
bc1ac7fbc5 ngIRCd release 15~rc1 2009-10-15 10:04:34 +02:00
Alexander Barton
37e950a40c Updated NEWS and ChangeLog files 2009-10-03 16:45:09 +02:00
Alexander Barton
55c04e691d Make sure forwarded CONNECT commands are handled correctly 2009-09-30 16:00:06 +02:00
Alexander Barton
881b9af251 Generate WALLOPS message on operator-generated SQUIT 2009-09-30 16:00:06 +02:00
Alexander Barton
294320ed62 Enable SQUIT command for IRC Operators
This patch enables IRC Operators to use the SQUIT command as specified in
RFC 2812, section 3.1.8 "Squit".

When forwarding SQUIT commands, the server connected to the target will
drop the connection (not the target server itself!).

Please note:

 - the configuration option "AllowRemoteOper" mus be enabled on the
   server disconnecting the target to allow forwarding of SQUIT commands.
 - if the remote server is configured to establish the connection, it
   will just do this; so the disconnect is not permanent in this case!
2009-09-30 16:00:06 +02:00
Alexander Barton
03b70229eb Xcode: added new op.{c|h} to project file 2009-09-30 16:00:06 +02:00
Alexander Barton
9918dfc1d5 Use functions provided by op.c "module"
Local functions Check_Oper() and No_Privileges() have been replaced by
global functions in op.c "module": Op_Check() and Op_NoPrivileges().
2009-09-30 16:00:06 +02:00
Alexander Barton
e46cf64cc1 New "module" op.c/op.h for IRC operator related functions
The new "module" op.c is used to implement functions related to IRC Ops.
At the moment, these two functions are available:

 - Op_Check() to check for a valid IRC Op, and
 - Op_NoPrivileges() to generate "permission denied" messages.
2009-09-30 16:00:06 +02:00
Alexander Barton
113bd34878 Allow forwarding of CONNECT commands.
The syntax of the CONNECT command now is:

  - CONNECT <server-id>
  - CONNECT <server-id> <port>
  - CONNECT <server-id> <port> <target>
  - CONNECT <server-id> <port> <host> <my-pwd> <peer-pwd>
  - CONNECT <server-id> <port> <host> <my-pwd> <peer-pwd> <target>

Note: the configuration option "AllowRemoteOper" mus be enabled on the
target server to allow forwarding of CONNECT commands.
2009-09-30 16:00:06 +02:00
Alexander Barton
4a3e40bc95 Check_Oper(): check origin of forwarded messages instead of server. 2009-09-30 16:00:05 +02:00
Alexander Barton
45b1a45c97 No_Privileges(): handle forwarded messages. 2009-09-30 16:00:05 +02:00
Alexander Barton
7d6de7c352 IRC_SendWallops(): support format string and variable parameter lists. 2009-09-30 16:00:05 +02:00
Alexander Barton
30b584c2e8 CONNECT, DISCONNECT: generate WALLOPS messages 2009-09-30 16:00:05 +02:00
Alexander Barton
eaaf0c3bd5 New function IRC_SendWallops().
Implement new global function IRC_SendWallops() that can be called by
other functions to generate WALLOPS messages to users with +w mode.
2009-09-30 16:00:05 +02:00
Alexander Barton
9a7499af8b Code cleanup of IRC_DISCONNECT(). 2009-09-30 16:00:05 +02:00
Alexander Barton
bce16c2864 Code cleanup of IRC_SQUIT() in preparation to deal with bug #73. 2009-09-30 16:00:05 +02:00
Alexander Barton
926204cacd New local functions Check_Oper() and No_Privileges(). 2009-09-30 16:00:05 +02:00
Alexander Barton
3bf0c6f3b9 Bad_OperPass(): code cleanup. 2009-09-30 16:00:05 +02:00
Alexander Barton
f78b0c61e9 New configuration option "AllowRemoteOper"
Added new configuration option "AllowRemoteOper" to control whether
remote IRC operators are allowed to use administrative commands that
affect this server or not

This commit introduces the configuration variable, but actually no
function is using it. That's up for the next patches to come ...
2009-09-30 16:00:04 +02:00
Florian Westphal
fa09883c72 fix assertion failure in ng_ipaddr.c
when building with debugging enabled, but without ipv6 support,
ngircd dumped core when loading a config file that specified an ipv6
listen address.

ngircd: ng_ipaddr.c:45: ng_ipaddr_init: Assertion `sizeof(*addr) >=
res0->ai_addrlen' failed.
2009-09-26 11:12:47 +02:00
Florian Westphal
affa03b277 configtest: complain when ssl keys are not readable 2009-09-20 23:22:28 +02:00
Alexander Barton
5b1efaee67 Check for sockaddr_in.sin_len and initialize it
Test for sockaddr_in.sin_len and initialize it to the correct value
which some systems (notably Mac OS X) require.

Note: this code path is only relevant when not using getaddrinfo().
2009-09-14 01:23:19 +02:00
Alexander Barton
d5f80b2a8d Always use get{addr|name}info() when available
Both getaddrinfo() and getnameinfo() are now used always when available, and
not only when compiling ngIRCd with support for IPv6.

This not only enables ngIRCd to handle multiple addresses per hostname when
compiled without support for IPv6, but fixes binding ngIRCd to IP addresses
on Mac OS X (and probably other BSD-based systems) as well: these systems
require that sockaddr_in is zeroed out and sockaddr_in.sin_len is set to
sizeof(sockaddr_in) like that:

  src/ipaddr/ng_ipaddr.c, line 54:

        assert(ip_str);
      + memset(addr, 0, sizeof *addr);
      + addr->sin4.sin_len = sizeof(addr->sin4);
        addr->sin4.sin_family = AF_INET;

But this would break all the systems not using sockaddr_in.sin_len, for
example Linux -- so we assume that all these systems provide getaddrinfo()
and use that for now.
2009-09-14 01:07:39 +02:00
Alexander Barton
60fc4d6335 Xcode: add "debug" configuration to project 2009-09-14 00:23:44 +02:00
Alexander Barton
536538968c Fix cb_connserver() to handle aborted outgoing connections
A configured server could have been removed while a connection apptempt
is still in progress. So the cb_connserver() callback has to test if the
server configuration record is still valid.
2009-09-12 00:17:42 +02:00
Florian Westphal
4daf780f01 conn.c: fix more sizeof(..dst_addr) misuse
the wrong sizeof() usage fixed in
d76910ce7b
(conn.c: fix resolver server address backlog) was a bit more
widespread, fix all others, too.
2009-09-11 23:31:46 +02:00
Florian Westphal
ed72bf4ceb resolve.c: fix valgrind 'uninitialized memory' warning
fix the following warning generated by valgrind if ipv6 is enabled:

Syscall param write(buf) points to uninitialised byte(s)
   at 0x4000982: (within /lib/ld-2.9.so)
   by 0x80681A8: Resolve_Name (resolve.c:477)
   by 0x805439F: Conn_Handler (conn.c:1658)
   by 0x804AA7C: main (ngircd.c:331)

The warning is because ng_ipaddr_t can be a union, and only the
necessary parts are initialised.  The callers know what part
of the union is valid, so this is not a bug.
2009-09-11 23:09:11 +02:00
Florian Westphal
d76910ce7b conn.c: fix resolver server address backlog
if more than one ip address is returned for a single host
name, ngircd is supposed to try other addresses in case
connect() to the first address returned fails for some
reason.

Alexander Barton noticed that this did not work at all,
as the additional results were not stored.
2009-09-11 22:55:32 +02:00
Alexander Barton
8fd0e29d46 Fix "implicit conversion shortens 64-bit value" warning
This patch fixes the following gcc warning in our sources:
"implicit conversion shortens 64-bit value into a 32-bit value"
2009-09-11 22:52:12 +02:00
Alexander Barton
bfa48f3448 Xcode: use gcc 4.0 for Mac OS X 10.4 compatibility 2009-09-11 20:19:51 +02:00
Alexander Barton
66c6458ae7 Channel_Mode(): fix return code of function
Fix error handling of Channel_Mode() to return the correct connection
status ("connected"/"disconnected") insted of always returning success.
2009-09-11 00:48:07 +02:00
Alexander Barton
3b37ad334b IRC_SERVER(): code cleanup, remove unneeded variable 2009-09-11 00:41:12 +02:00
Alexander Barton
c191ea53a9 IRC_PASS(): remove unnecessary variable initialization 2009-09-10 11:50:43 +02:00
Alexander Barton
e1598e2670 Conn_Close(): remove unused variable "txt" 2009-09-10 11:49:39 +02:00
Alexander Barton
44acf41cc1 Mac OS X: fix test for packagemaker(1) tool in Makefile 2009-09-10 11:48:14 +02:00
Alexander Barton
933da741c6 Fix --with-{openssl|gnutls} to accept path names
This patch fixes --with-openssl and --with-gnutls and enables both to
accept path names, so that you can use "./configure --with-XXX=/path".
All the other --with-XXX parameters support this already.
2009-09-02 14:28:09 +02:00
Florian Westphal
cf7e19193b do not add default listening port if ssl ports were specified
Cosmo Kastemaa reported that its impossible to create an ssl-only setup,
as ngircd binds to port 6667 by default, even if setting "Ports =".

Only add the default port if _both_ "Ports" and "SSLPorts" are
unspecified.

Fixes bugzilla #98.
2009-08-31 22:08:35 +02:00
Alexander Barton
5f1e43416a Fix LSB header of Debian init script 2009-08-29 23:57:39 +02:00
Alexander Barton
5debe20509 Use AM_SILENT_RULES([yes]), if available
Starting with GNU automake 1.11 "AM_SILENT_RULES([yes])" is available to
make the build process less verbose ("Linux 2.6 style") which helps to
spot warning and error messages.

So we use it if it is available.
2009-08-16 16:08:21 +02:00
Alexander Barton
a7eef6666b Update NEWS and ChangeLog for next release 2009-08-12 14:48:33 +02:00
Alexander Barton
56a8abc253 Updated doc/Platforms.txt 2009-08-04 22:53:38 +02:00
Alexander Barton
21bb2bd658 New script contrib/platformtest.sh
This script analyzes the build process of ngIRCd and generates output
suitable for inclusion in doc/Platforms.txt.
2009-08-04 22:30:59 +02:00
Florian Westphal
bddfd67550 doc/Platforms.txt: ngircd builds on hppa2.0w-hp-hpux11.11 target
Goetz Hoffart reports successful compile on HPUX/HPPA (on ngircd mailing list):

             Target: hppa2.0w-hp-hpux11.11
           Compiler: gcc
     Compiler flags: -g -O2 -pipe -W -Wall -Wpointer-arith -Wstrict-prototypes -fstack-protector -D_XOPEN_SOURCE_EXTENDED
-DSYSCONFDIR='"$(sysconfdir)"'
          Libraries: -lz -lnsl

     Syslog support: yes     Enable debug code: no
   zlib compression: yes           IRC sniffer: no
   Use TCP Wrappers: no        Strict RFC mode: no
   Zeroconf support: no          IRC+ protocol: yes
      IDENT support: no            I/O backend: "poll()"
      IPv6 protocol: no            SSL support: no
2009-07-22 22:06:36 +02:00
Alexander Barton
805bf03490 Client_CheckID(): fix connection information
This patch fixes the following silly log messages:
'ID "XXX" already registered (on connection -1)!'

If the ID is already registered on a local connection, the local
connection ID is printed; and if the ID is connected via a remote
server, "via network" is displayed.
2009-07-17 16:16:04 +02:00
Alexander Barton
63cbc6cd42 Fix return code of Conf_EnableServer()
Conf_EnableServer() only reports success if all required variables,
including host name and port, are set for the specific server.
2009-07-17 14:55:30 +02:00
Florian Westphal
b3cacf86df AUTHORS: update my email address 2009-06-08 12:25:35 +02:00
Florian Westphal
0ef94edad7 add section and rfc number to comment about QUIT error 2009-06-05 01:39:33 +02:00
Florian Westphal
643ae1b48b enforce upper limit on maximum number of handled commands
reported on #ngircd: pasting lots of lines into a channel can kill off
many people on the channel if the read buffer is drained quickly enough
and the client-side TCP can't keep up with the incoming data.

This implements a throttling scheme:
- an irc client may send up to 3 commands per second before a one second
pause is enforced.
- an irc client may send up to 256 bytes per second before a one second
pause is enforced.

After discussion with Alexander Barton, server <-> server links are
treated specially: There is no artificial limit on the number of bytes
sent per second, and up to 10 commands are processed per second before
a pause is enforced.

It may be neccessary to make those limits tuneable to accomondate larger
networks, but for now they are compile time values.
2009-05-25 22:25:18 +02:00
Florian Westphal
9b1c47220f conn.c: fix NumConnections imbalance
New_Server() can call Conn_Close() in its error paths,
but that function decrements the number of current active
connections. Thus we need to increment it earlier.
2009-05-17 21:32:53 +02:00
Florian Westphal
8e2c5816ee SSL/TLS: fix error handling when ssl ctx init for outgoing server link fails 2009-05-17 21:27:27 +02:00
Florian Westphal
f31c3a3aa2 SSL/TLS: fix error path in gnutls ssl ctx allocation 2009-05-17 21:18:04 +02:00
Florian Westphal
b0931f322b manpage: move SSLConnect option to the right section 2009-05-17 01:22:18 +02:00
Florian Westphal
5196e9bcb1 SSL/TLS: remove redundant asserts/ifdefs 2009-05-16 20:48:43 +02:00
Florian Westphal
57aa64e117 SSL/TLS: proper indentation, remove erroneous comment 2009-05-14 00:00:55 +02:00
Alexander Barton
fd7e85b798 Update copyright notice, it's 2009 already! 2009-05-05 17:08:48 +02:00
Alexander Barton
b1852f3029 Updated Debian "changelog" file for ngIRCd 14.1 2009-05-05 13:14:23 +02:00
Alexander Barton
822c1e9265 ngIRCd release 14.1 2009-05-05 12:58:51 +02:00
Alexander Barton
5b4a3eda08 Added start/stop script for Red Hat based distributions
Script contributed by Naoya Nakazawa <naoya@sanow.net>.
2009-05-05 12:50:55 +02:00
Alexander Barton
a83554b572 Renamed contrib/ngircd.sh to contrib/ngircd-bsd.sh 2009-05-05 11:41:26 +02:00
Florian Westphal
627b0b713c security: fix remotely triggerable crash in SSL/TLS code
When a server is running with SSL/TLS support compiled in,
it is trivial to crash the server by sending an MOTD request
via another server in the network.

- ONLY servers without ssl/tls support compiled in are not affected.
  Disabling SSL in the configuration (no ssl listening ports, etc)
  does NOT help.
- servers that are running standalone (i.e., not connected to any
  other servers) are not affected, either.

This affects all ngircd releases since ngircd 13 (earlier versions
have no SSL/TLS support).
2009-05-05 10:21:20 +02:00
Alexander Barton
95428a72ff Fixed "Conflicts:" line in debian/control: missing comma 2009-05-04 11:23:19 +02:00
Alexander Barton
6b83d1740e Debian: build ngircd-full-dbg package
In addition to the "ngircd" and "ngircd-full" packages a new package named
"ngircd-full-dbg" is build: this package contains all the features of the
"full" package but includes debug code and both the --debug and --sniffer
options and the resulting binaries are _not_ stripped.
2009-04-29 02:14:17 +02:00
Alexander Barton
c8bba8e5c3 debian/rules: whitespace fixes 2009-04-29 02:12:56 +02:00
Tassilo Schweyer
37359799eb Fix server list announcement
When ngircd announces the list of currently known servers
to a new (connecting) server, it sent the introducer of
the servers instead of the top server.

Assuming this network:

irc1.example.com
|--irc2.example.com
|    `--irc3.example.com
|         `--irc4.example.com
`--irc5.example.com

When irc4 connects to irc3, irc3 tells irc4 that irc5 was
connected to irc2. (irc2 had introduced irc5 to irc3; but thats
not what ngircd should have sent to the new server).

This also placed users on the wrong servers.
2009-04-26 00:30:49 +02:00
Alexander Barton
4a14fb252d Doxygen: update source code repository link to GIT 2009-04-25 00:53:47 +02:00
David Kingston
9b59f043c8 allow ping timeout quit messages to show the timeout value 2009-04-23 21:39:45 +02:00
Florian Westphal
b545d38ae4 irc-server: do not remove hostnames from info text
that code does not really make sense -- the info
text is freely cofngiureable and des not follow a specific
format.

Also, that "+2" might have caused invalid memory accesses.
2009-04-22 23:15:17 +02:00
Florian Westphal
84eaed6c9a conn-zip: fix error handling
callers of (Un)Zip_Buffer() assume that
the function closes the connection on error.

However, this was not always the case.
2009-04-21 21:00:43 +02:00
Florian Westphal
544b9884f4 remove or translate old comments 2009-04-21 20:58:30 +02:00
Florian Westphal
5e16b6df2d client.c: remove unecessary comments 2009-04-21 20:58:28 +02:00
Florian Westphal
ea041b8838 add const qualifier to pointers where possible 2009-04-21 20:58:23 +02:00
Alexander Barton
68835a1d1a ngIRCd release 14 2009-04-20 11:36:27 +02:00
Alexander Barton
54879b432b Display IPv6 addresses as "[<addr>]" when accepting connections.
With this patch ngIRCd displays IPv6 addresses as "[<addr>]:<port>" when
accepting new connections and later, if no successful DNS lookup could
be made (or DNS is disabled altogether).
2009-04-10 13:22:03 +02:00
Alexander Barton
d9355d53f8 Xcode: #define include __DATE__ in VERSION
Change VERSION to include the __DATE__ when compiling from within Xcode.

When building using "make xcode" or "make osxpkg" VERSION already is defined
to the "real" version number set in configure.in.
2009-04-10 13:08:04 +02:00
Alexander Barton
8c0137a6e0 Fix ChangeLog: Local channels are already implemented in Release 13 2009-04-09 15:17:44 +02:00
Alexander Barton
166ab3925e Fix up last Debian changelog entry 2009-03-30 13:44:04 +02:00
Alexander Barton
1f6a5744f6 ngIRCd release 14~rc1 2009-03-29 17:16:02 +02:00
Alexander Barton
156569d263 Updated NEWS and ChangeLog files 2009-03-29 17:05:37 +02:00
Alexander Barton
c3a8d6a73e Updated Debian/Linux init script
- PidFile, ServerUID and ServerGID are read from actual server configuration
- Exit code and behaviour is more LSB compliant
- New "status" and "test" sub-functions
2009-03-29 16:37:06 +02:00
Dana Dahlstrom
3a7d59c1ac misspelling in ERR_NORECIPIENT reply 2009-03-25 20:44:40 +01:00
Alexander Barton
51b88b12f3 Add missing contributors to AUTHORS file 2009-03-11 11:51:59 +01:00
Florian Westphal
ea35ba74b6 testsuite: add more predefined channels to server config
make sure it creates & and +, and accepts channel names without
a special character (ngircd should treat
'Name = chan' as 'Name = #chan').
2009-03-07 00:30:11 +01:00
Florian Westphal
2d4361d088 allow creation of persistent modeless channels 2009-03-07 00:21:43 +01:00
Florian Westphal
e9e7fc33f1 add and use Channel_IsModeless()
avoid "name[0] == '+'" where possible, having Channel_IsModeless()
makes things much more obvious.
2009-03-07 00:13:25 +01:00
Alexander Barton
c09742c518 Enhance INFO command to report compile time, if available 2009-03-05 16:04:36 +01:00
Alexander Barton
c56ab96270 Update NEWS and ChangeLog files 2009-03-03 17:59:43 +01:00
Alexander Barton
0a9608a26f Channel mode changes: break on error
Don't echo multiple syntax error messages (461) on invalid commands,
but break after the first one.
In addition, this solves corrupted 'Unknown mode "+' messages.
2009-03-03 16:33:40 +01:00
Alexander Barton
dee89c2355 Channel_Mode(): code cleanup (no functional changes) 2009-03-03 15:06:34 +01:00
Florian Westphal
b8c6dd503f TLS/SSL: remove useless error message when ssl connection is closed
When using OpenSSL, the following annoying "error" message was logged whenever
an encrypted connection was shut down in a orderly fashion:
TLS/SSL Connection shutdown: ConnSSL_Read: Unable to determine error

of course, this isn't an error at all.
2009-02-05 23:47:28 +01:00
Florian Westphal
66d6c3c84b update ChangeLog. 2009-02-04 23:33:46 +01:00
Florian Westphal
2fce4667a8 SSL/TLS: clear all ssl realted flags on shutdown
one ssl related flags was not cleared on ssl shutdown.
introduce and use CONN_SSL_FLAGS_ALL to zap them all.
2009-02-04 23:23:12 +01:00
Florian Westphal
c6a43fbaf0 TLS/SSL: fix memory leak when using compressed server links with ssl
commit 6bc2d3d06e
(New connection option CONN_RFC1459) forgot to adjust the ssl bitmasks.

The result is that when a compressed AND encrypted server link goes down
the memory allocated by zlib and the r/w buffers are no longer
free'd as the previous ConnSSL_Free() would then also remove the CONN_ZIP flag
from the flag mask.
2009-02-04 23:01:53 +01:00
Alexander Barton
3be9c477be Fix spelling of log message: "channek" vs. "channel" ... 2009-01-20 17:20:30 +01:00
Alexander Barton
d09094812f Channel key file: store file name and open on each access.
Store the file name of channel key files and reopen them on each access
(on each JOIN command) insted of just storing the file handles.

This eliminates the special requirements (no delete) and makes sure
that always the actual file contents are used in all circumstances.
2009-01-20 17:20:30 +01:00
Alexander Barton
c5000694d1 Support individual channel keys for pre-defined channels.
This patch introduces the new configuration variable "KeyFile" for
[Channel] sections in ngircd.conf. Here a file can be configured for each
pre-defined channel which contains individual channel keys for different
users. This file is line-based and must have the following syntax:

  <user>:<nick>:<key>

<user> and <nick> can contain the wildcard character "*".

Please not that these channel keys are only in effect, when the channel
has a regular key set using channel mode "k"!
2009-01-20 17:20:30 +01:00
Alexander Barton
2c1b6280fa RFC 2812, sec. 3.3.1: really check for the last dot
This fixes commit 5a3128243f and makes the test suite ("make check")
run again without errors.
2009-01-20 16:49:34 +01:00
Florian Westphal
5a3128243f irc.c: reject masks with wildcard after last dot
RFC 2812 says in section 3.3.1 ("Private Messages"):

The mask MUST have at least 1 (one) "." in it and no wildcards
following the last ".".
2009-01-18 00:36:38 +01:00
Florian Westphal
95e8320ca9 irc.c: Fix handling of channels containing dots
commit 2546a13ad2
('Cumulative Message Patch') broke PRIVMSG to channels
containing dots.

Fix this by switching evaluation order:
Check first if the target matches a existing channel and only do a check
for target masks if that failed.

PRIVMSG with host/server masks is described in RFC 2812, section 3.3.1.

Makes one wonder how a server is _really_ supposed to tell the difference
between hostmasks and channel names.

Sigh.
2009-01-18 00:20:38 +01:00
Ask Bjørn Hansen
8f46681bc8 Update ngircd.spec file
- Change Copyright to License
- Update URL
- Make BuildRoot use %{_tmppath} macro
- Add basic BuildRequires
- Compile with zlib and openssl
- Install all docs in standard document location

Signed-off-by: Ask Bjørn Hansen <ask@develooper.com>
2009-01-13 11:01:09 +01:00
Florian Westphal
1c7b9dbe93 remove unneeded LOG_DEBUG when not compiling with DEBUG support
when ngircd is build without DEBUG enabled, LOG_DEBUG messages
are always discarded.

To avoid the extra code, ngircd has a LogDebug() wrapper which
gets removed by the compiler when compiling without DEBUG defined.

Update a few functings which were using the
Log(LOG_DEBUG, .. interface directly without #ifdef DEBUG guards.

   text	   data	    bss	    dec	    hex	filename
 127748	   1900	  28280	 157928	  268e8	ngircd.before
 126836	   1896	  28280	 157012	  26554	ngircd.after
2009-01-10 00:54:07 +01:00
Florian Westphal
0acef7c598 documentation: gnutls does not support password-protected privkeys
already mentioned in man page and sample config file, but for
completeness also document it in doc/SSL.txt.
2009-01-09 21:33:19 +01:00
Alexander Barton
00c8dfa8be Mac OS X: update texts for Mac OS X Installer.app 2009-01-06 17:40:25 +01:00
Alexander Barton
75243ffb37 Xcode: build ngIRCd with IPv6 support on Mac OS X 2009-01-06 17:39:11 +01:00
Alexander Barton
5468ba3744 Xcode: get release number dynamically; new make target "xcode-clean".
- make target "xcode" now detects the release number stored in the
  configure.in file and passes it to Xcode.
- new make target "xcode-clean" which removes all files generated by
  "make xcode" and removes the Xcode build directory.
2009-01-06 16:02:27 +01:00
Alexander Barton
eb159e0a8d Xcode: define TARGET_VENDOR and TARGET_OS 2009-01-06 16:00:15 +01:00
Alexander Barton
df3473c9c1 Add new and missing files to Mac OS X Xcode project 2009-01-06 15:09:39 +01:00
Alexander Barton
a11e895045 Rename Channel_Free() to Free_Channel(), it is a local function 2009-01-05 13:53:33 +01:00
Alexander Barton
175f0af979 Clean up channel allocation table on shutdown/restart.
Silly bug: the condition of a while() loop in the Channel_Exit() function
used the wrong variable and therefore got never executed ...

This bug is in the code since the beginning (see commit bb19cfda in 2002);
shame on me!
2009-01-05 12:58:37 +01:00
Florian Westphal
40a0e9abbe Add Channel_Free().
Central function to free a channel structure and all its resources
(invite/ban lists, topic, ...).
2009-01-05 12:48:48 +01:00
Alexander Barton
0659503afd Clean up (reformat and comment) Delete_Channel() function. 2009-01-04 15:25:07 +01:00
Alexander Barton
18efc7469c Free topic array on channel deletion.
The topic array in the CHANNEL structure must be free()'d before the
channel itself becomes deleted.
2009-01-04 15:22:32 +01:00
Alexander Barton
fd9266df78 Fix spelling in some documents. 2009-01-01 17:56:42 +01:00
Alexander Barton
0e4e22a7a6 Allow pre-defined server local channels ("&"). 2008-12-30 19:23:03 +01:00
Alexander Barton
9d20397470 Spell check and enhance ngIRCd manual pages. 2008-12-30 19:20:09 +01:00
Florian Westphal
307cdce908 man ngircd.conf: line break missing before the SSLConnect description
reported by Christoph Biedl.
2008-12-29 23:34:20 +01:00
Florian Westphal
dc9f42dc3c defines.h: remove MAX_LISTEN_PORTS, MAX_SERVICES
_SERVICES was never used; _LISTEN_PORTS is a leftover from
commit 51ccb5928a
('internal changes needed for future ssl support').
2008-12-27 23:51:52 +01:00
Florian Westphal
a971047bc5 Remove limit on max number of predefined channels.
This resolves Bugzilla Bug 68 ('Too many pre-defined channels configured.')
2008-12-26 01:07:56 +01:00
Florian Westphal
6500d443fc channel.c: constify a few function arguments. 2008-12-26 01:07:52 +01:00
Florian Westphal
d26a283ea9 use %ld as format specifier for posix data types
in the same vein as the earlier commit:
cast posix data types (pid_t, ...) to long and use
%ld as format specifier. This will avoid problems
when sizeof(int) != sizeof(type).

We could also cast to int, but this might truncate the value.
2008-12-26 01:07:13 +01:00
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
95 changed files with 5267 additions and 2146 deletions

4
.mailmap Normal file
View File

@@ -0,0 +1,4 @@
# mailmap file for git-[short]log and git-blame
Alexander Barton <anonymous>
Ali Shemiran <ashemira@ucsd.edu>

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2007 Alexander Barton,
(c)2001-2009 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -19,12 +19,13 @@ directly, if possible!
Main Authors
~~~~~~~~~~~~
Alexander Barton, <alex@barton.de> (alex)
Florian Westphal, <westphal@foo.fh-furtwangen.de> (fw)
Florian Westphal, <fw@strlen.de>
Contributors
~~~~~~~~~~~~
Ali Shemiran, <ashemira@ucsd.edu>
Ask Bjørn Hansen, <ask@develooper.com>
Benjamin Pineau, <ben@zouh.org>
Brandon Beresini, <beresini@google.com>
Bryan Caldwell, <bcaldwel@ucsd.edu>
@@ -32,6 +33,7 @@ Dana Dahlstrom, <dana+ngIRCd@cs.ucsd.edu>
Eric Grunow, <egrunow@ucsd.edu>
Goetz Hoffart, <goetz@hoffart.de>
Ilja Osthoff, <i.osthoff@gmx.net>
Jari Aalto, <jari.aalto@cante.net>
Rolf Eike Beer, <eike@sf-mail.de>
Scott Perry, <scperry@ucsd.edu>
Sean Reifschneider, <jafo-rpms@tummy.com>

181
ChangeLog
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2008 Alexander Barton,
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -10,11 +10,170 @@
-- ChangeLog --
ngIRCd Release 13
ngIRCd Release 17
ngIRCd 17~rc1 (2010-10-11)
- New configuration option "NoZeroConf" to disable service registration at
runtime even if ngIRCd is compiled with support for ZeroConf (e.g. using
Howl, Avahi or on Mac OS X).
- New configuration option "SyslogFacility" to define the syslog "facility"
(the "target"), to which ngIRCd should send its log messages.
Possible values are system dependant, but most probably "auth", "daemon",
"user" and "local1" through "local7" are possible values; see syslog(3).
Default is "local5" for historical reasons.
- Dump the "internal server state" (configured servers, established
connections and known clients) to the console or syslog when receiving
the SIGUSR2 signal and debug mode is enabled.
- Enable the daemon to disable and enable "debug mode" on runtime using
signal SIGUSR1, when debug code is compiled in, not only on startup
using the command line parameters.
- Signal handler: added new 'delayed' signal handlers, including fallback
to deprecated sysv API. And removed global NGIRCd_SignalRehash variable.
- IO: add io_cloexec() to set close-on-exec flag.
- ng_ipaddr.h: include required assert.h header.
- Conn_SyncServerStruct(): test all connections; and work case insensitive
- configure script: correctly indent IPv6 yes/no summary output.
- Don't reset My_Connections[Idx].lastping when reading data, so the
client lag debug-output is working again.
- Implement user mode "x": hostname cloaking (closes: #102).
- Make configure switch "--docdir" work (closes: #108).
- Reformat and update FAQ.txt a little bit.
- INSTALL: mention SSL, IPv6, and changed handling of MotdFile.
- Change MOTD file handling: ngIRCd now caches the contens of the MOTD
file, so the daemon now requires a HUP signal or REHASH command to
re-read the MOTD file when its content changed.
- Startup: open /dev/null before chroot'ing the daemon.
- Allow IRC ops to change channel modes even without OperServerMode set.
- Allow IRC operators to use MODE command on any channel (closes: #100).
- Added mailmap file for git-[short]log and git-blame.
- Authenticated users should be registered without the "~" mark.
- Set NoPAM=yes in configuration files used for the testsuite.
- New configuration option "NoPAM" to disable PAM.
- Implement asynchronous user authentication using PAM, please see the
file doc/PAM.txt for details.
- Resolver: Implement signal handler and catch TERM signals.
- Don't set a penalty time when doing DNS lookups.
- Add some documentation for using BOPM with ngIRCd, see doc/Bopm.txt.
- Implement user mode "c": receive connect/disconnect NOTICEs. Note that
this new mode requires the user to be an IRC operator.
- ngircd.init: require "$network" and "$remote_fs" when stopping ngircd.
- Show SSL status in WHOIS output, numeric 275.
- Include correct header files when testing for arpa/inet.h (Closes: #105).
- Don't access already freed memory in IRC_KILL().
- Fix "beeing" typo ...
- SSL/TLS: fix bogus "socket closed" error message.
ngIRCd Release 16 (2010-05-02)
- doc/SSL: remove line continuation marker
ngIRCd 16~rc2 (2010-04-25)
- Updated some more copyright notices, it's 2010 already :-)
- Only compile in Get_Error() if really needed
- Fix gcc warning "ignoring return value of ..."
- Include netinet/in_systm.h alongside netinet/ip.h
- Include netinet/{in.h, in_systm.h} when checking for netinet/ip.h
- Only include <netinet/in_systm.h> if it exists
- Updated doc/Platforms.txt
- Enhace connection statistics counters: display total number of served
connections on daemon shutdown and when a new client connects using
the new numeric RPL_STATSCONN (250).
ngIRCd 16~rc1 (2010-03-25)
- Various fixes to the build system and code cleanups.
- contrib/platformtest.sh: Only show latest commit.
- Updatet doc/Platforms.txt, added new README-Interix.txt documenting
how to tun ngIRCd on Microsoft Services for UNIX (MS SFU, MS SUA).
- Updated links to the ngIRCd homepage (bug tracker, mailing list).
- Added missing modes to USERMODES #define
- Show our name (IRCD=ngIRCd) in ISUPPORT (005) numeric
- Quote received messages of ERROR commands in log output.
- ngircd.conf manual page: document missing "Password" variable.
- Implement WEBIRC command used by some Web-IRC frontends. The password
required to secure this command must be configured using the new
"WebircPassword" variable in the ngircd.conf file.
- Don't use port 6668 as example for both "Ports" and "SSLPorts".
- Remove limit on max number of configured irc operators.
- Only link "nsl" library when really needed.
- A new channel mode "secure connections only" (+z) has been implemented:
Only clients using a SSL encrypted connection to the server are allowed
to join such a channel.
But please note three things: a) already joined clients are not checked
when setting this mode, b) IRC operators are always allowed to join
every channel, and c) remote clients using a server not supporting this
mode are not checked either and therefore always allowed to join.
ngIRCd Release 15 (2009-11-07)
- "ngircd --configtest": print SSL configuration options even when unset.
ngIRCd 15~rc1 (2009-10-15)
- Do not add default listening port (6667) if SSL ports were specified, so
ngIRCd can be configured to only accept SSL-encrypted connections now.
- Enable IRC operators to use the IRC command SQUIT (insted of the already
implemented but non-standard DISCONNECT command).
- New configuration option "AllowRemoteOper" (disabled by default) that
enables remote IRC operators to use the IRC commands SQUIT and CONNECT
on the local server.
- Mac OS X: fix test for packagemaker(1) tool in Makefile and use gcc 4.0
for Mac OS X 10.4 compatibility in the Xcode project file.
- Fix --with-{openssl|gnutls} to accept path names.
- Fix LSB header of Debian init script.
- Updated doc/Platforms.txt and include new script contrib/platformtest.sh
to ease generating platform reports.
- Fix connection information for already registered connections.
- Enforce upper limit on maximum number of handled commands. This implements
a throttling scheme: an IRC client can send up to 3 commands or 256 bytes
per second before a one second pause is enforced.
- Fix connection counter.
- Fix a few error handling glitches for SSL/TLS connections.
- Minor fixes to manual pages and documentation.
ngIRCd Release 14.1 (2009-05-05)
- Security: fix remotely triggerable crash in SSL/TLS code.
- BSD start script contrib/ngircd.sh has been renamed to ngircd-bsd.sh.
- New start/stop script for RedHat-based distributions:
contrib/ngircd-redhat.init, thanks to Naoya Nakazawa <naoya@sanow.net>.
- Doxygen: update source code repository link to GIT.
- Debian: build ngircd-full-dbg package.
- Allow ping timeout quit messages to show the timeout value.
- Fix error handling on compressed links.
- Fix server list announcement.
- Do not remove hostnames from info text.
ngIRCd Release 14 (2009-04-20)
- Display IPv6 addresses as "[<addr>]" when accepting connections.
ngIRCd 14~rc1 (2009-03-29)
- Updated Debian/Linux init script (see contrib/Debian/ngircd.init).
- Allow creation of persistent modeless channels.
- The INFO command reports the compile time now (if available).
- Spell check and enhance ngIRCd manual pages.
- Channel mode changes: break on syntax errors in MODE command.
- Support individual channel keys for pre-defined channels: introduce
new configuration variable "KeyFile" in [Channel] sections in ngircd.conf,
here a file can be configured for each pre-defined channel which contains
individual channel keys for different users.
- Remove limit on maximum number of predefined channels in ngircd.conf.
- Updated ngircd.spec file for building RPM packages.
- Add new and missing files to Mac OS X Xcode project, and update project.
- Reject masks with wildcard after last dot.
- TLS/SSL: remove useless error message when ssl connection is closed.
- Fix memory leak when a encrypted and compressed server link goes down.
(closes bug #95, reported by Christoph, fiesh@fiesh.homeip.net)
- Fix handling of channels containing dots.
(closes ug #93, reported by Gonosz Csiga)
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,
- New version number scheme :-)
- Initial support for IRC services, using a RFC1459 style 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.
@@ -46,7 +205,7 @@ ngIRCd 0.12.1 (2008-07-09)
- 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
- Make Listen parameter a comma-separated 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,
@@ -56,11 +215,11 @@ 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.
- Fix compile 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.
- IPv6: Add config options to disable 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.
@@ -103,11 +262,11 @@ ngIRCd 0.11.0 (2008-01-15)
- 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.
the source IP address 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).
enable server to recognize 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
@@ -436,7 +595,7 @@ ngIRCd 0.7.0 (2003-05-01)
- Better error reporting to clients on connect.
- Enhanced manual pages ngircd(8) and ngircd.conf(5).
- Documentation is now installed in $(datadir)/doc/ngircd.
- Enhanced hanling of NJOIN in case of nick collisions.
- Enhanced handling of NJOIN in case of nick collisions.
ngIRCd 0.6.1, 2003-01-21

26
INSTALL
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2007 Alexander Barton,
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -9,11 +9,15 @@
-- INSTALL --
I. Upgrade Information
~~~~~~~~~~~~~~~~~~~~~~
Differences to version 16
- Changes to the "MotdFile" specified in ngircd.conf now require a ngircd
configuration reload to take effect (HUP signal, REHASH command).
Differences to version 0.9.x
- The option of the configure script to enable support for Zeroconf/Bonjour/
@@ -184,6 +188,24 @@ standard locations.
to the daemon, for example by using "/etc/hosts.{allow|deny}".
The "libwrap" is required for this option.
* PAM:
--with-pam[=<path>]
Enable support for PAM, the Pluggable Authentication Modules library.
See doc/PAM.txt for details.
* SSL:
--with-openssl[=<path>]
--with-gnutls[=<path>]
Enable support for SSL/TLS using OpenSSL or gnutls libraries.
See doc/SSL.txt for details.
* IPv6:
--enable-ipv6
Adds support for version 6 of the Internet Protocol.
IV. Useful make-targets
~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -32,12 +32,21 @@ lint:
srcdoc:
make -C doc srcdoc
xcode:
have-xcodebuild:
@xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -list \
>/dev/null 2>&1 \
|| ( echo; echo "Error: \"xcodebuild\" not found!"; echo; exit 1 )
xcode: have-xcodebuild
rel=`grep AC_INIT configure.in | cut -d' ' -f2 | cut -d')' -f1`; \
def="GCC_PREPROCESSOR_DEFINITIONS=\"VERSION=\\\"$$rel\\\"\""; \
xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -alltargets \
-configuration Default $$def build
xcode-clean: have-xcodebuild
xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -alltargets \
-buildstyle Development
-configuration Default clean
rm -fr contrib/MacOSX/build
rpm: distcheck
rpm -ta ngircd-*.tar.gz
@@ -46,8 +55,8 @@ deb:
[ -f debian/rules ] || ln -s contrib/Debian debian
dpkg-buildpackage -rfakeroot -i
osxpkg:
@packagemaker >/dev/null 2>&1; [ $$? -ge 1 ] \
osxpkg: have-xcodebuild
@packagemaker >/dev/null 2>&1; [ $$? -le 1 ] \
|| ( echo; echo "Error: \"packagemaker\" not found!"; echo; exit 2)
make clean
./configure --prefix=/opt/ngircd

96
NEWS
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2008 Alexander Barton,
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -10,11 +10,93 @@
-- NEWS --
ngIRCd Release 13
ngIRCd Release 17
ngIRCd 17~rc1 (2010-10-11)
- New configuration option "NoZeroConf" to disable service registration at
runtime even if ngIRCd is compiled with support for ZeroConf (e.g. using
Howl, Avahi or on Mac OS X).
- New configuration option "SyslogFacility" to define the syslog "facility"
(the "target"), to which ngIRCd should send its log messages.
Possible values are system dependant, but most probably "auth", "daemon",
"user" and "local1" through "local7" are possible values; see syslog(3).
Default is "local5" for historical reasons.
- Dump the "internal server state" (configured servers, established
connections and known clients) to the console or syslog when receiving
the SIGUSR2 signal and debug mode is enabled.
- Enable the daemon to disable and enable "debug mode" on runtime using
signal SIGUSR1, when debug code is compiled in, not only on startup
using the command line parameters.
- Implement user mode "x": hostname cloaking (closes: #102).
- Change MOTD file handling: ngIRCd now caches the contens of the MOTD
file, so the daemon now requires a HUP signal or REHASH command to
re-read the MOTD file when its content changed.
- Allow IRC ops to change channel modes even without OperServerMode set.
- Allow IRC operators to use MODE command on any channel (closes: #100).
- New configuration option "NoPAM" to disable PAM.
- Implement asynchronous user authentication using PAM, please see the
file doc/PAM.txt for details.
- Add some documentation for using BOPM with ngIRCd, see doc/Bopm.txt.
- Implement user mode "c": receive connect/disconnect NOTICEs. Note that
this new mode requires the user to be an IRC operator.
- Show SSL status in WHOIS output, numeric 275.
ngIRCd Release 16 (2010-05-02)
ngIRCd 16~rc2 (2010-04-25)
- Enhace connection statistics counters: display total number of served
connections on daemon shutdown and when a new client connects using
the new numeric RPL_STATSCONN (250).
ngIRCd 16~rc1 (2010-03-25)
- Implement WEBIRC command used by some Web-IRC frontends. The password
required to secure this command must be configured using the new
"WebircPassword" variable in the ngircd.conf file.
- Remove limit on max number of configured irc operators.
- A new channel mode "secure connections only" (+z) has been implemented:
Only clients using a SSL encrypted connection to the server are allowed
to join such a channel.
But please note three things: a) already joined clients are not checked
when setting this mode, b) IRC operators are always allowed to join
every channel, and c) remote clients using a server not supporting this
mode are not checked either and therefore always allowed to join.
ngIRCd Release 15 (2009-11-07)
ngIRCd 15~rc1 (2009-10-15)
- Do not add default listening port (6667) if SSL ports were specified, so
ngIRCd can be configured to only accept SSL-encrypted connections now.
- Enable IRC operators to use the IRC command SQUIT (insted of the already
implemented but non-standard DISCONNECT command).
- New configuration option "AllowRemoteOper" (disabled by default) that
enables remote IRC operators to use the IRC commands SQUIT and CONNECT
on the local server.
- Enforce upper limit on maximum number of handled commands. This implements
a throttling scheme: an IRC client can send up to 3 commands or 256 bytes
per second before a one second pause is enforced.
ngIRCd Release 14.1 (2009-05-05)
- Security: fix remotely triggerable crash in SSL/TLS code.
- Debian: build ngircd-full-dbg package.
- Allow ping timeout quit messages to show the timeout value.
ngIRCd Release 14 (2009-04-20)
ngIRCd 14~rc1 (2009-03-29)
- Allow creation of persistent modeless channels.
- The INFO command reports the compile time now (if available).
- Support individual channel keys for pre-defined channels: introduce
new configuration variable "KeyFile" in [Channel] sections in ngircd.conf,
here a file can be configured for each pre-defined channel which contains
individual channel keys for different users.
- Remove limit on maximum number of predefined channels in ngircd.conf.
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,
- New version number scheme :-)
- Initial support for IRC services, using a RFC1459 style 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.
@@ -33,7 +115,7 @@ ngIRCd Release 13
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
- Make Listen parameter a comma-separated 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,
@@ -42,7 +124,7 @@ ngIRCd 0.12.1 (2008-07-09)
ngIRCd 0.12.0 (2008-05-13)
ngIRCd 0.12.0-pre2 (2008-04-29)
- IPv6: Add config options to disabe ipv4/ipv6 support.
- IPv6: Add config options to disable ipv4/ipv6 support.
ngIRCd 0.12.0-pre1 (2008-04-20)
- Add IPv6 support.
@@ -61,7 +143,7 @@ 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.
the source IP address 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).

4
README
View File

@@ -78,10 +78,10 @@ VI. Bugs
If you find bugs in the ngIRCd (which might be there :-), please report
them at the following URL:
<http://ngircd.barton.de/#bugs>
<http://ngircd.barton.de/bugtracker.php>
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 the ngIRCd mailing list: <ngircd-ml@arthur.ath.cx> (please see
<http://ngircd.barton.de/#ml> for details).
<http://ngircd.barton.de/support.php#ml> for details).

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
# Copyright (c)2001-2010 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
@@ -12,12 +12,14 @@
# -- Initialisation --
AC_PREREQ(2.50)
AC_INIT(ngircd, 13~rc1)
AC_INIT(ngircd, 17~rc1)
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE(1.6)
AM_CONFIG_HEADER(src/config.h)
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# -- Templates for config.h --
AH_TEMPLATE([DEBUG], [Define if debug-mode should be enabled])
@@ -31,6 +33,8 @@ 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])
AH_TEMPLATE([PAM], [Define if PAM should be used])
AH_TEMPLATE([HAVE_sockaddr_in_len], [Define if sockaddr_in.sin_len exists])
AH_TEMPLATE([TARGET_OS], [Target operating system name])
AH_TEMPLATE([TARGET_VENDOR], [Target system vendor])
@@ -71,7 +75,6 @@ AC_DEFUN([GCC_STACK_PROTECT_CC],[
fi
])
if test "$GCC" = "yes"; then
# We are using the GNU C compiler. Good!
CFLAGS="$CFLAGS -pipe -W -Wall -Wpointer-arith -Wstrict-prototypes"
@@ -99,11 +102,24 @@ AC_HEADER_TIME
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([ \
ctype.h errno.h fcntl.h netdb.h netinet/in.h stdlib.h string.h \
strings.h sys/socket.h sys/time.h unistd.h \
ctype.h errno.h fcntl.h netdb.h netinet/in.h netinet/in_systm.h \
stdlib.h string.h strings.h sys/socket.h sys/time.h unistd.h \
],,AC_MSG_ERROR([required C header missing!]))
AC_CHECK_HEADERS([arpa/inet.h ctype.h malloc.h stdbool.h stddef.h varargs.h])
AC_CHECK_HEADERS([ \
arpa/inet.h ctype.h malloc.h netinet/ip.h stdbool.h stddef.h varargs.h \
],[],[],[[
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
]]
)
# -- Datatypes --
@@ -123,12 +139,16 @@ AC_TRY_COMPILE([
AC_TYPE_SIGNAL
AC_TYPE_SIZE_T
AC_CHECK_MEMBER([struct sockaddr_in.sin_len], AC_DEFINE(HAVE_sockaddr_in_len),,
[#include <arpa/inet.h>])
# -- Libraries --
# A/UX needs this.
AC_CHECK_LIB(UTIL,memmove)
# needed on solaris. GNU libc also has a libnsl, but we do not need it.
AC_SEARCH_LIBS(gethostbyname,nsl)
AC_CHECK_LIB(socket,bind)
AC_CHECK_LIB(nsl,gethostent)
# -- Functions --
@@ -139,7 +159,8 @@ AC_CHECK_FUNCS([ \
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 strtok_r)
AC_CHECK_FUNCS(getaddrinfo getnameinfo inet_aton isdigit sigaction sigprocmask snprintf \
vsnprintf strdup strlcpy strlcat strtok_r)
# -- Configuration options --
@@ -313,7 +334,7 @@ fi
AC_ARG_WITH(openssl,
[ --with-openssl enable SSL support using OpenSSL],
[ if test "$withval" = "yes"; then
[ if test "$withval" != "no"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
@@ -330,7 +351,7 @@ AC_ARG_WITH(openssl,
AC_ARG_WITH(gnutls,
[ --with-gnutls enable SSL support using gnutls],
[ if test "$withval" = "yes"; then
[ if test "$withval" != "no"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
@@ -459,6 +480,33 @@ if test "$x_identauth_on" = "yes"; then
AC_CHECK_HEADERS(ident.h,,AC_MSG_ERROR([required C header missing!]))
fi
# compile in PAM support?
x_pam_on=no
AC_ARG_WITH(pam,
[ --with-pam enable user authentication using PAM],
[ 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_LIB(pam, pam_authenticate)
AC_CHECK_FUNCS(pam_authenticate, x_pam_on=yes,
AC_MSG_ERROR([Can't enable PAM support!])
)
fi
]
)
if test "$x_pam_on" = "yes"; then
AC_DEFINE(PAM, 1)
AC_CHECK_HEADERS(security/pam_appl.h,pam_ok=yes)
if test "$pam_ok" != "yes"; then
AC_CHECK_HEADERS(pam/pam_appl.h,pam_ok=yes,
AC_MSG_ERROR([required C header missing!]))
fi
fi
# compile in IRC+ protocol support?
x_ircplus_on=yes
@@ -477,6 +525,8 @@ AC_ARG_ENABLE(ipv6,
if test "$enableval" = "yes"; then x_ipv6_on=yes; fi
)
if test "$x_ipv6_on" = "yes"; then
# getaddrinfo() and getnameinfo() are optional when not compiling
# with IPv6 support, but are required for IPv6 to work!
AC_CHECK_FUNCS([ \
getaddrinfo getnameinfo \
],,AC_MSG_ERROR([required function missing for IPv6 support!]))
@@ -566,7 +616,7 @@ B=`eval echo ${bindir}` ; B=`eval echo ${B}`
S=`eval echo ${sbindir}` ; S=`eval echo ${S}`
C=`eval echo ${sysconfdir}` ; C=`eval echo ${C}`
M=`eval echo ${mandir}` ; M=`eval echo ${M}`
D=`eval echo ${datadir}/doc/${PACKAGE}` ; D=`eval echo ${D}`
D=`eval echo ${docdir}` ; D=`eval echo ${D}`
echo " Target: ${target}"
test "$target" != "$host" && echo " Host: ${host}"
@@ -634,11 +684,17 @@ echo $ECHO_N " I/O backend: $ECHO_C"
echo "\"$x_io_backend\""
echo $ECHO_N " IPv6 protocol: $ECHO_C"
echo $ECHO_N "$x_ipv6_on $ECHO_C"
test "$x_ipv6_on" = "yes" \
&& echo $ECHO_N "yes $ECHO_C" \
|| echo $ECHO_N "no $ECHO_C"
echo $ECHO_N " SSL support: $ECHO_C"
echo "$x_ssl_lib"
echo $ECHO_N " PAM support: $ECHO_C"
test "$x_pam_on" = "yes" \
&& echo "yes" \
|| echo "no"
echo
# -eof-

View File

@@ -7,3 +7,7 @@ ngircd-full/
ngircd-full.default
ngircd-full.init
ngircd-full.postinst
ngircd-full-dbg/
ngircd-full-dbg.default
ngircd-full-dbg.init
ngircd-full-dbg.postinst

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
# Copyright (c)2001-2009 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
@@ -20,7 +20,10 @@ clean-local:
ngircd.prerm.debhelper ngircd.substvars
rm -f ngircd-full.postinst.debhelper ngircd-full.postrm.debhelper \
ngircd-full.prerm.debhelper ngircd-full.substvars
rm -rf ngircd ngircd-full
rm -f ngircd-full-dbg.postinst.debhelper \
ngircd-full-dbg.postrm.debhelper ngircd-full-dbg.prerm.debhelper \
ngircd-full-dbg.substvars
rm -rf ngircd ngircd-full ngircd-full-dbg
rm -f files
# -eof-

View File

@@ -1,3 +1,76 @@
ngircd (17~rc1-0ab1) unstable; urgency=low
* New "upstream" release candidate 1 for ngIRCd Release 17.
-- Alexander Barton <alex@barton.de> Mon, 11 Oct 2010 16:57:47 +0200
ngircd (16-0ab1) unstable; urgency=low
* New "upstream" release: ngIRCd 16.
-- Alexander Barton <alex@barton.de> Sun, 02 May 2010 13:32:41 +0200
ngircd (16~rc2-0ab1) unstable; urgency=low
* New "upstream" release candidate 2 for ngIRCd Release 16.
-- Alexander Barton <alex@barton.de> Sun, 25 Apr 2010 13:12:42 +0200
ngircd (16~rc1-0ab1) unstable; urgency=low
* New "upstream" release candidate 1 for ngIRCd Release 16.
-- Alexander Barton <alex@barton.de> Thu, 25 Mar 2010 15:56:03 +0200
ngircd (15-0ab1) unstable; urgency=low
* New "upstream" release: ngIRCd 15.
-- Alexander Barton <alex@barton.de> Thu, 7 Nov 2009 12:07:08 +0200
ngircd (15~rc1-0ab1) unstable; urgency=low
* New "upstream" release candidate 1 for ngIRCd Release 15.
-- Alexander Barton <alex@barton.de> Thu, 15 Oct 2009 10:01:08 +0200
ngircd (14.1-0ab1) unstable; urgency=high
* New "upstream" release ngIRCd 14.1, fixing a security-related bug.
-- Alexander Barton <alex@barton.de> Tue, 5 May 2009 13:13:38 +0200
ngircd (14-0ab3) unstable; urgency=low
* Fixed "Conflicts:" line in debian/control: missing comma.
-- Alexander Barton <alex@barton.de> Mon, 4 May 2009 11:21:55 +0200
ngircd (14-0ab2) unstable; urgency=low
* Add new "ngircd-full-dbg" package including degug code and both
the --debug and --sniffer options, and containing debug symbols.
-- Alexander Barton <alex@barton.de> Wed, 29 Apr 2009 01:13:03 +0200
ngircd (14-0ab1) unstable; urgency=low
* New "upstream" release: ngIRCd 14.
-- Alexander Barton <alex@barton.de> Mon, 20 Apr 2009 11:09:12 +0200
ngircd (14~rc1-0ab1) unstable; urgency=low
* New "upstream" release candidate 1 for ngIRCd Release 14.
-- Alexander Barton <alex@barton.de> Sun, 29 Mar 2009 17:09:17 +0200
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.

View File

@@ -32,7 +32,7 @@ Package: ngircd-full
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: ircd
Conflicts: ngircd
Conflicts: ngircd, ngircd-dbg
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
@@ -50,3 +50,29 @@ Description: A lightweight daemon for the Internet Relay Chat (IRC)
.
ngIRCd is compatible to the "original" ircd 2.10.3p3, so you can run
mixed networks.
Package: ngircd-full-dbg
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: ircd
Conflicts: ngircd, ngircd-full
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.
.
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.
.
And in addition to the "full" variant, the binaries contained in this
package are build with debug code and contain debug symbols.
.
Advantages of ngIRCd:
- no problems with servers using changing/non-static IP addresses.
- small and lean configuration file.
- free, modern and open source C code.
- still under active development.
.
ngIRCd is compatible to the "original" ircd 2.10.3p3, so you can run
mixed networks.

View File

@@ -1,18 +1,19 @@
#!/bin/sh
#
# ngIRCd start and stop script for Debian-based systems
# Copyright 2008 Alexander Barton <alex@barton.de>
# Copyright 2008-2010 Alexander Barton <alex@barton.de>
#
### BEGIN INIT INFO
# Provides: ircd
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Should-Start: $syslog
# Provides: ngircd
# Required-Start: $network $remote_fs
# Required-Stop: $network $remote_fs
# Should-Start: $syslog $named
# Should-Stop: $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Next Generation IRC Server
# Description: IRC daemon written from scratch
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
@@ -20,14 +21,16 @@ DAEMON=/usr/sbin/ngircd
NAME=ngIRCd
DESC="IRC daemon"
PARAMS=""
STARTTIME=1
DIETIME=10
test -x $DAEMON || exit 5
test -h "$0" && me=`readlink $0` || me="$0"
BASENAME=`basename $me`
test -r /etc/default/$BASENAME && . /etc/default/$BASENAME
test -x $DAEMON || exit 0
# LSB compatibility functions that become used if there is no local
# include file available.
log_daemon_msg() {
@@ -39,69 +42,134 @@ log_end_msg() {
log_failure_msg() {
echo "$*"
}
log_warning_msg() {
log_failure_msg "$*"
}
# Include LSB functions, if available:
test -r /lib/lsb/init-functions && . /lib/lsb/init-functions
PIDFILE=`$DAEMON $PARAMS -t | tr -d ' ' | grep "^PidFile=" | cut -d'=' -f2`
[ -n "$PIDFILE" ] || PIDFILE="/var/run/ircd/ngircd.pid"
r=3
Check_Config()
{
# Make sure that the configuration of ngIRCd is valid:
$DAEMON --configtest >/dev/null 2>&1
if [ $? -ne 0 ]; then
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
$DAEMON $PARAMS --configtest >/dev/null 2>&1
[ $? -eq 0 ] && return 0
log_end_msg 1
log_failure_msg "Configuration of $NAME is not valid, won't (re)start!"
log_failure_msg "Run \"$DAEMON --configtest\" and fix it up ..."
exit 6
}
Prepare() {
# Make sure the PID file directory exists and is writable:
if [ ! -d /var/run/ircd ]; then
mkdir -p /var/run/ircd
user=`$DAEMON $PARAMS -t|tr -d ' '|grep "^ServerUID="|cut -d'=' -f2`
group=`$DAEMON $PARAMS -t|tr -d ' '|grep "^ServerGID="|cut -d'=' -f2`
piddir=`dirname "$PIDFILE"`
[ -d "$piddir" ] || mkdir -p "$piddir" 2>/dev/null
chown "$user:$group" "$piddir" 2>/dev/null
[ $? -eq 0 ] && return 0
log_end_msg 1
log_failure_msg "Failed to prepare '$piddir' for user '$user'!"
exit 1
}
Do_Start() {
if Do_Status; then
log_end_msg 0
log_warning_msg "$NAME seems to be already running, nothing to do."
exit 0
fi
chown irc:irc /var/run/ircd
start-stop-daemon --start \
--quiet --exec $DAEMON -- $PARAMS
sleep $STARTTIME
Do_Status || return 7
return 0
}
Do_Stop() {
if ! Do_Status; then
log_end_msg 0
log_warning_msg "$NAME seems not to be running, nothing to do."
exit 0
fi
Do_ForceStop
return $?
}
Do_ForceStop() {
[ -e $PIDFILE ] \
&& pidfile="--pidfile $PIDFILE" \
|| pidfile=""
start-stop-daemon --stop \
--quiet --oknodo --exec $DAEMON $pidfile
for i in `seq 1 $DIETIME`; do
Do_Status || return 0
sleep 1
done
return 1
}
Do_Reload() {
start-stop-daemon --stop --signal 1 --quiet --exec $DAEMON
return $?
}
Do_Status() {
[ -e $PIDFILE ] \
&& pidfile="--pidfile $PIDFILE" \
|| pidfile=""
start-stop-daemon --stop \
--quiet --signal 0 --exec $DAEMON $pidfile >/dev/null
return $?
}
case "$1" in
start)
Check_Config
log_daemon_msg "Starting $DESC" "$NAME"
start-stop-daemon --start \
--quiet --exec $DAEMON -- $PARAMS
log_end_msg $?
Check_Config
Prepare
Do_Start; r=$?
log_end_msg $r
;;
stop)
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 $?
Do_Stop; r=$?
log_end_msg $r
;;
reload|force-reload)
Check_Config
log_daemon_msg "Reloading $DESC" "$NAME"
start-stop-daemon --stop --signal 1 --quiet --exec $DAEMON
log_end_msg $?
Check_Config
Do_Reload; r=$?
log_end_msg $r
;;
restart)
Check_Config
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
start-stop-daemon --start \
--quiet --exec $DAEMON -- $PARAMS
log_end_msg $?
Check_Config
Prepare
Do_ForceStop
Do_Start; r=$?
log_end_msg $r
;;
status)
log_daemon_msg "Checking for $DESC" "$NAME"
Do_Status; r=$?
log_end_msg $r
;;
test)
Check_Config
echo "Configuration of $DAEMON seems to be ok."; r=0
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
exit 1
N=/etc/init.d/$NAME; r=2
echo "Usage: $N {start|stop|restart|reload|force-reload|status|test}" >&2
;;
esac
exit 0
exit $r
# -eof-

View File

@@ -1,7 +1,7 @@
#!/usr/bin/make -f
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
# Copyright (c)2001-2009 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
@@ -36,7 +36,7 @@ endif
configure-ngircd: configure
dh_testdir
# configure "standard" variant:
./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) \
--prefix=/usr \
@@ -46,14 +46,27 @@ configure-ngircd: configure
configure-ngircd-full: configure
dh_testdir
# configure "full" variant:
./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) \
--prefix=/usr \
--sysconfdir=/etc/ngircd \
--mandir=\$${prefix}/share/man \
--with-syslog --with-zlib \
--with-gnutls --with-ident --with-tcp-wrappers \
--with-gnutls --with-ident --with-tcp-wrappers --with-pam \
--enable-ipv6
configure-ngircd-full-dbg: configure
dh_testdir
# configure "full debug" variant:
./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) \
--prefix=/usr \
--sysconfdir=/etc/ngircd \
--mandir=\$${prefix}/share/man \
--enable-debug --enable-sniffer \
--with-syslog --with-zlib \
--with-gnutls --with-ident --with-tcp-wrappers --with-pam \
--enable-ipv6
build:
@@ -63,20 +76,30 @@ build-ngircd: build-stamp-ngircd
build-stamp-ngircd: configure-ngircd
dh_testdir
rm -f build-stamp-*
# Add here commands to compile the "standard" package:
$(MAKE)
touch build-stamp-ngircd
build-ngircd-full: build-stamp-ngircd-full
build-stamp-ngircd-full: configure-ngircd-full
dh_testdir
rm -f build-stamp-*
# Add here commands to compile the "full" package:
$(MAKE)
touch build-stamp-ngircd-full
build-ngircd-full-dbg: build-stamp-ngircd-full-dbg
build-stamp-ngircd-full-dbg: configure-ngircd-full-dbg
dh_testdir
rm -f build-stamp-*
# Add here commands to compile the "full debug" package:
$(MAKE)
touch build-stamp-ngircd-full
clean:
@@ -86,10 +109,13 @@ clean:
rm -f $(CURDIR)/debian/ngircd-full.default
rm -f $(CURDIR)/debian/ngircd-full.init
rm -f $(CURDIR)/debian/ngircd-full.postinst
rm -f $(CURDIR)/debian/ngircd-full-dbg.default
rm -f $(CURDIR)/debian/ngircd-full-dbg.postinst
rm -f $(CURDIR)/debian/ngircd-full-dbg.init
# Add here commands to clean up after the build process:
[ ! -f Makefile ] || $(MAKE) distclean
ifneq "$(wildcard /usr/share/misc/config.sub)" ""
cp -f /usr/share/misc/config.sub config.sub
endif
@@ -98,13 +124,13 @@ ifneq "$(wildcard /usr/share/misc/config.guess)" ""
endif
dh_clean
install: install-ngircd install-ngircd-full
install: install-ngircd install-ngircd-full install-ngircd-full-dbg
install-ngircd: build-ngircd
dh_testdir
dh_testroot
dh_installdirs
# Add here commands to install the "standard" package into debian/ngircd:
$(MAKE) install DESTDIR=$(CURDIR)/debian/ngircd
rm $(CURDIR)/debian/ngircd/usr/share/doc/ngircd/INSTALL*
@@ -122,7 +148,7 @@ install-ngircd-full: build-ngircd-full
dh_testdir
dh_testroot
dh_installdirs
# Add here commands to install the "full" package into debian/ngircd-full:
$(MAKE) install DESTDIR=$(CURDIR)/debian/ngircd-full
rm $(CURDIR)/debian/ngircd-full/usr/share/doc/ngircd/INSTALL*
@@ -138,6 +164,26 @@ install-ngircd-full: build-ngircd-full
>$(CURDIR)/debian/ngircd-full/etc/ngircd/ngircd.conf
touch $(CURDIR)/debian/ngircd-full/etc/ngircd/ngircd.motd
install-ngircd-full-dbg: build-ngircd-full-dbg
dh_testdir
dh_testroot
dh_installdirs
# Add here commands to install the "full" package into debian/ngircd-full:
$(MAKE) install DESTDIR=$(CURDIR)/debian/ngircd-full-dbg
rm $(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd/INSTALL*
rm $(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd/COPYING*
mv $(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd \
$(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd-full-dbg
mkdir -p $(CURDIR)/debian/ngircd-full-dbg/var/run/ircd
cat $(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd-full-dbg/sample-ngircd.conf | \
sed -e "s/;ServerUID = 65534/ServerUID = irc/g" | \
sed -e "s/;ServerGID = 65534/ServerGID = irc/g" | \
sed -e "s/;MotdFile = \/usr\/local\/etc\/ngircd.motd/MotdFile = \/etc\/ngircd\/ngircd.motd/g" | \
sed -e "s/;PidFile = \/var\/run\/ngircd\/ngircd.pid/PidFile = \/var\/run\/ircd\/ngircd.pid/g" \
>$(CURDIR)/debian/ngircd-full-dbg/etc/ngircd/ngircd.conf
touch $(CURDIR)/debian/ngircd-full-dbg/etc/ngircd/ngircd.motd
# Build architecture-independent files here.
binary-indep:
# We have nothing to do by default.
@@ -150,13 +196,20 @@ binary-arch: build install
$(CURDIR)/debian/ngircd-full.init
ln -s $(CURDIR)/debian/ngircd.postinst \
$(CURDIR)/debian/ngircd-full.postinst
ln -s $(CURDIR)/debian/ngircd.default \
$(CURDIR)/debian/ngircd-full-dbg.default
ln -s $(CURDIR)/debian/ngircd.init \
$(CURDIR)/debian/ngircd-full-dbg.init
ln -s $(CURDIR)/debian/ngircd.postinst \
$(CURDIR)/debian/ngircd-full-dbg.postinst
dh_testdir
dh_testroot
dh_installchangelogs -a -A ChangeLog
dh_installdocs -a
dh_installinit -a
dh_strip -a
dh_strip -a --no-package=ngircd-full-dbg
dh_compress -a
dh_fixperms -a
dh_installdeb -a

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2007 Alexander Barton (alex@barton.de).
* Copyright (c)2001-2010 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,15 +8,20 @@
* (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 "??"
#ifndef VERSION
#define VERSION "??("__DATE__")"
#endif
#define SYSCONFDIR "/etc/ngircd"
#ifndef TARGET_VENDOR
#define TARGET_VENDOR "apple"
#define TARGET_OS "darwin"
#endif
/* -- Build options -- */
/* Define if debug-mode should be enabled */
@@ -43,6 +48,12 @@
/* Define if zlib compression should be enabled */
#define ZLIB 1
/* Define if IPV6 protocol should be enabled */
#define WANT_IPV6 1
/* Define if PAM should be used */
#define PAM 1
/* -- Supported features -- */
/* Define if SSP C support is enabled. */
@@ -63,6 +74,8 @@
#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 <netinet/ip.h> header file. */
#define HAVE_NETINET_IP_H 1
/* Define to 1 if you have the `kqueue' function. */
#define HAVE_KQUEUE 1
@@ -78,6 +91,14 @@
#define HAVE_STRDUP 1
/* Define to 1 if you have the `vsnprintf' function. */
#define HAVE_VSNPRINTF 1
/* Define to 1 if you have the `inet_aton' function. */
#define HAVE_INET_ATON 1
/* Define to 1 if you have the `getaddrinfo' function. */
#define HAVE_GETADDRINFO 1
/* Define to 1 if you have the `getnameinfo' function. */
#define HAVE_GETNAMEINFO 1
/* Define to 1 if you have the `sigaction' function. */
#define HAVE_SIGACTION 1
/* Define if socklen_t exists */
#define HAVE_socklen_t 1
@@ -89,4 +110,11 @@
#define HAVE_DNSSERVICEREGISTRATIONCREATE 1
#endif
#ifdef PAM
/* Define to 1 if you have the `pam_authenticate' function. */
#define HAVE_PAM_AUTHENTICATE 1
/* Define to 1 if you have the <pam/pam_appl.h> header file. */
#define HAVE_PAM_PAM_APPL_H 1
#endif
/* -eof- */

View File

@@ -1,10 +1,10 @@
<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
<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\cocoasubrtf430
{\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.\
Copyright (c)2001-2010 Alexander Barton and Contributors.\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\i0 \cf0 \
@@ -151,7 +151,7 @@ Each version is given a distinguishing version number. If the Program specifies
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
}]]></resource><resource mime-type="text/rtf" kind="embedded" type="welcome"><![CDATA[{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf430
{\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
@@ -160,7 +160,7 @@ Each version is given a distinguishing version number. If the Program specifies
\
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
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\cocoasubrtf430
{\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}
@@ -168,7 +168,9 @@ You will be guided through all steps necessary to install this software.}]]></re
{\*\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).\
\f0\fs26 \cf0 ngIRCd has been successfully installed/upgraded.\
\
It 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:\
\
@@ -185,4 +187,4 @@ To disable automatic starting of ngIRCd, use this command:\
\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>
}]]></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

@@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
FA2D564A11EA158B00D37A35 /* pam.c in Sources */ = {isa = PBXBuildFile; fileRef = FA2D564911EA158B00D37A35 /* pam.c */; };
FA2D567B11EA1AB300D37A35 /* libpam.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA2D567A11EA1AB300D37A35 /* libpam.dylib */; };
FA322D350CEF74B1001761B3 /* array.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322CD90CEF74B1001761B3 /* array.c */; };
FA322D360CEF74B1001761B3 /* channel.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322CDB0CEF74B1001761B3 /* channel.c */; };
FA322D370CEF74B1001761B3 /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322CDD0CEF74B1001761B3 /* client.c */; };
@@ -35,6 +37,10 @@
FA322DBE0CEF7766001761B3 /* tool.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D330CEF74B1001761B3 /* tool.c */; };
FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA322DC00CEF77CB001761B3 /* libz.dylib */; };
FA407F2E0DB159F400271AF1 /* ng_ipaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */; };
FA85178C0FA061EC006A1F5A /* op.c in Sources */ = {isa = PBXBuildFile; fileRef = FA85178B0FA061EC006A1F5A /* op.c */; };
FA99428C10E82A27007F27ED /* proc.c in Sources */ = {isa = PBXBuildFile; fileRef = FA99428B10E82A27007F27ED /* proc.c */; };
FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA3D2790F139CDC00B2447E /* conn-ssl.c */; };
FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA97C55124A271400D5BBA9 /* sighandlers.c */; };
FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */ = {isa = PBXBuildFile; fileRef = FAE5CC2D0CF2308A007D69B6 /* numeric.c */; };
/* End PBXBuildFile section */
@@ -53,6 +59,9 @@
/* Begin PBXFileReference section */
FA1A6BBC0D6857BB00AA8F71 /* misc-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "misc-test.e"; sourceTree = "<group>"; };
FA1A6BBD0D6857D900AA8F71 /* who-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "who-test.e"; sourceTree = "<group>"; };
FA2D564811EA158B00D37A35 /* pam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pam.h; sourceTree = "<group>"; };
FA2D564911EA158B00D37A35 /* pam.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pam.c; sourceTree = "<group>"; };
FA2D567A11EA1AB300D37A35 /* libpam.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpam.dylib; path = usr/lib/libpam.dylib; sourceTree = SDKROOT; };
FA322BBA0CEF72E4001761B3 /* ngIRCd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ngIRCd; sourceTree = BUILT_PRODUCTS_DIR; };
FA322CD60CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322CD90CEF74B1001761B3 /* array.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = array.c; sourceTree = "<group>"; };
@@ -126,7 +135,6 @@
FA322D210CEF74B1001761B3 /* getpid.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = getpid.sh; sourceTree = "<group>"; };
FA322D220CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322D230CEF74B1001761B3 /* mode-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "mode-test.e"; sourceTree = "<group>"; };
FA322D240CEF74B1001761B3 /* ngircd-test.conf */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "ngircd-test.conf"; sourceTree = "<group>"; };
FA322D250CEF74B1001761B3 /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
FA322D260CEF74B1001761B3 /* start-server.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = "start-server.sh"; sourceTree = "<group>"; };
FA322D270CEF74B1001761B3 /* stop-server.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = "stop-server.sh"; sourceTree = "<group>"; };
@@ -193,6 +201,34 @@
FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = ng_ipaddr.c; path = ipaddr/ng_ipaddr.c; sourceTree = "<group>"; };
FA407F2D0DB159F400271AF1 /* ng_ipaddr.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = ng_ipaddr.h; path = ipaddr/ng_ipaddr.h; sourceTree = "<group>"; };
FA407F380DB15AC700271AF1 /* GIT.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = GIT.txt; sourceTree = "<group>"; };
FA85178A0FA061EC006A1F5A /* op.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = op.h; sourceTree = "<group>"; };
FA85178B0FA061EC006A1F5A /* op.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = op.c; sourceTree = "<group>"; };
FA99428A10E82A27007F27ED /* proc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = proc.h; sourceTree = "<group>"; };
FA99428B10E82A27007F27ED /* proc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = proc.c; sourceTree = "<group>"; };
FAA3D2700F139CB300B2447E /* invite-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "invite-test.e"; sourceTree = "<group>"; };
FAA3D2710F139CB300B2447E /* join-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "join-test.e"; sourceTree = "<group>"; };
FAA3D2720F139CB300B2447E /* kick-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "kick-test.e"; sourceTree = "<group>"; };
FAA3D2730F139CB300B2447E /* message-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "message-test.e"; sourceTree = "<group>"; };
FAA3D2740F139CB300B2447E /* ngircd-test1.conf */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "ngircd-test1.conf"; sourceTree = "<group>"; };
FAA3D2750F139CB300B2447E /* ngircd-test2.conf */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "ngircd-test2.conf"; sourceTree = "<group>"; };
FAA3D2760F139CB300B2447E /* opless-channel-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "opless-channel-test.e"; sourceTree = "<group>"; };
FAA3D2770F139CB300B2447E /* server-link-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "server-link-test.e"; sourceTree = "<group>"; };
FAA3D2780F139CDC00B2447E /* conf-ssl.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = "conf-ssl.h"; sourceTree = "<group>"; };
FAA3D2790F139CDC00B2447E /* conn-ssl.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = "conn-ssl.c"; sourceTree = "<group>"; };
FAA3D27A0F139CDC00B2447E /* conn-ssl.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = "conn-ssl.h"; sourceTree = "<group>"; };
FAA3D27C0F139CF800B2447E /* strtok_r.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = strtok_r.c; sourceTree = "<group>"; };
FAA3D27D0F139CF800B2447E /* waitpid.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = waitpid.c; sourceTree = "<group>"; };
FAA3D2800F139D1500B2447E /* Services.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Services.txt; sourceTree = "<group>"; };
FAA3D2820F139D2E00B2447E /* 01ngircd-contents.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = "01ngircd-contents.xml"; sourceTree = "<group>"; };
FAA3D2830F139D2E00B2447E /* 01ngircd.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = 01ngircd.xml; sourceTree = "<group>"; };
FAA3D2840F139D2E00B2447E /* 02de-contents.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = "02de-contents.xml"; sourceTree = "<group>"; };
FAA3D2850F139D2E00B2447E /* 02de.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = 02de.xml; sourceTree = "<group>"; };
FAA3D2860F139D2E00B2447E /* index.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = index.xml; sourceTree = "<group>"; };
FAA3D2880F139D2E00B2447E /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FAA3D28A0F139D2E00B2447E /* postinstall.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = postinstall.sh; sourceTree = "<group>"; };
FAA3D28B0F139D2E00B2447E /* preinstall.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = preinstall.sh; sourceTree = "<group>"; };
FAA97C55124A271400D5BBA9 /* sighandlers.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = sighandlers.c; sourceTree = "<group>"; };
FAA97C56124A271400D5BBA9 /* sighandlers.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = sighandlers.h; sourceTree = "<group>"; };
FAE5CC2C0CF2308A007D69B6 /* numeric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = numeric.h; sourceTree = "<group>"; };
FAE5CC2D0CF2308A007D69B6 /* numeric.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = numeric.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -203,6 +239,7 @@
buildActionMask = 2147483647;
files = (
FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */,
FA2D567B11EA1AB300D37A35 /* libpam.dylib in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -229,6 +266,7 @@
FA322D630CEF750F001761B3 /* Makefile.am */,
1AB674ADFE9D54B511CA2CBB /* Products */,
FA322DC00CEF77CB001761B3 /* libz.dylib */,
FA2D567A11EA1AB300D37A35 /* libpam.dylib */,
);
name = ngIRCd;
sourceTree = "<group>";
@@ -258,6 +296,9 @@
FA322CD70CEF74B1001761B3 /* ngircd */ = {
isa = PBXGroup;
children = (
FAA3D2780F139CDC00B2447E /* conf-ssl.h */,
FAA3D2790F139CDC00B2447E /* conn-ssl.c */,
FAA3D27A0F139CDC00B2447E /* conn-ssl.h */,
FA322CD90CEF74B1001761B3 /* array.c */,
FA322CDA0CEF74B1001761B3 /* array.h */,
FA322CDB0CEF74B1001761B3 /* channel.c */,
@@ -307,12 +348,20 @@
FA322D070CEF74B1001761B3 /* ngircd.h */,
FAE5CC2D0CF2308A007D69B6 /* numeric.c */,
FAE5CC2C0CF2308A007D69B6 /* numeric.h */,
FA85178A0FA061EC006A1F5A /* op.h */,
FA85178B0FA061EC006A1F5A /* op.c */,
FA322D080CEF74B1001761B3 /* parse.c */,
FA322D090CEF74B1001761B3 /* parse.h */,
FA99428B10E82A27007F27ED /* proc.c */,
FA99428A10E82A27007F27ED /* proc.h */,
FA322D0A0CEF74B1001761B3 /* rendezvous.c */,
FA322D0B0CEF74B1001761B3 /* rendezvous.h */,
FA322D0C0CEF74B1001761B3 /* resolve.c */,
FA322D0D0CEF74B1001761B3 /* resolve.h */,
FAA97C55124A271400D5BBA9 /* sighandlers.c */,
FAA97C56124A271400D5BBA9 /* sighandlers.h */,
FA2D564811EA158B00D37A35 /* pam.h */,
FA2D564911EA158B00D37A35 /* pam.c */,
);
path = ngircd;
sourceTree = "<group>";
@@ -320,6 +369,8 @@
FA322D0E0CEF74B1001761B3 /* portab */ = {
isa = PBXGroup;
children = (
FAA3D27C0F139CF800B2447E /* strtok_r.c */,
FAA3D27D0F139CF800B2447E /* waitpid.c */,
FA322D100CEF74B1001761B3 /* ansi2knr.1 */,
FA322D110CEF74B1001761B3 /* ansi2knr.c */,
FA322D120CEF74B1001761B3 /* exp.h */,
@@ -338,6 +389,14 @@
FA322D1B0CEF74B1001761B3 /* testsuite */ = {
isa = PBXGroup;
children = (
FAA3D2700F139CB300B2447E /* invite-test.e */,
FAA3D2710F139CB300B2447E /* join-test.e */,
FAA3D2720F139CB300B2447E /* kick-test.e */,
FAA3D2730F139CB300B2447E /* message-test.e */,
FAA3D2740F139CB300B2447E /* ngircd-test1.conf */,
FAA3D2750F139CB300B2447E /* ngircd-test2.conf */,
FAA3D2760F139CB300B2447E /* opless-channel-test.e */,
FAA3D2770F139CB300B2447E /* server-link-test.e */,
FA322D1D0CEF74B1001761B3 /* channel-test.e */,
FA322D1E0CEF74B1001761B3 /* check-idle.e */,
FA322D1F0CEF74B1001761B3 /* connect-test.e */,
@@ -346,7 +405,6 @@
FA322D220CEF74B1001761B3 /* Makefile.am */,
FA1A6BBC0D6857BB00AA8F71 /* misc-test.e */,
FA322D230CEF74B1001761B3 /* mode-test.e */,
FA322D240CEF74B1001761B3 /* ngircd-test.conf */,
FA322D250CEF74B1001761B3 /* README */,
FA322D260CEF74B1001761B3 /* start-server.sh */,
FA322D270CEF74B1001761B3 /* stop-server.sh */,
@@ -408,6 +466,9 @@
FA322D730CEF7523001761B3 /* MacOSX */ = {
isa = PBXGroup;
children = (
FAA3D2810F139D2E00B2447E /* ngIRCd.pmdoc */,
FAA3D28A0F139D2E00B2447E /* postinstall.sh */,
FAA3D28B0F139D2E00B2447E /* preinstall.sh */,
FA322D750CEF7523001761B3 /* build */,
FA322D8D0CEF7523001761B3 /* Makefile.am */,
FA322D8E0CEF7523001761B3 /* ngIRCd.xcodeproj */,
@@ -497,6 +558,7 @@
FA322D970CEF752C001761B3 /* doc */ = {
isa = PBXGroup;
children = (
FAA3D2800F139D1500B2447E /* Services.txt */,
FA407F380DB15AC700271AF1 /* GIT.txt */,
FA322D9A0CEF752C001761B3 /* FAQ.txt */,
FA322D9B0CEF752C001761B3 /* Makefile.am */,
@@ -547,6 +609,19 @@
name = ipaddr;
sourceTree = "<group>";
};
FAA3D2810F139D2E00B2447E /* ngIRCd.pmdoc */ = {
isa = PBXGroup;
children = (
FAA3D2820F139D2E00B2447E /* 01ngircd-contents.xml */,
FAA3D2830F139D2E00B2447E /* 01ngircd.xml */,
FAA3D2840F139D2E00B2447E /* 02de-contents.xml */,
FAA3D2850F139D2E00B2447E /* 02de.xml */,
FAA3D2860F139D2E00B2447E /* index.xml */,
FAA3D2880F139D2E00B2447E /* Makefile.am */,
);
path = ngIRCd.pmdoc;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -624,6 +699,11 @@
FA322DBE0CEF7766001761B3 /* tool.c in Sources */,
FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */,
FA407F2E0DB159F400271AF1 /* ng_ipaddr.c in Sources */,
FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */,
FA85178C0FA061EC006A1F5A /* op.c in Sources */,
FA99428C10E82A27007F27ED /* proc.c in Sources */,
FA2D564A11EA158B00D37A35 /* pam.c in Sources */,
FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -660,10 +740,9 @@
1DEB928B08733DD80010E9CD /* Default */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
ppc,
i386,
);
ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
GCC_VERSION = 4.0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
@@ -671,6 +750,50 @@
};
name = Default;
};
FAB0570C105D917F006AF9E2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
GCC_DEBUGGING_SYMBOLS = full;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = 4.0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
};
name = Debug;
};
FAB0570D105D917F006AF9E2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
GCC_WARN_MISSING_PARENTHESES = YES;
GCC_WARN_PEDANTIC = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
GCC_WARN_UNINITIALIZED_AUTOS = NO;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VALUE = YES;
INSTALL_PATH = /usr/local/bin;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = ngIRCd;
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
};
name = Debug;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -678,6 +801,7 @@
isa = XCConfigurationList;
buildConfigurations = (
1DEB928708733DD80010E9CD /* Default */,
FAB0570D105D917F006AF9E2 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Default;
@@ -686,6 +810,7 @@
isa = XCConfigurationList;
buildConfigurations = (
1DEB928B08733DD80010E9CD /* Default */,
FAB0570C105D917F006AF9E2 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Default;

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
# Copyright (c)2001-2009 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,7 +11,8 @@
SUBDIRS = Debian MacOSX
EXTRA_DIST = README ngircd.spec systrace.policy ngindent ngircd.sh
EXTRA_DIST = README ngircd.spec systrace.policy ngindent ngircd-bsd.sh \
ngircd-redhat.init platformtest.sh
maintainer-clean-local:
rm -f Makefile Makefile.in

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2005 Alexander Barton,
(c)2001-2009 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -19,15 +19,17 @@ MacOSX/
ngindent
- Script to indent the code of ngIRCd in the "standard way".
ngircd.sh
ngircd-bsd.sh
- Start script for FreeBSD.
ngircd-redhat.init
- Start/stop script for RedHat-based distributions (like CentOS).
ngircd.spec
- RPM "spec" file.
platformtest.sh
- Build ngIRCd and output a "result line" suitable for doc/Platforms.txt.
systrace.policy
- Systrace policy file for OpenBSD (and probably NetBSD).
--
$Id: README,v 1.3 2006/07/23 11:34:32 alex Exp $

119
contrib/ngircd-redhat.init Normal file
View File

@@ -0,0 +1,119 @@
#!/bin/sh
#
# ngIRCd start and stop script for RedHat based distributions.
# Written by Naoya Nakazawa <naoya@sanow.net> for CentOS 5.2, 2009.
#
# chkconfig: 2345 01
# description: ngIRCd is an Open Source server for \
# the Internet Relay Chat (IRC), which \
# is developed and published under \
# the terms of the GNU General Public
# 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.
#
# processname: /usr/sbin/ngircd
# config: /etc/ngircd
# pidfile: /var/run/ngircd.pid
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/ngircd
NAME=ngIRCd
BASENAME=ngircd
CONF=/etc/$BASENAME.conf
DESC="IRC daemon"
PARAMS="-f $CONF"
# Source function library.
. /etc/init.d/functions
# Get config.
test -f /etc/sysconfig/network && . /etc/sysconfig/network
test -f /etc/sysconfig/makuosan && . /etc/sysconfig/makuosan
# Check that networking is up.
[ "${NETWORKING}" = "yes" ] || exit 0
[ -x $DAEMON ] || exit 1
[ -f $CONF ] || exit 2
RETVAL=0
start(){
echo -n $"Starting $NAME: "
daemon $DAEMON $PARAMS
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$BASENAME
echo
return $RETVAL
}
stop(){
echo -n $"Stopping $NAME: "
killproc $DAEMON
RETVAL=$?
if [ $RETVAL -eq 0 ] ; then
rm -f /var/lock/subsys/$BASENAME
fi
echo
return $RETVAL
}
reload(){
echo -n $"Reloading configuration: "
killproc $DAEMON -HUP
RETVAL=$?
echo
return $RETVAL
}
restart(){
stop
start
}
condrestart(){
[ -e /var/lock/subsys/$BASENAME ] && restart
return 0
}
check_config(){
$DAEMON $PARAMS --configtest >/dev/null 2>&1
[ $? -eq 0 ] && return 0
echo -n $"Configuration of $NAME is not valid, won't (re)start!"
echo -n $"Run \"$DAEMON --configtest\" and fix it up ..."
exit 6
}
# See how we were called.
case "$1" in
start)
check_config
start
;;
stop)
stop
;;
status)
status $NAME
;;
restart)
restart
;;
reload)
reload
;;
condrestart)
condrestart
;;
test)
check_config
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|reload|test}"
RETVAL=1
esac
exit $RETVAL

View File

@@ -1,5 +1,5 @@
%define name ngircd
%define version 13~rc1
%define version 17~rc1
%define release 1
%define prefix %{_prefix}
@@ -7,12 +7,12 @@ Summary: A lightweight daemon for the Internet Relay Chat (IRC)
Name: %{name}
Version: %{version}
Release: %{release}
Copyright: GPL
Group: Networking/Daemons
URL: http://arthur.ath.cx/~alex/ngircd/
License: GPLv2+
Group: System Environment/Daemons
URL: http://ngircd.barton.de/
Source: %{name}-%{version}.tar.gz
Packager: Sean Reifschneider <jafo-rpms@tummy.com>
BuildRoot: /var/tmp/%{name}-root
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: zlib-devel, openssl-devel
%description
ngIRCd is a free open source daemon for the Internet Relay Chat (IRC),
@@ -29,10 +29,13 @@ ngIRCd is compatible to the "original" ircd 2.10.3p3, so you can run
mixed networks.
%prep
%setup
%setup -q
%build
%configure
make
%configure \
--with-zlib \
--with-openssl
make %{?_smp_mflags}
%install
[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"
@@ -42,6 +45,7 @@ make
( cd usr/sbin; mv *-ngircd ngircd )
( cd usr/share/man/man5; mv *-ngircd.conf.5 ngircd.conf.5 )
( cd usr/share/man/man8; mv *-ngircd.8 ngircd.8 )
rm -fr usr/share/doc/ngircd
)
%clean
@@ -49,7 +53,8 @@ make
%files
%defattr(755,root,root)
%doc AUTHORS COPYING ChangeLog INSTALL NEWS README
%doc AUTHORS COPYING ChangeLog INSTALL NEWS README doc/*
%config(noreplace) /etc
%{_prefix}/sbin
%{_prefix}/share/man/
%{_mandir}/man5/ngircd.conf*
%{_mandir}/man8/ngircd.8*

143
contrib/platformtest.sh Executable file
View File

@@ -0,0 +1,143 @@
#!/bin/sh
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2009 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.
#
# This script analyzes the build process of ngIRCd and generates output
# suitable for inclusion in doc/Platforms.txt -- please send reports
# to the ngIRCd mailing list: <ngircd-ml@ngircd.barton.de>.
NAME=`basename "$0"`
VERBOSE=
PLATFORM=
COMPILER="unknown"
VERSION="unknown"
DATE=`date "+%y-%m-%d"`
CONFIGURE=
MAKE=
CHECK=
RUN=
COMMENT=
while [ $# -gt 0 ]; do
case "$1" in
"-v")
VERBOSE=1
;;
*)
echo "Usage: $NAME [-v]"
exit 2
esac
shift
done
echo "$NAME: Checking ngIRCd base source directory ..."
grep "ngIRCd" ./ChangeLog >/dev/null 2>&1
if [ $? -ne 0 ]; then
grep "ngIRCd" ../ChangeLog >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "$NAME: ngIRCd base source directory not found!?"
exit 1
fi
cd ..
fi
echo "$NAME: Checking for ./configure script ..."
if [ ! -e ./configure ]; then
echo "$NAME: Not found. Running ./autogen.sh ..."
[ -n "$VERBOSE" ] && ./autogen.sh || ./autogen.sh >/dev/null
fi
if [ -e ./configure ]; then
echo "$NAME: Running \"./configure\" script ..."
[ -n "$VERBOSE" ] && ./configure || ./configure >/dev/null
if [ $? -eq 0 -a -e ./Makefile ]; then
CONFIGURE=1
echo "$NAME: Running \"make\" ..."
[ -n "$VERBOSE" ] && make || make >/dev/null
if [ $? -eq 0 -a -x src/ngircd/ngircd ]; then
MAKE=1
echo "$NAME: Running \"make check\" ..."
[ -n "$VERBOSE" ] && make check || make check >/dev/null
if [ $? -eq 0 ]; then
CHECK=1
RUN=$CHECK
else
./src/ngircd/ngircd --help 2>/dev/null \
| grep "^ngircd" >/dev/null
[ $? -eq 0 ] && RUN=1
fi
fi
fi
fi
# Get target platform information
if [ -r "src/config.h" ]; then
CPU=`grep "TARGET_CPU" "src/config.h" | cut -d'"' -f2`
OS=`grep "TARGET_OS" "src/config.h" | cut -d'"' -f2`
VENDOR=`grep "TARGET_VENDOR" "src/config.h" | cut -d'"' -f2`
PLATFORM="$CPU/$VENDOR/$OS"
fi
if [ -z "$PLATFORM" ]; then
PLATFORM="`uname 2>/dev/null` `uname -r 2>/dev/null`, `uname -m 2>/dev/null`"
fi
# Get compiler information
if [ -r "Makefile" ]; then
eval $(grep "^CC = " Makefile | sed -e 's/ //g')
$CC --version 2>&1 | grep -i "GCC" >/dev/null
if [ $? -eq 0 ]; then
COMPILER=$($CC --version | head -n 1 | awk "{ print \$3 }" \
| cut -d'-' -f1)
COMPILER="gcc $COMPILER"
fi
fi
# Get ngIRCd version information
if [ -d ".git" ]; then
VERSION=`git log --abbrev-commit --pretty=oneline HEAD~1.. \
| head -1 | cut -d' ' -f1 | tr -d '.'`
elif [ -r "Makefile" ]; then
eval $(grep "^VERSION = " Makefile | sed -e 's/ //g')
fi
[ -n "$VERSION" ] || VERSION="unknown"
# Get IO interface information
if [ "$OS" = "linux-gnu" ]; then
COMMENT="(1)"
else
grep "^#define HAVE_SYS_DEVPOLL_H 1" src/config.h >/dev/null 2>&1
[ $? -eq 0 ] && COMMENT="(4)"
grep "^#define HAVE_EPOLL_CREATE 1" src/config.h >/dev/null 2>&1
[ $? -eq 0 ] && COMMENT="(5)"
grep "^#define HAVE_KQUEUE 1" src/config.h >/dev/null 2>&1
[ $? -eq 0 ] && COMMENT="(3)"
fi
[ -n "$CONFIGURE" ] && C="Y" || C="N"
[ -n "$MAKE" ] && M="Y" || M="N"
[ -n "$CHECK" ] && T="Y" || T="N"
[ -n "$RUN" ] && R="Y" || R="N"
[ -n "$COMMENT" ] && COMMENT=" $COMMENT"
echo
echo " the executable works (\"runs\") as expected --+"
echo " tests run successfully (\"make check\") --+ |"
echo " ngIRCd compiles (\"make\") --+ | |"
echo " ./configure works --+ | | |"
echo " | | | |"
echo "Platform Compiler ngIRCd Date Tester C M T R See"
echo "--------------------------- ------------ ---------- -------- ------ - - - - ---"
printf "%-27s %-12s %-10s %s %-6s %s %s %s %s%s" \
"$PLATFORM" "$COMPILER" "$VERSION" "$DATE" "$USER" \
"$C" "$M" "$T" "$R" "$COMMENT"
echo; echo

53
doc/Bopm.txt Normal file
View File

@@ -0,0 +1,53 @@
ngIRCd - Next Generation IRC Server
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- BOPM.txt --
I. Introduction
~~~~~~~~~~~~~~~~
Citing <http://wiki.blitzed.org/BOPM>: "BOPM is an open source open proxy
monitor, designed for use with hybrid-based ircds, although it can be used
with slight modification on any server which has the ability to show connects
to opers and that supports KLINEs."
And starting with Release 17, ngIRCd supports all required log messages that
BOPM requires to be useful.
II. Installation
~~~~~~~~~~~~~~~~~
Install BOPM as usual, please see the BOPM documentation for details.
Afterwards adjust the following configuration parameters that are important
for ngIRCd:
a) BOPM "IRC" section:
1) Set "server" and "port" accordingly,
2) adjust the "oper" line to match an [Operator] block in ngircd.conf,
3) change "mode" to "+ci" or "+c".
4) Set "connregex" to the following string, everything in one line(!):
"\\*\\*\\* Notice -- Client connecting: ([^ ]+) \\(([^@]+)@([^\\)]+)\\) \\[([0-9\\.]+)\\].*";
and comment all the other "connregex" examples (prepend a "#" character).
5) Set "kline" to "KILL %n :Open proxy found on your host!"; for example,
and comment all the other "kline" examples.
b) BOPM "scanner" section:
Make sure you configure a valid "target_ip" and "target_port" for the
configured scanners to test. And please note that you CAN'T USE the port
of ngIRCd, because ngIRCd doesn't send any banner message by default!
So you need a service what sends a banner, so for example POP3, SMTP,
IMAP, or SSH daemons should work ...

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2003 by Alexander Barton,
(c)2001-2010 by Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -12,9 +12,11 @@
I. General
~~~~~~~~~~
Q: Is it possible to link the ngIRCd with non-ngIRCd servers?
A: Yes. ngIRCd is compatible to the original ircd used by IRCNet. Actually
this is being tested with version 2.10.3p3.
this is being tested with version 2.10.3p3. Please note that newer
versions (2.11.x) aren't compatible any more!
Q: Is there a homepage with further information and downloads?
A: Yes. Please visit <http://ngircd.barton.de/>.
@@ -26,6 +28,7 @@ A: ngIRCd offers several benefits: no problems with dynamic IPs, easy to
II. Compilation
~~~~~~~~~~~~~~~
Q: I did a "CVS checkout" but can't execute ./configure because the script
is missing in the generated directory!?
A: When using development versions via CVS, the configure script as well as
@@ -55,27 +58,33 @@ 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.
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
the chroot as well, notably libnss_dns; maybe others. Unfortunately, even
linking ngircd statically does not help this. The only known workaround
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 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.
A: You need to set 'OperCanUseMode = yes' in ngircd.conf, then IRC operators
can use the MODE command for changing modes even when they are not joined
to the specific channel.
IV. Bugs!?
~~~~~~~~~~
Q: Is there a list of known bugs and desired feature enhancements?
A: Yes. Have a look at the bug tracking system (Bugzilla) for ngIRCd located
at <http://ngircd.barton.de/bugzilla/index.cgi>. There you can file bug
@@ -85,6 +94,3 @@ Q: What should I do if I found a bug?
A: Please file a bug report at <http://ngircd.barton.de/bugzilla/index.cgi>!
The author of the particular component will be notified automagically :-)
--
$Id: FAQ.txt,v 1.12 2008/01/02 22:47:58 alex Exp $

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 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
@@ -13,12 +13,13 @@
SUBDIRS = src
EXTRA_DIST = FAQ.txt GIT.txt Protocol.txt Platforms.txt README-AUX.txt \
README-BeOS.txt RFC.txt SSL.txt Zeroconf.txt sample-ngircd.conf
README-BeOS.txt RFC.txt Services.txt SSL.txt Zeroconf.txt \
sample-ngircd.conf
maintainer-clean-local:
rm -f Makefile Makefile.in
docdir = $(datadir)/doc/$(PACKAGE)
docdir ?= $(datadir)/doc/$(PACKAGE)
documents = $(EXTRA_DIST) ../AUTHORS ../COPYING ../ChangeLog ../INSTALL \
../NEWS ../README

36
doc/PAM.txt Normal file
View File

@@ -0,0 +1,36 @@
ngIRCd - Next Generation IRC Server
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- PAM.txt --
ngIRCd can optionally be compiled to use PAM, the Pluggable Authentication
Modules library, for user authentication. When compiled with PAM support,
ngIRCd will authenticate all users connecting to the daemon using the
configured PAM modules in an asynchronous child process.
To enable PAM, you have to pass the command line parameter "--with-pam" to
the "configure" script. Please see the PAM documentation ("man 7 pam") for
details and information about configuring PAM and its individual modules.
A very simple -- and quite useless ;-) -- example would be:
/etc/pam.d/ngircd:
auth required pam_debug.so
Here the "pam_debug" module will be called each time a client connects to
the ngIRCd and has sent its PASS, NICK, and USER commands.
Please note ONE VERY IMPORTANT THING:
All the PAM modules are executed with the privileges of the user ngIRCd
is running as. Therefore a lot of PAM modules aren't working as expected,
because they need root privileges ("pam_unix", for example)!
Only PAM modules not(!) requiring root privileges (such as "pam_pgsql",
"pam_mysql", "pam_opendirectory" ...) can be used in conjunction with ngIRCd.

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2008 Alexander Barton
(c)2001-2010 Alexander Barton
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -29,28 +29,34 @@ 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)
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 0.9.x-CVS 05-06-27 alex Y Y Y Y
i386/apple/darwin9.4.0 gcc 4.0.1 0.12.1 08-07-21 alex Y Y Y Y (3)
hppa2.0/unknown/linux-gnu gcc 3.3.5 13~rc1 08-12-02 alex Y Y Y Y
hppa2.0w-hp-hpux11.11 gcc 4.2.3 14.1 09-07-22 goetz Y Y Y Y
i386/apple/darwin9.7.0 gcc 4.0.1 14.1 09-08-04 alex Y Y Y Y (3)
i386/apple/darwin10.4.0 gcc 4.2.1 17-dev 10-10-05 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 CVSHEAD 06-08-04 alex Y Y Y Y
i386/pc/solaris2.11 gcc 3.4.3 0.12.1 08-07-21 alex Y Y Y Y (4)
i386/pc/solaris2.11 gcc 3.4.3 14.1 09-08-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.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/freebsd7.0 gcc 4.2.1 0.12.1 08-07-21 alex Y Y Y Y (3)
i386/unknown/freebsd6.2 gcc 3.4.6 17-dev 10-10-05 alex Y Y Y Y (3)
i386/unknown/freebsd7.0 gcc 4.2.1 14.1 09-07-28 alex Y Y Y Y (3)
i386/unknown/freebsd7.2 gcc 4.2.1 14.1 09-08-03 alex Y Y Y Y (3)
i386/unknown/freebsd7.3 gcc 4.2.1 17-dev 10-10-05 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 0.12.1 08-08-10 alex Y Y Y Y
i686/unknown/gnu0.3 gcc 4.3.1 14.1 09-07-28 alex Y Y Y Y
i686/unkn./kfreebsd7.2-gnu gcc 4.3.4 15 09-12-02 alex Y Y Y Y (3)
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 0.12.1 08-07-21 alex Y Y Y Y (3)
i386/unknown/netbsdelf4.0 gcc 4.1.2 17-dev 10-10-05 alex Y Y Y Y (3)
i386/unknown/netbsdelf5.0.2 gcc 4.1.3 17-dev 10-10-07 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 0.12.1 08-07-21 alex Y Y n Y (3)
i386/unknown/openbsd4.1 gcc 3.3.5 master 08-07-21 alex Y Y Y Y (3)
i386/unknown/openbsd4.1 gcc 3.3.5 16 10-04-11 alex Y Y Y Y (3)
i586/pc/interix3.5 gcc 3.3 15 10-01-22 alex Y Y N Y
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)
i386/pc/linux-gnu gcc 4.1.2 0.10.0-p1 06-08-30 alex Y Y Y Y (1)
i386/pc/linux-gnu gcc 4.3.1 0.12.1 08-07-21 alex Y Y Y Y (1)
i686/pc/linux-gnu gcc 3.3.5 14.1 09-08-04 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)
i686/pc/linux-gnu gcc 4.3.2 14.1 09-08-04 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 ? ?
@@ -63,18 +69,22 @@ 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/freebsd8.0 gcc 4.2.1 16 10-04-23 alex Y Y Y Y (3)
x86_64/unknown/freebsd8.1 gcc 4.2.1 17-dev 10-10-05 alex Y Y Y Y (3)
x86_64/unknown/linux-gnu gcc 4.3.2 17-dev 10-10-05 alex Y Y Y Y (1)
x86_64/unknown/openbsd4.7 gcc 3.3.5 17-dev 10-10-05 alex Y Y Y Y (3)
Notes
~~~~~
(1) i686/pc/linux-gnu:
(1) i686/pc/linux-gnu & x86_64/unknown/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 (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.
Actual Linux kernels (2.6.x) and glibc'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.
@@ -83,3 +93,4 @@ Notes
(4) Using the /dev/poll IO interface.
(5) Using the epoll() IO interface.

View File

@@ -37,7 +37,7 @@ The following software packages are needed:
ftp://arthur.barton.de/pub/unix/aux/libraries/libUTIL-2.1.tar.gz
This library contains functions that are common on other UNIX
systems but not on A/UX e.g. memmove(), strerror() und strdup().
systems but not on A/UX e.g. memmove(), strerror() and strdup().
After installation of these packages just do a "./configure" and "make" to
@@ -60,7 +60,7 @@ A few hints in case of errors:
the 'config.status' script. Better rename /bin/sh to /bin/sh.AUX and
replace it by a symbolic link to /bin/ksh (ln -s /bin/ksh /bin/sh as
root).
These procedure should'nt cause you into problems and is recommended
These procedure shouldn't cause you into problems and is recommended
even if you don't use ngIRCd.
--

View File

@@ -24,7 +24,7 @@ mit diesem Fehler ab:
select(): Bad file descriptor!
Es sieht leider so aus, als ob das select() von BeOS nicht mit File-Handles
von Pipes verschiedener Prozesse umgehen kann: sobald der Resolver asyncron
von Pipes verschiedener Prozesse umgehen kann: sobald der Resolver asynchron
gestartet wird, also Pipe-Handles im select() vorhanden sind, fuehrt das zu
obiger Meldung.

37
doc/README-Interix.txt Normal file
View File

@@ -0,0 +1,37 @@
ngIRCd - Next Generation IRC Server
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- README-Interix.txt --
ngIRCd release 15 has successfully been tested on Microsoft Windows XP
Professional using the Services for UNIX (SFU) version 3.5 and Microsoft
Windows 7 with the bundled Subsystem for UNIX Applications (SUA).
SFU are supported on Windows 2000, Windows 2000 Server, Windows XP, and
Windows Server 2003. SUA is supported on Windows Server 2003 R2, Windows
Server 2008 & 2008 R2, Windows Vista, and Windows 7 -- so ngIRCd should be
able to run on all of these platforms.
But please note that the poll() API function is not fully implemented by
SFU/SUA and therefore can't be used by ngIRCd -- which normally would be
the default. Please see <http://www.suacommunity.com/faqs.aspx> section
4.25 for details:
"If you do try to use the poll() API your program will block on the
API call forever. You must direct your program to build using the
select() API."
So when running the ./configure script, you HAVE TO DISABLE poll() support:
./configure --without-poll
ngIRCd then defaults to using the select() API function which works fine.

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,39 +10,71 @@
-- SSL.txt --
ngIRCd supports SSL/TLSv1 encrypted connections using the
OpenSSL or gnutls library.
Both encryped server <-> client and server <-> server links should 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.
BEWARE! The Code is mostly untested, use at your own risk!
SSL is a compile-time option which is disabled by default. Use one of these
options of the ./configure script to enable it:
Example that creates a self-signed certificate and key (using OpenSSL):
openssl req -newkey rsa:2048 -x509 -keyout server-key.pem \
-out server-cert.pem -days 1461
--with-openssl enable SSL support using OpenSSL
--with-gnutls enable SSL support using GnuTLS
Example that creates DH parameters (optional):
openssl dhparam -2 -out dhparams.pem 2048
You also need a key/certificate, see below for how to create a self-signed one.
Example that creates a self-signed certificate
and key (using gnutls):
From a feature point of view, ngIRCds support for both libraries is
comparable. The only major difference (at this time) is that ngircd with gnutls
does not support password protected private keys.
certtool --generate-privkey --bits 2048 --outfile server-key.pem
certtool --generate-self-signed --load-privkey server-key.pem \
--outfile server-cert.pem
Configuration
~~~~~~~~~~~~~
Example that creates DH parameters (optional):
certtool --generate-dh-params --bits 2048 --outfile dhparams.pem
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 ...
Alternatively, you may use external programs/tools like stunnel to
make it work:
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 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 !
@@ -70,10 +102,7 @@ short "how-to", thanks Stefan!
That's it.
Don't forget to activate ssl support in your irc client ;)
The main drawback of this approach compared to using builtin ssl
is that from ngIRCds point of view, all ssl-enabled client connections will
originate from the host running stunnel.
=== snip ===
--
$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

@@ -20,7 +20,7 @@ To use this features you can use one of two APIs:
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
available API will be autodetected and the required additional libraries will
be linked to the ngircd binary as required.
ngIRCd then registers a DNS-SD service for each port it is listening on using

View File

@@ -1,14 +1,13 @@
# $Id: sample-ngircd.conf,v 1.44 2008/01/07 23:02:29 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.
# 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!
@@ -29,9 +28,15 @@
# LINKS requests for example.
Info = Server Info Text
# Global password for all users needed to connect to the server
# Global password for all users needed to connect to the server.
# (Default: not set)
;Password = abc
# Password required for using the WEBIRC command used by some
# Web-to-IRC gateways. If not set/empty, the WEBIRC command can't
# be used. (Default: not set)
;WebircPassword = xyz
# Information about the server and the administrator, used by the
# ADMIN command. Not required by server but by RFC!
;AdminInfo1 = Description
@@ -43,7 +48,7 @@
;Ports = 6667, 6668, 6669
# Additional Listen Ports that expect SSL/TLS encrypted connections
;SSLPorts = 9999,6668
;SSLPorts = 6697, 9999
# SSL Server Key
;SSLKeyFile = /usr/local/etc/ngircd/ssl/server-key.pem
@@ -57,18 +62,24 @@
# Diffie-Hellman parameters
;SSLDHFile = /usr/local/etc/ngircd/ssl/dhparams.pem
# comma seperated list of IP addresses on which the server should
# comma separated 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
# Syslog "facility" to which ngIRCd should send log messages.
# Possible values are system dependant, but most probably auth, daemon,
# user and local1 through local7 are possible values; see syslog(3).
# Default is "local5" for historical reasons, you probably want to
# change this to "daemon", for example.
SyslogFacility = local1
# Text file with the "message of the day" (MOTD). This message will
# be shown to all users connecting to the server:
;MotdFile = /usr/local/etc/ngircd.motd
# 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.
;MotdPhrase = "Hello world!"
# User ID under which the server should run; you can use the name
@@ -116,6 +127,10 @@
# server? (This is a compatibility hack for ircd-irc2 servers)
;OperServerMode = no
# Are remote IRC operators allowed to control this server, e. g.
# use commands like CONNECT, SQUIT, DIE, ...?
;AllowRemoteOper = no
# Allow Pre-Defined Channels only (see Section [Channels])
;PredefChannelsOnly = no
@@ -126,6 +141,13 @@
# with support for it.
;NoIdent = no
# Don't use PAM, even if ngIRCd has been compiled with support for it.
;NoPAM = no
# Don't use ZeroConf service registration, even if ngIRCd has been
# compiled with support for it (e.g. Howl, Avahi, Mac OS X).
;NoZeroConf = no
# try to connect to other irc servers using ipv4 and ipv6, if possible
;ConnectIPv6 = yes
;ConnectIPv4 = yes
@@ -213,13 +235,13 @@
# Connect to the remote server using TLS/SSL (Default: false)
;SSLConnect = yes
# Define a (case insensitive) mask matching nick names that sould be
# Define a (case insensitive) mask matching nick names that should 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
# "NickServ" and "ChanServ", you should set this parameter to
# something like "*Serv".
;ServiceMask = *Serv
@@ -246,6 +268,10 @@
# initial channel password (mode k)
;Key = Secret
# Key file, syntax for each line: "<user>:<nick>:<key>".
# Default: none.
;KeyFile = /etc/ngircd/#chan.key
# maximum users per channel (mode l)
;MaxUsers = 23

View File

@@ -3,7 +3,7 @@
<p>
ngIRCd
<a href="http://ngircd.barton.de/">Homepage</a>,
<a href="http://arthur.barton.de/cgi-bin/viewcvs.cgi/ngircd/">CVS-Repository</a>,
<a href="http://ngircd.barton.de/cgi-bin/gitweb.cgi?p=ngircd.git">GIT-Repository</a>,
<a href="http://ngircd.barton.de/bugzilla/index.cgi">Bug-Tracker</a>.
</p>

View File

@@ -1,7 +1,7 @@
.\"
.\" $Id: ngircd.8.tmpl,v 1.2 2007/11/15 01:03:29 fw Exp $
.\" ngircd(8) manual page template
.\"
.TH ngircd 8 "May 2008" ngircd "ngIRCd Manual"
.TH ngircd 8 "Dec 2008" ngircd "ngIRCd Manual"
.SH NAME
ngIRCd \- the next generation IRC daemon
.SH SYNOPSIS
@@ -64,15 +64,16 @@ The system wide default configuration file.
.RS
Default "message of the day" (MOTD).
.RE
.SH HINTS
It's wise to use "ngircd \-\-configtest" to validate the configuration file
after changing it.
.SH AUTHOR
Alexander Barton,
.UR mailto:alex@barton.de
alex@barton.de
.UE
.br
Homepage:
.UR http://ngircd.barton.de/
http://ngircd.barton.de/
.UE
.SH "SEE ALSO"
.BR ngircd.conf (5),

View File

@@ -1,7 +1,7 @@
.\"
.\" $Id: ngircd.conf.5.tmpl,v 1.7 2007/11/23 16:26:03 fw Exp $
.\" ngircd.conf(5) manual page template
.\"
.TH ngircd.conf 5 "May 2008" ngircd "ngIRCd Manual"
.TH ngircd.conf 5 "Dec 2008" ngircd "ngIRCd Manual"
.SH NAME
ngircd.conf \- configuration file of ngIRCd
.SH SYNOPSIS
@@ -12,6 +12,9 @@ is the configuration file of the
.BR ngircd (8)
Internet Relay Chat (IRC) daemon which you should adept to your local
preferences and needs.
.PP
Most variables can be modified while the ngIRCd daemon is already running:
It will reload its configuration when a HUP signal is received.
.SH "FILE FORMAT"
The file consists of sections and parameters. A section begins with the name
of the section in square brackets and continues until the next section
@@ -58,23 +61,36 @@ 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, must contain at least one dot (".").
Server name in the IRC network. This is an individual name of the IRC
server, it is not related to the DNS host name. It must be unique in the
IRC network and must contain at least one dot (".") character.
.TP
\fBInfo\fR
Info text of the server. This will be shown by WHOIS and LINKS requests for
example.
.TP
\fBPassword\fR
Global password for all users needed to connect to the server. The default
is empty, so no password is required.
.TP
\fBWebircPassword\fR
Password required for using the WEBIRC command used by some Web-to-IRC
gateways. If not set or empty, the WEBIRC command can't be used.
Default: not set.
.TP
\fBAdminInfo1\fR, \fBAdminInfo2\fR, \fBAdminEMail\fR
Information about the server and the administrator, used by the ADMIN
command.
.TP
\fBPorts\fR
Ports on which the server should listen. There may be more than one port,
separated with ','. Default: 6667.
separated with commas (","). Default: 6667, unless \fBSSL_Ports\fR are also
specified.
.TP
\fBSSLPorts\fR
Same as \fBPorts\fR , except that ngircd will expect incoming connections
to be SSL/TLS encrypted. Default: None
Same as \fBPorts\fR , except that ngIRCd will expect incoming connections
to be SSL/TLS encrypted. Common port numbers for SSL-encrypted IRC are 6669
and 6697. Default: none.
.TP
\fBSSLKeyFile\fR
Filename of SSL Server Key to be used for SSL connections. This is required for
@@ -84,30 +100,36 @@ SSL/TLS support.
(OpenSSL only:) Password to decrypt private key.
.TP
\fBSSLCertFile\fR
Certificate of the private key
Certificate file 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
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
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
A comma separated 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
\fBSyslogFacility\fR
Syslog "facility" to which ngIRCd should send log messages. Possible
values are system dependant, but most probably "auth", "daemon", "user"
and "local1" through "local7" are possible values; see syslog(3).
Default is "local5" for historical reasons, you probably want to
change this to "daemon", for example.
.TP
\fBMotdFile\fR
Text file with the "message of the day" (MOTD). This message will be shown
to all users connecting to the server.
to all users connecting to the server. Changes made to this file
take effect when ngircd is instructed to re-read its configuration file.
.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 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
@@ -168,35 +190,52 @@ Should IRC Operators be allowed to use the MODE command even if they are
not(!) channel-operators? Default: no.
.TP
\fBOperServerMode\fR
If OperCanUseMode is enabled, this may lead the compatibility problems with
If \fBOperCanUseMode\fR 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
\fBAllowRemoteOper\fR
Are IRC operators connected to remote servers allowed to control this server,
e. g. are they allowed to use administrative commands like CONNECT, DIE,
SQUIT, ... that affect this 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.
[Channel] sections in the configuration 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
If set to true, ngIRCd will not make DNS lookups when clients connect.
If you configure the daemon to connect to other servers, ngIRCd may still
perform a DNS lookup if required.
Default: false.
Default: no.
.TP
\fBNoIdent\fR
If ngircd is compiled with IDENT support this can be used to disable IDENT
If ngIRCd is compiled with IDENT support this can be used to disable IDENT
lookups at run time.
Default: false.
Default: no.
.TP
\fBNoPAM\fR
If ngIRCd is compiled with PAM support this can be used to disable all calls
to the PAM library at runtime; all users connecting without password are
allowed to connect, all passwords given will fail.
Default: no.
.TP
\fBNoZeroConf\fR
If ngIRCd is compiled to register its services using ZeroConf (e.g. using
Howl, Avahi or on Mac OS X) this parameter can be used to disable service
registration at runtime.
Default: no.
.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.
Set this to no if you do not want ngIRCd to connect to other IRC servers using
IPv4. This allows usage 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.
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 in- and outbound connections the server is
@@ -215,8 +254,6 @@ Default: 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!
\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
@@ -257,21 +294,21 @@ IRC name of the remote server.
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
IP address to use as source IP for the outgoing connection. Default is
to let the operating system decide.
.TP
\fBPort\fR
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).
incoming connections (passive, default).
.TP
\fBMyPassword\fR
Own password for this connection. This password has to be configured as
"PeerPassword" on the other server. Must not have ':' as first character.
\fBPeerPassword\fR on the other server. Must not have ':' as first character.
.TP
\fBPeerPassword\fR
Foreign password for this connection. This password has to be configured as
"MyPassword" on the other server.
\fBMyPassword\fR on the other server.
.TP
\fBGroup\fR
Group of this server (optional).
@@ -280,14 +317,17 @@ Group of this server (optional).
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
\fBSSLConnect\fR
Connect to the remote server using TLS/SSL. Default: false.
.TP
\fBServiceMask\fR
Define a (case insensitive) mask matching nick names that sould be treated as
Define a (case insensitive) mask matching nick names that should 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",
"virtual users" to communicate with, for example "NickServ" and "ChanServ",
you should set this parameter to something like "*Serv".
.SH [CHANNEL]
Pre-defined channels can be configured in
@@ -303,7 +343,7 @@ There may be more than one
block.
.TP
\fBName\fR
Name of the channel, including channel prefix ("#").
Name of the channel, including channel prefix ("#" or "&").
.TP
\fBTopic\fR
Topic for this channel.
@@ -312,10 +352,54 @@ Topic for this channel.
Initial channel modes.
.TP
\fBKey\fR
Sets initial channel key (only relevant if mode k is set).
Sets initial channel key (only relevant if channel mode "k" is set).
.TP
\fBKeyFile\fR
Path and file name of a "key file" containing individual channel keys for
different users. The file consists of plain text lines with the following
syntax (without spaces!):
.PP
.RS
.RS
.I user
:
.I nick
:
.I key
.RE
.PP
.I user
and
.I nick
can contain the wildcard character "*".
.br
.I key
is an arbitrary password.
.PP
Valid examples are:
.PP
.RS
*:*:KeY
.br
*:nick:123
.br
~user:*:xyz
.RE
.PP
The key file is read on each JOIN command when this channel has a key
(channel mode +k). Access is granted, if a) the channel key set using the
MODE +k command or b) one of the lines in the key file match.
.PP
.B Please note:
.br
The file is not reopened on each access, so you can modify and overwrite it
without problems, but moving or deleting the file will have not effect until
the daemon re-reads its configuration!
.RE
.TP
\fBMaxUsers\fR
Set maximum user limit for this channel (only relevant if mode l is set).
Set maximum user limit for this channel (only relevant if channel mode "l"
is set).
.SH HINTS
It's wise to use "ngircd \-\-configtest" to validate the configuration file
after changing it. See
@@ -324,12 +408,10 @@ for details.
.SH AUTHOR
Alexander Barton,
.UR mailto:alex@barton.de
alex@barton.de
.UE
.br
Homepage:
.UR http://ngircd.barton.de/
http://ngircd.barton.de/
.UE
.SH "SEE ALSO"
.BR ngircd (8)

View File

@@ -30,6 +30,9 @@ ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICHOST;
#ifndef WANT_IPV6 /* do not convert ipv6 addresses */
hints.ai_family = AF_INET;
#endif
/* some getaddrinfo implementations require that ai_socktype is set. */
hints.ai_socktype = SOCK_STREAM;
@@ -38,7 +41,6 @@ ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
snprintf(portstr, sizeof(portstr), "%u", (unsigned int) port);
ret = getaddrinfo(ip_str, portstr, &hints, &res0);
assert(ret == 0);
if (ret != 0)
return false;
@@ -51,6 +53,10 @@ ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
return ret == 0;
#else /* HAVE_GETADDRINFO */
assert(ip_str);
memset(addr, 0, sizeof *addr);
#ifdef HAVE_sockaddr_in_len
addr->sin4.sin_len = sizeof(addr->sin4);
#endif
addr->sin4.sin_family = AF_INET;
# ifdef HAVE_INET_ATON
if (inet_aton(ip_str, &addr->sin4.sin_addr) == 0)
@@ -151,7 +157,8 @@ ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *str)
if (*str == ':') {
char tmp[NG_INET_ADDRSTRLEN] = "0";
ret = getnameinfo(sa, ng_ipaddr_salen(addr),
tmp+1, sizeof(tmp) -1, NULL, 0, NI_NUMERICHOST);
tmp + 1, (socklen_t)sizeof(tmp) - 1,
NULL, 0, NI_NUMERICHOST);
if (ret == 0)
strlcpy(str, tmp, NG_INET_ADDRSTRLEN);
}

View File

@@ -8,6 +8,7 @@
#define NG_IPADDR_HDR
#include "portab.h"
#include <assert.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -58,10 +59,10 @@ 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);
return (socklen_t)sizeof(a->sin6);
#endif
assert(a->sin4.sin_family == AF_INET);
return sizeof(a->sin4);
return (socklen_t)sizeof(a->sin4);
}
@@ -115,4 +116,3 @@ ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *d)
#endif
/* -eof- */

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-2010 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.51 2008/02/26 22:04:17 fw Exp $
#
AUTOMAKE_OPTIONS = ../portab/ansi2knr
@@ -23,7 +21,7 @@ sbin_PROGRAMS = ngircd
ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.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 numeric.c parse.c rendezvous.c resolve.c
match.c op.c numeric.c pam.c parse.c proc.c rendezvous.c resolve.c sighandlers.c
ngircd_LDFLAGS = -L../portab -L../tool -L../ipaddr
@@ -32,8 +30,8 @@ ngircd_LDADD = -lngportab -lngtool -lngipaddr
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
irc-write.h lists.h log.h match.h numeric.h op.h pam.h parse.h proc.h \
rendezvous.h resolve.h sighandlers.h defines.h messages.h
clean-local:
rm -f check-version check-help lint.out

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2009 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,23 +22,23 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <strings.h>
#include "defines.h"
#include "conn-func.h"
#include "client.h"
#include "exp.h"
#include "channel.h"
#include "imp.h"
#include "irc-write.h"
#include "resolve.h"
#include "conf.h"
#include "hash.h"
#include "lists.h"
#include "log.h"
#include "messages.h"
#include "match.h"
#include "exp.h"
@@ -57,7 +57,9 @@ static CL2CHAN *Add_Client PARAMS(( CHANNEL *Chan, CLIENT *Client ));
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 ));
static void Delete_Channel PARAMS(( CHANNEL *Chan ));
static void Free_Channel PARAMS(( CHANNEL *Chan ));
static void Set_KeyFile PARAMS((CHANNEL *Chan, const char *KeyFile));
GLOBAL void
@@ -97,58 +99,70 @@ Channel_InitPredefined( void )
{
/* Generate predefined persistent channels */
CHANNEL *chan;
char *c;
unsigned int i;
CHANNEL *new_chan;
const struct Conf_Channel *conf_chan;
const char *c;
size_t i, channel_count = array_length(&Conf_Channels, sizeof(*conf_chan));
for( i = 0; i < Conf_Channel_Count; i++ )
{
/* Check for Name configuration */
if( ! Conf_Channel[i].name[0] ) continue;
conf_chan = array_start(&Conf_Channels);
/* 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 );
array_free(&Conf_Channel[i].topic);
assert(channel_count == 0 || conf_chan != NULL);
for (i = 0; i < channel_count; i++, conf_chan++) {
if (!conf_chan->name[0] || !Channel_IsValidName(conf_chan->name)) {
Log(LOG_ERR, "Can't create pre-defined channel: invalid name: \"%s\"",
conf_chan->name);
continue;
}
/* Check if the channel name is already in use */
chan = Channel_Search( Conf_Channel[i].name );
if( chan )
{
Log( LOG_INFO, "Can't create pre-defined channel \"%s\": name already in use.", Conf_Channel[i].name );
array_free(&Conf_Channel[i].topic);
new_chan = Channel_Search(conf_chan->name);
if (new_chan) {
Log(LOG_INFO,
"Can't create pre-defined channel \"%s\": name already in use.",
conf_chan->name);
Set_KeyFile(new_chan, conf_chan->keyfile);
continue;
}
/* Create channel */
chan = Channel_Create(Conf_Channel[i].name);
if (chan) {
Channel_ModeAdd(chan, 'P');
if (array_start(&Conf_Channel[i].topic) != NULL)
Channel_SetTopic(chan, NULL,
array_start(&Conf_Channel[i].topic));
array_free(&Conf_Channel[i].topic);
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 );
new_chan = Channel_Create(conf_chan->name);
if (!new_chan) {
Log(LOG_ERR, "Can't create pre-defined channel \"%s\"",
conf_chan->name);
continue;
}
else Log(LOG_ERR, "Can't create pre-defined channel \"%s\"!",
Conf_Channel[i].name );
Log(LOG_INFO, "Created pre-defined channel \"%s\"",
conf_chan->name);
Channel_ModeAdd(new_chan, 'P');
if (conf_chan->topic[0])
Channel_SetTopic(new_chan, NULL, conf_chan->topic);
c = conf_chan->modes;
while (*c)
Channel_ModeAdd(new_chan, *c++);
Channel_SetKey(new_chan, conf_chan->key);
Channel_SetMaxUsers(new_chan, conf_chan->maxusers);
Set_KeyFile(new_chan, conf_chan->keyfile);
}
if (channel_count)
array_free(&Conf_Channels);
} /* Channel_InitPredefined */
static void
Free_Channel(CHANNEL *chan)
{
array_free(&chan->topic);
array_free(&chan->keyfile);
Lists_Free(&chan->list_bans);
Lists_Free(&chan->list_invites);
free(chan);
}
GLOBAL void
Channel_Exit( void )
{
@@ -157,20 +171,17 @@ Channel_Exit( void )
/* free struct Channel */
c = My_Channels;
while( c )
{
while (c) {
c_next = c->next;
array_free(&c->topic);
free( c );
Free_Channel(c);
c = c_next;
}
/* Free Channel allocation table */
cl2chan = My_Cl2Chan;
while( c )
{
while (cl2chan) {
cl2chan_next = cl2chan->next;
free( cl2chan );
free(cl2chan);
cl2chan = cl2chan_next;
}
} /* Channel_Exit */
@@ -185,7 +196,7 @@ Channel_Exit( void )
* Add_Client().
*/
GLOBAL bool
Channel_Join( CLIENT *Client, char *Name )
Channel_Join( CLIENT *Client, const char *Name )
{
CHANNEL *chan;
@@ -312,7 +323,7 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
GLOBAL void
Channel_Quit( CLIENT *Client, char *Reason )
Channel_Quit( CLIENT *Client, const char *Reason )
{
CHANNEL *c, *next_c;
@@ -690,7 +701,7 @@ Channel_TopicWho(CHANNEL *Chan)
GLOBAL void
Channel_SetTopic(CHANNEL *Chan, CLIENT *Client, char *Topic)
Channel_SetTopic(CHANNEL *Chan, CLIENT *Client, const char *Topic)
{
size_t len;
assert( Chan != NULL );
@@ -718,7 +729,7 @@ Channel_SetTopic(CHANNEL *Chan, CLIENT *Client, char *Topic)
GLOBAL void
Channel_SetModes( CHANNEL *Chan, char *Modes )
Channel_SetModes( CHANNEL *Chan, const char *Modes )
{
assert( Chan != NULL );
assert( Modes != NULL );
@@ -728,7 +739,7 @@ Channel_SetModes( CHANNEL *Chan, char *Modes )
GLOBAL void
Channel_SetKey( CHANNEL *Chan, char *Key )
Channel_SetKey( CHANNEL *Chan, const char *Key )
{
assert( Chan != NULL );
assert( Key != NULL );
@@ -806,7 +817,7 @@ Channel_Write(CHANNEL *Chan, CLIENT *From, CLIENT *Client, const char *Command,
GLOBAL CHANNEL *
Channel_Create( char *Name )
Channel_Create( const char *Name )
{
/* Create new CHANNEL structure and add it to linked list */
CHANNEL *c;
@@ -870,7 +881,7 @@ Add_Client( CHANNEL *Chan, CLIENT *Client )
cl2chan->next = My_Cl2Chan;
My_Cl2Chan = cl2chan;
Log( LOG_DEBUG, "User \"%s\" joined channel \"%s\".", Client_Mask( Client ), Chan->name );
LogDebug("User \"%s\" joined channel \"%s\".", Client_Mask(Client), Chan->name);
return cl2chan;
} /* Add_Client */
@@ -1029,7 +1040,7 @@ Channel_ShowInvites( CLIENT *Client, CHANNEL *Channel )
* Log a message to the local &SERVER channel, if it exists.
*/
GLOBAL void
Channel_LogServer(char *msg)
Channel_LogServer(const char *msg)
{
CHANNEL *sc;
CLIENT *c;
@@ -1045,6 +1056,56 @@ Channel_LogServer(char *msg)
} /* Channel_LogServer */
GLOBAL bool
Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const char *Key)
{
char *file_name, line[COMMAND_LEN], *nick, *pass;
FILE *fd;
assert(Chan != NULL);
assert(Client != NULL);
assert(Key != NULL);
if (!strchr(Chan->modes, 'k'))
return true;
if (strcmp(Chan->key, Key) == 0)
return true;
if (*Key == '\0')
return false;
file_name = array_start(&Chan->keyfile);
if (!file_name)
return false;
fd = fopen(file_name, "r");
if (!fd) {
Log(LOG_ERR, "Can't open channel key file \"%s\" for %s: %s",
file_name, Chan->name, strerror(errno));
return false;
}
while (fgets(line, (int)sizeof(line), fd) != NULL) {
ngt_TrimStr(line);
if (! (nick = strchr(line, ':')))
continue;
*nick++ = '\0';
if (!Match(line, Client_User(Client)))
continue;
if (! (pass = strchr(nick, ':')))
continue;
*pass++ = '\0';
if (!Match(nick, Client_ID(Client)))
continue;
if (strcmp(Key, pass) != 0)
continue;
fclose(fd);
return true;
}
fclose(fd);
return false;
} /* Channel_CheckKey */
static CL2CHAN *
Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan )
{
@@ -1070,35 +1131,64 @@ Get_Next_Cl2Chan( CL2CHAN *Start, CLIENT *Client, CHANNEL *Channel )
} /* Get_Next_Cl2Chan */
static bool
Delete_Channel( CHANNEL *Chan )
/**
* Remove a channel and free all of its data structures.
*/
static void
Delete_Channel(CHANNEL *Chan)
{
/* delete channel structure */
CHANNEL *chan, *last_chan;
last_chan = NULL;
chan = My_Channels;
while( chan )
{
if( chan == Chan ) break;
while (chan) {
if (chan == Chan)
break;
last_chan = chan;
chan = chan->next;
}
if( ! chan ) return false;
Log( LOG_DEBUG, "Freed channel structure for \"%s\".", Chan->name );
/* free invite and ban lists */
Lists_Free( &chan->list_bans );
Lists_Free( &chan->list_invites );
assert(chan != NULL);
if (!chan)
return;
/* maintain channel list */
if( last_chan ) last_chan->next = chan->next;
else My_Channels = chan->next;
free( chan );
if (last_chan)
last_chan->next = chan->next;
else
My_Channels = chan->next;
return true;
LogDebug("Freed channel structure for \"%s\".", Chan->name);
Free_Channel(Chan);
} /* Delete_Channel */
static void
Set_KeyFile(CHANNEL *Chan, const char *KeyFile)
{
size_t len;
assert(Chan != NULL);
assert(KeyFile != NULL);
len = strlen(KeyFile);
if (len < array_bytes(&Chan->keyfile)) {
Log(LOG_INFO, "Channel key file of %s removed.", Chan->name);
array_free(&Chan->keyfile);
}
if (len < 1)
return;
if (!array_copyb(&Chan->keyfile, KeyFile, len+1))
Log(LOG_WARNING,
"Could not set new channel key file \"%s\" for %s: %s",
KeyFile, Chan->name, strerror(errno));
else
Log(LOG_INFO|LOG_snotice,
"New local channel key file \"%s\" for %s activated.",
KeyFile, Chan->name);
} /* Set_KeyFile */
/* -eof- */

View File

@@ -37,6 +37,7 @@ typedef struct _CHANNEL
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 */
array keyfile; /* Name of the channel key file */
} CHANNEL;
typedef struct _CLIENT2CHAN
@@ -61,10 +62,10 @@ 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_Join PARAMS(( CLIENT *Client, const char *Name ));
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_Quit PARAMS(( CLIENT *Client, const char *Reason ));
GLOBAL void Channel_Kick PARAMS((CLIENT *Peer, CLIENT *Target, CLIENT *Origin,
const char *Name, const char *Reason));
@@ -79,9 +80,9 @@ GLOBAL char *Channel_Topic PARAMS(( CHANNEL *Chan ));
GLOBAL char *Channel_Key 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_SetTopic PARAMS(( CHANNEL *Chan, CLIENT *Client, const char *Topic ));
GLOBAL void Channel_SetModes PARAMS(( CHANNEL *Chan, const char *Modes ));
GLOBAL void Channel_SetKey PARAMS(( CHANNEL *Chan, const char *Key ));
GLOBAL void Channel_SetMaxUsers PARAMS(( CHANNEL *Chan, unsigned long Count ));
GLOBAL CHANNEL *Channel_Search PARAMS(( const char *Name ));
@@ -112,7 +113,7 @@ 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 ));
GLOBAL CHANNEL *Channel_Create PARAMS(( const char *Name ));
#ifndef STRICT_RFC
GLOBAL unsigned int Channel_TopicTime PARAMS(( CHANNEL *Chan ));
@@ -125,10 +126,13 @@ 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));
GLOBAL void Channel_LogServer PARAMS((const char *msg));
GLOBAL bool Channel_CheckKey PARAMS((CHANNEL *Chan, CLIENT *Client,
const char *Key));
#define Channel_IsLocal(c) (Channel_Name(c)[0] == '&')
#define Channel_IsModeless(c) (Channel_Name(c)[0] == '+')
#endif

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 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
@@ -35,7 +35,6 @@
#include <imp.h>
#include "ngircd.h"
#include "channel.h"
#include "resolve.h"
#include "conf.h"
#include "hash.h"
#include "irc-write.h"
@@ -49,7 +48,6 @@
static CLIENT *This_Server, *My_Clients;
static char GetID_Buffer[GETID_LEN];
static WHOWAS My_Whowas[MAX_WHOWAS];
static int Last_Whowas = -1;
@@ -64,12 +62,12 @@ 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,
CLIENT *TopServer, int Type, const char *ID,
const char *User, const char *Hostname, const char *Info,
int Hops, int Token, const char *Modes,
bool Idented));
static void Destroy_UserOrService PARAMS((CLIENT *Client, char *Txt, char *FwdMsg,
static void Destroy_UserOrService PARAMS((CLIENT *Client,const char *Txt, const char *FwdMsg,
bool SendQuit));
@@ -142,7 +140,7 @@ Client_ThisServer( void )
* @return New CLIENT structure.
*/
GLOBAL CLIENT *
Client_NewLocal(CONN_ID Idx, char *Hostname, int Type, bool Idented)
Client_NewLocal(CONN_ID Idx, const char *Hostname, int Type, bool Idented)
{
return Init_New_Client(Idx, This_Server, NULL, Type, NULL, NULL,
Hostname, NULL, 0, 0, NULL, Idented);
@@ -154,8 +152,8 @@ Client_NewLocal(CONN_ID Idx, char *Hostname, int Type, bool Idented)
* @return New CLIENT structure.
*/
GLOBAL CLIENT *
Client_NewRemoteServer(CLIENT *Introducer, char *Hostname, CLIENT *TopServer,
int Hops, int Token, char *Info, bool Idented)
Client_NewRemoteServer(CLIENT *Introducer, const char *Hostname, CLIENT *TopServer,
int Hops, int Token, const char *Info, bool Idented)
{
return Init_New_Client(NONE, Introducer, TopServer, CLIENT_SERVER,
Hostname, NULL, Hostname, Info, Hops, Token, NULL, Idented);
@@ -167,8 +165,8 @@ Client_NewRemoteServer(CLIENT *Introducer, char *Hostname, CLIENT *TopServer,
* @return New CLIENT structure.
*/
GLOBAL CLIENT *
Client_NewRemoteUser(CLIENT *Introducer, char *Nick, int Hops, char *User,
char *Hostname, int Token, char *Modes, char *Info, bool Idented)
Client_NewRemoteUser(CLIENT *Introducer, const char *Nick, int Hops, const char *User,
const char *Hostname, int Token, const char *Modes, const char *Info, bool Idented)
{
return Init_New_Client(NONE, Introducer, NULL, CLIENT_USER, Nick,
User, Hostname, Info, Hops, Token, Modes, Idented);
@@ -182,54 +180,61 @@ Client_NewRemoteUser(CLIENT *Introducer, char *Nick, int Hops, char *User,
*/
static CLIENT *
Init_New_Client(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)
int Type, const char *ID, const char *User, const char *Hostname,
const char *Info, int Hops, int Token, const char *Modes, bool Idented)
{
CLIENT *client;
assert( Idx >= NONE );
assert( Introducer != NULL );
assert( Hostname != NULL );
assert(Idx >= NONE);
assert(Introducer != NULL);
assert(Hostname != NULL);
client = New_Client_Struct( );
if( ! client ) return NULL;
client = New_Client_Struct();
if (!client)
return NULL;
/* Initialisieren */
client->starttime = time(NULL);
client->conn_id = Idx;
client->introducer = Introducer;
client->topserver = TopServer;
client->type = Type;
if( ID ) Client_SetID( client, ID );
if( User ) Client_SetUser( client, User, Idented );
if( Hostname ) Client_SetHostname( client, Hostname );
if( Info ) Client_SetInfo( client, Info );
if (ID)
Client_SetID(client, ID);
if (User) {
Client_SetUser(client, User, Idented);
Client_SetOrigUser(client, User);
}
if (Hostname)
Client_SetHostname(client, Hostname);
if (Info)
Client_SetInfo(client, Info);
client->hops = Hops;
client->token = Token;
if( Modes ) Client_SetModes( client, Modes );
if( Type == CLIENT_SERVER ) Generate_MyToken( client );
if (Modes)
Client_SetModes(client, Modes);
if (Type == CLIENT_SERVER)
Generate_MyToken(client);
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;
My_Clients = client;
/* Adjust counters */
Adjust_Counters( client );
Adjust_Counters(client);
return client;
} /* Init_New_Client */
GLOBAL void
Client_Destroy( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit )
Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool SendQuit )
{
/* Client entfernen. */
/* remove a client */
CLIENT *last, *c;
char msg[LINE_LEN], *txt;
char msg[LINE_LEN];
const char *txt;
assert( Client != NULL );
@@ -237,7 +242,7 @@ Client_Destroy( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit )
else txt = FwdMsg;
if( ! txt ) txt = "Reason unknown.";
/* Netz-Split-Nachricht vorbereiten (noch nicht optimal) */
/* netsplit message */
if( Client->type == CLIENT_SERVER ) {
strlcpy(msg, This_Server->id, sizeof (msg));
strlcat(msg, " ", sizeof (msg));
@@ -250,8 +255,16 @@ Client_Destroy( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit )
{
if(( Client->type == CLIENT_SERVER ) && ( c->introducer == Client ) && ( c != Client ))
{
/* der Client, der geloescht wird ist ein Server. Der Client, den wir gerade
* pruefen, ist ein Child von diesem und muss daher auch entfernt werden */
/*
* The client that is about to be removed is a server,
* the client we are checking right now is a child of that
* server and thus has to be removed, too.
*
* Call Client_Destroy() recursively with the server as the
* new "object to be removed". This starts the cycle again, until
* all servers that are linked via the original server have been
* removed.
*/
Client_Destroy( c, NULL, msg, false );
last = NULL;
c = My_Clients;
@@ -259,7 +272,7 @@ Client_Destroy( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit )
}
if( c == Client )
{
/* Wir haben den Client gefunden: entfernen */
/* found the client: remove it */
if( last ) last->next = c->next;
else My_Clients = (CLIENT *)c->next;
@@ -273,7 +286,7 @@ Client_Destroy( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit )
else Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" unregistered: %s", c->id, txt );
}
/* andere Server informieren */
/* inform other servers */
if( ! NGIRCd_SignalQuit )
{
if( FwdMsg ) IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "SQUIT %s :%s", c->id, FwdMsg );
@@ -302,10 +315,8 @@ Client_Destroy( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit )
GLOBAL void
Client_SetHostname( CLIENT *Client, char *Hostname )
Client_SetHostname( CLIENT *Client, const char *Hostname )
{
/* Hostname eines Clients setzen */
assert( Client != NULL );
assert( Hostname != NULL );
@@ -314,10 +325,8 @@ Client_SetHostname( CLIENT *Client, char *Hostname )
GLOBAL void
Client_SetID( CLIENT *Client, char *ID )
Client_SetID( CLIENT *Client, const char *ID )
{
/* Hostname eines Clients setzen, Hash-Wert berechnen */
assert( Client != NULL );
assert( ID != NULL );
@@ -329,72 +338,87 @@ Client_SetID( CLIENT *Client, char *ID )
GLOBAL void
Client_SetUser( CLIENT *Client, char *User, bool Idented )
Client_SetUser( CLIENT *Client, const char *User, bool Idented )
{
/* Username eines Clients setzen */
/* set clients username */
assert( Client != NULL );
assert( User != NULL );
if( Idented ) strlcpy( Client->user, User, sizeof( Client->user ));
else
{
if (Idented) {
strlcpy(Client->user, User, sizeof(Client->user));
} else {
Client->user[0] = '~';
strlcpy( Client->user + 1, User, sizeof( Client->user ) - 1 );
strlcpy(Client->user + 1, User, sizeof(Client->user) - 1);
}
} /* Client_SetUser */
/**
* Set "original" user name of a client.
* This function saves the "original" user name, the user name specified by
* the peer using the USER command, into the CLIENT structure. This user
* name may be used for authentication, for example.
* @param Client The client.
* @param User User name to set.
*/
GLOBAL void
Client_SetInfo( CLIENT *Client, char *Info )
Client_SetOrigUser(CLIENT UNUSED *Client, const char UNUSED *User) {
assert(Client != NULL);
assert(User != NULL);
#if defined(PAM) && defined(IDENTAUTH)
strlcpy(Client->orig_user, User, sizeof(Client->orig_user));
#endif
} /* Client_SetOrigUser */
GLOBAL void
Client_SetInfo( CLIENT *Client, const char *Info )
{
/* Hostname eines Clients setzen */
/* set client hostname */
assert( Client != NULL );
assert( Info != NULL );
strlcpy( Client->info, Info, sizeof( Client->info ));
strlcpy(Client->info, Info, sizeof(Client->info));
} /* Client_SetInfo */
GLOBAL void
Client_SetModes( CLIENT *Client, char *Modes )
Client_SetModes( CLIENT *Client, const char *Modes )
{
/* Modes eines Clients setzen */
assert( Client != NULL );
assert( Modes != NULL );
strlcpy( Client->modes, Modes, sizeof( Client->modes ));
strlcpy(Client->modes, Modes, sizeof( Client->modes ));
} /* Client_SetModes */
GLOBAL void
Client_SetFlags( CLIENT *Client, char *Flags )
Client_SetFlags( CLIENT *Client, const char *Flags )
{
/* Flags eines Clients setzen */
assert( Client != NULL );
assert( Flags != NULL );
strlcpy( Client->flags, Flags, sizeof( Client->flags ));
strlcpy(Client->flags, Flags, sizeof(Client->flags));
} /* Client_SetFlags */
GLOBAL void
Client_SetPassword( CLIENT *Client, char *Pwd )
Client_SetPassword( CLIENT *Client, const char *Pwd )
{
/* Von einem Client geliefertes Passwort */
/* set password sent by client */
assert( Client != NULL );
assert( Pwd != NULL );
strlcpy( Client->pwd, Pwd, sizeof( Client->pwd ));
strlcpy(Client->pwd, Pwd, sizeof(Client->pwd));
} /* Client_SetPassword */
GLOBAL void
Client_SetAway( CLIENT *Client, char *Txt )
Client_SetAway( CLIENT *Client, const char *Txt )
{
/* Set AWAY reason of client */
@@ -463,9 +487,7 @@ Client_ModeAdd( CLIENT *Client, char Mode )
assert( Client != NULL );
x[0] = Mode; x[1] = '\0';
if( ! strchr( Client->modes, x[0] ))
{
/* Client hat den Mode noch nicht -> setzen */
if (!strchr( Client->modes, x[0])) {
strlcat( Client->modes, x, sizeof( Client->modes ));
return true;
}
@@ -518,16 +540,12 @@ Client_Search( const char *Nick )
ptr = strchr( search_id, '!' );
if( ptr ) *ptr = '\0';
search_hash = Hash( search_id );
search_hash = Hash(search_id);
c = My_Clients;
while( c )
{
if( c->hash == search_hash )
{
/* lt. Hash-Wert: Treffer! */
if( strcasecmp( c->id, search_id ) == 0 ) return c;
}
while (c) {
if (c->hash == search_hash && strcasecmp(c->id, search_id) == 0)
return c;
c = (CLIENT *)c->next;
}
return NULL;
@@ -547,9 +565,10 @@ Client_GetFromToken( CLIENT *Client, int Token )
assert( Token > 0 );
c = My_Clients;
while( c )
{
if(( c->type == CLIENT_SERVER ) && ( c->introducer == Client ) && ( c->token == Token )) return c;
while (c) {
if ((c->type == CLIENT_SERVER) && (c->introducer == Client) &&
(c->token == Token))
return c;
c = (CLIENT *)c->next;
}
return NULL;
@@ -603,14 +622,61 @@ Client_User( CLIENT *Client )
} /* Client_User */
#ifdef PAM
/**
* Get the "original" user name as supplied by the USER command.
* The user name as given by the client is used for authentication instead
* of the one detected using IDENT requests.
* @param Client The client.
* @return Original user name.
*/
GLOBAL char *
Client_Hostname( CLIENT *Client )
Client_OrigUser(CLIENT *Client) {
#ifndef IDENTAUTH
char *user = Client->user;
if (user[0] == '~')
user++;
return user;
#else
return Client->orig_user;
#endif
} /* Client_OrigUser */
#endif
/**
* Return the hostname of a client.
* @param Client Pointer to client structure
* @return Pointer to client hostname
*/
GLOBAL char *
Client_Hostname(CLIENT *Client)
{
assert( Client != NULL );
assert (Client != NULL);
return Client->host;
} /* Client_Hostname */
/**
* Get potentially cloaked hostname of a client.
* If the client has not enabled cloaking, the real hostname is used.
* @param Client Pointer to client structure
* @return Pointer to client hostname
*/
GLOBAL char *
Client_HostnameCloaked(CLIENT *Client)
{
assert(Client != NULL);
if (Client_HasMode(Client, 'x'))
return Client_ID(Client->introducer);
else
return Client_Hostname(Client);
} /* Client_HostnameCloaked */
GLOBAL char *
Client_Password( CLIENT *Client )
{
@@ -682,21 +748,57 @@ Client_NextHop( CLIENT *Client )
} /* Client_NextHop */
/**
* Return ID of a client: "client!user@host"
* This client ID is used for IRC prefixes, for example.
* Please note that this function uses a global static buffer, so you can't
* nest invocations without overwriting erlier results!
* @param Client Pointer to client structure
* @return Pointer to global buffer containing the client ID
*/
GLOBAL char *
Client_Mask( CLIENT *Client )
{
/* Client-"ID" liefern, wie sie z.B. fuer
* Prefixe benoetigt wird. */
static char Mask_Buffer[GETID_LEN];
assert( Client != NULL );
assert (Client != NULL);
if( Client->type == CLIENT_SERVER ) return Client->id;
/* Servers: return name only, there is no "mask" */
if (Client->type == CLIENT_SERVER)
return Client->id;
snprintf( GetID_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user, Client->host );
return GetID_Buffer;
snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s",
Client->id, Client->user, Client->host);
return Mask_Buffer;
} /* Client_Mask */
/**
* Return ID of a client with cloaked hostname: "client!user@server-name"
* This client ID is used for IRC prefixes, for example.
* Please note that this function uses a global static buffer, so you can't
* nest invocations without overwriting erlier results!
* If the client has not enabled cloaking, the real hostname is used.
* @param Client Pointer to client structure
* @return Pointer to global buffer containing the client ID
*/
GLOBAL char *
Client_MaskCloaked(CLIENT *Client)
{
static char Mask_Buffer[GETID_LEN];
assert (Client != NULL);
/* Is the client using cloaking at all? */
if (!Client_HasMode(Client, 'x'))
return Client_Mask(Client);
snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s",
Client->id, Client->user, Client_ID(Client->introducer));
return Mask_Buffer;
} /* Client_MaskCloaked */
GLOBAL CLIENT *
Client_Introducer( CLIENT *Client )
{
@@ -724,8 +826,6 @@ Client_HasMode( CLIENT *Client, char Mode )
GLOBAL char *
Client_Away( CLIENT *Client )
{
/* AWAY-Text liefern */
assert( Client != NULL );
return Client->away;
} /* Client_Away */
@@ -737,7 +837,7 @@ Client_CheckNick( CLIENT *Client, char *Nick )
assert( Client != NULL );
assert( Nick != NULL );
if( ! Client_IsValidNick( Nick ))
if (! Client_IsValidNick( Nick ))
{
IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), Nick );
return false;
@@ -758,8 +858,6 @@ Client_CheckNick( CLIENT *Client, char *Nick )
GLOBAL bool
Client_CheckID( CLIENT *Client, char *ID )
{
/* Nick ueberpruefen */
char str[COMMAND_LEN];
CLIENT *c;
@@ -767,24 +865,22 @@ Client_CheckID( CLIENT *Client, char *ID )
assert( Client->conn_id > NONE );
assert( ID != NULL );
/* Nick zu lang? */
if( strlen( ID ) > CLIENT_ID_LEN )
{
IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), ID );
/* ID too long? */
if (strlen(ID) > CLIENT_ID_LEN) {
IRC_WriteStrClient(Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID(Client), ID);
return false;
}
/* ID bereits vergeben? */
/* ID already in use? */
c = My_Clients;
while( c )
{
if( strcasecmp( c->id, ID ) == 0 )
{
/* die Server-ID gibt es bereits */
snprintf( str, sizeof( str ), "ID \"%s\" already registered", ID );
if( Client->conn_id != c->conn_id ) Log( LOG_ERR, "%s (on connection %d)!", str, c->conn_id );
else Log( LOG_ERR, "%s (via network)!", str );
Conn_Close( Client->conn_id, str, str, true);
while (c) {
if (strcasecmp(c->id, ID) == 0) {
snprintf(str, sizeof(str), "ID \"%s\" already registered", ID);
if (c->conn_id != NONE)
Log(LOG_ERR, "%s (on connection %d)!", str, c->conn_id);
else
Log(LOG_ERR, "%s (via network)!", str);
Conn_Close(Client->conn_id, str, str, true);
return false;
}
c = (CLIENT *)c->next;
@@ -797,8 +893,6 @@ Client_CheckID( CLIENT *Client, char *ID )
GLOBAL CLIENT *
Client_First( void )
{
/* Ersten Client liefern. */
return My_Clients;
} /* Client_First */
@@ -806,9 +900,6 @@ Client_First( void )
GLOBAL CLIENT *
Client_Next( CLIENT *c )
{
/* Naechsten Client liefern. Existiert keiner,
* so wird NULL geliefert. */
assert( c != NULL );
return (CLIENT *)c->next;
} /* Client_Next */
@@ -1047,7 +1138,7 @@ Generate_MyToken( CLIENT *Client )
else c = (CLIENT *)c->next;
}
Client->mytoken = token;
Log( LOG_DEBUG, "Assigned token %d to server \"%s\".", token, Client->id );
LogDebug("Assigned token %d to server \"%s\".", token, Client->id);
} /* Generate_MyToken */
@@ -1102,7 +1193,7 @@ Client_RegisterWhowas( CLIENT *Client )
sizeof( My_Whowas[slot].id ));
strlcpy( My_Whowas[slot].user, Client_User( Client ),
sizeof( My_Whowas[slot].user ));
strlcpy( My_Whowas[slot].host, Client_Hostname( Client ),
strlcpy( My_Whowas[slot].host, Client_HostnameCloaked( Client ),
sizeof( My_Whowas[slot].host ));
strlcpy( My_Whowas[slot].info, Client_Info( Client ),
sizeof( My_Whowas[slot].info ));
@@ -1113,7 +1204,7 @@ Client_RegisterWhowas( CLIENT *Client )
} /* Client_RegisterWhowas */
GLOBAL char *
GLOBAL const char *
Client_TypeText(CLIENT *Client)
{
assert(Client != NULL);
@@ -1137,7 +1228,7 @@ Client_TypeText(CLIENT *Client)
* Destroy user or service client.
*/
static void
Destroy_UserOrService(CLIENT *Client, char *Txt, char *FwdMsg, bool SendQuit)
Destroy_UserOrService(CLIENT *Client, const char *Txt, const char *FwdMsg, bool SendQuit)
{
if(Client->conn_id != NONE) {
/* Local (directly connected) client */
@@ -1145,6 +1236,9 @@ Destroy_UserOrService(CLIENT *Client, char *Txt, char *FwdMsg, bool SendQuit)
"%s \"%s\" unregistered (connection %d): %s",
Client_TypeText(Client), Client_Mask(Client),
Client->conn_id, Txt);
Log_ServerNotice('c', "Client exiting: %s (%s@%s) [%s]",
Client_ID(Client), Client_User(Client),
Client_Hostname(Client), Txt);
if (SendQuit) {
/* Inforam all the other servers */
@@ -1180,4 +1274,26 @@ Destroy_UserOrService(CLIENT *Client, char *Txt, char *FwdMsg, bool SendQuit)
} /* Destroy_UserOrService */
#ifdef DEBUG
GLOBAL void
Client_DebugDump(void)
{
CLIENT *c;
Log(LOG_DEBUG, "Client status:");
c = My_Clients;
while (c) {
Log(LOG_DEBUG,
" - %s: type=%d, host=%s, user=%s, conn=%d, start=%ld, flags=%s",
Client_ID(c), Client_Type(c), Client_Hostname(c),
Client_User(c), Client_Conn(c), Client_StartTime(c),
Client_Flags(c));
c = (CLIENT *)c->next;
}
} /* Client_DumpClients */
#endif
/* -eof- */

View File

@@ -43,6 +43,9 @@ typedef struct _CLIENT
char pwd[CLIENT_PASS_LEN]; /* password received of the client */
char host[CLIENT_HOST_LEN]; /* hostname of the client */
char user[CLIENT_USER_LEN]; /* user name ("login") */
#if defined(PAM) && defined(IDENTAUTH)
char orig_user[CLIENT_USER_LEN];/* user name supplied by USER command */
#endif
char info[CLIENT_INFO_LEN]; /* long user name (user) / info text (server) */
char modes[CLIENT_MODE_LEN]; /* client modes */
int hops, token, mytoken; /* "hops" and "Token" (see SERVER command) */
@@ -72,11 +75,11 @@ typedef struct _WHOWAS
GLOBAL void Client_Init PARAMS(( void ));
GLOBAL void Client_Exit PARAMS(( void ));
GLOBAL CLIENT *Client_NewLocal PARAMS(( CONN_ID Idx, char *Hostname, int Type, bool Idented ));
GLOBAL CLIENT *Client_NewRemoteServer PARAMS(( CLIENT *Introducer, char *Hostname, CLIENT *TopServer, int Hops, int Token, char *Info, bool Idented ));
GLOBAL CLIENT *Client_NewRemoteUser PARAMS(( CLIENT *Introducer, char *Nick, int Hops, char *User, char *Hostname, int Token, char *Modes, char *Info, bool Idented ));
GLOBAL CLIENT *Client_NewLocal PARAMS(( CONN_ID Idx, const char *Hostname, int Type, bool Idented ));
GLOBAL CLIENT *Client_NewRemoteServer PARAMS(( CLIENT *Introducer, const char *Hostname, CLIENT *TopServer, int Hops, int Token, const char *Info, bool Idented ));
GLOBAL CLIENT *Client_NewRemoteUser PARAMS(( CLIENT *Introducer, const char *Nick, int Hops, const char *User, const char *Hostname, int Token, const char *Modes, const char *Info, bool Idented ));
GLOBAL void Client_Destroy PARAMS(( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit ));
GLOBAL void Client_Destroy PARAMS(( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool SendQuit ));
GLOBAL CLIENT *Client_ThisServer PARAMS(( void ));
@@ -90,9 +93,14 @@ GLOBAL int Client_Type PARAMS(( CLIENT *Client ));
GLOBAL CONN_ID Client_Conn PARAMS(( CLIENT *Client ));
GLOBAL char *Client_ID PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Mask PARAMS(( CLIENT *Client ));
GLOBAL char *Client_MaskCloaked PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Info PARAMS(( CLIENT *Client ));
GLOBAL char *Client_User PARAMS(( CLIENT *Client ));
#ifdef PAM
GLOBAL char *Client_OrigUser PARAMS(( CLIENT *Client ));
#endif
GLOBAL char *Client_Hostname PARAMS(( CLIENT *Client ));
GLOBAL char *Client_HostnameCloaked PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Password PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Modes PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Flags PARAMS(( CLIENT *Client ));
@@ -108,19 +116,20 @@ GLOBAL time_t Client_StartTime PARAMS(( CLIENT *Client ));
GLOBAL bool Client_HasMode PARAMS(( CLIENT *Client, char Mode ));
GLOBAL void Client_SetHostname PARAMS(( CLIENT *Client, char *Hostname ));
GLOBAL void Client_SetID PARAMS(( CLIENT *Client, char *Nick ));
GLOBAL void Client_SetUser PARAMS(( CLIENT *Client, char *User, bool Idented ));
GLOBAL void Client_SetInfo PARAMS(( CLIENT *Client, char *Info ));
GLOBAL void Client_SetPassword PARAMS(( CLIENT *Client, char *Pwd ));
GLOBAL void Client_SetHostname PARAMS(( CLIENT *Client, const char *Hostname ));
GLOBAL void Client_SetID PARAMS(( CLIENT *Client, const char *Nick ));
GLOBAL void Client_SetUser PARAMS(( CLIENT *Client, const char *User, bool Idented ));
GLOBAL void Client_SetOrigUser PARAMS(( CLIENT *Client, const char *User ));
GLOBAL void Client_SetInfo PARAMS(( CLIENT *Client, const char *Info ));
GLOBAL void Client_SetPassword PARAMS(( CLIENT *Client, const char *Pwd ));
GLOBAL void Client_SetType PARAMS(( CLIENT *Client, int Type ));
GLOBAL void Client_SetHops PARAMS(( CLIENT *Client, int Hops ));
GLOBAL void Client_SetToken PARAMS(( CLIENT *Client, int Token ));
GLOBAL void Client_SetOperByMe PARAMS(( CLIENT *Client, bool OperByMe ));
GLOBAL void Client_SetModes PARAMS(( CLIENT *Client, char *Modes ));
GLOBAL void Client_SetFlags PARAMS(( CLIENT *Client, char *Flags ));
GLOBAL void Client_SetModes PARAMS(( CLIENT *Client, const char *Modes ));
GLOBAL void Client_SetFlags PARAMS(( CLIENT *Client, const char *Flags ));
GLOBAL void Client_SetIntroducer PARAMS(( CLIENT *Client, CLIENT *Introducer ));
GLOBAL void Client_SetAway PARAMS(( CLIENT *Client, char *Txt ));
GLOBAL void Client_SetAway PARAMS(( CLIENT *Client, const char *Txt ));
GLOBAL bool Client_ModeAdd PARAMS(( CLIENT *Client, char Mode ));
GLOBAL bool Client_ModeDel PARAMS(( CLIENT *Client, char Mode ));
@@ -146,8 +155,14 @@ GLOBAL int Client_GetLastWhowasIndex PARAMS(( void ));
GLOBAL void Client_RegisterWhowas PARAMS(( CLIENT *Client ));
GLOBAL char * Client_TypeText PARAMS((CLIENT *Client));
GLOBAL const char *Client_TypeText PARAMS((CLIENT *Client));
#ifdef DEBUG
GLOBAL void Client_DebugDump PARAMS((void));
#endif
#endif
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 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
@@ -39,11 +39,10 @@
#include "array.h"
#include "ngircd.h"
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "defines.h"
#include "log.h"
#include "match.h"
#include "resolve.h"
#include "tool.h"
#include "exp.h"
@@ -54,6 +53,9 @@ static bool Use_Log = true;
static CONF_SERVER New_Server;
static int New_Server_Idx;
static size_t Conf_Oper_Count;
static size_t Conf_Channel_Count;
static char Conf_MotdFile[FNAME_LEN];
static void Set_Defaults PARAMS(( bool InitServers ));
static bool Read_Config PARAMS(( bool ngircd_starting ));
@@ -94,19 +96,46 @@ ConfSSL_Init(void)
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
}
static bool
ssl_print_configvar(const char *name, const char *file)
{
FILE *fp;
static void
if (!file) {
printf(" %s =\n", name);
return true;
}
fp = fopen(file, "r");
if (fp)
fclose(fp);
else
fprintf(stderr, "ERROR: %s \"%s\": %s\n",
name, file, strerror(errno));
printf(" %s = %s\n", name, file);
return fp != NULL;
}
static bool
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);
bool ret;
ret = ssl_print_configvar("SSLKeyFile", Conf_SSLOptions.KeyFile);
if (!ssl_print_configvar("SSLCertFile", Conf_SSLOptions.CertFile))
ret = false;
if (!ssl_print_configvar("SSLDHFile", Conf_SSLOptions.DHFile))
ret = false;
if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
puts(" SSLKeyFilePassword = <secret>" );
puts(" SSLKeyFilePassword = <secret>");
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
return ret;
}
#endif
@@ -151,8 +180,8 @@ ports_parse(array *a, int Line, char *Arg)
* must be separated by "," */
ptr = strtok( Arg, "," );
while (ptr) {
ngt_TrimStr( ptr );
port = atol( ptr );
ngt_TrimStr(ptr);
port = atoi(ptr);
if (port > 0 && port < 0xFFFF) {
port16 = (UINT16) port;
if (!array_catb(a, (char*)&port16, sizeof port16))
@@ -198,6 +227,41 @@ yesno_to_str(int boolean_value)
}
static void
opers_free(void)
{
struct Conf_Oper *op;
size_t len;
len = array_length(&Conf_Opers, sizeof(*op));
op = array_start(&Conf_Opers);
while (len--) {
free(op->mask);
op++;
}
array_free(&Conf_Opers);
}
static void
opers_puts(void)
{
struct Conf_Oper *op;
size_t len;
len = array_length(&Conf_Opers, sizeof(*op));
op = array_start(&Conf_Opers);
while (len--) {
assert(op->name[0]);
puts("[OPERATOR]");
printf(" Name = %s\n", op->name);
printf(" Password = %s\n", op->pwd);
printf(" Mask = %s\n\n", op->mask ? op->mask : "");
op++;
}
}
GLOBAL int
Conf_Test( void )
{
@@ -206,8 +270,9 @@ Conf_Test( void )
struct passwd *pwd;
struct group *grp;
unsigned int i;
char *topic;
bool config_valid;
size_t predef_channel_count;
struct Conf_Channel *predef_chan;
Use_Log = false;
@@ -226,60 +291,65 @@ Conf_Test( void )
}
puts( "[GLOBAL]" );
printf( " Name = %s\n", Conf_ServerName );
printf( " Info = %s\n", Conf_ServerInfo );
printf( " Password = %s\n", Conf_ServerPwd );
printf( " AdminInfo1 = %s\n", Conf_ServerAdmin1 );
printf( " AdminInfo2 = %s\n", Conf_ServerAdmin2 );
printf( " AdminEMail = %s\n", Conf_ServerAdminMail );
printf( " MotdFile = %s\n", Conf_MotdFile );
printf( " MotdPhrase = %s\n", Conf_MotdPhrase );
printf( " ChrootDir = %s\n", Conf_Chroot );
printf( " PidFile = %s\n", Conf_PidFile);
printf(" Name = %s\n", Conf_ServerName);
printf(" Info = %s\n", Conf_ServerInfo);
#ifndef PAM
printf(" Password = %s\n", Conf_ServerPwd);
#endif
printf(" WebircPassword = %s\n", Conf_WebircPwd);
printf(" AdminInfo1 = %s\n", Conf_ServerAdmin1);
printf(" AdminInfo2 = %s\n", Conf_ServerAdmin2);
printf(" AdminEMail = %s\n", Conf_ServerAdminMail);
printf(" MotdFile = %s\n", Conf_MotdFile);
printf(" MotdPhrase = %.32s\n", array_bytes(&Conf_Motd) ? (const char*) array_start(&Conf_Motd) : "");
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();
if (!ConfSSL_Puts())
config_valid = false;
#endif
pwd = getpwuid( Conf_UID );
if( pwd ) printf( " ServerUID = %s\n", pwd->pw_name );
else printf( " ServerUID = %ld\n", (long)Conf_UID );
grp = getgrgid( Conf_GID );
if( grp ) printf( " ServerGID = %s\n", grp->gr_name );
else printf( " ServerGID = %ld\n", (long)Conf_GID );
printf( " PingTimeout = %d\n", Conf_PingTimeout );
printf( " PongTimeout = %d\n", Conf_PongTimeout );
printf( " ConnectRetry = %d\n", Conf_ConnectRetry );
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));
pwd = getpwuid(Conf_UID);
if (pwd)
printf(" ServerUID = %s\n", pwd->pw_name);
else
printf(" ServerUID = %ld\n", (long)Conf_UID);
grp = getgrgid(Conf_GID);
if (grp)
printf(" ServerGID = %s\n", grp->gr_name);
else
printf(" ServerGID = %ld\n", (long)Conf_GID);
#ifdef SYSLOG
printf(" SyslogFacility = %s\n",
ngt_SyslogFacilityName(Conf_SyslogFacility));
#endif
printf(" PingTimeout = %d\n", Conf_PingTimeout);
printf(" PongTimeout = %d\n", Conf_PongTimeout);
printf(" ConnectRetry = %d\n", Conf_ConnectRetry);
printf(" OperCanUseMode = %s\n", yesno_to_str(Conf_OperCanMode));
printf(" OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode));
printf(" AllowRemoteOper = %s\n", yesno_to_str(Conf_AllowRemoteOper));
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));
printf(" NoPAM = %s\n", yesno_to_str(Conf_NoPAM));
printf(" NoZeroConf = %s\n", yesno_to_str(Conf_NoZeroConf));
#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);
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 );
printf( " Password = %s\n", Conf_Oper[i].pwd );
if ( Conf_Oper[i].mask ) printf( " Mask = %s\n", Conf_Oper[i].mask );
puts( "" );
}
opers_puts();
for( i = 0; i < MAX_SERVERS; i++ ) {
if( ! Conf_Server[i].name[0] ) continue;
@@ -299,18 +369,21 @@ Conf_Test( void )
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;
predef_channel_count = array_length(&Conf_Channels, sizeof(*predef_chan));
predef_chan = array_start(&Conf_Channels);
for (i = 0; i < predef_channel_count; i++, predef_chan++) {
if (!predef_chan->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 : "");
printf(" Name = %s\n", predef_chan->name);
printf(" Modes = %s\n", predef_chan->modes);
printf(" Key = %s\n", predef_chan->key);
printf(" MaxUsers = %lu\n", predef_chan->maxusers);
printf(" Topic = %s\n", predef_chan->topic);
printf(" KeyFile = %s\n\n", predef_chan->keyfile);
}
return (config_valid ? 0 : 1);
@@ -382,7 +455,7 @@ Conf_GetServer( CONN_ID Idx )
GLOBAL bool
Conf_EnableServer( char *Name, UINT16 Port )
Conf_EnableServer( const char *Name, UINT16 Port )
{
/* Enable specified server and adjust port */
@@ -395,7 +468,7 @@ Conf_EnableServer( char *Name, UINT16 Port )
/* Gotcha! Set port and enable server: */
Conf_Server[i].port = Port;
Conf_Server[i].flags &= ~CONF_SFLAG_DISABLED;
return true;
return (Conf_Server[i].port && Conf_Server[i].host[0]);
}
}
return false;
@@ -421,7 +494,7 @@ Conf_EnablePassiveServer(const char *Name)
GLOBAL bool
Conf_DisableServer( char *Name )
Conf_DisableServer( const char *Name )
{
/* Enable specified server and adjust port */
@@ -442,7 +515,7 @@ Conf_DisableServer( char *Name )
GLOBAL bool
Conf_AddServer( char *Name, UINT16 Port, char *Host, char *MyPwd, char *PeerPwd )
Conf_AddServer( const char *Name, UINT16 Port, const char *Host, const char *MyPwd, const char *PeerPwd )
{
/* Add new server to configuration */
@@ -476,53 +549,54 @@ Conf_AddServer( char *Name, UINT16 Port, char *Host, char *MyPwd, char *PeerPwd
* Check if the given nick name is an service
*/
GLOBAL bool
Conf_IsService(int ConfServer, char *Nick)
Conf_IsService(int ConfServer, const char *Nick)
{
return MatchCaseInsensitive(Conf_Server[ConfServer].svs_mask, Nick);
} /* Conf_IsService */
/**
* Initialize configuration settings with their default values.
*/
static void
Set_Defaults( bool InitServers )
Set_Defaults(bool InitServers)
{
/* Initialize configuration variables with default values. */
int i;
strcpy( Conf_ServerName, "" );
snprintf( Conf_ServerInfo, sizeof Conf_ServerInfo, "%s %s", PACKAGE_NAME, PACKAGE_VERSION );
strcpy( Conf_ServerPwd, "" );
strcpy(Conf_ServerName, "");
snprintf(Conf_ServerInfo, sizeof Conf_ServerInfo, "%s %s",
PACKAGE_NAME, PACKAGE_VERSION);
strcpy(Conf_ServerPwd, "");
strcpy( Conf_ServerAdmin1, "" );
strcpy( Conf_ServerAdmin2, "" );
strcpy( Conf_ServerAdminMail, "" );
strcpy(Conf_ServerAdmin1, "");
strcpy(Conf_ServerAdmin2, "");
strcpy(Conf_ServerAdminMail, "");
strlcpy( Conf_MotdFile, SYSCONFDIR, sizeof( Conf_MotdFile ));
strlcat( Conf_MotdFile, MOTD_FILE, sizeof( Conf_MotdFile ));
strlcpy(Conf_MotdFile, SYSCONFDIR, sizeof(Conf_MotdFile));
strlcat(Conf_MotdFile, MOTD_FILE, sizeof(Conf_MotdFile));
strlcpy( Conf_MotdPhrase, MOTD_PHRASE, sizeof( Conf_MotdPhrase ));
strlcpy( Conf_Chroot, CHROOT_DIR, sizeof( Conf_Chroot ));
strlcpy( Conf_PidFile, PID_FILE, sizeof( Conf_PidFile ));
Conf_UID = Conf_GID = 0;
strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot));
strlcpy(Conf_PidFile, PID_FILE, sizeof(Conf_PidFile));
free(Conf_ListenAddress);
Conf_ListenAddress = NULL;
Conf_UID = Conf_GID = 0;
Conf_PingTimeout = 120;
Conf_PongTimeout = 20;
Conf_ConnectRetry = 60;
Conf_NoDNS = false;
Conf_NoIdent = false;
Conf_NoPAM = false;
Conf_NoZeroConf = false;
Conf_Oper_Count = 0;
Conf_Channel_Count = 0;
Conf_OperCanMode = false;
Conf_NoDNS = false;
Conf_NoIdent = false;
Conf_PredefChannelsOnly = false;
Conf_OperServerMode = false;
Conf_AllowRemoteOper = false;
Conf_PredefChannelsOnly = false;
Conf_ConnectIPv4 = true;
Conf_ConnectIPv6 = true;
@@ -532,11 +606,62 @@ Set_Defaults( bool InitServers )
Conf_MaxJoins = 10;
Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
#ifdef SYSLOG
#ifdef LOG_LOCAL5
Conf_SyslogFacility = LOG_LOCAL5;
#else
Conf_SyslogFacility = 0;
#endif
#endif
/* Initialize server configuration structures */
if( InitServers ) for( i = 0; i < MAX_SERVERS; Init_Server_Struct( &Conf_Server[i++] ));
if (InitServers) {
for (i = 0; i < MAX_SERVERS;
Init_Server_Struct(&Conf_Server[i++]));
}
} /* Set_Defaults */
static bool
no_listenports(void)
{
size_t cnt = array_bytes(&Conf_ListenPorts);
#ifdef SSL_SUPPORT
cnt += array_bytes(&Conf_SSLOptions.ListenPorts);
#endif
return cnt == 0;
}
static void
Read_Motd(const char *filename)
{
char line[127];
FILE *fp;
if (*filename == '\0')
return;
fp = fopen(filename, "r");
if (!fp) {
Log(LOG_WARNING, "Can't read MOTD file \"%s\": %s",
filename, strerror(errno));
return;
}
array_free(&Conf_Motd);
while (fgets(line, (int)sizeof line, fp)) {
ngt_TrimLastChr( line, '\n');
/* add text including \0 */
if (!array_catb(&Conf_Motd, line, strlen(line) + 1)) {
Log(LOG_WARNING, "Cannot add MOTD text: %s", strerror(errno));
break;
}
}
fclose(fp);
}
static bool
Read_Config( bool ngircd_starting )
{
@@ -559,6 +684,7 @@ Read_Config( bool ngircd_starting )
exit( 1 );
}
opers_free();
Set_Defaults( ngircd_starting );
Config_Error( LOG_INFO, "Reading configuration from \"%s\" ...", NGIRCd_ConfFile );
@@ -617,21 +743,6 @@ Read_Config( bool ngircd_starting )
if( strcasecmp( section, "[GLOBAL]" ) == 0 )
continue;
if( strcasecmp( section, "[OPERATOR]" ) == 0 ) {
if( Conf_Oper_Count + 1 > MAX_OPERATORS )
Config_Error( LOG_ERR, "Too many operators configured.");
else {
/* Initialize new operator structure */
Conf_Oper[Conf_Oper_Count].name[0] = '\0';
Conf_Oper[Conf_Oper_Count].pwd[0] = '\0';
if (Conf_Oper[Conf_Oper_Count].mask) {
free(Conf_Oper[Conf_Oper_Count].mask );
Conf_Oper[Conf_Oper_Count].mask = NULL;
}
Conf_Oper_Count++;
}
continue;
}
if( strcasecmp( section, "[SERVER]" ) == 0 ) {
/* Check if there is already a server to add */
if( New_Server.name[0] ) {
@@ -656,20 +767,15 @@ Read_Config( bool ngircd_starting )
else New_Server_Idx = i;
continue;
}
if( strcasecmp( section, "[CHANNEL]" ) == 0 ) {
if( Conf_Channel_Count + 1 > MAX_DEFCHANNELS ) {
Config_Error( LOG_ERR, "Too many pre-defined channels configured." );
} else {
/* 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++;
}
if (strcasecmp(section, "[CHANNEL]") == 0) {
Conf_Channel_Count++;
continue;
}
if (strcasecmp(section, "[OPERATOR]") == 0) {
Conf_Oper_Count++;
continue;
}
Config_Error( LOG_ERR, "%s, line %d: Unknown section \"%s\"!", NGIRCd_ConfFile, line, section );
section[0] = 0x1;
}
@@ -702,12 +808,14 @@ Read_Config( bool ngircd_starting )
Conf_Server[New_Server_Idx] = New_Server;
}
if (0 == array_length(&Conf_ListenPorts, sizeof(UINT16))) {
if (!array_copyb(&Conf_ListenPorts, (char*) &defaultport, sizeof defaultport)) {
Config_Error( LOG_ALERT, "Could not add default listening Port %u: %s",
(unsigned int) defaultport, strerror(errno));
exit( 1 );
}
/* not a single listening port? Add default. */
if (no_listenports() &&
!array_copyb(&Conf_ListenPorts, (char*) &defaultport, sizeof defaultport))
{
Config_Error(LOG_ALERT, "Could not add default listening Port %u: %s",
(unsigned int) defaultport, strerror(errno));
exit(1);
}
if (!Conf_ListenAddress)
@@ -717,6 +825,10 @@ Read_Config( bool ngircd_starting )
Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME);
exit(1);
}
/* No MOTD phrase configured? (re)try motd file. */
if (array_bytes(&Conf_Motd) == 0)
Read_Motd(Conf_MotdFile);
return true;
} /* Read_Config */
@@ -753,6 +865,7 @@ static unsigned int Handle_MaxNickLength(int Line, const char *Arg)
} /* Handle_MaxNickLength */
static void
Handle_GLOBAL( int Line, char *Var, char *Arg )
{
@@ -785,6 +898,13 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
Config_Error_TooLong( Line, Var );
return;
}
if (strcasecmp(Var, "WebircPassword") == 0) {
/* Password required for WEBIRC command */
len = strlcpy(Conf_WebircPwd, Arg, sizeof(Conf_WebircPwd));
if (len >= sizeof(Conf_WebircPwd))
Config_Error_TooLong(Line, Var);
return;
}
if( strcasecmp( Var, "AdminInfo1" ) == 0 ) {
/* Administrative info #1 */
len = strlcpy( Conf_ServerAdmin1, Arg, sizeof( Conf_ServerAdmin1 ));
@@ -812,17 +932,24 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
return;
}
if( strcasecmp( Var, "MotdFile" ) == 0 ) {
/* "Message of the day" (MOTD) file */
len = strlcpy( Conf_MotdFile, Arg, sizeof( Conf_MotdFile ));
if (len >= sizeof( Conf_MotdFile ))
Config_Error_TooLong( Line, Var );
Read_Motd(Arg);
return;
}
if( strcasecmp( Var, "MotdPhrase" ) == 0 ) {
/* "Message of the day" phrase (instead of file) */
len = strlcpy( Conf_MotdPhrase, Arg, sizeof( Conf_MotdPhrase ));
if (len >= sizeof( Conf_MotdPhrase ))
len = strlen(Arg);
if (len == 0)
return;
if (len >= LINE_LEN) {
Config_Error_TooLong( Line, Var );
return;
}
if (!array_copyb(&Conf_Motd, Arg, len + 1))
Config_Error(LOG_WARNING, "%s, line %d: Could not append MotdPhrase: %s",
NGIRCd_ConfFile, Line, strerror(errno));
return;
}
if( strcasecmp( Var, "ChrootDir" ) == 0 ) {
@@ -918,6 +1045,16 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
#endif
return;
}
if(strcasecmp(Var, "NoPAM") == 0) {
/* don't use PAM library to authenticate users */
Conf_NoPAM = Check_ArgIsTrue(Arg);
return;
}
if(strcasecmp(Var, "NoZeroConf") == 0) {
/* don't register services using ZeroConf */
Conf_NoZeroConf = Check_ArgIsTrue(Arg);
return;
}
#ifdef WANT_IPV6
/* the default setting for all the WANT_IPV6 special options is 'true' */
if( strcasecmp( Var, "ConnectIPv6" ) == 0 ) {
@@ -942,6 +1079,11 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
Conf_OperServerMode = Check_ArgIsTrue( Arg );
return;
}
if(strcasecmp(Var, "AllowRemoteOper") == 0) {
/* Are remote IRC operators allowed to control this server? */
Conf_AllowRemoteOper = Check_ArgIsTrue(Arg);
return;
}
if( strcasecmp( Var, "MaxConnections" ) == 0 ) {
/* Maximum number of connections. 0 -> "no limit". */
#ifdef HAVE_ISDIGIT
@@ -1024,6 +1166,13 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
Conf_SSLOptions.DHFile = strdup_warn( Arg );
return;
}
#endif
#ifdef SYSLOG
if (strcasecmp(Var, "SyslogFacility") == 0) {
Conf_SyslogFacility = ngt_SyslogFacilityID(Arg,
Conf_SyslogFacility);
return;
}
#endif
Config_Error(LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!",
NGIRCd_ConfFile, Line, Var);
@@ -1033,36 +1182,38 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
static void
Handle_OPERATOR( int Line, char *Var, char *Arg )
{
unsigned int opercount;
size_t len;
struct Conf_Oper *op;
assert( Line > 0 );
assert( Var != NULL );
assert( Arg != NULL );
assert( Conf_Oper_Count > 0 );
if ( Conf_Oper_Count == 0 )
op = array_alloc(&Conf_Opers, sizeof(*op), Conf_Oper_Count - 1);
if (!op) {
Config_Error(LOG_ERR, "Could not allocate memory for operator (%d:%s = %s)", Line, Var, Arg);
return;
}
opercount = Conf_Oper_Count - 1;
if( strcasecmp( Var, "Name" ) == 0 ) {
if (strcasecmp(Var, "Name") == 0) {
/* Name of IRC operator */
len = strlcpy( Conf_Oper[opercount].name, Arg, sizeof( Conf_Oper[opercount].name ));
if (len >= sizeof( Conf_Oper[opercount].name ))
Config_Error_TooLong( Line, Var );
len = strlcpy(op->name, Arg, sizeof(op->name));
if (len >= sizeof(op->name))
Config_Error_TooLong(Line, Var);
return;
}
if( strcasecmp( Var, "Password" ) == 0 ) {
if (strcasecmp(Var, "Password") == 0) {
/* Password of IRC operator */
len = strlcpy( Conf_Oper[opercount].pwd, Arg, sizeof( Conf_Oper[opercount].pwd ));
if (len >= sizeof( Conf_Oper[opercount].pwd ))
Config_Error_TooLong( Line, Var );
len = strlcpy(op->pwd, Arg, sizeof(op->pwd));
if (len >= sizeof(op->pwd))
Config_Error_TooLong(Line, Var);
return;
}
if( strcasecmp( Var, "Mask" ) == 0 ) {
if (Conf_Oper[opercount].mask) return; /* Hostname already configured */
Conf_Oper[opercount].mask = strdup_warn( Arg );
if (strcasecmp(Var, "Mask") == 0) {
if (op->mask)
return; /* Hostname already configured */
op->mask = strdup_warn( Arg );
return;
}
Config_Error( LOG_ERR, "%s, line %d (section \"Operator\"): Unknown variable \"%s\"!",
@@ -1162,19 +1313,23 @@ Handle_SERVER( int Line, char *Var, char *Arg )
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)
Handle_Channelname(struct Conf_Channel *new_chan, const char *name)
{
size_t size = sizeof( Conf_Channel[chancount].name );
char *dest = Conf_Channel[chancount].name;
size_t size = sizeof(new_chan->name);
char *dest = new_chan->name;
if (*name && *name != '#') {
if (!Channel_IsValidName(name)) {
/*
* maybe user forgot to add a '#'.
* This is only here for user convenience.
*/
*dest = '#';
--size;
++dest;
@@ -1184,51 +1339,64 @@ Handle_Channelname(size_t chancount, const char *name)
static void
Handle_CHANNEL( int Line, char *Var, char *Arg )
Handle_CHANNEL(int Line, char *Var, char *Arg)
{
size_t len;
size_t chancount = 0;
size_t chancount;
struct Conf_Channel *chan;
assert( Line > 0 );
assert( Var != NULL );
assert( Arg != NULL );
if (Conf_Channel_Count > 0)
chancount = Conf_Channel_Count - 1;
assert(Conf_Channel_Count > 0);
if( strcasecmp( Var, "Name" ) == 0 ) {
if (!Handle_Channelname(chancount, Arg))
Config_Error_TooLong( Line, Var );
chancount = Conf_Channel_Count - 1;
chan = array_alloc(&Conf_Channels, sizeof(*chan), chancount);
if (!chan) {
Config_Error(LOG_ERR, "Could not allocate memory for predefined channel (%d:%s = %s)", Line, Var, Arg);
return;
}
if( strcasecmp( Var, "Modes" ) == 0 ) {
if (strcasecmp(Var, "Name") == 0) {
if (!Handle_Channelname(chan, Arg))
Config_Error_TooLong(Line, Var);
return;
}
if (strcasecmp(Var, "Modes") == 0) {
/* Initial modes */
len = strlcpy( Conf_Channel[chancount].modes, Arg, sizeof( Conf_Channel[chancount].modes ));
if (len >= sizeof( Conf_Channel[chancount].modes ))
len = strlcpy(chan->modes, Arg, sizeof(chan->modes));
if (len >= sizeof(chan->modes))
Config_Error_TooLong( Line, Var );
return;
}
if( strcasecmp( Var, "Topic" ) == 0 ) {
/* Initial topic */
if (!array_copys( &Conf_Channel[chancount].topic, Arg))
len = strlcpy(chan->topic, Arg, sizeof(chan->topic));
if (len >= sizeof(chan->topic))
Config_Error_TooLong( Line, Var );
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 ))
len = strlcpy(chan->key, Arg, sizeof(chan->key));
if (len >= sizeof(chan->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)
chan->maxusers = (unsigned long) atol(Arg);
if (chan->maxusers == 0)
Config_Error_NaN(Line, Var);
return;
}
if (strcasecmp(Var, "KeyFile") == 0) {
/* channel keys */
len = strlcpy(chan->keyfile, Arg, sizeof(chan->keyfile));
if (len >= sizeof(chan->keyfile))
Config_Error_TooLong(Line, Var);
return;
}
Config_Error( LOG_ERR, "%s, line %d (section \"Channel\"): Unknown variable \"%s\"!",
NGIRCd_ConfFile, Line, Var );
@@ -1311,6 +1479,12 @@ Validate_Config(bool Configtest, bool Rehash)
"No administrative information configured but required by RFC!");
}
#ifdef PAM
if (Conf_ServerPwd[0])
Config_Error(LOG_ERR,
"This server uses PAM, \"Password\" will be ignored!");
#endif
#ifdef DEBUG
servers = servers_once = 0;
for (i = 0; i < MAX_SERVERS; i++) {
@@ -1376,6 +1550,29 @@ va_dcl
} /* Config_Error */
#ifdef DEBUG
GLOBAL void
Conf_DebugDump(void)
{
int i;
Log(LOG_DEBUG, "Configured servers:");
for (i = 0; i < MAX_SERVERS; i++) {
if (! Conf_Server[i].name[0])
continue;
Log(LOG_DEBUG,
" - %s: %s:%d, last=%ld, group=%d, flags=%d, conn=%d",
Conf_Server[i].name, Conf_Server[i].host,
Conf_Server[i].port, Conf_Server[i].lasttry,
Conf_Server[i].group, Conf_Server[i].flags,
Conf_Server[i].conn_id);
}
} /* Conf_DebugDump */
#endif
static void
Init_Server_Struct( CONF_SERVER *Server )
{
@@ -1390,7 +1587,7 @@ Init_Server_Struct( CONF_SERVER *Server )
if( NGIRCd_Passive ) Server->flags = CONF_SFLAG_DISABLED;
Resolve_Init(&Server->res_stat);
Proc_InitStruct(&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-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 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,16 +22,15 @@
#include "portab.h"
#include "tool.h"
#include "ng_ipaddr.h"
#include "resolve.h"
#include "proc.h"
#include "conf-ssl.h"
typedef struct _Conf_Oper
{
struct Conf_Oper {
char name[CLIENT_PASS_LEN]; /* Name (ID) of IRC operator */
char pwd[CLIENT_PASS_LEN]; /* Password */
char *mask;
} CONF_OPER;
char *mask; /* allowed host mask */
};
typedef struct _Conf_Server
{
@@ -42,7 +41,7 @@ typedef struct _Conf_Server
UINT16 port; /* Server port */
int group; /* Group of server */
time_t lasttry; /* Last connect attempt */
RES_STAT res_stat; /* Status of the resolver */
PROC_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
@@ -67,14 +66,14 @@ struct SSLOptions {
#endif
typedef struct _Conf_Channel
{
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" ) */
char topic[COMMAND_LEN]; /* Initial topic */
char keyfile[512]; /* Path and name of channel key file */
unsigned long maxusers; /* maximum usercount for this channel, mode "l" */
array topic; /* Initial topic */
} CONF_CHANNEL;
};
#define CONF_SFLAG_ONCE 1 /* Delete this entry after next disconnect */
@@ -95,11 +94,8 @@ GLOBAL char Conf_ServerAdmin1[CLIENT_INFO_LEN];
GLOBAL char Conf_ServerAdmin2[CLIENT_INFO_LEN];
GLOBAL char Conf_ServerAdminMail[CLIENT_INFO_LEN];
/* File with MOTD text */
GLOBAL char Conf_MotdFile[FNAME_LEN];
/* Phrase with MOTD text */
GLOBAL char Conf_MotdPhrase[LINE_LEN];
/* Message of the Day */
GLOBAL array Conf_Motd;
/* Ports the server should listen on */
GLOBAL array Conf_ListenPorts;
@@ -125,27 +121,40 @@ GLOBAL int Conf_PongTimeout;
GLOBAL int Conf_ConnectRetry;
/* Operators */
GLOBAL CONF_OPER Conf_Oper[MAX_OPERATORS];
GLOBAL unsigned int Conf_Oper_Count;
GLOBAL array Conf_Opers;
/* Servers */
GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS];
/* Pre-defined channels */
GLOBAL CONF_CHANNEL Conf_Channel[MAX_DEFCHANNELS];
GLOBAL unsigned int Conf_Channel_Count;
GLOBAL array Conf_Channels;
/* Pre-defined channels only */
GLOBAL bool Conf_PredefChannelsOnly;
/* Are IRC operators allowed to always use MODE? */
GLOBAL bool Conf_OperCanMode;
/* 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 */
GLOBAL bool Conf_OperServerMode;
/* Are remote IRC operators allowed to manage this server? */
GLOBAL bool Conf_AllowRemoteOper;
/* Disable all DNS functions? */
GLOBAL bool Conf_NoDNS;
/* Disable IDENT lookups, even when compiled with support for it */
GLOBAL bool Conf_NoIdent;
/* Disable all usage of PAM, even when compiled with support for it */
GLOBAL bool Conf_NoPAM;
/* Disable service registration using "ZeroConf" */
GLOBAL bool Conf_NoZeroConf;
/*
* try to connect to remote systems using the ipv6 protocol,
* if they have an ipv6 address? (default yes)
@@ -155,11 +164,6 @@ 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 */
GLOBAL bool Conf_OperServerMode;
/* Maximum number of connections to this server */
GLOBAL long Conf_MaxConnections;
@@ -172,6 +176,13 @@ GLOBAL int Conf_MaxConnectionsIP;
/* Maximum length of a nick name */
GLOBAL unsigned int Conf_MaxNickLength;
#ifdef SYSLOG
/* Syslog "facility" */
GLOBAL int Conf_SyslogFacility;
#endif
GLOBAL void Conf_Init PARAMS((void));
GLOBAL bool Conf_Rehash PARAMS((void));
GLOBAL int Conf_Test PARAMS((void));
@@ -180,12 +191,19 @@ GLOBAL void Conf_UnsetServer PARAMS(( CONN_ID Idx ));
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_EnableServer PARAMS(( const 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_DisableServer PARAMS(( const char *Name ));
GLOBAL bool Conf_AddServer PARAMS(( const char *Name, UINT16 Port, const char *Host, const char *MyPwd, const char *PeerPwd ));
GLOBAL bool Conf_IsService PARAMS((int ConfServer, char *Nick));
GLOBAL bool Conf_IsService PARAMS((int ConfServer, const char *Nick));
/* Password required by WEBIRC command */
GLOBAL char Conf_WebircPwd[CLIENT_PASS_LEN];
#ifdef DEBUG
GLOBAL void Conf_DebugDump PARAMS((void));
#endif
#endif

View File

@@ -16,8 +16,6 @@
#include "portab.h"
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 <string.h>
@@ -33,8 +31,6 @@ static char UNUSED id[] = "$Id: conn-func.c,v 1.12 2008/03/11 14:05:27 alex Exp
GLOBAL void
Conn_UpdateIdle( CONN_ID Idx )
{
/* Idle-Timer zuruecksetzen */
assert( Idx > NONE );
My_Connections[Idx].lastprivmsg = time( NULL );
}
@@ -53,8 +49,7 @@ Conn_GetSignon(CONN_ID Idx)
GLOBAL time_t
Conn_GetIdle( CONN_ID Idx )
{
/* Idle-Time einer Verbindung liefern (in Sekunden) */
/* Return Idle-Timer of a connetion */
assert( Idx > NONE );
return time( NULL ) - My_Connections[Idx].lastprivmsg;
} /* Conn_GetIdle */
@@ -63,8 +58,6 @@ Conn_GetIdle( CONN_ID Idx )
GLOBAL time_t
Conn_LastPing( CONN_ID Idx )
{
/* Zeitpunkt des letzten PING liefern */
assert( Idx > NONE );
return My_Connections[Idx].lastping;
} /* Conn_LastPing */
@@ -73,11 +66,11 @@ Conn_LastPing( CONN_ID Idx )
GLOBAL void
Conn_SetPenalty( CONN_ID Idx, time_t Seconds )
{
/* Penalty-Delay fuer eine Verbindung (in Sekunden) setzen;
* waehrend dieser Zeit wird der entsprechende Socket vom Server
* bei Lese-Operationen komplett ignoriert. Der Delay kann mit
* dieser Funktion nur erhoeht, nicht aber verringert werden. */
/* set Penalty-Delay for a socket.
* during the penalty, the socket is ignored completely, no new
* data is read. This function only increases the penalty, it is
* not possible to decrease the penalty time.
*/
time_t t;
assert( Idx > NONE );
@@ -105,8 +98,6 @@ Conn_ResetPenalty( CONN_ID Idx )
GLOBAL void
Conn_ClearFlags( void )
{
/* Alle Connection auf "nicht-markiert" setzen */
CONN_ID i;
for( i = 0; i < Pool_Size; i++ ) My_Connections[i].flag = 0;
@@ -116,8 +107,6 @@ Conn_ClearFlags( void )
GLOBAL int
Conn_Flag( CONN_ID Idx )
{
/* Ist eine Connection markiert (true) oder nicht? */
assert( Idx > NONE );
return My_Connections[Idx].flag;
} /* Conn_Flag */
@@ -206,12 +195,12 @@ Conn_StartTime( CONN_ID Idx )
return 0;
} /* Conn_StartTime */
/**
* return number of bytes queued for writing
*/
GLOBAL size_t
Conn_SendQ( CONN_ID Idx )
{
/* Laenge der Daten im Schreibbuffer liefern */
assert( Idx > NONE );
#ifdef ZLIB
if( My_Connections[Idx].options & CONN_ZIP )
@@ -222,31 +211,36 @@ Conn_SendQ( CONN_ID Idx )
} /* Conn_SendQ */
/**
* return number of messages sent on this connection so far
*/
GLOBAL long
Conn_SendMsg( CONN_ID Idx )
{
/* Anzahl gesendeter Nachrichten liefern */
assert( Idx > NONE );
return My_Connections[Idx].msg_out;
} /* Conn_SendMsg */
/**
* return number of (uncompressed) bytes sent
* on this connection so far
*/
GLOBAL long
Conn_SendBytes( CONN_ID Idx )
{
/* Anzahl gesendeter Bytes (unkomprimiert) liefern */
assert( Idx > NONE );
return My_Connections[Idx].bytes_out;
} /* Conn_SendBytes */
/**
* return number of bytes pending in read buffer
*/
GLOBAL size_t
Conn_RecvQ( CONN_ID Idx )
{
/* Laenge der Daten im Lesebuffer liefern */
assert( Idx > NONE );
#ifdef ZLIB
if( My_Connections[Idx].options & CONN_ZIP )
@@ -257,25 +251,38 @@ Conn_RecvQ( CONN_ID Idx )
} /* Conn_RecvQ */
/**
* return number of messages received on this connection so far
*/
GLOBAL long
Conn_RecvMsg( CONN_ID Idx )
{
/* Anzahl empfangener Nachrichten liefern */
assert( Idx > NONE );
return My_Connections[Idx].msg_in;
} /* Conn_RecvMsg */
/**
* return number of (uncompressed) bytes received on this
* connection so far
*/
GLOBAL long
Conn_RecvBytes( CONN_ID Idx )
{
/* Anzahl empfangener Bytes (unkomprimiert) liefern */
assert( Idx > NONE );
return My_Connections[Idx].bytes_in;
} /* Conn_RecvBytes */
/**
* Return the remote IP address of this connection as string.
*/
GLOBAL const char *
Conn_IPA(CONN_ID Idx)
{
assert (Idx > NONE);
return ng_ipaddr_tostr(&My_Connections[Idx].addr);
}
GLOBAL void
Conn_ResetWCounter( void )

View File

@@ -39,6 +39,7 @@ GLOBAL long Conn_SendMsg PARAMS(( CONN_ID Idx ));
GLOBAL long Conn_RecvMsg PARAMS(( CONN_ID Idx ));
GLOBAL long Conn_SendBytes PARAMS(( CONN_ID Idx ));
GLOBAL long Conn_RecvBytes PARAMS(( CONN_ID Idx ));
GLOBAL const char *Conn_IPA PARAMS(( CONN_ID Idx ));
GLOBAL void Conn_SetPenalty PARAMS(( CONN_ID Idx, time_t Seconds ));
GLOBAL void Conn_ResetPenalty PARAMS(( CONN_ID Idx ));

View File

@@ -228,7 +228,8 @@ void ConnSSL_Free(CONNECTION *c)
}
#endif
assert(Conn_OPTION_ISSET(c, CONN_SSL));
Conn_OPTION_DEL(c, (CONN_SSL_CONNECT|CONN_SSL|CONN_SSL_WANT_WRITE));
/* can't just set bitmask to 0 -- there are other, non-ssl related flags, e.g. CONN_ZIP. */
Conn_OPTION_DEL(c, CONN_SSL_FLAGS_ALL);
}
@@ -382,10 +383,10 @@ ConnSSL_Init_SSL(CONNECTION *c)
int ret;
assert(c != NULL);
#ifdef HAVE_LIBSSL
assert(ssl_ctx);
if (!ssl_ctx) /* NULL when library initialization failed */
if (!ssl_ctx) {
Log(LOG_ERR, "Cannot init ssl_ctx: OpenSSL initialization failed at startup");
return false;
}
assert(c->ssl_state.ssl == NULL);
c->ssl_state.ssl = SSL_new(ssl_ctx);
@@ -406,6 +407,7 @@ ConnSSL_Init_SSL(CONNECTION *c)
if (ret < 0) {
Log(LOG_ERR, "gnutls_set_default_priority: %s", gnutls_strerror(ret));
ConnSSL_Free(c);
return false;
}
/*
* The intermediate (long) cast is here to avoid a warning like:
@@ -418,6 +420,7 @@ ConnSSL_Init_SSL(CONNECTION *c)
if (ret < 0) {
Log(LOG_ERR, "gnutls_credentials_set: %s", gnutls_strerror(ret));
ConnSSL_Free(c);
return false;
}
gnutls_dh_set_prime_bits(c->ssl_state.gnutls_session, DH_BITS);
#endif
@@ -432,10 +435,7 @@ 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));
@@ -470,8 +470,6 @@ ConnSSL_HandleError( CONNECTION *c, const int code, const char *fname )
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:
@@ -483,8 +481,8 @@ ConnSSL_HandleError( CONNECTION *c, const int code, const char *fname )
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);
case SSL_ERROR_ZERO_RETURN:
LogDebug("TLS/SSL connection shut down normally");
break;
/*
SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT, SSL_ERROR_WANT_X509_LOOKUP
@@ -517,15 +515,14 @@ ConnSSL_HandleError( CONNECTION *c, const int code, const char *fname )
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 */
if (gnutls_record_get_direction(c->ssl_state.gnutls_session)) {
Conn_OPTION_ADD(c, CONN_SSL_WANT_WRITE);
io_event_del(c->sock, IO_WANTREAD);
} else {
Conn_OPTION_ADD(c, CONN_SSL_WANT_READ);
io_event_del(c->sock, IO_WANTWRITE);
}
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)) {
@@ -545,8 +542,7 @@ ConnSSL_LogCertInfo( CONNECTION *c )
#ifdef HAVE_LIBSSL
SSL *ssl = c->ssl_state.ssl;
assert( c );
assert( ssl );
assert(ssl);
Log(LOG_INFO, "New %s connection using cipher %s on socket %d.",
SSL_get_version(ssl), SSL_get_cipher(ssl), c->sock);
@@ -574,11 +570,8 @@ 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)) {
#ifdef HAVE_LIBGNUTLS
int err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_SERVER);
if (err) {
Log(LOG_ERR, "gnutls_init: %s", gnutls_strerror(err));
@@ -600,9 +593,7 @@ ConnSSL_Connect( CONNECTION *c )
#ifdef HAVE_LIBSSL
assert(c->ssl_state.ssl);
#endif
#ifdef HAVE_LIBGNUTLS
assert(Conn_OPTION_ISSET(c, CONN_SSL));
#endif
return ConnectAccept(c, true);
}
@@ -622,7 +613,6 @@ ConnectAccept( CONNECTION *c, bool connect)
#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");
@@ -647,7 +637,8 @@ ConnSSL_Write(CONNECTION *c, const void *buf, size_t count)
#ifdef HAVE_LIBGNUTLS
bw = gnutls_write(c->ssl_state.gnutls_session, buf, count);
#endif
if ( bw > 0 ) return bw;
if (bw > 0)
return bw;
if (ConnSSL_HandleError( c, bw, "ConnSSL_Write") == 0)
errno = EAGAIN; /* try again */
return -1;
@@ -684,11 +675,8 @@ ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len)
{
#ifdef HAVE_LIBSSL
char *nl;
SSL *ssl = c->ssl_state.ssl;
SSL *ssl;
assert(c != NULL);
assert(len >= 128);
ssl = c->ssl_state.ssl;
if (!ssl)
return false;
*buf = 0;
@@ -699,8 +687,6 @@ ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len)
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;

View File

@@ -11,19 +11,15 @@
* Connection compression using ZLIB
*/
#include "portab.h"
#define CONN_MODULE
#ifdef ZLIB
/* enable more zlib related debug messages: */
/* #define DEBUG_ZLIB */
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>
#include <string.h>
@@ -41,7 +37,7 @@ static char UNUSED id[] = "$Id: conn-zip.c,v 1.16 2007/05/17 23:34:24 alex Exp $
GLOBAL bool
Zip_InitConn( CONN_ID Idx )
{
/* Kompression fuer Link initialisieren */
/* initialize zlib compression on this link */
assert( Idx > NONE );
@@ -52,10 +48,8 @@ Zip_InitConn( CONN_ID Idx )
My_Connections[Idx].zip.in.zfree = NULL;
My_Connections[Idx].zip.in.data_type = Z_ASCII;
if( inflateInit( &My_Connections[Idx].zip.in ) != Z_OK )
{
/* Fehler! */
Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib inflate)!", Idx );
if (inflateInit( &My_Connections[Idx].zip.in ) != Z_OK) {
Log(LOG_ALERT, "Can't initialize compression on connection %d (zlib inflate)!", Idx);
return false;
}
@@ -65,17 +59,15 @@ Zip_InitConn( CONN_ID Idx )
My_Connections[Idx].zip.out.zfree = NULL;
My_Connections[Idx].zip.out.data_type = Z_ASCII;
if( deflateInit( &My_Connections[Idx].zip.out, Z_DEFAULT_COMPRESSION ) != Z_OK )
{
/* Fehler! */
Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib deflate)!", Idx );
if (deflateInit( &My_Connections[Idx].zip.out, Z_DEFAULT_COMPRESSION ) != Z_OK) {
Log(LOG_ALERT, "Can't initialize compression on connection %d (zlib deflate)!", Idx);
return false;
}
My_Connections[Idx].zip.bytes_in = My_Connections[Idx].bytes_in;
My_Connections[Idx].zip.bytes_out = My_Connections[Idx].bytes_out;
Log( LOG_INFO, "Enabled link compression (zlib) on connection %d.", Idx );
Log(LOG_INFO, "Enabled link compression (zlib) on connection %d.", Idx);
Conn_OPTION_ADD( &My_Connections[Idx], CONN_ZIP );
return true;
@@ -88,12 +80,14 @@ Zip_InitConn( CONN_ID Idx )
* 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.
* This function closes the connection on error.
* @param Idx Connection handle.
* @param Data Pointer to the data.
* @param Len Length of the data to add.
* @return true on success, false otherwise. */
* @return true on success, false otherwise.
*/
GLOBAL bool
Zip_Buffer( CONN_ID Idx, char *Data, size_t Len )
Zip_Buffer( CONN_ID Idx, const char *Data, size_t Len )
{
size_t buflen;
@@ -110,9 +104,11 @@ Zip_Buffer( CONN_ID Idx, char *Data, size_t Len )
/* 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)
if (buflen + Len >= WRITEBUFFER_SLINK_LEN) {
Log(LOG_ALERT, "Zip Write Buffer overflow: %lu bytes\n", buflen + Len);
Conn_Close(Idx, "Zip Write buffer overflow", NULL, false);
return false;
}
return array_catb(&My_Connections[Idx].zip.wbuf, Data, Len);
} /* Zip_Buffer */
@@ -120,8 +116,9 @@ Zip_Buffer( CONN_ID Idx, char *Data, size_t Len )
/**
* Compress data in ZIP buffer and move result to the write buffer of
* the connection.
* This function closes the connection on error.
* @param Idx Connection handle.
* @retrun true on success, false otherwise.
* @return true on success, false otherwise.
*/
GLOBAL bool
Zip_Flush( CONN_ID Idx )
@@ -184,13 +181,17 @@ Zip_Flush( CONN_ID Idx )
} /* Zip_Flush */
/**
* uncompress data and copy it to read buffer.
* Returns true if data has been unpacked or no
* compressed data is currently pending in the zread buffer.
* This function closes the connection on error.
* @param Idx Connection handle.
* @return true on success, false otherwise.
*/
GLOBAL bool
Unzip_Buffer( CONN_ID Idx )
{
/* Daten entpacken und in Lesepuffer kopieren. Bei Fehlern
* wird false geliefert, ansonsten true. Der Fall, dass keine
* Daten mehr zu entpacken sind, ist _kein_ Fehler! */
int result;
unsigned char unzipbuf[READBUFFER_LEN];
int unzipbuf_used = 0;
@@ -221,8 +222,8 @@ Unzip_Buffer( CONN_ID Idx )
result = inflate( in, Z_SYNC_FLUSH );
if( result != Z_OK )
{
Log( LOG_ALERT, "Decompression error: %s (code=%d, ni=%d, ai=%d, no=%d, ao=%d)!?", in->msg, result, in->next_in, in->avail_in, in->next_out, in->avail_out );
Conn_Close( Idx, "Decompression error!", NULL, false );
Log(LOG_ALERT, "Decompression error: %s (code=%d, ni=%d, ai=%d, no=%d, ao=%d)!?", in->msg, result, in->next_in, in->avail_in, in->next_out, in->avail_out);
Conn_Close(Idx, "Decompression error!", NULL, false);
return false;
}
@@ -235,9 +236,11 @@ Unzip_Buffer( CONN_ID Idx )
#endif
assert(unzipbuf_used <= READBUFFER_LEN);
if (!array_catb(&My_Connections[Idx].rbuf, (char*) unzipbuf,
(size_t)unzipbuf_used))
(size_t)unzipbuf_used)) {
Log (LOG_ALERT, "Decompression error: can't copy data!?");
Conn_Close(Idx, "Decompression error!", NULL, false);
return false;
}
if( in->avail_in > 0 ) {
array_moveleft(&My_Connections[Idx].zip.rbuf, 1, in_len );
} else {
@@ -249,21 +252,25 @@ Unzip_Buffer( CONN_ID Idx )
} /* Unzip_Buffer */
/**
* @param Idx Connection handle.
* @return amount of sent (compressed) bytes
*/
GLOBAL long
Zip_SendBytes( CONN_ID Idx )
{
/* Anzahl gesendeter Bytes (komprimiert!) liefern */
assert( Idx > NONE );
return My_Connections[Idx].zip.bytes_out;
} /* Zip_SendBytes */
/**
* @param Idx Connection handle.
* @return amount of received (compressed) bytes
*/
GLOBAL long
Zip_RecvBytes( CONN_ID Idx )
{
/* Anzahl gesendeter Bytes (komprimiert!) liefern */
assert( Idx > NONE );
return My_Connections[Idx].zip.bytes_in;
} /* Zip_RecvBytes */

View File

@@ -22,7 +22,7 @@
GLOBAL bool Zip_InitConn PARAMS(( CONN_ID Idx ));
GLOBAL bool Zip_Buffer PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
GLOBAL bool Zip_Buffer PARAMS(( CONN_ID Idx, const char *Data, size_t Len ));
GLOBAL bool Zip_Flush PARAMS(( CONN_ID Idx ));
GLOBAL bool Unzip_Buffer PARAMS(( CONN_ID Idx ));

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-2008 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 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
@@ -18,7 +18,13 @@
#include <time.h> /* for time_t, see below */
/*
* connection state flags. this is a bitmask -- all values must
* be unique and a power of two.
*
* If you introduce new ones in between, make sure to adjust all
* remaining ones.
*/
#define CONN_ISCLOSING 1 /* Conn_Close() already called */
#define CONN_ISCONNECTING 2 /* connect() in progress */
#define CONN_RFC1459 4 /* RFC 1459 compatibility mode */
@@ -29,19 +35,20 @@
#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 */
#define CONN_SSL_CONNECT 16 /* wait for ssl connect to finish */
#define CONN_SSL 32 /* this connection is SSL encrypted */
#define CONN_SSL_WANT_WRITE 64 /* SSL/TLS library needs to write protocol data */
#define CONN_SSL_WANT_READ 128 /* SSL/TLS library needs to read protocol data */
#define CONN_SSL_FLAGS_ALL (CONN_SSL_CONNECT|CONN_SSL|CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ)
#endif
typedef int CONN_ID;
typedef long CONN_ID;
#include "client.h"
#include "proc.h"
#ifdef CONN_MODULE
#include "defines.h"
#include "resolve.h"
#include "array.h"
#include "tool.h"
#include "ng_ipaddr.h"
@@ -62,7 +69,7 @@ typedef struct _Connection
{
int sock; /* Socket handle */
ng_ipaddr_t addr; /* Client address */
RES_STAT res_stat; /* Status of resolver process */
PROC_STAT proc_stat; /* Status of resolver process */
char host[HOST_LEN]; /* Hostname */
array rbuf; /* Read buffer */
array wbuf; /* Write buffer */
@@ -75,12 +82,13 @@ typedef struct _Connection
long msg_in, msg_out; /* Received and sent IRC messages */
int flag; /* Flag (see "irc-write" module) */
UINT16 options; /* Link options / connection state */
UINT16 bps; /* bytes processed within last second */
CLIENT *client; /* pointer to client structure */
#ifdef ZLIB
ZIPDATA zip; /* Compression information */
#endif /* ZLIB */
#ifdef SSL_SUPPORT
struct ConnSSL_State ssl_state; /* SSL/GNUTLS state information */
struct ConnSSL_State ssl_state; /* SSL/GNUTLS state information */
#endif
} CONNECTION;
@@ -94,24 +102,38 @@ GLOBAL long WCounter;
GLOBAL void Conn_Init PARAMS((void ));
GLOBAL void Conn_Exit PARAMS(( void ));
GLOBAL void Conn_CloseAllSockets PARAMS((void));
GLOBAL unsigned int Conn_InitListeners PARAMS(( void ));
GLOBAL void Conn_ExitListeners PARAMS(( void ));
GLOBAL void Conn_Handler PARAMS(( void ));
GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, char *Format, ... ));
GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, const char *Format, ... ));
GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, char *LogMsg, char *FwdMsg, bool InformClient ));
GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient ));
GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
GLOBAL CONN_ID Conn_GetFromProc PARAMS((int fd));
GLOBAL CLIENT* Conn_GetClient PARAMS((CONN_ID i));
GLOBAL PROC_STAT* Conn_GetProcStat 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
GLOBAL long Conn_Count PARAMS((void));
GLOBAL long Conn_CountMax PARAMS((void));
GLOBAL long Conn_CountAccepted PARAMS((void));
#ifdef DEBUG
GLOBAL void Conn_DebugDump PARAMS((void));
#endif
#endif
/* -eof- */

View File

@@ -1,14 +1,12 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2007 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 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: defines.h,v 1.62 2007/11/21 12:16:36 alex Exp $
*/
@@ -30,16 +28,8 @@
#define HOST_LEN 256 /* Max. lenght of fully qualified host
names (e. g. "abc.domain.tld") */
#define MAX_LISTEN_PORTS 16 /* Max. count of listening ports */
#define MAX_OPERATORS 16 /* Max. count of configurable IRC Ops */
#define MAX_SERVERS 16 /* Max. count of configurable servers */
#define MAX_DEFCHANNELS 16 /* Max. count of predefined channels */
#define MAX_SERVICES 8 /* Max. count of services */
#define MAX_WHOWAS 64 /* Max. number of WHOWAS items */
#define DEFAULT_WHOWAS 5 /* default count for WHOWAS command */
@@ -90,8 +80,8 @@
#define RECONNECT_DELAY 3 /* Time to delay re-connect attempts
in seconds. */
#define USERMODES "aios" /* Supported user modes. */
#define CHANMODES "biIklmnoPstv" /* Supported channel modes. */
#define USERMODES "aciorswx" /* Supported user modes. */
#define CHANMODES "biIklmnoPstvz" /* Supported channel modes. */
#define CONNECTED true /* Internal status codes. */
#define DISCONNECTED false
@@ -103,7 +93,6 @@
#define CONFIG_FILE "/ngircd.conf" /* Configuration file name. */
#define MOTD_FILE "/ngircd.motd" /* Name of the MOTD file. */
#define MOTD_PHRASE "" /* Default MOTD phrase string. */
#define CHROOT_DIR "" /* Default chroot() directory. */
#define PID_FILE "" /* Default file for the process ID. */

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-2009 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
@@ -37,8 +37,9 @@ Hash( const char *String )
char buffer[LINE_LEN];
strlcpy( buffer, String, sizeof( buffer ));
return jenkins_hash( (UINT8 *)ngt_LowerStr( buffer ), strlen( buffer ), 42 );
strlcpy(buffer, String, sizeof(buffer));
return jenkins_hash((UINT8 *)ngt_LowerStr(buffer),
(UINT32)strlen(buffer), 42);
} /* Hash */

View File

@@ -104,8 +104,8 @@ static bool io_event_change_devpoll(int fd, short what);
#ifdef IO_USE_SELECT
#include "defines.h" /* for conn.h */
#include "conn.h" /* for CONN_IDX (needed by resolve.h) */
#include "resolve.h" /* for RES_STAT (needed by conf.h) */
#include "proc.h" /* for PROC_STAT (needed by conf.h) */
#include "conn.h" /* for CONN_ID (needed by conf.h) */
#include "conf.h" /* for Conf_MaxConnections */
static fd_set readers;
@@ -785,6 +785,16 @@ io_setnonblock(int fd)
return fcntl(fd, F_SETFL, flags) == 0;
}
bool
io_setcloexec(int fd)
{
int flags = fcntl(fd, F_GETFD);
if (flags == -1)
return false;
flags |= FD_CLOEXEC;
return fcntl(fd, F_SETFD, flags) == 0;
}
bool
io_close(int fd)

View File

@@ -45,6 +45,9 @@ bool io_close PARAMS((int fd));
/* set O_NONBLOCK */
bool io_setnonblock PARAMS((int fd));
/* set O_CLOEXEC */
bool io_setcloexec PARAMS((int fd));
/* watch fds for activity */
int io_dispatch PARAMS((struct timeval *tv));

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 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,6 @@
#include "defines.h"
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "conn-func.h"
#include "lists.h"
@@ -32,7 +31,6 @@
#include "parse.h"
#include "irc-info.h"
#include "irc-write.h"
#include "resolve.h"
#include "conf.h"
#include "exp.h"
@@ -62,9 +60,18 @@ part_from_all_channels(CLIENT* client, CLIENT *target)
}
/**
* Check weather a local client is allowed to join an already existing
* channel or not.
* @param Client Client that sent the JOIN command
* @param chan Channel to check
* @param channame Name of the channel
* @param key Provided channel key (or NULL if none has been provided)
* @return true if client is allowed to join channel, false otherwise
*/
static bool
join_allowed(CLIENT *Client, CLIENT *target, CHANNEL *chan,
const char *channame, const char *key)
join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
const char *key)
{
bool is_invited, is_banned;
const char *channel_modes;
@@ -73,33 +80,48 @@ join_allowed(CLIENT *Client, CLIENT *target, CHANNEL *chan,
if (strchr(Client_Modes(Client), 'o'))
return true;
is_banned = Lists_Check(Channel_GetListBans(chan), target);
is_invited = Lists_Check(Channel_GetListInvites(chan), target);
is_banned = Lists_Check(Channel_GetListBans(chan), Client);
is_invited = Lists_Check(Channel_GetListInvites(chan), Client);
if (is_banned && !is_invited) {
IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG, Client_ID(Client), channame);
/* Client is banned from channel (and not on invite list) */
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);
if (strchr(channel_modes, 'i') && !is_invited) {
/* Channel is "invite-only" and client is not on invite list */
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);
if (!Channel_CheckKey(chan, Client, key ? key : "")) {
/* Channel is protected by a channel key and the client
* didn't specify the correct one */
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);
if (strchr(channel_modes, 'l') &&
(Channel_MaxUsers(chan) <= Channel_MemberCount(chan))) {
/* There are more clints joined to this channel than allowed */
IRC_WriteStrClient(Client, ERR_CHANNELISFULL_MSG,
Client_ID(Client), channame);
return false;
}
if (strchr(channel_modes, 'z') && !Conn_UsesSSL(Client_Conn(Client))) {
/* Only "secure" clients are allowed, but clients doesn't
* use SSL encryption */
IRC_WriteStrClient(Client, ERR_SECURECHANNEL_MSG,
Client_ID(Client), channame);
return false;
}
return true;
}
@@ -271,20 +293,23 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
/* 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.
*/
/* Test if the user has reached the channel limit */
if ((Conf_MaxJoins > 0) &&
(Channel_CountForUser(Client) >= Conf_MaxJoins))
return IRC_WriteStrClient(Client,
ERR_TOOMANYCHANNELS_MSG,
Client_ID(Client), channame);
if (chan) {
/* Already existing channel: check if the
* client is allowed to join */
if (!join_allowed(Client, chan, channame, key))
break;
} else {
/* New channel: first user will become 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));
@@ -294,7 +319,9 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
* that the "one shot" entries (generated by INVITE
* commands) in this list become deleted when a user
* joins a channel this way. */
if (chan) (void)Lists_Check(Channel_GetListInvites(chan), target);
if (chan)
(void)Lists_Check(Channel_GetListInvites(chan),
target);
}
/* Join channel (and create channel if it doesn't exist) */
@@ -304,7 +331,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
if (!chan) { /* channel is new; it has been created above */
chan = Channel_Search(channame);
assert(chan != NULL);
if (*channame == '+') { /* modeless channel... */
if (Channel_IsModeless(chan)) {
Channel_ModeAdd(chan, 't'); /* /TOPIC not allowed */
Channel_ModeAdd(chan, 'n'); /* no external msgs */
}

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 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
@@ -25,9 +25,7 @@
#include "ngircd.h"
#include "conn-func.h"
#include "conn-zip.h"
#include "client.h"
#include "channel.h"
#include "resolve.h"
#include "conf.h"
#include "defines.h"
#include "log.h"
@@ -49,24 +47,23 @@ IRC_ADMIN(CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
/* Falsche Anzahl Parameter? */
if(( Req->argc > 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* Ziel suchen */
/* find target ... */
if( Req->argc == 1 ) target = Client_Search( Req->argv[0] );
else target = Client_ThisServer( );
/* Prefix ermitteln */
/* find Prefix */
if( Client_Type( Client ) == CLIENT_SERVER ) prefix = Client_Search( Req->prefix );
else prefix = Client;
if( ! prefix ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
/* An anderen Server weiterleiten? */
/* forwad message to another server? */
if( target != Client_ThisServer( ))
{
if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( prefix, ERR_NOSUCHSERVER_MSG, Client_ID( prefix ), Req->argv[0] );
/* forwarden */
/* forward */
IRC_WriteStrClientPrefix( target, prefix, "ADMIN %s", Req->argv[0] );
return CONNECTED;
}
@@ -133,8 +130,14 @@ IRC_INFO(CLIENT * Client, REQUEST * Req)
if (!IRC_WriteStrClient(Client, RPL_INFO_MSG, Client_ID(prefix),
NGIRCd_Version))
return DISCONNECTED;
strlcpy(msg, "Server has been started ", sizeof(msg));
#if defined(__DATE__) && defined(__TIME__)
snprintf(msg, sizeof(msg), "Birth Date: %s at %s", __DATE__, __TIME__);
if (!IRC_WriteStrClient(Client, RPL_INFO_MSG, Client_ID(prefix), msg))
return DISCONNECTED;
#endif
strlcpy(msg, "On-line since ", sizeof(msg));
strlcat(msg, NGIRCd_StartStr, sizeof(msg));
if (!IRC_WriteStrClient(Client, RPL_INFO_MSG, Client_ID(prefix), msg))
return DISCONNECTED;
@@ -193,7 +196,6 @@ IRC_LINKS( CLIENT *Client, REQUEST *Req )
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 );
/* Server-Mask ermitteln */
@@ -241,7 +243,6 @@ IRC_LUSERS( CLIENT *Client, REQUEST *Req )
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 );
/* Absender ermitteln */
@@ -315,7 +316,6 @@ IRC_MOTD( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
/* Falsche Anzahl Parameter? */
if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* From aus Prefix ermitteln */
@@ -325,7 +325,7 @@ IRC_MOTD( CLIENT *Client, REQUEST *Req )
if( Req->argc == 1 )
{
/* an anderen Server forwarden */
/* forward? */
target = Client_Search( Req->argv[0] );
if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[0] );
@@ -351,23 +351,21 @@ IRC_NAMES( CLIENT *Client, REQUEST *Req )
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 );
/* From aus Prefix ermitteln */
/* use prefix to determine "From" */
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( Req->argc == 2 )
{
/* an anderen Server forwarden */
/* forward to another server? */
target = Client_Search( Req->argv[1] );
if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[1] );
if( target != Client_ThisServer( ))
{
/* Ok, anderer Server ist das Ziel: forwarden */
if( target != Client_ThisServer( )) {
/* target is another server, forward */
return IRC_WriteStrClientPrefix( target, from, "NAMES %s :%s", Req->argv[0], Req->argv[1] );
}
}
@@ -381,53 +379,48 @@ IRC_NAMES( CLIENT *Client, REQUEST *Req )
chan = Channel_Search( ptr );
if( chan )
{
/* Namen ausgeben */
/* print name */
if( ! IRC_Send_NAMES( from, chan )) return DISCONNECTED;
}
if( ! IRC_WriteStrClient( from, RPL_ENDOFNAMES_MSG, Client_ID( from ), ptr )) return DISCONNECTED;
/* naechsten Namen ermitteln */
/* get next channel name */
ptr = strtok( NULL, "," );
}
return CONNECTED;
}
/* alle Channels durchgehen */
chan = Channel_First( );
while( chan )
{
/* Namen ausgeben */
if( ! IRC_Send_NAMES( from, chan )) return DISCONNECTED;
/* naechster Channel */
chan = Channel_Next( chan );
}
/* Nun noch alle Clients ausgeben, die in keinem Channel sind */
/* Now print all clients which are not in any channel */
c = Client_First( );
snprintf( rpl, sizeof( rpl ), RPL_NAMREPLY_MSG, Client_ID( from ), "*", "*" );
while( c )
{
if(( Client_Type( c ) == CLIENT_USER ) && ( Channel_FirstChannelOf( c ) == NULL ) && ( ! strchr( Client_Modes( c ), 'i' )))
{
/* Okay, das ist ein User: anhaengen */
/* its a user, concatenate ... */
if( rpl[strlen( rpl ) - 1] != ':' ) strlcat( rpl, " ", sizeof( rpl ));
strlcat( rpl, Client_ID( c ), sizeof( rpl ));
if( strlen( rpl ) > ( LINE_LEN - CLIENT_NICK_LEN - 4 ))
{
/* Zeile wird zu lang: senden! */
/* Line is gwoing too long, send now */
if( ! IRC_WriteStrClient( from, "%s", rpl )) return DISCONNECTED;
snprintf( rpl, sizeof( rpl ), RPL_NAMREPLY_MSG, Client_ID( from ), "*", "*" );
}
}
/* naechster Client */
c = Client_Next( c );
}
if( rpl[strlen( rpl ) - 1] != ':')
{
/* es wurden User gefunden */
if( ! IRC_WriteStrClient( from, "%s", rpl )) return DISCONNECTED;
}
@@ -445,7 +438,7 @@ t_diff(time_t *t, const time_t d)
remain = diff * d;
*t -= remain;
return diff;
return (unsigned int)diff;
}
@@ -470,6 +463,10 @@ uptime_mins(time_t *now)
}
/**
* Handler for the IRC command "STATS".
* See RFC 2812 section 3.4.4.
*/
GLOBAL bool
IRC_STATS( CLIENT *Client, REQUEST *Req )
{
@@ -480,31 +477,34 @@ IRC_STATS( CLIENT *Client, REQUEST *Req )
time_t time_now;
unsigned int days, hrs, mins;
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);
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* From aus Prefix ermitteln */
/* use prefix to determine "From" */
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 (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
if (Req->argc == 2) {
/* an anderen Server forwarden */
target = Client_Search( Req->argv[1] );
if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER ))
return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[1] );
/* forward to another server? */
target = Client_Search(Req->argv[1]);
if ((!target) || (Client_Type(target) != CLIENT_SERVER))
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from), Req->argv[1]);
if( target != Client_ThisServer()) {
/* Ok, anderer Server ist das Ziel: forwarden */
return IRC_WriteStrClientPrefix( target, from, "STATS %s %s", Req->argv[0], Req->argv[1] );
if (target != Client_ThisServer()) {
/* forward to another server */
return IRC_WriteStrClientPrefix(target, from,
"STATS %s %s", Req->argv[0], Req->argv[1]);
}
}
@@ -514,57 +514,70 @@ IRC_STATS( CLIENT *Client, REQUEST *Req )
query = '*';
switch (query) {
case 'l': /* Links */
case 'L':
time_now = time(NULL);
for (con = Conn_First(); con != NONE ;con = Conn_Next(con)) {
cl = Conn_GetClient(con);
if (!cl)
continue;
if ((Client_Type(cl) == CLIENT_SERVER) || (cl == Client)) {
/* Server link or our own connection */
case 'l': /* Link status (servers and own link) */
case 'L':
time_now = time(NULL);
for (con = Conn_First(); con != NONE; con = Conn_Next(con)) {
cl = Conn_GetClient(con);
if (!cl)
continue;
if ((Client_Type(cl) == CLIENT_SERVER)
|| (cl == Client)) {
/* Server link or our own connection */
#ifdef ZLIB
if (Conn_Options(con) & CONN_ZIP) {
if (!IRC_WriteStrClient(from, RPL_STATSLINKINFOZIP_MSG,
Client_ID(from), Client_Mask(cl), Conn_SendQ(con),
Conn_SendMsg(con), Zip_SendBytes(con), Conn_SendBytes(con),
Conn_RecvMsg(con), Zip_RecvBytes(con), Conn_RecvBytes(con), (long)(time_now - Conn_StartTime(con))))
return DISCONNECTED;
continue;
}
#endif
if (!IRC_WriteStrClient(from, RPL_STATSLINKINFO_MSG, Client_ID(from),
Client_Mask(cl), Conn_SendQ(con), Conn_SendMsg(con), Conn_SendBytes(con),
Conn_RecvMsg(con), Conn_RecvBytes(con), (long)(time_now - Conn_StartTime(con))))
return DISCONNECTED;
}
}
break;
case 'm': /* IRC-Commands */
case 'M':
cmd = Parse_GetCommandStruct( );
for (; cmd->name ; cmd++) {
if (cmd->lcount == 0 && cmd->rcount == 0)
continue;
if (!IRC_WriteStrClient(from, RPL_STATSCOMMANDS_MSG, Client_ID(from),
cmd->name, cmd->lcount, cmd->bytes, cmd->rcount))
return DISCONNECTED;
}
break;
case 'u': /* server uptime */
case 'U':
time_now = time(NULL) - NGIRCd_Start;
days = uptime_days(&time_now);
hrs = uptime_hrs(&time_now);
mins = uptime_mins(&time_now);
if (!IRC_WriteStrClient(from, RPL_STATSUPTIME, Client_ID(from),
days, hrs, mins, (unsigned int) time_now))
if (Conn_Options(con) & CONN_ZIP) {
if (!IRC_WriteStrClient
(from, RPL_STATSLINKINFOZIP_MSG,
Client_ID(from), Client_Mask(cl),
Conn_SendQ(con), Conn_SendMsg(con),
Zip_SendBytes(con),
Conn_SendBytes(con),
Conn_RecvMsg(con),
Zip_RecvBytes(con),
Conn_RecvBytes(con),
(long)(time_now - Conn_StartTime(con))))
return DISCONNECTED;
break;
continue;
}
#endif
if (!IRC_WriteStrClient
(from, RPL_STATSLINKINFO_MSG,
Client_ID(from), Client_Mask(cl),
Conn_SendQ(con), Conn_SendMsg(con),
Conn_SendBytes(con), Conn_RecvMsg(con),
Conn_RecvBytes(con),
(long)(time_now - Conn_StartTime(con))))
return DISCONNECTED;
}
}
break;
case 'm': /* IRC command status (usage count) */
case 'M':
cmd = Parse_GetCommandStruct();
for (; cmd->name; cmd++) {
if (cmd->lcount == 0 && cmd->rcount == 0)
continue;
if (!IRC_WriteStrClient
(from, RPL_STATSCOMMANDS_MSG, Client_ID(from),
cmd->name, cmd->lcount, cmd->bytes, cmd->rcount))
return DISCONNECTED;
}
break;
case 'u': /* Server uptime */
case 'U':
time_now = time(NULL) - NGIRCd_Start;
days = uptime_days(&time_now);
hrs = uptime_hrs(&time_now);
mins = uptime_mins(&time_now);
if (!IRC_WriteStrClient(from, RPL_STATSUPTIME, Client_ID(from),
days, hrs, mins, (unsigned int)time_now))
return DISCONNECTED;
break;
}
IRC_SetPenalty(from, 2);
return IRC_WriteStrClient(from, RPL_ENDOFSTATS_MSG, Client_ID(from), query);
return IRC_WriteStrClient(from, RPL_ENDOFSTATS_MSG,
Client_ID(from), query);
} /* IRC_STATS */
@@ -591,23 +604,19 @@ IRC_TIME( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
/* Falsche Anzahl Parameter? */
if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* From aus Prefix ermitteln */
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( Req->argc == 1 )
{
/* an anderen Server forwarden */
target = Client_Search( Req->argv[0] );
if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] );
if( target != Client_ThisServer( ))
{
/* Ok, anderer Server ist das Ziel: forwarden */
return IRC_WriteStrClientPrefix( target, from, "TIME %s", Req->argv[0] );
}
}
@@ -618,43 +627,51 @@ IRC_TIME( CLIENT *Client, REQUEST *Req )
} /* IRC_TIME */
/**
* Handler for the IRC command "USERHOST".
* See RFC 2812 section 4.8.
*/
GLOBAL bool
IRC_USERHOST( CLIENT *Client, REQUEST *Req )
IRC_USERHOST(CLIENT *Client, REQUEST *Req)
{
char rpl[COMMAND_LEN];
CLIENT *c;
int max, i;
assert( Client != NULL );
assert( Req != NULL );
assert(Client != NULL);
assert(Req != NULL);
/* Falsche Anzahl Parameter? */
if(( Req->argc < 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if ((Req->argc < 1))
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if( Req->argc > 5 ) max = 5;
else max = Req->argc;
if (Req->argc > 5)
max = 5;
else
max = Req->argc;
strlcpy( rpl, RPL_USERHOST_MSG, sizeof rpl );
for( i = 0; i < max; i++ )
{
c = Client_Search( Req->argv[i] );
if( c && ( Client_Type( c ) == CLIENT_USER ))
{
/* Dieser Nick ist "online" */
strlcat( rpl, Client_ID( c ), sizeof( rpl ));
if( Client_HasMode( c, 'o' )) strlcat( rpl, "*", sizeof( rpl ));
strlcat( rpl, "=", sizeof( rpl ));
if( Client_HasMode( c, 'a' )) strlcat( rpl, "-", sizeof( rpl ));
else strlcat( rpl, "+", sizeof( rpl ));
strlcat( rpl, Client_User( c ), sizeof( rpl ));
strlcat( rpl, "@", sizeof( rpl ));
strlcat( rpl, Client_Hostname( c ), sizeof( rpl ));
strlcat( rpl, " ", sizeof( rpl ));
strlcpy(rpl, RPL_USERHOST_MSG, sizeof rpl);
for (i = 0; i < max; i++) {
c = Client_Search(Req->argv[i]);
if (c && (Client_Type(c) == CLIENT_USER)) {
/* This Nick is "online" */
strlcat(rpl, Client_ID(c), sizeof(rpl));
if (Client_HasMode(c, 'o'))
strlcat(rpl, "*", sizeof(rpl));
strlcat(rpl, "=", sizeof(rpl));
if (Client_HasMode(c, 'a'))
strlcat(rpl, "-", sizeof(rpl));
else
strlcat(rpl, "+", sizeof(rpl));
strlcat(rpl, Client_User(c), sizeof(rpl));
strlcat(rpl, "@", sizeof(rpl));
strlcat(rpl, Client_HostnameCloaked(c), sizeof(rpl));
strlcat(rpl, " ", sizeof(rpl));
}
}
ngt_TrimLastChr( rpl, ' ');
ngt_TrimLastChr(rpl, ' ');
return IRC_WriteStrClient( Client, rpl, Client_ID( Client ) );
return IRC_WriteStrClient(Client, rpl, Client_ID(Client));
} /* IRC_USERHOST */
@@ -678,7 +695,6 @@ IRC_VERSION( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
/* Falsche Anzahl Parameter? */
if(( Req->argc > 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* Ziel suchen */
@@ -712,9 +728,11 @@ IRC_VERSION( CLIENT *Client, REQUEST *Req )
static bool
write_whoreply(CLIENT *Client, CLIENT *c, const char *channelname, const char *flags)
{
return IRC_WriteStrClient(Client, RPL_WHOREPLY_MSG, Client_ID(Client), channelname,
Client_User(c), Client_Hostname(c), Client_ID(Client_Introducer(c)), Client_ID(c),
flags, Client_Hops(c), Client_Info(c));
return IRC_WriteStrClient(Client, RPL_WHOREPLY_MSG, Client_ID(Client),
channelname, Client_User(c),
Client_HostnameCloaked(c),
Client_ID(Client_Introducer(c)), Client_ID(c),
flags, Client_Hops(c), Client_Info(c));
}
@@ -932,8 +950,11 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
if(( Client_NextHop( target ) != Client_ThisServer( )) && ( Client_Type( Client_NextHop( target )) == CLIENT_SERVER )) return IRC_WriteStrClientPrefix( target, from, "WHOIS %s :%s", Req->argv[0], Req->argv[1] );
/* Nick, user and name */
if( ! IRC_WriteStrClient( from, RPL_WHOISUSER_MSG, Client_ID( from ), Client_ID( c ), Client_User( c ), Client_Hostname( c ), Client_Info( c ))) return DISCONNECTED;
/* Nick, user, hostname and client info */
if (!IRC_WriteStrClient(from, RPL_WHOISUSER_MSG, Client_ID(from),
Client_ID(c), Client_User(c),
Client_HostnameCloaked(c), Client_Info(c)))
return DISCONNECTED;
/* Server */
if( ! IRC_WriteStrClient( from, RPL_WHOISSERVER_MSG, Client_ID( from ), Client_ID( c ), Client_ID( Client_Introducer( c )), Client_Info( Client_Introducer( c )))) return DISCONNECTED;
@@ -984,6 +1005,13 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
if( ! IRC_WriteStrClient( from, RPL_WHOISOPERATOR_MSG, Client_ID( from ), Client_ID( c ))) return DISCONNECTED;
}
/* Connected using SSL? */
if (Conn_UsesSSL(Client_Conn(c))) {
if (!IRC_WriteStrClient
(from, RPL_WHOISSSL_MSG, Client_ID(from), Client_ID(c)))
return DISCONNECTED;
}
/* Idle and signon time (local clients only!) */
if (Client_Conn(c) > NONE ) {
if (! IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG,
@@ -1167,6 +1195,10 @@ IRC_Send_LUSERS( CLIENT *Client )
if(! IRC_WriteStrClient(Client, RPL_NETUSERS_MSG, Client_ID(Client),
cnt, max, cnt, max))
return DISCONNECTED;
/* Connection counters */
if (! IRC_WriteStrClient(Client, RPL_STATSCONN_MSG, Client_ID(Client),
Conn_CountMax(), Conn_CountAccepted()))
return DISCONNECTED;
#endif
return CONNECTED;
@@ -1213,45 +1245,30 @@ static inline bool Show_MOTD_SSLInfo(UNUSED CLIENT *c) { return true; }
GLOBAL bool
IRC_Show_MOTD( CLIENT *Client )
{
char line[127];
FILE *fd;
const char *line;
size_t len_tot, len_str;
assert( Client != NULL );
if (Conf_MotdPhrase[0]) {
if (!Show_MOTD_Start(Client))
len_tot = array_bytes(&Conf_Motd);
if (len_tot == 0 && !Conn_UsesSSL(Client_Conn(Client)))
return IRC_WriteStrClient(Client, ERR_NOMOTD_MSG, Client_ID(Client));
if (!Show_MOTD_Start(Client))
return DISCONNECTED;
line = array_start(&Conf_Motd);
while (len_tot > 0) {
len_str = strlen(line) + 1;
assert(len_tot >= len_str);
len_tot -= len_str;
if (!Show_MOTD_Sendline(Client, line))
return DISCONNECTED;
if (!Show_MOTD_Sendline(Client, Conf_MotdPhrase))
return DISCONNECTED;
goto out;
line += len_str;
}
fd = fopen( Conf_MotdFile, "r" );
if( ! fd ) {
Log( LOG_WARNING, "Can't read MOTD file \"%s\": %s", Conf_MotdFile, strerror( errno ));
if (Conn_UsesSSL(Client_Conn(Client))) {
if (!Show_MOTD_Start(Client))
return DISCONNECTED;
goto out;
}
return IRC_WriteStrClient( Client, ERR_NOMOTD_MSG, Client_ID( Client ) );
}
if (!Show_MOTD_Start( Client )) {
fclose(fd);
return false;
}
while (fgets( line, (int)sizeof line, fd )) {
ngt_TrimLastChr( line, '\n');
if( ! Show_MOTD_Sendline( Client, line)) {
fclose( fd );
return false;
}
}
fclose(fd);
out:
if (!Show_MOTD_SSLInfo(Client))
return DISCONNECTED;
return Show_MOTD_End(Client);
@@ -1314,7 +1331,6 @@ IRC_Send_NAMES( CLIENT *Client, CHANNEL *Chan )
} /* IRC_Send_NAMES */
/**
* Send the ISUPPORT numeric (005).
* This numeric indicates the features that are supported by this server.

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 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
@@ -20,15 +20,17 @@
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <signal.h>
#include <unistd.h>
#include "ngircd.h"
#include "resolve.h"
#include "conn-func.h"
#include "conf.h"
#include "client.h"
#include "channel.h"
#include "io.h"
#include "log.h"
#include "messages.h"
#include "pam.h"
#include "parse.h"
#include "irc.h"
#include "irc-info.h"
@@ -39,11 +41,17 @@
static bool Hello_User PARAMS(( CLIENT *Client ));
static bool Hello_User_PostAuth 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 Reject_Client PARAMS((CLIENT *Client));
static void cb_introduceClient PARAMS((CLIENT *Client, CLIENT *Prefix,
void *i));
#ifdef PAM
static void cb_Read_Auth_Result PARAMS((int r_fd, UNUSED short events));
#endif
/**
* Handler for the IRC command "PASS".
@@ -148,7 +156,6 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
} else {
/* The peer seems to be a server supporting the
* "original" IRC protocol (RFC 2813). */
serverver = "";
if (strchr(orig_flags, 'Z'))
flags = "Z";
else
@@ -242,7 +249,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
Client_Type(target) != CLIENT_SERVICE &&
Client_Type(target) != CLIENT_SERVER) {
/* New client */
Log( LOG_DEBUG, "Connection %d: got valid NICK command ...",
LogDebug("Connection %d: got valid NICK command ...",
Client_Conn( Client ));
/* Register new nickname of this client */
@@ -322,18 +329,18 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
info = Req->argv[0];
}
/* Nick ueberpruefen */
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. */
/*
* the new nick is already present on this server:
* the new and the old one have to be disconnected now.
*/
Log( LOG_ERR, "Server %s introduces already registered nick \"%s\"!", Client_ID( Client ), Req->argv[0] );
Kill_Nick( Req->argv[0], "Nick collision" );
return CONNECTED;
}
/* Server, zu dem der Client connectiert ist, suchen */
/* Find the Server this client is connected to */
intr_c = Client_GetFromToken(Client, token);
if( ! intr_c )
{
@@ -342,14 +349,11 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
return CONNECTED;
}
/* Neue Client-Struktur anlegen */
c = Client_NewRemoteUser(intr_c, nick, hops, user, hostname,
token, modes, info, true);
if( ! c )
{
/* Eine neue Client-Struktur konnte nicht angelegt werden.
* Der Client muss disconnectiert werden, damit der Netz-
* status konsistent bleibt. */
/* out of memory, need to disconnect client to keep network state consistent */
Log( LOG_ALERT, "Can't create client structure! (on connection %d)", Client_Conn( Client ));
Kill_Nick( Req->argv[0], "Server error" );
return CONNECTED;
@@ -360,7 +364,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
* 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) ...",
LogDebug("Client \"%s\" is being registered (RFC 1459) ...",
Client_Mask(c));
Client_SetType(c, CLIENT_GOTNICK);
} else
@@ -407,6 +411,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
#else
Client_SetUser(Client, Req->argv[0], false);
#endif
Client_SetOrigUser(Client, Req->argv[0]);
/* "Real name" or user info text: Don't set it to the empty
* string, the original ircd can't deal with such "real names"
@@ -439,6 +444,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
Req->prefix);
Client_SetUser(c, Req->argv[0], true);
Client_SetOrigUser(c, Req->argv[0]);
Client_SetHostname(c, Req->argv[1]);
Client_SetInfo(c, Req->argv[3]);
@@ -561,6 +567,32 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req)
} /* IRC_SERVICE */
/**
* Handler for the IRC command "WEBIRC".
* Syntax: WEBIRC <password> <username> <real-hostname> <real-IP-address>
*/
GLOBAL bool
IRC_WEBIRC(CLIENT *Client, REQUEST *Req)
{
/* Exactly 4 parameters are requited */
if (Req->argc != 4)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (!Conf_WebircPwd[0] || strcmp(Req->argv[0], Conf_WebircPwd) != 0)
return IRC_WriteStrClient(Client, ERR_PASSWDMISMATCH_MSG,
Client_ID(Client));
LogDebug("Connection %d: got valid WEBIRC command: user=%s, host=%s, ip=%s",
Client_Conn(Client), Req->argv[1], Req->argv[2], Req->argv[3]);
Client_SetUser(Client, Req->argv[1], true);
Client_SetOrigUser(Client, Req->argv[1]);
Client_SetHostname(Client, Req->argv[2]);
return CONNECTED;
} /* IRC_WEBIRC */
GLOBAL bool
IRC_QUIT( CLIENT *Client, REQUEST *Req )
{
@@ -583,7 +615,6 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
target = Client_Search( Req->prefix );
if( ! target )
{
/* Den Client kennen wir nicht (mehr), also nichts zu tun. */
Log( LOG_WARNING, "Got QUIT from %s for unknown client!?", Client_ID( Client ));
return CONNECTED;
}
@@ -601,7 +632,7 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
strlcat(quitmsg, "\"", sizeof quitmsg );
}
/* User, Service, oder noch nicht registriert */
/* User, Service, or not yet registered */
Conn_Close( Client_Conn( Client ), "Got QUIT command.", Req->argc == 1 ? quitmsg : NULL, true);
return DISCONNECTED;
@@ -617,7 +648,6 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
assert(Client != NULL);
assert(Req != NULL);
/* Wrong number of arguments? */
if (Req->argc < 1)
return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG,
Client_ID(Client));
@@ -723,7 +753,7 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
/* The connection timestamp has already been updated when the data has
* been read from so socket, so we don't need to update it here. */
#ifdef DEBUG
if (Client_Conn(Client) > NONE)
Log(LOG_DEBUG,
"Connection %d: received PONG. Lag: %ld seconds.",
@@ -732,7 +762,7 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
else
Log(LOG_DEBUG,
"Connection %d: received PONG.", Client_Conn(Client));
#endif
return CONNECTED;
} /* IRC_PONG */
@@ -740,18 +770,116 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
static bool
Hello_User(CLIENT * Client)
{
assert(Client != NULL);
#ifdef PAM
int pipefd[2], result;
CONN_ID conn;
pid_t pid;
/* Check password ... */
if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
/* Bad password! */
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);
assert(Client != NULL);
conn = Client_Conn(Client);
if (Conf_NoPAM) {
/* Don't do any PAM authentication at all, instead emulate
* the beahiour of the daemon compiled without PAM support:
* because there can't be any "server password", all
* passwords supplied are classified as "wrong". */
if(Client_Password(Client)[0] == '\0')
return Hello_User_PostAuth(Client);
Reject_Client(Client);
return DISCONNECTED;
}
/* Fork child process for PAM authentication; and make sure that the
* process timeout is set higher than the login timeout! */
pid = Proc_Fork(Conn_GetProcStat(conn), pipefd,
cb_Read_Auth_Result, Conf_PongTimeout + 1);
if (pid > 0) {
LogDebug("Authenticator for connection %d created (PID %d).",
conn, pid);
return CONNECTED;
} else {
/* Sub process */
Log_Init_Subprocess("Auth");
result = PAM_Authenticate(Client);
write(pipefd[1], &result, sizeof(result));
Log_Exit_Subprocess("Auth");
exit(0);
}
#else
assert(Client != NULL);
/* Check global server password ... */
if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
/* Bad password! */
Reject_Client(Client);
return DISCONNECTED;
}
return Hello_User_PostAuth(Client);
#endif
}
#ifdef PAM
/**
* Read result of the authenticatior sub-process from pipe
*/
static void
cb_Read_Auth_Result(int r_fd, UNUSED short events)
{
CONN_ID conn;
CLIENT *client;
int result;
size_t len;
PROC_STAT *proc;
LogDebug("Auth: Got callback on fd %d, events %d", r_fd, events);
conn = Conn_GetFromProc(r_fd);
if (conn == NONE) {
/* Ops, none found? Probably the connection has already
* been closed!? We'll ignore that ... */
io_close(r_fd);
LogDebug("Auth: Got callback for unknown connection!?");
return;
}
proc = Conn_GetProcStat(conn);
client = Conn_GetClient(conn);
/* Read result from pipe */
len = Proc_Read(proc, &result, sizeof(result));
if (len == 0)
return;
if (len != sizeof(result)) {
Log(LOG_CRIT, "Auth: Got malformed result!");
Reject_Client(client);
return;
}
if (result == true) {
Client_SetUser(client, Client_OrigUser(client), true);
(void)Hello_User_PostAuth(client);
} else
Reject_Client(client);
}
#endif
static void
Reject_Client(CLIENT *Client)
{
Log(LOG_ERR,
"User \"%s\" rejected (connection %d): Access denied!",
Client_Mask(Client), Client_Conn(Client));
Conn_Close(Client_Conn(Client), NULL,
"Access denied! Bad password?", true);
}
static bool
Hello_User_PostAuth(CLIENT *Client)
{
Introduce_Client(NULL, Client, CLIENT_USER);
if (!IRC_WriteStrClient
@@ -785,7 +913,7 @@ Hello_User(CLIENT * Client)
IRC_SetPenalty(Client, 1);
return CONNECTED;
} /* Hello_User */
}
static void
@@ -821,10 +949,16 @@ Introduce_Client(CLIENT *From, CLIENT *Client, int Type)
Client_Modes(Client), Client_ID(From),
Client_ID(Client_Introducer(Client)),
Client_Hops(Client), Client_Hops(Client) > 1 ? "s": "");
} else
} else {
Log(LOG_NOTICE, "%s \"%s\" registered (connection %d).",
Client_TypeText(Client), Client_Mask(Client),
Client_Conn(Client));
Log_ServerNotice('c', "Client connecting: %s (%s@%s) [%s] - %s",
Client_ID(Client), Client_User(Client),
Client_Hostname(Client),
Conn_IPA(Client_Conn(Client)),
Client_TypeText(Client));
}
/* Inform other servers */
IRC_WriteStrServersPrefixFlag_CB(From,

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 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
@@ -19,6 +19,7 @@ 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_WEBIRC 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));

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 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,27 +22,30 @@
#include "defines.h"
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "irc-write.h"
#include "lists.h"
#include "log.h"
#include "parse.h"
#include "messages.h"
#include "resolve.h"
#include "conf.h"
#include "exp.h"
#include "irc-mode.h"
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 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_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 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 Send_ListChange PARAMS(( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Mask ));
static bool Send_ListChange PARAMS((const char *Mode, CLIENT *Prefix,
CLIENT *Client, CHANNEL *Channel, const char *Mask));
GLOBAL bool
@@ -172,6 +175,17 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
else ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin ));
break;
case 'c': /* Receive connect notices
* (only settable by IRC operators!) */
if(!set || Client_OperByMe(Origin)
|| Client_Type(Client) == CLIENT_SERVER)
x[0] = 'c';
else
ok = IRC_WriteStrClient(Origin,
ERR_NOPRIVILEGES_MSG,
Client_ID(Origin));
break;
case 'o': /* IRC operator (only unsettable!) */
if(( ! set ) || ( Client_Type( Client ) == CLIENT_SERVER ))
{
@@ -186,6 +200,15 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
else ok = IRC_WriteStrClient( Origin, ERR_RESTRICTED_MSG, Client_ID( Origin ));
break;
case 'x': /* Cloak hostname */
if (Client_HasMode(Client, 'r'))
IRC_WriteStrClient(Origin,
ERR_RESTRICTED_MSG,
Client_ID(Origin));
else
x[0] = 'x';
break;
default:
Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\"!?", set ? '+' : '-', *mode_ptr, Client_ID( Origin ));
if( Client_Type( Client ) != CLIENT_SERVER ) ok = IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Origin ), set ? '+' : '-', *mode_ptr );
@@ -276,20 +299,22 @@ Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel)
}
/**
* Handle channel mode and channel-user mode changes
*/
static bool
Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
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 = true, skiponce, use_servermode = false, retval;
char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2],
argadd[CLIENT_PASS_LEN], *mode_ptr;
bool connected, set, skiponce, retval, onchannel;
bool modeok = true, use_servermode = false;
int mode_arg, arg_arg;
CLIENT *client;
long l;
size_t len;
/* Are modes allowed on channel? */
if (Channel_Name(Channel)[0] == '+')
if (Channel_IsModeless(Channel))
return IRC_WriteStrClient(Client, ERR_NOCHANMODES_MSG,
Client_ID(Client), Channel_Name(Channel));
@@ -300,14 +325,13 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
/* Is the user allowed to change modes? */
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));
onchannel = Channel_IsMemberOf(Channel, Origin);
modeok = false;
/* channel operator? */
if (strchr(Channel_UserModes(Channel, Origin), 'o'))
if (onchannel &&
strchr(Channel_UserModes(Channel, Origin), 'o')) {
modeok = true;
else if(Conf_OperCanMode) {
} else if (Conf_OperCanMode) {
/* IRC-Operators can use MODE as well */
if (Client_OperByMe(Origin)) {
modeok = true;
@@ -315,6 +339,10 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
use_servermode = true; /* Change Origin to Server */
}
}
if (!onchannel && !modeok)
return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG,
Client_ID(Origin), Channel_Name(Channel));
}
mode_arg = 1;
@@ -327,8 +355,12 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
/* Initial state: set or unset modes? */
skiponce = false;
switch (*mode_ptr) {
case '-': set = false; break;
case '+': set = true; break;
case '-':
set = false;
break;
case '+':
set = true;
break;
default:
set = true;
skiponce = true;
@@ -339,9 +371,9 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
the_args[0] = '\0';
x[1] = '\0';
ok = CONNECTED;
connected = CONNECTED;
while (mode_ptr) {
if (! skiponce)
if (!skiponce)
mode_ptr++;
if (!*mode_ptr) {
/* Try next argument if there's any */
@@ -364,10 +396,11 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
switch (*mode_ptr) {
case '+':
case '-':
if (((*mode_ptr == '+') && !set) || ((*mode_ptr == '-') && set)) {
if (((*mode_ptr == '+') && !set)
|| ((*mode_ptr == '-') && set)) {
/* Action modifier ("+"/"-") must be changed ... */
len = strlen( the_modes ) - 1;
if ((the_modes[len] == '+') || (the_modes[len] == '-')) {
len = strlen(the_modes) - 1;
if (the_modes[len] == '+' || the_modes[len] == '-') {
/* Adjust last action modifier in result */
the_modes[len] = *mode_ptr;
} else {
@@ -381,7 +414,8 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
}
/* Are there arguments left? */
if( arg_arg >= Req->argc ) arg_arg = -1;
if (arg_arg >= Req->argc)
arg_arg = -1;
/* Validate modes */
x[0] = '\0';
@@ -394,32 +428,46 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
case 'n': /* Only members can write */
case 's': /* Secret channel */
case 't': /* Topic locked */
case 'z': /* Secure connections only */
if (modeok)
x[0] = *mode_ptr;
else
ok = IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID(Origin), Channel_Name(Channel));
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin), Channel_Name(Channel));
break;
case 'k': /* Channel key */
if (! set) {
if (!set) {
if (modeok)
x[0] = *mode_ptr;
else
ok = IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID(Origin), Channel_Name(Channel));
connected = 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));
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));
connected = 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);
connected = IRC_WriteStrClient(Origin,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Origin), Req->command);
goto chan_exit;
}
break;
case 'l': /* Member limit */
@@ -427,7 +475,10 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
if (modeok)
x[0] = *mode_ptr;
else
ok = IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID(Origin), Channel_Name(Channel));
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
break;
}
if (arg_arg > mode_arg) {
@@ -436,28 +487,41 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
if (l > 0 && l < 0xFFFF) {
Channel_ModeDel(Channel, 'l');
Channel_SetMaxUsers(Channel, l);
snprintf(argadd, sizeof(argadd), "%ld", 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));
connected = 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);
connected = IRC_WriteStrClient(Origin,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Origin), Req->command);
goto chan_exit;
}
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));
if (set && !(Client_OperByMe(Client)
|| Client_Type(Client) == CLIENT_SERVER))
connected = IRC_WriteStrClient(Origin,
ERR_NOPRIVILEGES_MSG,
Client_ID(Origin));
else
x[0] = 'P';
x[0] = 'P';
} else
ok = IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID(Origin), Channel_Name(Channel));
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
break;
/* --- Channel user modes --- */
case 'o': /* Channel operator */
@@ -468,14 +532,23 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
if (client)
x[0] = *mode_ptr;
else
ok = IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->argv[arg_arg]);
connected = 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));
connected = 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);
connected = IRC_WriteStrClient(Origin,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Origin), Req->command);
goto chan_exit;
}
break;
/* --- Channel lists --- */
@@ -484,11 +557,18 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
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]);
connected = 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));
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
}
Req->argv[arg_arg][0] = '\0';
arg_arg++;
@@ -500,15 +580,20 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
}
break;
default:
Log(LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\" on %s!?",
set ? '+' : '-', *mode_ptr, Client_ID(Origin), Channel_Name(Channel));
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);
connected = IRC_WriteStrClient(Origin,
ERR_UMODEUNKNOWNFLAG2_MSG,
Client_ID(Origin),
set ? '+' : '-', *mode_ptr);
x[0] = '\0';
goto chan_exit;
} /* switch() */
} /* switch() */
if (!ok)
if (!connected)
break;
/* Is there a valid mode change? */
@@ -517,29 +602,40 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
/* 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 (!IRC_WriteStrClient
(Origin, ERR_USERNOTINCHANNEL_MSG,
Client_ID(Origin), Client_ID(client),
Channel_Name(Channel)))
break;
continue;
}
if (client) {
/* Channel-User-Mode */
retval = set ? Channel_UserModeAdd(Channel, client, x[0]) : Channel_UserModeDel(Channel, client, x[0]);
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_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));
LogDebug
("User \"%s\": Mode change on %s, now \"%s\"",
Client_Mask(client), Channel_Name(Channel),
Channel_UserModes(Channel, client));
}
} else {
/* Channel-Mode */
retval = set ? Channel_ModeAdd(Channel, x[0]) : Channel_ModeDel(Channel, x[0]);
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));
LogDebug("Channel %s: Mode change, now \"%s\".",
Channel_Name(Channel),
Channel_Modes(Channel));
}
}
@@ -549,7 +645,8 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
strlcat(the_args, argadd, sizeof(the_args));
}
}
chan_exit:
chan_exit:
/* Are there changed modes? */
if (the_modes[1]) {
/* Clean up mode string */
@@ -567,14 +664,19 @@ chan_exit:
/* 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);
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);
connected = 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,
@@ -587,7 +689,7 @@ chan_exit:
}
IRC_SetPenalty(Client, 1);
return CONNECTED;
return connected;
} /* Channel_Mode */
@@ -597,12 +699,10 @@ IRC_AWAY( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
/* Falsche Anzahl Parameter? */
if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if(( Req->argc == 1 ) && (Req->argv[0][0] ))
{
/* AWAY setzen */
Client_SetAway( Client, Req->argv[0] );
Client_ModeAdd( Client, 'a' );
IRC_WriteStrServersPrefix( Client, Client, "MODE %s :+a", Client_ID( Client ));
@@ -610,7 +710,6 @@ IRC_AWAY( CLIENT *Client, REQUEST *Req )
}
else
{
/* AWAY loeschen */
Client_ModeDel( Client, 'a' );
IRC_WriteStrServersPrefix( Client, Client, "MODE %s :-a", Client_ID( Client ));
return IRC_WriteStrClient( Client, RPL_UNAWAY_MSG, Client_ID( Client ));
@@ -676,23 +775,22 @@ Del_Ban_Invite(int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const
static bool
Send_ListChange( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Mask )
Send_ListChange(const char *Mode, CLIENT *Prefix, CLIENT *Client,
CHANNEL *Channel, const char *Mask)
{
/* Bestaetigung an Client schicken & andere Server sowie Channel-User informieren */
bool ok;
if( Client_Type( Client ) == CLIENT_USER )
{
/* Bestaetigung an Client */
/* send confirmation to client */
ok = IRC_WriteStrClientPrefix( Client, Prefix, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
}
else ok = true;
/* an andere Server */
/* to other servers */
IRC_WriteStrServersPrefix( Client, Prefix, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
/* und lokale User im Channel */
/* and local users in channel */
IRC_WriteStrChannelPrefix( Client, Channel, Prefix, false, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
return ok;

View File

@@ -21,7 +21,6 @@
#include "defines.h"
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "irc-write.h"
#include "lists.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,69 +14,69 @@
#include "portab.h"
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>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "ngircd.h"
#include "resolve.h"
#include "conn-func.h"
#include "conf.h"
#include "client.h"
#include "channel.h"
#include "irc-write.h"
#include "log.h"
#include "match.h"
#include "messages.h"
#include "parse.h"
#include "op.h"
#include <exp.h>
#include "irc-oper.h"
/**
* Handle invalid received OPER command.
* Log OPER attempt and send error message to client.
*/
static bool
Bad_OperPass(CLIENT *Client, char *errtoken, char *errmsg)
{
Log( LOG_WARNING, "Got invalid OPER from \"%s\": \"%s\" -- %s", Client_Mask( Client ),
errtoken, errmsg);
Log(LOG_WARNING, "Got invalid OPER from \"%s\": \"%s\" -- %s",
Client_Mask(Client), errtoken, errmsg);
IRC_SetPenalty(Client, 3);
return IRC_WriteStrClient( Client, ERR_PASSWDMISMATCH_MSG, Client_ID( Client ));
}
return IRC_WriteStrClient(Client, ERR_PASSWDMISMATCH_MSG,
Client_ID(Client));
} /* Bad_OperPass */
GLOBAL bool
IRC_OPER( CLIENT *Client, REQUEST *Req )
{
unsigned int i;
struct Conf_Oper *op;
size_t len, i;
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 );
/* Operator suchen */
for( i = 0; i < Conf_Oper_Count; i++)
{
if( Conf_Oper[i].name[0] && Conf_Oper[i].pwd[0] && ( strcmp( Conf_Oper[i].name, Req->argv[0] ) == 0 )) break;
}
if( i >= Conf_Oper_Count )
len = array_length(&Conf_Opers, sizeof(*op));
op = array_start(&Conf_Opers);
for (i = 0; i < len && strcmp(op[i].name, Req->argv[0]); i++)
;
if (i >= len)
return Bad_OperPass(Client, Req->argv[0], "not configured");
/* Stimmt das Passwort? */
if( strcmp( Conf_Oper[i].pwd, Req->argv[1] ) != 0 )
return Bad_OperPass(Client, Conf_Oper[i].name, "Bad password");
if (strcmp(op[i].pwd, Req->argv[1]) != 0)
return Bad_OperPass(Client, op[i].name, "bad password");
/* Authorized Mask? */
if( Conf_Oper[i].mask && (! Match( Conf_Oper[i].mask, Client_Mask( Client ) )))
return Bad_OperPass(Client, Conf_Oper[i].mask, "hostmask check failed" );
if (op[i].mask && (!Match(op[i].mask, Client_Mask(Client))))
return Bad_OperPass(Client, op[i].mask, "hostmask check failed");
if( ! Client_HasMode( Client, 'o' ))
{
/* noch kein o-Mode gesetzt */
Client_ModeAdd( Client, 'o' );
if( ! IRC_WriteStrClient( Client, "MODE %s :+o", Client_ID( Client ))) return DISCONNECTED;
IRC_WriteStrServersPrefix( NULL, Client, "MODE %s :+o", Client_ID( Client ));
@@ -100,10 +100,8 @@ IRC_DIE(CLIENT * Client, REQUEST * Req)
assert(Client != NULL);
assert(Req != NULL);
/* Not a local IRC operator? */
if ((!Client_HasMode(Client, 'o')) || (!Client_OperByMe(Client)))
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
Client_ID(Client));
if (!Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
#ifdef STRICT_RFC
@@ -142,15 +140,15 @@ IRC_REHASH( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
/* Not a local IRC operator? */
if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
if (!Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
Log( LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...", Client_Mask( Client ));
NGIRCd_SignalRehash = true;
raise(SIGHUP);
return CONNECTED;
} /* IRC_REHASH */
@@ -163,8 +161,8 @@ IRC_RESTART( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
/* Not a local IRC operator? */
if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
if (!Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
@@ -181,17 +179,18 @@ IRC_RESTART( CLIENT *Client, REQUEST *Req )
GLOBAL bool
IRC_CONNECT(CLIENT * Client, REQUEST * Req)
{
CLIENT *from, *target;
assert(Client != NULL);
assert(Req != NULL);
/* Not a local IRC operator? */
if ((!Client_HasMode(Client, 'o')) || (!Client_OperByMe(Client)))
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
Client_ID(Client));
if (Client_Type(Client) != CLIENT_SERVER
&& !Client_HasMode(Client, 'o'))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
if ((Req->argc != 1) && (Req->argc != 2) && (Req->argc != 5))
if (Req->argc != 1 && Req->argc != 2 && Req->argc != 3 &&
Req->argc != 5 && Req->argc != 6)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
@@ -200,74 +199,125 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
Log(LOG_NOTICE | LOG_snotice,
"Got CONNECT command from \"%s\" for \"%s\".", Client_Mask(Client),
Req->argv[0]);
from = Client;
target = Client_ThisServer();
if (Req->argc == 3 || Req->argc == 6) {
/* This CONNECT has a target parameter */
if (Client_Type(Client) == CLIENT_SERVER && Req->prefix)
from = Client_Search(Req->prefix);
if (! from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
target = (Req->argc == 3) ? Client_Search(Req->argv[2])
: Client_Search(Req->argv[5]);
if (! target || Client_Type(target) != CLIENT_SERVER)
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from), Req->argv[0]);
}
if (target != Client_ThisServer()) {
/* Forward CONNECT command ... */
if (Req->argc == 3)
IRC_WriteStrClientPrefix(target, from,
"CONNECT %s %s :%s", Req->argv[0],
Req->argv[1], Req->argv[2]);
else
IRC_WriteStrClientPrefix(target, from,
"CONNECT %s %s %s %s %s :%s", Req->argv[0],
Req->argv[1], Req->argv[2], Req->argv[3],
Req->argv[4], Req->argv[5]);
return CONNECTED;
}
if (!Op_Check(from, Req))
return Op_NoPrivileges(Client, Req);
switch (Req->argc) {
case 1:
if (!Conf_EnablePassiveServer(Req->argv[0]))
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client),
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from),
Req->argv[0]);
break;
break;
case 2:
case 3:
/* Connect configured server */
if (!Conf_EnableServer
(Req->argv[0], (UINT16) atoi(Req->argv[1])))
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client),
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from),
Req->argv[0]);
break;
break;
default:
/* Add server */
if (!Conf_AddServer
(Req->argv[0], (UINT16) atoi(Req->argv[1]), Req->argv[2],
Req->argv[3], Req->argv[4]))
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client),
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from),
Req->argv[0]);
}
Log(LOG_NOTICE | LOG_snotice,
"Got CONNECT command from \"%s\" for \"%s\".", Client_Mask(from),
Req->argv[0]);
IRC_SendWallops(Client_ThisServer(), Client_ThisServer(),
"Received CONNECT %s from %s",
Req->argv[0], Client_ID(from));
return CONNECTED;
} /* IRC_CONNECT */
/**
* Disconnect (and disable) configured server.
*/
GLOBAL bool
IRC_DISCONNECT(CLIENT *Client, REQUEST *Req )
IRC_DISCONNECT(CLIENT * Client, REQUEST * Req)
{
/* Disconnect and disable configured server */
CONN_ID my_conn;
assert( Client != NULL );
assert( Req != NULL );
assert(Client != NULL);
assert(Req != NULL);
/* Not a local IRC operator? */
if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
if (!Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
if( Req->argc != 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if (Req->argc != 1)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
Log( LOG_NOTICE|LOG_snotice, "Got DISCONNECT command from \"%s\" for0 \"%s\".", Client_Mask( Client ), Req->argv[0]);
IRC_SendWallops(Client_ThisServer(), Client_ThisServer(),
"Received DISCONNECT %s from %s",
Req->argv[0], Client_ID(Client));
Log(LOG_NOTICE | LOG_snotice,
"Got DISCONNECT command from \"%s\" for \"%s\".",
Client_Mask(Client), Req->argv[0]);
/* Save ID of this connection */
my_conn = Client_Conn( Client );
my_conn = Client_Conn(Client);
/* Connect configured server */
if( ! Conf_DisableServer( Req->argv[0] )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] );
/* Disconnect configured server */
if (!Conf_DisableServer(Req->argv[0]))
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client), Req->argv[0]);
/* Are we still connected or were we killed, too? */
if( Conn_GetClient( my_conn )) return CONNECTED;
else return DISCONNECTED;
} /* IRC_CONNECT */
if (Conn_GetClient(my_conn))
return CONNECTED;
else
return DISCONNECTED;
} /* IRC_DISCONNECT */
GLOBAL bool
IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
{
CLIENT *to, *from;
int client_type;
CLIENT *from;
assert( Client != NULL );
assert( Req != NULL );
@@ -275,8 +325,7 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
if (Req->argc != 1)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
client_type = Client_Type(Client);
switch (client_type) {
switch (Client_Type(Client)) {
case CLIENT_USER:
if (!Client_OperByMe(Client))
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG, Client_ID(Client));
@@ -292,25 +341,9 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
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;
}
}
IRC_SendWallops(Client, from, "%s", Req->argv[0]);
return CONNECTED;
}
} /* IRC_WALLOPS */
/* -eof- */

View File

@@ -22,12 +22,10 @@
#include <strings.h>
#include "defines.h"
#include "resolve.h"
#include "conn.h"
#include "conn-func.h"
#include "conn-zip.h"
#include "conf.h"
#include "client.h"
#include "channel.h"
#include "irc-write.h"
#include "lists.h"
@@ -37,6 +35,7 @@
#include "numeric.h"
#include "ngircd.h"
#include "irc-info.h"
#include "op.h"
#include "exp.h"
#include "irc-server.h"
@@ -49,9 +48,8 @@
GLOBAL bool
IRC_SERVER( CLIENT *Client, REQUEST *Req )
{
char str[LINE_LEN], *ptr;
char str[LINE_LEN];
CLIENT *from, *c;
bool ok;
int i;
CONN_ID con;
@@ -70,56 +68,52 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
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 );
/* Ist dieser Server bei uns konfiguriert? */
/* Ist this server configured on out side? */
for( i = 0; i < MAX_SERVERS; i++ ) if( strcasecmp( Req->argv[0], Conf_Server[i].name ) == 0 ) break;
if( i >= MAX_SERVERS )
{
/* Server ist nicht konfiguriert! */
Log( LOG_ERR, "Connection %d: Server \"%s\" not configured here!", Client_Conn( Client ), Req->argv[0] );
Conn_Close( Client_Conn( Client ), NULL, "Server not configured here", true);
return DISCONNECTED;
}
if( strcmp( Client_Password( Client ), Conf_Server[i].pwd_in ) != 0 )
{
/* Falsches Passwort */
/* wrong password */
Log( LOG_ERR, "Connection %d: Got bad password from server \"%s\"!", Client_Conn( Client ), Req->argv[0] );
Conn_Close( Client_Conn( Client ), NULL, "Bad password", true);
return DISCONNECTED;
}
/* Ist ein Server mit dieser ID bereits registriert? */
/* Is there a registered server with this ID? */
if( ! Client_CheckID( Client, Req->argv[0] )) return DISCONNECTED;
/* Server-Strukturen fuellen ;-) */
Client_SetID( Client, Req->argv[0] );
Client_SetHops( Client, 1 );
Client_SetInfo( Client, Req->argv[Req->argc - 1] );
/* Meldet sich der Server bei uns an (d.h., bauen nicht wir
* selber die Verbindung zu einem anderen Server auf)? */
con = Client_Conn( Client );
if( Client_Token( Client ) != TOKEN_OUTBOUND )
{
/* Eingehende Verbindung: Unseren SERVER- und PASS-Befehl senden */
ok = true;
if( ! IRC_WriteStrClient( Client, "PASS %s %s", Conf_Server[i].pwd_out, NGIRCd_ProtoID )) ok = false;
else ok = IRC_WriteStrClient( Client, "SERVER %s 1 :%s", Conf_ServerName, Conf_ServerInfo );
if( ! ok )
{
Conn_Close( con, "Unexpected server behavior!", NULL, false );
return DISCONNECTED;
/* Is this server registering on our side, or are we connecting to
* a remote server? */
con = Client_Conn(Client);
if (Client_Token(Client) != TOKEN_OUTBOUND) {
/* Incoming connection, send user/pass */
if (!IRC_WriteStrClient(Client, "PASS %s %s",
Conf_Server[i].pwd_out,
NGIRCd_ProtoID)
|| !IRC_WriteStrClient(Client, "SERVER %s 1 :%s",
Conf_ServerName,
Conf_ServerInfo)) {
Conn_Close(con, "Unexpected server behavior!",
NULL, false);
return DISCONNECTED;
}
Client_SetIntroducer( Client, Client );
Client_SetToken( Client, 1 );
}
else
{
/* Ausgehende verbindung, SERVER und PASS wurden von uns bereits
* an die Gegenseite uerbermittelt */
Client_SetToken( Client, atoi( Req->argv[1] ));
Client_SetIntroducer(Client, Client);
Client_SetToken(Client, 1);
} else {
/* outgoing connect, we already sent a SERVER and PASS
* command to the peer */
Client_SetToken(Client, atoi(Req->argv[1]));
}
/* Mark this connection as belonging to an configured server */
@@ -139,15 +133,9 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
Client_SetType(Client, CLIENT_UNKNOWNSERVER);
#ifdef ZLIB
/* Kompression initialisieren, wenn erforderlich */
if( strchr( Client_Flags( Client ), 'Z' ))
{
if( ! Zip_InitConn( con ))
{
/* Fehler! */
Conn_Close( con, "Can't inizialize compression (zlib)!", NULL, false );
return DISCONNECTED;
}
if (strchr(Client_Flags(Client), 'Z') && !Zip_InitConn(con)) {
Conn_Close( con, "Can't inizialize compression (zlib)!", NULL, false );
return DISCONNECTED;
}
#endif
@@ -171,43 +159,34 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
}
else if( Client_Type( Client ) == CLIENT_SERVER )
{
/* Neuer Server wird im Netz angekuendigt */
/* New server is being introduced to the network */
/* Falsche Anzahl Parameter? */
if( Req->argc != 4 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* Ist ein Server mit dieser ID bereits registriert? */
/* check for existing server with same ID */
if( ! Client_CheckID( Client, Req->argv[0] )) return DISCONNECTED;
/* Ueberfluessige Hostnamen aus Info-Text entfernen */
ptr = strchr( Req->argv[3] + 2, '[' );
if( ! ptr ) ptr = Req->argv[3];
from = Client_Search( Req->prefix );
if( ! from )
{
/* Hm, Server, der diesen einfuehrt, ist nicht bekannt!? */
/* Uh, Server, that introduced the new server is unknown?! */
Log( LOG_ALERT, "Unknown ID in prefix of SERVER: \"%s\"! (on connection %d)", Req->prefix, Client_Conn( Client ));
Conn_Close( Client_Conn( Client ), NULL, "Unknown ID in prefix of SERVER", true);
return DISCONNECTED;
}
/* Neue Client-Struktur anlegen */
c = Client_NewRemoteServer( Client, Req->argv[0], from, atoi( Req->argv[1] ), atoi( Req->argv[2] ), ptr, true);
if( ! c )
{
/* Neue Client-Struktur konnte nicht angelegt werden */
c = Client_NewRemoteServer(Client, Req->argv[0], from, atoi(Req->argv[1]), atoi(Req->argv[2]), Req->argv[3], true);
if (!c) {
Log( LOG_ALERT, "Can't create client structure for server! (on connection %d)", Client_Conn( Client ));
Conn_Close( Client_Conn( Client ), NULL, "Can't allocate client structure for remote server", true);
return DISCONNECTED;
}
/* Log-Meldung zusammenbauen und ausgeben */
if(( Client_Hops( c ) > 1 ) && ( Req->prefix[0] )) snprintf( str, sizeof( str ), "connected to %s, ", Client_ID( from ));
else strcpy( str, "" );
Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" registered (via %s, %s%d hop%s).", Client_ID( c ), Client_ID( Client ), str, Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
/* Andere Server informieren */
/* notify other servers */
IRC_WriteStrServersPrefix( Client, from, "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ));
return CONNECTED;
@@ -228,7 +207,6 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
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 );
strlcpy( nick_in, Req->argv[1], sizeof( nick_in ));
@@ -240,7 +218,7 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
{
is_op = is_voiced = false;
/* Prefixe abschneiden */
/* cut off prefixes */
while(( *ptr == '@' ) || ( *ptr == '+' ))
{
if( *ptr == '@' ) is_op = true;
@@ -258,14 +236,14 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
if( is_op ) Channel_UserModeAdd( chan, c, 'o' );
if( is_voiced ) Channel_UserModeAdd( chan, c, 'v' );
/* im Channel bekannt machen */
/* announce to channel... */
IRC_WriteStrChannelPrefix( Client, chan, c, false, "JOIN :%s", channame );
/* Channel-User-Modes setzen */
/* set Channel-User-Modes */
strlcpy( modes, Channel_UserModes( chan, c ), sizeof( modes ));
if( modes[0] )
{
/* Modes im Channel bekannt machen */
/* send modes to channel */
IRC_WriteStrChannelPrefix( Client, chan, Client, false, "MODE %s +%s %s", channame, modes, Client_ID( c ));
}
@@ -276,60 +254,110 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
}
else Log( LOG_ERR, "Got NJOIN for unknown nick \"%s\" for channel \"%s\"!", ptr, channame );
/* naechsten Nick suchen */
/* search for next Nick */
ptr = strtok( NULL, "," );
}
/* an andere Server weiterleiten */
/* forward to other servers */
if( nick_out[0] != '\0' ) IRC_WriteStrServersPrefix( Client, Client_ThisServer( ), "NJOIN %s :%s", Req->argv[0], nick_out );
return CONNECTED;
} /* IRC_NJOIN */
/**
* Handler for the IRC command "SQUIT".
* See RFC 2813 section 4.1.2 and RFC 2812 section 3.1.8.
*/
GLOBAL bool
IRC_SQUIT( CLIENT *Client, REQUEST *Req )
IRC_SQUIT(CLIENT * Client, REQUEST * Req)
{
CLIENT *target;
char msg[LINE_LEN + 64];
char msg[COMMAND_LEN], logmsg[COMMAND_LEN];
CLIENT *from, *target;
CONN_ID con;
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 (Client_Type(Client) != CLIENT_SERVER
&& !Client_HasMode(Client, 'o'))
return Op_NoPrivileges(Client, Req);
Log( LOG_DEBUG, "Got SQUIT from %s for \"%s\": \"%s\" ...", Client_ID( Client ), Req->argv[0], Req->argv[1] );
/* Bad number of arguments? */
if (Req->argc != 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
target = Client_Search( Req->argv[0] );
if( ! target )
{
/* Den Server kennen wir nicht (mehr), also nichts zu tun. */
Log( LOG_WARNING, "Got SQUIT from %s for unknown server \"%s\"!?", Client_ID( Client ), Req->argv[0] );
if (Client_Type(Client) == CLIENT_SERVER && Req->prefix) {
from = Client_Search(Req->prefix);
if (Client_Type(from) != CLIENT_SERVER
&& !Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
} else
from = Client;
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
Log(LOG_DEBUG, "Got SQUIT from %s for \"%s\": \"%s\" ...",
Client_ID(from), Req->argv[0], Req->argv[1]);
target = Client_Search(Req->argv[0]);
if (Client_Type(Client) != CLIENT_SERVER &&
target == Client_ThisServer())
return Op_NoPrivileges(Client, Req);
if (!target) {
/* The server is (already) unknown */
Log(LOG_WARNING,
"Got SQUIT from %s for unknown server \"%s\"!?",
Client_ID(Client), Req->argv[0]);
return CONNECTED;
}
if( Req->argv[1][0] )
{
if( strlen( Req->argv[1] ) > LINE_LEN ) Req->argv[1][LINE_LEN] = '\0';
snprintf( msg, sizeof( msg ), "%s (SQUIT from %s).", Req->argv[1], Client_ID( Client ));
}
else snprintf( msg, sizeof( msg ), "Got SQUIT from %s.", Client_ID( Client ));
con = Client_Conn(target);
if( Client_Conn( target ) > NONE )
{
/* dieser Server hat die Connection */
if( Req->argv[1][0] ) Conn_Close( Client_Conn( target ), msg, Req->argv[1], true);
else Conn_Close( Client_Conn( target ), msg, NULL, true);
return DISCONNECTED;
}
if (Req->argv[1][0])
if (Client_NextHop(from) != Client || con > NONE)
snprintf(msg, sizeof(msg), "%s (SQUIT from %s)",
Req->argv[1], Client_ID(from));
else
strlcpy(msg, Req->argv[1], sizeof(msg));
else
{
/* Verbindung hielt anderer Server */
Client_Destroy( target, msg, Req->argv[1], false );
return CONNECTED;
snprintf(msg, sizeof(msg), "Got SQUIT from %s",
Client_ID(from));
if (con > NONE) {
/* We are directly connected to the target server, so we
* have to tear down the connection and to inform all the
* other remaining servers in the network */
IRC_SendWallops(Client_ThisServer(), Client_ThisServer(),
"Received SQUIT %s from %s: %s",
Req->argv[0], Client_ID(from),
Req->argv[1][0] ? Req->argv[1] : "-");
Conn_Close(con, NULL, msg, true);
if (con == Client_Conn(Client))
return DISCONNECTED;
} else {
/* This server is not directly connected, so the SQUIT must
* be forwarded ... */
if (Client_Type(from) != CLIENT_SERVER) {
/* The origin is not an IRC server, so don't evaluate
* this SQUIT but simply forward it */
IRC_WriteStrClientPrefix(Client_NextHop(target),
from, "SQUIT %s :%s", Req->argv[0], Req->argv[1]);
} else {
/* SQUIT has been generated by another server, so
* remove the target server from the network! */
logmsg[0] = '\0';
if (!strchr(msg, '('))
snprintf(logmsg, sizeof(logmsg),
"%s (SQUIT from %s)", Req->argv[1],
Client_ID(from));
Client_Destroy(target, logmsg[0] ? logmsg : msg,
msg, false);
}
}
return CONNECTED;
} /* IRC_SQUIT */
/* -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
@@ -14,8 +14,6 @@
#include "portab.h"
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>
#ifdef PROTOTYPES
@@ -28,7 +26,6 @@ static char UNUSED id[] = "$Id: irc-write.c,v 1.21 2006/08/12 11:56:24 fw Exp $"
#include "defines.h"
#include "conn-func.h"
#include "client.h"
#include "channel.h"
#include "exp.h"
@@ -39,19 +36,20 @@ static char UNUSED id[] = "$Id: irc-write.c,v 1.21 2006/08/12 11:56:24 fw Exp $"
#define SEND_TO_SERVER 2
static char *Get_Prefix PARAMS((CLIENT *Target, CLIENT *Client));
static const char *Get_Prefix PARAMS((CLIENT *Target, CLIENT *Client));
static void cb_writeStrServersPrefixFlag PARAMS((CLIENT *Client,
CLIENT *Prefix, void *Buffer));
static bool Send_Marked_Connections PARAMS((CLIENT *Prefix, const char *Buffer));
#ifdef PROTOTYPES
GLOBAL bool
IRC_WriteStrClient( CLIENT *Client, char *Format, ... )
IRC_WriteStrClient( CLIENT *Client, const char *Format, ... )
#else
GLOBAL bool
IRC_WriteStrClient( Client, Format, va_alist )
CLIENT *Client;
char *Format;
const char *Format;
va_dcl
#endif
{
@@ -70,7 +68,7 @@ va_dcl
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
/* an den Client selber */
/* to the client itself */
ok = IRC_WriteStrClientPrefix( Client, Client_ThisServer( ), "%s", buffer );
return ok;
@@ -79,17 +77,17 @@ va_dcl
#ifdef PROTOTYPES
GLOBAL bool
IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, char *Format, ... )
IRC_WriteStrClientPrefix(CLIENT *Client, CLIENT *Prefix, const char *Format, ...)
#else
GLOBAL bool
IRC_WriteStrClientPrefix( Client, Prefix, Format, va_alist )
IRC_WriteStrClientPrefix(Client, Prefix, Format, va_alist)
CLIENT *Client;
CLIENT *Prefix;
char *Format;
const char *Format;
va_dcl
#endif
{
/* Text an Clients, lokal bzw. remote, senden. */
/* send text to local and remote clients */
char buffer[1000];
va_list ap;
@@ -106,20 +104,22 @@ va_dcl
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
return Conn_WriteStr( Client_Conn( Client_NextHop( Client )), ":%s %s", Get_Prefix( Client_NextHop( Client ), Prefix ), buffer );
return Conn_WriteStr(Client_Conn(Client_NextHop(Client)), ":%s %s",
Get_Prefix(Client_NextHop(Client), Prefix), buffer);
} /* IRC_WriteStrClientPrefix */
#ifdef PROTOTYPES
GLOBAL bool
IRC_WriteStrChannel( CLIENT *Client, CHANNEL *Chan, bool Remote, char *Format, ... )
IRC_WriteStrChannel(CLIENT *Client, CHANNEL *Chan, bool Remote,
const char *Format, ...)
#else
GLOBAL bool
IRC_WriteStrChannel( Client, Chan, Remote, Format, va_alist )
IRC_WriteStrChannel(Client, Chan, Remote, Format, va_alist)
CLIENT *Client;
CHANNEL *Chan;
bool Remote;
char *Format;
const char *Format;
va_dcl
#endif
{
@@ -141,21 +141,26 @@ va_dcl
} /* IRC_WriteStrChannel */
/**
* send message to all clients in the same channel, but only send message
* once per remote server.
*/
#ifdef PROTOTYPES
GLOBAL bool
IRC_WriteStrChannelPrefix( CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, bool Remote, char *Format, ... )
IRC_WriteStrChannelPrefix(CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix,
bool Remote, const char *Format, ...)
#else
GLOBAL bool
IRC_WriteStrChannelPrefix( Client, Chan, Prefix, Remote, Format, va_alist )
IRC_WriteStrChannelPrefix(Client, Chan, Prefix, Remote, Format, va_alist)
CLIENT *Client;
CHANNEL *Chan;
CLIENT *Prefix;
bool Remote;
char *Format;
const char *Format;
va_dcl
#endif
{
bool ok = CONNECTED;
char buffer[1000];
CL2CHAN *cl2chan;
CONN_ID conn;
@@ -177,8 +182,6 @@ va_dcl
Conn_ClearFlags( );
/* An alle Clients, die in den selben Channels sind.
* Dabei aber nur einmal je Remote-Server */
cl2chan = Channel_FirstMember( Chan );
while( cl2chan )
{
@@ -192,39 +195,25 @@ va_dcl
if( c && ( c != Client ))
{
/* Ok, anderer Client */
/* Ok, another Client */
conn = Client_Conn( c );
if( Client_Type( c ) == CLIENT_SERVER ) Conn_SetFlag( conn, SEND_TO_SERVER );
else Conn_SetFlag( conn, SEND_TO_USER );
}
cl2chan = Channel_NextMember( Chan, cl2chan );
}
/* Senden: alle Verbindungen durchgehen ... */
conn = Conn_First( );
while( conn != NONE )
{
/* muessen Daten ueber diese Verbindung verschickt werden? */
if( Conn_Flag( conn ) == SEND_TO_SERVER) ok = Conn_WriteStr( conn, ":%s %s", Client_ID( Prefix ), buffer );
else if( Conn_Flag( conn ) == SEND_TO_USER ) ok = Conn_WriteStr( conn, ":%s %s", Client_Mask( Prefix ), buffer );
if( ! ok ) break;
/* naechste Verbindung testen */
conn = Conn_Next( conn );
}
return ok;
return Send_Marked_Connections(Prefix, buffer);
} /* IRC_WriteStrChannelPrefix */
#ifdef PROTOTYPES
GLOBAL void
IRC_WriteStrServers( CLIENT *ExceptOf, char *Format, ... )
IRC_WriteStrServers(CLIENT *ExceptOf, const char *Format, ...)
#else
GLOBAL void
IRC_WriteStrServers( ExceptOf, Format, va_alist )
IRC_WriteStrServers(ExceptOf, Format, va_alist)
CLIENT *ExceptOf;
char *Format;
const char *Format;
va_dcl
#endif
{
@@ -241,20 +230,20 @@ va_dcl
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
/* an den Client selber */
IRC_WriteStrServersPrefix( ExceptOf, Client_ThisServer( ), "%s", buffer );
} /* IRC_WriteStrServers */
#ifdef PROTOTYPES
GLOBAL void
IRC_WriteStrServersPrefix( CLIENT *ExceptOf, CLIENT *Prefix, char *Format, ... )
IRC_WriteStrServersPrefix(CLIENT *ExceptOf, CLIENT *Prefix,
const char *Format, ...)
#else
GLOBAL void
IRC_WriteStrServersPrefix( ExceptOf, Prefix, Format, va_alist )
IRC_WriteStrServersPrefix(ExceptOf, Prefix, Format, va_alist)
CLIENT *ExceptOf;
CLIENT *Prefix;
char *Format;
const char *Format;
va_dcl
#endif
{
@@ -278,14 +267,15 @@ va_dcl
#ifdef PROTOTYPES
GLOBAL void
IRC_WriteStrServersPrefixFlag( CLIENT *ExceptOf, CLIENT *Prefix, char Flag, char *Format, ... )
IRC_WriteStrServersPrefixFlag(CLIENT *ExceptOf, CLIENT *Prefix, char Flag,
const char *Format, ...)
#else
GLOBAL void
IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, Flag, Format, va_alist )
IRC_WriteStrServersPrefixFlag(ExceptOf, Prefix, Flag, Format, va_alist)
CLIENT *ExceptOf;
CLIENT *Prefix;
char Flag;
char *Format;
const char *Format;
va_dcl
#endif
{
@@ -327,20 +317,24 @@ IRC_WriteStrServersPrefixFlag_CB(CLIENT *ExceptOf, CLIENT *Prefix, char Flag,
} /* IRC_WriteStrServersPrefixFlag */
/**
* send message to all clients that are in the same channels as the client sending this message.
* only send message once per reote server.
*/
#ifdef PROTOTYPES
GLOBAL bool
IRC_WriteStrRelatedPrefix( CLIENT *Client, CLIENT *Prefix, bool Remote, char *Format, ... )
IRC_WriteStrRelatedPrefix(CLIENT *Client, CLIENT *Prefix, bool Remote,
const char *Format, ...)
#else
GLOBAL bool
IRC_WriteStrRelatedPrefix( Client, Prefix, Remote, Format, va_alist )
IRC_WriteStrRelatedPrefix(Client, Prefix, Remote, Format, va_alist)
CLIENT *Client;
CLIENT *Prefix;
bool Remote;
char *Format;
const char *Format;
va_dcl
#endif
{
bool ok = CONNECTED;
CL2CHAN *chan_cl2chan, *cl2chan;
char buffer[1000];
CHANNEL *chan;
@@ -360,15 +354,11 @@ va_dcl
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
/* initialisieren */
Conn_ClearFlags( );
/* An alle Clients, die in einem Channel mit dem "Ausloeser" sind,
* den Text schicken. An Remote-Server aber jeweils nur einmal. */
chan_cl2chan = Channel_FirstChannelOf( Client );
while( chan_cl2chan )
{
/* Channel des Users durchsuchen */
chan = Channel_GetChannel( chan_cl2chan );
cl2chan = Channel_FirstMember( chan );
while( cl2chan )
@@ -383,7 +373,6 @@ va_dcl
if( c && ( c != Client ))
{
/* Ok, anderer Client */
conn = Client_Conn( c );
if( Client_Type( c ) == CLIENT_SERVER ) Conn_SetFlag( conn, SEND_TO_SERVER );
else Conn_SetFlag( conn, SEND_TO_USER );
@@ -391,26 +380,59 @@ va_dcl
cl2chan = Channel_NextMember( chan, cl2chan );
}
/* naechsten Channel */
chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan );
}
/* Senden: alle Verbindungen durchgehen ... */
conn = Conn_First( );
while( conn != NONE )
{
/* muessen ueber diese Verbindung Daten gesendet werden? */
if( Conn_Flag( conn ) == SEND_TO_SERVER ) ok = Conn_WriteStr( conn, ":%s %s", Client_ID( Prefix ), buffer );
else if( Conn_Flag( conn ) == SEND_TO_USER ) ok = Conn_WriteStr( conn, ":%s %s", Client_Mask( Prefix ), buffer );
if( ! ok ) break;
/* naechste Verbindung testen */
conn = Conn_Next( conn );
}
return ok;
return Send_Marked_Connections(Prefix, buffer);
} /* IRC_WriteStrRelatedPrefix */
/**
* Send WALLOPS message.
*/
#ifdef PROTOTYPES
GLOBAL void
IRC_SendWallops(CLIENT *Client, CLIENT *From, const char *Format, ...)
#else
GLOBAL void
IRC_SendWallops(Client, From, Format, va_alist )
CLIENT *Client;
CLIENT *From;
const char *Format;
va_dcl
#endif
{
va_list ap;
char msg[1000];
CLIENT *to;
#ifdef PROTOTYPES
va_start(ap, Format);
#else
va_start(ap);
#endif
vsnprintf(msg, 1000, Format, ap);
va_end(ap);
for (to=Client_First(); to != NULL; to=Client_Next(to)) {
if (Client_Conn(to) == NONE) /* no local connection */
continue;
switch (Client_Type(to)) {
case CLIENT_USER:
if (Client_HasMode(to, 'w'))
IRC_WriteStrClientPrefix(to, From,
"WALLOPS :%s", msg);
break;
case CLIENT_SERVER:
if (to != Client)
IRC_WriteStrClientPrefix(to, From,
"WALLOPS :%s", msg);
break;
}
}
} /* IRC_SendWallops */
GLOBAL void
IRC_SetPenalty( CLIENT *Client, time_t Seconds )
{
@@ -427,14 +449,16 @@ IRC_SetPenalty( CLIENT *Client, time_t Seconds )
} /* IRC_SetPenalty */
static char *
Get_Prefix( CLIENT *Target, CLIENT *Client )
static const char *
Get_Prefix(CLIENT *Target, CLIENT *Client)
{
assert( Target != NULL );
assert( Client != NULL );
assert (Target != NULL);
assert (Client != NULL);
if( Client_Type( Target ) == CLIENT_SERVER ) return Client_ID( Client );
else return Client_Mask( Client );
if (Client_Type(Target) == CLIENT_SERVER)
return Client_ID(Client);
else
return Client_MaskCloaked(Client);
} /* Get_Prefix */
@@ -445,4 +469,29 @@ cb_writeStrServersPrefixFlag(CLIENT *Client, CLIENT *Prefix, void *Buffer)
} /* cb_writeStrServersPrefixFlag */
static bool
Send_Marked_Connections(CLIENT *Prefix, const char *Buffer)
{
CONN_ID conn;
bool ok = CONNECTED;
assert(Prefix != NULL);
assert(Buffer != NULL);
conn = Conn_First();
while (conn != NONE) {
if (Conn_Flag(conn) == SEND_TO_SERVER)
ok = Conn_WriteStr(conn, ":%s %s",
Client_ID(Prefix), Buffer);
else if (Conn_Flag(conn) == SEND_TO_USER)
ok = Conn_WriteStr(conn, ":%s %s",
Client_MaskCloaked(Prefix), Buffer);
if (!ok)
break;
conn = Conn_Next( conn );
}
return ok;
}
/* -eof- */

View File

@@ -14,26 +14,30 @@
#ifndef __irc_write_h__
#define __irc_write_h__
GLOBAL bool IRC_WriteStrClient PARAMS((CLIENT *Client, char *Format, ...));
GLOBAL bool IRC_WriteStrClient PARAMS((CLIENT *Client, const char *Format, ...));
GLOBAL bool IRC_WriteStrClientPrefix PARAMS((CLIENT *Client, CLIENT *Prefix,
char *Format, ...));
const char *Format, ...));
GLOBAL bool IRC_WriteStrChannel PARAMS((CLIENT *Client, CHANNEL *Chan,
bool Remote, char *Format, ...));
bool Remote, const char *Format, ...));
GLOBAL bool IRC_WriteStrChannelPrefix PARAMS((CLIENT *Client, CHANNEL *Chan,
CLIENT *Prefix, bool Remote, char *Format, ...));
CLIENT *Prefix, bool Remote, const char *Format, ...));
GLOBAL void IRC_WriteStrServers PARAMS((CLIENT *ExceptOf, char *Format, ...));
GLOBAL void IRC_WriteStrServers PARAMS((CLIENT *ExceptOf,
const char *Format, ...));
GLOBAL void IRC_WriteStrServersPrefix PARAMS((CLIENT *ExceptOf, CLIENT *Prefix,
char *Format, ...));
const char *Format, ...));
GLOBAL void IRC_WriteStrServersPrefixFlag PARAMS((CLIENT *ExceptOf,
CLIENT *Prefix, char Flag, char *Format, ...));
CLIENT *Prefix, char Flag, const char *Format, ...));
GLOBAL void IRC_WriteStrServersPrefixFlag_CB PARAMS((CLIENT *ExceptOf,
CLIENT *Prefix, char Flag,
void (*callback)(CLIENT *, CLIENT *, void *), void *cb_data));
GLOBAL bool IRC_WriteStrRelatedPrefix PARAMS((CLIENT *Client, CLIENT *Prefix,
bool Remote, char *Format, ...));
bool Remote, const char *Format, ...));
GLOBAL void IRC_SendWallops PARAMS((CLIENT *Client, CLIENT *From,
const char *Format, ...));
GLOBAL void IRC_SetPenalty PARAMS((CLIENT *Client, time_t Seconds));

View File

@@ -22,10 +22,8 @@ static char UNUSED id[] = "$Id: irc.c,v 1.132 2008/01/15 22:28:14 fw Exp $";
#include <string.h>
#include "ngircd.h"
#include "resolve.h"
#include "conn-func.h"
#include "conf.h"
#include "client.h"
#include "channel.h"
#include "defines.h"
#include "irc-write.h"
@@ -53,8 +51,12 @@ IRC_ERROR( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
if( Req->argc < 1 ) Log( LOG_NOTICE, "Got ERROR from \"%s\"!", Client_Mask( Client ));
else Log( LOG_NOTICE, "Got ERROR from \"%s\": %s!", Client_Mask( Client ), Req->argv[0] );
if (Req->argc < 1)
Log(LOG_NOTICE, "Got ERROR from \"%s\"!",
Client_Mask(Client));
else
Log(LOG_NOTICE, "Got ERROR from \"%s\": \"%s\"!",
Client_Mask(Client), Req->argv[0]);
return CONNECTED;
} /* IRC_ERROR */
@@ -66,7 +68,7 @@ IRC_ERROR( CLIENT *Client, REQUEST *Req )
* disconnect clients. It can be used by IRC operators and servers, for example
* to "solve" nick collisions after netsplits.
* Please note that this function is also called internally, without a real
* KILL command beeing received over the network! Client is Client_ThisServer()
* KILL command being received over the network! Client is Client_ThisServer()
* in this case. */
GLOBAL bool
IRC_KILL( CLIENT *Client, REQUEST *Req )
@@ -156,11 +158,15 @@ IRC_KILL( CLIENT *Client, REQUEST *Req )
Client_Type( c ), Req->argv[0] );
}
/* Kill client NOW! */
/* Kill the client NOW:
* - Close the local connection (if there is one),
* - Destroy the CLIENT structure for remote clients.
* Note: Conn_Close() removes the CLIENT structure as well. */
conn = Client_Conn( c );
Client_Destroy( c, NULL, reason, false );
if( conn > NONE )
Conn_Close( conn, NULL, reason, true );
if(conn > NONE)
Conn_Close(conn, NULL, reason, true);
else
Client_Destroy(c, NULL, reason, false);
}
else
Log( LOG_NOTICE, "Client with nick \"%s\" is unknown here.", Req->argv[0] );
@@ -406,7 +412,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
if (nick != NULL && host != NULL) {
if (strcmp(nick, Client_ID(cl)) == 0 &&
strcmp(user, Client_User(cl)) == 0 &&
strcasecmp(host, Client_Hostname(cl)) == 0)
strcasecmp(host, Client_HostnameCloaked(cl)) == 0)
break;
else
continue;
@@ -414,7 +420,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
if (strcasecmp(user, Client_User(cl)) != 0)
continue;
if (host != NULL && strcasecmp(host,
Client_Hostname(cl)) != 0)
Client_HostnameCloaked(cl)) != 0)
continue;
if (server != NULL && strcasecmp(server,
Client_ID(Client_Introducer(cl))) != 0)
@@ -467,18 +473,18 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
Req->argv[1]))
return DISCONNECTED;
} else if (ForceType != CLIENT_SERVICE
&& (chan = Channel_Search(currentTarget))) {
if (!Channel_Write(chan, from, Client, Req->command,
SendErrors, Req->argv[1]))
return DISCONNECTED;
} else if (ForceType != CLIENT_SERVICE
/* $#: server/target mask, RFC 2812, sec. 3.3.1 */
&& 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;
@@ -501,6 +507,7 @@ Send_Message_Mask(CLIENT * from, char * command, char * targetMask,
CLIENT *cl;
bool client_match;
char *mask = targetMask + 1;
const char *check_wildcards;
cl = NULL;
@@ -511,6 +518,21 @@ Send_Message_Mask(CLIENT * from, char * command, char * targetMask,
Client_ID(from));
}
/*
* RFC 2812, sec. 3.3.1 requires that targetMask have at least one
* dot (".") and no wildcards ("*", "?") following the last one.
*/
check_wildcards = strrchr(targetMask, '.');
assert(check_wildcards != NULL);
if (check_wildcards &&
check_wildcards[strcspn(check_wildcards, "*?")])
{
if (!SendErrors)
return true;
return IRC_WriteStrClient(from, ERR_WILDTOPLEVEL, targetMask);
}
/* #: hostmask, see RFC 2812, sec. 3.3.1 */
if (targetMask[0] == '#') {
for (cl = Client_First(); cl != NULL; cl = Client_Next(cl)) {
if (Client_Type(cl) != CLIENT_USER)
@@ -522,6 +544,7 @@ Send_Message_Mask(CLIENT * from, char * command, char * targetMask,
return false;
}
} else {
assert(targetMask[0] == '$'); /* $: server mask, see RFC 2812, sec. 3.3.1 */
for (cl = Client_First(); cl != NULL; cl = Client_Next(cl)) {
if (Client_Type(cl) != CLIENT_USER)
continue;

View File

@@ -19,7 +19,6 @@
#include "defines.h"
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "log.h"
#include "match.h"

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2005 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 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: log.c,v 1.62 2006/08/05 09:16:21 fw Exp $";
#include "imp.h"
#include <assert.h>
#include <errno.h>
@@ -36,9 +34,9 @@ static char UNUSED id[] = "$Id: log.c,v 1.62 2006/08/05 09:16:21 fw Exp $";
#include "ngircd.h"
#include "defines.h"
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "irc-write.h"
#include "conf.h"
#include "exp.h"
#include "log.h"
@@ -52,7 +50,21 @@ static char Error_File[FNAME_LEN];
#endif
static void Wall_ServerNotice PARAMS(( char *Msg ));
static void
Log_Message(int Level, const char *msg)
{
if (!Is_Daemon) {
/* log to console */
fprintf(stdout, "[%ld:%d %4ld] %s\n", (long)getpid(), Level,
(long)time(NULL) - NGIRCd_Start, msg);
fflush(stdout);
}
#ifdef SYSLOG
else {
syslog(Level, "%s", msg);
}
#endif
}
GLOBAL void
@@ -61,20 +73,15 @@ 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 */
#define LOG_CONS 0
#endif
#ifndef LOG_LOCAL5
#define LOG_LOCAL5 0
#endif
/* Syslog initialisieren */
openlog( PACKAGE_NAME, LOG_CONS|LOG_PID, LOG_LOCAL5 );
openlog(PACKAGE_NAME, LOG_CONS|LOG_PID, Conf_SyslogFacility);
#endif
/* Hello World! */
Log( LOG_NOTICE, "%s started.", NGIRCd_Version );
/* Informationen uebern den "Operation Mode" */
/* Information about "Operation Mode" */
Init_Txt[0] = '\0';
#ifdef DEBUG
if( NGIRCd_Debug )
@@ -108,17 +115,11 @@ Log_Init( bool Daemon_Mode )
#ifdef DEBUG
GLOBAL void
Log_InitErrorfile( void )
{
/* "Error-Log" initialisieren: stderr in Datei umlenken. Dort
* landen z.B. alle Ausgaben von assert()-Aufrufen. */
/* Dateiname zusammen bauen */
snprintf( Error_File, sizeof Error_File, "%s/%s-%ld.err", ERROR_DIR, PACKAGE_NAME, (long)getpid( ));
/* stderr umlenken */
fflush( stderr );
if( ! freopen( Error_File, "w", stderr ))
{
@@ -126,17 +127,13 @@ Log_InitErrorfile( void )
return;
}
/* Einige Infos in das Error-File schreiben */
fputs( ctime( &NGIRCd_Start ), stderr );
fprintf( stderr, "%s started.\n", NGIRCd_Version );
fprintf( stderr, "Activating: %s\n\n", Init_Txt[0] ? Init_Txt : "-" );
fflush( stderr );
#ifdef DEBUG
Log( LOG_DEBUG, "Redirected stderr to \"%s\".", Error_File );
#endif
Log(LOG_DEBUG, "Redirected stderr to \"%s\".", Error_File);
} /* Log_InitErrfile */
#endif
@@ -144,8 +141,8 @@ GLOBAL void
Log_Exit( void )
{
/* Good Bye! */
if( NGIRCd_SignalRestart ) Log( LOG_NOTICE, "%s done (restarting).", PACKAGE_NAME );
else Log( LOG_NOTICE, "%s done.", PACKAGE_NAME );
Log(LOG_NOTICE, "%s done%s, served %lu connections.", PACKAGE_NAME,
NGIRCd_SignalRestart ? " (restarting)" : "", Conn_CountAccepted());
#ifdef DEBUG
if( Error_File[0] )
@@ -156,8 +153,7 @@ Log_Exit( void )
#endif
#ifdef SYSLOG
/* syslog abmelden */
closelog( );
closelog();
#endif
} /* Log_Exit */
@@ -248,125 +244,121 @@ va_dcl
vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
va_end( ap );
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
{
/* Syslog */
syslog( Level, "%s", msg );
}
#endif
Log_Message(Level, msg);
if( Level <= LOG_CRIT )
{
if (Level <= LOG_CRIT) {
/* log critical messages to stderr */
fprintf( stderr, "%s\n", msg );
fflush( stderr );
fprintf(stderr, "%s\n", msg);
fflush(stderr);
}
if (snotice) {
/* Send NOTICE to all local users with mode +s and to the
* local &SERVER channel */
Wall_ServerNotice(msg);
Log_ServerNotice('s', "%s", msg);
Channel_LogServer(msg);
}
} /* Log */
GLOBAL void
Log_Init_Resolver( void )
Log_Init_Subprocess(char UNUSED *Name)
{
#ifdef SYSLOG
openlog( PACKAGE_NAME, LOG_CONS|LOG_PID, LOG_LOCAL5 );
openlog(PACKAGE_NAME, LOG_CONS|LOG_PID, Conf_SyslogFacility);
#endif
#ifdef DEBUG
Log_Resolver( LOG_DEBUG, "Resolver sub-process starting, PID %d.", getpid( ));
Log_Subprocess(LOG_DEBUG, "%s sub-process starting, PID %ld.",
Name, (long)getpid());
#endif
} /* Log_Init_Resolver */
}
GLOBAL void
Log_Exit_Resolver( void )
Log_Exit_Subprocess(char UNUSED *Name)
{
#ifdef DEBUG
Log_Resolver( LOG_DEBUG, "Resolver sub-process %d done.", getpid( ));
Log_Subprocess(LOG_DEBUG, "%s sub-process %ld done.",
Name, (long)getpid());
#endif
#ifdef SYSLOG
closelog( );
#endif
} /* Log_Exit_Resolver */
}
#ifdef PROTOTYPES
GLOBAL void
Log_Resolver( const int Level, const char *Format, ... )
Log_Subprocess(const int Level, const char *Format, ...)
#else
GLOBAL void
Log_Resolver( Level, Format, va_alist )
Log_Subprocess(Level, Format, va_alist)
const int Level;
const char *Format;
va_dcl
#endif
{
/* Eintrag des Resolver in Logfile(s) schreiben */
char msg[MAX_LOG_MSG_LEN];
va_list ap;
assert( Format != NULL );
assert(Format != NULL);
#ifdef DEBUG
if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
if ((Level == LOG_DEBUG) && (!NGIRCd_Debug))
return;
#else
if( Level == LOG_DEBUG ) return;
if (Level == LOG_DEBUG)
return;
#endif
/* String mit variablen Argumenten zusammenbauen ... */
#ifdef PROTOTYPES
va_start( ap, Format );
va_start(ap, Format);
#else
va_start( ap );
va_start(ap);
#endif
vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
va_end( ap );
vsnprintf(msg, MAX_LOG_MSG_LEN, Format, ap);
va_end(ap);
if (!Is_Daemon) {
/* Output to console */
fprintf(stdout, "[%d:%d %4ld] %s\n", (int)getpid( ), Level,
time(NULL) - NGIRCd_Start, msg);
fflush(stdout);
}
#ifdef SYSLOG
else syslog( Level, "%s", msg );
#endif
} /* Log_Resolver */
Log_Message(Level, msg);
}
/**
* Send log messages to users flagged with the "s" mode.
* @param Msg The message to send.
* Send a log message to all local users flagged with the given user mode.
* @param UserMode User mode which the target user must have set,
* @param Format The format string.
*/
static void
Wall_ServerNotice( char *Msg )
#ifdef PROTOTYPES
GLOBAL void
Log_ServerNotice(const char UserMode, const char *Format, ... )
#else
GLOBAL void
Log_ServerNotice(UserMode, Format, va_alist)
const char UserMode;
const char *Format;
va_dcl
#endif
{
CLIENT *c;
char msg[MAX_LOG_MSG_LEN];
va_list ap;
assert( Msg != NULL );
assert(Format != NULL);
c = Client_First( );
while(c) {
if (Client_Conn(c) > NONE && Client_HasMode(c, 's'))
#ifdef PROTOTYPES
va_start(ap, Format);
#else
va_start(ap);
#endif
vsnprintf(msg, MAX_LOG_MSG_LEN, Format, ap);
va_end(ap);
for(c=Client_First(); c != NULL; c=Client_Next(c)) {
if (Client_Conn(c) > NONE && Client_HasMode(c, UserMode))
IRC_WriteStrClient(c, "NOTICE %s :%s%s", Client_ID(c),
NOTICE_TXTPREFIX, Msg);
c = Client_Next( c );
NOTICE_TXTPREFIX, msg);
}
} /* Wall_ServerNotice */
} /* Log_ServerNotice */
/* -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-2010 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: log.h,v 1.20 2006/08/05 09:16:21 fw Exp $
*
* Logging functions (header)
*/
@@ -40,17 +38,18 @@ GLOBAL void Log_Exit PARAMS(( void ));
GLOBAL void Log PARAMS(( int Level, const char *Format, ... ));
GLOBAL void Log_ServerNotice PARAMS((char UserMode, 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_Subprocess PARAMS((char *Name));
GLOBAL void Log_Exit_Subprocess PARAMS((char *Name));
GLOBAL void Log_Init_Resolver PARAMS(( void ));
GLOBAL void Log_Exit_Resolver PARAMS(( void ));
GLOBAL void Log_Resolver PARAMS(( const int Level, const char *Format, ... ));
GLOBAL void Log_Subprocess PARAMS((const int Level, const char *Format, ...));
#ifdef DEBUG
GLOBAL void Log_InitErrorfile PARAMS(( void ));

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
* Copyright (c)2001-2010 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
@@ -20,7 +20,7 @@
#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_ISUPPORT1_MSG "005 %s RFC2812 CASEMAPPING=ascii PREFIX=(ov)@+ CHANTYPES=#&+ CHANMODES=bI,k,l,imnPst CHANLIMIT=#&+:%d :are supported on this server"
#define RPL_ISUPPORT1_MSG "005 %s RFC2812 IRCD=ngIRCd 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"
@@ -46,6 +46,8 @@
#define RPL_TRACEEND_MSG "262 %s %s %s-%s.%s :End of TRACE"
#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_STATSCONN_MSG "250 %s :Highest connection count: %lu (%lu connections received)"
#define RPL_WHOISSSL_MSG "275 %s %s :is connected via SSL (secure link)"
#define RPL_AWAY_MSG "301 %s %s :%s"
#define RPL_USERHOST_MSG "302 %s :"
@@ -94,8 +96,9 @@
#define ERR_TOOMANYCHANNELS_MSG "405 %s %s :You have joined too many channels"
#define ERR_WASNOSUCHNICK_MSG "406 %s %s :There was no such nickname"
#define ERR_NOORIGIN_MSG "409 %s :No origin specified"
#define ERR_NORECIPIENT_MSG "411 %s :No receipient given (%s)"
#define ERR_NORECIPIENT_MSG "411 %s :No recipient given (%s)"
#define ERR_NOTEXTTOSEND_MSG "412 %s :No text to send"
#define ERR_WILDTOPLEVEL "414 %s :Wildcard in toplevel domain"
#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"
@@ -112,6 +115,7 @@
#define ERR_ALREADYREGISTRED_MSG "462 %s :Connection already registered"
#define ERR_PASSWDMISMATCH_MSG "464 %s :Invalid password"
#define ERR_CHANNELISFULL_MSG "471 %s %s :Cannot join channel (+l)"
#define ERR_SECURECHANNEL_MSG "471 %s %s :Cannot join channel (+z)"
#define ERR_UNKNOWNMODE_MSG "472 %s: %c :is unknown mode char for %s"
#define ERR_INVITEONLYCHAN_MSG "473 %s %s :Cannot join channel (+i)"
#define ERR_BANNEDFROMCHAN_MSG "474 %s %s :Cannot join channel (+b)"

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de).
* Copyright (c)2001-2010 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
@@ -29,7 +29,6 @@
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
@@ -39,15 +38,15 @@
#endif
#include "defines.h"
#include "resolve.h"
#include "conn.h"
#include "conf-ssl.h"
#include "client.h"
#include "channel.h"
#include "conf.h"
#include "lists.h"
#include "log.h"
#include "parse.h"
#include "sighandlers.h"
#include "io.h"
#include "irc.h"
#ifdef ZEROCONF
@@ -58,9 +57,6 @@
#include "ngircd.h"
static void Initialize_Signal_Handler PARAMS(( void ));
static void Signal_Handler PARAMS(( int Signal ));
static void Show_Version PARAMS(( void ));
static void Show_Help PARAMS(( void ));
@@ -69,10 +65,11 @@ static void Pidfile_Delete PARAMS(( void ));
static void Fill_Version PARAMS(( void ));
static void Setup_FDStreams PARAMS(( void ));
static void Setup_FDStreams PARAMS(( int fd ));
static bool NGIRCd_Init PARAMS(( bool ));
/**
* The main() function of ngIRCd.
* Here all starts: this function is called by the operating system loader,
@@ -97,7 +94,7 @@ main( int argc, const char *argv[] )
umask( 0077 );
NGIRCd_SignalQuit = NGIRCd_SignalRestart = NGIRCd_SignalRehash = false;
NGIRCd_SignalQuit = NGIRCd_SignalRestart = false;
NGIRCd_Passive = false;
#ifdef DEBUG
NGIRCd_Debug = false;
@@ -110,14 +107,13 @@ main( int argc, const char *argv[] )
Fill_Version( );
/* Kommandozeile parsen */
/* parse conmmand line */
for( i = 1; i < argc; i++ )
{
ok = false;
if(( argv[i][0] == '-' ) && ( argv[i][1] == '-' ))
{
/* Lange Option */
/* long option */
if( strcmp( argv[i], "--config" ) == 0 )
{
if( i + 1 < argc )
@@ -172,7 +168,7 @@ main( int argc, const char *argv[] )
}
else if(( argv[i][0] == '-' ) && ( argv[i][1] != '-' ))
{
/* Kurze Option */
/* short option */
for( n = 1; n < strlen( argv[i] ); n++ )
{
ok = false;
@@ -241,7 +237,7 @@ main( int argc, const char *argv[] )
}
}
/* Debug-Level (fuer IRC-Befehl "VERSION") ermitteln */
/* Debug-Level (for IRCs "VERSION" command) */
NGIRCd_DebugLevel[0] = '\0';
#ifdef DEBUG
if( NGIRCd_Debug ) strcpy( NGIRCd_DebugLevel, "1" );
@@ -254,7 +250,6 @@ main( int argc, const char *argv[] )
}
#endif
/* Soll nur die Konfigurations ueberprueft und ausgegeben werden? */
if( configtest )
{
Show_Version( ); puts( "" );
@@ -267,7 +262,6 @@ main( int argc, const char *argv[] )
NGIRCd_Start = time( NULL );
(void)strftime( NGIRCd_StartStr, 64, "%a %b %d %Y at %H:%M:%S (%Z)", localtime( &NGIRCd_Start ));
NGIRCd_SignalRehash = false;
NGIRCd_SignalRestart = false;
NGIRCd_SignalQuit = false;
@@ -296,13 +290,21 @@ main( int argc, const char *argv[] )
* when not running in "no daemon" mode: */
if( ! NGIRCd_NoDaemon ) Log_InitErrorfile( );
#endif
if (!io_library_init(CONNECTION_POOL)) {
Log(LOG_ALERT, "Fatal: Cannot initialize IO routines: %s", strerror(errno));
exit(1);
}
/* Signal-Handler initialisieren */
Initialize_Signal_Handler( );
if (!Signals_Init()) {
Log(LOG_ALERT, "Fatal: Could not set up signal handlers: %s", strerror(errno));
exit(1);
}
/* Protokoll- und Server-Identifikation erzeugen. Die vom ngIRCd
* beim PASS-Befehl verwendete Syntax sowie die erweiterten Flags
* sind in doc/Protocol.txt beschrieben. */
/*
* create protocol and server identification.
* The syntax used by ngIRCd in PASS commands and the extended flags
* are described in doc/Protocol.txt
*/
#ifdef IRCPLUS
snprintf( NGIRCd_ProtoID, sizeof NGIRCd_ProtoID, "%s%s %s|%s:%s", PROTOVER, PROTOIRCPLUS, PACKAGE_NAME, PACKAGE_VERSION, IRCPLUSFLAGS );
#ifdef ZLIB
@@ -316,12 +318,10 @@ main( int argc, const char *argv[] )
#ifdef ZLIB
strlcat( NGIRCd_ProtoID, "Z", sizeof NGIRCd_ProtoID );
#endif
Log( LOG_DEBUG, "Protocol and server ID is \"%s\".", NGIRCd_ProtoID );
LogDebug("Protocol and server ID is \"%s\".", NGIRCd_ProtoID);
/* Vordefinierte Channels anlegen */
Channel_InitPredefined( );
/* Listen-Ports initialisieren */
if( Conn_InitListeners( ) < 1 )
{
Log( LOG_ALERT, "Server isn't listening on a single port!" );
@@ -365,7 +365,6 @@ Fill_Version( void )
#ifdef ZLIB
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "ZLIB", sizeof NGIRCd_VersionAddition );
#endif
#ifdef SSL_SUPPORT
@@ -375,49 +374,46 @@ Fill_Version( void )
#ifdef TCPWRAP
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "TCPWRAP", sizeof NGIRCd_VersionAddition );
#endif
#ifdef ZEROCONF
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "ZEROCONF", sizeof NGIRCd_VersionAddition );
#endif
#ifdef IDENTAUTH
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "IDENT", sizeof NGIRCd_VersionAddition );
#endif
#ifdef PAM
if (NGIRCd_VersionAddition[0])
strlcat(NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition);
strlcat(NGIRCd_VersionAddition, "PAM", sizeof NGIRCd_VersionAddition);
#endif
#ifdef DEBUG
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "DEBUG", sizeof NGIRCd_VersionAddition );
#endif
#ifdef SNIFFER
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "SNIFFER", sizeof NGIRCd_VersionAddition );
#endif
#ifdef STRICT_RFC
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "RFC", sizeof NGIRCd_VersionAddition );
#endif
#ifdef IRCPLUS
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "IRCPLUS", sizeof NGIRCd_VersionAddition );
#endif
#ifdef WANT_IPV6
if (NGIRCd_VersionAddition[0])
strlcat(NGIRCd_VersionAddition, "+", sizeof(NGIRCd_VersionAddition));
strlcat(NGIRCd_VersionAddition, "IPv6", sizeof(NGIRCd_VersionAddition));
#endif
if( NGIRCd_VersionAddition[0] )
@@ -434,140 +430,6 @@ Fill_Version( void )
} /* Fill_Version */
/**
* Reload the server configuration file.
*/
GLOBAL void
NGIRCd_Rehash( void )
{
char old_name[CLIENT_ID_LEN];
unsigned old_nicklen;
Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" );
NGIRCd_SignalRehash = false;
/* Remember old server name and nick name length */
strlcpy( old_name, Conf_ServerName, sizeof old_name );
old_nicklen = Conf_MaxNickLength;
/* Re-read configuration ... */
if (!Conf_Rehash( ))
return;
/* Close down all listening sockets */
Conn_ExitListeners( );
/* Recover old server name and nick name length: these values can't
* be changed during run-time */
if (strcmp(old_name, Conf_ServerName) != 0 ) {
strlcpy(Conf_ServerName, old_name, sizeof Conf_ServerName);
Log(LOG_ERR, "Can't change \"ServerName\" on runtime! Ignored new name.");
}
if (old_nicklen != Conf_MaxNickLength) {
Conf_MaxNickLength = old_nicklen;
Log(LOG_ERR, "Can't change \"MaxNickLength\" on runtime! Ignored new value.");
}
/* Create new pre-defined channels */
Channel_InitPredefined( );
if (!ConnSSL_InitLibrary())
Log(LOG_WARNING, "Re-Initializing SSL failed, using old keys");
/* Start listening on sockets */
Conn_InitListeners( );
/* Sync configuration with established connections */
Conn_SyncServerStruct( );
Log( LOG_NOTICE|LOG_snotice, "Re-reading of configuration done." );
} /* NGIRCd_Rehash */
/**
* Initialize the signal handler.
*/
static void
Initialize_Signal_Handler( void )
{
/* Signal-Handler initialisieren: einige Signale
* werden ignoriert, andere speziell behandelt. */
#ifdef HAVE_SIGACTION
/* sigaction() ist vorhanden */
struct sigaction saction;
/* Signal-Struktur initialisieren */
memset( &saction, 0, sizeof( saction ));
saction.sa_handler = Signal_Handler;
#ifdef SA_RESTART
saction.sa_flags |= SA_RESTART;
#endif
#ifdef SA_NOCLDWAIT
saction.sa_flags |= SA_NOCLDWAIT;
#endif
/* Signal-Handler einhaengen */
sigaction(SIGINT, &saction, NULL);
sigaction(SIGQUIT, &saction, NULL);
sigaction(SIGTERM, &saction, NULL);
sigaction(SIGHUP, &saction, NULL);
sigaction(SIGCHLD, &saction, NULL);
/* einige Signale ignorieren */
saction.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &saction, NULL);
#else
/* kein sigaction() vorhanden */
/* Signal-Handler einhaengen */
signal(SIGINT, Signal_Handler);
signal(SIGQUIT, Signal_Handler);
signal(SIGTERM, Signal_Handler);
signal(SIGHUP, Signal_Handler);
signal(SIGCHLD, Signal_Handler);
/* einige Signale ignorieren */
signal(SIGPIPE, SIG_IGN);
#endif
} /* Initialize_Signal_Handler */
/**
* Signal handler of ngIRCd.
* This function is called whenever ngIRCd catches a signal sent by the
* user and/or the system to it. For example SIGTERM and SIGHUP.
* @param Signal Number of the signal to handle.
*/
static void
Signal_Handler( int Signal )
{
switch( Signal )
{
case SIGTERM:
case SIGINT:
case SIGQUIT:
/* wir soll(t)en uns wohl beenden ... */
NGIRCd_SignalQuit = true;
break;
case SIGHUP:
/* Konfiguration neu einlesen: */
NGIRCd_SignalRehash = true;
break;
case SIGCHLD:
/* Child-Prozess wurde beendet. Zombies vermeiden: */
while( waitpid( -1, NULL, WNOHANG ) > 0);
break;
#ifdef DEBUG
default:
/* unbekanntes bzw. unbehandeltes Signal */
Log( LOG_DEBUG, "Got signal %d! Ignored.", Signal );
#endif
}
} /* Signal_Handler */
/**
* Display copyright and version information of ngIRCd on the console.
*/
@@ -575,7 +437,7 @@ static void
Show_Version( void )
{
puts( NGIRCd_Version );
puts( "Copyright (c)2001-2008 Alexander Barton (<alex@barton.de>) and Contributors." );
puts( "Copyright (c)2001-2010 Alexander Barton (<alex@barton.de>) and Contributors." );
puts( "Homepage: <http://ngircd.barton.de/>\n" );
puts( "This is free software; see the source for copying conditions. There is NO" );
puts( "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." );
@@ -665,27 +527,16 @@ Pidfile_Create(pid_t pid)
* Redirect stdin, stdout and stderr to apropriate file handles.
*/
static void
Setup_FDStreams( void )
Setup_FDStreams(int fd)
{
int fd;
/* Test if we can open /dev/null for reading and writing. If not
* we are most probably chrooted already and the server has been
* restarted. So we simply don't try to redirect stdXXX ... */
fd = open( "/dev/null", O_RDWR );
if ( fd < 0 ) {
Log(LOG_WARNING, "Could not open /dev/null: %s", strerror(errno));
if (fd < 0)
return;
}
fflush(stdout);
fflush(stderr);
/* Create new stdin(0), stdout(1) and stderr(2) descriptors */
dup2( fd, 0 ); dup2( fd, 1 ); dup2( fd, 2 );
/* Close newly opened file descriptor if not stdin/out/err */
if( fd > 2 ) close( fd );
} /* Setup_FDStreams */
@@ -728,12 +579,19 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
bool chrooted = false;
struct passwd *pwd;
struct group *grp;
int real_errno;
int real_errno, fd = -1;
pid_t pid;
if (initialized)
return true;
if (!NGIRCd_NoDaemon) {
/* open /dev/null before chroot() */
fd = open( "/dev/null", O_RDWR);
if (fd < 0)
Log(LOG_WARNING, "Could not open /dev/null: %s", strerror(errno));
}
if (!ConnSSL_InitLibrary())
Log(LOG_WARNING,
"Warning: Error during SSL initialization, continuing ...");
@@ -741,15 +599,14 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
if( Conf_Chroot[0] ) {
if( chdir( Conf_Chroot ) != 0 ) {
Log( LOG_ERR, "Can't chdir() in ChrootDir (%s): %s", Conf_Chroot, strerror( errno ));
return false;
goto out;
}
if( chroot( Conf_Chroot ) != 0 ) {
if (errno != EPERM) {
Log( LOG_ERR, "Can't change root directory to \"%s\": %s",
Conf_Chroot, strerror( errno ));
return false;
goto out;
}
} else {
chrooted = true;
@@ -763,7 +620,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
if (! NGIRCd_getNobodyID(&Conf_UID, &Conf_GID)) {
Log(LOG_WARNING, "Could not get user/group ID of user \"nobody\": %s",
errno ? strerror(errno) : "not found" );
return false;
goto out;
}
}
@@ -773,7 +630,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
real_errno = errno;
Log( LOG_ERR, "Can't change group ID to %u: %s", Conf_GID, strerror( errno ));
if (real_errno != EPERM)
return false;
goto out;
}
}
@@ -783,7 +640,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
real_errno = errno;
Log(LOG_ERR, "Can't change user ID to %u: %s", Conf_UID, strerror(errno));
if (real_errno != EPERM)
return false;
goto out;
}
}
@@ -811,10 +668,16 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
#else
setpgrp(0, getpid());
#endif
chdir( "/" );
if (chdir( "/" ) != 0)
Log(LOG_ERR, "Can't change directory to '/': %s",
strerror(errno));
/* Detach stdin, stdout and stderr */
Setup_FDStreams( );
Setup_FDStreams(fd);
if (fd > 2) {
close(fd);
fd = -1;
}
}
pid = getpid();
@@ -828,9 +691,9 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
pwd = getpwuid( Conf_UID );
grp = getgrgid( Conf_GID );
Log( LOG_INFO, "Running as user %s(%ld), group %s(%ld), with PID %ld.",
pwd ? pwd->pw_name : "unknown", Conf_UID,
grp ? grp->gr_name : "unknown", Conf_GID, pid);
Log(LOG_INFO, "Running as user %s(%ld), group %s(%ld), with PID %ld.",
pwd ? pwd->pw_name : "unknown", (long)Conf_UID,
grp ? grp->gr_name : "unknown", (long)Conf_GID, (long)pid);
if (chrooted) {
Log(LOG_INFO, "Running with root directory \"%s\".",
@@ -841,8 +704,8 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
/* Change working directory to home directory of the user
* we are running as (only when running in daemon mode and not in chroot) */
if ( pwd ) {
if (pwd) {
if (!NGIRCd_NoDaemon ) {
if( chdir( pwd->pw_dir ) == 0 )
Log( LOG_DEBUG, "Changed working directory to \"%s\" ...", pwd->pw_dir );
@@ -854,7 +717,12 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
Log( LOG_ERR, "Can't get user informaton for UID %d!?", Conf_UID );
}
return true;
return true;
out:
if (fd > 2)
close(fd);
return false;
}
/* -eof- */

View File

@@ -21,6 +21,8 @@
#include "defines.h"
#define C_ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
GLOBAL time_t NGIRCd_Start; /* Startzeitpunkt des Daemon */
GLOBAL char NGIRCd_StartStr[64];
@@ -39,7 +41,6 @@ GLOBAL bool NGIRCd_Passive; /* nicht zu anderen Servern connecten */
GLOBAL bool NGIRCd_SignalQuit; /* true: quit server*/
GLOBAL bool NGIRCd_SignalRestart; /* true: restart server */
GLOBAL bool NGIRCd_SignalRehash; /* true: reload configuration */
GLOBAL char NGIRCd_DebugLevel[2]; /* Debug-Level fuer IRC_VERSION() */
@@ -48,9 +49,6 @@ GLOBAL char NGIRCd_ConfFile[FNAME_LEN]; /* Konfigurationsdatei */
GLOBAL char NGIRCd_ProtoID[COMMAND_LEN];/* Protokoll- und Server-Identifikation */
GLOBAL void NGIRCd_Rehash PARAMS(( void ));
#endif

View File

@@ -20,12 +20,10 @@
#include <string.h>
#include "defines.h"
#include "resolve.h"
#include "conn.h"
#include "conf.h"
#include "conn.h"
#include "conn-func.h"
#include "client.h"
#include "channel.h"
#include "irc-write.h"
#include "lists.h"
@@ -131,7 +129,7 @@ Announce_Server(CLIENT * Client, CLIENT * Server)
if (Client_Hops(Server) == 1)
c = Client_ThisServer();
else
c = Client_Introducer(Server);
c = Client_TopServer(Server);
/* Inform new server about the one already registered in the network */
return IRC_WriteStrClientPrefix(Client, c, "SERVER %s %d %d :%s",

81
src/ngircd/op.c Normal file
View File

@@ -0,0 +1,81 @@
/*
* 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.
*
* IRC operator functions
*/
#include "portab.h"
#include "imp.h"
#include <assert.h>
#include <string.h>
#include "conn.h"
#include "channel.h"
#include "conf.h"
#include "log.h"
#include "parse.h"
#include "messages.h"
#include "irc-write.h"
#include <exp.h>
#include "op.h"
/**
* Return and log a "no privileges" message.
*/
GLOBAL bool
Op_NoPrivileges(CLIENT * Client, REQUEST * Req)
{
CLIENT *from = NULL;
if (Req->prefix)
from = Client_Search(Req->prefix);
if (from) {
Log(LOG_NOTICE, "No privileges: client \"%s\" (%s), command \"%s\"",
Req->prefix, Client_Mask(Client), Req->command);
return IRC_WriteStrClient(from, ERR_NOPRIVILEGES_MSG,
Client_ID(from));
} else {
Log(LOG_NOTICE, "No privileges: client \"%s\", command \"%s\"",
Client_Mask(Client), Req->command);
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
Client_ID(Client));
}
} /* Op_NoPrivileges */
/**
* Check that the client is an IRC operator allowed to administer this server.
*/
GLOBAL bool
Op_Check(CLIENT * Client, REQUEST * Req)
{
CLIENT *c;
assert(Client != NULL);
assert(Req != NULL);
if (Client_Type(Client) == CLIENT_SERVER && Req->prefix)
c = Client_Search(Req->prefix);
else
c = Client;
if (!c)
return false;
if (!Client_HasMode(c, 'o'))
return false;
if (!Client_OperByMe(c) && !Conf_AllowRemoteOper)
return false;
/* The client is an local IRC operator, or this server is configured
* to trust remote operators. */
return true;
} /* Op_Check */

22
src/ngircd/op.h Normal file
View File

@@ -0,0 +1,22 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2009 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.
*
* Operator management (header)
*/
#ifndef __oper_h__
#define __oper_h__
GLOBAL bool Op_NoPrivileges PARAMS((CLIENT * Client, REQUEST * Req));
GLOBAL bool Op_Check PARAMS((CLIENT * Client, REQUEST * Req));
#endif
/* -eof- */

139
src/ngircd/pam.c Normal file
View File

@@ -0,0 +1,139 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 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.
*
* PAM User Authentification
*/
#include "portab.h"
#ifdef PAM
#include "imp.h"
#include <assert.h>
#include "defines.h"
#include "log.h"
#include "conn.h"
#include "client.h"
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SECURITY_PAM_APPL_H
#include <security/pam_appl.h>
#endif
#ifdef HAVE_PAM_PAM_APPL_H
#include <pam/pam_appl.h>
#endif
#include "exp.h"
#include "pam.h"
static char *password;
/**
* PAM "conversation function".
* This is a callback function used by the PAM library to get the password.
* Please see the PAM documentation for details :-)
*/
static int
password_conversation(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr) {
LogDebug("PAM: conv(%d, %d, '%s', '%s')",
num_msg, msg[0]->msg_style, msg[0]->msg, appdata_ptr);
/* Can we deal with this request? */
if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF) {
Log(LOG_ERR, "PAM: Unexpected PAM conversation '%d:%s'!",
msg[0]->msg_style, msg[0]->msg);
return PAM_CONV_ERR;
}
if (!appdata_ptr) {
/* Sometimes appdata_ptr gets lost!? */
appdata_ptr = password;
}
/* Duplicate password ("application data") for the PAM library */
*resp = calloc(num_msg, sizeof(struct pam_response));
if (!*resp) {
Log(LOG_ERR, "PAM: Out of memory!");
return PAM_CONV_ERR;
}
(*resp)[0].resp = strdup((char *)appdata_ptr);
(*resp)[0].resp_retcode = 0;
return ((*resp)[0].resp ? PAM_SUCCESS : PAM_CONV_ERR);
}
/**
* PAM "conversation" structure.
*/
static struct pam_conv conv = {
&password_conversation,
NULL
};
/**
* Authenticate a connectiong client using PAM.
* @param Client The client to authenticate.
* @return true when authentication succeeded, false otherwise.
*/
GLOBAL bool
PAM_Authenticate(CLIENT *Client) {
pam_handle_t *pam;
int retval = PAM_SUCCESS;
LogDebug("PAM: Authenticate \"%s\" (%s) ...",
Client_OrigUser(Client), Client_Mask(Client));
/* Set supplied client password */
if (password)
free(password);
password = strdup(Client_Password(Client));
conv.appdata_ptr = password;
/* Initialize PAM */
retval = pam_start("ngircd", Client_OrigUser(Client), &conv, &pam);
if (retval != PAM_SUCCESS) {
Log(LOG_ERR, "PAM: Failed to create authenticator! (%d)", retval);
return false;
}
pam_set_item(pam, PAM_RUSER, Client_User(Client));
pam_set_item(pam, PAM_RHOST, Client_Hostname(Client));
#ifdef HAVE_PAM_FAIL_DELAY
pam_fail_delay(pam, 0);
#endif
/* PAM authentication ... */
retval = pam_authenticate(pam, 0);
/* Success? */
if (retval == PAM_SUCCESS)
Log(LOG_INFO, "PAM: Authenticated \"%s\" (%s).",
Client_OrigUser(Client), Client_Mask(Client));
else
Log(LOG_ERR, "PAM: Error on \"%s\" (%s): %s",
Client_OrigUser(Client), Client_Mask(Client),
pam_strerror(pam, retval));
/* Free PAM structures */
if (pam_end(pam, retval) != PAM_SUCCESS)
Log(LOG_ERR, "PAM: Failed to release authenticator!");
return (retval == PAM_SUCCESS);
}
#endif /* PAM */
/* -eof- */

25
src/ngircd/pam.h Normal file
View File

@@ -0,0 +1,25 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 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.
*
* PAM User Authentification (header)
*/
#ifdef PAM
#ifndef __pam_h__
#define __pam_h__
GLOBAL bool PAM_Authenticate PARAMS((CLIENT *Client));
#endif /* __pam_h__ */
#endif /* PAM */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 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
@@ -26,7 +26,6 @@
#include "ngircd.h"
#include "defines.h"
#include "conn-func.h"
#include "client.h"
#include "channel.h"
#include "log.h"
#include "messages.h"
@@ -59,7 +58,7 @@ static COMMAND My_Commands[] =
{
{ "ADMIN", IRC_ADMIN, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "AWAY", IRC_AWAY, CLIENT_USER, 0, 0, 0 },
{ "CONNECT", IRC_CONNECT, CLIENT_USER, 0, 0, 0 },
{ "CONNECT", IRC_CONNECT, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "DIE", IRC_DIE, CLIENT_USER, 0, 0, 0 },
{ "DISCONNECT", IRC_DISCONNECT, CLIENT_USER, 0, 0, 0 },
{ "ERROR", IRC_ERROR, 0xFFFF, 0, 0, 0 },
@@ -92,7 +91,7 @@ static COMMAND My_Commands[] =
{ "SERVICE", IRC_SERVICE, 0xFFFF, 0, 0, 0 },
{ "SERVLIST", IRC_SERVLIST, CLIENT_USER, 0, 0, 0 },
{ "SQUERY", IRC_SQUERY, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "SQUIT", IRC_SQUIT, CLIENT_SERVER, 0, 0, 0 },
{ "SQUIT", IRC_SQUIT, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "STATS", IRC_STATS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "SUMMON", IRC_SUMMON, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "TIME", IRC_TIME, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
@@ -103,6 +102,7 @@ static COMMAND My_Commands[] =
{ "USERS", IRC_USERS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "VERSION", IRC_VERSION, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "WALLOPS", IRC_WALLOPS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "WEBIRC", IRC_WEBIRC, CLIENT_UNKNOWN, 0, 0, 0 },
{ "WHO", IRC_WHO, CLIENT_USER, 0, 0, 0 },
{ "WHOIS", IRC_WHOIS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "WHOWAS", IRC_WHOWAS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
@@ -120,8 +120,6 @@ static bool Validate_Args PARAMS(( CONN_ID Idx, REQUEST *Req, bool *Closed ));
static bool Handle_Request PARAMS(( CONN_ID Idx, REQUEST *Req ));
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
/**
* Return the pointer to the global "IRC command structure".
* This structure, an array of type "COMMAND" describes all the IRC commands
@@ -169,51 +167,45 @@ Parse_Request( CONN_ID Idx, char *Request )
Init_Request( &req );
/* Fuehrendes und folgendes "Geraffel" verwerfen */
/* remove leading & trailing whitespace */
ngt_TrimStr( Request );
/* gibt es ein Prefix? */
if( Request[0] == ':' )
{
/* Prefix vorhanden */
/* Prefix */
req.prefix = Request + 1;
ptr = strchr( Request, ' ' );
if( ! ptr )
{
Log( LOG_DEBUG, "Connection %d: Parse error: prefix without command!?", Idx );
LogDebug("Connection %d: Parse error: prefix without command!?", Idx);
return Conn_WriteStr( Idx, "ERROR :Prefix without command!?" );
}
*ptr = '\0';
#ifndef STRICT_RFC
/* multiple Leerzeichen als Trenner zwischen
* Prefix und Befehl ignorieren */
/* ignore multiple spaces between prefix and command */
while( *(ptr + 1) == ' ' ) ptr++;
#endif
start = ptr + 1;
}
else start = Request;
/* Befehl */
ptr = strchr( start, ' ' );
if( ptr )
{
*ptr = '\0';
#ifndef STRICT_RFC
/* multiple Leerzeichen als Trenner vor
* Parametern ignorieren */
/* ignore multiple spaces between parameters */
while( *(ptr + 1) == ' ' ) ptr++;
#endif
}
req.command = start;
/* Argumente, Parameter */
/* Arguments, Parameters */
if( ptr )
{
/* Prinzipiell gibt es welche :-) */
start = ptr + 1;
while( start )
{
/* Parameter-String "zerlegen" */
if( start[0] == ':' )
{
req.argv[req.argc] = start + 1;
@@ -227,8 +219,6 @@ Parse_Request( CONN_ID Idx, char *Request )
{
*ptr = '\0';
#ifndef STRICT_RFC
/* multiple Leerzeichen als
* Parametertrenner ignorieren */
while( *(ptr + 1) == ' ' ) ptr++;
#endif
}
@@ -244,7 +234,6 @@ Parse_Request( CONN_ID Idx, char *Request )
}
}
/* Daten validieren */
if( ! Validate_Prefix( Idx, &req, &closed )) return ! closed;
if( ! Validate_Command( Idx, &req, &closed )) return ! closed;
if( ! Validate_Args( Idx, &req, &closed )) return ! closed;
@@ -283,39 +272,32 @@ Validate_Prefix( CONN_ID Idx, REQUEST *Req, bool *Closed )
*Closed = false;
/* ist ueberhaupt ein Prefix vorhanden? */
if( ! Req->prefix ) return true;
/* Client-Struktur der Connection ermitteln */
client = Conn_GetClient( Idx );
assert( client != NULL );
/* nur validieren, wenn bereits registrierte Verbindung */
/* only validate if this connection is already registered */
if(( Client_Type( client ) != CLIENT_USER ) && ( Client_Type( client ) != CLIENT_SERVER ) && ( Client_Type( client ) != CLIENT_SERVICE ))
{
/* noch nicht registrierte Verbindung.
* Das Prefix wird ignoriert. */
/* not registered, ignore prefix */
Req->prefix = NULL;
return true;
}
/* pruefen, ob der im Prefix angegebene Client bekannt ist */
/* check if client in prefix is known */
c = Client_Search( Req->prefix );
if( ! c )
{
/* im Prefix angegebener Client ist nicht bekannt */
Log( LOG_ERR, "Invalid prefix \"%s\", client not known (connection %d, command %s)!?", Req->prefix, Idx, Req->command );
if( ! Conn_WriteStr( Idx, "ERROR :Invalid prefix \"%s\", client not known!?", Req->prefix )) *Closed = true;
return false;
}
/* pruefen, ob der Client mit dem angegebenen Prefix in Richtung
* des Senders liegt, d.h. sicherstellen, dass das Prefix nicht
* gefaelscht ist */
/* check if the client named in the prefix is expected
* to come from that direction */
if( Client_NextHop( c ) != client )
{
/* das angegebene Prefix ist aus dieser Richtung, also
* aus der gegebenen Connection, ungueltig! */
Log( LOG_ERR, "Spoofed prefix \"%s\" from \"%s\" (connection %d, command %s)!", Req->prefix, Client_Mask( Conn_GetClient( Idx )), Idx, Req->command );
Conn_Close( Idx, NULL, "Spoofed prefix", true);
*Closed = true;
@@ -413,7 +395,7 @@ Handle_Numeric(CLIENT *client, REQUEST *Req)
/* This server is the target of the numeric */
num = atoi(Req->command);
for (i = 0; i < (int) ARRAY_SIZE(Numerics); i++) {
for (i = 0; i < (int) C_ARRAY_SIZE(Numerics); i++) {
if (num == Numerics[i].numeric) {
if (!Numerics[i].function)
return CONNECTED;
@@ -456,8 +438,6 @@ Handle_Numeric(CLIENT *client, REQUEST *Req)
static bool
Handle_Request( CONN_ID Idx, REQUEST *Req )
{
/* Client-Request verarbeiten. Bei einem schwerwiegenden Fehler
* wird die Verbindung geschlossen und false geliefert. */
CLIENT *client;
bool result = true;
int client_type;
@@ -479,7 +459,6 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
cmd = My_Commands;
while (cmd->name) {
/* Befehl suchen */
if (strcasecmp(Req->command, cmd->name) != 0) {
cmd++;
continue;

View File

@@ -30,7 +30,7 @@ typedef struct _REQUEST /* vgl. RFC 2812, 2.3 */
typedef struct _COMMAND
{
char *name; /* command name */
const char *name; /* command name */
bool (*function) PARAMS(( CLIENT *Client, REQUEST *Request ));
CLIENT_TYPE type; /* valid client types (bit mask) */
long lcount, rcount; /* number of local and remote calls */

145
src/ngircd/proc.c Normal file
View File

@@ -0,0 +1,145 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 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.
*
* Process management
*/
#include "portab.h"
#include "imp.h"
#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "log.h"
#include "io.h"
#include "conn.h"
#include "exp.h"
#include "sighandlers.h"
#include "proc.h"
/**
* Initialize process structure.
*/
GLOBAL void
Proc_InitStruct (PROC_STAT *proc)
{
assert(proc != NULL);
proc->pid = 0;
proc->pipe_fd = -1;
}
/**
* Fork a child process.
*/
GLOBAL pid_t
Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout)
{
pid_t pid;
assert(proc != NULL);
assert(pipefds != NULL);
assert(cbfunc != NULL);
if (pipe(pipefds) != 0) {
Log(LOG_ALERT, "Can't create output pipe for child process: %s!",
strerror(errno));
return -1;
}
pid = fork();
switch (pid) {
case -1:
/* Error on fork: */
Log(LOG_CRIT, "Can't fork child process: %s!", strerror(errno));
close(pipefds[0]);
close(pipefds[1]);
return -1;
case 0:
/* New child process: */
Signals_Exit();
signal(SIGTERM, Proc_GenericSignalHandler);
signal(SIGALRM, Proc_GenericSignalHandler);
close(pipefds[0]);
alarm(timeout);
Conn_CloseAllSockets();
return 0;
}
/* Old parent process: */
close(pipefds[1]);
if (!io_setnonblock(pipefds[0])
|| !io_event_create(pipefds[0], IO_WANTREAD, cbfunc)) {
Log(LOG_CRIT, "Can't register callback for child process: %s!",
strerror(errno));
close(pipefds[0]);
return -1;
}
proc->pid = pid;
proc->pipe_fd = pipefds[0];
return pid;
}
/**
* Generic signal handler for forked child processes.
*/
GLOBAL void
Proc_GenericSignalHandler(int Signal)
{
switch(Signal) {
case SIGTERM:
#ifdef DEBUG
Log_Subprocess(LOG_DEBUG, "Child got TERM signal, exiting.");
#endif
exit(1);
case SIGALRM:
#ifdef DEBUG
Log_Subprocess(LOG_DEBUG, "Child got ALARM signal, exiting.");
#endif
exit(1);
}
}
/**
* Read bytes from a pipe of a forked child process.
* In addition, this function makes sure that the child process is ignored
* after all data has been read or a fatal error occurred.
*/
GLOBAL size_t
Proc_Read(PROC_STAT *proc, void *buffer, size_t buflen)
{
ssize_t bytes_read = 0;
assert(buffer != NULL);
assert(buflen > 0);
bytes_read = read(proc->pipe_fd, buffer, buflen);
if (bytes_read < 0) {
if (errno == EAGAIN)
return 0;
Log(LOG_CRIT, "Can't read from child process %ld: %s",
proc->pid, strerror(errno));
bytes_read = 0;
}
#if DEBUG
else if (bytes_read == 0)
LogDebug("Can't read from child process %ld: EOF", proc->pid);
#endif
Proc_InitStruct(proc);
return (size_t)bytes_read;
}
/* -eof- */

37
src/ngircd/proc.h Normal file
View File

@@ -0,0 +1,37 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 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.
*
* Process management (header)
*/
#ifndef __proc_h__
#define __proc_h__
/* This struct must not be accessed directly! */
typedef struct _Proc_Stat {
pid_t pid; /* PID of the child process or 0 if none */
int pipe_fd; /* Pipe file descriptor or -1 if none */
} PROC_STAT;
#define Proc_InProgress(x) ((x)->pid != 0)
#define Proc_GetPipeFd(x) ((x)->pipe_fd)
GLOBAL void Proc_InitStruct PARAMS((PROC_STAT *proc));
GLOBAL pid_t Proc_Fork PARAMS((PROC_STAT *proc, int *pipefds,
void (*cbfunc)(int, short), int timeout));
GLOBAL void Proc_GenericSignalHandler PARAMS((int Signal));
GLOBAL size_t Proc_Read PARAMS((PROC_STAT *proc, void *buffer, size_t buflen));
#endif
/* -eof- */

View File

@@ -144,12 +144,16 @@ GLOBAL void Rendezvous_Exit( void )
} /* Rendezvous_Exit */
/**
* Register ZeroConf service
*/
GLOBAL bool Rendezvous_Register( char *Name, char *Type, UINT16 Port )
{
/* Register new service */
int i;
if (Conf_NoZeroConf)
return;
/* Search free port structure */
for( i = 0; i < MAX_RENDEZVOUS; i++ ) if( ! My_Rendezvous[i].Desc[0] ) break;
if( i >= MAX_RENDEZVOUS )

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-2009 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
@@ -12,9 +12,9 @@
*/
#include "portab.h"
#define RESOLVER_TIMEOUT (Conf_PongTimeout*3)/4
static char UNUSED id[] = "$Id: resolve.c,v 1.29 2008/02/26 22:04:17 fw Exp $";
#include "portab.h"
#include "imp.h"
#include <assert.h>
@@ -25,6 +25,7 @@ static char UNUSED id[] = "$Id: resolve.c,v 1.29 2008/02/26 22:04:17 fw Exp $";
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#ifdef IDENTAUTH
#ifdef HAVE_IDENT_H
@@ -32,9 +33,12 @@ static char UNUSED id[] = "$Id: resolve.c,v 1.29 2008/02/26 22:04:17 fw Exp $";
#endif
#endif
#include "array.h"
#include "conn.h"
#include "conf.h"
#include "defines.h"
#include "log.h"
#include "ng_ipaddr.h"
#include "exp.h"
#include "resolve.h"
@@ -43,46 +47,18 @@ static char UNUSED id[] = "$Id: resolve.c,v 1.29 2008/02/26 22:04:17 fw Exp $";
static void Do_ResolveAddr PARAMS(( const ng_ipaddr_t *Addr, int Sock, int w_fd ));
static void Do_ResolveName PARAMS(( const char *Host, int w_fd ));
static bool register_callback PARAMS((RES_STAT *s, void (*cbfunc)(int, short)));
#ifdef WANT_IPV6
extern bool Conf_ConnectIPv4;
extern bool Conf_ConnectIPv6;
#endif
static pid_t
Resolver_fork(int *pipefds)
{
pid_t pid;
if (pipe(pipefds) != 0) {
Log( LOG_ALERT, "Resolver: Can't create output pipe: %s!", strerror( errno ));
return -1;
}
pid = fork();
switch(pid) {
case -1:
Log( LOG_CRIT, "Resolver: Can't fork: %s!", strerror( errno ));
close(pipefds[0]);
close(pipefds[1]);
return -1;
case 0: /* child */
close(pipefds[0]);
Log_Init_Resolver( );
return 0;
}
/* parent */
close(pipefds[1]);
return pid;
}
/**
* Resolve IP (asynchronous!).
*/
GLOBAL bool
Resolve_Addr(RES_STAT * s, const ng_ipaddr_t *Addr, int identsock,
Resolve_Addr(PROC_STAT * s, const ng_ipaddr_t *Addr, int identsock,
void (*cbfunc) (int, short))
{
int pipefd[2];
@@ -90,17 +66,15 @@ Resolve_Addr(RES_STAT * s, const ng_ipaddr_t *Addr, int identsock,
assert(s != NULL);
pid = Resolver_fork(pipefd);
pid = Proc_Fork(s, pipefd, cbfunc, RESOLVER_TIMEOUT);
if (pid > 0) {
Log(LOG_DEBUG, "Resolver for %s created (PID %d).", ng_ipaddr_tostr(Addr), pid);
s->pid = pid;
s->resolver_fd = pipefd[0];
return register_callback(s, cbfunc);
LogDebug("Resolver for %s created (PID %d).", ng_ipaddr_tostr(Addr), pid);
return true;
} else if( pid == 0 ) {
/* Sub process */
Log_Init_Subprocess("Resolver");
Do_ResolveAddr( Addr, identsock, pipefd[1]);
Log_Exit_Resolver( );
Log_Exit_Subprocess("Resolver");
exit(0);
}
return false;
@@ -111,43 +85,33 @@ Resolve_Addr(RES_STAT * s, const ng_ipaddr_t *Addr, int identsock,
* Resolve hostname (asynchronous!).
*/
GLOBAL bool
Resolve_Name( RES_STAT *s, const char *Host, void (*cbfunc)(int, short))
Resolve_Name( PROC_STAT *s, const char *Host, void (*cbfunc)(int, short))
{
int pipefd[2];
pid_t pid;
assert(s != NULL);
pid = Resolver_fork(pipefd);
pid = Proc_Fork(s, pipefd, cbfunc, RESOLVER_TIMEOUT);
if (pid > 0) {
/* Main process */
#ifdef DEBUG
Log( LOG_DEBUG, "Resolver for \"%s\" created (PID %d).", Host, pid );
#endif
s->pid = pid;
s->resolver_fd = pipefd[0];
return register_callback(s, cbfunc);
return true;
} else if( pid == 0 ) {
/* Sub process */
Log_Init_Subprocess("Resolver");
Do_ResolveName(Host, pipefd[1]);
Log_Exit_Resolver( );
Log_Exit_Subprocess("Resolver");
exit(0);
}
return false;
} /* Resolve_Name */
GLOBAL void
Resolve_Init(RES_STAT *s)
{
assert(s != NULL);
s->resolver_fd = -1;
s->pid = 0;
}
#ifndef WANT_IPV6
#ifdef h_errno
#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO)
#if !defined(WANT_IPV6) && defined(h_errno)
static char *
Get_Error( int H_Error )
{
@@ -164,8 +128,8 @@ Get_Error( int H_Error )
}
return "unknown error";
}
#endif /* h_errno */
#endif /* WANT_IPV6 */
#endif
#endif
/* Do "IDENT" (aka "AUTH") lookup and append result to resolved_addr array */
@@ -179,17 +143,20 @@ Do_IdentQuery(int identsock, array *resolved_addr)
return;
#ifdef DEBUG
Log_Resolver(LOG_DEBUG, "Doing IDENT lookup on socket %d ...", identsock);
Log_Subprocess(LOG_DEBUG, "Doing IDENT lookup on socket %d ...",
identsock);
#endif
res = ident_id( identsock, 10 );
#ifdef DEBUG
Log_Resolver(LOG_DEBUG, "Ok, IDENT lookup on socket %d done: \"%s\"",
identsock, res ? res : "(NULL)" );
Log_Subprocess(LOG_DEBUG, "Ok, IDENT lookup on socket %d done: \"%s\"",
identsock, res ? res : "(NULL)");
#endif
if (!res) /* no result */
return;
if (!array_cats(resolved_addr, res))
Log_Resolver(LOG_WARNING, "Resolver: Cannot copy IDENT result: %s!", strerror(errno));
Log_Subprocess(LOG_WARNING,
"Resolver: Cannot copy IDENT result: %s!",
strerror(errno));
free(res);
#else
@@ -205,7 +172,7 @@ Do_IdentQuery(int identsock, array *resolved_addr)
* the IP address in resbuf and returns false.
* @param IpAddr ip address to resolve
* @param resbuf result buffer to store DNS name/string representation of ip address
* @reslen size of result buffer (must be >= NGT_INET_ADDRSTRLEN)
* @param reslen size of result buffer (must be >= NGT_INET_ADDRSTRLEN)
* @return true if reverse lookup successful, false otherwise
*/
static bool
@@ -220,7 +187,7 @@ ReverseLookup(const ng_ipaddr_t *IpAddr, char *resbuf, size_t reslen)
*resbuf = 0;
res = getnameinfo((struct sockaddr *) IpAddr, ng_ipaddr_salen(IpAddr),
resbuf, reslen, NULL, 0, NI_NAMEREQD);
resbuf, (socklen_t)reslen, NULL, 0, NI_NAMEREQD);
if (res == 0)
return true;
@@ -251,7 +218,7 @@ ReverseLookup(const ng_ipaddr_t *IpAddr, char *resbuf, size_t reslen)
assert(reslen >= NG_INET_ADDRSTRLEN);
ng_ipaddr_tostr_r(IpAddr, tmp_ip_str);
Log_Resolver(LOG_WARNING, "%s: Can't resolve address \"%s\": %s",
Log_Subprocess(LOG_WARNING, "%s: Can't resolve address \"%s\": %s",
funcname, tmp_ip_str, errmsg);
strlcpy(resbuf, tmp_ip_str, reslen);
return false;
@@ -293,14 +260,16 @@ ForwardLookup(const char *hostname, array *IpAddr)
if (!Conf_ConnectIPv4)
hints.ai_family = AF_INET6;
#endif
memset(&addr, 0, sizeof(addr));
res = getaddrinfo(hostname, NULL, &hints, &ai_results);
switch (res) {
case 0: break;
case EAI_SYSTEM:
Log_Resolver(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, strerror(errno));
Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, strerror(errno));
return false;
default:
Log_Resolver(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, gai_strerror(res));
Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, gai_strerror(res));
return false;
}
@@ -323,9 +292,10 @@ ForwardLookup(const char *hostname, array *IpAddr)
if (!h) {
#ifdef h_errno
Log_Resolver(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, Get_Error(h_errno));
Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\": %s",
hostname, Get_Error(h_errno));
#else
Log_Resolver(LOG_WARNING, "Can't resolve \"%s\"", hostname);
Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\"", hostname);
#endif
return false;
}
@@ -361,7 +331,7 @@ Addr_in_list(const array *resolved_addr, const ng_ipaddr_t *Addr)
tmpAddrs = array_start(resolved_addr);
while (len > 0) {
Log_Resolver(LOG_WARNING, "Address mismatch: %s != %s",
Log_Subprocess(LOG_WARNING, "Address mismatch: %s != %s",
tmp_ip_str, ng_ipaddr_tostr(tmpAddrs));
tmpAddrs++;
len--;
@@ -374,14 +344,14 @@ Addr_in_list(const array *resolved_addr, const ng_ipaddr_t *Addr)
static void
Log_Forgery_NoIP(const char *ip, const char *host)
{
Log_Resolver(LOG_WARNING, "Possible forgery: %s resolved to %s "
Log_Subprocess(LOG_WARNING, "Possible forgery: %s resolved to %s "
"(which has no ip address)", ip, host);
}
static void
Log_Forgery_WrongIP(const char *ip, const char *host)
{
Log_Resolver(LOG_WARNING,"Possible forgery: %s resolved to %s "
Log_Subprocess(LOG_WARNING,"Possible forgery: %s resolved to %s "
"(which points to different address)", ip, host);
}
@@ -395,7 +365,7 @@ ArrayWrite(int fd, const array *a)
assert(data);
if( (size_t)write(fd, data, len) != len )
Log_Resolver( LOG_CRIT, "Resolver: Can't write to parent: %s!",
Log_Subprocess( LOG_CRIT, "Resolver: Can't write to parent: %s!",
strerror(errno));
}
@@ -413,7 +383,7 @@ Do_ResolveAddr(const ng_ipaddr_t *Addr, int identsock, int w_fd)
array_init(&resolved_addr);
ng_ipaddr_tostr_r(Addr, tmp_ip_str);
#ifdef DEBUG
Log_Resolver(LOG_DEBUG, "Now resolving %s ...", tmp_ip_str);
Log_Subprocess(LOG_DEBUG, "Now resolving %s ...", tmp_ip_str);
#endif
if (!ReverseLookup(Addr, hostname, sizeof(hostname)))
goto dns_done;
@@ -428,13 +398,15 @@ Do_ResolveAddr(const ng_ipaddr_t *Addr, int identsock, int w_fd)
strlcpy(hostname, tmp_ip_str, sizeof(hostname));
}
#ifdef DEBUG
Log_Resolver(LOG_DEBUG, "Ok, translated %s to \"%s\".", tmp_ip_str, hostname);
Log_Subprocess(LOG_DEBUG, "Ok, translated %s to \"%s\".", tmp_ip_str, hostname);
#endif
dns_done:
len = strlen(hostname);
hostname[len] = '\n';
if (!array_copyb(&resolved_addr, hostname, ++len)) {
Log_Resolver(LOG_CRIT, "Resolver: Can't copy resolved name: %s!", strerror(errno));
Log_Subprocess(LOG_CRIT,
"Resolver: Can't copy resolved name: %s!",
strerror(errno));
array_free(&resolved_addr);
return;
}
@@ -457,7 +429,7 @@ Do_ResolveName( const char *Host, int w_fd )
ng_ipaddr_t *addr;
size_t len;
#endif
Log_Resolver(LOG_DEBUG, "Now resolving \"%s\" ...", Host);
Log_Subprocess(LOG_DEBUG, "Now resolving \"%s\" ...", Host);
array_init(&IpAddrs);
/* Resolve hostname */
@@ -471,7 +443,7 @@ Do_ResolveName( const char *Host, int w_fd )
addr = array_start(&IpAddrs);
assert(addr);
for (; len > 0; --len,addr++) {
Log_Resolver(LOG_DEBUG, "translated \"%s\" to %s.",
Log_Subprocess(LOG_DEBUG, "translated \"%s\" to %s.",
Host, ng_ipaddr_tostr(addr));
}
#endif
@@ -482,65 +454,4 @@ Do_ResolveName( const char *Host, int w_fd )
} /* Do_ResolveName */
static bool
register_callback( RES_STAT *s, void (*cbfunc)(int, short))
{
assert(cbfunc != NULL);
assert(s != NULL);
assert(s->resolver_fd >= 0);
if (io_setnonblock(s->resolver_fd) &&
io_event_create(s->resolver_fd, IO_WANTREAD, cbfunc))
return true;
Log( LOG_CRIT, "Resolver: Could not register callback function: %s!", strerror(errno));
close(s->resolver_fd);
Resolve_Init(s);
return false;
}
GLOBAL bool
Resolve_Shutdown( RES_STAT *s)
{
bool ret = false;
assert(s != NULL);
assert(s->resolver_fd >= 0);
if (s->resolver_fd >= 0)
ret = io_close(s->resolver_fd);
Resolve_Init(s);
return ret;
}
/**
* Read result of resolver sub-process from pipe
*/
GLOBAL size_t
Resolve_Read( RES_STAT *s, void* readbuf, size_t buflen)
{
ssize_t bytes_read;
assert(buflen > 0);
/* Read result from pipe */
bytes_read = read(s->resolver_fd, readbuf, buflen);
if (bytes_read < 0) {
if (errno == EAGAIN)
return 0;
Log( LOG_CRIT, "Resolver: Can't read result: %s!", strerror(errno));
bytes_read = 0;
}
#ifdef DEBUG
else if (bytes_read == 0)
Log( LOG_DEBUG, "Resolver: Can't read result: EOF");
#endif
Resolve_Shutdown(s);
return (size_t)bytes_read;
}
/* -eof- */

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-2010 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,34 +8,17 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: resolve.h,v 1.14 2008/02/26 22:04:17 fw Exp $
*
* Asynchronous resolver (header)
*/
#ifndef __resolve_h__
#define __resolve_h__
#include "array.h"
#include "tool.h"
#include "ng_ipaddr.h"
/* This struct must not be accessed directly */
typedef struct _Res_Stat {
pid_t pid; /* PID of resolver process */
int resolver_fd; /* pipe fd for lookup result. */
} RES_STAT;
#define Resolve_Getfd(x) ((x)->resolver_fd)
#define Resolve_INPROGRESS(x) ((x)->resolver_fd >= 0)
GLOBAL bool Resolve_Addr PARAMS(( RES_STAT *s, const ng_ipaddr_t *Addr, int identsock, void (*cbfunc)(int, short)));
GLOBAL bool Resolve_Name PARAMS(( RES_STAT *s, const char *Host, void (*cbfunc)(int, short) ));
GLOBAL size_t Resolve_Read PARAMS(( RES_STAT *s, void *buf, size_t buflen));
GLOBAL void Resolve_Init PARAMS(( RES_STAT *s));
GLOBAL bool Resolve_Shutdown PARAMS(( RES_STAT *s));
GLOBAL bool Resolve_Addr PARAMS((PROC_STAT * s, const ng_ipaddr_t * Addr,
int identsock, void (*cbfunc) (int, short)));
GLOBAL bool Resolve_Name PARAMS((PROC_STAT * s, const char *Host,
void (*cbfunc) (int, short)));
#endif
/* -eof- */

336
src/ngircd/sighandlers.c Normal file
View File

@@ -0,0 +1,336 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
*
* 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.
*/
#include "portab.h"
/**
* @file
* Signal Handlers: Actions to be performed when the program
* receives a signal.
*/
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "imp.h"
#include "conn.h"
#include "conf-ssl.h"
#include "channel.h"
#include "conf.h"
#include "io.h"
#include "log.h"
#include "ngircd.h"
#include "sighandlers.h"
static int signalpipe[2];
static const int signals_catch[] = {
SIGINT, SIGQUIT, SIGTERM, SIGHUP, SIGCHLD, SIGUSR1, SIGUSR2
};
#ifdef DEBUG
static void
Dump_State(void)
{
Log(LOG_DEBUG, "--- Internal server state: %s ---",
Client_ID(Client_ThisServer()));
Log(LOG_DEBUG, "time()=%ld", time(NULL));
Conf_DebugDump();
Conn_DebugDump();
Client_DebugDump();
Log(LOG_DEBUG, "--- End of state dump ---");
} /* Dump_State */
#endif
static void
Signal_Block(int sig)
{
#ifdef HAVE_SIGPROCMASK
sigset_t set;
sigemptyset(&set);
sigaddset(&set, sig);
sigprocmask(SIG_BLOCK, &set, NULL);
#else
sigblock(sig);
#endif
}
static void
Signal_Unblock(int sig)
{
#ifdef HAVE_SIGPROCMASK
sigset_t set;
sigemptyset(&set);
sigaddset(&set, sig);
sigprocmask(SIG_UNBLOCK, &set, NULL);
#else
int old = sigblock(0) & ~sig;
sigsetmask(old);
#endif
}
/**
* Reload the server configuration file.
*/
static void
Rehash(void)
{
char old_name[CLIENT_ID_LEN];
unsigned old_nicklen;
Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" );
/* Remember old server name and nick name length */
strlcpy( old_name, Conf_ServerName, sizeof old_name );
old_nicklen = Conf_MaxNickLength;
/* Re-read configuration ... */
if (!Conf_Rehash( ))
return;
/* Close down all listening sockets */
Conn_ExitListeners( );
/* Recover old server name and nick name length: these values can't
* be changed during run-time */
if (strcmp(old_name, Conf_ServerName) != 0 ) {
strlcpy(Conf_ServerName, old_name, sizeof Conf_ServerName);
Log(LOG_ERR, "Can't change \"ServerName\" on runtime! Ignored new name.");
}
if (old_nicklen != Conf_MaxNickLength) {
Conf_MaxNickLength = old_nicklen;
Log(LOG_ERR, "Can't change \"MaxNickLength\" on runtime! Ignored new value.");
}
/* Create new pre-defined channels */
Channel_InitPredefined( );
if (!ConnSSL_InitLibrary())
Log(LOG_WARNING, "Re-Initializing SSL failed, using old keys");
/* Start listening on sockets */
Conn_InitListeners( );
/* Sync configuration with established connections */
Conn_SyncServerStruct( );
Log( LOG_NOTICE|LOG_snotice, "Re-reading of configuration done." );
} /* Rehash */
/**
* Signal handler of ngIRCd.
* This function is called whenever ngIRCd catches a signal sent by the
* user and/or the system to it. For example SIGTERM and SIGHUP.
*
* It blocks the signal and queues it for later execution by Signal_Handler_BH.
* @param Signal Number of the signal to handle.
*/
static void
Signal_Handler(int Signal)
{
switch (Signal) {
case SIGTERM:
case SIGINT:
case SIGQUIT:
/* shut down sever */
NGIRCd_SignalQuit = true;
return;
case SIGCHLD:
/* child-process exited, avoid zombies */
while (waitpid( -1, NULL, WNOHANG) > 0)
;
return;
#ifdef DEBUG
case SIGUSR1:
if (! NGIRCd_Debug) {
Log(LOG_INFO|LOG_snotice,
"Got SIGUSR1, debug mode activated.");
#ifdef SNIFFER
strcpy(NGIRCd_DebugLevel, "2");
NGIRCd_Debug = true;
NGIRCd_Sniffer = true;
#else
strcpy(NGIRCd_DebugLevel, "1");
NGIRCd_Debug = true;
#endif /* SNIFFER */
} else {
Log(LOG_INFO|LOG_snotice,
"Got SIGUSR1, debug mode deactivated.");
strcpy(NGIRCd_DebugLevel, "");
NGIRCd_Debug = false;
#ifdef SNIFFER
NGIRCd_Sniffer = false;
#endif /* SNIFFER */
}
return;
#endif
}
/*
* other signal: queue for later execution.
* This has the advantage that we are not restricted
* to functions that can be called safely from signal handlers.
*/
if (write(signalpipe[1], &Signal, sizeof(Signal)) != -1)
Signal_Block(Signal);
} /* Signal_Handler */
/**
* Signal processing handler of ngIRCd.
* This function is called from the main conn event loop in (io_dispatch)
* whenever ngIRCd has queued a signal.
*
* This function runs in normal context, not from the real signal handler,
* thus its not necessary to only use functions that are signal safe.
* @param Signal Number of the signal that was queued.
*/
static void
Signal_Handler_BH(int Signal)
{
switch (Signal) {
case SIGHUP:
/* re-read configuration */
Rehash();
break;
#ifdef DEBUG
case SIGUSR2:
if (NGIRCd_Debug)
Dump_State();
break;
default:
Log(LOG_DEBUG, "Got signal %d! Ignored.", Signal);
#endif
}
Signal_Unblock(Signal);
}
static void
Signal_Callback(int fd, short UNUSED what)
{
int sig, ret;
(void) what;
do {
ret = (int)read(fd, &sig, sizeof(sig));
if (ret == sizeof(int))
Signal_Handler_BH(sig);
} while (ret == sizeof(int));
if (ret == -1) {
if (errno == EAGAIN || errno == EINTR)
return;
Log(LOG_EMERG, "read from signal pipe: %s", strerror(errno));
exit(1);
}
Log(LOG_EMERG, "EOF on signal pipe");
exit(1);
}
/**
* Initialize the signal handlers, catch
* those signals we are interested in and sets SIGPIPE to be ignored.
* @return true if initialization was sucessful.
*/
bool
Signals_Init(void)
{
size_t i;
#ifdef HAVE_SIGACTION
struct sigaction saction;
#endif
if (signalpipe[0] > 0 || signalpipe[1] > 0)
return true;
if (pipe(signalpipe))
return false;
if (!io_setnonblock(signalpipe[0]) ||
!io_setnonblock(signalpipe[1]))
return false;
if (!io_setcloexec(signalpipe[0]) ||
!io_setcloexec(signalpipe[1]))
return false;
#ifdef HAVE_SIGACTION
memset( &saction, 0, sizeof( saction ));
saction.sa_handler = Signal_Handler;
#ifdef SA_RESTART
saction.sa_flags |= SA_RESTART;
#endif
#ifdef SA_NOCLDWAIT
saction.sa_flags |= SA_NOCLDWAIT;
#endif
for (i=0; i < C_ARRAY_SIZE(signals_catch) ; i++)
sigaction(signals_catch[i], &saction, NULL);
/* we handle write errors properly; ignore SIGPIPE */
saction.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &saction, NULL);
#else
for (i=0; i < C_ARRAY_SIZE(signals_catch) ; i++)
signal(signals_catch[i], Signal_Handler);
signal(SIGPIPE, SIG_IGN);
#endif
return io_event_create(signalpipe[0], IO_WANTREAD, Signal_Callback);
} /* Signals_Init */
/**
* Restores signals to their default behaviour.
*
* This should be called after a fork() in the new
* child prodcess, especially when we are about to call
* 3rd party code (e.g. PAM).
*/
void
Signals_Exit(void)
{
size_t i;
#ifdef HAVE_SIGACTION
struct sigaction saction;
memset(&saction, 0, sizeof(saction));
saction.sa_handler = SIG_DFL;
for (i=0; i < C_ARRAY_SIZE(signals_catch) ; i++)
sigaction(signals_catch[i], &saction, NULL);
sigaction(SIGPIPE, &saction, NULL);
#else
for (i=0; i < C_ARRAY_SIZE(signals_catch) ; i++)
signal(signals_catch[i], SIG_DFL);
signal(SIGPIPE, SIG_DFL);
#endif
close(signalpipe[1]);
close(signalpipe[0]);
}
/* -eof- */

19
src/ngircd/sighandlers.h Normal file
View File

@@ -0,0 +1,19 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
*
* 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.
*/
#ifndef signals_included_
#define signals_included_
#include "portab.h"
bool Signals_Init PARAMS((void));
void Signals_Exit PARAMS((void));
#endif

View File

@@ -7,12 +7,14 @@
# detect flags for "ps" and "head"
UNAME=`uname`
if [ $UNAME = "FreeBSD" -o $UNAME = "SunOS" ]; then
if [ $UNAME = "FreeBSD" ]; then
PS_FLAGS="-a"; PS_PIDCOL="1"; HEAD_FLAGS="-n 1"
elif [ $UNAME = "A/UX" ]; then
PS_FLAGS="-ae"; PS_PIDCOL="1"; HEAD_FLAGS="-1"
elif [ $UNAME = "GNU" ]; then
PS_FLAGS="-ax"; PS_PIDCOL="2"; HEAD_FLAGS="-n 1"
elif [ $UNAME = "SunOS" ]; then
PS_FLAGS="-af"; PS_PIDCOL=2; HEAD_FLAGS="-n 1"
else
PS_FLAGS="-f"; PS_PIDCOL="2"; HEAD_FLAGS="-n 1"
ps $PS_FLAGS > /dev/null 2>&1

View File

@@ -11,6 +11,7 @@
OperCanUseMode = yes
MaxJoins = 4
NoIdent = yes
NoPAM = yes
[Operator]
Name = TestOp
@@ -22,7 +23,8 @@
PeerPassword = pwd2
[Channel]
Name = #InviteChannel
# This name should be accepted as '#InviteChannel' by ngircd.
Name = InviteChannel
Modes = i
[Channel]
@@ -35,10 +37,17 @@
Name = #TopicChannel
Modes = t
Topic = the topic
[Channel]
Name = #SecretChannel
Modes = s
Topic = A secret Channel
[Channel]
Name = &LocalChannel
Topic = A local Channel
[Channel]
Name = +ModelessChannel
Topic = A modeless Channel
# -eof-

View File

@@ -11,6 +11,7 @@
OperCanUseMode = yes
MaxJoins = 4
NoIdent = yes
NoPAM = yes
[Operator]
Name = TestOp

View File

@@ -45,6 +45,6 @@ pid=`./getpid.sh T-ngircd${id}`
[ -n "$pid" ] && kill -0 $pid > /dev/null 2>&1; r=$?
[ $r -eq 0 ] && echo " ok." || echo " failure!"
exit
exit $r
# -eof-

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 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,6 +22,11 @@
#include <netinet/in.h>
#ifdef SYSLOG
#define SYSLOG_NAMES 1
#include <syslog.h>
#endif
#include "exp.h"
#include "tool.h"
@@ -107,16 +112,107 @@ ngt_TrimLastChr( char *String, const char Chr)
/* If last character in the string matches Chr, remove it.
* Empty strings are handled correctly. */
unsigned int len;
size_t len;
assert( String != NULL );
assert(String != NULL);
len = strlen( String );
if( len == 0 ) return;
len = strlen(String);
if(len == 0)
return;
len--;
if( String[len] == Chr ) String[len] = '\0';
if(String[len] == Chr)
String[len] = '\0';
} /* ngt_TrimLastChr */
#ifdef SYSLOG
#ifndef INTERNAL_MARK
#ifndef _code
typedef struct _code {
char *c_name;
int c_val;
} CODE;
#endif
CODE facilitynames[] = {
#ifdef LOG_AUTH
{ "auth", LOG_AUTH },
#endif
#ifdef LOG_AUTHPRIV
{ "authpriv", LOG_AUTHPRIV },
#endif
#ifdef LOG_CRON
{ "cron", LOG_CRON },
#endif
#ifdef LOG_DAEMON
{ "daemon", LOG_DAEMON },
#endif
#ifdef LOG_FTP
{ "ftp", LOG_FTP },
#endif
#ifdef LOG_LPR
{ "lpr", LOG_LPR },
#endif
#ifdef LOG_MAIL
{ "mail", LOG_MAIL },
#endif
#ifdef LOG_NEWS
{ "news", LOG_NEWS },
#endif
#ifdef LOG_UUCP
{ "uucp", LOG_UUCP },
#endif
#ifdef LOG_USER
{ "user", LOG_USER },
#endif
#ifdef LOG_LOCAL7
{ "local0", LOG_LOCAL0 },
{ "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 },
{ "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 },
{ "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 },
{ "local7", LOG_LOCAL7 },
#endif
{ 0, -1 }
};
#endif
GLOBAL const char
*ngt_SyslogFacilityName(int Facility)
{
int i = 0;
while(facilitynames[i].c_name) {
if (facilitynames[i].c_val == Facility)
return facilitynames[i].c_name;
i++;
}
return "unknown";
}
GLOBAL int
ngt_SyslogFacilityID(char *Name, int DefaultFacility)
{
int i = 0;
while(facilitynames[i].c_name) {
if (strcasecmp(facilitynames[i].c_name, Name) == 0)
return facilitynames[i].c_val;
i++;
}
return DefaultFacility;
}
#endif
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 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
@@ -29,6 +29,11 @@ GLOBAL void ngt_TrimStr PARAMS((char *String ));
GLOBAL char *ngt_UpperStr PARAMS((char *String ));
GLOBAL char *ngt_LowerStr PARAMS((char *String ));
#ifdef SYSLOG
GLOBAL const char *ngt_SyslogFacilityName PARAMS((int Facility));
GLOBAL int ngt_SyslogFacilityID PARAMS((char *Name, int DefaultFacility));
#endif
#endif