mirror of
https://github.com/osmarks/ngircd.git
synced 2025-10-07 10:52:24 +00:00
Compare commits
168 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9e7360e5fa | ||
![]() |
273d4bdd32 | ||
![]() |
27d244dfae | ||
![]() |
a39a1a5273 | ||
![]() |
ef392e7d37 | ||
![]() |
c38751191f | ||
![]() |
5cbdcf4f0d | ||
![]() |
3641e51109 | ||
![]() |
3f46e93ccc | ||
![]() |
8e3c56e5b2 | ||
![]() |
e1026d5dd1 | ||
![]() |
f7bdee5f13 | ||
![]() |
391aa8d1f7 | ||
![]() |
89d99e2ff9 | ||
![]() |
c16133c5ee | ||
![]() |
4888984429 | ||
![]() |
44bb22d23e | ||
![]() |
c7dd5ea0ba | ||
![]() |
871760583c | ||
![]() |
bc20f9ec10 | ||
![]() |
5a200e1543 | ||
![]() |
d2df7396a8 | ||
![]() |
3d27073d61 | ||
![]() |
b6f19ea8fe | ||
![]() |
8c46067b34 | ||
![]() |
594fdd02aa | ||
![]() |
6a308fcb42 | ||
![]() |
1537c79132 | ||
![]() |
e0c9931ad8 | ||
![]() |
eba95bb0d2 | ||
![]() |
51a6a33056 | ||
![]() |
6e28f4a7d1 | ||
![]() |
9882e578e9 | ||
![]() |
73781c1b38 | ||
![]() |
f2fa1045e2 | ||
![]() |
33a165721b | ||
![]() |
a3a4b5f696 | ||
![]() |
39412d6486 | ||
![]() |
c1656256df | ||
![]() |
1f4711a547 | ||
![]() |
4d0069c3a8 | ||
![]() |
12c60a670e | ||
![]() |
2f7d0c0839 | ||
![]() |
1afbf71236 | ||
![]() |
7ed08f01ef | ||
![]() |
81cc5f82b5 | ||
![]() |
78a3b4c7d6 | ||
![]() |
39d630c00d | ||
![]() |
4fe6b42c53 | ||
![]() |
d4d8102fc9 | ||
![]() |
77f68b4fd1 | ||
![]() |
2f8877ded4 | ||
![]() |
4bff3daf92 | ||
![]() |
c5beca8aab | ||
![]() |
f8405b1a4f | ||
![]() |
fdfc27265e | ||
![]() |
a4d1e6007f | ||
![]() |
9260759cec | ||
![]() |
c2ac1ad3ba | ||
![]() |
470d2e2362 | ||
![]() |
888664435a | ||
![]() |
98493077a2 | ||
![]() |
1fa2af5b3a | ||
![]() |
05cc9bf9b0 | ||
![]() |
cc06e1ff89 | ||
![]() |
9fbf592924 | ||
![]() |
adf92302bf | ||
![]() |
566a451299 | ||
![]() |
e0f8ce093a | ||
![]() |
5e3449a241 | ||
![]() |
762b0325df | ||
![]() |
6b62a5ec4f | ||
![]() |
b24d645ca1 | ||
![]() |
1bb2fbedcc | ||
![]() |
3193d5477c | ||
![]() |
edab86e0f8 | ||
![]() |
e4006a93e3 | ||
![]() |
9069380ddf | ||
![]() |
ab188c1486 | ||
![]() |
5eb9f2e717 | ||
![]() |
abfc5c6e27 | ||
![]() |
565523cbb4 | ||
![]() |
013298d4c6 | ||
![]() |
af13732ec7 | ||
![]() |
408a74b865 | ||
![]() |
f47904bf95 | ||
![]() |
70eb8219f5 | ||
![]() |
9e5b9ddad0 | ||
![]() |
56b7e67307 | ||
![]() |
b681aa5b9f | ||
![]() |
b32f3b76e9 | ||
![]() |
1a5ed654b4 | ||
![]() |
9cbb8f3bb8 | ||
![]() |
e19ce437ca | ||
![]() |
4e550bf9ef | ||
![]() |
1d29a59f7e | ||
![]() |
765c2f26ea | ||
![]() |
69fa6f268a | ||
![]() |
43509fd22c | ||
![]() |
a71abfef4b | ||
![]() |
8a8e8a3a23 | ||
![]() |
65befdafaa | ||
![]() |
15fec92ed7 | ||
![]() |
1e4a00f94f | ||
![]() |
338758799d | ||
![]() |
164e15b8c6 | ||
![]() |
32bfafafd9 | ||
![]() |
6ef20e0f9a | ||
![]() |
e86e193e01 | ||
![]() |
ae5ebfb9f0 | ||
![]() |
e9e6224aae | ||
![]() |
e23f025dd6 | ||
![]() |
3ca8703309 | ||
![]() |
fc82efc3e8 | ||
![]() |
dc9fcb0fb2 | ||
![]() |
2b95c69ea1 | ||
![]() |
af70c3dbc9 | ||
![]() |
1e054e0b82 | ||
![]() |
06a20b87c4 | ||
![]() |
fea2194fc0 | ||
![]() |
872dc5042d | ||
![]() |
e1315f30fd | ||
![]() |
0a85c58878 | ||
![]() |
ee21490887 | ||
![]() |
8fa92f0a24 | ||
![]() |
8e193df973 | ||
![]() |
9d348d00d9 | ||
![]() |
9e48f3f8f8 | ||
![]() |
e4a06844a3 | ||
![]() |
20ccc1bba7 | ||
![]() |
13d9e0c5a7 | ||
![]() |
a7911e35af | ||
![]() |
60812b6fdf | ||
![]() |
1ea6811616 | ||
![]() |
d2f54abbed | ||
![]() |
07dbb73c92 | ||
![]() |
30796698a9 | ||
![]() |
f173a974be | ||
![]() |
8aac366802 | ||
![]() |
69803d6ff1 | ||
![]() |
be6994aece | ||
![]() |
1361b3742d | ||
![]() |
d3036c74e9 | ||
![]() |
553e8b6aa3 | ||
![]() |
51d7674ee7 | ||
![]() |
1189200d4a | ||
![]() |
7795b07c53 | ||
![]() |
d9325e8030 | ||
![]() |
641045249c | ||
![]() |
69f81a359a | ||
![]() |
be03bc672c | ||
![]() |
160c52400f | ||
![]() |
0b8acf1205 | ||
![]() |
88f6fc5fd8 | ||
![]() |
da897a2a14 | ||
![]() |
989c9fa531 | ||
![]() |
2fd42667c2 | ||
![]() |
2dfa24d2fa | ||
![]() |
1ed602eb47 | ||
![]() |
ea725b99b7 | ||
![]() |
3dc3a03538 | ||
![]() |
95f0e4033c | ||
![]() |
409b2c86c8 | ||
![]() |
d692286d7a | ||
![]() |
456e55921d | ||
![]() |
9f3690c39c | ||
![]() |
6cbe13085d | ||
![]() |
b7780e3f2a |
9
AUTHORS
9
AUTHORS
@@ -2,7 +2,7 @@
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2011 Alexander Barton and Contributors.
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
@@ -10,9 +10,10 @@
|
||||
|
||||
|
||||
Note: If you have critics, patches or something else, please feel free to
|
||||
post a mail to the ngIRCd mailing list: <ngircd-ml@arthur.ath.cx> (please see
|
||||
<http://ngircd.barton.de/#ml> for details). Don't mail the contributors
|
||||
directly, if possible!
|
||||
post a mail to the ngIRCd mailing list: <ngircd-ml@arthur.barton.de> (please
|
||||
see <http://ngircd.barton.de/#ml> for details).
|
||||
|
||||
Don't mail the people listed here directly, if possible!
|
||||
|
||||
|
||||
Main Authors
|
||||
|
39
COPYING
39
COPYING
@@ -1,12 +1,12 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
@@ -225,7 +225,7 @@ impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
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
|
||||
@@ -277,9 +277,9 @@ 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.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@@ -303,10 +303,9 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
160
ChangeLog
160
ChangeLog
@@ -2,13 +2,163 @@
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2011 Alexander Barton and Contributors.
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
-- ChangeLog --
|
||||
|
||||
|
||||
ngIRCd Release 19 (2012-02-29)
|
||||
|
||||
- Update build system: bump config.guess and config.sub files used by
|
||||
GNU autoconf/automake to recent versions.
|
||||
- Fix configuration file parser: don't accept "[SSL]" blocks in the
|
||||
configuration file when no SSL support is built in ngIRCd.
|
||||
- Fix building ngIRCd with old gcc versions (e. g. 2.7.2).
|
||||
- Correctly re-open syslog logging after reading of configuration
|
||||
file: Syslog logging has been initialized before reading the
|
||||
configuraton, so ngIRCd always used the default facility and ignored
|
||||
the "SyslogFacility" configuration option ...
|
||||
Thanks to Patrik Schindler for reporting this issue!
|
||||
|
||||
ngIRCd 19~rc1 (2012-02-12)
|
||||
- Enhance command limits for server links: the limit now is dependent
|
||||
on the number of users connected in the network and higher while
|
||||
servers are joining the network to make the login of servers faster.
|
||||
- Log more information about server synchronization.
|
||||
- Update preliminary ngIRCd protocol module for Anope 1.9.6, which now
|
||||
is the only supported version.
|
||||
- New numeric RPL_WHOISHOST_MSG(378), which returns the DNS hostname
|
||||
(if available) and the IP address of a client in the WHOIS reply.
|
||||
Only the user itself and local IRC operators get this numeric.
|
||||
- Implement channel exception list (mode 'e'). This allows a channel
|
||||
operator to define exception masks that allow users to join the
|
||||
channel even when a "ban" would match and prevent them from joining:
|
||||
the exception list (e) overrides the ban list (b).
|
||||
- PRIVMSG and NOTICE: Handle nick!user@host masks case-insensitive.
|
||||
- Implement user mode 'C': If the target user of a PRIVMSG or NOTICE
|
||||
command has the user mode 'C' set, it is required that both sender
|
||||
and receiver are on the same channel. This prevents private flooding
|
||||
by completely unknown clients.
|
||||
- New RPL_WHOISREGNICK_MSG(307) numeric in WHOIS command replies: it
|
||||
indicates if a nick name is registered (if user mode 'R' set).
|
||||
- Limit channel invite, ban, and exception lists to 50 entries and fix
|
||||
duplicate check and error messages when adding already listed entries
|
||||
or deleting no (longer) existing ones.
|
||||
- Fix both ERR_SUMMONDISABLED(445) and ERR_USERSDISABLED(446) replies.
|
||||
- MODE command: correctly return ERR_UNKNOWNMODE(472) numeric for
|
||||
unknown channel modes, instead of ERR_UMODEUNKNOWNFLAG(501).
|
||||
- ISUPPORT(005) numeric: add "O", "R", and "z" modes to "CHANMODES",
|
||||
add "EXCEPTS=e" and "INVEX=I", add "MAXLIST=beI:50".
|
||||
- Limit the number of list items in the reply of LIST (100), WHO (25),
|
||||
WHOIS (10), and WHOWAS (25) commands.
|
||||
- LIST command: compare pattern case insensitive.
|
||||
- Limit the MODE command to handle a maximum number of 5 channel modes
|
||||
that require an argument (+Ibkl) per call and report this number
|
||||
in the ISUPPORT(005) numeric: "MODES=5".
|
||||
- Fix handling of channel mode sequence with/without arguments.
|
||||
For example, don't generate wrong error messages when handling
|
||||
"MODE #chan +IIIIItn *!aa@b *!bb@c *!cc@d *!dd@e *!ee@f".
|
||||
- When sending data on a connection, only try to get the type of
|
||||
the client if there still is one assigned. This could trigger an
|
||||
assertion and end the daemon in some error paths.
|
||||
- Don't try to close already closed/invalid sockets to forked child
|
||||
processes. This could potentially crash the daemon in some cases
|
||||
with IDENT lookups enabled.
|
||||
- WHOIS command: make sure that the reply ends with RPL_ENDOFWHOIS,
|
||||
don't answer queries for IRC servers, make sure mask matching is
|
||||
case-insensitive, and that RPL_ENDOFWHOIS numeric is sent with the
|
||||
unmodified mask (like it has been received from the client).
|
||||
- LINKS command: support <mask> parameter to limit the reply.
|
||||
- Add 1 second penalty for every further target on PRIVMSG/NOTICE
|
||||
commands: this reduces the possibility of flooding channels with
|
||||
commands like "PRIVMSG/NOTICE #a,#n,#c,... :message" a little bit.
|
||||
Problem noticed by Cahata, thanks!
|
||||
- Display correct error message when "Server{UID|GID}" variabe in the
|
||||
configuration file is invalid (not a number and no existing user).
|
||||
- Update Copyright notices for 2012 :-)
|
||||
- JOIN command: don't stop handling of channel lists when a single
|
||||
channel cannot be joined (because of bad name, wrong key or channel
|
||||
limit reached), but report an error and continue. And don't check
|
||||
the channel limit and don't report with "too many channels" when
|
||||
trying to join a channel that the client already is a member of.
|
||||
- ISON command: reply with the correct upper-/lowercase nick names.
|
||||
- New configuration option "PAMIsOptional": when set, clients not
|
||||
sending a password are still allowed to connect: they won't become
|
||||
"identified" and keep the "~" character prepended to their supplied
|
||||
user name. See "man 5 ngircd.conf" for details.
|
||||
- Fixed handling of WHO commands. This fixes two bugs: "WHO <nick>"
|
||||
returned nothing at all if the user was "+i" (reported by Cahata,
|
||||
thanks) and "WHO <nick|nickmask>" returned channel names instead
|
||||
of "*" when the user was member of a (visible) channel.
|
||||
- Fixed some spelling errors in documentation and code comments
|
||||
(Thanks to Christoph Biedl).
|
||||
- contrib/Debian/control: Update and complete "Build-Depends" and
|
||||
update our Debian package descriptions with "official" ones.
|
||||
- Fixed typo in two error messages.
|
||||
- LUSERS reply: only count channels that are visible to the requesting
|
||||
client, so the existence of secret channels is no longer revealed by
|
||||
using LUSERS. Reported by Cahata, thanks!
|
||||
- Unknown user and channel modes no longer stop the mode parser, but
|
||||
are simply ignored. Therefore modes after the unknown one are now
|
||||
handled. This is how ircd2.10/ircd2.11/ircd-seven behave, at least.
|
||||
Reported by Cahata, thanks!
|
||||
- README: Update list of implemented commands.
|
||||
- Log better error messages when rejecting clients.
|
||||
- Implement IRC commands "GLINE" and "KLINE" to ban users. G-Lines are
|
||||
synchronized between server on peering, K-Lines are local only.
|
||||
If you use "*!<user>@<host>" or "*!*@<host>" masks, these connections
|
||||
are blocked even before the user is fully logged in (before PASS,
|
||||
NICK, and USER commands have been processed) and before the child
|
||||
processes for authentication are forked, so resource usage is smaller.
|
||||
- Xcode: update project file for Xcode 4.2 and define HAVE_GAI_STRERROR
|
||||
for Mac OS X Xcode builds.
|
||||
- ./configure: Fix logic and quoting of poll() detection code: only use
|
||||
poll() when poll.h exists as well.
|
||||
- Suppress 'Can't create pre-defined channel: invalid name: ""' message.
|
||||
- whois-test: handle local hostname = "localhost.localdomain" using the
|
||||
pattern "localhost*" for valid local hostnames.
|
||||
- sample-ngircd.conf: show correct default for "PAM" variable: The
|
||||
default of "PAM" is "yes" when ngIRCd has been configured to use it,
|
||||
so show the correct default value in the sample configuration file.
|
||||
(Closes #119)
|
||||
- Update GPL 2 license text to current version.
|
||||
- Only close "unrelated" sockets in forked child processes: This fixes
|
||||
the problem that ngIRCd can't do any IDENT lookups because of the
|
||||
socket has already been closed in the child process.
|
||||
The bug has been introduced starting with ngIRCd 17 ... :-(
|
||||
(commit ID 6ebb31ab35e)
|
||||
- Added doc/Modes.txt: document modes supported by ngIRCd.
|
||||
- Implement user mode "R": indicates that the nick name of this user
|
||||
is "registered". This mode isn't handled by ngIRCd itself, but must
|
||||
be set and unset by IRC services like Anope.
|
||||
- Implement channel mode "R": only registered users (having the user
|
||||
mode "R" set) are allowed to join this channel.
|
||||
- Test suite: bind to loopback (127.0.0.1) interface only.
|
||||
- New 2nd message "Nickname too long" for error code 432.
|
||||
- Xcode: Mac OS X config.h: support 10.5 as well as 10.6/10.7 SDK.
|
||||
- Xcode: exclude more Xcode 4 specific directories in ".gitignore".
|
||||
- Disconnect directly linked servers sending QUIT. Without this,
|
||||
the server becomes removed from the network and the client list,
|
||||
but the connection isn't shut down at all ...
|
||||
- contrib/ngindent: detect "gindent" as GNU indent.
|
||||
- Handle unknown user and channel modes: these modes are saved and
|
||||
forwarded to other servers, but ignored otherwise.
|
||||
- Handle channel user modes 'a', 'h', and 'q' from remote servers.
|
||||
These channel user modes aren't used for anything at the moment,
|
||||
but ngIRCd knows that these three modes are "channel user modes"
|
||||
and not "channel modes", that is that these modes take an "nick name"
|
||||
argument. Like unknown user and channel modes, these modes are saved
|
||||
and forwarded to other servers, but ignored otherwise.
|
||||
- Correctly inform clients when other servers change their user modes.
|
||||
This is required for some services to work correctly.
|
||||
- Test suite: make getpid.sh work even when run as root.
|
||||
- Spoofed prefixes: close connection on non-server links only.
|
||||
On server-links, spoofed prefixes can happen because of the
|
||||
asynchronous nature of the IRC protocol. So don't break server-
|
||||
links, only log a message and ignore the command. (Closes #113)
|
||||
|
||||
ngIRCd Release 18 (2011-07-10)
|
||||
|
||||
- Update timestamp of ngircd(8) manual page.
|
||||
@@ -797,7 +947,7 @@ ngIRCd 0.6.0, 2002-12-24
|
||||
werden (beide Server versuchen sich dann gegenseitig zu connectieren).
|
||||
- Test-Suite und Dokumentation an A/UX angepasst.
|
||||
- unter HP-UX definiert das configure-Script nun _XOPEN_SOURCE_EXTENDED.
|
||||
- Server identifizieren sich nun mit asyncronen Passwoertern, d.h. das
|
||||
- Server identifizieren sich nun mit asynchronen Passwoertern, d.h. das
|
||||
Passwort, welches A an B schickt, kann ein anderes sein als das, welches
|
||||
B als Antwort an A sendet. In der Konfig.-Datei, Abschnitt "Server",
|
||||
wurde "Password" dazu durch "MyPassword" und "PeerPassword" ersetzt.
|
||||
@@ -927,7 +1077,7 @@ ngIRCd 0.5.0, 20.09.2002
|
||||
- Protokoll- und Server-ID bei PASS-Befehlen auf neues Format umgestellt;
|
||||
bei empfangenen PASS-Befehlen werden diese zudem nun auch ausgewertet.
|
||||
Die unterstuetzten Flags sind in doc/Protocol.txt beschrieben.
|
||||
- mit dem neuen Befehl CHANINFO syncronisieren Server, die das IRC+-
|
||||
- mit dem neuen Befehl CHANINFO synchronisieren Server, die das IRC+-
|
||||
Protokoll unterstuetzen, Channel-Modes und Topics.
|
||||
- neue Option "--disable-ircplus" fuer das configure-Script, um das
|
||||
IRC+-Protokoll abzuschalten (per Default ist es aktiviert).
|
||||
@@ -1032,7 +1182,7 @@ ngIRCd 0.3.0, 02.03.2002
|
||||
- PRIVMSG beachtet nun die Channel-Modes "n" und "m".
|
||||
- AWAY implementiert. PRIVMSG, MODE, USERHOST und WHOIS angepasst.
|
||||
- der ngIRCd unterstuetzt nun Channel-Topics (TOPIC-Befehl).
|
||||
- ausgehende Server-Verbindungen werden nun asyncron connectiert und
|
||||
- ausgehende Server-Verbindungen werden nun asynchron connectiert und
|
||||
blockieren nicht mehr den ganzen Server, wenn die Gegenseite nicht
|
||||
erreicht werden kann (bis zum Timeout konnten Minuten vergehen!).
|
||||
- Wert der Konfigurations-Variable "ConnectRetry" wird besser beachtet.
|
||||
@@ -1111,7 +1261,7 @@ ngIRCd 0.0.2, 06.01.2002
|
||||
- NICK kann nun die Gross- und Kleinschreibung eines Nicks aendern.
|
||||
- ein Server-Passwort ist nun konfigurierbar.
|
||||
- neue Befehle: ERROR, SERVER, NJOIN (nur als "Fake"), SQUIT.
|
||||
- Asyncroner Resolver Hostname->IP implementiert.
|
||||
- Asynchroner Resolver Hostname->IP implementiert.
|
||||
- Server-Links teilweise implementiert: bisher kann der ngIRCd jedoch
|
||||
nur "leafed server" sein, d.h. keine "Client-Server" haben. Einige
|
||||
Befehle sind auch noch nicht (optimal) angepasst: PRIVMSG funktioniert
|
||||
|
2
INSTALL
2
INSTALL
@@ -2,7 +2,7 @@
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2011 Alexander Barton and Contributors.
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
|
79
NEWS
79
NEWS
@@ -2,12 +2,81 @@
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2011 Alexander Barton and Contributors.
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
-- NEWS --
|
||||
|
||||
|
||||
ngIRCd Release 19 (2012-02-29)
|
||||
|
||||
ngIRCd 19~rc1 (2012-02-12)
|
||||
- Update preliminary ngIRCd protocol module for Anope 1.9.6, which now
|
||||
is the only supported version.
|
||||
- New numeric RPL_WHOISHOST_MSG(378), which returns the DNS hostname
|
||||
(if available) and the IP address of a client in the WHOIS reply.
|
||||
Only the user itself and local IRC operators get this numeric.
|
||||
- Implement channel exception list (mode 'e'). This allows a channel
|
||||
operator to define exception masks that allow users to join the
|
||||
channel even when a "ban" would match and prevent them from joining:
|
||||
the exception list (e) overrides the ban list (b).
|
||||
- Implement user mode 'C': If the target user of a PRIVMSG or NOTICE
|
||||
command has the user mode 'C' set, it is required that both sender
|
||||
and receiver are on the same channel. This prevents private flooding
|
||||
by completely unknown clients.
|
||||
- New RPL_WHOISREGNICK_MSG(307) numeric in WHOIS command replies: it
|
||||
indicates if a nick name is registered (if user mode 'R' set).
|
||||
- Limit channel invite, ban, and exception lists to 50 entries and fix
|
||||
duplicate check and error messages when adding already listed entries
|
||||
or deleting no (longer) existing ones.
|
||||
- Limit the number of list items in the reply of LIST (100), WHO (25),
|
||||
WHOIS (10), and WHOWAS (25) commands.
|
||||
- Limit the MODE command to handle a maximum number of 5 channel modes
|
||||
that require an argument (+Ibkl) per call and report this number
|
||||
in the ISUPPORT(005) numeric: "MODES=5".
|
||||
- LINKS command: support <mask> parameter to limit the reply.
|
||||
- Add 1 second penalty for every further target on PRIVMSG/NOTICE
|
||||
commands: this reduces the possibility of flooding channels with
|
||||
commands like "PRIVMSG/NOTICE #a,#n,#c,... :message" a little bit.
|
||||
Problem noticed by Cahata, thanks!
|
||||
- New configuration option "PAMIsOptional": when set, clients not
|
||||
sending a password are still allowed to connect: they won't become
|
||||
"identified" and keep the "~" character prepended to their supplied
|
||||
user name. See "man 5 ngircd.conf" for details.
|
||||
- Fixed handling of WHO commands. This fixes two bugs: "WHO <nick>"
|
||||
returned nothing at all if the user was "+i" (reported by Cahata,
|
||||
thanks) and "WHO <nick|nickmask>" returned channel names instead
|
||||
of "*" when the user was member of a (visible) channel.
|
||||
- LUSERS reply: only count channels that are visible to the requesting
|
||||
client, so the existence of secret channels is no longer revealed by
|
||||
using LUSERS. Reported by Cahata, thanks!
|
||||
- Unknown user and channel modes no longer stop the mode parser, but
|
||||
are simply ignored. Therefore modes after the unknown one are now
|
||||
handled. This is how ircd2.10/ircd2.11/ircd-seven behave, at least.
|
||||
Reported by Cahata, thanks!
|
||||
- Implement IRC commands "GLINE" and "KLINE" to ban users. G-Lines are
|
||||
synchronized between server on peering, K-Lines are local only.
|
||||
If you use "*!<user>@<host>" or "*!*@<host>" masks, these connections
|
||||
are blocked even before the user is fully logged in (before PASS,
|
||||
NICK, and USER commands have been processed) and before the child
|
||||
processes for authentication are forked, so resource usage is smaller.
|
||||
- Added doc/Modes.txt: document modes supported by ngIRCd.
|
||||
- Implement user mode "R": indicates that the nick name of this user
|
||||
is "registered". This mode isn't handled by ngIRCd itself, but must
|
||||
be set and unset by IRC services like Anope.
|
||||
- Implement channel mode "R": only registered users (having the user
|
||||
mode "R" set) are allowed to join this channel.
|
||||
- Test suite: bind to loopback (127.0.0.1) interface only.
|
||||
- Handle unknown user and channel modes: these modes are saved and
|
||||
forwarded to other servers, but ignored otherwise.
|
||||
- Handle channel user modes 'a', 'h', and 'q' from remote servers.
|
||||
These channel user modes aren't used for anything at the moment,
|
||||
but ngIRCd knows that these three modes are "channel user modes"
|
||||
and not "channel modes", that is that these modes take an "nick name"
|
||||
argument. Like unknown user and channel modes, these modes are saved
|
||||
and forwarded to other servers, but ignored otherwise.
|
||||
|
||||
ngIRCd Release 18 (2011-07-10)
|
||||
|
||||
- Add preliminary ngIRCd protocol module for Anope 1.9 to contrib/Anope/.
|
||||
@@ -351,7 +420,7 @@ ngIRCd 0.6.0, 2002-12-24
|
||||
ausgehende Verbindung zu diesem auufzubauen. Dadurch kann nun auf beiden
|
||||
Servern in der Konfiguration ein Port fuer den Connect konfiguriert
|
||||
werden (beide Server versuchen sich dann gegenseitig zu connectieren).
|
||||
- Server identifizieren sich nun mit asyncronen Passwoertern, d.h. das
|
||||
- Server identifizieren sich nun mit asynchronen Passwoertern, d.h. das
|
||||
Passwort, welches A an B schickt, kann ein anderes sein als das, welches
|
||||
B als Antwort an A sendet. In der Konfig.-Datei, Abschnitt "Server",
|
||||
wurde "Password" dazu durch "MyPassword" und "PeerPassword" ersetzt.
|
||||
@@ -377,7 +446,7 @@ ngIRCd 0.5.0, 20.09.2002
|
||||
Konfiguration "sample-ngircd.conf") und bleiben auch dann bestehen,
|
||||
wenn kein User mehr im Channel ist.
|
||||
- neue IRC-Befehle: KICK, INVITE, ADMIN, CHANINFO; LIST wurde erweitert.
|
||||
Mit dem neuen Befehl CHANINFO syncronisieren Server, die das IRC+-
|
||||
Mit dem neuen Befehl CHANINFO synchronisieren Server, die das IRC+-
|
||||
Protokoll unterstuetzen, Channel-Modes und Topics. Fuer den ADMIN-Befehl
|
||||
gibt es neue Konfigurationsoptionen (Sektion "Global"): "AdminInfo1",
|
||||
"AdminInfo2" und "AdminEMail".
|
||||
@@ -463,7 +532,3 @@ ngIRCd 0.0.2, 06.01.2002
|
||||
ngIRCd 0.0.1, 31.12.2001
|
||||
|
||||
- erste oeffentliche Version von ngIRCd als "public preview" :-)
|
||||
|
||||
|
||||
--
|
||||
$Id: NEWS,v 1.88 2008/02/26 22:05:42 fw Exp $
|
||||
|
38
README
38
README
@@ -2,7 +2,7 @@
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2011 Alexander Barton and Contributors.
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
@@ -14,9 +14,10 @@ I. Introduction
|
||||
|
||||
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.
|
||||
Licence, see the file COPYING for details. ngIRCd means "next generation
|
||||
IRC daemon" (which is a little bit exaggerated, "lightweight Internet Relay
|
||||
Chat server" would be better), it's written from scratch and not deduced
|
||||
from the "grandfather of IRC daemons", the daemon of the IRCNet.
|
||||
|
||||
Please see the INSTALL document for installation and upgrade information!
|
||||
|
||||
@@ -33,22 +34,24 @@ used in real IRC networks.
|
||||
|
||||
Implemented IRC-commands are:
|
||||
|
||||
ADMIN, AWAY, CHANINFO, CONNECT, DIE, DISCONNECT, ERROR, HELP, INFO, INVITE,
|
||||
ISON, JOIN, KICK, KILL, LINKS, LIST, LUSERS, MODE, MOTD, NAMES, NICK, NJOIN,
|
||||
NOTICE, OPER, PART, PASS, PING, PONG, PRIVMSG, QUIT, REHASH, RESTART, SERVER,
|
||||
SERVICE, SERVLIST, SQUERY, SQUIT, STATS, SUMMON, TIME, TOPIC, TRACE, USER,
|
||||
USERHOST, USERS, VERSION, WALLOPS, WEBIRC, WHO, WHOIS, WHOWAS.
|
||||
|
||||
ADMIN, AWAY, CHANINFO, CONNECT, DIE, DISCONNECT, ERROR, GLINE, HELP, INFO,
|
||||
INVITE, ISON, JOIN, KICK, KILL, KLINE, LINKS, LIST, LUSERS, MODE, MOTD,
|
||||
NAMES, NICK, NJOIN, NOTICE, OPER, PART, PASS, PING, PONG, PRIVMSG, QUIT,
|
||||
REHASH, RESTART, SERVER, SERVICE, SERVLIST, SQUERY, SQUIT, STATS, SUMMON,
|
||||
TIME, TOPIC, TRACE, USER, USERHOST, USERS, VERSION, WALLOPS, WEBIRC, WHO,
|
||||
WHOIS, WHOWAS.
|
||||
|
||||
III. Features (or: why use ngIRCd?)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- no problems with servers which have dynamic IP addresses
|
||||
- simple, easy understandable configuration file,
|
||||
- freely published open-source C source code,
|
||||
- ngIRCd will be developed on in the future.
|
||||
- well arranged (lean) configuration file
|
||||
- simple to build/install, configure and maintain
|
||||
- supports IPv6 and SSL
|
||||
- no problems with servers that have dynamic IP addresses
|
||||
- freely available, modern, portable and tidy C-source
|
||||
- wide field of supported platforms, including AIX, A/UX, FreeBSD, HP-UX,
|
||||
IRIX, Linux, Mac OS X, NetBSD, OpenBSD, Solaris, and Windows with Cygwin.
|
||||
- ngIRCd is being actively developed since 2001.
|
||||
|
||||
|
||||
IV. Documentation
|
||||
@@ -68,7 +71,7 @@ releases there.
|
||||
If you are interested in the latest development versions (which are not
|
||||
always stable), then please read the section about "GIT" on the homepage and
|
||||
the file "doc/GIT.txt" which describes the use of GIT, the version control
|
||||
system used by ngIRCd (homepage: http://git.or.cz/).
|
||||
system used by ngIRCd (homepage: http://git-scm.com/).
|
||||
|
||||
|
||||
VI. Bugs
|
||||
@@ -82,5 +85,6 @@ them at the following URL:
|
||||
There you can read about known bugs and limitations, too.
|
||||
|
||||
If you have critics, patches or something else, please feel free to post a
|
||||
mail to the ngIRCd mailing list: <ngircd-ml@arthur.ath.cx> (please see
|
||||
<http://ngircd.barton.de/support.php#ml> for details).
|
||||
mail to the ngIRCd mailing list: <ngircd-ml@arthur.barton.de> (please see
|
||||
<http://ngircd.barton.de/support.php#ml> for details) or join the ngIRCd
|
||||
IRC channel: <irc://irc.barton.de/ngircd>.
|
||||
|
546
config.guess
vendored
546
config.guess
vendored
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2008-01-23'
|
||||
timestamp='2012-02-10'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@@ -17,9 +17,7 @@ timestamp='2008-01-23'
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
@@ -27,16 +25,16 @@ timestamp='2008-01-23'
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
|
||||
# Originally written by Per Bothner <per@bothner.com>.
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
# Originally written by Per Bothner. Please send patches (context
|
||||
# diff format) to <config-patches@gnu.org> and include a ChangeLog
|
||||
# entry.
|
||||
#
|
||||
# This script attempts to guess a canonical system name similar to
|
||||
# config.sub. If it succeeds, it prints the system name on stdout, and
|
||||
# exits with 0. Otherwise, it exits with 1.
|
||||
#
|
||||
# The plan is that this can be called by configure scripts if you
|
||||
# don't specify an explicit build system type.
|
||||
# You can get the latest version of this script from:
|
||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
||||
|
||||
me=`echo "$0" | sed -e 's,.*/,,'`
|
||||
|
||||
@@ -56,8 +54,9 @@ version="\
|
||||
GNU config.guess ($timestamp)
|
||||
|
||||
Originally written by Per Bothner.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -144,7 +143,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||||
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
*:NetBSD:*:*)
|
||||
# NetBSD (nbsd) targets should (where applicable) match one or
|
||||
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
|
||||
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
|
||||
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
|
||||
# switched to ELF, *-*-netbsd* would select the old
|
||||
# object file format. This provides both forward
|
||||
@@ -170,7 +169,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
||||
eval $set_cc_for_build
|
||||
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep __ELF__ >/dev/null
|
||||
| grep -q __ELF__
|
||||
then
|
||||
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
|
||||
# Return netbsd for either. FIX?
|
||||
@@ -180,7 +179,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
os=netbsd
|
||||
os=netbsd
|
||||
;;
|
||||
esac
|
||||
# The OS release
|
||||
@@ -223,7 +222,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
|
||||
;;
|
||||
*5.*)
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
|
||||
;;
|
||||
esac
|
||||
# According to Compaq, /usr/sbin/psrinfo has been available on
|
||||
@@ -269,7 +268,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# A Xn.n version is an unreleased experimental baselevel.
|
||||
# 1.2 uses "1.2" for uname -r.
|
||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
exit ;;
|
||||
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
|
||||
exitcode=$?
|
||||
trap '' 0
|
||||
exit $exitcode ;;
|
||||
Alpha\ *:Windows_NT*:*)
|
||||
# How do we know it's Interix rather than the generic POSIX subsystem?
|
||||
# Should we change UNAME_MACHINE based on the output of uname instead
|
||||
@@ -295,7 +297,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
echo s390-ibm-zvmoe
|
||||
exit ;;
|
||||
*:OS400:*:*)
|
||||
echo powerpc-ibm-os400
|
||||
echo powerpc-ibm-os400
|
||||
exit ;;
|
||||
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||
@@ -324,14 +326,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
case `/usr/bin/uname -p` in
|
||||
sparc) echo sparc-icl-nx7; exit ;;
|
||||
esac ;;
|
||||
s390x:SunOS:*:*)
|
||||
echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4H:SunOS:5.*:*)
|
||||
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
||||
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
|
||||
echo i386-pc-auroraux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
|
||||
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
eval $set_cc_for_build
|
||||
SUN_ARCH="i386"
|
||||
# If there is a compiler, see if it is configured for 64-bit objects.
|
||||
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
|
||||
# This test works for both compilers.
|
||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||||
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
then
|
||||
SUN_ARCH="x86_64"
|
||||
fi
|
||||
fi
|
||||
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4*:SunOS:6*:*)
|
||||
# According to config.sub, this is the proper way to canonicalize
|
||||
@@ -375,23 +396,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# MiNT. But MiNT is downward compatible to TOS, so this should
|
||||
# be no problem.
|
||||
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
exit ;;
|
||||
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
|
||||
echo m68k-milan-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-milan-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
|
||||
echo m68k-hades-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-hades-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
|
||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
m68k:machten:*:*)
|
||||
echo m68k-apple-machten${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -461,8 +482,8 @@ EOF
|
||||
echo m88k-motorola-sysv3
|
||||
exit ;;
|
||||
AViiON:dgux:*:*)
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
|
||||
then
|
||||
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
|
||||
@@ -475,7 +496,7 @@ EOF
|
||||
else
|
||||
echo i586-dg-dgux${UNAME_RELEASE}
|
||||
fi
|
||||
exit ;;
|
||||
exit ;;
|
||||
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
|
||||
echo m88k-dolphin-sysv3
|
||||
exit ;;
|
||||
@@ -532,7 +553,7 @@ EOF
|
||||
echo rs6000-ibm-aix3.2
|
||||
fi
|
||||
exit ;;
|
||||
*:AIX:*:[456])
|
||||
*:AIX:*:[4567])
|
||||
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
|
||||
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
|
||||
IBM_ARCH=rs6000
|
||||
@@ -575,52 +596,52 @@ EOF
|
||||
9000/[678][0-9][0-9])
|
||||
if [ -x /usr/bin/getconf ]; then
|
||||
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||
case "${sc_cpu_version}" in
|
||||
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
||||
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
|
||||
532) # CPU_PA_RISC2_0
|
||||
case "${sc_kernel_bits}" in
|
||||
32) HP_ARCH="hppa2.0n" ;;
|
||||
64) HP_ARCH="hppa2.0w" ;;
|
||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||
case "${sc_cpu_version}" in
|
||||
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
||||
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
|
||||
532) # CPU_PA_RISC2_0
|
||||
case "${sc_kernel_bits}" in
|
||||
32) HP_ARCH="hppa2.0n" ;;
|
||||
64) HP_ARCH="hppa2.0w" ;;
|
||||
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
|
||||
esac ;;
|
||||
esac
|
||||
esac ;;
|
||||
esac
|
||||
fi
|
||||
if [ "${HP_ARCH}" = "" ]; then
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
|
||||
#define _HPUX_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#define _HPUX_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
long bits = sysconf(_SC_KERNEL_BITS);
|
||||
#endif
|
||||
long cpu = sysconf (_SC_CPU_VERSION);
|
||||
int main ()
|
||||
{
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
long bits = sysconf(_SC_KERNEL_BITS);
|
||||
#endif
|
||||
long cpu = sysconf (_SC_CPU_VERSION);
|
||||
|
||||
switch (cpu)
|
||||
{
|
||||
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
|
||||
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
|
||||
case CPU_PA_RISC2_0:
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
switch (bits)
|
||||
{
|
||||
case 64: puts ("hppa2.0w"); break;
|
||||
case 32: puts ("hppa2.0n"); break;
|
||||
default: puts ("hppa2.0"); break;
|
||||
} break;
|
||||
#else /* !defined(_SC_KERNEL_BITS) */
|
||||
puts ("hppa2.0"); break;
|
||||
#endif
|
||||
default: puts ("hppa1.0"); break;
|
||||
}
|
||||
exit (0);
|
||||
}
|
||||
switch (cpu)
|
||||
{
|
||||
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
|
||||
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
|
||||
case CPU_PA_RISC2_0:
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
switch (bits)
|
||||
{
|
||||
case 64: puts ("hppa2.0w"); break;
|
||||
case 32: puts ("hppa2.0n"); break;
|
||||
default: puts ("hppa2.0"); break;
|
||||
} break;
|
||||
#else /* !defined(_SC_KERNEL_BITS) */
|
||||
puts ("hppa2.0"); break;
|
||||
#endif
|
||||
default: puts ("hppa1.0"); break;
|
||||
}
|
||||
exit (0);
|
||||
}
|
||||
EOF
|
||||
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
|
||||
test -z "$HP_ARCH" && HP_ARCH=hppa
|
||||
@@ -640,7 +661,7 @@ EOF
|
||||
# => hppa64-hp-hpux11.23
|
||||
|
||||
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
|
||||
grep __LP64__ >/dev/null
|
||||
grep -q __LP64__
|
||||
then
|
||||
HP_ARCH="hppa2.0w"
|
||||
else
|
||||
@@ -711,22 +732,22 @@ EOF
|
||||
exit ;;
|
||||
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
|
||||
echo c1-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
|
||||
if getsysinfo -f scalar_acc
|
||||
then echo c32-convex-bsd
|
||||
else echo c2-convex-bsd
|
||||
fi
|
||||
exit ;;
|
||||
exit ;;
|
||||
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
|
||||
echo c34-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
|
||||
echo c38-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
|
||||
echo c4-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
CRAY*Y-MP:*:*:*)
|
||||
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit ;;
|
||||
@@ -750,14 +771,14 @@ EOF
|
||||
exit ;;
|
||||
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
|
||||
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
5000:UNIX_System_V:4.*:*)
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
|
||||
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
|
||||
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
||||
@@ -769,13 +790,12 @@ EOF
|
||||
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:FreeBSD:*:*)
|
||||
case ${UNAME_MACHINE} in
|
||||
pc98)
|
||||
echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
case ${UNAME_PROCESSOR} in
|
||||
amd64)
|
||||
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
*)
|
||||
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
esac
|
||||
exit ;;
|
||||
i*:CYGWIN*:*)
|
||||
@@ -784,19 +804,22 @@ EOF
|
||||
*:MINGW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw32
|
||||
exit ;;
|
||||
i*:MSYS*:*)
|
||||
echo ${UNAME_MACHINE}-pc-msys
|
||||
exit ;;
|
||||
i*:windows32*:*)
|
||||
# uname -m includes "-pc" on this system.
|
||||
echo ${UNAME_MACHINE}-mingw32
|
||||
# uname -m includes "-pc" on this system.
|
||||
echo ${UNAME_MACHINE}-mingw32
|
||||
exit ;;
|
||||
i*:PW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-pw32
|
||||
exit ;;
|
||||
*:Interix*:[3456]*)
|
||||
case ${UNAME_MACHINE} in
|
||||
*:Interix*:*)
|
||||
case ${UNAME_MACHINE} in
|
||||
x86)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
EM64T | authenticamd)
|
||||
authenticamd | genuineintel | EM64T)
|
||||
echo x86_64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
IA64)
|
||||
@@ -806,6 +829,9 @@ EOF
|
||||
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
|
||||
echo i${UNAME_MACHINE}-pc-mks
|
||||
exit ;;
|
||||
8664:Windows_NT:*)
|
||||
echo x86_64-pc-mks
|
||||
exit ;;
|
||||
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
|
||||
# How do we know it's Interix rather than the generic POSIX subsystem?
|
||||
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
|
||||
@@ -835,92 +861,13 @@ EOF
|
||||
i*86:Minix:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-minix
|
||||
exit ;;
|
||||
arm*:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_EABI__
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
else
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
|
||||
fi
|
||||
exit ;;
|
||||
avr32*:Linux:*:*)
|
||||
aarch64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
cris:Linux:*:*)
|
||||
echo cris-axis-linux-gnu
|
||||
exit ;;
|
||||
crisv32:Linux:*:*)
|
||||
echo crisv32-axis-linux-gnu
|
||||
exit ;;
|
||||
frv:Linux:*:*)
|
||||
echo frv-unknown-linux-gnu
|
||||
exit ;;
|
||||
ia64:Linux:*:*)
|
||||
aarch64_be:Linux:*:*)
|
||||
UNAME_MACHINE=aarch64_be
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
m32r*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
m68*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
mips:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef mips
|
||||
#undef mipsel
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=mipsel
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=mips
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^CPU/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||
;;
|
||||
mips64:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef mips64
|
||||
#undef mips64el
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=mips64el
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=mips64
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^CPU/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||
;;
|
||||
or32:Linux:*:*)
|
||||
echo or32-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc64:Linux:*:*)
|
||||
echo powerpc64-unknown-linux-gnu
|
||||
exit ;;
|
||||
alpha:Linux:*:*)
|
||||
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
|
||||
EV5) UNAME_MACHINE=alphaev5 ;;
|
||||
@@ -930,11 +877,90 @@ EOF
|
||||
EV6) UNAME_MACHINE=alphaev6 ;;
|
||||
EV67) UNAME_MACHINE=alphaev67 ;;
|
||||
EV68*) UNAME_MACHINE=alphaev68 ;;
|
||||
esac
|
||||
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
|
||||
esac
|
||||
objdump --private-headers /bin/sh | grep -q ld.so.1
|
||||
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
|
||||
exit ;;
|
||||
arm*:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_EABI__
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
else
|
||||
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_PCS_VFP
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
|
||||
else
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
|
||||
fi
|
||||
fi
|
||||
exit ;;
|
||||
avr32*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
cris:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-axis-linux-gnu
|
||||
exit ;;
|
||||
crisv32:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-axis-linux-gnu
|
||||
exit ;;
|
||||
frv:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
hexagon:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
i*86:Linux:*:*)
|
||||
LIBC=gnu
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#ifdef __dietlibc__
|
||||
LIBC=dietlibc
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
|
||||
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
|
||||
exit ;;
|
||||
ia64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
m32r*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
m68*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
mips:Linux:*:* | mips64:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef ${UNAME_MACHINE}
|
||||
#undef ${UNAME_MACHINE}el
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=${UNAME_MACHINE}el
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=${UNAME_MACHINE}
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||
;;
|
||||
or32:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
padre:Linux:*:*)
|
||||
echo sparc-unknown-linux-gnu
|
||||
exit ;;
|
||||
parisc64:Linux:*:* | hppa64:Linux:*:*)
|
||||
echo hppa64-unknown-linux-gnu
|
||||
exit ;;
|
||||
parisc:Linux:*:* | hppa:Linux:*:*)
|
||||
# Look for CPU level
|
||||
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
|
||||
@@ -943,14 +969,17 @@ EOF
|
||||
*) echo hppa-unknown-linux-gnu ;;
|
||||
esac
|
||||
exit ;;
|
||||
parisc64:Linux:*:* | hppa64:Linux:*:*)
|
||||
echo hppa64-unknown-linux-gnu
|
||||
ppc64:Linux:*:*)
|
||||
echo powerpc64-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-gnu
|
||||
exit ;;
|
||||
s390:Linux:*:* | s390x:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-ibm-linux
|
||||
exit ;;
|
||||
sh64*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
sh*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
@@ -958,78 +987,18 @@ EOF
|
||||
sparc:Linux:*:* | sparc64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
tile*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
vax:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-dec-linux-gnu
|
||||
exit ;;
|
||||
x86_64:Linux:*:*)
|
||||
echo x86_64-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
xtensa*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
i*86:Linux:*:*)
|
||||
# The BFD linker knows what the default object file format is, so
|
||||
# first see if it will tell us. cd to the root directory to prevent
|
||||
# problems with other programs or directories called `ld' in the path.
|
||||
# Set LC_ALL=C to ensure ld outputs messages in English.
|
||||
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
|
||||
| sed -ne '/supported targets:/!d
|
||||
s/[ ][ ]*/ /g
|
||||
s/.*supported targets: *//
|
||||
s/ .*//
|
||||
p'`
|
||||
case "$ld_supported_targets" in
|
||||
elf32-i386)
|
||||
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
|
||||
;;
|
||||
a.out-i386-linux)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
|
||||
exit ;;
|
||||
coff-i386)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
|
||||
exit ;;
|
||||
"")
|
||||
# Either a pre-BFD a.out linker (linux-gnuoldld) or
|
||||
# one that does not give us useful --help.
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
|
||||
exit ;;
|
||||
esac
|
||||
# Determine whether the default compiler is a.out or elf
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#include <features.h>
|
||||
#ifdef __ELF__
|
||||
# ifdef __GLIBC__
|
||||
# if __GLIBC__ >= 2
|
||||
LIBC=gnu
|
||||
# else
|
||||
LIBC=gnulibc1
|
||||
# endif
|
||||
# else
|
||||
LIBC=gnulibc1
|
||||
# endif
|
||||
#else
|
||||
#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
LIBC=gnu
|
||||
#else
|
||||
LIBC=gnuaout
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __dietlibc__
|
||||
LIBC=dietlibc
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^LIBC/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${LIBC}" != x && {
|
||||
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
|
||||
exit
|
||||
}
|
||||
test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
|
||||
;;
|
||||
i*86:DYNIX/ptx:4*:*)
|
||||
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
|
||||
# earlier versions are messed up and put the nodename in both
|
||||
@@ -1037,11 +1006,11 @@ EOF
|
||||
echo i386-sequent-sysv4
|
||||
exit ;;
|
||||
i*86:UNIX_SV:4.2MP:2.*)
|
||||
# Unixware is an offshoot of SVR4, but it has its own version
|
||||
# number series starting with 2...
|
||||
# I am not positive that other SVR4 systems won't match this,
|
||||
# Unixware is an offshoot of SVR4, but it has its own version
|
||||
# number series starting with 2...
|
||||
# I am not positive that other SVR4 systems won't match this,
|
||||
# I just have to hope. -- rms.
|
||||
# Use sysv4.2uw... so that sysv4* matches it.
|
||||
# Use sysv4.2uw... so that sysv4* matches it.
|
||||
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
|
||||
exit ;;
|
||||
i*86:OS/2:*:*)
|
||||
@@ -1058,7 +1027,7 @@ EOF
|
||||
i*86:syllable:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-syllable
|
||||
exit ;;
|
||||
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
|
||||
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
|
||||
echo i386-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
i*86:*DOS:*:*)
|
||||
@@ -1073,7 +1042,7 @@ EOF
|
||||
fi
|
||||
exit ;;
|
||||
i*86:*:5:[678]*)
|
||||
# UnixWare 7.x, OpenUNIX and OpenServer 6.
|
||||
# UnixWare 7.x, OpenUNIX and OpenServer 6.
|
||||
case `/bin/uname -X | grep "^Machine"` in
|
||||
*486*) UNAME_MACHINE=i486 ;;
|
||||
*Pentium) UNAME_MACHINE=i586 ;;
|
||||
@@ -1101,10 +1070,13 @@ EOF
|
||||
exit ;;
|
||||
pc:*:*:*)
|
||||
# Left here for compatibility:
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i386.
|
||||
echo i386-pc-msdosdjgpp
|
||||
exit ;;
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i586.
|
||||
# Note: whatever this is, it MUST be the same as what config.sub
|
||||
# prints for the "djgpp" host, or else GDB configury will decide that
|
||||
# this is a cross-build.
|
||||
echo i586-pc-msdosdjgpp
|
||||
exit ;;
|
||||
Intel:Mach:3*:*)
|
||||
echo i386-pc-mach3
|
||||
exit ;;
|
||||
@@ -1139,8 +1111,18 @@ EOF
|
||||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
|
||||
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4; exit; } ;;
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4; exit; } ;;
|
||||
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
|
||||
OS_REL='.3'
|
||||
test -r /etc/.relid \
|
||||
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
|
||||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; }
|
||||
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
|
||||
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
|
||||
echo m68k-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -1153,7 +1135,7 @@ EOF
|
||||
rs6000:LynxOS:2.*:*)
|
||||
echo rs6000-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
|
||||
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
|
||||
echo powerpc-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SM[BE]S:UNIX_SV:*:*)
|
||||
@@ -1173,10 +1155,10 @@ EOF
|
||||
echo ns32k-sni-sysv
|
||||
fi
|
||||
exit ;;
|
||||
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit ;;
|
||||
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit ;;
|
||||
*:UNIX_System_V:4*:FTX*)
|
||||
# From Gerald Hewes <hewes@openmarket.com>.
|
||||
# How about differentiating between stratus architectures? -djm
|
||||
@@ -1202,11 +1184,11 @@ EOF
|
||||
exit ;;
|
||||
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
|
||||
if [ -d /usr/nec ]; then
|
||||
echo mips-nec-sysv${UNAME_RELEASE}
|
||||
echo mips-nec-sysv${UNAME_RELEASE}
|
||||
else
|
||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||
fi
|
||||
exit ;;
|
||||
exit ;;
|
||||
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
|
||||
echo powerpc-be-beos
|
||||
exit ;;
|
||||
@@ -1216,6 +1198,9 @@ EOF
|
||||
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
|
||||
echo i586-pc-beos
|
||||
exit ;;
|
||||
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
|
||||
echo i586-pc-haiku
|
||||
exit ;;
|
||||
SX-4:SUPER-UX:*:*)
|
||||
echo sx4-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -1243,6 +1228,16 @@ EOF
|
||||
*:Darwin:*:*)
|
||||
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
|
||||
case $UNAME_PROCESSOR in
|
||||
i386)
|
||||
eval $set_cc_for_build
|
||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||||
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
then
|
||||
UNAME_PROCESSOR="x86_64"
|
||||
fi
|
||||
fi ;;
|
||||
unknown) UNAME_PROCESSOR=powerpc ;;
|
||||
esac
|
||||
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
|
||||
@@ -1258,6 +1253,9 @@ EOF
|
||||
*:QNX:*:4*)
|
||||
echo i386-pc-qnx
|
||||
exit ;;
|
||||
NEO-?:NONSTOP_KERNEL:*:*)
|
||||
echo neo-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
NSE-?:NONSTOP_KERNEL:*:*)
|
||||
echo nse-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -1303,13 +1301,13 @@ EOF
|
||||
echo pdp10-unknown-its
|
||||
exit ;;
|
||||
SEI:*:*:SEIUX)
|
||||
echo mips-sei-seiux${UNAME_RELEASE}
|
||||
echo mips-sei-seiux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:DragonFly:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||
exit ;;
|
||||
*:*VMS:*:*)
|
||||
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
||||
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
||||
case "${UNAME_MACHINE}" in
|
||||
A*) echo alpha-dec-vms ; exit ;;
|
||||
I*) echo ia64-dec-vms ; exit ;;
|
||||
@@ -1324,6 +1322,12 @@ EOF
|
||||
i*86:rdos:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-rdos
|
||||
exit ;;
|
||||
i*86:AROS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-aros
|
||||
exit ;;
|
||||
x86_64:VMkernel:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-esx
|
||||
exit ;;
|
||||
esac
|
||||
|
||||
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||
@@ -1346,11 +1350,11 @@ main ()
|
||||
#include <sys/param.h>
|
||||
printf ("m68k-sony-newsos%s\n",
|
||||
#ifdef NEWSOS4
|
||||
"4"
|
||||
"4"
|
||||
#else
|
||||
""
|
||||
""
|
||||
#endif
|
||||
); exit (0);
|
||||
); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
269
config.sub
vendored
269
config.sub
vendored
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2008-01-16'
|
||||
timestamp='2012-02-10'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
@@ -21,9 +21,7 @@ timestamp='2008-01-16'
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
@@ -32,13 +30,16 @@ timestamp='2008-01-16'
|
||||
|
||||
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
# diff and a properly formatted GNU ChangeLog entry.
|
||||
#
|
||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||
# Supply the specified configuration type as an argument.
|
||||
# If it is invalid, we print an error message on stderr and exit with code 1.
|
||||
# Otherwise, we print the canonical config type on stdout and succeed.
|
||||
|
||||
# You can get the latest version of this script from:
|
||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
||||
|
||||
# This file is supposed to be the same for all GNU packages
|
||||
# and recognize all the CPU types, system types and aliases
|
||||
# that are meaningful with *any* GNU software.
|
||||
@@ -72,8 +73,9 @@ Report bugs and patches to <config-patches@gnu.org>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -120,12 +122,18 @@ esac
|
||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
|
||||
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
||||
linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||
knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
kopensolaris*-gnu* | \
|
||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
android-linux)
|
||||
os=-linux-android
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
|
||||
;;
|
||||
*)
|
||||
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
|
||||
if [ $basic_machine != $1 ]
|
||||
@@ -148,10 +156,13 @@ case $os in
|
||||
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||
-apple | -axis | -knuth | -cray)
|
||||
-apple | -axis | -knuth | -cray | -microblaze)
|
||||
os=
|
||||
basic_machine=$1
|
||||
;;
|
||||
-bluegene*)
|
||||
os=-cnk
|
||||
;;
|
||||
-sim | -cisco | -oki | -wec | -winbond)
|
||||
os=
|
||||
basic_machine=$1
|
||||
@@ -166,10 +177,10 @@ case $os in
|
||||
os=-chorusos
|
||||
basic_machine=$1
|
||||
;;
|
||||
-chorusrdb)
|
||||
os=-chorusrdb
|
||||
-chorusrdb)
|
||||
os=-chorusrdb
|
||||
basic_machine=$1
|
||||
;;
|
||||
;;
|
||||
-hiux*)
|
||||
os=-hiuxwe2
|
||||
;;
|
||||
@@ -238,24 +249,32 @@ case $basic_machine in
|
||||
# Some are omitted here because they have special meanings below.
|
||||
1750a | 580 \
|
||||
| a29k \
|
||||
| aarch64 | aarch64_be \
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||
| am33_2.0 \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
|
||||
| be32 | be64 \
|
||||
| bfin \
|
||||
| c4x | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| epiphany \
|
||||
| fido | fr30 | frv \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| hexagon \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| le32 | le64 \
|
||||
| lm32 \
|
||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||
| maxq | mb | microblaze | mcore | mep \
|
||||
| maxq | mb | microblaze | mcore | mep | metag \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
| mips64vr | mips64vrel \
|
||||
| mips64octeon | mips64octeonel \
|
||||
| mips64orion | mips64orionel \
|
||||
| mips64r5900 | mips64r5900el \
|
||||
| mips64vr | mips64vrel \
|
||||
| mips64vr4100 | mips64vr4100el \
|
||||
| mips64vr4300 | mips64vr4300el \
|
||||
| mips64vr5000 | mips64vr5000el \
|
||||
@@ -268,29 +287,42 @@ case $basic_machine in
|
||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mn10200 | mn10300 \
|
||||
| moxie \
|
||||
| mt \
|
||||
| msp430 \
|
||||
| nds32 | nds32le | nds32be \
|
||||
| nios | nios2 \
|
||||
| ns16k | ns32k \
|
||||
| open8 \
|
||||
| or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
||||
| pyramid \
|
||||
| rl78 | rx \
|
||||
| score \
|
||||
| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh64 | sh64le \
|
||||
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
|
||||
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
||||
| spu | strongarm \
|
||||
| tahoe | thumb | tic4x | tic80 | tron \
|
||||
| v850 | v850e \
|
||||
| spu \
|
||||
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
|
||||
| ubicom32 \
|
||||
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
|
||||
| we32k \
|
||||
| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
|
||||
| z8k)
|
||||
| x86 | xc16x | xstormy16 | xtensa \
|
||||
| z8k | z80)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12)
|
||||
# Motorola 68HC11/12.
|
||||
c54x)
|
||||
basic_machine=tic54x-unknown
|
||||
;;
|
||||
c55x)
|
||||
basic_machine=tic55x-unknown
|
||||
;;
|
||||
c6x)
|
||||
basic_machine=tic6x-unknown
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-none
|
||||
;;
|
||||
@@ -300,6 +332,21 @@ case $basic_machine in
|
||||
basic_machine=mt-unknown
|
||||
;;
|
||||
|
||||
strongarm | thumb | xscale)
|
||||
basic_machine=arm-unknown
|
||||
;;
|
||||
xgate)
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-none
|
||||
;;
|
||||
xscaleeb)
|
||||
basic_machine=armeb-unknown
|
||||
;;
|
||||
|
||||
xscaleel)
|
||||
basic_machine=armel-unknown
|
||||
;;
|
||||
|
||||
# We use `pc' rather than `unknown'
|
||||
# because (1) that's what they normally are, and
|
||||
# (2) the word "unknown" tends to confuse beginning users.
|
||||
@@ -314,29 +361,36 @@ case $basic_machine in
|
||||
# Recognize the basic CPU types with company name.
|
||||
580-* \
|
||||
| a29k-* \
|
||||
| aarch64-* | aarch64_be-* \
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||
| avr-* | avr32-* \
|
||||
| be32-* | be64-* \
|
||||
| bfin-* | bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
||||
| clipper-* | craynv-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| hexagon-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* | iq2000-* \
|
||||
| le32-* | le64-* \
|
||||
| lm32-* \
|
||||
| m32c-* | m32r-* | m32rle-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
| mips64vr-* | mips64vrel-* \
|
||||
| mips64octeon-* | mips64octeonel-* \
|
||||
| mips64orion-* | mips64orionel-* \
|
||||
| mips64r5900-* | mips64r5900el-* \
|
||||
| mips64vr-* | mips64vrel-* \
|
||||
| mips64vr4100-* | mips64vr4100el-* \
|
||||
| mips64vr4300-* | mips64vr4300el-* \
|
||||
| mips64vr5000-* | mips64vr5000el-* \
|
||||
@@ -351,27 +405,32 @@ case $basic_machine in
|
||||
| mmix-* \
|
||||
| mt-* \
|
||||
| msp430-* \
|
||||
| nds32-* | nds32le-* | nds32be-* \
|
||||
| nios-* | nios2-* \
|
||||
| none-* | np1-* | ns16k-* | ns32k-* \
|
||||
| open8-* \
|
||||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
|
||||
| pyramid-* \
|
||||
| romp-* | rs6000-* \
|
||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||
| rl78-* | romp-* | rs6000-* | rx-* \
|
||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
||||
| sparclite-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
|
||||
| tahoe-* \
|
||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
||||
| tile*-* \
|
||||
| tron-* \
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| ubicom32-* \
|
||||
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
|
||||
| vax-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* \
|
||||
| xstormy16-* | xtensa*-* \
|
||||
| ymp-* \
|
||||
| z8k-*)
|
||||
| z8k-* | z80-*)
|
||||
;;
|
||||
# Recognize the basic CPU types without company name, with glob match.
|
||||
xtensa*)
|
||||
@@ -393,7 +452,7 @@ case $basic_machine in
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
abacus)
|
||||
abacus)
|
||||
basic_machine=abacus-unknown
|
||||
;;
|
||||
adobe68k)
|
||||
@@ -439,6 +498,10 @@ case $basic_machine in
|
||||
basic_machine=m68k-apollo
|
||||
os=-bsd
|
||||
;;
|
||||
aros)
|
||||
basic_machine=i386-pc
|
||||
os=-aros
|
||||
;;
|
||||
aux)
|
||||
basic_machine=m68k-apple
|
||||
os=-aux
|
||||
@@ -455,10 +518,27 @@ case $basic_machine in
|
||||
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
bluegene*)
|
||||
basic_machine=powerpc-ibm
|
||||
os=-cnk
|
||||
;;
|
||||
c54x-*)
|
||||
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c55x-*)
|
||||
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c6x-*)
|
||||
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c90)
|
||||
basic_machine=c90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
cegcc)
|
||||
basic_machine=arm-unknown
|
||||
os=-cegcc
|
||||
;;
|
||||
convex-c1)
|
||||
basic_machine=c1-convex
|
||||
os=-bsd
|
||||
@@ -487,7 +567,7 @@ case $basic_machine in
|
||||
basic_machine=craynv-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
cr16)
|
||||
cr16 | cr16-*)
|
||||
basic_machine=cr16-unknown
|
||||
os=-elf
|
||||
;;
|
||||
@@ -526,6 +606,10 @@ case $basic_machine in
|
||||
basic_machine=m88k-motorola
|
||||
os=-sysv3
|
||||
;;
|
||||
dicos)
|
||||
basic_machine=i686-pc
|
||||
os=-dicos
|
||||
;;
|
||||
djgpp)
|
||||
basic_machine=i586-pc
|
||||
os=-msdosdjgpp
|
||||
@@ -641,7 +725,6 @@ case $basic_machine in
|
||||
i370-ibm* | ibm*)
|
||||
basic_machine=i370-ibm
|
||||
;;
|
||||
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
|
||||
i*86v32)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-sysv32
|
||||
@@ -699,6 +782,9 @@ case $basic_machine in
|
||||
basic_machine=ns32k-utek
|
||||
os=-sysv
|
||||
;;
|
||||
microblaze)
|
||||
basic_machine=microblaze-xilinx
|
||||
;;
|
||||
mingw32)
|
||||
basic_machine=i386-pc
|
||||
os=-mingw32
|
||||
@@ -735,10 +821,18 @@ case $basic_machine in
|
||||
ms1-*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
||||
;;
|
||||
msys)
|
||||
basic_machine=i386-pc
|
||||
os=-msys
|
||||
;;
|
||||
mvs)
|
||||
basic_machine=i370-ibm
|
||||
os=-mvs
|
||||
;;
|
||||
nacl)
|
||||
basic_machine=le32-unknown
|
||||
os=-nacl
|
||||
;;
|
||||
ncr3000)
|
||||
basic_machine=i486-ncr
|
||||
os=-sysv4
|
||||
@@ -803,6 +897,12 @@ case $basic_machine in
|
||||
np1)
|
||||
basic_machine=np1-gould
|
||||
;;
|
||||
neo-tandem)
|
||||
basic_machine=neo-tandem
|
||||
;;
|
||||
nse-tandem)
|
||||
basic_machine=nse-tandem
|
||||
;;
|
||||
nsr-tandem)
|
||||
basic_machine=nsr-tandem
|
||||
;;
|
||||
@@ -885,9 +985,10 @@ case $basic_machine in
|
||||
;;
|
||||
power) basic_machine=power-ibm
|
||||
;;
|
||||
ppc) basic_machine=powerpc-unknown
|
||||
ppc | ppcbe) basic_machine=powerpc-unknown
|
||||
;;
|
||||
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
ppc-* | ppcbe-*)
|
||||
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppcle | powerpclittle | ppc-le | powerpc-little)
|
||||
basic_machine=powerpcle-unknown
|
||||
@@ -981,6 +1082,9 @@ case $basic_machine in
|
||||
basic_machine=i860-stratus
|
||||
os=-sysv4
|
||||
;;
|
||||
strongarm-* | thumb-*)
|
||||
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
sun2)
|
||||
basic_machine=m68000-sun
|
||||
;;
|
||||
@@ -1037,20 +1141,8 @@ case $basic_machine in
|
||||
basic_machine=t90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
tic54x | c54x*)
|
||||
basic_machine=tic54x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic55x | c55x*)
|
||||
basic_machine=tic55x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic6x | c6x*)
|
||||
basic_machine=tic6x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tile*)
|
||||
basic_machine=tile-unknown
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
tx39)
|
||||
@@ -1120,6 +1212,9 @@ case $basic_machine in
|
||||
xps | xps100)
|
||||
basic_machine=xps100-honeywell
|
||||
;;
|
||||
xscale-* | xscalee[bl]-*)
|
||||
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
|
||||
;;
|
||||
ymp)
|
||||
basic_machine=ymp-cray
|
||||
os=-unicos
|
||||
@@ -1128,6 +1223,10 @@ case $basic_machine in
|
||||
basic_machine=z8k-unknown
|
||||
os=-sim
|
||||
;;
|
||||
z80-*-coff)
|
||||
basic_machine=z80-unknown
|
||||
os=-sim
|
||||
;;
|
||||
none)
|
||||
basic_machine=none-none
|
||||
os=-none
|
||||
@@ -1166,7 +1265,7 @@ case $basic_machine in
|
||||
we32k)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
|
||||
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
|
||||
basic_machine=sh-unknown
|
||||
;;
|
||||
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
|
||||
@@ -1213,9 +1312,12 @@ esac
|
||||
if [ x"$os" != x"" ]
|
||||
then
|
||||
case $os in
|
||||
# First match some system type aliases
|
||||
# that might get confused with valid system types.
|
||||
# First match some system type aliases
|
||||
# that might get confused with valid system types.
|
||||
# -solaris* is a basic system type, with this one exception.
|
||||
-auroraux)
|
||||
os=-auroraux
|
||||
;;
|
||||
-solaris1 | -solaris1.*)
|
||||
os=`echo $os | sed -e 's|solaris1|sunos4|'`
|
||||
;;
|
||||
@@ -1236,10 +1338,11 @@ case $os in
|
||||
# Each alternative MUST END IN A *, to match a version number.
|
||||
# -sysv* is not here because it comes later, after sysvr4.
|
||||
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
|
||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
|
||||
| -sym* | -kopensolaris* \
|
||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||
| -aos* \
|
||||
| -aos* | -aros* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||
@@ -1248,9 +1351,10 @@ case $os in
|
||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* \
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
|
||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
||||
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -linux-android* \
|
||||
| -linux-newlib* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||
@@ -1258,7 +1362,7 @@ case $os in
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@@ -1297,7 +1401,7 @@ case $os in
|
||||
-opened*)
|
||||
os=-openedition
|
||||
;;
|
||||
-os400*)
|
||||
-os400*)
|
||||
os=-os400
|
||||
;;
|
||||
-wince*)
|
||||
@@ -1346,7 +1450,7 @@ case $os in
|
||||
-sinix*)
|
||||
os=-sysv4
|
||||
;;
|
||||
-tpf*)
|
||||
-tpf*)
|
||||
os=-tpf
|
||||
;;
|
||||
-triton*)
|
||||
@@ -1388,6 +1492,11 @@ case $os in
|
||||
-zvmoe)
|
||||
os=-zvmoe
|
||||
;;
|
||||
-dicos*)
|
||||
os=-dicos
|
||||
;;
|
||||
-nacl*)
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
@@ -1410,10 +1519,10 @@ else
|
||||
# system, and we'll never get to this point.
|
||||
|
||||
case $basic_machine in
|
||||
score-*)
|
||||
score-*)
|
||||
os=-elf
|
||||
;;
|
||||
spu-*)
|
||||
spu-*)
|
||||
os=-elf
|
||||
;;
|
||||
*-acorn)
|
||||
@@ -1425,8 +1534,17 @@ case $basic_machine in
|
||||
arm*-semi)
|
||||
os=-aout
|
||||
;;
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
tic54x-*)
|
||||
os=-coff
|
||||
;;
|
||||
tic55x-*)
|
||||
os=-coff
|
||||
;;
|
||||
tic6x-*)
|
||||
os=-coff
|
||||
;;
|
||||
# This must come before the *-dec entry.
|
||||
pdp10-*)
|
||||
@@ -1446,14 +1564,11 @@ case $basic_machine in
|
||||
;;
|
||||
m68000-sun)
|
||||
os=-sunos3
|
||||
# This also exists in the configure program, but was not the
|
||||
# default.
|
||||
# os=-sunos4
|
||||
;;
|
||||
m68*-cisco)
|
||||
os=-aout
|
||||
;;
|
||||
mep-*)
|
||||
mep-*)
|
||||
os=-elf
|
||||
;;
|
||||
mips*-cisco)
|
||||
@@ -1480,7 +1595,7 @@ case $basic_machine in
|
||||
*-ibm)
|
||||
os=-aix
|
||||
;;
|
||||
*-knuth)
|
||||
*-knuth)
|
||||
os=-mmixware
|
||||
;;
|
||||
*-wec)
|
||||
@@ -1585,7 +1700,7 @@ case $basic_machine in
|
||||
-sunos*)
|
||||
vendor=sun
|
||||
;;
|
||||
-aix*)
|
||||
-cnk*|-aix*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-beos*)
|
||||
|
24
configure.in
24
configure.in
@@ -160,10 +160,12 @@ AC_FUNC_STRFTIME
|
||||
|
||||
AC_CHECK_FUNCS([ \
|
||||
bind gethostbyaddr gethostbyname gethostname inet_ntoa \
|
||||
setsid setsockopt socket strcasecmp waitpid],,AC_MSG_ERROR([required function missing!]))
|
||||
setsid setsockopt socket strcasecmp waitpid],,
|
||||
AC_MSG_ERROR([required function missing!]))
|
||||
|
||||
AC_CHECK_FUNCS(getaddrinfo getnameinfo inet_aton sigaction sigprocmask snprintf \
|
||||
vsnprintf strdup strlcpy strlcat strtok_r)
|
||||
AC_CHECK_FUNCS([ \
|
||||
gai_strerror getaddrinfo getnameinfo inet_aton sigaction \
|
||||
sigprocmask snprintf vsnprintf strdup strlcpy strlcat strtok_r])
|
||||
|
||||
# -- Configuration options --
|
||||
|
||||
@@ -250,13 +252,21 @@ AC_ARG_WITH(poll,
|
||||
CPPFLAGS="-I$withval/include $CPPFLAGS"
|
||||
LDFLAGS="-L$withval/lib $LDFLAGS"
|
||||
fi
|
||||
AC_CHECK_FUNCS(poll, x_io_backend=poll\(\),
|
||||
AC_CHECK_FUNCS(poll, [
|
||||
AC_CHECK_HEADERS(poll.h,
|
||||
x_io_backend=poll\(\),
|
||||
AC_MSG_ERROR(
|
||||
[Can't enable poll IO support!])
|
||||
)
|
||||
], [
|
||||
AC_MSG_ERROR([Can't enable poll IO support!])
|
||||
)
|
||||
])
|
||||
fi
|
||||
],
|
||||
[
|
||||
AC_CHECK_FUNCS(poll, x_io_backend=poll\(\))
|
||||
AC_CHECK_FUNCS(poll, [
|
||||
AC_CHECK_HEADERS(poll.h, x_io_backend=poll\(\))
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
@@ -330,7 +340,7 @@ else
|
||||
fi
|
||||
|
||||
if test "$x_io_backend" = "none"; then
|
||||
AC_MSG_ERROR([No useabe IO API activated/found!?])
|
||||
AC_MSG_ERROR([No useable IO API activated/found!?])
|
||||
fi
|
||||
|
||||
# use SSL?
|
||||
|
@@ -0,0 +1,128 @@
|
||||
From d8eddbeaadc7d161865b5342d59748b80266533c Mon Sep 17 00:00:00 2001
|
||||
From: DukePyrolator <DukePyrolator@anope.org>
|
||||
Date: Mon, 22 Aug 2011 14:53:37 +0200
|
||||
Subject: [PATCH 03/16] Update ngIRCd protocol module for current Anope 1.9
|
||||
GIT
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 37 ++++++++++++++++++-------------------
|
||||
1 files changed, 18 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index e546d05..790b8f4 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
#include "services.h"
|
||||
#include "modules.h"
|
||||
+#include "nickserv.h"
|
||||
+#include "oper.h"
|
||||
|
||||
IRCDVar myIrcd[] = {
|
||||
{"ngIRCd", /* ircd name */
|
||||
@@ -45,14 +47,7 @@ class ngIRCdProto : public IRCDProto
|
||||
{
|
||||
void SendAkill(User *u, const XLine *x)
|
||||
{
|
||||
- if (SGLine && u == NULL)
|
||||
- for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end();)
|
||||
- {
|
||||
- u = it->second;
|
||||
- ++it;
|
||||
- if (SGLine->Check(u) != NULL)
|
||||
- break;
|
||||
- }
|
||||
+ // TODO: ADD SOME CODE
|
||||
}
|
||||
|
||||
void SendAkillDel(const XLine*) { }
|
||||
@@ -62,13 +57,16 @@ class ngIRCdProto : public IRCDProto
|
||||
send_cmd(source ? source->nick : Config->ServerName, "WALLOPS :%s", buf.c_str());
|
||||
}
|
||||
|
||||
- void SendJoin(BotInfo *user, Channel *c, const ChannelStatus *status)
|
||||
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status)
|
||||
{
|
||||
send_cmd(user->nick, "JOIN %s", c->name.c_str());
|
||||
if (status)
|
||||
+ {
|
||||
+ BotInfo *setter = findbot(user->nick);
|
||||
for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
|
||||
if (status->HasFlag(ModeManager::ChannelModes[i]->Name))
|
||||
- c->SetMode(user, ModeManager::ChannelModes[i], user->nick, false);
|
||||
+ c->SetMode(setter, ModeManager::ChannelModes[i], user->nick, false);
|
||||
+ }
|
||||
}
|
||||
|
||||
void SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf)
|
||||
@@ -84,7 +82,7 @@ class ngIRCdProto : public IRCDProto
|
||||
|
||||
void SendConnect()
|
||||
{
|
||||
- send_cmd("", "PASS %s 0210-IRC+ Anope|%s:CLHSo P", uplink_server->password.c_str(), Anope::VersionShort().c_str());
|
||||
+ send_cmd("", "PASS %s 0210-IRC+ Anope|%s:CLHSo P", Config->Uplinks[CurrentUplink]->password.c_str(), Anope::VersionShort().c_str());
|
||||
/* Make myself known to myself in the serverlist */
|
||||
SendServer(Me);
|
||||
/* finish the enhanced server handshake and register the connection */
|
||||
@@ -92,9 +90,11 @@ class ngIRCdProto : public IRCDProto
|
||||
}
|
||||
|
||||
// Received: :dev.anope.de NICK DukeP 1 ~DukePyro p57ABF9C9.dip.t-dialin.net 1 +i :DukePyrolator
|
||||
- void SendClientIntroduction(const User *u, const Anope::string &modes)
|
||||
+ void SendClientIntroduction(const User *u)
|
||||
{
|
||||
- EnforceQlinedNick(u->nick, "");
|
||||
+ Anope::string modes = "+" + u->GetModes();
|
||||
+ XLine x(u->nick, "Reserved for services");
|
||||
+ ircdproto->SendSQLine(NULL, &x);
|
||||
send_cmd(Config->ServerName, "NICK %s 1 %s %s 1 %s :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), modes.c_str(), u->realname.c_str());
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ class ngIRCdProto : public IRCDProto
|
||||
|
||||
void SendNoticeChanopsInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf)
|
||||
{
|
||||
- send_cmd(source ? source->nick : Config->s_ChanServ, "NOTICE @%s :%s", dest->name.c_str(), buf.c_str());
|
||||
+ send_cmd(source->nick, "NOTICE @%s :%s", dest->name.c_str(), buf.c_str());
|
||||
}
|
||||
|
||||
/* INVITE */
|
||||
@@ -196,8 +196,8 @@ class ngIRCdIRCdMessage : public IRCdMessage
|
||||
{
|
||||
// a new user is connecting to the network
|
||||
User *user = do_nick("", params[0], params[2], params[3], source, params[6], Anope::CurTime, "", "", "", params[5]);
|
||||
- if (user)
|
||||
- validate_user(user);
|
||||
+ if (user && nickserv)
|
||||
+ nickserv->Validate(user);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -433,7 +433,7 @@ class ProtongIRCd : public Module
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
|
||||
|
||||
/* b/e/I */
|
||||
- ModeManager::AddChannelMode(new ChannelModeBan(CMODE_BAN, 'b'));
|
||||
+ ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b'));
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
|
||||
|
||||
/* v/h/o/a/q */
|
||||
@@ -454,13 +454,12 @@ class ProtongIRCd : public Module
|
||||
}
|
||||
|
||||
public:
|
||||
- ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator),
|
||||
+ ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL),
|
||||
message_kick("KICK", event_kick), message_pass("PASS", event_pass),
|
||||
message_njoin("NJOIN", event_njoin), message_chaninfo("CHANINFO", event_chaninfo),
|
||||
message_005("005", event_005), message_442("442", event_442), message_376("376", event_376)
|
||||
{
|
||||
this->SetAuthor("Anope");
|
||||
- this->SetType(PROTOCOL);
|
||||
|
||||
Capab.SetFlag(CAPAB_QS);
|
||||
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -0,0 +1,93 @@
|
||||
From 88b2b14a76b8ee053b1f6ea64139350260590043 Mon Sep 17 00:00:00 2001
|
||||
From: DukePyrolator <DukePyrolator@anope.org>
|
||||
Date: Mon, 22 Aug 2011 14:55:07 +0200
|
||||
Subject: [PATCH 04/16] ngircd: Do PING-PONG on server burst to "sync servers"
|
||||
|
||||
Imagine we had three servers, A, B & C linked like so: A<->B<->C:
|
||||
|
||||
If Anope is linked to A and B splits from A and then reconnects B
|
||||
introduces itself, introduces C, sends EOS for C, introduces B's clients
|
||||
introduces C's clients, sends EOS for B. This causes all of C's clients
|
||||
to be introduced with their server "not syncing".
|
||||
|
||||
We now send a PING immediately when receiving a new server and then
|
||||
finish sync once we get a pong back from that server.
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 28 ++++++++++++++++++++++++++--
|
||||
1 files changed, 26 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 790b8f4..89aecfd 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -108,11 +108,13 @@ class ngIRCdProto : public IRCDProto
|
||||
|
||||
void SendModeInternal(const BotInfo *bi, const Channel *dest, const Anope::string &buf)
|
||||
{
|
||||
+Log(LOG_DEBUG) << "SendModeInternal 1";
|
||||
send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", dest->name.c_str(), buf.c_str());
|
||||
}
|
||||
|
||||
void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf)
|
||||
{
|
||||
+Log(LOG_DEBUG) << "SendModeInternal 2";
|
||||
send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", u->nick.c_str(), buf.c_str());
|
||||
}
|
||||
|
||||
@@ -212,6 +214,8 @@ class ngIRCdIRCdMessage : public IRCdMessage
|
||||
do_server("", params[0], 0, params[2], params[1]);
|
||||
else
|
||||
do_server(source, params[0], params[1].is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0, params[3], params[2]);
|
||||
+
|
||||
+ ircdproto->SendPing(Config->ServerName, params[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -253,6 +257,25 @@ class ngIRCdIRCdMessage : public IRCdMessage
|
||||
}
|
||||
};
|
||||
|
||||
+/** This is here because:
|
||||
+ *
|
||||
+ * If we had three servers, A, B & C linked like so: A<->B<->C
|
||||
+ * If Anope is linked to A and B splits from A and then reconnects
|
||||
+ * B introduces itself, introduces C, sends EOS for C, introduces Bs clients
|
||||
+ * introduces Cs clients, sends EOS for B. This causes all of Cs clients to be introduced
|
||||
+ * with their server "not syncing". We now send a PING immediately when receiving a new server
|
||||
+ * and then finish sync once we get a pong back from that server.
|
||||
+ */
|
||||
+bool event_pong(const Anope::string &source, const std::vector<Anope::string> ¶ms)
|
||||
+{
|
||||
+ Server *s = Server::Find(source);
|
||||
+ if (s && !s->IsSynced())
|
||||
+ s->Sync(false);
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
/*
|
||||
* CHANINFO <chan> +<modes>
|
||||
* CHANINFO <chan> +<modes> :<topic>
|
||||
@@ -416,7 +439,7 @@ bool event_376(const Anope::string &source, const std::vector<Anope::string> &pa
|
||||
class ProtongIRCd : public Module
|
||||
{
|
||||
Message message_kick, message_pass, message_njoin, message_chaninfo, message_005,
|
||||
- message_442, message_376;
|
||||
+ message_442, message_376, message_pong;
|
||||
|
||||
ngIRCdProto ircd_proto;
|
||||
ngIRCdIRCdMessage ircd_message;
|
||||
@@ -457,7 +480,8 @@ class ProtongIRCd : public Module
|
||||
ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL),
|
||||
message_kick("KICK", event_kick), message_pass("PASS", event_pass),
|
||||
message_njoin("NJOIN", event_njoin), message_chaninfo("CHANINFO", event_chaninfo),
|
||||
- message_005("005", event_005), message_442("442", event_442), message_376("376", event_376)
|
||||
+ message_005("005", event_005), message_442("442", event_442), message_376("376", event_376),
|
||||
+ message_pong("PONG", event_pong)
|
||||
{
|
||||
this->SetAuthor("Anope");
|
||||
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -0,0 +1,29 @@
|
||||
From 0d83f8f9ca0de651d664eca6f467f36df0417f7d Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Mon, 22 Aug 2011 14:59:49 +0200
|
||||
Subject: [PATCH 05/16] ngircd: always prefix modes in CHANINFO with "+"
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 6 ++----
|
||||
1 files changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 89aecfd..3e5beb3 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -139,10 +139,8 @@ Log(LOG_DEBUG) << "SendModeInternal 2";
|
||||
|
||||
void SendChannel(Channel *c)
|
||||
{
|
||||
- Anope::string mlock_modes = get_mlock_modes(c->ci, true);
|
||||
- if (mlock_modes.empty())
|
||||
- mlock_modes = "+";
|
||||
- send_cmd(Config->ServerName, "CHANINFO %s %s", c->name.c_str(), mlock_modes.c_str());
|
||||
+ Anope::string modes = c->GetModes(true, true);
|
||||
+ send_cmd(Config->ServerName, "CHANINFO %s +%s", c->name.c_str(), modes.c_str());
|
||||
}
|
||||
void SendTopic(BotInfo *bi, Channel *c)
|
||||
{
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -0,0 +1,47 @@
|
||||
From 1914a36b83b1fc6b4678ef261a1a06eefab9a0ca Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Fri, 26 Aug 2011 17:51:37 +0200
|
||||
Subject: [PATCH 06/16] ngircd: support user mode "R" and channel mode "R"
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 7 ++++---
|
||||
1 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 3e5beb3..7f4186e 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -449,26 +449,27 @@ class ProtongIRCd : public Module
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i'));
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o'));
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_RESTRICTED, 'r'));
|
||||
+ ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'R'));
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's'));
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
|
||||
|
||||
- /* b/e/I */
|
||||
+ /* Add modes for ban and invite lists */
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b'));
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
|
||||
|
||||
- /* v/h/o/a/q */
|
||||
+ /* Add channel user modes */
|
||||
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
|
||||
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
|
||||
|
||||
/* Add channel modes */
|
||||
- // channel modes: biIklmnoPstvz
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
|
||||
ModeManager::AddChannelMode(new ChannelModeKey('k'));
|
||||
ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P'));
|
||||
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z'));
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -0,0 +1,96 @@
|
||||
From 4c9300ede35310ee5642f34e5ac227bd96fc7384 Mon Sep 17 00:00:00 2001
|
||||
From: DukePyrolator <DukePyrolator@anope.org>
|
||||
Date: Sun, 4 Sep 2011 15:08:55 +0200
|
||||
Subject: [PATCH 07/16] ngircd: Fix handling of JOIN commands
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 60 +++++++++++++++++++++++++++++++++++++++---
|
||||
1 files changed, 55 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 7f4186e..3024fdd 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -240,16 +240,58 @@ class ngIRCdIRCdMessage : public IRCdMessage
|
||||
{
|
||||
if (!params.empty())
|
||||
{
|
||||
+ Anope::string channel, mode;
|
||||
size_t pos = params[0].find('\7');
|
||||
if (pos != Anope::string::npos)
|
||||
{
|
||||
- Anope::string channel = params[0].substr(0, pos);
|
||||
- Anope::string mode = '+' + params[0].substr(pos, params[0].length()) + " " + source;
|
||||
- do_join(source, channel, "");
|
||||
- do_cmode(source, channel, mode, "");
|
||||
+ channel = params[0].substr(0, pos);
|
||||
+ mode = '+' + params[0].substr(pos+1, params[0].length()) + " " + source;
|
||||
}
|
||||
else
|
||||
- do_join(source, params[0], "");
|
||||
+ channel = params[0];
|
||||
+
|
||||
+ Channel *c = findchan(channel);
|
||||
+
|
||||
+ if (!c)
|
||||
+ {
|
||||
+ c = new Channel(channel, Anope::CurTime);
|
||||
+ c->SetFlag(CH_SYNCING);
|
||||
+ }
|
||||
+
|
||||
+ User *u = finduser(source);
|
||||
+
|
||||
+ if (!u)
|
||||
+ {
|
||||
+ Log(LOG_DEBUG) << "JOIN for nonexistant user " << source << " on " << channel;
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ EventReturn MOD_RESULT;
|
||||
+ FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c));
|
||||
+
|
||||
+ /* Add the user to the channel */
|
||||
+ c->JoinUser(u);
|
||||
+
|
||||
+ /* set the usermodes to the channel */
|
||||
+ do_cmode(source, channel, mode, "");
|
||||
+
|
||||
+ /* Now set whatever modes this user is allowed to have on the channel */
|
||||
+ chan_set_correct_modes(u, c, 1);
|
||||
+
|
||||
+ /* Check to see if modules want the user to join, if they do
|
||||
+ * check to see if they are allowed to join (CheckKick will kick/ban them)
|
||||
+ * Don't trigger OnJoinChannel event then as the user will be destroyed
|
||||
+ */
|
||||
+ if (MOD_RESULT != EVENT_STOP && c->ci && c->ci->CheckKick(u))
|
||||
+ return false;
|
||||
+
|
||||
+ FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c));
|
||||
+
|
||||
+ if (c->HasFlag(CH_SYNCING))
|
||||
+ {
|
||||
+ c->UnsetFlag(CH_SYNCING);
|
||||
+ c->Sync();
|
||||
+ }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -491,7 +533,15 @@ class ProtongIRCd : public Module
|
||||
pmodule_ircd_message(&this->ircd_message);
|
||||
|
||||
this->AddModes();
|
||||
+
|
||||
+ ModuleManager::Attach(I_OnUserNickChange, this);
|
||||
}
|
||||
+
|
||||
+ void OnUserNickChange(User *u, const Anope::string &)
|
||||
+ {
|
||||
+ u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED));
|
||||
+ }
|
||||
+
|
||||
};
|
||||
|
||||
MODULE_INIT(ProtongIRCd)
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -0,0 +1,38 @@
|
||||
From d363ebd841ea7e1db3c62730023759d69520e0d8 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Tue, 27 Sep 2011 15:08:09 +0200
|
||||
Subject: [PATCH 08/16] ngircd: Allow setting modes by clients on burst
|
||||
|
||||
This change is required by commit 43201ead9575a for the ngIRCd protocol
|
||||
module as well.
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 7 +++++--
|
||||
1 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 3024fdd..2774168 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -57,14 +57,17 @@ class ngIRCdProto : public IRCDProto
|
||||
send_cmd(source ? source->nick : Config->ServerName, "WALLOPS :%s", buf.c_str());
|
||||
}
|
||||
|
||||
- void SendJoin(User *user, Channel *c, const ChannelStatus *status)
|
||||
+ void SendJoin(User *user, Channel *c, ChannelStatus *status)
|
||||
{
|
||||
send_cmd(user->nick, "JOIN %s", c->name.c_str());
|
||||
if (status)
|
||||
{
|
||||
+ ChannelStatus cs = *status;
|
||||
+ status->ClearFlags();
|
||||
+
|
||||
BotInfo *setter = findbot(user->nick);
|
||||
for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
|
||||
- if (status->HasFlag(ModeManager::ChannelModes[i]->Name))
|
||||
+ if (cs.HasFlag(ModeManager::ChannelModes[i]->Name))
|
||||
c->SetMode(setter, ModeManager::ChannelModes[i], user->nick, false);
|
||||
}
|
||||
}
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -0,0 +1,143 @@
|
||||
From e74a5303f2357f4a9915bb91038a2e326323db3c Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Fri, 25 Nov 2011 19:16:37 +0100
|
||||
Subject: [PATCH 09/16] ngircd: Update protocol module for current Anope 1.9
|
||||
GIT
|
||||
|
||||
This changes are rquired by:
|
||||
|
||||
- b14f5ea88: Fixed accidentally clearing botmodes when joins are sent
|
||||
- cef3eb78d: Remove send_cmd and replace it with a stringstream
|
||||
- ddc3c2f38: Added options:nonicknameownership config option
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 54 ++++++++++++++++++++++--------------------
|
||||
1 files changed, 28 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 2774168..55cb8d7 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -54,16 +54,22 @@ class ngIRCdProto : public IRCDProto
|
||||
|
||||
void SendGlobopsInternal(const BotInfo *source, const Anope::string &buf)
|
||||
{
|
||||
- send_cmd(source ? source->nick : Config->ServerName, "WALLOPS :%s", buf.c_str());
|
||||
+ UplinkSocket::Message(source ? source->nick : Config->ServerName) << "WALLOPS :" << buf;
|
||||
}
|
||||
|
||||
- void SendJoin(User *user, Channel *c, ChannelStatus *status)
|
||||
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status)
|
||||
{
|
||||
- send_cmd(user->nick, "JOIN %s", c->name.c_str());
|
||||
+ UplinkSocket::Message(user->nick) << "JOIN " << c->name;
|
||||
if (status)
|
||||
{
|
||||
+ /* First save the channel status incase uc->Status == status */
|
||||
ChannelStatus cs = *status;
|
||||
- status->ClearFlags();
|
||||
+ /* If the user is internally on the channel with flags, kill them so that
|
||||
+ * the stacker will allow this.
|
||||
+ */
|
||||
+ UserContainer *uc = c->FindUser(user);
|
||||
+ if (uc != NULL)
|
||||
+ uc->Status->ClearFlags();
|
||||
|
||||
BotInfo *setter = findbot(user->nick);
|
||||
for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
|
||||
@@ -74,18 +80,18 @@ class ngIRCdProto : public IRCDProto
|
||||
|
||||
void SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf)
|
||||
{
|
||||
- send_cmd(source ? source->nick : Config->ServerName, "KILL %s :%s", user->nick.c_str(), buf.c_str());
|
||||
+ UplinkSocket::Message(source ? source->nick : Config->ServerName) << "KILL " << user->nick << " :" << buf;
|
||||
}
|
||||
|
||||
/* SERVER name hop descript */
|
||||
void SendServer(const Server *server)
|
||||
{
|
||||
- send_cmd("", "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str());
|
||||
+ UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :" << server->GetDescription();
|
||||
}
|
||||
|
||||
void SendConnect()
|
||||
{
|
||||
- send_cmd("", "PASS %s 0210-IRC+ Anope|%s:CLHSo P", Config->Uplinks[CurrentUplink]->password.c_str(), Anope::VersionShort().c_str());
|
||||
+ UplinkSocket::Message() << "PASS " << Config->Uplinks[CurrentUplink]->password << " 0210-IRC+ Anope|" << Anope::VersionShort() << ":CLHSo P";
|
||||
/* Make myself known to myself in the serverlist */
|
||||
SendServer(Me);
|
||||
/* finish the enhanced server handshake and register the connection */
|
||||
@@ -98,56 +104,52 @@ class ngIRCdProto : public IRCDProto
|
||||
Anope::string modes = "+" + u->GetModes();
|
||||
XLine x(u->nick, "Reserved for services");
|
||||
ircdproto->SendSQLine(NULL, &x);
|
||||
- send_cmd(Config->ServerName, "NICK %s 1 %s %s 1 %s :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), modes.c_str(), u->realname.c_str());
|
||||
+ UplinkSocket::Message(Config->ServerName) << "NICK " << u->nick << " 1 " << u->GetIdent() << " " << u->host << " 1 " << modes << " :" << u->realname;
|
||||
}
|
||||
|
||||
void SendPartInternal(const BotInfo *bi, const Channel *chan, const Anope::string &buf)
|
||||
{
|
||||
if (!buf.empty())
|
||||
- send_cmd(bi->nick, "PART %s :%s", chan->name.c_str(), buf.c_str());
|
||||
+ UplinkSocket::Message(bi->nick) << "PART " << chan->name << " :" << buf;
|
||||
else
|
||||
- send_cmd(bi->nick, "PART %s", chan->name.c_str());
|
||||
+ UplinkSocket::Message(bi->nick) << "PART " << chan->name;
|
||||
}
|
||||
|
||||
void SendModeInternal(const BotInfo *bi, const Channel *dest, const Anope::string &buf)
|
||||
{
|
||||
-Log(LOG_DEBUG) << "SendModeInternal 1";
|
||||
- send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", dest->name.c_str(), buf.c_str());
|
||||
+ UplinkSocket::Message(bi ? bi->nick : Config->ServerName) << "MODE " << dest->name << " " << buf;
|
||||
}
|
||||
|
||||
void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf)
|
||||
{
|
||||
-Log(LOG_DEBUG) << "SendModeInternal 2";
|
||||
- send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", u->nick.c_str(), buf.c_str());
|
||||
+ UplinkSocket::Message(bi ? bi->nick : Config->ServerName) << "MODE " << u->nick << " " << buf;
|
||||
}
|
||||
|
||||
void SendKickInternal(const BotInfo *bi, const Channel *chan, const User *user, const Anope::string &buf)
|
||||
{
|
||||
if (!buf.empty())
|
||||
- send_cmd(bi->nick, "KICK %s %s :%s", chan->name.c_str(), user->nick.c_str(), buf.c_str());
|
||||
+ UplinkSocket::Message(bi->nick) << "KICK " << chan->name << " " << user->nick << " :" << buf;
|
||||
else
|
||||
- send_cmd(bi->nick, "KICK %s %s", chan->name.c_str(), user->nick.c_str());
|
||||
+ UplinkSocket::Message(bi->nick) << "KICK " << chan->name << " " << user->nick;
|
||||
}
|
||||
|
||||
- void SendNoticeChanopsInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf)
|
||||
+ void SendChannel(Channel *c)
|
||||
{
|
||||
- send_cmd(source->nick, "NOTICE @%s :%s", dest->name.c_str(), buf.c_str());
|
||||
+ Anope::string modes = c->GetModes(true, true);
|
||||
+ UplinkSocket::Message(Config->ServerName) << "CHANINFO " << c->name << " +" << modes;
|
||||
}
|
||||
|
||||
- /* INVITE */
|
||||
- void SendInvite(BotInfo *source, const Anope::string &chan, const Anope::string &nick)
|
||||
+ void SendTopic(BotInfo *bi, Channel *c)
|
||||
{
|
||||
- send_cmd(source->nick, "INVITE %s %s", nick.c_str(), chan.c_str());
|
||||
+ UplinkSocket::Message(bi->nick) << "TOPIC " << c->name << " :" << c->topic;
|
||||
}
|
||||
|
||||
- void SendChannel(Channel *c)
|
||||
+ void SendLogin(User *u)
|
||||
{
|
||||
- Anope::string modes = c->GetModes(true, true);
|
||||
- send_cmd(Config->ServerName, "CHANINFO %s +%s", c->name.c_str(), modes.c_str());
|
||||
}
|
||||
- void SendTopic(BotInfo *bi, Channel *c)
|
||||
+
|
||||
+ void SendLogout(User *u)
|
||||
{
|
||||
- send_cmd(bi->nick, "TOPIC %s :%s", c->name.c_str(), c->topic.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
--
|
||||
1.7.8.3
|
||||
|
57
contrib/Anope/0010-ngircd-Add-ProtongIRCd.patch
Normal file
57
contrib/Anope/0010-ngircd-Add-ProtongIRCd.patch
Normal file
@@ -0,0 +1,57 @@
|
||||
From d2c45d7c578ec684d3b471020f631847316de196 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Fri, 25 Nov 2011 19:17:19 +0100
|
||||
Subject: [PATCH 10/16] ngircd: Add ~ProtongIRCd()
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 13 ++++++++-----
|
||||
1 files changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 55cb8d7..5fd62db 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -302,8 +302,7 @@ class ngIRCdIRCdMessage : public IRCdMessage
|
||||
}
|
||||
};
|
||||
|
||||
-/** This is here because:
|
||||
- *
|
||||
+/*
|
||||
* If we had three servers, A, B & C linked like so: A<->B<->C
|
||||
* If Anope is linked to A and B splits from A and then reconnects
|
||||
* B introduces itself, introduces C, sends EOS for C, introduces Bs clients
|
||||
@@ -319,8 +318,6 @@ bool event_pong(const Anope::string &source, const std::vector<Anope::string> &p
|
||||
return true;
|
||||
}
|
||||
|
||||
-
|
||||
-
|
||||
/*
|
||||
* CHANINFO <chan> +<modes>
|
||||
* CHANINFO <chan> +<modes> :<topic>
|
||||
@@ -480,7 +477,6 @@ bool event_376(const Anope::string &source, const std::vector<Anope::string> &pa
|
||||
return true;
|
||||
}
|
||||
|
||||
-
|
||||
class ProtongIRCd : public Module
|
||||
{
|
||||
Message message_kick, message_pass, message_njoin, message_chaninfo, message_005,
|
||||
@@ -542,6 +538,13 @@ class ProtongIRCd : public Module
|
||||
ModuleManager::Attach(I_OnUserNickChange, this);
|
||||
}
|
||||
|
||||
+ ~ProtongIRCd()
|
||||
+ {
|
||||
+ pmodule_ircd_var(NULL);
|
||||
+ pmodule_ircd_proto(NULL);
|
||||
+ pmodule_ircd_message(NULL);
|
||||
+ }
|
||||
+
|
||||
void OnUserNickChange(User *u, const Anope::string &)
|
||||
{
|
||||
u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED));
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -0,0 +1,29 @@
|
||||
From 4dc5a3d3e2fbb218461d9459bff1c0a392a75881 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Sat, 31 Dec 2011 16:12:52 +0100
|
||||
Subject: [PATCH 11/16] ngircd: Update protocol module for current Anope 1.9
|
||||
GIT
|
||||
|
||||
This changes are rquired by:
|
||||
|
||||
- 150831c1a: Made capab management a bit simplier
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 5fd62db..9c26ec8 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -527,7 +527,7 @@ class ProtongIRCd : public Module
|
||||
{
|
||||
this->SetAuthor("Anope");
|
||||
|
||||
- Capab.SetFlag(CAPAB_QS);
|
||||
+ Capab.insert("QS");
|
||||
|
||||
pmodule_ircd_var(myIrcd);
|
||||
pmodule_ircd_proto(&this->ircd_proto);
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -0,0 +1,25 @@
|
||||
From 99c18cafdee28bfb17fad5f0526b3ed5d1f5f312 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Sat, 31 Dec 2011 16:17:50 +0100
|
||||
Subject: [PATCH 12/16] ngircd: let Anope know that channel mode "r" is
|
||||
supported
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 9c26ec8..6155667 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -512,6 +512,7 @@ class ProtongIRCd : public Module
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P'));
|
||||
+ ModeManager::AddChannelMode(new ChannelModeRegistered('r'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
|
||||
--
|
||||
1.7.8.3
|
||||
|
28
contrib/Anope/0013-ngircd-Update-copyright-notice.patch
Normal file
28
contrib/Anope/0013-ngircd-Update-copyright-notice.patch
Normal file
@@ -0,0 +1,28 @@
|
||||
From 5a19b69f0daceb5b12ec751bc919519a7f712f2d Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Sun, 15 Jan 2012 13:36:14 +0100
|
||||
Subject: [PATCH 13/16] ngircd: Update copyright notice
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 7 ++++---
|
||||
1 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 6155667..024c61d 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -1,7 +1,8 @@
|
||||
-/* ngIRCd IRCD functions
|
||||
+/*
|
||||
+ * ngIRCd Protocol module for Anope IRC Services
|
||||
*
|
||||
- * (C) 2003-2011 Anope Team
|
||||
- * Contact us at team@anope.org
|
||||
+ * (C) 2011-2012 Alexander Barton <alex@barton.de>
|
||||
+ * (C) 2011 Anope Team <team@anope.org>
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -0,0 +1,35 @@
|
||||
From acc24a7f4488f6ef0fb240a76766db4220b62d53 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Sun, 22 Jan 2012 19:05:28 +0100
|
||||
Subject: [PATCH 14/16] ngircd: set/unset GLINE's on AKILL commands
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 10 ++++++++--
|
||||
1 files changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 024c61d..3bc3812 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -48,10 +48,16 @@ class ngIRCdProto : public IRCDProto
|
||||
{
|
||||
void SendAkill(User *u, const XLine *x)
|
||||
{
|
||||
- // TODO: ADD SOME CODE
|
||||
+ // Calculate the time left before this would expire, capping it at 2 days
|
||||
+ time_t timeleft = x->Expires - Anope::CurTime;
|
||||
+ if (timeleft > 172800 || !x->Expires)
|
||||
+ timeleft = 172800;
|
||||
+ UplinkSocket::Message(Config->ServerName) << "GLINE " << x->Mask << " " << timeleft << " :" << x->Reason << " (" << x->By << ")";
|
||||
}
|
||||
|
||||
- void SendAkillDel(const XLine*) { }
|
||||
+ void SendAkillDel(const XLine *x) {
|
||||
+ UplinkSocket::Message(Config->ServerName) << "GLINE " << x->Mask;
|
||||
+ }
|
||||
|
||||
void SendGlobopsInternal(const BotInfo *source, const Anope::string &buf)
|
||||
{
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -0,0 +1,27 @@
|
||||
From 3a61b190db79848d4519296432ebb2ab714c42b7 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Sun, 22 Jan 2012 19:06:34 +0100
|
||||
Subject: [PATCH 15/16] ngircd: ngIRCd supports channel mode 'e' now
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 3 ++-
|
||||
1 files changed, 2 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 3bc3812..0f87cbd 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -504,8 +504,9 @@ class ProtongIRCd : public Module
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
|
||||
|
||||
- /* Add modes for ban and invite lists */
|
||||
+ /* Add modes for ban, exception, and invite lists */
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b'));
|
||||
+ ModeManager::AddChannelMode(new ChannelModeList(CMODE_EXCEPT, 'e'));
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
|
||||
|
||||
/* Add channel user modes */
|
||||
--
|
||||
1.7.8.3
|
||||
|
35
contrib/Anope/0016-ngircd-support-SQUERY-command.patch
Normal file
35
contrib/Anope/0016-ngircd-support-SQUERY-command.patch
Normal file
@@ -0,0 +1,35 @@
|
||||
From a7c48fcf47af757cf1b4eeaa6bcc96f4ae1f7410 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Sat, 4 Feb 2012 11:13:36 +0100
|
||||
Subject: [PATCH 16/16] ngircd: support SQUERY command
|
||||
|
||||
Thanks to DukePyrolator for explaining these changes to me.
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 0f87cbd..530686e 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -487,7 +487,7 @@ bool event_376(const Anope::string &source, const std::vector<Anope::string> &pa
|
||||
class ProtongIRCd : public Module
|
||||
{
|
||||
Message message_kick, message_pass, message_njoin, message_chaninfo, message_005,
|
||||
- message_442, message_376, message_pong;
|
||||
+ message_442, message_376, message_pong, message_squery;
|
||||
|
||||
ngIRCdProto ircd_proto;
|
||||
ngIRCdIRCdMessage ircd_message;
|
||||
@@ -532,7 +532,7 @@ class ProtongIRCd : public Module
|
||||
message_kick("KICK", event_kick), message_pass("PASS", event_pass),
|
||||
message_njoin("NJOIN", event_njoin), message_chaninfo("CHANINFO", event_chaninfo),
|
||||
message_005("005", event_005), message_442("442", event_442), message_376("376", event_376),
|
||||
- message_pong("PONG", event_pong)
|
||||
+ message_pong("PONG", event_pong), message_squery("SQUERY", ::OnPrivmsg)
|
||||
{
|
||||
this->SetAuthor("Anope");
|
||||
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -2,7 +2,7 @@
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2011 Alexander Barton and Contributors.
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
@@ -11,22 +11,21 @@
|
||||
|
||||
This directory contains two preliminary patches that (re-) add a ngIRCd
|
||||
protocol module to the Anope 1.9 development branch. It has been tested
|
||||
with Anope 1.9.4, there is no guarantee that it will work with other
|
||||
with Anope 1.9.6, there is no guarantee that it will work with other
|
||||
versions as Anope 1.9.x is under heavy development ...
|
||||
|
||||
To build this Anope protocol module, you have to
|
||||
|
||||
- Download the Anope 1.9.x sources (tested with 1.9.4),
|
||||
- Download the Anope 1.9.x sources (only tested with 1.9.6!),
|
||||
- Patch in the ngIRCd protocol module,
|
||||
- Build and install Anope as usual,
|
||||
- Configure Anope as usual, use "ngircd" as protocol module.
|
||||
|
||||
So the command sequence can be something like this:
|
||||
|
||||
$ tar xzf anope-1.9.4-source.tar.gz
|
||||
$ cd anope-1.9.4-source
|
||||
$ patch -p1 < .../ngircd/contrib/Anope/0001-Revert-Removed-ngircd.patch
|
||||
$ patch -p1 < .../ngircd/contrib/Anope/0002-ngircd-whitespace-fixes.patch
|
||||
$ tar xzf anope-1.9.6-source.tar.gz
|
||||
$ cd anope-1.9.6-source
|
||||
$ for p in .../ngircd/contrib/Anope/*.patch ; do patch -p1 < $p ; done
|
||||
$ ./Config
|
||||
$ cd build
|
||||
$ make
|
||||
|
@@ -1,3 +1,15 @@
|
||||
ngircd (19-0ab1) unstable; urgency=low
|
||||
|
||||
* New "upstream" release: ngIRCd 19.
|
||||
|
||||
-- Alexander Barton <alex@barton.de> Wed, 29 Feb 2012 17:34:08 +0100
|
||||
|
||||
ngircd (19~rc1-0ab1) unstable; urgency=low
|
||||
|
||||
* New "upstream" release candidate 1 for ngIRCd Release 19.
|
||||
|
||||
-- Alexander Barton <alex@barton.de> Sun, 12 Feb 2012 17:47:51 +0100
|
||||
|
||||
ngircd (18-0ab1) unstable; urgency=low
|
||||
|
||||
* New "upstream" release: ngIRCd 18.
|
||||
|
@@ -2,64 +2,60 @@ Source: ngircd
|
||||
Section: net
|
||||
Priority: optional
|
||||
Maintainer: Alexander Barton <alex@barton.de>
|
||||
Build-Depends: debhelper (>> 4.0.0), libz-dev, libwrap0-dev, libident-dev, libgnutls-dev, libpam0g-dev
|
||||
Build-Depends: debhelper (>> 4.0.0),
|
||||
autotools-dev,
|
||||
expect,
|
||||
libz-dev,
|
||||
libwrap0-dev,
|
||||
libident-dev,
|
||||
libgnutls-dev,
|
||||
libpam0g-dev,
|
||||
telnet,
|
||||
Standards-Version: 3.9.1
|
||||
|
||||
Package: ngircd
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Provides: ircd
|
||||
Description: A lightweight daemon for the Internet Relay Chat (IRC)
|
||||
ngIRCd is a free open source daemon for the Internet Relay Chat (IRC)
|
||||
network. It is written from scratch and is not based upon the original
|
||||
IRCd like many others.
|
||||
Description: lightweight Internet Relay Chat server
|
||||
This package provides ngIRCd, a lightweight Internet Relay Chat
|
||||
server for small or private networks. It is simple to configure, can
|
||||
cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
|
||||
is written from scratch, not based on the original IRCd and quite
|
||||
portable.
|
||||
.
|
||||
This package contains the "standard distribution", including support for
|
||||
syslog logging and compressed server-links using zlib. Please have a look
|
||||
at the "ngircd-full" package if you need advanced functionality like support
|
||||
for IPv6 or SSL.
|
||||
.
|
||||
Advantages of ngIRCd:
|
||||
- no problems with servers using changing/non-static IP addresses.
|
||||
- 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.
|
||||
|
||||
Package: ngircd-full
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Provides: ircd
|
||||
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
|
||||
IRCd like many others.
|
||||
Description: lightweight Internet Relay Chat server
|
||||
This package provides ngIRCd, a lightweight Internet Relay Chat
|
||||
server for small or private networks. It is simple to configure, can
|
||||
cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
|
||||
is written from scratch, not based on the original IRCd and quite
|
||||
portable.
|
||||
.
|
||||
In addition to the features of the "standard package", this package
|
||||
includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
|
||||
SSL encrypted client and server links.
|
||||
.
|
||||
Advantages of ngIRCd:
|
||||
- no problems with servers using changing/non-static IP addresses.
|
||||
- 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.
|
||||
|
||||
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.
|
||||
Description: lightweight Internet Relay Chat server
|
||||
This package provides ngIRCd, a lightweight Internet Relay Chat
|
||||
server for small or private networks. It is simple to configure, can
|
||||
cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
|
||||
is written from scratch, not based on the original IRCd and quite
|
||||
portable.
|
||||
.
|
||||
In addition to the features of the "standard package", this package
|
||||
includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
|
||||
@@ -67,12 +63,3 @@ Description: A lightweight daemon for the Internet Relay Chat (IRC)
|
||||
.
|
||||
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.
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de).
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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
|
||||
@@ -74,6 +74,8 @@
|
||||
/* 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 `gai_strerror' function. */
|
||||
#define HAVE_GAI_STRERROR 1
|
||||
/* Define to 1 if you have the `kqueue' function. */
|
||||
#define HAVE_KQUEUE 1
|
||||
/* Define to 1 if you have the `inet_ntoa' function. */
|
||||
@@ -103,10 +105,15 @@
|
||||
#ifdef PAM
|
||||
/* Define to 1 if you have the `pam_authenticate' function. */
|
||||
#define HAVE_PAM_AUTHENTICATE 1
|
||||
#if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1060)
|
||||
/* Define to 1 if you have the <pam/pam_appl.h> header file. */
|
||||
#define HAVE_PAM_PAM_APPL_H 1
|
||||
/* Mac OS X <10.6 doesn't have pam_fail_delay() */
|
||||
#define NO_PAM_FAIL_DELAY 1
|
||||
#else
|
||||
/* Define to 1 if you have the <security/pam_appl.h> header file. */
|
||||
#define HAVE_SECURITY_PAM_APPL_H 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* -eof- */
|
||||
|
2
contrib/MacOSX/ngIRCd.xcodeproj/.gitignore
vendored
2
contrib/MacOSX/ngIRCd.xcodeproj/.gitignore
vendored
@@ -1,2 +1,4 @@
|
||||
project.xcworkspace
|
||||
xcuserdata
|
||||
*.mode1v3
|
||||
*.pbxuser
|
||||
|
@@ -3,7 +3,7 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 44;
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
@@ -40,6 +40,7 @@
|
||||
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 */; };
|
||||
FAACD5F514A6099C006ED74F /* class.c in Sources */ = {isa = PBXBuildFile; fileRef = FAACD5F314A6099C006ED74F /* class.c */; };
|
||||
FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */ = {isa = PBXBuildFile; fileRef = FAE5CC2D0CF2308A007D69B6 /* numeric.c */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -170,7 +171,6 @@
|
||||
FA322D8E0CEF7523001761B3 /* ngIRCd.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = ngIRCd.xcodeproj; sourceTree = "<group>"; };
|
||||
FA322D910CEF7523001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
|
||||
FA322D920CEF7523001761B3 /* ngindent */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngindent; sourceTree = "<group>"; };
|
||||
FA322D930CEF7523001761B3 /* ngircd.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = ngircd.sh; sourceTree = "<group>"; };
|
||||
FA322D940CEF7523001761B3 /* ngircd.spec */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngircd.spec; sourceTree = "<group>"; };
|
||||
FA322D950CEF7523001761B3 /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
|
||||
FA322D960CEF7523001761B3 /* systrace.policy */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = systrace.policy; sourceTree = "<group>"; };
|
||||
@@ -196,6 +196,10 @@
|
||||
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>"; };
|
||||
FA4B08E513E7F8FB00765BA3 /* ngircd-bsd.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "ngircd-bsd.sh"; sourceTree = "<group>"; };
|
||||
FA4B08E613E7F91700765BA3 /* ngIRCd-Logo.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "ngIRCd-Logo.gif"; sourceTree = "<group>"; };
|
||||
FA4B08E713E7F91700765BA3 /* ngircd-redhat.init */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "ngircd-redhat.init"; sourceTree = "<group>"; };
|
||||
FA4B08E813E7F91C00765BA3 /* platformtest.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = platformtest.sh; sourceTree = "<group>"; };
|
||||
FA77849A133FB9FF00740057 /* sample-ngircd.conf.tmpl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "sample-ngircd.conf.tmpl"; 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>"; };
|
||||
@@ -225,6 +229,8 @@
|
||||
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>"; };
|
||||
FAACD5F314A6099C006ED74F /* class.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = class.c; sourceTree = "<group>"; };
|
||||
FAACD5F414A6099C006ED74F /* class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = class.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 */
|
||||
@@ -292,17 +298,19 @@
|
||||
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 */,
|
||||
FA322CDC0CEF74B1001761B3 /* channel.h */,
|
||||
FAACD5F314A6099C006ED74F /* class.c */,
|
||||
FAACD5F414A6099C006ED74F /* class.h */,
|
||||
FA322CDD0CEF74B1001761B3 /* client.c */,
|
||||
FA322CDE0CEF74B1001761B3 /* client.h */,
|
||||
FA322CDF0CEF74B1001761B3 /* conf.c */,
|
||||
FA322CE00CEF74B1001761B3 /* conf.h */,
|
||||
FAA3D2780F139CDC00B2447E /* conf-ssl.h */,
|
||||
FA322CE10CEF74B1001761B3 /* conn-func.c */,
|
||||
FA322CE20CEF74B1001761B3 /* conn-func.h */,
|
||||
FA322CE30CEF74B1001761B3 /* conn-zip.c */,
|
||||
@@ -346,6 +354,8 @@
|
||||
FAE5CC2C0CF2308A007D69B6 /* numeric.h */,
|
||||
FA85178B0FA061EC006A1F5A /* op.c */,
|
||||
FA85178A0FA061EC006A1F5A /* op.h */,
|
||||
FA2D564911EA158B00D37A35 /* pam.c */,
|
||||
FA2D564811EA158B00D37A35 /* pam.h */,
|
||||
FA322D080CEF74B1001761B3 /* parse.c */,
|
||||
FA322D090CEF74B1001761B3 /* parse.h */,
|
||||
FA99428B10E82A27007F27ED /* proc.c */,
|
||||
@@ -354,8 +364,6 @@
|
||||
FA322D0D0CEF74B1001761B3 /* resolve.h */,
|
||||
FAA97C55124A271400D5BBA9 /* sighandlers.c */,
|
||||
FAA97C56124A271400D5BBA9 /* sighandlers.h */,
|
||||
FA2D564811EA158B00D37A35 /* pam.h */,
|
||||
FA2D564911EA158B00D37A35 /* pam.c */,
|
||||
);
|
||||
path = ngircd;
|
||||
sourceTree = "<group>";
|
||||
@@ -432,8 +440,11 @@
|
||||
FA322D730CEF7523001761B3 /* MacOSX */,
|
||||
FA322D910CEF7523001761B3 /* Makefile.am */,
|
||||
FA322D920CEF7523001761B3 /* ngindent */,
|
||||
FA322D930CEF7523001761B3 /* ngircd.sh */,
|
||||
FA4B08E513E7F8FB00765BA3 /* ngircd-bsd.sh */,
|
||||
FA4B08E613E7F91700765BA3 /* ngIRCd-Logo.gif */,
|
||||
FA4B08E713E7F91700765BA3 /* ngircd-redhat.init */,
|
||||
FA322D940CEF7523001761B3 /* ngircd.spec */,
|
||||
FA4B08E813E7F91C00765BA3 /* platformtest.sh */,
|
||||
FA322D950CEF7523001761B3 /* README */,
|
||||
FA322D960CEF7523001761B3 /* systrace.policy */,
|
||||
);
|
||||
@@ -641,8 +652,11 @@
|
||||
/* Begin PBXProject section */
|
||||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0420;
|
||||
};
|
||||
buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "ngIRCd" */;
|
||||
compatibilityVersion = "Xcode 3.0";
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 1;
|
||||
knownRegions = (
|
||||
@@ -703,6 +717,7 @@
|
||||
FA99428C10E82A27007F27ED /* proc.c in Sources */,
|
||||
FA2D564A11EA158B00D37A35 /* pam.c in Sources */,
|
||||
FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */,
|
||||
FAACD5F514A6099C006ED74F /* class.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -713,6 +728,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
@@ -738,13 +754,11 @@
|
||||
1DEB928B08733DD80010E9CD /* Default */ = {
|
||||
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_VERSION = 4.0;
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
GCC_VERSION = 4.2;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
|
||||
SDKROOT = macosx10.6;
|
||||
};
|
||||
name = Default;
|
||||
};
|
||||
@@ -754,12 +768,11 @@
|
||||
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
|
||||
GCC_DEBUGGING_SYMBOLS = full;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_VERSION = 4.0;
|
||||
GCC_VERSION = 4.2;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = "";
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -767,6 +780,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
|
@@ -4,6 +4,7 @@ INDENTARGS="-kr -i8 -ts8 -l80 -c3 -cd41 -ss -ncs -psl"
|
||||
|
||||
# check if indent(1) is available
|
||||
type indent >/dev/null 2>&1 && INDENT="indent"
|
||||
type gindent >/dev/null 2>&1 && INDENT="gindent"
|
||||
type gnuindent >/dev/null 2>&1 && INDENT="gnuindent"
|
||||
|
||||
if [ -z "$INDENT" ]; then
|
||||
|
@@ -1,5 +1,5 @@
|
||||
%define name ngircd
|
||||
%define version 18
|
||||
%define version 19
|
||||
%define release 1
|
||||
%define prefix %{_prefix}
|
||||
|
||||
@@ -15,18 +15,19 @@ 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),
|
||||
developed under the GNU General Public License (GPL). It's written from
|
||||
scratch and is not based upon the original IRCd like many others.
|
||||
This package provides ngIRCd, a lightweight Internet Relay Chat
|
||||
server for small or private networks. It is simple to configure, can
|
||||
cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
|
||||
is written from scratch, not based on the original IRCd and quite
|
||||
portable.
|
||||
|
||||
Advantages:
|
||||
- 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.
|
||||
- well arranged (lean) configuration file
|
||||
- simple to build/install, configure and maintain
|
||||
- supports IPv6 and SSL
|
||||
- no problems with servers that have dynamic IP addresses
|
||||
- freely available, modern, portable and tidy C-source
|
||||
- ngIRCd is being actively developed since 11 years.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
37
doc/GIT.txt
37
doc/GIT.txt
@@ -9,13 +9,23 @@
|
||||
-- GIT.txt --
|
||||
|
||||
|
||||
The source code of ngIRCd is maintained using git, the stupid content
|
||||
tracker.
|
||||
The source code of ngIRCd is maintained using GIT, an distributed version
|
||||
control system. Homepage including documentation: <http://git-scm.com/>.
|
||||
|
||||
|
||||
I. Getting the source code
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
To access the source tree anonymously, run:
|
||||
I. Viewing the source code online
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ngIRCd "GITweb" interface allows you to browse the GIT repository and
|
||||
to see all individual files, tags, branches, commits etc.:
|
||||
|
||||
<http://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd.git>
|
||||
|
||||
|
||||
II. Getting the source code
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To access (copy, clone) the source tree repository anonymously, run:
|
||||
|
||||
$ git clone git://ngircd.barton.de/ngircd.git
|
||||
|
||||
@@ -23,23 +33,23 @@ Thereby a new folder "ngircd" will be created containing all the individual
|
||||
source files.
|
||||
|
||||
The newly created directory ("ngircd") is the "working directory", all
|
||||
git commands will be executed from within this directory in the future.
|
||||
GIT commands will be executed from within this directory in the future.
|
||||
|
||||
Please note: When checking out a fresh copy of ngIRCd using git, the
|
||||
Please note: When checking out a fresh copy of ngIRCd using GIT, the
|
||||
configure script doesn't exist; you have to run the autogen.sh shell script
|
||||
(which is included in the source tree) to generate it. This requires you to
|
||||
have GNU automake and GNU autoconf installed on your system. Please see the
|
||||
file INSTALL for details!
|
||||
|
||||
To update the git tree:
|
||||
To update the local GIT repository:
|
||||
|
||||
$ git pull
|
||||
|
||||
This retrieves all changes and merges them into the current branch.
|
||||
|
||||
|
||||
II. Contributing
|
||||
~~~~~~~~~~~~~~~~
|
||||
III. Contributing
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Patches should be sent to the ngircd mailing list. List homepage:
|
||||
http://arthur.barton.de/mailman/listinfo/ngircd-ml
|
||||
@@ -48,7 +58,8 @@ If you do not want to send them to the list, you can also mail them
|
||||
to Alex Barton, <alex@barton.de>.
|
||||
|
||||
|
||||
III. Write Access
|
||||
~~~~~~~~~~~~~~~~~
|
||||
If you want to contribute a couple of patches and write access to the git
|
||||
IV. Write Access
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want to contribute a couple of patches and write access to the GIT
|
||||
repository would be handy, please contact Alex Barton, <alex@barton.de>.
|
||||
|
@@ -1,13 +1,12 @@
|
||||
#
|
||||
# ngIRCd -- The Next Generation IRC Daemon
|
||||
# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
|
||||
# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
|
||||
#
|
||||
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
|
||||
# der GNU General Public License (GPL), wie von der Free Software Foundation
|
||||
# herausgegeben, weitergeben und/oder modifizieren, entweder unter Version 2
|
||||
# der Lizenz oder (wenn Sie es wuenschen) jeder spaeteren Version.
|
||||
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
# 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.
|
||||
#
|
||||
|
||||
.tmpl:
|
||||
@@ -17,9 +16,9 @@
|
||||
|
||||
SUFFIXES = .tmpl
|
||||
|
||||
static_docs = Bopm.txt FAQ.txt GIT.txt HowToRelease.txt PAM.txt Platforms.txt \
|
||||
Protocol.txt README-AUX.txt README-BeOS.txt README-Interix.txt RFC.txt \
|
||||
SSL.txt Services.txt
|
||||
static_docs = Bopm.txt FAQ.txt GIT.txt HowToRelease.txt Modes.txt PAM.txt \
|
||||
Platforms.txt Protocol.txt README-AUX.txt README-BeOS.txt \
|
||||
README-Interix.txt RFC.txt SSL.txt Services.txt
|
||||
|
||||
doc_templates = sample-ngircd.conf.tmpl
|
||||
|
||||
|
76
doc/Modes.txt
Normal file
76
doc/Modes.txt
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2011 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
-- Modes.txt --
|
||||
|
||||
|
||||
This document lists the different user modes, channel modes, and channel
|
||||
user modes that ngIRCd supports.
|
||||
|
||||
|
||||
I. User Modes
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
User modes are attributes a user has in the network, regardless of the
|
||||
channels he is using at the moment.
|
||||
|
||||
mode since description
|
||||
|
||||
a 0.3.0 User is away.
|
||||
c 17 IRC operator wants to receive connect/disconnect NOTICEs.
|
||||
C 19 Only users that share a channel are allowed to send messages.
|
||||
i 0.0.1 User is "invisible".
|
||||
o 0.0.1 User is IRC operator.
|
||||
r 0.0.1 User is restricted.
|
||||
R (1) 19 User is registered (e.g. by NickServ).
|
||||
s 0.4.0 User wants to receive server notices.
|
||||
w 0.11.0 User wants to receive WALLOPS messages.
|
||||
x 17 Hostname of this user is "cloaked".
|
||||
|
||||
II. Channel Modes
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Channel modes are attributes of specific channels which are valid for all
|
||||
users joined (or trying to join) to this channel. Some modes add and remove
|
||||
users to lists (e.g. "invite list", "ban list"), others have parameters
|
||||
(like "channel key"), most are simple flags (like "moderated").
|
||||
|
||||
mode since description
|
||||
|
||||
b 0.5.0 Add/remove a host mask to the ban list.
|
||||
i 0.5.0 Channel is "invite only".
|
||||
I 0.5.0 Add/remove a host mask to the invite list.
|
||||
k 0.6.0 Channel has a "key" (a password).
|
||||
l 0.6.0 Channel has a user limit.
|
||||
m 0.3.0 Channel is moderated, only "voiced" users can send messages.
|
||||
n 0.3.0 Channel doesn't allow messages of users not being members.
|
||||
O 18 Only IRC operators are allowed to join this channel.
|
||||
P 0.5.0 Channel is "persistent".
|
||||
r (1) 19 Channel is "registered" (e.g. by ChanServ).
|
||||
R 19 Only registered users are allowed to join this channel.
|
||||
s 0.9.0 Channel is "secret".
|
||||
t 0.3.0 Only ChanOps are allowed to modify the channel topic.
|
||||
z 16 Only users connected via SSL are allowed to join the channel.
|
||||
|
||||
III. Channel User Modes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Channel user modes are attributes that a particular user has in a specific
|
||||
channel of which he is a member.
|
||||
|
||||
mode since description
|
||||
|
||||
o 0.2.0 User is channel operator and can op/kick/... other members.
|
||||
v 0.2.0 User is "voiced" and can speak even if channel is moderated.
|
||||
|
||||
|
||||
Notes
|
||||
~~~~~
|
||||
|
||||
(1) This mode is not set by ngIRCd itself but by services. ngIRCd handles
|
||||
the mode transparently and possibly adjusts its behaviour.
|
@@ -2,7 +2,7 @@
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2011 Alexander Barton and Contributors.
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
@@ -31,22 +31,23 @@ hppa1.1/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
|
||||
hppa2.0/unknown/linux-gnu gcc 3.3.5 13~rc1 08-12-02 alex Y Y Y Y
|
||||
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.7.0 gcc 4.2.1 18 11-07-05 alex Y Y Y Y (3)
|
||||
i386/apple/darwin11.0.0 gcc 4.2.1 18 11-07-02 alex Y Y Y Y (3)
|
||||
i386/apple/darwin10.8.0 gcc 4.2.1 19 12-02-26 alex Y Y Y Y (3)
|
||||
i386/apple/darwin11.3.0 gcc 4.2.1 19 12-02-26 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 18 11-07-10 alex Y Y N Y (4)
|
||||
i386/pc/solaris2.11 gcc 3.4.3 19 12-02-26 alex Y Y N Y (4)
|
||||
i386/pc/solaris2.11 gcc 4.2.3 18 11-08-17 goetz 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.2 gcc 3.4.6 18 11-07-10 alex Y Y Y Y (3)
|
||||
i386/unknown/freebsd7.3 gcc 4.2.1 18 11-07-1ß alex Y Y Y Y (3)
|
||||
i686/unknown/gnu0.3 gcc 4.4.5 18 11-07-10 alex Y Y Y Y
|
||||
i386/unknown/freebsd6.2 gcc 3.4.6 19 12-02-26 alex Y Y Y Y (3)
|
||||
i386/unknown/freebsd7.3 gcc 4.2.1 19 12-02-26 alex Y Y Y Y (3)
|
||||
i686/unknown/gnu0.3 gcc 4.4.5 19 12-02-29 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.2 gcc 2.95.3 18 11-07-10 goetz 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 18 11-07-10 alex Y Y Y Y (3)
|
||||
i386/unknown/netbsdelf5.0.2 gcc 4.1.3 18 11-07-10 alex Y Y Y Y (3)
|
||||
i386/unknown/netbsdelf4.0 gcc 4.1.2 19 12-02-29 alex Y Y Y Y (3)
|
||||
i386/unknown/netbsdelf5.0.2 gcc 4.1.3 19 12-02-26 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 16 10-04-11 alex Y Y Y Y (3)
|
||||
i586/pc/interix3.5 gcc 3.3 18 11-07-10 alex Y Y N Y
|
||||
i586/pc/interix3.5 gcc 3.3 19 12-02-29 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.5 14.1 09-08-04 alex Y Y Y Y (1)
|
||||
@@ -54,11 +55,12 @@ 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.0.1 gcc 2.7.2 17 10-11-07 alex Y Y N Y
|
||||
m68k/apple/aux3.0.1 Orig. A/UX 17 10-11-07 alex Y Y N Y (2)
|
||||
m68k/apple/aux3.1.1 gcc 2.7.2 18 11-07-02 alex Y Y N Y
|
||||
m68k/apple/aux3.1.1 Orig. A/UX 18 11-07-02 alex Y Y N Y (2)
|
||||
m68k/apple/aux3.1.1 gcc 2.7.2 19 12-02-26 alex Y Y N Y
|
||||
m68k/apple/aux3.1.1 Orig. A/UX 19 12-02-26 alex Y Y N 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 ? ?
|
||||
mipsel/unknown/linux-gnu gcc 4.1.2 18 11-07-05 goetz Y Y N Y (1)
|
||||
mipsel/unknown/linux-gnu gcc 4.4.5 18 11-07-30 goetz Y Y Y Y (1)
|
||||
powerpc/apple/darwin6.5 gcc 3.1 0.7.x-CVS 03-04-23 alex Y Y Y Y
|
||||
powerpc/apple/darwin7.9.0 gcc 3.3 CVSHEAD 06-05-07 fw Y Y Y Y (3)
|
||||
powerpc/apple/darwin8.11.0 gcc 4.0.1 18 11-07-02 goetz Y Y Y Y (3)
|
||||
@@ -67,15 +69,16 @@ 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.1 gcc 4.2.1 18 11-07-10 alex Y Y Y Y (3)
|
||||
x86_64/unknown/linux-gnu gcc 4.4.5 18 11-07-02 alex Y Y Y Y (1)
|
||||
x86_64/unknown/openbsd4.7 gcc 3.3.5 18 11-07-10 alex Y Y Y Y (3)
|
||||
x86_64/unknown/freebsd8.1 gcc 4.2.1 19 12-02-26 alex Y Y Y Y (3)
|
||||
x86_64/unkn./freebsd8.1-gnu gcc 4.4.5 19 12-02-26 alex Y Y Y Y (3)
|
||||
x86_64/unknown/linux-gnu gcc 4.4.5 19 12-02-26 alex Y Y Y Y (1)
|
||||
x86_64/unknown/openbsd4.7 gcc 3.3.5 19 12-02-26 alex Y Y Y Y (3)
|
||||
|
||||
|
||||
Notes
|
||||
~~~~~
|
||||
|
||||
(1) i686/pc/linux-gnu & x86_64/unknown/linux-gnu:
|
||||
(1) */*/linux-gnu (Linux platforms):
|
||||
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
|
||||
|
@@ -1,12 +1,10 @@
|
||||
|
||||
ngIRCd - Next Generation IRC Server
|
||||
|
||||
(c)2001-2010 Alexander Barton,
|
||||
alex@barton.de, http://www.barton.de/
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
terms of the GNU General Public License.
|
||||
|
||||
-- README-Interix.txt --
|
||||
|
||||
@@ -20,10 +18,13 @@ 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:
|
||||
But please note that two things:
|
||||
|
||||
1. Don't use the poll() IO API
|
||||
|
||||
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
|
||||
@@ -35,3 +36,9 @@ So when running the ./configure script, you HAVE TO DISABLE poll() support:
|
||||
|
||||
ngIRCd then defaults to using the select() API function which works fine.
|
||||
|
||||
2. Use GNU make(1)
|
||||
|
||||
Starting with ngIRCd 18, our build system doesn't work with the default
|
||||
make(1) binary of Interix, you should use GNU make instead (tested with
|
||||
version 3.82 built from source).
|
||||
|
||||
|
@@ -140,6 +140,8 @@
|
||||
;DNS = yes
|
||||
|
||||
# Do IDENT lookups if ngIRCd has been compiled with support for it.
|
||||
# Users identified using IDENT are registered without the "~" character
|
||||
# prepended to their user name.
|
||||
;Ident = yes
|
||||
|
||||
# Enhance user privacy slightly (useful for IRC server on TOR or I2P)
|
||||
@@ -160,7 +162,22 @@
|
||||
;OperServerMode = no
|
||||
|
||||
# Use PAM if ngIRCd has been compiled with support for it.
|
||||
;PAM = no
|
||||
# Users identified using PAM are registered without the "~" character
|
||||
# prepended to their user name.
|
||||
;PAM = yes
|
||||
|
||||
# When PAM is enabled, all clients are required to be authenticated
|
||||
# using PAM; connecting to the server without successful PAM
|
||||
# authentication isn't possible.
|
||||
# If this option is set, clients not sending a password are still
|
||||
# allowed to connect: they won't become "identified" and keep the "~"
|
||||
# character prepended to their supplied user name.
|
||||
# Please note: To make some use of this behavior, it most probably
|
||||
# isn't useful to enable "Ident", "PAM" and "PAMIsOptional" at the
|
||||
# same time, because you wouldn't be able to distinguish between
|
||||
# Ident'ified and PAM-authenticated users: both don't have a "~"
|
||||
# character prepended to their respective user names!
|
||||
;PAMIsOptional = no
|
||||
|
||||
# Allow Pre-Defined Channels only (see Section [Channels])
|
||||
;PredefChannelsOnly = no
|
||||
|
@@ -132,9 +132,8 @@ the pidfile resides in must be writable by the ngIRCd user and exist in the
|
||||
chroot directory (if configured, see above).
|
||||
.TP
|
||||
\fBPorts\fR (list of numbers)
|
||||
Ports on which the server should listen. There may be more than one port,
|
||||
separated with commas (","). Default: 6667, unless \fBSSL_Ports\fR are also
|
||||
specified.
|
||||
Ports on which the server should listen for unencrypted connections. There
|
||||
may be more than one port, separated with commas (","). Default: 6667.
|
||||
.TP
|
||||
\fBServerGID\fR (string or number)
|
||||
Group ID under which the ngIRCd should run; you can use the name of the
|
||||
@@ -244,6 +243,8 @@ Default: yes.
|
||||
\fBIdent\fR (boolean)
|
||||
If ngIRCd is compiled with IDENT support this can be used to disable IDENT
|
||||
lookups at run time.
|
||||
Users identified using IDENT are registered without the "~" character
|
||||
prepended to their user name.
|
||||
Default: yes.
|
||||
.TP
|
||||
\fBMorePrivacy\fR (boolean)
|
||||
@@ -274,8 +275,23 @@ only enable it if you have ircd-irc2 servers in your IRC network.
|
||||
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.
|
||||
Users identified using PAM are registered without the "~" character
|
||||
prepended to their user name.
|
||||
Default: yes.
|
||||
.TP
|
||||
\fBPAMIsOptional\fR (boolean)
|
||||
When PAM is enabled, all clients are required to be authenticated using PAM;
|
||||
connecting to the server without successful PAM authentication isn't possible.
|
||||
If this option is set, clients not sending a password are still allowed to
|
||||
connect: they won't become "identified" and keep the "~" character prepended
|
||||
to their supplied user name.
|
||||
Please note:
|
||||
To make some use of this behavior, it most probably isn't useful to enable
|
||||
"Ident", "PAM" and "PAMIsOptional" at the same time, because you wouldn't be
|
||||
able to distinguish between Ident'ified and PAM-authenticated users: both
|
||||
don't have a "~" character prepended to their respective user names!
|
||||
Default: no.
|
||||
.TP
|
||||
\fBPredefChannelsOnly\fR (boolean)
|
||||
If enabled, no new channels can be created. Useful if you do not want to have
|
||||
other channels than those defined in [Channel] sections in the configuration
|
||||
|
@@ -32,7 +32,9 @@ ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
|
||||
assert(ip_str);
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
#ifdef AI_NUMERICHOST
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
#endif
|
||||
#ifndef WANT_IPV6 /* do not convert ipv6 addresses */
|
||||
hints.ai_family = AF_INET;
|
||||
#endif
|
||||
|
@@ -18,20 +18,21 @@ LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN \
|
||||
|
||||
sbin_PROGRAMS = ngircd
|
||||
|
||||
ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.c \
|
||||
conn-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 op.c numeric.c pam.c parse.c proc.c resolve.c sighandlers.c
|
||||
ngircd_SOURCES = ngircd.c array.c channel.c class.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 op.c numeric.c pam.c parse.c \
|
||||
proc.c resolve.c sighandlers.c
|
||||
|
||||
ngircd_LDFLAGS = -L../portab -L../tool -L../ipaddr
|
||||
|
||||
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 op.h pam.h parse.h proc.h \
|
||||
resolve.h sighandlers.h defines.h messages.h
|
||||
noinst_HEADERS = ngircd.h array.h channel.h class.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 \
|
||||
op.h pam.h parse.h proc.h resolve.h sighandlers.h defines.h messages.h
|
||||
|
||||
clean-local:
|
||||
rm -f check-version check-help lint.out
|
||||
|
@@ -84,7 +84,7 @@ extern void* array_get PARAMS((array* a, size_t membersize, size_t pos));
|
||||
/* free the contents of this array. */
|
||||
extern void array_free PARAMS((array* a));
|
||||
|
||||
/* overwrite array with zeroes before free */
|
||||
/* overwrite array with zeros before free */
|
||||
extern void array_free_wipe PARAMS((array* a));
|
||||
|
||||
/* return pointer to first element in this array */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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
|
||||
@@ -87,6 +87,14 @@ Channel_GetListBans(CHANNEL *c)
|
||||
}
|
||||
|
||||
|
||||
GLOBAL struct list_head *
|
||||
Channel_GetListExcepts(CHANNEL *c)
|
||||
{
|
||||
assert(c != NULL);
|
||||
return &c->list_excepts;
|
||||
}
|
||||
|
||||
|
||||
GLOBAL struct list_head *
|
||||
Channel_GetListInvites(CHANNEL *c)
|
||||
{
|
||||
@@ -110,9 +118,12 @@ Channel_InitPredefined( void )
|
||||
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);
|
||||
if (!conf_chan->name[0])
|
||||
continue;
|
||||
if (!Channel_IsValidName(conf_chan->name)) {
|
||||
Log(LOG_ERR,
|
||||
"Can't create pre-defined channel: invalid name: \"%s\"",
|
||||
conf_chan->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -158,6 +169,7 @@ Free_Channel(CHANNEL *chan)
|
||||
array_free(&chan->topic);
|
||||
array_free(&chan->keyfile);
|
||||
Lists_Free(&chan->list_bans);
|
||||
Lists_Free(&chan->list_excepts);
|
||||
Lists_Free(&chan->list_invites);
|
||||
|
||||
free(chan);
|
||||
@@ -349,20 +361,31 @@ Channel_Quit( CLIENT *Client, const char *Reason )
|
||||
} /* Channel_Quit */
|
||||
|
||||
|
||||
/**
|
||||
* Get number of channels this server knows and that are "visible" to
|
||||
* the given client. If no client is given, all channels will be counted.
|
||||
*
|
||||
* @param Client The client to check or NULL.
|
||||
* @return Number of channels visible to the client.
|
||||
*/
|
||||
GLOBAL unsigned long
|
||||
Channel_Count( void )
|
||||
Channel_CountVisible (CLIENT *Client)
|
||||
{
|
||||
CHANNEL *c;
|
||||
unsigned long count = 0;
|
||||
|
||||
c = My_Channels;
|
||||
while( c )
|
||||
{
|
||||
count++;
|
||||
while(c) {
|
||||
if (Client) {
|
||||
if (!strchr(Channel_Modes(c), 's')
|
||||
|| Channel_IsMemberOf(c, Client))
|
||||
count++;
|
||||
} else
|
||||
count++;
|
||||
c = c->next;
|
||||
}
|
||||
return count;
|
||||
} /* Channel_Count */
|
||||
}
|
||||
|
||||
|
||||
GLOBAL unsigned long
|
||||
@@ -774,6 +797,13 @@ Channel_SetMaxUsers(CHANNEL *Chan, unsigned long Count)
|
||||
} /* Channel_SetMaxUsers */
|
||||
|
||||
|
||||
/**
|
||||
* Check if a client is allowed to send to a specific channel.
|
||||
*
|
||||
* @param Chan The channel to check.
|
||||
* @param From The client that wants to send.
|
||||
* @return true if the client is allowed to send, false otherwise.
|
||||
*/
|
||||
static bool
|
||||
Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
|
||||
{
|
||||
@@ -808,6 +838,9 @@ Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
|
||||
if (strchr(Channel_Modes(Chan), 'm'))
|
||||
return false;
|
||||
|
||||
if (Lists_Check(&Chan->list_excepts, From))
|
||||
return true;
|
||||
|
||||
return !Lists_Check(&Chan->list_bans, From);
|
||||
}
|
||||
|
||||
@@ -999,8 +1032,17 @@ GLOBAL bool
|
||||
Channel_AddBan(CHANNEL *c, const char *mask )
|
||||
{
|
||||
struct list_head *h = Channel_GetListBans(c);
|
||||
LogDebug("Adding \"%s\" to \"%s\" %s list", mask, Channel_Name(c), "ban");
|
||||
return Lists_Add(h, mask, false);
|
||||
LogDebug("Adding \"%s\" to \"%s\" ban list", mask, Channel_Name(c));
|
||||
return Lists_Add(h, mask, false, NULL);
|
||||
}
|
||||
|
||||
|
||||
GLOBAL bool
|
||||
Channel_AddExcept(CHANNEL *c, const char *mask )
|
||||
{
|
||||
struct list_head *h = Channel_GetListExcepts(c);
|
||||
LogDebug("Adding \"%s\" to \"%s\" exception list", mask, Channel_Name(c));
|
||||
return Lists_Add(h, mask, false, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -1008,30 +1050,31 @@ GLOBAL bool
|
||||
Channel_AddInvite(CHANNEL *c, const char *mask, bool onlyonce)
|
||||
{
|
||||
struct list_head *h = Channel_GetListInvites(c);
|
||||
LogDebug("Adding \"%s\" to \"%s\" %s list", mask, Channel_Name(c), "invite");
|
||||
return Lists_Add(h, mask, onlyonce);
|
||||
LogDebug("Adding \"%s\" to \"%s\" invite list", mask, Channel_Name(c));
|
||||
return Lists_Add(h, mask, onlyonce, NULL);
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
ShowInvitesBans(struct list_head *head, CLIENT *Client, CHANNEL *Channel, bool invite)
|
||||
ShowChannelList(struct list_head *head, CLIENT *Client, CHANNEL *Channel,
|
||||
char *msg, char *msg_end)
|
||||
{
|
||||
struct list_elem *e;
|
||||
char *msg = invite ? RPL_INVITELIST_MSG : RPL_BANLIST_MSG;
|
||||
char *msg_end;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Channel != NULL );
|
||||
assert (Client != NULL);
|
||||
assert (Channel != NULL);
|
||||
|
||||
e = Lists_GetFirst(head);
|
||||
while (e) {
|
||||
if( ! IRC_WriteStrClient( Client, msg, Client_ID( Client ),
|
||||
Channel_Name( Channel ), Lists_GetMask(e) )) return DISCONNECTED;
|
||||
if (!IRC_WriteStrClient(Client, msg, Client_ID(Client),
|
||||
Channel_Name(Channel),
|
||||
Lists_GetMask(e)))
|
||||
return DISCONNECTED;
|
||||
e = Lists_GetNext(e);
|
||||
}
|
||||
|
||||
msg_end = invite ? RPL_ENDOFINVITELIST_MSG : RPL_ENDOFBANLIST_MSG;
|
||||
return IRC_WriteStrClient( Client, msg_end, Client_ID( Client ), Channel_Name( Channel ));
|
||||
return IRC_WriteStrClient(Client, msg_end, Client_ID(Client),
|
||||
Channel_Name(Channel));
|
||||
}
|
||||
|
||||
|
||||
@@ -1043,7 +1086,21 @@ Channel_ShowBans( CLIENT *Client, CHANNEL *Channel )
|
||||
assert( Channel != NULL );
|
||||
|
||||
h = Channel_GetListBans(Channel);
|
||||
return ShowInvitesBans(h, Client, Channel, false);
|
||||
return ShowChannelList(h, Client, Channel, RPL_BANLIST_MSG,
|
||||
RPL_ENDOFBANLIST_MSG);
|
||||
}
|
||||
|
||||
|
||||
GLOBAL bool
|
||||
Channel_ShowExcepts( CLIENT *Client, CHANNEL *Channel )
|
||||
{
|
||||
struct list_head *h;
|
||||
|
||||
assert( Channel != NULL );
|
||||
|
||||
h = Channel_GetListExcepts(Channel);
|
||||
return ShowChannelList(h, Client, Channel, RPL_EXCEPTLIST_MSG,
|
||||
RPL_ENDOFEXCEPTLIST_MSG);
|
||||
}
|
||||
|
||||
|
||||
@@ -1055,7 +1112,8 @@ Channel_ShowInvites( CLIENT *Client, CHANNEL *Channel )
|
||||
assert( Channel != NULL );
|
||||
|
||||
h = Channel_GetListInvites(Channel);
|
||||
return ShowInvitesBans(h, Client, Channel, true);
|
||||
return ShowChannelList(h, Client, Channel, RPL_INVITELIST_MSG,
|
||||
RPL_ENDOFINVITELIST_MSG);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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
|
||||
@@ -38,6 +38,7 @@ typedef struct _CHANNEL
|
||||
char key[CLIENT_PASS_LEN]; /* Channel key ("password", mode "k" ) */
|
||||
unsigned long maxusers; /* Maximum number of members (mode "l") */
|
||||
struct list_head list_bans; /* list head of banned users */
|
||||
struct list_head list_excepts; /* list head of (ban) exception list */
|
||||
struct list_head list_invites; /* list head of invited users */
|
||||
array keyfile; /* Name of the channel key file */
|
||||
} CHANNEL;
|
||||
@@ -58,6 +59,7 @@ typedef POINTER CL2CHAN;
|
||||
#endif
|
||||
|
||||
GLOBAL struct list_head *Channel_GetListBans PARAMS((CHANNEL *c));
|
||||
GLOBAL struct list_head *Channel_GetListExcepts PARAMS((CHANNEL *c));
|
||||
GLOBAL struct list_head *Channel_GetListInvites PARAMS((CHANNEL *c));
|
||||
|
||||
GLOBAL void Channel_Init PARAMS(( void ));
|
||||
@@ -72,7 +74,7 @@ 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));
|
||||
|
||||
GLOBAL unsigned long Channel_Count PARAMS(( void ));
|
||||
GLOBAL unsigned long Channel_CountVisible PARAMS((CLIENT *Client));
|
||||
GLOBAL unsigned long Channel_MemberCount PARAMS(( CHANNEL *Chan ));
|
||||
GLOBAL int Channel_CountForUser PARAMS(( CLIENT *Client ));
|
||||
|
||||
@@ -123,10 +125,13 @@ GLOBAL char *Channel_TopicWho PARAMS(( CHANNEL *Chan ));
|
||||
GLOBAL unsigned int Channel_CreationTime PARAMS(( CHANNEL *Chan ));
|
||||
#endif
|
||||
|
||||
GLOBAL bool Channel_AddInvite PARAMS((CHANNEL *c, const char *Mask, bool OnlyOnce ));
|
||||
GLOBAL bool Channel_AddBan PARAMS((CHANNEL *c, const char *Mask ));
|
||||
GLOBAL bool Channel_AddBan PARAMS((CHANNEL *c, const char *Mask));
|
||||
GLOBAL bool Channel_AddExcept PARAMS((CHANNEL *c, const char *Mask));
|
||||
GLOBAL bool Channel_AddInvite PARAMS((CHANNEL *c, const char *Mask,
|
||||
bool OnlyOnce));
|
||||
|
||||
GLOBAL bool Channel_ShowBans PARAMS((CLIENT *client, CHANNEL *c));
|
||||
GLOBAL bool Channel_ShowExcepts PARAMS((CLIENT *client, CHANNEL *c));
|
||||
GLOBAL bool Channel_ShowInvites PARAMS((CLIENT *client, CHANNEL *c));
|
||||
|
||||
GLOBAL void Channel_LogServer PARAMS((const char *msg));
|
||||
|
143
src/ngircd/class.c
Normal file
143
src/ngircd/class.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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
|
||||
* User class management.
|
||||
*/
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "array.h"
|
||||
#include "conn.h"
|
||||
#include "client.h"
|
||||
#include "lists.h"
|
||||
#include "match.h"
|
||||
#include "stdio.h"
|
||||
|
||||
#include "exp.h"
|
||||
#include "class.h"
|
||||
|
||||
struct list_head My_Classes[CLASS_COUNT];
|
||||
|
||||
char Reject_Reason[COMMAND_LEN];
|
||||
|
||||
GLOBAL void
|
||||
Class_Init(void)
|
||||
{
|
||||
memset(My_Classes, 0, sizeof(My_Classes));
|
||||
}
|
||||
|
||||
GLOBAL void
|
||||
Class_Exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CLASS_COUNT; Lists_Free(&My_Classes[i++]));
|
||||
}
|
||||
|
||||
GLOBAL char *
|
||||
Class_GetMemberReason(const int Class, CLIENT *Client)
|
||||
{
|
||||
char *reason;
|
||||
|
||||
assert(Class < CLASS_COUNT);
|
||||
assert(Client != NULL);
|
||||
|
||||
reason = Lists_CheckReason(&My_Classes[Class], Client);
|
||||
if (!reason)
|
||||
return NULL;
|
||||
|
||||
if (!*reason)
|
||||
reason = "listed";
|
||||
|
||||
switch(Class) {
|
||||
case CLASS_GLINE:
|
||||
snprintf(Reject_Reason, sizeof(Reject_Reason),
|
||||
"\"%s\" (G-Line)", reason);
|
||||
return Reject_Reason;
|
||||
case CLASS_KLINE:
|
||||
snprintf(Reject_Reason, sizeof(Reject_Reason),
|
||||
"\"%s\" (K-Line)", reason);
|
||||
return Reject_Reason;
|
||||
}
|
||||
return reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a client is banned from this server: GLINE, KLINE.
|
||||
*
|
||||
* If a client isn't allowed to connect, it will be disconnected again.
|
||||
*
|
||||
* @param Client The client to check.
|
||||
* @return CONNECTED if client is allowed to join, DISCONNECTED if not.
|
||||
*/
|
||||
GLOBAL bool
|
||||
Class_HandleServerBans(CLIENT *Client)
|
||||
{
|
||||
char *rejectptr;
|
||||
|
||||
assert(Client != NULL);
|
||||
|
||||
rejectptr = Class_GetMemberReason(CLASS_GLINE, Client);
|
||||
if (!rejectptr)
|
||||
rejectptr = Class_GetMemberReason(CLASS_KLINE, Client);
|
||||
if (rejectptr) {
|
||||
Client_Reject(Client, rejectptr, true);
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
|
||||
GLOBAL bool
|
||||
Class_AddMask(const int Class, const char *Mask, time_t ValidUntil,
|
||||
const char *Reason)
|
||||
{
|
||||
assert(Class < CLASS_COUNT);
|
||||
assert(Mask != NULL);
|
||||
assert(Reason != NULL);
|
||||
|
||||
return Lists_Add(&My_Classes[Class], Lists_MakeMask(Mask),
|
||||
ValidUntil, Reason);
|
||||
}
|
||||
|
||||
GLOBAL void
|
||||
Class_DeleteMask(const int Class, const char *Mask)
|
||||
{
|
||||
assert(Class < CLASS_COUNT);
|
||||
assert(Mask != NULL);
|
||||
|
||||
Lists_Del(&My_Classes[Class], Lists_MakeMask(Mask));
|
||||
}
|
||||
|
||||
GLOBAL struct list_head *
|
||||
Class_GetList(const int Class)
|
||||
{
|
||||
assert(Class < CLASS_COUNT);
|
||||
|
||||
return &My_Classes[Class];
|
||||
}
|
||||
|
||||
GLOBAL void
|
||||
Class_Expire(void)
|
||||
{
|
||||
Lists_Expire(&My_Classes[CLASS_GLINE], "G-Line");
|
||||
Lists_Expire(&My_Classes[CLASS_KLINE], "K-Line");
|
||||
}
|
||||
|
||||
/* -eof- */
|
41
src/ngircd/class.h
Normal file
41
src/ngircd/class.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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 __class_h__
|
||||
#define __class_h__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* User class management.
|
||||
*/
|
||||
|
||||
#define CLASS_KLINE 0
|
||||
#define CLASS_GLINE 1
|
||||
|
||||
#define CLASS_COUNT 2
|
||||
|
||||
GLOBAL void Class_Init PARAMS((void));
|
||||
GLOBAL void Class_Exit PARAMS((void));
|
||||
|
||||
GLOBAL bool Class_AddMask PARAMS((const int Class, const char *Mask,
|
||||
const time_t ValidUntil, const char *Reason));
|
||||
GLOBAL void Class_DeleteMask PARAMS((const int Class, const char *Mask));
|
||||
|
||||
GLOBAL char *Class_GetMemberReason PARAMS((const int Class, CLIENT *Client));
|
||||
GLOBAL bool Class_HandleServerBans PARAMS((CLIENT *Client));
|
||||
|
||||
GLOBAL struct list_head *Class_GetList PARAMS((const int Class));
|
||||
|
||||
GLOBAL void Class_Expire PARAMS((void));
|
||||
|
||||
#endif /* __class_h__ */
|
||||
|
||||
/* -eof- */
|
@@ -186,7 +186,6 @@ Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer,
|
||||
|
||||
assert(Idx >= NONE);
|
||||
assert(Introducer != NULL);
|
||||
assert(Hostname != NULL);
|
||||
|
||||
client = New_Client_Struct();
|
||||
if (!client)
|
||||
@@ -313,16 +312,29 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen
|
||||
} /* Client_Destroy */
|
||||
|
||||
|
||||
/**
|
||||
* Set client hostname.
|
||||
*
|
||||
* If global hostname cloaking is in effect, don't set the real hostname
|
||||
* but the configured one.
|
||||
*
|
||||
* @param Client The client of which the hostname should be set.
|
||||
* @param Hostname The new hostname.
|
||||
*/
|
||||
GLOBAL void
|
||||
Client_SetHostname( CLIENT *Client, const char *Hostname )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
assert( Hostname != NULL );
|
||||
assert(Client != NULL);
|
||||
assert(Hostname != NULL);
|
||||
|
||||
if (strlen(Conf_CloakHost)) {
|
||||
strlcpy( Client->host, Conf_CloakHost, sizeof( Client->host ));
|
||||
LogDebug("Updating hostname of \"%s\": \"%s\" -> \"%s\"",
|
||||
Client_ID(Client), Client->host, Conf_CloakHost);
|
||||
strlcpy(Client->host, Conf_CloakHost, sizeof(Client->host));
|
||||
} else {
|
||||
strlcpy( Client->host, Hostname, sizeof( Client->host ));
|
||||
LogDebug("Updating hostname of \"%s\": \"%s\" -> \"%s\"",
|
||||
Client_ID(Client), Client->host, Hostname);
|
||||
strlcpy(Client->host, Hostname, sizeof(Client->host));
|
||||
}
|
||||
} /* Client_SetHostname */
|
||||
|
||||
@@ -768,7 +780,7 @@ Client_NextHop( CLIENT *Client )
|
||||
* 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!
|
||||
* nest invocations without overwriting earlier results!
|
||||
* @param Client Pointer to client structure
|
||||
* @return Pointer to global buffer containing the client ID
|
||||
*/
|
||||
@@ -793,7 +805,7 @@ Client_Mask( CLIENT *Client )
|
||||
* 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!
|
||||
* nest invocations without overwriting earlier 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
|
||||
@@ -847,23 +859,37 @@ Client_Away( CLIENT *Client )
|
||||
} /* Client_Away */
|
||||
|
||||
|
||||
/**
|
||||
* Make sure that a given nickname is valid.
|
||||
*
|
||||
* If the nickname is not valid for the given client, this function sends back
|
||||
* the appropriate error messages.
|
||||
*
|
||||
* @param Client Client that wants to change the nickname.
|
||||
* @param Nick New nick name.
|
||||
* @returns true if nickname is valid, false otherwise.
|
||||
*/
|
||||
GLOBAL bool
|
||||
Client_CheckNick( CLIENT *Client, char *Nick )
|
||||
Client_CheckNick(CLIENT *Client, char *Nick)
|
||||
{
|
||||
assert( Client != NULL );
|
||||
assert( Nick != NULL );
|
||||
assert(Client != NULL);
|
||||
assert(Nick != NULL);
|
||||
|
||||
if (! Client_IsValidNick( Nick ))
|
||||
{
|
||||
IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), Nick );
|
||||
if (!Client_IsValidNick(Nick)) {
|
||||
if (strlen(Nick ) >= Conf_MaxNickLength)
|
||||
IRC_WriteStrClient(Client, ERR_NICKNAMETOOLONG_MSG,
|
||||
Client_ID(Client), Nick,
|
||||
Conf_MaxNickLength - 1);
|
||||
else
|
||||
IRC_WriteStrClient(Client, ERR_ERRONEUSNICKNAME_MSG,
|
||||
Client_ID(Client), Nick);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Nick bereits vergeben? */
|
||||
if( Client_Search( Nick ))
|
||||
{
|
||||
/* den Nick gibt es bereits */
|
||||
IRC_WriteStrClient( Client, ERR_NICKNAMEINUSE_MSG, Client_ID( Client ), Nick );
|
||||
/* Nickname already registered? */
|
||||
if (Client_Search(Nick)) {
|
||||
IRC_WriteStrClient(Client, ERR_NICKNAMEINUSE_MSG,
|
||||
Client_ID(Client), Nick);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1019,23 +1045,31 @@ Client_MyMaxUserCount( void )
|
||||
} /* Client_MyMaxUserCount */
|
||||
|
||||
|
||||
/**
|
||||
* Check that a given nickname is valid.
|
||||
*
|
||||
* @param Nick the nickname to check.
|
||||
* @returns true if nickname is valid, false otherwise.
|
||||
*/
|
||||
GLOBAL bool
|
||||
Client_IsValidNick( const char *Nick )
|
||||
Client_IsValidNick(const char *Nick)
|
||||
{
|
||||
const char *ptr;
|
||||
static const char goodchars[] = ";0123456789-";
|
||||
|
||||
assert( Nick != NULL );
|
||||
assert (Nick != NULL);
|
||||
|
||||
if( Nick[0] == '#' ) return false;
|
||||
if( strchr( goodchars, Nick[0] )) return false;
|
||||
if( strlen( Nick ) >= Conf_MaxNickLength) return false;
|
||||
if (strchr(goodchars, Nick[0]))
|
||||
return false;
|
||||
if (strlen(Nick ) >= Conf_MaxNickLength)
|
||||
return false;
|
||||
|
||||
ptr = Nick;
|
||||
while( *ptr )
|
||||
{
|
||||
if (( *ptr < 'A' ) && ( ! strchr( goodchars, *ptr ))) return false;
|
||||
if ( *ptr > '}' ) return false;
|
||||
while (*ptr) {
|
||||
if (*ptr < 'A' && !strchr(goodchars, *ptr ))
|
||||
return false;
|
||||
if (*ptr > '}')
|
||||
return false;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
@@ -1075,6 +1109,39 @@ Client_StartTime(CLIENT *Client)
|
||||
} /* Client_Uptime */
|
||||
|
||||
|
||||
/**
|
||||
* Reject a client when logging in.
|
||||
*
|
||||
* This function is called when a client isn't allowed to connect to this
|
||||
* server. Possible reasons are bad server password, bad PAM password,
|
||||
* or that the client is G/K-Line'd.
|
||||
*
|
||||
* After calling this function, the client isn't connected any more.
|
||||
*
|
||||
* @param Client The client to reject.
|
||||
* @param Reason The reason why the client has been rejected.
|
||||
* @param InformClient If true, send the exact reason to the client.
|
||||
*/
|
||||
GLOBAL void
|
||||
Client_Reject(CLIENT *Client, const char *Reason, bool InformClient)
|
||||
{
|
||||
char info[COMMAND_LEN];
|
||||
|
||||
assert(Client != NULL);
|
||||
assert(Reason != NULL);
|
||||
|
||||
if (InformClient)
|
||||
snprintf(info, sizeof(info), "Access denied: %s", Reason);
|
||||
else
|
||||
strcpy(info, "Access denied: Bad password?");
|
||||
|
||||
Log(LOG_ERR,
|
||||
"User \"%s\" rejected (connection %d): %s!",
|
||||
Client_Mask(Client), Client_Conn(Client), Reason);
|
||||
Conn_Close(Client_Conn(Client), Reason, info, true);
|
||||
}
|
||||
|
||||
|
||||
static unsigned long
|
||||
Count( CLIENT_TYPE Type )
|
||||
{
|
||||
|
@@ -163,6 +163,9 @@ GLOBAL void Client_RegisterWhowas PARAMS(( CLIENT *Client ));
|
||||
|
||||
GLOBAL const char *Client_TypeText PARAMS((CLIENT *Client));
|
||||
|
||||
GLOBAL void Client_Reject PARAMS((CLIENT *Client, const char *Reason,
|
||||
bool InformClient));
|
||||
|
||||
#ifdef DEBUG
|
||||
GLOBAL void Client_DebugDump PARAMS((void));
|
||||
#endif
|
||||
|
@@ -55,8 +55,6 @@ static bool Use_Log = true, Using_MotdFile = 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 ));
|
||||
@@ -265,18 +263,18 @@ static void
|
||||
opers_puts(void)
|
||||
{
|
||||
struct Conf_Oper *op;
|
||||
size_t len;
|
||||
size_t count, i;
|
||||
|
||||
len = array_length(&Conf_Opers, sizeof(*op));
|
||||
count = array_length(&Conf_Opers, sizeof(*op));
|
||||
op = array_start(&Conf_Opers);
|
||||
while (len--) {
|
||||
assert(op->name[0]);
|
||||
for (i = 0; i < count; i++, op++) {
|
||||
if (!op->name[0])
|
||||
continue;
|
||||
|
||||
puts("[OPERATOR]");
|
||||
printf(" Name = %s\n", op->name);
|
||||
printf(" Password = %s\n", op->pwd);
|
||||
printf(" Mask = %s\n\n", op->mask ? op->mask : "");
|
||||
op++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,6 +373,7 @@ Conf_Test( void )
|
||||
printf(" OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode));
|
||||
#ifdef PAM
|
||||
printf(" PAM = %s\n", yesno_to_str(Conf_PAM));
|
||||
printf(" PAMIsOptional = %s\n", yesno_to_str(Conf_PAMIsOptional));
|
||||
#endif
|
||||
printf(" PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly));
|
||||
#ifndef STRICT_RFC
|
||||
@@ -699,6 +698,7 @@ Set_Defaults(bool InitServers)
|
||||
#else
|
||||
Conf_PAM = false;
|
||||
#endif
|
||||
Conf_PAMIsOptional = false;
|
||||
Conf_PredefChannelsOnly = false;
|
||||
#ifdef SYSLOG
|
||||
Conf_ScrubCTCP = false;
|
||||
@@ -709,10 +709,6 @@ Set_Defaults(bool InitServers)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Initialize IRC operators and channels */
|
||||
Conf_Oper_Count = 0;
|
||||
Conf_Channel_Count = 0;
|
||||
|
||||
/* Initialize server configuration structures */
|
||||
if (InitServers) {
|
||||
for (i = 0; i < MAX_SERVERS;
|
||||
@@ -787,6 +783,7 @@ Read_Config( bool ngircd_starting )
|
||||
char section[LINE_LEN], str[LINE_LEN], *var, *arg, *ptr;
|
||||
const UINT16 defaultport = 6667;
|
||||
int line, i, n;
|
||||
size_t count;
|
||||
FILE *fd;
|
||||
|
||||
/* Open configuration file */
|
||||
@@ -857,10 +854,13 @@ Read_Config( bool ngircd_starting )
|
||||
/* Is this the beginning of a new section? */
|
||||
if(( str[0] == '[' ) && ( str[strlen( str ) - 1] == ']' )) {
|
||||
strlcpy( section, str, sizeof( section ));
|
||||
if (strcasecmp(section, "[GLOBAL]") == 0 ||
|
||||
strcasecmp(section, "[LIMITS]") == 0 ||
|
||||
strcasecmp(section, "[OPTIONS]") == 0 ||
|
||||
strcasecmp(section, "[SSL]") == 0)
|
||||
if (strcasecmp(section, "[GLOBAL]") == 0
|
||||
|| strcasecmp(section, "[LIMITS]") == 0
|
||||
|| strcasecmp(section, "[OPTIONS]") == 0
|
||||
#ifdef SSL_SUPPORT
|
||||
|| strcasecmp(section, "[SSL]") == 0
|
||||
#endif
|
||||
)
|
||||
continue;
|
||||
|
||||
if( strcasecmp( section, "[SERVER]" ) == 0 ) {
|
||||
@@ -887,12 +887,30 @@ Read_Config( bool ngircd_starting )
|
||||
else New_Server_Idx = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcasecmp(section, "[CHANNEL]") == 0) {
|
||||
Conf_Channel_Count++;
|
||||
count = array_length(&Conf_Channels,
|
||||
sizeof(struct Conf_Channel));
|
||||
if (!array_alloc(&Conf_Channels,
|
||||
sizeof(struct Conf_Channel),
|
||||
count)) {
|
||||
Config_Error(LOG_ERR,
|
||||
"Could not allocate memory for new operator (line %d)",
|
||||
line);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcasecmp(section, "[OPERATOR]") == 0) {
|
||||
Conf_Oper_Count++;
|
||||
count = array_length(&Conf_Opers,
|
||||
sizeof(struct Conf_Oper));
|
||||
if (!array_alloc(&Conf_Opers,
|
||||
sizeof(struct Conf_Oper),
|
||||
count)) {
|
||||
Config_Error(LOG_ERR,
|
||||
"Could not allocate memory for new channel (line &d)",
|
||||
line);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -978,17 +996,21 @@ Read_Config( bool ngircd_starting )
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether an string argument is true or false.
|
||||
* Check whether a string argument is "true" or "false".
|
||||
*
|
||||
* @param Arg Input string.
|
||||
* @returns true if string has been parsed as "yes"/"true"/"on".
|
||||
* @returns true if the input string has been parsed as "yes", "true"
|
||||
* (case insensitive) or a non-zero integer value.
|
||||
*/
|
||||
static bool
|
||||
Check_ArgIsTrue( const char *Arg )
|
||||
Check_ArgIsTrue(const char *Arg)
|
||||
{
|
||||
if( strcasecmp( Arg, "yes" ) == 0 ) return true;
|
||||
if( strcasecmp( Arg, "true" ) == 0 ) return true;
|
||||
if( atoi( Arg ) != 0 ) return true;
|
||||
if (strcasecmp(Arg, "yes") == 0)
|
||||
return true;
|
||||
if (strcasecmp(Arg, "true") == 0)
|
||||
return true;
|
||||
if (atoi(Arg) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1289,7 +1311,9 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
|
||||
else {
|
||||
Conf_GID = (unsigned int)atoi(Arg);
|
||||
if (!Conf_GID && strcmp(Arg, "0"))
|
||||
Config_Error_NaN(Line, Var);
|
||||
Config_Error(LOG_WARNING,
|
||||
"%s, line %d: Value of \"%s\" is not a valid group name or ID!",
|
||||
NGIRCd_ConfFile, Line, Var);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1300,7 +1324,9 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
|
||||
else {
|
||||
Conf_UID = (unsigned int)atoi(Arg);
|
||||
if (!Conf_UID && strcmp(Arg, "0"))
|
||||
Config_Error_NaN(Line, Var);
|
||||
Config_Error(LOG_WARNING,
|
||||
"%s, line %d: Value of \"%s\" is not a valid user name or ID!",
|
||||
NGIRCd_ConfFile, Line, Var);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1483,6 +1509,10 @@ Handle_OPTIONS(int Line, char *Var, char *Arg)
|
||||
WarnPAM(Line);
|
||||
return;
|
||||
}
|
||||
if (strcasecmp(Var, "PAMIsOptional") == 0 ) {
|
||||
Conf_PAMIsOptional = Check_ArgIsTrue(Arg);
|
||||
return;
|
||||
}
|
||||
if (strcasecmp(Var, "PredefChannelsOnly") == 0) {
|
||||
Conf_PredefChannelsOnly = Check_ArgIsTrue(Arg);
|
||||
return;
|
||||
@@ -1580,13 +1610,11 @@ Handle_OPERATOR( int Line, char *Var, char *Arg )
|
||||
assert( Line > 0 );
|
||||
assert( Var != NULL );
|
||||
assert( Arg != NULL );
|
||||
assert( 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);
|
||||
op = array_get(&Conf_Opers, sizeof(*op),
|
||||
array_length(&Conf_Opers, sizeof(*op)) - 1);
|
||||
if (!op)
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(Var, "Name") == 0) {
|
||||
/* Name of IRC operator */
|
||||
@@ -1752,21 +1780,17 @@ static void
|
||||
Handle_CHANNEL(int Line, char *Var, char *Arg)
|
||||
{
|
||||
size_t len;
|
||||
size_t chancount;
|
||||
struct Conf_Channel *chan;
|
||||
|
||||
assert( Line > 0 );
|
||||
assert( Var != NULL );
|
||||
assert( Arg != NULL );
|
||||
assert(Conf_Channel_Count > 0);
|
||||
|
||||
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);
|
||||
chan = array_get(&Conf_Channels, sizeof(*chan),
|
||||
array_length(&Conf_Channels, sizeof(*chan)) - 1);
|
||||
if (!chan)
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(Var, "Name") == 0) {
|
||||
if (!Handle_Channelname(chan, Arg))
|
||||
Config_Error_TooLong(Line, Var);
|
||||
@@ -1913,8 +1937,10 @@ Validate_Config(bool Configtest, bool Rehash)
|
||||
}
|
||||
}
|
||||
Log(LOG_DEBUG,
|
||||
"Configuration: Operators=%d, Servers=%d[%d], Channels=%d",
|
||||
Conf_Oper_Count, servers, servers_once, Conf_Channel_Count);
|
||||
"Configuration: Operators=%ld, Servers=%d[%d], Channels=%ld",
|
||||
array_length(&Conf_Opers, sizeof(struct Conf_Oper)),
|
||||
servers, servers_once,
|
||||
array_length(&Conf_Channels, sizeof(struct Conf_Channel)));
|
||||
#endif
|
||||
|
||||
return config_valid;
|
||||
@@ -2044,7 +2070,7 @@ Init_Server_Struct( CONF_SERVER *Server )
|
||||
|
||||
Proc_InitStruct(&Server->res_stat);
|
||||
Server->conn_id = NONE;
|
||||
memset(&Server->bind_addr, 0, sizeof(&Server->bind_addr));
|
||||
memset(&Server->bind_addr, 0, sizeof(Server->bind_addr));
|
||||
}
|
||||
|
||||
/* -eof- */
|
||||
|
@@ -154,7 +154,7 @@ GLOBAL bool Conf_OperCanMode;
|
||||
/**
|
||||
* If true, mask channel MODE commands of IRC operators to the server.
|
||||
* Background: ircd2 will ignore channel MODE commands if an IRC operator
|
||||
* gives chanel operator privileges to someone without being a channel operator
|
||||
* gives channel operator privileges to someone without being a channel operator
|
||||
* himself. This enables a workaround: it masks the MODE command as coming
|
||||
* from the IRC server and not the IRC operator.
|
||||
*/
|
||||
@@ -184,6 +184,9 @@ GLOBAL bool Conf_NoticeAuth;
|
||||
/** Enable all usage of PAM, even when compiled with support for it */
|
||||
GLOBAL bool Conf_PAM;
|
||||
|
||||
/** Don't require all clients to send a password an to be PAM authenticated */
|
||||
GLOBAL bool Conf_PAMIsOptional;
|
||||
|
||||
/** Disable all CTCP commands except for /me ? */
|
||||
GLOBAL bool Conf_ScrubCTCP;
|
||||
|
||||
|
@@ -30,13 +30,30 @@
|
||||
#include "conn-func.h"
|
||||
|
||||
|
||||
/**
|
||||
* Update "idle timestamp", the time of the last visible user action
|
||||
* (e. g. like sending messages, joining or leaving channels).
|
||||
*
|
||||
* @param Idx Connection index.
|
||||
*/
|
||||
GLOBAL void
|
||||
Conn_UpdateIdle( CONN_ID Idx )
|
||||
Conn_UpdateIdle(CONN_ID Idx)
|
||||
{
|
||||
assert( Idx > NONE );
|
||||
My_Connections[Idx].lastprivmsg = time( NULL );
|
||||
assert(Idx > NONE);
|
||||
My_Connections[Idx].lastprivmsg = time(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update "ping timestamp", the time of the last outgoing PING request.
|
||||
*
|
||||
* @param Idx Connection index.
|
||||
*/
|
||||
GLOBAL void
|
||||
Conn_UpdatePing(CONN_ID Idx)
|
||||
{
|
||||
assert(Idx > NONE);
|
||||
My_Connections[Idx].lastping = time(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get signon time of a connection.
|
||||
@@ -65,35 +82,56 @@ Conn_LastPing( CONN_ID Idx )
|
||||
} /* Conn_LastPing */
|
||||
|
||||
|
||||
/**
|
||||
* Add "penalty time" for a connection.
|
||||
*
|
||||
* During the "penalty time" 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.
|
||||
*
|
||||
* @param Idex Connection index.
|
||||
* @param Seconds Seconds to add.
|
||||
* @see Conn_ResetPenalty
|
||||
*/
|
||||
GLOBAL void
|
||||
Conn_SetPenalty( CONN_ID Idx, time_t Seconds )
|
||||
Conn_SetPenalty(CONN_ID Idx, time_t Seconds)
|
||||
{
|
||||
/* 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 );
|
||||
assert( Seconds >= 0 );
|
||||
|
||||
t = time( NULL ) + Seconds;
|
||||
if (t > My_Connections[Idx].delaytime)
|
||||
assert(Idx > NONE);
|
||||
assert(Seconds >= 0);
|
||||
|
||||
t = time(NULL);
|
||||
if (My_Connections[Idx].delaytime < t)
|
||||
My_Connections[Idx].delaytime = t;
|
||||
|
||||
My_Connections[Idx].delaytime += Seconds;
|
||||
|
||||
#ifdef DEBUG
|
||||
Log(LOG_DEBUG, "Add penalty time on connection %d: %ld second(s).",
|
||||
Idx, (long)Seconds);
|
||||
Log(LOG_DEBUG,
|
||||
"Add penalty time on connection %d: %ld second%s, total %ld second%s.",
|
||||
Idx, (long)Seconds, Seconds != 1 ? "s" : "",
|
||||
My_Connections[Idx].delaytime - t,
|
||||
My_Connections[Idx].delaytime - t != 1 ? "s" : "");
|
||||
#endif
|
||||
} /* Conn_SetPenalty */
|
||||
|
||||
|
||||
/**
|
||||
* Reset the "penalty time" for one connection.
|
||||
*
|
||||
* @param Idx Connection index.
|
||||
* @see Conn_SetPenalty
|
||||
*/
|
||||
GLOBAL void
|
||||
Conn_ResetPenalty( CONN_ID Idx )
|
||||
Conn_ResetPenalty(CONN_ID Idx)
|
||||
{
|
||||
assert( Idx > NONE );
|
||||
assert(Idx > NONE);
|
||||
|
||||
My_Connections[Idx].delaytime = 0;
|
||||
#ifdef DEBUG
|
||||
Log(LOG_DEBUG, "Penalty time on connection %d has been reset.");
|
||||
#endif
|
||||
} /* Conn_ResetPenalty */
|
||||
|
||||
|
||||
|
@@ -29,7 +29,9 @@
|
||||
#endif
|
||||
|
||||
|
||||
GLOBAL void Conn_UpdateIdle PARAMS(( CONN_ID Idx ));
|
||||
GLOBAL void Conn_UpdateIdle PARAMS((CONN_ID Idx));
|
||||
GLOBAL void Conn_UpdatePing PARAMS((CONN_ID Idx));
|
||||
|
||||
GLOBAL time_t Conn_GetSignon PARAMS((CONN_ID Idx));
|
||||
GLOBAL time_t Conn_GetIdle PARAMS(( CONN_ID Idx ));
|
||||
GLOBAL time_t Conn_LastPing PARAMS(( CONN_ID Idx ));
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -9,6 +9,8 @@
|
||||
* Please read the file COPYING, README and AUTHORS for more information.
|
||||
*/
|
||||
|
||||
#undef DEBUG_BUFFER
|
||||
|
||||
#define CONN_MODULE
|
||||
|
||||
#include "portab.h"
|
||||
@@ -63,6 +65,7 @@
|
||||
#include "ngircd.h"
|
||||
#include "array.h"
|
||||
#include "client.h"
|
||||
#include "class.h"
|
||||
#include "conf.h"
|
||||
#include "conn-ssl.h"
|
||||
#include "conn-zip.h"
|
||||
@@ -79,8 +82,8 @@
|
||||
#define SERVER_WAIT (NONE - 1)
|
||||
|
||||
#define MAX_COMMANDS 3
|
||||
#define MAX_COMMANDS_SERVER 10
|
||||
#define MAX_COMMANDS_SERVICE MAX_COMMANDS_SERVER
|
||||
#define MAX_COMMANDS_SERVER_MIN 10
|
||||
#define MAX_COMMANDS_SERVICE 10
|
||||
|
||||
|
||||
static bool Handle_Write PARAMS(( CONN_ID Idx ));
|
||||
@@ -367,7 +370,7 @@ cb_clientserver_ssl(int sock, short what)
|
||||
|
||||
|
||||
/**
|
||||
* Initialite connecion module.
|
||||
* Initialize connecion module.
|
||||
*/
|
||||
GLOBAL void
|
||||
Conn_Init( void )
|
||||
@@ -433,12 +436,13 @@ Conn_Exit( void )
|
||||
* they don't hold connections open that the main process wants to close.
|
||||
*/
|
||||
GLOBAL void
|
||||
Conn_CloseAllSockets(void)
|
||||
Conn_CloseAllSockets(int ExceptOf)
|
||||
{
|
||||
CONN_ID idx;
|
||||
|
||||
for(idx = 0; idx < Pool_Size; idx++) {
|
||||
if(My_Connections[idx].sock > NONE)
|
||||
if(My_Connections[idx].sock > NONE &&
|
||||
My_Connections[idx].sock != ExceptOf)
|
||||
close(My_Connections[idx].sock);
|
||||
}
|
||||
}
|
||||
@@ -739,6 +743,9 @@ Conn_Handler(void)
|
||||
Check_Servers();
|
||||
Check_Connections();
|
||||
|
||||
/* Expire outdated class/list items */
|
||||
Class_Expire();
|
||||
|
||||
/* Look for non-empty read buffers ... */
|
||||
for (i = 0; i < Pool_Size; i++) {
|
||||
if ((My_Connections[i].sock > NONE)
|
||||
@@ -929,22 +936,25 @@ Conn_Write( CONN_ID Idx, char *Data, size_t Len )
|
||||
assert( Data != NULL );
|
||||
assert( Len > 0 );
|
||||
|
||||
c = Conn_GetClient(Idx);
|
||||
assert( c != NULL);
|
||||
|
||||
/* Servers do get special write buffer limits, so they can generate
|
||||
* all the messages that are required while peering. */
|
||||
if (Client_Type(c) == CLIENT_SERVER)
|
||||
writebuf_limit = WRITEBUFFER_SLINK_LEN;
|
||||
|
||||
/* Is the socket still open? A previous call to Conn_Write()
|
||||
* may have closed the connection due to a fatal error.
|
||||
* In this case it is sufficient to return an error, as well. */
|
||||
if( My_Connections[Idx].sock <= NONE ) {
|
||||
if (My_Connections[Idx].sock <= NONE) {
|
||||
LogDebug("Skipped write on closed socket (connection %d).", Idx);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Make sure that there still exists a CLIENT structure associated
|
||||
* with this connection and check if this is a server or not: */
|
||||
c = Conn_GetClient(Idx);
|
||||
if (c) {
|
||||
/* Servers do get special write buffer limits, so they can
|
||||
* generate all the messages that are required while peering. */
|
||||
if (Client_Type(c) == CLIENT_SERVER)
|
||||
writebuf_limit = WRITEBUFFER_SLINK_LEN;
|
||||
} else
|
||||
LogDebug("Write on socket without client (connection %d)!?", Idx);
|
||||
|
||||
#ifdef ZLIB
|
||||
if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) {
|
||||
/* Compressed link:
|
||||
@@ -1007,7 +1017,7 @@ Conn_Write( CONN_ID Idx, char *Data, size_t Len )
|
||||
GLOBAL void
|
||||
Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient )
|
||||
{
|
||||
/* Close connection. Open pipes of asyncronous resolver
|
||||
/* Close connection. Open pipes of asynchronous resolver
|
||||
* sub-processes are closed down. */
|
||||
|
||||
CLIENT *c;
|
||||
@@ -1216,6 +1226,20 @@ Conn_SyncServerStruct(void)
|
||||
} /* SyncServerStruct */
|
||||
|
||||
|
||||
/**
|
||||
* Get IP address string of a connection.
|
||||
*
|
||||
* @param Idx Connection index.
|
||||
* @return Pointer to a global buffer containing the IP address as string.
|
||||
*/
|
||||
GLOBAL const char *
|
||||
Conn_GetIPAInfo(CONN_ID Idx)
|
||||
{
|
||||
assert(Idx > NONE);
|
||||
return ng_ipaddr_tostr(&My_Connections[Idx].addr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send out data of write buffer; connect new sockets.
|
||||
*
|
||||
@@ -1255,9 +1279,11 @@ Handle_Write( CONN_ID Idx )
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_BUFFER
|
||||
LogDebug
|
||||
("Handle_Write() called for connection %d, %ld bytes pending ...",
|
||||
Idx, wdatalen);
|
||||
#endif
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_SSL )) {
|
||||
@@ -1326,6 +1352,8 @@ New_Connection(int Sock)
|
||||
|
||||
assert(Sock > NONE);
|
||||
|
||||
LogDebug("Accepting new connection on socket %d ...", Sock);
|
||||
|
||||
new_sock_len = (int)sizeof(new_addr);
|
||||
new_sock = accept(Sock, (struct sockaddr *)&new_addr,
|
||||
(socklen_t *)&new_sock_len);
|
||||
@@ -1410,7 +1438,7 @@ New_Connection(int Sock)
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = Client_NewLocal(new_sock, ip_str, CLIENT_UNKNOWN, false);
|
||||
c = Client_NewLocal(new_sock, NULL, CLIENT_UNKNOWN, false);
|
||||
if (!c) {
|
||||
Log(LOG_ALERT,
|
||||
"Can't accept connection: can't create client structure!");
|
||||
@@ -1561,7 +1589,7 @@ Read_Request( CONN_ID Idx )
|
||||
if (!array_catb(&My_Connections[Idx].zip.rbuf, readbuf,
|
||||
(size_t) len)) {
|
||||
Log(LOG_ERR,
|
||||
"Could not append recieved data to zip input buffer (connn %d): %d bytes!",
|
||||
"Could not append recieved data to zip input buffer (connection %d): %d bytes!",
|
||||
Idx, len);
|
||||
Conn_Close(Idx, "Receive buffer space exhausted", NULL,
|
||||
false);
|
||||
@@ -1571,7 +1599,9 @@ Read_Request( CONN_ID Idx )
|
||||
#endif
|
||||
{
|
||||
if (!array_catb( &My_Connections[Idx].rbuf, readbuf, len)) {
|
||||
Log( LOG_ERR, "Could not append recieved data to input buffer (connn %d): %d bytes!", Idx, len );
|
||||
Log(LOG_ERR,
|
||||
"Could not append recieved data to input buffer (connection %d): %d bytes!",
|
||||
Idx, len);
|
||||
Conn_Close(Idx, "Receive buffer space exhausted", NULL, false );
|
||||
}
|
||||
}
|
||||
@@ -1644,16 +1674,15 @@ Handle_Buffer(CONN_ID Idx)
|
||||
|
||||
assert(c != NULL);
|
||||
|
||||
/* Servers do get special command limits, so they can process
|
||||
* all the messages that are required while peering. */
|
||||
/* Servers get special command limits that depend on the user count */
|
||||
switch (Client_Type(c)) {
|
||||
case CLIENT_SERVER:
|
||||
/* Allow servers to send more commands in the first 10 secods
|
||||
maxcmd = (int)(Client_UserCount() / 5)
|
||||
+ MAX_COMMANDS_SERVER_MIN;
|
||||
/* Allow servers to handle even more commands while peering
|
||||
* to speed up server login and network synchronisation. */
|
||||
if (starttime - Client_StartTime(c) < 10)
|
||||
maxcmd = MAX_COMMANDS_SERVER * 5;
|
||||
else
|
||||
maxcmd = MAX_COMMANDS_SERVER;
|
||||
if (Conn_LastPing(Idx) == 0)
|
||||
maxcmd *= 5;
|
||||
break;
|
||||
case CLIENT_SERVICE:
|
||||
maxcmd = MAX_COMMANDS_SERVICE; break;
|
||||
@@ -1753,8 +1782,10 @@ Handle_Buffer(CONN_ID Idx)
|
||||
return 0; /* error -> connection has been closed */
|
||||
|
||||
array_moveleft(&My_Connections[Idx].rbuf, 1, len);
|
||||
#ifdef DEBUG_BUFFER
|
||||
LogDebug("Connection %d: %d bytes left in read buffer.",
|
||||
Idx, array_bytes(&My_Connections[Idx].rbuf));
|
||||
#endif
|
||||
#ifdef ZLIB
|
||||
if ((!old_z) && (My_Connections[Idx].options & CONN_ZIP) &&
|
||||
(array_bytes(&My_Connections[Idx].rbuf) > 0)) {
|
||||
@@ -1818,7 +1849,7 @@ Check_Connections(void)
|
||||
time(NULL) - Conf_PingTimeout) {
|
||||
/* We need to send a PING ... */
|
||||
LogDebug("Connection %d: sending PING ...", i);
|
||||
My_Connections[i].lastping = time(NULL);
|
||||
Conn_UpdatePing(i);
|
||||
Conn_WriteStr(i, "PING :%s",
|
||||
Client_ID(Client_ThisServer()));
|
||||
}
|
||||
@@ -2051,13 +2082,14 @@ Init_Socket( int Sock )
|
||||
/* Set type of service (TOS) */
|
||||
#if defined(IPPROTO_IP) && defined(IPTOS_LOWDELAY)
|
||||
value = IPTOS_LOWDELAY;
|
||||
LogDebug("Setting IP_TOS on socket %d to IPTOS_LOWDELAY.", Sock);
|
||||
if (setsockopt(Sock, IPPROTO_IP, IP_TOS, &value,
|
||||
(socklen_t) sizeof(value))) {
|
||||
LogDebug("Can't set socket option IP_TOS: %s!",
|
||||
strerror(errno));
|
||||
/* ignore this error */
|
||||
}
|
||||
} else
|
||||
LogDebug("IP_TOS on socket %d has been set to IPTOS_LOWDELAY.",
|
||||
Sock);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
@@ -2098,6 +2130,7 @@ cb_Connect_to_Server(int fd, UNUSED short events)
|
||||
|
||||
/* Read result from pipe */
|
||||
len = Proc_Read(&Conf_Server[i].res_stat, dest_addrs, sizeof(dest_addrs));
|
||||
Proc_Close(&Conf_Server[i].res_stat);
|
||||
if (len == 0) {
|
||||
/* Error resolving hostname: reset server structure */
|
||||
Conf_Server[i].conn_id = NONE;
|
||||
@@ -2157,6 +2190,7 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
|
||||
|
||||
/* Read result from pipe */
|
||||
len = Proc_Read(&My_Connections[i].proc_stat, readbuf, sizeof readbuf -1);
|
||||
Proc_Close(&My_Connections[i].proc_stat);
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
@@ -2204,6 +2238,7 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
|
||||
"NOTICE AUTH :*** No ident response");
|
||||
}
|
||||
#endif
|
||||
Class_HandleServerBans(c);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else Log( LOG_DEBUG, "Resolver: discarding result for already registered connection %d.", i );
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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
|
||||
@@ -106,7 +106,7 @@ GLOBAL long WCounter;
|
||||
GLOBAL void Conn_Init PARAMS((void ));
|
||||
GLOBAL void Conn_Exit PARAMS(( void ));
|
||||
|
||||
GLOBAL void Conn_CloseAllSockets PARAMS((void));
|
||||
GLOBAL void Conn_CloseAllSockets PARAMS((int ExceptOf));
|
||||
|
||||
GLOBAL unsigned int Conn_InitListeners PARAMS(( void ));
|
||||
GLOBAL void Conn_ExitListeners PARAMS(( void ));
|
||||
@@ -131,6 +131,8 @@ Conn_UsesSSL(UNUSED CONN_ID Idx)
|
||||
{ return false; }
|
||||
#endif
|
||||
|
||||
GLOBAL const char *Conn_GetIPAInfo PARAMS((CONN_ID Idx));
|
||||
|
||||
GLOBAL long Conn_Count PARAMS((void));
|
||||
GLOBAL long Conn_CountMax PARAMS((void));
|
||||
GLOBAL long Conn_CountAccepted PARAMS((void));
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,98 +17,188 @@
|
||||
* Global constants ("#defines") used by the ngIRCd.
|
||||
*/
|
||||
|
||||
|
||||
/* Internal flags */
|
||||
|
||||
/** Flag: there is no connection. */
|
||||
#define NONE -1
|
||||
|
||||
#define FNAME_LEN 256 /* Max. length of file name */
|
||||
/** Flag: connection is (still) established. */
|
||||
#define CONNECTED true
|
||||
|
||||
#define LINE_LEN 256 /* Max. length of a line in the
|
||||
configuration file */
|
||||
|
||||
#define HOST_LEN 256 /* Max. lenght of fully qualified host
|
||||
names (e. g. "abc.domain.tld") */
|
||||
|
||||
#define MAX_SERVERS 16 /* Max. count of configurable servers */
|
||||
|
||||
#define MAX_WHOWAS 64 /* Max. number of WHOWAS items */
|
||||
#define DEFAULT_WHOWAS 5 /* default count for WHOWAS command */
|
||||
|
||||
#define CONNECTION_POOL 100 /* Size of default connection pool */
|
||||
|
||||
#define CLIENT_ID_LEN 64 /* Max. length of an IRC ID; see RFC
|
||||
RFC 2812 section 1.1 and 1.2.1 */
|
||||
#define CLIENT_NICK_LEN_DEFAULT 10 /* Default nick length, see. RFC 2812
|
||||
* section 1.2.1 */
|
||||
#define CLIENT_NICK_LEN 32 /* Maximum nick name length */
|
||||
#define CLIENT_PASS_LEN 21 /* Max. password length */
|
||||
#define CLIENT_USER_LEN 10 /* Max. length of user name ("login")
|
||||
see RFC 2812, section 1.2.1 */
|
||||
#define CLIENT_NAME_LEN 32 /* Max. length of "real names" */
|
||||
#define CLIENT_HOST_LEN 64 /* Max. host name length */
|
||||
#define CLIENT_MODE_LEN 9 /* Max. lenth of all client modes */
|
||||
#define CLIENT_INFO_LEN 64 /* Max. length of server info texts */
|
||||
#define CLIENT_AWAY_LEN 128 /* Max. length of away messages */
|
||||
#define CLIENT_FLAGS_LEN 100 /* Max. length of client flags */
|
||||
|
||||
#define CHANNEL_NAME_LEN 51 /* Max. length of a channel name, see
|
||||
RFC 2812 section 1.3 */
|
||||
#define CHANNEL_MODE_LEN 9 /* Max. length of channel modes */
|
||||
|
||||
#define COMMAND_LEN 513 /* Max. IRC command length, see. RFC
|
||||
2812 section 3.2 */
|
||||
|
||||
#define READBUFFER_LEN 2048 /* Size of the read buffer of a
|
||||
connection in bytes. */
|
||||
#define WRITEBUFFER_FLUSH_LEN 4096 /* Size of a write buffer that triggers
|
||||
buffer flushing if more space is
|
||||
needed for storing data. */
|
||||
#define WRITEBUFFER_MAX_LEN 32768 /* Maximum size of the write buffer of a
|
||||
connection in bytes. */
|
||||
#define WRITEBUFFER_SLINK_LEN 65536 /* Maximum size of the write buffer of a
|
||||
server link connection in bytes. */
|
||||
|
||||
#define PROTOVER "0210" /* Implemented IRC protocol version,
|
||||
see RFC 2813 section 4.1.1. */
|
||||
#define PROTOIRC "-IRC" /* Protocol suffix, see RFC 2813
|
||||
section 4.1.1 */
|
||||
#define PROTOIRCPLUS "-IRC+" /* Protocol suffix used by the IRC+
|
||||
protocol, see doc/Protocol.txt */
|
||||
|
||||
#ifdef IRCPLUS
|
||||
# define IRCPLUSFLAGS "CHLS" /* Standard IRC+ flags */
|
||||
#endif
|
||||
|
||||
#define STARTUP_DELAY 1 /* Delay outgoing connections n seconds
|
||||
after startup. */
|
||||
#define RECONNECT_DELAY 3 /* Time to delay re-connect attempts
|
||||
in seconds. */
|
||||
|
||||
#define USERMODES "aciorswx" /* Supported user modes. */
|
||||
#define CHANMODES "biIklmnoOPstvz" /* Supported channel modes. */
|
||||
|
||||
#define CONNECTED true /* Internal status codes. */
|
||||
/** Flag: connection isn't established (any more). */
|
||||
#define DISCONNECTED false
|
||||
|
||||
#define DEFAULT_AWAY_MSG "Away" /* Away message for users connected to
|
||||
linked servers. */
|
||||
/** Tag for outbound server links. */
|
||||
#define TOKEN_OUTBOUND -2
|
||||
|
||||
#define DEFAULT_TOPIC_ID "-Server-" /* Default ID for "topic owner". */
|
||||
|
||||
#define CONFIG_FILE "/ngircd.conf" /* Configuration file name. */
|
||||
#define MOTD_FILE "/ngircd.motd" /* Name of the MOTD file. */
|
||||
#define CHROOT_DIR "" /* Default chroot() directory. */
|
||||
#define PID_FILE "" /* Default file for the process ID. */
|
||||
/* Generic buffer sizes */
|
||||
|
||||
#define ERROR_DIR "/tmp" /* Error directory used in debug mode */
|
||||
/** Max. length of a line in the configuration file. */
|
||||
#define LINE_LEN 256
|
||||
|
||||
#define MAX_LOG_MSG_LEN 256 /* Max. length of a log message. */
|
||||
/** Max. length of a log message. */
|
||||
#define MAX_LOG_MSG_LEN 256
|
||||
|
||||
#define TOKEN_OUTBOUND -2 /* Tag for outbound server links. */
|
||||
/** Max. length of file name. */
|
||||
#define FNAME_LEN 256
|
||||
|
||||
#define NOTICE_TXTPREFIX "" /* Prefix for NOTICEs from the server
|
||||
to users. Some servers use '*'. */
|
||||
/** Max. lenght of fully qualified host names (e. g. "abc.domain.tld"). */
|
||||
#define HOST_LEN 256
|
||||
|
||||
|
||||
/* Size of structures */
|
||||
|
||||
/** Max. count of configurable servers. */
|
||||
#define MAX_SERVERS 16
|
||||
|
||||
/** Max. number of WHOWAS list items that can be stored. */
|
||||
#define MAX_WHOWAS 64
|
||||
|
||||
/** Size of default connection pool. */
|
||||
#define CONNECTION_POOL 100
|
||||
|
||||
|
||||
/* Hard-coded (default) options */
|
||||
|
||||
/** Delay after startup before outgoing connections are initiated in seconds. */
|
||||
#define STARTUP_DELAY 1
|
||||
|
||||
/** Time to delay re-connect attempts in seconds. */
|
||||
#define RECONNECT_DELAY 3
|
||||
|
||||
/** Configuration file name. */
|
||||
#define CONFIG_FILE "/ngircd.conf"
|
||||
|
||||
/** Name of the MOTD file. */
|
||||
#define MOTD_FILE "/ngircd.motd"
|
||||
|
||||
/** Default chroot() directory. */
|
||||
#define CHROOT_DIR ""
|
||||
|
||||
/** Default file for the process ID. */
|
||||
#define PID_FILE ""
|
||||
|
||||
|
||||
/* Sizes of "IRC elements": nicks, users, ... */
|
||||
|
||||
/** Max. length of an IRC ID (incl. NULL); see RFC 2812 section 1.1 and 1.2.1. */
|
||||
#define CLIENT_ID_LEN 64
|
||||
|
||||
/** Default nick length (including NULL), see. RFC 2812 section 1.2.1. */
|
||||
#define CLIENT_NICK_LEN_DEFAULT 10
|
||||
|
||||
/** Maximum nick name length (including NULL). */
|
||||
#define CLIENT_NICK_LEN 32
|
||||
|
||||
/** Max. password length (including NULL). */
|
||||
#define CLIENT_PASS_LEN 21
|
||||
|
||||
/** Max. length of user name ("login"; incl. NULL), RFC 2812, section 1.2.1. */
|
||||
#define CLIENT_USER_LEN 10
|
||||
|
||||
/** Max. length of "real names" (including NULL). */
|
||||
#define CLIENT_NAME_LEN 32
|
||||
|
||||
/** Max. host name length (including NULL). */
|
||||
#define CLIENT_HOST_LEN 64
|
||||
|
||||
/** Max. length of all client modes (including NULL). */
|
||||
#define CLIENT_MODE_LEN 16
|
||||
|
||||
/** Max. length of server info texts (including NULL). */
|
||||
#define CLIENT_INFO_LEN 64
|
||||
|
||||
/** Max. length of away messages (including NULL). */
|
||||
#define CLIENT_AWAY_LEN 128
|
||||
|
||||
/** Max. length of client flags (including NULL). */
|
||||
#define CLIENT_FLAGS_LEN 16
|
||||
|
||||
/** Max. length of a channel name (including NULL), see RFC 2812 section 1.3. */
|
||||
#define CHANNEL_NAME_LEN 51
|
||||
|
||||
/** Max. length of channel modes (including NULL). */
|
||||
#define CHANNEL_MODE_LEN 9
|
||||
|
||||
/** Max. IRC command length (including NULL), see. RFC 2812 section 3.2. */
|
||||
#define COMMAND_LEN 513
|
||||
|
||||
|
||||
/* Read and write buffer sizes */
|
||||
|
||||
/** Size of the read buffer of a connection in bytes. */
|
||||
#define READBUFFER_LEN 2048
|
||||
|
||||
/** Size that triggers write buffer flushing if more space is needed. */
|
||||
#define WRITEBUFFER_FLUSH_LEN 4096
|
||||
|
||||
/** Maximum size of the write buffer of a connection in bytes. */
|
||||
#define WRITEBUFFER_MAX_LEN 32768
|
||||
|
||||
/** Maximum size of the write buffer of a server link connection in bytes. */
|
||||
#define WRITEBUFFER_SLINK_LEN 65536
|
||||
|
||||
|
||||
/* IRC/IRC+ protocol */
|
||||
|
||||
/** Implemented IRC protocol version, see RFC 2813 section 4.1.1. */
|
||||
#define PROTOVER "0210"
|
||||
|
||||
/** Protocol suffix, see RFC 2813 section 4.1.1. */
|
||||
#define PROTOIRC "-IRC"
|
||||
|
||||
/** Protocol suffix used by the IRC+ protocol, see <doc/Protocol.txt>. */
|
||||
#define PROTOIRCPLUS "-IRC+"
|
||||
|
||||
#ifdef IRCPLUS
|
||||
/** Standard IRC+ flags. */
|
||||
# define IRCPLUSFLAGS "CHLS"
|
||||
#endif
|
||||
|
||||
/** Supported user modes. */
|
||||
#define USERMODES "acCiorRswx"
|
||||
|
||||
/** Supported channel modes. */
|
||||
#define CHANMODES "beiIklmnoOPRstvz"
|
||||
|
||||
/** Away message for users connected to linked servers. */
|
||||
#define DEFAULT_AWAY_MSG "Away"
|
||||
|
||||
/** Default ID for "topic owner". */
|
||||
#define DEFAULT_TOPIC_ID "-Server-"
|
||||
|
||||
/** Prefix for NOTICEs from the server to users. Some servers use '*'. */
|
||||
#define NOTICE_TXTPREFIX ""
|
||||
|
||||
/** Suffix for oversized messages that have been shortened and cut off. */
|
||||
#define CUT_TXTSUFFIX "[CUT]"
|
||||
|
||||
|
||||
/* Defaults and limits for IRC commands */
|
||||
|
||||
/** Max. number of LIST replies. */
|
||||
#define MAX_RPL_LIST 100
|
||||
|
||||
/** Max. number of elemets allowed in channel invite and ban lists. */
|
||||
#define MAX_HNDL_CHANNEL_LISTS 50
|
||||
|
||||
/** Max. number of channel modes with arguments per MODE command. */
|
||||
#define MAX_HNDL_MODES_ARG 5
|
||||
|
||||
/** Max. number of WHO replies. */
|
||||
#define MAX_RPL_WHO 25
|
||||
|
||||
/** Max. number of WHOIS replies. */
|
||||
#define MAX_RPL_WHOIS 10
|
||||
|
||||
/** Default count of WHOWAS command replies. */
|
||||
#define DEF_RPL_WHOWAS 5
|
||||
|
||||
/** Max count of WHOWAS command replies. */
|
||||
#define MAX_RPL_WHOWAS 25
|
||||
|
||||
#define CUT_TXTSUFFIX "[CUT]" /* Suffix for oversized messages that
|
||||
have been shortened and cut off. */
|
||||
|
||||
#endif
|
||||
|
||||
|
157
src/ngircd/io.c
157
src/ngircd/io.c
@@ -41,6 +41,7 @@ typedef struct {
|
||||
|
||||
#define INIT_IOEVENT { NULL, -1, 0, NULL }
|
||||
#define IO_ERROR 4
|
||||
#define MAX_EVENTS 100
|
||||
|
||||
#ifdef HAVE_EPOLL_CREATE
|
||||
# define IO_USE_EPOLL 1
|
||||
@@ -54,7 +55,7 @@ typedef struct {
|
||||
# ifdef HAVE_SYS_DEVPOLL_H
|
||||
# define IO_USE_DEVPOLL 1
|
||||
# else
|
||||
# ifdef HAVE_POLL
|
||||
# if defined(HAVE_POLL) && defined(HAVE_POLL_H)
|
||||
# define IO_USE_POLL 1
|
||||
# else
|
||||
# ifdef HAVE_SELECT
|
||||
@@ -160,39 +161,34 @@ io_dispatch_devpoll(struct timeval *tv)
|
||||
{
|
||||
struct dvpoll dvp;
|
||||
time_t sec = tv->tv_sec * 1000;
|
||||
int i, total, ret, timeout = tv->tv_usec + sec;
|
||||
int i, ret, timeout = tv->tv_usec + sec;
|
||||
short what;
|
||||
struct pollfd p[100];
|
||||
struct pollfd p[MAX_EVENTS];
|
||||
|
||||
if (timeout < 0)
|
||||
timeout = 1000;
|
||||
|
||||
total = 0;
|
||||
do {
|
||||
dvp.dp_timeout = timeout;
|
||||
dvp.dp_nfds = 100;
|
||||
dvp.dp_fds = p;
|
||||
ret = ioctl(io_masterfd, DP_POLL, &dvp);
|
||||
total += ret;
|
||||
if (ret <= 0)
|
||||
return total;
|
||||
for (i=0; i < ret ; i++) {
|
||||
what = 0;
|
||||
if (p[i].revents & (POLLIN|POLLPRI))
|
||||
what = IO_WANTREAD;
|
||||
dvp.dp_timeout = timeout;
|
||||
dvp.dp_nfds = MAX_EVENTS;
|
||||
dvp.dp_fds = p;
|
||||
ret = ioctl(io_masterfd, DP_POLL, &dvp);
|
||||
|
||||
if (p[i].revents & POLLOUT)
|
||||
what |= IO_WANTWRITE;
|
||||
for (i=0; i < ret ; i++) {
|
||||
what = 0;
|
||||
if (p[i].revents & (POLLIN|POLLPRI))
|
||||
what = IO_WANTREAD;
|
||||
|
||||
if (p[i].revents && !what) {
|
||||
/* other flag is set, probably POLLERR */
|
||||
what = IO_ERROR;
|
||||
}
|
||||
io_docallback(p[i].fd, what);
|
||||
if (p[i].revents & POLLOUT)
|
||||
what |= IO_WANTWRITE;
|
||||
|
||||
if (p[i].revents && !what) {
|
||||
/* other flag is set, probably POLLERR */
|
||||
what = IO_ERROR;
|
||||
}
|
||||
} while (ret == 100);
|
||||
io_docallback(p[i].fd, what);
|
||||
}
|
||||
|
||||
return total;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -462,37 +458,30 @@ static int
|
||||
io_dispatch_epoll(struct timeval *tv)
|
||||
{
|
||||
time_t sec = tv->tv_sec * 1000;
|
||||
int i, total = 0, ret, timeout = tv->tv_usec + sec;
|
||||
struct epoll_event epoll_ev[100];
|
||||
int i, ret, timeout = tv->tv_usec + sec;
|
||||
struct epoll_event epoll_ev[MAX_EVENTS];
|
||||
short type;
|
||||
|
||||
if (timeout < 0)
|
||||
timeout = 1000;
|
||||
|
||||
do {
|
||||
ret = epoll_wait(io_masterfd, epoll_ev, 100, timeout);
|
||||
total += ret;
|
||||
if (ret <= 0)
|
||||
return total;
|
||||
ret = epoll_wait(io_masterfd, epoll_ev, MAX_EVENTS, timeout);
|
||||
|
||||
for (i = 0; i < ret; i++) {
|
||||
type = 0;
|
||||
if (epoll_ev[i].events & (EPOLLERR | EPOLLHUP))
|
||||
type = IO_ERROR;
|
||||
for (i = 0; i < ret; i++) {
|
||||
type = 0;
|
||||
if (epoll_ev[i].events & (EPOLLERR | EPOLLHUP))
|
||||
type = IO_ERROR;
|
||||
|
||||
if (epoll_ev[i].events & (EPOLLIN | EPOLLPRI))
|
||||
type |= IO_WANTREAD;
|
||||
if (epoll_ev[i].events & (EPOLLIN | EPOLLPRI))
|
||||
type |= IO_WANTREAD;
|
||||
|
||||
if (epoll_ev[i].events & EPOLLOUT)
|
||||
type |= IO_WANTWRITE;
|
||||
if (epoll_ev[i].events & EPOLLOUT)
|
||||
type |= IO_WANTWRITE;
|
||||
|
||||
io_docallback(epoll_ev[i].data.fd, type);
|
||||
}
|
||||
io_docallback(epoll_ev[i].data.fd, type);
|
||||
}
|
||||
|
||||
timeout = 0;
|
||||
} while (ret == 100);
|
||||
|
||||
return total;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -576,58 +565,50 @@ io_event_change_kqueue(int fd, short what, const int action)
|
||||
static int
|
||||
io_dispatch_kqueue(struct timeval *tv)
|
||||
{
|
||||
int i, total = 0, ret;
|
||||
struct kevent kev[100];
|
||||
int i, ret;
|
||||
struct kevent kev[MAX_EVENTS];
|
||||
struct kevent *newevents;
|
||||
struct timespec ts;
|
||||
int newevents_len;
|
||||
ts.tv_sec = tv->tv_sec;
|
||||
ts.tv_nsec = tv->tv_usec * 1000;
|
||||
|
||||
do {
|
||||
newevents_len = (int) array_length(&io_evcache, sizeof (struct kevent));
|
||||
newevents = (newevents_len > 0) ? array_start(&io_evcache) : NULL;
|
||||
assert(newevents_len >= 0);
|
||||
newevents_len = (int) array_length(&io_evcache, sizeof (struct kevent));
|
||||
newevents = (newevents_len > 0) ? array_start(&io_evcache) : NULL;
|
||||
assert(newevents_len >= 0);
|
||||
|
||||
ret = kevent(io_masterfd, newevents, newevents_len, kev, 100, &ts);
|
||||
if (newevents && ret != -1)
|
||||
array_trunc(&io_evcache);
|
||||
ret = kevent(io_masterfd, newevents, newevents_len, kev, MAX_EVENTS, &ts);
|
||||
if (newevents && ret != -1)
|
||||
array_trunc(&io_evcache);
|
||||
|
||||
total += ret;
|
||||
if (ret <= 0)
|
||||
return total;
|
||||
|
||||
for (i = 0; i < ret; i++) {
|
||||
io_debug("dispatch_kqueue: fd, kev.flags", (int)kev[i].ident, kev[i].flags);
|
||||
if (kev[i].flags & (EV_EOF|EV_ERROR)) {
|
||||
if (kev[i].flags & EV_ERROR)
|
||||
Log(LOG_ERR, "kevent fd %d: EV_ERROR (%s)",
|
||||
(int)kev[i].ident, strerror((int)kev[i].data));
|
||||
io_docallback((int)kev[i].ident, IO_ERROR);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (kev[i].filter) {
|
||||
case EVFILT_READ:
|
||||
io_docallback((int)kev[i].ident, IO_WANTREAD);
|
||||
break;
|
||||
case EVFILT_WRITE:
|
||||
io_docallback((int)kev[i].ident, IO_WANTWRITE);
|
||||
break;
|
||||
default:
|
||||
LogDebug("Unknown kev.filter number %d for fd %d",
|
||||
kev[i].filter, kev[i].ident);
|
||||
/* Fall through */
|
||||
case EV_ERROR:
|
||||
io_docallback((int)kev[i].ident, IO_ERROR);
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < ret; i++) {
|
||||
io_debug("dispatch_kqueue: fd, kev.flags", (int)kev[i].ident, kev[i].flags);
|
||||
if (kev[i].flags & (EV_EOF|EV_ERROR)) {
|
||||
if (kev[i].flags & EV_ERROR)
|
||||
Log(LOG_ERR, "kevent fd %d: EV_ERROR (%s)",
|
||||
(int)kev[i].ident, strerror((int)kev[i].data));
|
||||
io_docallback((int)kev[i].ident, IO_ERROR);
|
||||
continue;
|
||||
}
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 0;
|
||||
} while (ret == 100);
|
||||
|
||||
return total;
|
||||
switch (kev[i].filter) {
|
||||
case EVFILT_READ:
|
||||
io_docallback((int)kev[i].ident, IO_WANTREAD);
|
||||
break;
|
||||
case EVFILT_WRITE:
|
||||
io_docallback((int)kev[i].ident, IO_WANTWRITE);
|
||||
break;
|
||||
default:
|
||||
LogDebug("Unknown kev.filter number %d for fd %d",
|
||||
kev[i].filter, kev[i].ident);
|
||||
/* Fall through */
|
||||
case EV_ERROR:
|
||||
io_docallback((int)kev[i].ident, IO_ERROR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "match.h"
|
||||
#include "messages.h"
|
||||
#include "parse.h"
|
||||
#include "irc.h"
|
||||
#include "irc-info.h"
|
||||
#include "irc-write.h"
|
||||
#include "conf.h"
|
||||
@@ -81,7 +82,7 @@ static bool
|
||||
join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
|
||||
const char *key)
|
||||
{
|
||||
bool is_invited, is_banned;
|
||||
bool is_invited, is_banned, is_exception;
|
||||
const char *channel_modes;
|
||||
|
||||
/* Allow IRC operators to overwrite channel limits */
|
||||
@@ -89,9 +90,10 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
|
||||
return true;
|
||||
|
||||
is_banned = Lists_Check(Channel_GetListBans(chan), Client);
|
||||
is_exception = Lists_Check(Channel_GetListExcepts(chan), Client);
|
||||
is_invited = Lists_Check(Channel_GetListInvites(chan), Client);
|
||||
|
||||
if (is_banned && !is_invited) {
|
||||
if (is_banned && !is_invited && !is_exception) {
|
||||
/* Client is banned from channel (and not on invite list) */
|
||||
IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG,
|
||||
Client_ID(Client), channame);
|
||||
@@ -137,6 +139,13 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strchr(channel_modes, 'R') && !strchr(Client_Modes(Client), 'R')) {
|
||||
/* Only registered users are allowed! */
|
||||
IRC_WriteStrClient(Client, ERR_REGONLYCHANNEL_MSG,
|
||||
Client_ID(Client), channame);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} /* join_allowed */
|
||||
|
||||
@@ -237,7 +246,7 @@ join_forward(CLIENT *Client, CLIENT *target, CHANNEL *chan,
|
||||
IRC_WriteStrChannelPrefix(Client, chan, target, false,
|
||||
"JOIN :%s", channame);
|
||||
|
||||
/* syncronize channel modes */
|
||||
/* synchronize channel modes */
|
||||
if (modes[1]) {
|
||||
IRC_WriteStrChannelPrefix(Client, chan, target, false,
|
||||
"MODE %s +%s %s", channame,
|
||||
@@ -294,9 +303,9 @@ join_send_topic(CLIENT *Client, CLIENT *target, CHANNEL *chan,
|
||||
*
|
||||
* See RFC 2812, 3.2.1 "Join message"; RFC 2813, 4.2.1 "Join message".
|
||||
*
|
||||
* @param Client The client from which this command has been received
|
||||
* @param Req Request structure with prefix and all parameters
|
||||
* @returns CONNECTED or DISCONNECTED
|
||||
* @param Client The client from which this command has been received
|
||||
* @param Req Request structure with prefix and all parameters
|
||||
* @returns CONNECTED or DISCONNECTED
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_JOIN( CLIENT *Client, REQUEST *Req )
|
||||
@@ -305,8 +314,8 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
|
||||
CLIENT *target;
|
||||
CHANNEL *chan;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
assert (Client != NULL);
|
||||
assert (Req != NULL);
|
||||
|
||||
/* Bad number of arguments? */
|
||||
if (Req->argc < 1 || Req->argc > 2)
|
||||
@@ -320,7 +329,8 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
|
||||
target = Client;
|
||||
|
||||
if (!target)
|
||||
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix);
|
||||
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client), Req->prefix);
|
||||
|
||||
/* Is argument "0"? */
|
||||
if (Req->argc == 1 && !strncmp("0", Req->argv[0], 2))
|
||||
@@ -352,24 +362,35 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
|
||||
|
||||
chan = Channel_Search(channame);
|
||||
if (!chan && Conf_PredefChannelsOnly) {
|
||||
/* channel must be created, but server does not allow this */
|
||||
IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG, Client_ID(Client), channame);
|
||||
break;
|
||||
/* channel must be created, but forbidden by config */
|
||||
IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG,
|
||||
Client_ID(Client), channame);
|
||||
goto join_next;
|
||||
}
|
||||
|
||||
/* Local client? */
|
||||
if (Client_Type(Client) == CLIENT_USER) {
|
||||
if (chan) {
|
||||
/* Already existing channel: already member? */
|
||||
if (Channel_IsMemberOf(chan, Client))
|
||||
goto join_next;
|
||||
}
|
||||
|
||||
/* Test if the user has reached the channel limit */
|
||||
if ((Conf_MaxJoins > 0) &&
|
||||
(Channel_CountForUser(Client) >= Conf_MaxJoins))
|
||||
return IRC_WriteStrClient(Client,
|
||||
(Channel_CountForUser(Client) >= Conf_MaxJoins)) {
|
||||
if (!IRC_WriteStrClient(Client,
|
||||
ERR_TOOMANYCHANNELS_MSG,
|
||||
Client_ID(Client), channame);
|
||||
Client_ID(Client), channame))
|
||||
return DISCONNECTED;
|
||||
goto join_next;
|
||||
}
|
||||
|
||||
if (chan) {
|
||||
/* Already existing channel: check if the
|
||||
* client is allowed to join */
|
||||
if (!join_allowed(Client, chan, channame, key))
|
||||
break;
|
||||
goto join_next;
|
||||
} else {
|
||||
/* New channel: first user will become channel
|
||||
* operator unless this is a modeless channel */
|
||||
@@ -392,7 +413,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
|
||||
|
||||
/* Join channel (and create channel if it doesn't exist) */
|
||||
if (!Channel_Join(target, channame))
|
||||
break;
|
||||
goto join_next;
|
||||
|
||||
if (!chan) { /* channel is new; it has been created above */
|
||||
chan = Channel_Search(channame);
|
||||
@@ -411,6 +432,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
|
||||
if (!join_send_topic(Client, target, chan, channame))
|
||||
break; /* write error */
|
||||
|
||||
join_next:
|
||||
/* next channel? */
|
||||
channame = strtok_r(NULL, ",", &lastchan);
|
||||
if (channame && key)
|
||||
@@ -582,9 +604,9 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
|
||||
* This implementation handles the local case as well as the forwarding of the
|
||||
* LIST command to other servers in the IRC network.
|
||||
*
|
||||
* @param Client The client from which this command has been received
|
||||
* @param Req Request structure with prefix and all parameters
|
||||
* @returns CONNECTED or DISCONNECTED
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_LIST( CLIENT *Client, REQUEST *Req )
|
||||
@@ -592,79 +614,84 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
|
||||
char *pattern;
|
||||
CHANNEL *chan;
|
||||
CLIENT *from, *target;
|
||||
int count = 0;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
assert(Client != NULL);
|
||||
assert(Req != NULL);
|
||||
|
||||
/* Bad number of prameters? */
|
||||
if( Req->argc > 2 )
|
||||
return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID( Client ), Req->command );
|
||||
if (Req->argc > 2)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
if( Req->argc > 0 )
|
||||
pattern = strtok( Req->argv[0], "," );
|
||||
if (Req->argc > 0)
|
||||
pattern = strtok(Req->argv[0], ",");
|
||||
else
|
||||
pattern = "*";
|
||||
|
||||
/* Get sender from prefix, if any */
|
||||
if( Client_Type( Client ) == CLIENT_SERVER )
|
||||
from = Client_Search( Req->prefix );
|
||||
if (Client_Type(Client) == CLIENT_SERVER)
|
||||
from = Client_Search(Req->prefix);
|
||||
else
|
||||
from = Client;
|
||||
|
||||
if( ! from )
|
||||
return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG,
|
||||
Client_ID( Client ), Req->prefix );
|
||||
if (!from)
|
||||
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
|
||||
Client_ID(Client), Req->prefix);
|
||||
|
||||
if( Req->argc == 2 )
|
||||
{
|
||||
if (Req->argc == 2) {
|
||||
/* Forward to other server? */
|
||||
target = Client_Search( Req->argv[1] );
|
||||
if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER ))
|
||||
return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG,
|
||||
Client_ID( Client ), Req->argv[1] );
|
||||
target = Client_Search(Req->argv[1]);
|
||||
if (! target || Client_Type(target) != CLIENT_SERVER)
|
||||
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
|
||||
Client_ID(Client),
|
||||
Req->argv[1]);
|
||||
|
||||
if( target != Client_ThisServer( ))
|
||||
{
|
||||
if (target != Client_ThisServer()) {
|
||||
/* Target is indeed an other server, forward it! */
|
||||
return IRC_WriteStrClientPrefix( target, from,
|
||||
"LIST %s :%s", Client_ID( from ),
|
||||
Req->argv[1] );
|
||||
return IRC_WriteStrClientPrefix(target, from,
|
||||
"LIST %s :%s",
|
||||
Req->argv[0],
|
||||
Req->argv[1]);
|
||||
}
|
||||
}
|
||||
|
||||
while( pattern )
|
||||
{
|
||||
while (pattern) {
|
||||
/* Loop through all the channels */
|
||||
chan = Channel_First( );
|
||||
while( chan )
|
||||
{
|
||||
if (Req->argc > 0)
|
||||
ngt_LowerStr(pattern);
|
||||
chan = Channel_First();
|
||||
while (chan) {
|
||||
/* Check search pattern */
|
||||
if( Match( pattern, Channel_Name( chan )))
|
||||
{
|
||||
if (MatchCaseInsensitive(pattern, Channel_Name(chan))) {
|
||||
/* Gotcha! */
|
||||
if( ! strchr( Channel_Modes( chan ), 's' ) ||
|
||||
Channel_IsMemberOf( chan, from ))
|
||||
{
|
||||
if( ! IRC_WriteStrClient( from,
|
||||
RPL_LIST_MSG, Client_ID( from ),
|
||||
Channel_Name( chan ),
|
||||
Channel_MemberCount( chan ),
|
||||
Channel_Topic( chan )))
|
||||
if (!strchr(Channel_Modes(chan), 's')
|
||||
|| Channel_IsMemberOf(chan, from)) {
|
||||
if (IRC_CheckListTooBig(from, count,
|
||||
MAX_RPL_LIST,
|
||||
"LIST"))
|
||||
break;
|
||||
if (!IRC_WriteStrClient(from,
|
||||
RPL_LIST_MSG, Client_ID(from),
|
||||
Channel_Name(chan),
|
||||
Channel_MemberCount(chan),
|
||||
Channel_Topic( chan )))
|
||||
return DISCONNECTED;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
chan = Channel_Next( chan );
|
||||
chan = Channel_Next(chan);
|
||||
}
|
||||
|
||||
/* Get next name ... */
|
||||
if( Req->argc > 0 )
|
||||
pattern = strtok( NULL, "," );
|
||||
if(Req->argc > 0)
|
||||
pattern = strtok(NULL, ",");
|
||||
else
|
||||
pattern = NULL;
|
||||
}
|
||||
|
||||
return IRC_WriteStrClient( from, RPL_LISTEND_MSG, Client_ID( from ));
|
||||
IRC_SetPenalty(from, 2);
|
||||
return IRC_WriteStrClient(from, RPL_LISTEND_MSG, Client_ID(from));
|
||||
} /* IRC_LIST */
|
||||
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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
|
||||
@@ -28,13 +28,16 @@
|
||||
#include "conn-func.h"
|
||||
#include "conn-zip.h"
|
||||
#include "channel.h"
|
||||
#include "class.h"
|
||||
#include "conf.h"
|
||||
#include "defines.h"
|
||||
#include "lists.h"
|
||||
#include "log.h"
|
||||
#include "messages.h"
|
||||
#include "match.h"
|
||||
#include "tool.h"
|
||||
#include "parse.h"
|
||||
#include "irc.h"
|
||||
#include "irc-write.h"
|
||||
|
||||
#include "exp.h"
|
||||
@@ -152,6 +155,15 @@ IRC_INFO(CLIENT * Client, REQUEST * Req)
|
||||
} /* IRC_INFO */
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the IRC "ISON" command.
|
||||
*
|
||||
* See RFC 2812, 4.9 "Ison message".
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_ISON( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
@@ -160,80 +172,103 @@ IRC_ISON( CLIENT *Client, REQUEST *Req )
|
||||
char *ptr;
|
||||
int 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 );
|
||||
/* Bad number of arguments? */
|
||||
if (Req->argc < 1)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
strlcpy( rpl, RPL_ISON_MSG, sizeof rpl );
|
||||
for( i = 0; i < Req->argc; i++ )
|
||||
{
|
||||
ptr = strtok( Req->argv[i], " " );
|
||||
while( ptr )
|
||||
{
|
||||
ngt_TrimStr( ptr );
|
||||
c = Client_Search( ptr );
|
||||
if( c && ( Client_Type( c ) == CLIENT_USER ))
|
||||
{
|
||||
/* Dieser Nick ist "online" */
|
||||
strlcat( rpl, ptr, sizeof( rpl ));
|
||||
strlcat( rpl, " ", sizeof( rpl ));
|
||||
strlcpy(rpl, RPL_ISON_MSG, sizeof rpl);
|
||||
for (i = 0; i < Req->argc; i++) {
|
||||
/* "All" ircd even parse ":<x> <y> ..." arguments and split
|
||||
* them up; so we do the same ... */
|
||||
ptr = strtok(Req->argv[i], " ");
|
||||
while (ptr) {
|
||||
ngt_TrimStr(ptr);
|
||||
c = Client_Search(ptr);
|
||||
if (c && Client_Type(c) == CLIENT_USER) {
|
||||
strlcat(rpl, Client_ID(c), sizeof(rpl));
|
||||
strlcat(rpl, " ", sizeof(rpl));
|
||||
}
|
||||
ptr = strtok( NULL, " " );
|
||||
ptr = strtok(NULL, " ");
|
||||
}
|
||||
}
|
||||
ngt_TrimLastChr(rpl, ' ');
|
||||
|
||||
return IRC_WriteStrClient( Client, rpl, Client_ID( Client ) );
|
||||
return IRC_WriteStrClient(Client, rpl, Client_ID(Client));
|
||||
} /* IRC_ISON */
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the IRC "LINKS" command.
|
||||
*
|
||||
* See RFC 2812, 3.4.5 "Links message".
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_LINKS( CLIENT *Client, REQUEST *Req )
|
||||
IRC_LINKS(CLIENT *Client, REQUEST *Req)
|
||||
{
|
||||
CLIENT *target, *from, *c;
|
||||
char *mask;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
assert(Client != NULL);
|
||||
assert(Req != NULL);
|
||||
|
||||
if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
|
||||
IRC_SetPenalty(Client, 1);
|
||||
|
||||
/* Server-Mask ermitteln */
|
||||
if( Req->argc > 0 ) mask = Req->argv[Req->argc - 1];
|
||||
else mask = "*";
|
||||
if (Req->argc > 2)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
/* Absender 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 );
|
||||
/* Get pointer to server mask or "*", if none given */
|
||||
if (Req->argc > 0)
|
||||
mask = Req->argv[Req->argc - 1];
|
||||
else
|
||||
mask = "*";
|
||||
|
||||
/* An anderen Server forwarden? */
|
||||
if( Req->argc == 2 )
|
||||
{
|
||||
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] );
|
||||
else if( target != Client_ThisServer( )) return IRC_WriteStrClientPrefix( target, from, "LINKS %s %s", Req->argv[0], Req->argv[1] );
|
||||
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);
|
||||
|
||||
/* Forward? */
|
||||
if (Req->argc == 2) {
|
||||
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] );
|
||||
else
|
||||
if (target != Client_ThisServer())
|
||||
return IRC_WriteStrClientPrefix(target, from,
|
||||
"LINKS %s %s", Req->argv[0],
|
||||
Req->argv[1]);
|
||||
}
|
||||
|
||||
/* Wer ist der Absender? */
|
||||
if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
|
||||
else target = Client;
|
||||
if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
|
||||
|
||||
c = Client_First( );
|
||||
while( c )
|
||||
{
|
||||
if( Client_Type( c ) == CLIENT_SERVER )
|
||||
{
|
||||
if( ! IRC_WriteStrClient( target, RPL_LINKS_MSG, Client_ID( target ), Client_ID( c ), Client_ID( Client_TopServer( c ) ? Client_TopServer( c ) : Client_ThisServer( )), Client_Hops( c ), Client_Info( c ))) return DISCONNECTED;
|
||||
c = Client_First();
|
||||
while (c) {
|
||||
if (Client_Type(c) == CLIENT_SERVER
|
||||
&& MatchCaseInsensitive(mask, Client_ID(c))) {
|
||||
if (!IRC_WriteStrClient(from, RPL_LINKS_MSG,
|
||||
Client_ID(from), Client_ID(c),
|
||||
Client_ID(Client_TopServer(c)
|
||||
? Client_TopServer(c)
|
||||
: Client_ThisServer()),
|
||||
Client_Hops(c), Client_Info(c)))
|
||||
return DISCONNECTED;
|
||||
}
|
||||
c = Client_Next( c );
|
||||
c = Client_Next(c);
|
||||
}
|
||||
|
||||
IRC_SetPenalty( target, 1 );
|
||||
return IRC_WriteStrClient( target, RPL_ENDOFLINKS_MSG, Client_ID( target ), mask );
|
||||
return IRC_WriteStrClient(from, RPL_ENDOFLINKS_MSG,
|
||||
Client_ID(from), mask);
|
||||
} /* IRC_LINKS */
|
||||
|
||||
|
||||
@@ -478,6 +513,8 @@ IRC_STATS( CLIENT *Client, REQUEST *Req )
|
||||
COMMAND *cmd;
|
||||
time_t time_now;
|
||||
unsigned int days, hrs, mins;
|
||||
struct list_head *list;
|
||||
struct list_elem *list_item;
|
||||
|
||||
assert(Client != NULL);
|
||||
assert(Req != NULL);
|
||||
@@ -516,6 +553,28 @@ IRC_STATS( CLIENT *Client, REQUEST *Req )
|
||||
query = '*';
|
||||
|
||||
switch (query) {
|
||||
case 'g': /* Network-wide bans ("G-Lines") */
|
||||
case 'G':
|
||||
case 'k': /* Server-local bans ("K-Lines") */
|
||||
case 'K':
|
||||
if (!Client_HasMode(from, 'o'))
|
||||
return IRC_WriteStrClient(from, ERR_NOPRIVILEGES_MSG,
|
||||
Client_ID(from));
|
||||
if (query == 'g' || query == 'G')
|
||||
list = Class_GetList(CLASS_GLINE);
|
||||
else
|
||||
list = Class_GetList(CLASS_KLINE);
|
||||
list_item = Lists_GetFirst(list);
|
||||
while (list_item) {
|
||||
if (!IRC_WriteStrClient(from, RPL_STATSXLINE_MSG,
|
||||
Client_ID(from), query,
|
||||
Lists_GetMask(list_item),
|
||||
Lists_GetValidity(list_item),
|
||||
Lists_GetReason(list_item)))
|
||||
return DISCONNECTED;
|
||||
list_item = Lists_GetNext(list_item);
|
||||
}
|
||||
break;
|
||||
case 'l': /* Link status (servers and own link) */
|
||||
case 'L':
|
||||
time_now = time(NULL);
|
||||
@@ -589,10 +648,10 @@ IRC_STATS( CLIENT *Client, REQUEST *Req )
|
||||
* therefore answers with ERR_SUMMONDISABLED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_SUMMON(CLIENT * Client, REQUEST * Req)
|
||||
IRC_SUMMON(CLIENT * Client, UNUSED REQUEST * Req)
|
||||
{
|
||||
return IRC_WriteStrClient(Client, ERR_SUMMONDISABLED_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
Client_ID(Client));
|
||||
} /* IRC_SUMMON */
|
||||
|
||||
|
||||
@@ -682,10 +741,10 @@ IRC_USERHOST(CLIENT *Client, REQUEST *Req)
|
||||
* See RFC 2812 section 4.6. As suggested there the command is disabled.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_USERS(CLIENT * Client, REQUEST * Req)
|
||||
IRC_USERS(CLIENT * Client, UNUSED REQUEST * Req)
|
||||
{
|
||||
return IRC_WriteStrClient(Client, ERR_USERSDISABLED_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
Client_ID(Client));
|
||||
} /* IRC_USERS */
|
||||
|
||||
|
||||
@@ -758,8 +817,16 @@ who_flags_qualifier(const char *chan_user_modes)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send WHO reply for a "channel target" ("WHO #channel").
|
||||
*
|
||||
* @param Client Client requesting the information.
|
||||
* @param Chan Channel being requested.
|
||||
* @param OnlyOps Only display IRC operators.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
static bool
|
||||
IRC_Send_WHO(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
|
||||
IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
|
||||
{
|
||||
bool is_visible, is_member, is_ircop;
|
||||
CL2CHAN *cl2chan;
|
||||
@@ -767,6 +834,7 @@ IRC_Send_WHO(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
|
||||
const char *chan_user_modes;
|
||||
char flags[8];
|
||||
CLIENT *c;
|
||||
int count = 0;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Chan != NULL );
|
||||
@@ -775,7 +843,8 @@ IRC_Send_WHO(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
|
||||
|
||||
/* Secret channel? */
|
||||
if (!is_member && strchr(Channel_Modes(Chan), 's'))
|
||||
return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client), Channel_Name(Chan));
|
||||
return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG,
|
||||
Client_ID(Client), Channel_Name(Chan));
|
||||
|
||||
cl2chan = Channel_FirstMember(Chan);
|
||||
for (; cl2chan ; cl2chan = Channel_NextMember(Chan, cl2chan)) {
|
||||
@@ -788,141 +857,178 @@ IRC_Send_WHO(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
|
||||
|
||||
is_visible = strchr(client_modes, 'i') == NULL;
|
||||
if (is_member || is_visible) {
|
||||
if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO"))
|
||||
break;
|
||||
|
||||
strcpy(flags, who_flags_status(client_modes));
|
||||
if (is_ircop)
|
||||
strlcat(flags, "*", sizeof(flags));
|
||||
|
||||
chan_user_modes = Channel_UserModes(Chan, c);
|
||||
strlcat(flags, who_flags_qualifier(chan_user_modes), sizeof(flags));
|
||||
strlcat(flags, who_flags_qualifier(chan_user_modes),
|
||||
sizeof(flags));
|
||||
|
||||
if (!write_whoreply(Client, c, Channel_Name(Chan), flags))
|
||||
if (!write_whoreply(Client, c, Channel_Name(Chan),
|
||||
flags))
|
||||
return DISCONNECTED;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client), Channel_Name(Chan));
|
||||
} /* IRC_Send_WHO */
|
||||
return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client),
|
||||
Channel_Name(Chan));
|
||||
}
|
||||
|
||||
|
||||
GLOBAL bool
|
||||
IRC_WHO( CLIENT *Client, REQUEST *Req )
|
||||
/**
|
||||
* Send WHO reply for a "mask target" ("WHO m*sk").
|
||||
*
|
||||
* @param Client Client requesting the information.
|
||||
* @param Mask Mask being requested or NULL for "all" clients.
|
||||
* @param OnlyOps Only display IRC operators.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
static bool
|
||||
IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps)
|
||||
{
|
||||
bool only_ops, have_arg, client_match;
|
||||
const char *channelname, *client_modes, *chan_user_modes;
|
||||
char pattern[COMMAND_LEN];
|
||||
char flags[4];
|
||||
CL2CHAN *cl2chan;
|
||||
CHANNEL *chan, *cn;
|
||||
CLIENT *c;
|
||||
CL2CHAN *cl2chan;
|
||||
CHANNEL *chan;
|
||||
bool client_match, is_visible;
|
||||
char flags[4];
|
||||
int count = 0;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
assert (Client != NULL);
|
||||
|
||||
if (Mask)
|
||||
ngt_LowerStr(Mask);
|
||||
|
||||
for (c = Client_First(); c != NULL; c = Client_Next(c)) {
|
||||
if (Client_Type(c) != CLIENT_USER)
|
||||
continue;
|
||||
|
||||
if (OnlyOps && !Client_HasMode(c, 'o'))
|
||||
continue;
|
||||
|
||||
if (Mask) {
|
||||
/* Match pattern against user host/server/name/nick */
|
||||
client_match = MatchCaseInsensitive(Mask,
|
||||
Client_Hostname(c));
|
||||
if (!client_match)
|
||||
client_match = MatchCaseInsensitive(Mask,
|
||||
Client_ID(Client_Introducer(c)));
|
||||
if (!client_match)
|
||||
client_match = MatchCaseInsensitive(Mask,
|
||||
Client_Info(c));
|
||||
if (!client_match)
|
||||
client_match = MatchCaseInsensitive(Mask,
|
||||
Client_ID(c));
|
||||
if (!client_match)
|
||||
continue; /* no match: skip this client */
|
||||
}
|
||||
|
||||
is_visible = !Client_HasMode(c, 'i');
|
||||
|
||||
/* Target client is invisible, but mask matches exactly? */
|
||||
if (!is_visible && Mask && strcasecmp(Client_ID(c), Mask) == 0)
|
||||
is_visible = true;
|
||||
|
||||
/* Target still invisible, but are both on the same channel? */
|
||||
if (!is_visible) {
|
||||
cl2chan = Channel_FirstChannelOf(Client);
|
||||
while (cl2chan && !is_visible) {
|
||||
chan = Channel_GetChannel(cl2chan);
|
||||
if (Channel_IsMemberOf(chan, c))
|
||||
is_visible = true;
|
||||
cl2chan = Channel_NextChannelOf(Client, cl2chan);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_visible) /* target user is not visible */
|
||||
continue;
|
||||
|
||||
if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO"))
|
||||
break;
|
||||
|
||||
strcpy(flags, who_flags_status(Client_Modes(c)));
|
||||
if (strchr(Client_Modes(c), 'o'))
|
||||
strlcat(flags, "*", sizeof(flags));
|
||||
|
||||
if (!write_whoreply(Client, c, "*", flags))
|
||||
return DISCONNECTED;
|
||||
count++;
|
||||
}
|
||||
|
||||
return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client),
|
||||
Mask ? Mask : "*");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the IRC "WHO" command.
|
||||
*
|
||||
* See RFC 2812, 3.6.1 "Who query".
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_WHO(CLIENT *Client, REQUEST *Req)
|
||||
{
|
||||
bool only_ops;
|
||||
CHANNEL *chan;
|
||||
|
||||
assert (Client != NULL);
|
||||
assert (Req != NULL);
|
||||
|
||||
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);
|
||||
|
||||
only_ops = false;
|
||||
have_arg = false;
|
||||
|
||||
if (Req->argc == 2) {
|
||||
if (strcmp(Req->argv[1], "o") == 0)
|
||||
only_ops = true;
|
||||
#ifdef STRICT_RFC
|
||||
else return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
|
||||
else
|
||||
return IRC_WriteStrClient(Client,
|
||||
ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client),
|
||||
Req->command);
|
||||
#endif
|
||||
}
|
||||
|
||||
IRC_SetPenalty(Client, 1);
|
||||
if (Req->argc >= 1) { /* Channel or Mask. */
|
||||
if (Req->argc >= 1) {
|
||||
/* Channel or mask given */
|
||||
chan = Channel_Search(Req->argv[0]);
|
||||
if (chan)
|
||||
return IRC_Send_WHO(Client, chan, only_ops);
|
||||
if (strcmp(Req->argv[0], "0") != 0) { /* RFC stupidity, same as no arguments */
|
||||
have_arg = true;
|
||||
strlcpy(pattern, Req->argv[0], sizeof(pattern));
|
||||
ngt_LowerStr(pattern);
|
||||
if (chan) {
|
||||
/* Members of a channel have been requested */
|
||||
IRC_SetPenalty(Client, 1);
|
||||
return IRC_WHO_Channel(Client, chan, only_ops);
|
||||
}
|
||||
if (strcmp(Req->argv[0], "0") != 0) {
|
||||
/* A mask has been given. But please note this RFC
|
||||
* stupidity: "0" is same as no arguments ... */
|
||||
IRC_SetPenalty(Client, 3);
|
||||
return IRC_WHO_Mask(Client, Req->argv[0], only_ops);
|
||||
}
|
||||
}
|
||||
|
||||
for (c = Client_First(); c != NULL; c = Client_Next(c)) {
|
||||
if (Client_Type(c) != CLIENT_USER)
|
||||
continue;
|
||||
/*
|
||||
* RFC 2812, 3.6.1:
|
||||
* In the absence of the parameter, all visible (users who aren't
|
||||
* invisible (user mode +i) and who don't have a common channel
|
||||
* with the requesting client) are listed.
|
||||
*
|
||||
* The same result can be achieved by using a [sic] of "0"
|
||||
* or any wildcard which will end up matching every visible user.
|
||||
*
|
||||
* The [sic] passed to WHO is matched against users' host, server, real name and
|
||||
* nickname if the channel cannot be found.
|
||||
*/
|
||||
client_modes = Client_Modes(c);
|
||||
if (strchr(client_modes, 'i'))
|
||||
continue;
|
||||
|
||||
if (only_ops && !strchr(client_modes, 'o'))
|
||||
continue;
|
||||
|
||||
if (have_arg) { /* match pattern against user host/server/name/nick */
|
||||
client_match = MatchCaseInsensitive(pattern, Client_Hostname(c)); /* user's host */
|
||||
if (!client_match)
|
||||
client_match = MatchCaseInsensitive(pattern, Client_ID(Client_Introducer(c))); /* server */
|
||||
if (!client_match)
|
||||
client_match = Match(Req->argv[0], Client_Info(c)); /* realname */
|
||||
if (!client_match)
|
||||
client_match = MatchCaseInsensitive(pattern, Client_ID(c)); /* nick name */
|
||||
|
||||
if (!client_match) /* This isn't the client you're looking for */
|
||||
continue;
|
||||
}
|
||||
|
||||
strcpy(flags, who_flags_status(client_modes));
|
||||
|
||||
if (strchr(client_modes, 'o')) /* this client is an operator */
|
||||
strlcat(flags, "*", sizeof(flags));
|
||||
|
||||
/* Search suitable channel */
|
||||
cl2chan = Channel_FirstChannelOf(c);
|
||||
while (cl2chan) {
|
||||
cn = Channel_GetChannel(cl2chan);
|
||||
if (Channel_IsMemberOf(cn, Client) ||
|
||||
!strchr(Channel_Modes(cn), 's'))
|
||||
{
|
||||
channelname = Channel_Name(cn);
|
||||
break;
|
||||
}
|
||||
cl2chan = Channel_NextChannelOf(c, cl2chan);
|
||||
}
|
||||
if (cl2chan) {
|
||||
chan = Channel_GetChannel(cl2chan);
|
||||
chan_user_modes = Channel_UserModes(chan, c);
|
||||
strlcat(flags, who_flags_qualifier(chan_user_modes), sizeof(flags));
|
||||
} else
|
||||
channelname = "*";
|
||||
|
||||
if (!write_whoreply(Client, c, channelname, flags))
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
if (Req->argc > 0)
|
||||
channelname = Req->argv[0];
|
||||
else
|
||||
channelname = "*";
|
||||
|
||||
return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client), channelname);
|
||||
/* No channel or (valid) mask given */
|
||||
IRC_SetPenalty(Client, 2);
|
||||
return IRC_WHO_Mask(Client, NULL, only_ops);
|
||||
} /* IRC_WHO */
|
||||
|
||||
|
||||
/**
|
||||
* Generate WHOIS reply of one actual client.
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param from The client requesting the information ("originator").
|
||||
* @param c The client of which information should be returned.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param from The client requesting the information ("originator").
|
||||
* @param c The client of which information should be returned.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
static bool
|
||||
IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
|
||||
@@ -931,6 +1037,10 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
|
||||
CL2CHAN *cl2chan;
|
||||
CHANNEL *chan;
|
||||
|
||||
assert(Client != NULL);
|
||||
assert(from != NULL);
|
||||
assert(c != NULL);
|
||||
|
||||
/* Nick, user, hostname and client info */
|
||||
if (!IRC_WriteStrClient(from, RPL_WHOISUSER_MSG, Client_ID(from),
|
||||
Client_ID(c), Client_User(c),
|
||||
@@ -988,33 +1098,43 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
|
||||
|
||||
/* IRC-Operator? */
|
||||
if (Client_HasMode(c, 'o') &&
|
||||
!IRC_WriteStrClient(from, RPL_WHOISOPERATOR_MSG,
|
||||
Client_ID(from), Client_ID(c)))
|
||||
return DISCONNECTED;
|
||||
!IRC_WriteStrClient(from, RPL_WHOISOPERATOR_MSG,
|
||||
Client_ID(from), Client_ID(c)))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Connected using SSL? */
|
||||
if (Conn_UsesSSL(Client_Conn(c)) &&
|
||||
!IRC_WriteStrClient(from, RPL_WHOISSSL_MSG,
|
||||
Client_ID(from), Client_ID(c)))
|
||||
return DISCONNECTED;
|
||||
!IRC_WriteStrClient(from, RPL_WHOISSSL_MSG, Client_ID(from),
|
||||
Client_ID(c)))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Registered nick name? */
|
||||
if (Client_HasMode(c, 'R') &&
|
||||
!IRC_WriteStrClient(from, RPL_WHOISREGNICK_MSG,
|
||||
Client_ID(from), Client_ID(c)))
|
||||
return DISCONNECTED;
|
||||
|
||||
if (Client_Conn(c) > NONE && (Client_OperByMe(from) || from == c) &&
|
||||
!IRC_WriteStrClient(from, RPL_WHOISHOST_MSG, Client_ID(from),
|
||||
Client_ID(c), Client_Hostname(c),
|
||||
Conn_GetIPAInfo(Client_Conn(c))))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Idle and signon time (local clients only!) */
|
||||
if (!Conf_MorePrivacy && Client_Conn(c) > NONE &&
|
||||
!IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG,
|
||||
Client_ID(from), Client_ID(c),
|
||||
(unsigned long)Conn_GetIdle(Client_Conn(c)),
|
||||
(unsigned long)Conn_GetSignon(Client_Conn(c))))
|
||||
return DISCONNECTED;
|
||||
!IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG,
|
||||
Client_ID(from), Client_ID(c),
|
||||
(unsigned long)Conn_GetIdle(Client_Conn(c)),
|
||||
(unsigned long)Conn_GetSignon(Client_Conn(c))))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Away? */
|
||||
if (Client_HasMode(c, 'a') &&
|
||||
!IRC_WriteStrClient(from, RPL_AWAY_MSG,
|
||||
Client_ID(from), Client_ID(c),
|
||||
Client_Away(c)))
|
||||
return DISCONNECTED;
|
||||
!IRC_WriteStrClient(from, RPL_AWAY_MSG,
|
||||
Client_ID(from), Client_ID(c), Client_Away(c)))
|
||||
return DISCONNECTED;
|
||||
|
||||
return IRC_WriteStrClient(from, RPL_ENDOFWHOIS_MSG,
|
||||
Client_ID(from), Client_ID(c));
|
||||
return CONNECTED;
|
||||
} /* IRC_WHOIS_SendReply */
|
||||
|
||||
|
||||
@@ -1034,7 +1154,7 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
|
||||
unsigned int match_count = 0, found = 0;
|
||||
bool has_wildcards, is_remote;
|
||||
bool got_wildcard = false;
|
||||
const char *query;
|
||||
char mask[COMMAND_LEN], *query;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
@@ -1075,7 +1195,8 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
|
||||
Req->argv[0], Req->argv[1]);
|
||||
|
||||
is_remote = Client_Conn(from) < 0;
|
||||
for (query = strtok(Req->argv[Req->argc - 1], ",");
|
||||
strlcpy(mask, Req->argv[Req->argc - 1], sizeof(mask));
|
||||
for (query = strtok(ngt_LowerStr(mask), ",");
|
||||
query && found < 3;
|
||||
query = strtok(NULL, ","), found++)
|
||||
{
|
||||
@@ -1086,11 +1207,11 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
|
||||
* - no wildcards for remote clients
|
||||
* - only one wildcard target per local client
|
||||
*
|
||||
* also, at most ten matches are returned.
|
||||
* Also, at most MAX_RPL_WHOIS matches are returned.
|
||||
*/
|
||||
if (!has_wildcards || is_remote) {
|
||||
c = Client_Search(query);
|
||||
if (c) {
|
||||
if (c && Client_Type(c) == CLIENT_USER) {
|
||||
if (!IRC_WHOIS_SendReply(Client, from, c))
|
||||
return DISCONNECTED;
|
||||
} else {
|
||||
@@ -1112,21 +1233,28 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
|
||||
got_wildcard = true;
|
||||
IRC_SetPenalty(Client, 3);
|
||||
|
||||
for (c = Client_First(); c && match_count < 10; c = Client_Next(c)) {
|
||||
for (c = Client_First(); c; c = Client_Next(c)) {
|
||||
if (IRC_CheckListTooBig(Client, match_count,
|
||||
MAX_RPL_WHOIS, "WHOIS"))
|
||||
break;
|
||||
|
||||
if (Client_Type(c) != CLIENT_USER)
|
||||
continue;
|
||||
if (!MatchCaseInsensitive(query, Client_ID(c)))
|
||||
continue;
|
||||
if (!IRC_WHOIS_SendReply(Client, from, c))
|
||||
return DISCONNECTED;
|
||||
|
||||
match_count++;
|
||||
}
|
||||
|
||||
if (match_count == 0)
|
||||
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client), Req->argv[Req->argc - 1]);
|
||||
IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client),
|
||||
Req->argv[Req->argc - 1]);
|
||||
}
|
||||
return CONNECTED;
|
||||
return IRC_WriteStrClient(from, RPL_ENDOFWHOIS_MSG,
|
||||
Client_ID(from), Req->argv[Req->argc - 1]);
|
||||
} /* IRC_WHOIS */
|
||||
|
||||
|
||||
@@ -1208,11 +1336,11 @@ IRC_WHOWAS( CLIENT *Client, REQUEST *Req )
|
||||
if (last < 0)
|
||||
last = 0;
|
||||
|
||||
max = DEFAULT_WHOWAS;
|
||||
max = DEF_RPL_WHOWAS;
|
||||
if (Req->argc > 1) {
|
||||
max = atoi(Req->argv[1]);
|
||||
if (max < 1)
|
||||
max = MAX_WHOWAS;
|
||||
max = MAX_RPL_WHOWAS;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1251,38 +1379,55 @@ IRC_WHOWAS( CLIENT *Client, REQUEST *Req )
|
||||
} /* IRC_WHOWAS */
|
||||
|
||||
|
||||
/**
|
||||
* Send LUSERS reply to a client.
|
||||
*
|
||||
* @param Client The receipient of the information.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_Send_LUSERS( CLIENT *Client )
|
||||
IRC_Send_LUSERS(CLIENT *Client)
|
||||
{
|
||||
unsigned long cnt;
|
||||
#ifndef STRICT_RFC
|
||||
unsigned long max;
|
||||
#endif
|
||||
|
||||
assert( Client != NULL );
|
||||
assert(Client != NULL);
|
||||
|
||||
/* Users, services and serevers in the network */
|
||||
if( ! IRC_WriteStrClient( Client, RPL_LUSERCLIENT_MSG, Client_ID( Client ), Client_UserCount( ), Client_ServiceCount( ), Client_ServerCount( ))) return DISCONNECTED;
|
||||
if (!IRC_WriteStrClient(Client, RPL_LUSERCLIENT_MSG, Client_ID(Client),
|
||||
Client_UserCount(), Client_ServiceCount(),
|
||||
Client_ServerCount()))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Number of IRC operators */
|
||||
cnt = Client_OperCount( );
|
||||
if( cnt > 0 )
|
||||
{
|
||||
if( ! IRC_WriteStrClient( Client, RPL_LUSEROP_MSG, Client_ID( Client ), cnt )) return DISCONNECTED;
|
||||
if (cnt > 0) {
|
||||
if (!IRC_WriteStrClient(Client, RPL_LUSEROP_MSG,
|
||||
Client_ID(Client), cnt))
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
/* Unknown connections */
|
||||
cnt = Client_UnknownCount( );
|
||||
if( cnt > 0 )
|
||||
{
|
||||
if( ! IRC_WriteStrClient( Client, RPL_LUSERUNKNOWN_MSG, Client_ID( Client ), cnt )) return DISCONNECTED;
|
||||
if (cnt > 0) {
|
||||
if (!IRC_WriteStrClient(Client, RPL_LUSERUNKNOWN_MSG,
|
||||
Client_ID(Client), cnt))
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
/* Number of created channels */
|
||||
if( ! IRC_WriteStrClient( Client, RPL_LUSERCHANNELS_MSG, Client_ID( Client ), Channel_Count( ))) return DISCONNECTED;
|
||||
if (!IRC_WriteStrClient(Client, RPL_LUSERCHANNELS_MSG,
|
||||
Client_ID(Client),
|
||||
Channel_CountVisible(Client)))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Number of local users, services and servers */
|
||||
if( ! IRC_WriteStrClient( Client, RPL_LUSERME_MSG, Client_ID( Client ), Client_MyUserCount( ), Client_MyServiceCount( ), Client_MyServerCount( ))) return DISCONNECTED;
|
||||
if (!IRC_WriteStrClient(Client, RPL_LUSERME_MSG, Client_ID(Client),
|
||||
Client_MyUserCount(), Client_MyServiceCount(),
|
||||
Client_MyServerCount()))
|
||||
return DISCONNECTED;
|
||||
|
||||
#ifndef STRICT_RFC
|
||||
/* Maximum number of local users */
|
||||
@@ -1453,7 +1598,8 @@ IRC_Send_ISUPPORT(CLIENT * Client)
|
||||
return IRC_WriteStrClient(Client, RPL_ISUPPORT2_MSG, Client_ID(Client),
|
||||
CHANNEL_NAME_LEN - 1, Conf_MaxNickLength - 1,
|
||||
COMMAND_LEN - 23, CLIENT_AWAY_LEN - 1,
|
||||
COMMAND_LEN - 113);
|
||||
COMMAND_LEN - 113, MAX_HNDL_MODES_ARG,
|
||||
MAX_HNDL_CHANNEL_LISTS);
|
||||
} /* IRC_Send_ISUPPORT */
|
||||
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "ngircd.h"
|
||||
#include "conn-func.h"
|
||||
#include "class.h"
|
||||
#include "conf.h"
|
||||
#include "channel.h"
|
||||
#include "io.h"
|
||||
@@ -46,7 +47,6 @@ 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));
|
||||
@@ -653,32 +653,37 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
|
||||
CLIENT *target;
|
||||
char quitmsg[LINE_LEN];
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
assert(Client != NULL);
|
||||
assert(Req != NULL);
|
||||
|
||||
/* Wrong number of arguments? */
|
||||
if( Req->argc > 1 )
|
||||
return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
|
||||
if (Req->argc > 1)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
if (Req->argc == 1)
|
||||
strlcpy(quitmsg, Req->argv[0], sizeof quitmsg);
|
||||
|
||||
if ( Client_Type( Client ) == CLIENT_SERVER )
|
||||
{
|
||||
if (Client_Type(Client) == CLIENT_SERVER) {
|
||||
/* Server */
|
||||
target = Client_Search( Req->prefix );
|
||||
if( ! target )
|
||||
{
|
||||
Log( LOG_WARNING, "Got QUIT from %s for unknown client!?", Client_ID( Client ));
|
||||
target = Client_Search(Req->prefix);
|
||||
if (!target) {
|
||||
Log(LOG_WARNING,
|
||||
"Got QUIT from %s for unknown client!?",
|
||||
Client_ID(Client));
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
Client_Destroy( target, "Got QUIT command.", Req->argc == 1 ? quitmsg : NULL, true);
|
||||
|
||||
return CONNECTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target != Client) {
|
||||
Client_Destroy(target, "Got QUIT command.",
|
||||
Req->argc == 1 ? quitmsg : NULL, true);
|
||||
return CONNECTED;
|
||||
} else {
|
||||
Conn_Close(Client_Conn(Client), "Got QUIT command.",
|
||||
Req->argc == 1 ? quitmsg : NULL, true);
|
||||
return DISCONNECTED;
|
||||
}
|
||||
} else {
|
||||
if (Req->argc == 1 && quitmsg[0] != '\"') {
|
||||
/* " " to avoid confusion */
|
||||
strlcpy(quitmsg, "\"", sizeof quitmsg);
|
||||
@@ -687,7 +692,8 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
|
||||
}
|
||||
|
||||
/* User, Service, or not yet registered */
|
||||
Conn_Close( Client_Conn( Client ), "Got QUIT command.", Req->argc == 1 ? quitmsg : NULL, true);
|
||||
Conn_Close(Client_Conn(Client), "Got QUIT command.",
|
||||
Req->argc == 1 ? quitmsg : NULL, true);
|
||||
|
||||
return DISCONNECTED;
|
||||
}
|
||||
@@ -883,15 +889,16 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
if (conn > NONE)
|
||||
Log(LOG_DEBUG,
|
||||
"Connection %d: received PONG. Lag: %ld seconds.", conn,
|
||||
time(NULL) - Conn_LastPing(Client_Conn(Client)));
|
||||
else
|
||||
Log(LOG_DEBUG,
|
||||
"Connection %d: received PONG.", conn);
|
||||
#endif
|
||||
if (Client_Type(Client) == CLIENT_SERVER && Conn_LastPing(conn) == 0) {
|
||||
Log(LOG_INFO,
|
||||
"Synchronization with \"%s\" done (connection %d): %ld seconds [%ld users, %ld channels]",
|
||||
Client_ID(Client), conn, time(NULL) - Conn_GetSignon(conn),
|
||||
Client_UserCount(), Channel_CountVisible(NULL));
|
||||
Conn_UpdatePing(conn);
|
||||
} else
|
||||
LogDebug("Connection %d: received PONG. Lag: %ld seconds.",
|
||||
conn, time(NULL) - Conn_LastPing(conn));
|
||||
|
||||
return CONNECTED;
|
||||
} /* IRC_PONG */
|
||||
|
||||
@@ -938,10 +945,19 @@ Hello_User(CLIENT * Client)
|
||||
* passwords supplied are classified as "wrong". */
|
||||
if(Client_Password(Client)[0] == '\0')
|
||||
return Hello_User_PostAuth(Client);
|
||||
Reject_Client(Client);
|
||||
Client_Reject(Client, "Non-empty password", false);
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
if (Conf_PAMIsOptional && strcmp(Client_Password(Client), "") == 0) {
|
||||
/* Clients are not required to send a password and to be PAM-
|
||||
* authenticated at all. If not, they won't become "identified"
|
||||
* and keep the "~" in their supplied user name.
|
||||
* Therefore it is sensible to either set Conf_PAMisOptional or
|
||||
* to enable IDENT lookups -- not both. */
|
||||
return Hello_User_PostAuth(Client);
|
||||
}
|
||||
|
||||
/* 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,
|
||||
@@ -953,6 +969,7 @@ Hello_User(CLIENT * Client)
|
||||
} else {
|
||||
/* Sub process */
|
||||
Log_Init_Subprocess("Auth");
|
||||
Conn_CloseAllSockets(NONE);
|
||||
result = PAM_Authenticate(Client);
|
||||
if (write(pipefd[1], &result, sizeof(result)) != sizeof(result))
|
||||
Log_Subprocess(LOG_ERR,
|
||||
@@ -964,7 +981,7 @@ Hello_User(CLIENT * Client)
|
||||
/* Check global server password ... */
|
||||
if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
|
||||
/* Bad password! */
|
||||
Reject_Client(Client);
|
||||
Client_Reject(Client, "Bad server password", false);
|
||||
return DISCONNECTED;
|
||||
}
|
||||
return Hello_User_PostAuth(Client);
|
||||
@@ -1003,12 +1020,13 @@ cb_Read_Auth_Result(int r_fd, UNUSED short events)
|
||||
|
||||
/* Read result from pipe */
|
||||
len = Proc_Read(proc, &result, sizeof(result));
|
||||
Proc_Close(proc);
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
if (len != sizeof(result)) {
|
||||
Log(LOG_CRIT, "Auth: Got malformed result!");
|
||||
Reject_Client(client);
|
||||
Client_Reject(client, "Internal error", false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1016,31 +1034,12 @@ cb_Read_Auth_Result(int r_fd, UNUSED short events)
|
||||
Client_SetUser(client, Client_OrigUser(client), true);
|
||||
(void)Hello_User_PostAuth(client);
|
||||
} else
|
||||
Reject_Client(client);
|
||||
Client_Reject(client, "Bad password", false);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Reject a client because of wrong password.
|
||||
*
|
||||
* This function is called either when the global server password or a password
|
||||
* checked using PAM has been wrong.
|
||||
*
|
||||
* @param Client The client to reject.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finish client registration.
|
||||
*
|
||||
@@ -1053,6 +1052,11 @@ Reject_Client(CLIENT *Client)
|
||||
static bool
|
||||
Hello_User_PostAuth(CLIENT *Client)
|
||||
{
|
||||
assert(Client != NULL);
|
||||
|
||||
if (Class_HandleServerBans(Client) != CONNECTED)
|
||||
return DISCONNECTED;
|
||||
|
||||
Introduce_Client(NULL, Client, CLIENT_USER);
|
||||
|
||||
if (!IRC_WriteStrClient
|
||||
@@ -1096,20 +1100,22 @@ Hello_User_PostAuth(CLIENT *Client)
|
||||
* @param Reason Reason for the KILL.
|
||||
*/
|
||||
static void
|
||||
Kill_Nick( char *Nick, char *Reason )
|
||||
Kill_Nick(char *Nick, char *Reason)
|
||||
{
|
||||
REQUEST r;
|
||||
|
||||
assert( Nick != NULL );
|
||||
assert( Reason != NULL );
|
||||
assert (Nick != NULL);
|
||||
assert (Reason != NULL);
|
||||
|
||||
r.prefix = (char *)Client_ThisServer( );
|
||||
r.prefix = NULL;
|
||||
r.argv[0] = Nick;
|
||||
r.argv[1] = Reason;
|
||||
r.argc = 2;
|
||||
|
||||
Log( LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s", Nick, Reason );
|
||||
IRC_KILL( Client_ThisServer( ), &r );
|
||||
Log(LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s",
|
||||
Nick, Reason);
|
||||
|
||||
IRC_KILL(Client_ThisServer(), &r);
|
||||
} /* Kill_Nick */
|
||||
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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,39 +36,54 @@
|
||||
#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_To_List PARAMS((char what, CLIENT *Prefix, CLIENT *Client,
|
||||
CHANNEL *Channel, const char *Pattern));
|
||||
static bool Del_From_List PARAMS((char what, CLIENT *Prefix, CLIENT *Client,
|
||||
CHANNEL *Channel, const char *Pattern));
|
||||
|
||||
static bool Send_ListChange PARAMS((const char *Mode, CLIENT *Prefix,
|
||||
CLIENT *Client, CHANNEL *Channel, const char *Mask));
|
||||
static bool Send_ListChange PARAMS((const bool IsAdd, const char ModeChar,
|
||||
CLIENT *Prefix, CLIENT *Client,
|
||||
CHANNEL *Channel, const char *Mask));
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the IRC "MODE" command.
|
||||
*
|
||||
* See RFC 2812 section 3.1.5 ("user mode message") and section 3.2.3
|
||||
* ("channel mode message"), and RFC 2811 section 4 ("channel modes").
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_MODE( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
CLIENT *cl, *origin;
|
||||
CHANNEL *chan;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
assert(Client != NULL);
|
||||
assert(Req != NULL);
|
||||
|
||||
/* No 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);
|
||||
|
||||
/* Origin for answers */
|
||||
if( Client_Type( Client ) == CLIENT_SERVER )
|
||||
{
|
||||
origin = Client_Search( Req->prefix );
|
||||
if( ! origin ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
|
||||
}
|
||||
else origin = Client;
|
||||
if (Client_Type(Client) == CLIENT_SERVER) {
|
||||
origin = Client_Search(Req->prefix);
|
||||
if (!origin)
|
||||
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client),
|
||||
Req->prefix);
|
||||
} else
|
||||
origin = Client;
|
||||
|
||||
/* Channel or user mode? */
|
||||
cl = NULL; chan = NULL;
|
||||
@@ -88,178 +103,242 @@ IRC_MODE( CLIENT *Client, REQUEST *Req )
|
||||
} /* IRC_MODE */
|
||||
|
||||
|
||||
/**
|
||||
* Check if the "mode limit" for a client has been reached.
|
||||
*
|
||||
* This limit doesn't apply for servers or services!
|
||||
*
|
||||
* @param Client The client to check.
|
||||
* @param Count The number of modes already handled.
|
||||
* @return true if the limit has been reached.
|
||||
*/
|
||||
static bool
|
||||
Mode_Limit_Reached(CLIENT *Client, int Count)
|
||||
{
|
||||
if (Client_Type(Client) == CLIENT_SERVER
|
||||
|| Client_Type(Client) == CLIENT_SERVICE)
|
||||
return false;
|
||||
if (Count < MAX_HNDL_MODES_ARG)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle client mode requests
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @param Origin The originator of the MODE command (prefix).
|
||||
* @param Target The target (client) of this MODE command.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
static bool
|
||||
Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
|
||||
{
|
||||
/* Handle client mode requests */
|
||||
|
||||
char the_modes[COMMAND_LEN], x[2], *mode_ptr;
|
||||
bool ok, set;
|
||||
int mode_arg;
|
||||
size_t len;
|
||||
|
||||
/* Is the client allowed to request or change the modes? */
|
||||
if( Client_Type( Client ) == CLIENT_USER )
|
||||
{
|
||||
if (Client_Type(Client) == CLIENT_USER) {
|
||||
/* Users are only allowed to manipulate their own modes! */
|
||||
if( Target != Client ) return IRC_WriteStrClient( Client, ERR_USERSDONTMATCH_MSG, Client_ID( Client ));
|
||||
if (Target != Client)
|
||||
return IRC_WriteStrClient(Client,
|
||||
ERR_USERSDONTMATCH_MSG,
|
||||
Client_ID(Client));
|
||||
}
|
||||
|
||||
/* Mode request: let's answer it :-) */
|
||||
if( Req->argc == 1 ) return IRC_WriteStrClient( Origin, RPL_UMODEIS_MSG, Client_ID( Origin ), Client_Modes( Target ));
|
||||
if (Req->argc == 1)
|
||||
return IRC_WriteStrClient(Origin, RPL_UMODEIS_MSG,
|
||||
Client_ID(Origin),
|
||||
Client_Modes(Target));
|
||||
|
||||
mode_arg = 1;
|
||||
mode_ptr = Req->argv[mode_arg];
|
||||
|
||||
/* Initial state: set or unset modes? */
|
||||
if( *mode_ptr == '+' ) set = true;
|
||||
else if( *mode_ptr == '-' ) set = false;
|
||||
else return IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG_MSG, Client_ID( Origin ));
|
||||
|
||||
/* Prepare reply string */
|
||||
if( set ) strcpy( the_modes, "+" );
|
||||
else strcpy( the_modes, "-" );
|
||||
if (*mode_ptr == '+') {
|
||||
set = true;
|
||||
strcpy(the_modes, "+");
|
||||
} else if (*mode_ptr == '-') {
|
||||
set = false;
|
||||
strcpy(the_modes, "-");
|
||||
} else
|
||||
return IRC_WriteStrClient(Origin, ERR_UMODEUNKNOWNFLAG_MSG,
|
||||
Client_ID(Origin));
|
||||
|
||||
x[1] = '\0';
|
||||
ok = CONNECTED;
|
||||
while( mode_ptr )
|
||||
{
|
||||
while (mode_ptr) {
|
||||
mode_ptr++;
|
||||
if( ! *mode_ptr )
|
||||
{
|
||||
if (!*mode_ptr) {
|
||||
/* Try next argument if there's any */
|
||||
mode_arg++;
|
||||
if( mode_arg < Req->argc ) mode_ptr = Req->argv[mode_arg];
|
||||
else break;
|
||||
if (mode_arg < Req->argc)
|
||||
mode_ptr = Req->argv[mode_arg];
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
switch( *mode_ptr )
|
||||
{
|
||||
case '+':
|
||||
case '-':
|
||||
if((( *mode_ptr == '+' ) && ( ! set )) || (( *mode_ptr == '-' ) && ( set )))
|
||||
{
|
||||
/* Action modifier ("+"/"-") must be changed ... */
|
||||
len = strlen( the_modes ) - 1;
|
||||
if(( the_modes[len] == '+' ) || ( the_modes[len] == '-' ))
|
||||
{
|
||||
/* Adjust last action modifier in result */
|
||||
the_modes[len] = *mode_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Append modifier character to result string */
|
||||
x[0] = *mode_ptr;
|
||||
strlcat( the_modes, x, sizeof( the_modes ));
|
||||
}
|
||||
if( *mode_ptr == '+' ) set = true;
|
||||
else set = false;
|
||||
|
||||
switch(*mode_ptr) {
|
||||
case '+':
|
||||
case '-':
|
||||
if ((*mode_ptr == '+' && !set)
|
||||
|| (*mode_ptr == '-' && set)) {
|
||||
/* Action modifier ("+"/"-") must be changed */
|
||||
len = strlen(the_modes) - 1;
|
||||
if (the_modes[len] == '+'
|
||||
|| the_modes[len] == '-') {
|
||||
/* Last character in the "result
|
||||
* string" was an "action", so just
|
||||
* overwrite it with the new action */
|
||||
the_modes[len] = *mode_ptr;
|
||||
} else {
|
||||
/* Append new modifier character to
|
||||
* the resulting mode string */
|
||||
x[0] = *mode_ptr;
|
||||
strlcat(the_modes, x,
|
||||
sizeof(the_modes));
|
||||
}
|
||||
continue;
|
||||
if (*mode_ptr == '+')
|
||||
set = true;
|
||||
else
|
||||
set = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* Validate modes */
|
||||
x[0] = '\0';
|
||||
switch( *mode_ptr )
|
||||
{
|
||||
case 'i': /* Invisible */
|
||||
case 's': /* Server messages */
|
||||
case 'w': /* Wallops messages */
|
||||
x[0] = *mode_ptr;
|
||||
break;
|
||||
|
||||
case 'a': /* Away */
|
||||
if( Client_Type( Client ) == CLIENT_SERVER )
|
||||
{
|
||||
x[0] = 'a';
|
||||
Client_SetAway( Origin, DEFAULT_AWAY_MSG );
|
||||
}
|
||||
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,
|
||||
switch (*mode_ptr) {
|
||||
case 'C': /* Only messages from clients sharing a channel */
|
||||
case 'i': /* Invisible */
|
||||
case 's': /* Server messages */
|
||||
case 'w': /* Wallops messages */
|
||||
x[0] = *mode_ptr;
|
||||
break;
|
||||
case 'a': /* Away */
|
||||
if (Client_Type(Client) == CLIENT_SERVER) {
|
||||
x[0] = 'a';
|
||||
Client_SetAway(Origin, DEFAULT_AWAY_MSG);
|
||||
} 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 ))
|
||||
{
|
||||
Client_SetOperByMe( Target, false );
|
||||
x[0] = 'o';
|
||||
}
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin ));
|
||||
break;
|
||||
|
||||
case 'r': /* Restricted (only settable) */
|
||||
if(( set ) || ( Client_Type( Client ) == CLIENT_SERVER )) x[0] = 'r';
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_RESTRICTED_MSG, Client_ID( Origin ));
|
||||
break;
|
||||
|
||||
case 'x': /* Cloak hostname */
|
||||
if (Client_HasMode(Client, 'r'))
|
||||
ok = 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 );
|
||||
break;
|
||||
case 'c': /* Receive connect notices
|
||||
* (only settable by IRC operators!) */
|
||||
if (!set || Client_Type(Client) == CLIENT_SERVER
|
||||
|| Client_OperByMe(Origin))
|
||||
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) {
|
||||
Client_SetOperByMe(Target, false);
|
||||
x[0] = 'o';
|
||||
} else
|
||||
ok = IRC_WriteStrClient(Origin,
|
||||
ERR_NOPRIVILEGES_MSG,
|
||||
Client_ID(Origin));
|
||||
break;
|
||||
case 'r': /* Restricted (only settable) */
|
||||
if (set || Client_Type(Client) == CLIENT_SERVER)
|
||||
x[0] = 'r';
|
||||
else
|
||||
ok = IRC_WriteStrClient(Origin,
|
||||
ERR_RESTRICTED_MSG,
|
||||
Client_ID(Origin));
|
||||
break;
|
||||
case 'x': /* Cloak hostname */
|
||||
if (Client_HasMode(Client, 'r'))
|
||||
ok = IRC_WriteStrClient(Origin,
|
||||
ERR_RESTRICTED_MSG,
|
||||
Client_ID(Origin));
|
||||
else
|
||||
x[0] = 'x';
|
||||
break;
|
||||
default:
|
||||
if (Client_Type(Client) != CLIENT_SERVER) {
|
||||
Log(LOG_DEBUG,
|
||||
"Unknown mode \"%c%c\" from \"%s\"!?",
|
||||
set ? '+' : '-', *mode_ptr,
|
||||
Client_ID(Origin));
|
||||
ok = IRC_WriteStrClient(Origin,
|
||||
ERR_UMODEUNKNOWNFLAG2_MSG,
|
||||
Client_ID(Origin),
|
||||
set ? '+' : '-',
|
||||
*mode_ptr);
|
||||
x[0] = '\0';
|
||||
goto client_exit;
|
||||
} else {
|
||||
Log(LOG_DEBUG,
|
||||
"Handling unknown mode \"%c%c\" from \"%s\" for \"%s\" ...",
|
||||
set ? '+' : '-', *mode_ptr,
|
||||
Client_ID(Origin), Client_ID(Target));
|
||||
x[0] = *mode_ptr;
|
||||
}
|
||||
}
|
||||
if( ! ok ) break;
|
||||
|
||||
if (!ok)
|
||||
break;
|
||||
|
||||
/* Is there a valid mode change? */
|
||||
if( ! x[0] ) continue;
|
||||
|
||||
if( set )
|
||||
{
|
||||
/* Set mode */
|
||||
if( Client_ModeAdd( Target, x[0] )) strlcat( the_modes, x, sizeof( the_modes ));
|
||||
if (!x[0])
|
||||
continue;
|
||||
|
||||
if (set) {
|
||||
if (Client_ModeAdd(Target, x[0]))
|
||||
strlcat(the_modes, x, sizeof(the_modes));
|
||||
} else {
|
||||
if (Client_ModeDel(Target, x[0]))
|
||||
strlcat(the_modes, x, sizeof(the_modes));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unset mode */
|
||||
if( Client_ModeDel( Target, x[0] )) strlcat( the_modes, x, sizeof( the_modes ));
|
||||
}
|
||||
}
|
||||
client_exit:
|
||||
|
||||
/* Are there changed modes? */
|
||||
if( the_modes[1] )
|
||||
{
|
||||
/* Remoce needless action modifier characters */
|
||||
len = strlen( the_modes ) - 1;
|
||||
if(( the_modes[len] == '+' ) || ( the_modes[len] == '-' )) the_modes[len] = '\0';
|
||||
|
||||
if( Client_Type( Client ) == CLIENT_SERVER )
|
||||
{
|
||||
/* Are there changed modes? */
|
||||
if (the_modes[1]) {
|
||||
/* Remove needless action modifier characters */
|
||||
len = strlen(the_modes) - 1;
|
||||
if (the_modes[len] == '+' || the_modes[len] == '-')
|
||||
the_modes[len] = '\0';
|
||||
|
||||
if (Client_Type(Client) == CLIENT_SERVER) {
|
||||
/* Forward modes to other servers */
|
||||
IRC_WriteStrServersPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Client_Conn(Target) != NONE) {
|
||||
/* Remote server (service?) changed modes
|
||||
* for one of our clients. Inform it! */
|
||||
IRC_WriteStrClientPrefix(Target, Origin,
|
||||
"MODE %s :%s",
|
||||
Client_ID(Target),
|
||||
the_modes);
|
||||
}
|
||||
IRC_WriteStrServersPrefix(Client, Origin,
|
||||
"MODE %s :%s",
|
||||
Client_ID(Target),
|
||||
the_modes);
|
||||
} else {
|
||||
/* Send reply to client and inform other servers */
|
||||
ok = IRC_WriteStrClientPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes );
|
||||
IRC_WriteStrServersPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes );
|
||||
ok = IRC_WriteStrClientPrefix(Client, Origin,
|
||||
"MODE %s :%s",
|
||||
Client_ID(Target),
|
||||
the_modes);
|
||||
IRC_WriteStrServersPrefix(Client, Origin,
|
||||
"MODE %s :%s",
|
||||
Client_ID(Target),
|
||||
the_modes);
|
||||
}
|
||||
LogDebug("%s \"%s\": Mode change, now \"%s\".",
|
||||
Client_TypeText(Target), Client_Mask(Target),
|
||||
Client_Modes(Target));
|
||||
}
|
||||
|
||||
IRC_SetPenalty( Client, 1 );
|
||||
|
||||
IRC_SetPenalty(Client, 1);
|
||||
return ok;
|
||||
} /* Client_Mode */
|
||||
|
||||
@@ -319,7 +398,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2],
|
||||
argadd[CLIENT_PASS_LEN], *mode_ptr;
|
||||
bool connected, set, skiponce, retval, onchannel, modeok, use_servermode;
|
||||
int mode_arg, arg_arg;
|
||||
int mode_arg, arg_arg, mode_arg_count = 0;
|
||||
CLIENT *client;
|
||||
long l;
|
||||
size_t len;
|
||||
@@ -372,6 +451,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
mode_ptr++;
|
||||
if (!*mode_ptr) {
|
||||
/* Try next argument if there's any */
|
||||
if (arg_arg < 0)
|
||||
break;
|
||||
if (arg_arg > mode_arg)
|
||||
mode_arg = arg_arg;
|
||||
else
|
||||
@@ -421,6 +502,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
case 'i': /* Invite only */
|
||||
case 'm': /* Moderated */
|
||||
case 'n': /* Only members can write */
|
||||
case 'R': /* Registered users only */
|
||||
case 's': /* Secret channel */
|
||||
case 't': /* Topic locked */
|
||||
case 'z': /* Secure connections only */
|
||||
@@ -432,6 +514,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
Client_ID(Origin), Channel_Name(Channel));
|
||||
break;
|
||||
case 'k': /* Channel key */
|
||||
if (Mode_Limit_Reached(Client, mode_arg_count++))
|
||||
goto chan_exit;
|
||||
if (!set) {
|
||||
if (modeok)
|
||||
x[0] = *mode_ptr;
|
||||
@@ -466,6 +550,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
}
|
||||
break;
|
||||
case 'l': /* Member limit */
|
||||
if (Mode_Limit_Reached(Client, mode_arg_count++))
|
||||
goto chan_exit;
|
||||
if (!set) {
|
||||
if (modeok)
|
||||
x[0] = *mode_ptr;
|
||||
@@ -536,6 +622,16 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
Channel_Name(Channel));
|
||||
break;
|
||||
/* --- Channel user modes --- */
|
||||
case 'a':
|
||||
case 'h':
|
||||
case 'q':
|
||||
if (Client_Type(Client) != CLIENT_SERVER) {
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
ERR_CHANOPRIVSNEEDED_MSG,
|
||||
Client_ID(Origin),
|
||||
Channel_Name(Channel));
|
||||
goto chan_exit;
|
||||
}
|
||||
case 'o': /* Channel operator */
|
||||
case 'v': /* Voice */
|
||||
if (arg_arg > mode_arg) {
|
||||
@@ -566,14 +662,17 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
/* --- Channel lists --- */
|
||||
case 'I': /* Invite lists */
|
||||
case 'b': /* Ban lists */
|
||||
case 'e': /* Channel exception lists */
|
||||
if (Mode_Limit_Reached(Client, mode_arg_count++))
|
||||
goto chan_exit;
|
||||
if (arg_arg > mode_arg) {
|
||||
/* modify list */
|
||||
if (modeok) {
|
||||
connected = set
|
||||
? Add_Ban_Invite(*mode_ptr, Origin,
|
||||
? Add_To_List(*mode_ptr, Origin,
|
||||
Client, Channel,
|
||||
Req->argv[arg_arg])
|
||||
: Del_Ban_Invite(*mode_ptr, Origin,
|
||||
: Del_From_List(*mode_ptr, Origin,
|
||||
Client, Channel,
|
||||
Req->argv[arg_arg]);
|
||||
} else {
|
||||
@@ -585,25 +684,38 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
Req->argv[arg_arg][0] = '\0';
|
||||
arg_arg++;
|
||||
} else {
|
||||
if (*mode_ptr == 'I')
|
||||
switch (*mode_ptr) {
|
||||
case 'I':
|
||||
Channel_ShowInvites(Origin, Channel);
|
||||
else
|
||||
break;
|
||||
case 'b':
|
||||
Channel_ShowBans(Origin, Channel);
|
||||
break;
|
||||
case 'e':
|
||||
Channel_ShowExcepts(Origin, Channel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log(LOG_DEBUG,
|
||||
"Unknown mode \"%c%c\" from \"%s\" on %s!?",
|
||||
set ? '+' : '-', *mode_ptr, Client_ID(Origin),
|
||||
Channel_Name(Channel));
|
||||
if (Client_Type(Client) != CLIENT_SERVER)
|
||||
if (Client_Type(Client) != CLIENT_SERVER) {
|
||||
Log(LOG_DEBUG,
|
||||
"Unknown mode \"%c%c\" from \"%s\" on %s!?",
|
||||
set ? '+' : '-', *mode_ptr,
|
||||
Client_ID(Origin), Channel_Name(Channel));
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
ERR_UMODEUNKNOWNFLAG2_MSG,
|
||||
Client_ID(Origin),
|
||||
set ? '+' : '-', *mode_ptr);
|
||||
x[0] = '\0';
|
||||
goto chan_exit;
|
||||
} /* switch() */
|
||||
ERR_UNKNOWNMODE_MSG,
|
||||
Client_ID(Origin), *mode_ptr,
|
||||
Channel_Name(Channel));
|
||||
x[0] = '\0';
|
||||
} else {
|
||||
Log(LOG_DEBUG,
|
||||
"Handling unknown mode \"%c%c\" from \"%s\" on %s ...",
|
||||
set ? '+' : '-', *mode_ptr,
|
||||
Client_ID(Origin), Channel_Name(Channel));
|
||||
x[0] = *mode_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!connected)
|
||||
break;
|
||||
@@ -729,82 +841,151 @@ IRC_AWAY( CLIENT *Client, REQUEST *Req )
|
||||
} /* IRC_AWAY */
|
||||
|
||||
|
||||
/**
|
||||
* Add entries to channel invite, ban and exception lists.
|
||||
*
|
||||
* @param what Can be 'I' for invite, 'b' for ban, and 'e' for exception list.
|
||||
* @param Prefix The originator of the command.
|
||||
* @param Client The sender of the command.
|
||||
* @param Channel The channel of which the list should be modified.
|
||||
* @param Pattern The pattern to add to the list.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
static bool
|
||||
Add_Ban_Invite(int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Pattern)
|
||||
Add_To_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
|
||||
const char *Pattern)
|
||||
{
|
||||
const char *mask;
|
||||
bool already;
|
||||
bool ret;
|
||||
struct list_head *list;
|
||||
long int current_count;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Channel != NULL );
|
||||
assert( Pattern != NULL );
|
||||
assert(what == 'I' || what == 'b');
|
||||
assert(Client != NULL);
|
||||
assert(Channel != NULL);
|
||||
assert(Pattern != NULL);
|
||||
assert(what == 'I' || what == 'b' || what == 'e');
|
||||
|
||||
mask = Lists_MakeMask(Pattern);
|
||||
current_count = Lists_Count(Channel_GetListInvites(Channel))
|
||||
+ Lists_Count(Channel_GetListExcepts(Channel))
|
||||
+ Lists_Count(Channel_GetListBans(Channel));
|
||||
|
||||
already = Lists_CheckDupeMask(Channel_GetListInvites(Channel), mask);
|
||||
if (!already) {
|
||||
if (what == 'I')
|
||||
ret = Channel_AddInvite(Channel, mask, false);
|
||||
else
|
||||
ret = Channel_AddBan(Channel, mask);
|
||||
if (!ret)
|
||||
return CONNECTED;
|
||||
switch(what) {
|
||||
case 'I':
|
||||
list = Channel_GetListInvites(Channel);
|
||||
break;
|
||||
case 'b':
|
||||
list = Channel_GetListBans(Channel);
|
||||
break;
|
||||
case 'e':
|
||||
list = Channel_GetListExcepts(Channel);
|
||||
break;
|
||||
}
|
||||
if (already && (Client_Type(Prefix) == CLIENT_SERVER))
|
||||
return CONNECTED;
|
||||
|
||||
if (what == 'I')
|
||||
return Send_ListChange("+I", Prefix, Client, Channel, mask);
|
||||
return Send_ListChange("+b", Prefix, Client, Channel, mask);
|
||||
if (Lists_CheckDupeMask(list, mask))
|
||||
return CONNECTED;
|
||||
if (Client_Type(Client) == CLIENT_USER &&
|
||||
current_count >= MAX_HNDL_CHANNEL_LISTS)
|
||||
return IRC_WriteStrClient(Client, ERR_LISTFULL_MSG,
|
||||
Client_ID(Client),
|
||||
Channel_Name(Channel), mask,
|
||||
MAX_HNDL_CHANNEL_LISTS);
|
||||
|
||||
switch (what) {
|
||||
case 'I':
|
||||
if (!Channel_AddInvite(Channel, mask, false))
|
||||
return CONNECTED;
|
||||
break;
|
||||
case 'b':
|
||||
if (!Channel_AddBan(Channel, mask))
|
||||
return CONNECTED;
|
||||
break;
|
||||
case 'e':
|
||||
if (!Channel_AddExcept(Channel, mask))
|
||||
return CONNECTED;
|
||||
break;
|
||||
}
|
||||
return Send_ListChange(true, what, Prefix, Client, Channel, mask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete entries from channel invite, ban and exeption lists.
|
||||
*
|
||||
* @param what Can be 'I' for invite, 'b' for ban, and 'e' for exception list.
|
||||
* @param Prefix The originator of the command.
|
||||
* @param Client The sender of the command.
|
||||
* @param Channel The channel of which the list should be modified.
|
||||
* @param Pattern The pattern to add to the list.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
static bool
|
||||
Del_Ban_Invite(int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Pattern)
|
||||
Del_From_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
|
||||
const char *Pattern)
|
||||
{
|
||||
const char *mask;
|
||||
struct list_head *list;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Channel != NULL );
|
||||
assert( Pattern != NULL );
|
||||
assert(what == 'I' || what == 'b');
|
||||
assert(Client != NULL);
|
||||
assert(Channel != NULL);
|
||||
assert(Pattern != NULL);
|
||||
assert(what == 'I' || what == 'b' || what == 'e');
|
||||
|
||||
mask = Lists_MakeMask( Pattern );
|
||||
mask = Lists_MakeMask(Pattern);
|
||||
|
||||
if (what == 'I')
|
||||
list = Channel_GetListInvites(Channel);
|
||||
else
|
||||
list = Channel_GetListBans(Channel);
|
||||
switch (what) {
|
||||
case 'I':
|
||||
list = Channel_GetListInvites(Channel);
|
||||
break;
|
||||
case 'b':
|
||||
list = Channel_GetListBans(Channel);
|
||||
break;
|
||||
case 'e':
|
||||
list = Channel_GetListExcepts(Channel);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Lists_CheckDupeMask(list, mask))
|
||||
return CONNECTED;
|
||||
Lists_Del(list, mask);
|
||||
if (what == 'I')
|
||||
return Send_ListChange( "-I", Prefix, Client, Channel, mask );
|
||||
return Send_ListChange( "-b", Prefix, Client, Channel, mask );
|
||||
|
||||
return Send_ListChange(false, what, Prefix, Client, Channel, mask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send information about changed channel invite/ban/exception lists to clients.
|
||||
*
|
||||
* @param IsAdd true if the list item has been added, false otherwise.
|
||||
* @param ModeChar The mode to use (e. g. 'b' or 'I')
|
||||
* @param Prefix The originator of the mode list change.
|
||||
* @param Client The sender of the command.
|
||||
* @param Channel The channel of which the list has been modified.
|
||||
* @param Mask The mask which has been added or removed.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
static bool
|
||||
Send_ListChange(const char *Mode, CLIENT *Prefix, CLIENT *Client,
|
||||
CHANNEL *Channel, const char *Mask)
|
||||
Send_ListChange(const bool IsAdd, const char ModeChar, CLIENT *Prefix,
|
||||
CLIENT *Client, CHANNEL *Channel, const char *Mask)
|
||||
{
|
||||
bool ok;
|
||||
bool ok = true;
|
||||
|
||||
if( Client_Type( Client ) == CLIENT_USER )
|
||||
{
|
||||
/* send confirmation to client */
|
||||
ok = IRC_WriteStrClientPrefix( Client, Prefix, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
|
||||
}
|
||||
else ok = true;
|
||||
/* Send confirmation to the client */
|
||||
if (Client_Type(Client) == CLIENT_USER)
|
||||
ok = IRC_WriteStrClientPrefix(Client, Prefix, "MODE %s %c%c %s",
|
||||
Channel_Name(Channel),
|
||||
IsAdd ? '+' : '-',
|
||||
ModeChar, Mask);
|
||||
|
||||
/* to other servers */
|
||||
IRC_WriteStrServersPrefix( Client, Prefix, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
|
||||
IRC_WriteStrServersPrefix(Client, Prefix, "MODE %s %c%c %s",
|
||||
Channel_Name(Channel), IsAdd ? '+' : '-',
|
||||
ModeChar, Mask);
|
||||
|
||||
/* and local users in channel */
|
||||
IRC_WriteStrChannelPrefix( Client, Channel, Prefix, false, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
|
||||
|
||||
IRC_WriteStrChannelPrefix(Client, Channel, Prefix, false,
|
||||
"MODE %s %c%c %s", Channel_Name(Channel),
|
||||
IsAdd ? '+' : '-', ModeChar, Mask );
|
||||
|
||||
return ok;
|
||||
} /* Send_ListChange */
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "conn-func.h"
|
||||
#include "conf.h"
|
||||
#include "channel.h"
|
||||
#include "class.h"
|
||||
#include "irc-write.h"
|
||||
#include "log.h"
|
||||
#include "match.h"
|
||||
@@ -37,7 +38,6 @@
|
||||
#include <exp.h>
|
||||
#include "irc-oper.h"
|
||||
|
||||
|
||||
/**
|
||||
* Handle invalid received OPER command.
|
||||
* Log OPER attempt and send error message to client.
|
||||
@@ -52,7 +52,15 @@ Bad_OperPass(CLIENT *Client, char *errtoken, char *errmsg)
|
||||
Client_ID(Client));
|
||||
} /* Bad_OperPass */
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the IRC "OPER" command.
|
||||
*
|
||||
* See RFC 2812, 3.1.4 "Oper message".
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_OPER( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
@@ -62,7 +70,9 @@ IRC_OPER( CLIENT *Client, REQUEST *Req )
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
|
||||
if (Req->argc != 2)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
len = array_length(&Conf_Opers, sizeof(*op));
|
||||
op = array_start(&Conf_Opers);
|
||||
@@ -77,20 +87,33 @@ IRC_OPER( CLIENT *Client, REQUEST *Req )
|
||||
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' ))
|
||||
{
|
||||
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 ));
|
||||
if (!Client_HasMode(Client, 'o')) {
|
||||
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));
|
||||
}
|
||||
|
||||
if( ! Client_OperByMe( Client )) Log( LOG_NOTICE|LOG_snotice, "Got valid OPER from \"%s\", user is an IRC operator now.", Client_Mask( Client ));
|
||||
if (!Client_OperByMe(Client))
|
||||
Log(LOG_NOTICE|LOG_snotice,
|
||||
"Got valid OPER from \"%s\", user is an IRC operator now.",
|
||||
Client_Mask(Client));
|
||||
|
||||
Client_SetOperByMe( Client, true);
|
||||
return IRC_WriteStrClient( Client, RPL_YOUREOPER_MSG, Client_ID( Client ));
|
||||
Client_SetOperByMe(Client, true);
|
||||
return IRC_WriteStrClient(Client, RPL_YOUREOPER_MSG, Client_ID(Client));
|
||||
} /* IRC_OPER */
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the IRC "DIE" command.
|
||||
*
|
||||
* See RFC 2812, 4.3 "Die message".
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_DIE(CLIENT * Client, REQUEST * Req)
|
||||
{
|
||||
@@ -133,7 +156,15 @@ IRC_DIE(CLIENT * Client, REQUEST * Req)
|
||||
return CONNECTED;
|
||||
} /* IRC_DIE */
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the IRC "REHASH" command.
|
||||
*
|
||||
* See RFC 2812, 4.2 "Rehash message".
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_REHASH( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
@@ -146,15 +177,26 @@ IRC_REHASH( CLIENT *Client, REQUEST *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 );
|
||||
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 ));
|
||||
Log(LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...",
|
||||
Client_Mask(Client));
|
||||
raise(SIGHUP);
|
||||
|
||||
return CONNECTED;
|
||||
} /* IRC_REHASH */
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the IRC "RESTART" command.
|
||||
*
|
||||
* See RFC 2812, 4.4 "Restart message".
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_RESTART( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
@@ -167,16 +209,25 @@ IRC_RESTART( CLIENT *Client, REQUEST *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 );
|
||||
if (Req->argc != 0)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
Log( LOG_NOTICE|LOG_snotice, "Got RESTART command from \"%s\" ...", Client_Mask( Client ));
|
||||
Log(LOG_NOTICE|LOG_snotice, "Got RESTART command from \"%s\" ...",
|
||||
Client_Mask(Client));
|
||||
NGIRCd_SignalRestart = true;
|
||||
|
||||
return CONNECTED;
|
||||
} /* IRC_RESTART */
|
||||
|
||||
|
||||
/**
|
||||
* Connect configured or new server.
|
||||
* Handler for the IRC "CONNECT" command.
|
||||
*
|
||||
* See RFC 2812, 3.4.7 "Connect message".
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_CONNECT(CLIENT * Client, REQUEST * Req)
|
||||
@@ -272,9 +323,15 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
|
||||
return CONNECTED;
|
||||
} /* IRC_CONNECT */
|
||||
|
||||
|
||||
/**
|
||||
* Disconnect (and disable) configured server.
|
||||
* Handler for the IRC "DISCONNECT" command.
|
||||
*
|
||||
* This command is not specified in the IRC RFCs, it is an extension
|
||||
* of ngIRCd: it shuts down and disables a configured server connection.
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_DISCONNECT(CLIENT * Client, REQUEST * Req)
|
||||
@@ -315,7 +372,15 @@ IRC_DISCONNECT(CLIENT * Client, REQUEST * Req)
|
||||
return DISCONNECTED;
|
||||
} /* IRC_DISCONNECT */
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the IRC "WALLOPS" command.
|
||||
*
|
||||
* See RFC 2812, 4.7 "Operwall message".
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
@@ -325,12 +390,14 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
|
||||
assert( Req != NULL );
|
||||
|
||||
if (Req->argc != 1)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
switch (Client_Type(Client)) {
|
||||
case CLIENT_USER:
|
||||
if (!Client_OperByMe(Client))
|
||||
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG, Client_ID(Client));
|
||||
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
|
||||
Client_ID(Client));
|
||||
from = Client;
|
||||
break;
|
||||
case CLIENT_SERVER:
|
||||
@@ -341,11 +408,87 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
|
||||
}
|
||||
|
||||
if (!from)
|
||||
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix);
|
||||
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client), Req->prefix);
|
||||
|
||||
IRC_SendWallops(Client, from, "%s", Req->argv[0]);
|
||||
return CONNECTED;
|
||||
} /* IRC_WALLOPS */
|
||||
|
||||
/**
|
||||
* Handle <?>LINE commands (GLINE, KLINE).
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_xLINE(CLIENT *Client, REQUEST *Req)
|
||||
{
|
||||
CLIENT *from;
|
||||
int class;
|
||||
char class_c;
|
||||
|
||||
assert(Client != NULL);
|
||||
assert(Req != NULL);
|
||||
|
||||
from = Op_Check(Client, Req);
|
||||
if (!from)
|
||||
return Op_NoPrivileges(Client, Req);
|
||||
|
||||
/* Bad number of parameters? */
|
||||
if (Req->argc != 1 && Req->argc != 3)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
switch(Req->command[0]) {
|
||||
case 'g':
|
||||
case 'G':
|
||||
class = CLASS_GLINE; class_c = 'G';
|
||||
break;
|
||||
case 'k':
|
||||
case 'K':
|
||||
class = CLASS_KLINE; class_c = 'K';
|
||||
break;
|
||||
default:
|
||||
Log(LOG_CRIT,
|
||||
"IRC_xLINE() called for unknown line: %c!? Ignored.",
|
||||
Req->command[0]);
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
if (Req->argc == 1) {
|
||||
/* Delete mask from list */
|
||||
Class_DeleteMask(class, Req->argv[0]);
|
||||
Log(LOG_NOTICE|LOG_snotice,
|
||||
"\"%s\" deleted \"%s\" from %c-Line list.",
|
||||
Client_Mask(from), Req->argv[0], class_c);
|
||||
if (class == CLASS_GLINE) {
|
||||
/* Inform other servers */
|
||||
IRC_WriteStrServersPrefix(Client, from, "%s %s",
|
||||
Req->command, Req->argv[0]);
|
||||
|
||||
}
|
||||
} else {
|
||||
/* Add new mask to list */
|
||||
if (Class_AddMask(class, Req->argv[0],
|
||||
time(NULL) + atol(Req->argv[1]),
|
||||
Req->argv[2])) {
|
||||
Log(LOG_NOTICE|LOG_snotice,
|
||||
"\"%s\" added \"%s\" to %c-Line list: \"%s\" (%ld seconds).",
|
||||
Client_Mask(from), Req->argv[0], class_c,
|
||||
Req->argv[2], atol(Req->argv[1]));
|
||||
if (class == CLASS_GLINE) {
|
||||
/* Inform other servers */
|
||||
IRC_WriteStrServersPrefix(Client, from,
|
||||
"%s %s %s :%s", Req->command,
|
||||
Req->argv[0], Req->argv[1],
|
||||
Req->argv[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
/* -eof- */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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,6 +25,8 @@ GLOBAL bool IRC_CONNECT PARAMS((CLIENT *Client, REQUEST *Req ));
|
||||
GLOBAL bool IRC_DISCONNECT PARAMS((CLIENT *Client, REQUEST *Req ));
|
||||
GLOBAL bool IRC_WALLOPS PARAMS(( CLIENT *Client, REQUEST *Req ));
|
||||
|
||||
GLOBAL bool IRC_xLINE PARAMS((CLIENT *Client, REQUEST *Req));
|
||||
|
||||
#endif
|
||||
|
||||
/* -eof- */
|
||||
|
158
src/ngircd/irc.c
158
src/ngircd/irc.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2004 Alexander Barton <alex@barton.de>
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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
|
||||
@@ -45,6 +45,35 @@ static bool Send_Message_Mask PARAMS((CLIENT *from, char *command,
|
||||
bool SendErrors));
|
||||
|
||||
|
||||
/**
|
||||
* Check if a list limit is reached and inform client accordingly.
|
||||
*
|
||||
* @param From The client.
|
||||
* @param Count Reply item count.
|
||||
* @param Limit Reply limit.
|
||||
* @param Name Name of the list.
|
||||
* @return true if list limit has been reached; false otherwise.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_CheckListTooBig(CLIENT *From, const int Count, const int Limit,
|
||||
const char *Name)
|
||||
{
|
||||
assert(From != NULL);
|
||||
assert(Count >= 0);
|
||||
assert(Limit > 0);
|
||||
assert(Name != NULL);
|
||||
|
||||
if (Count < Limit)
|
||||
return false;
|
||||
|
||||
(void)IRC_WriteStrClient(From,
|
||||
"NOTICE %s :%s list limit (%d) reached!",
|
||||
Client_ID(From), Name, Limit);
|
||||
IRC_SetPenalty(From, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
GLOBAL bool
|
||||
IRC_ERROR( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
@@ -63,13 +92,21 @@ IRC_ERROR( CLIENT *Client, REQUEST *Req )
|
||||
|
||||
|
||||
/**
|
||||
* Kill client on request.
|
||||
* Handler for the IRC "KILL" command.
|
||||
*
|
||||
* This function implements the IRC command "KILL" wich is used to selectively
|
||||
* disconnect clients. It can be used by IRC operators and servers, for example
|
||||
* to "solve" nick collisions after netsplits.
|
||||
* to "solve" nick collisions after netsplits. See RFC 2812 section 3.7.1.
|
||||
*
|
||||
* Please note that this function is also called internally, without a real
|
||||
* KILL command being received over the network! Client is Client_ThisServer()
|
||||
* in this case. */
|
||||
* in this case, and the prefix in Req is NULL.
|
||||
*
|
||||
* @param Client The client from which this command has been received
|
||||
* or Client_ThisServer() when generated interanlly.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_KILL( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
@@ -77,55 +114,47 @@ IRC_KILL( CLIENT *Client, REQUEST *Req )
|
||||
char reason[COMMAND_LEN], *msg;
|
||||
CONN_ID my_conn, conn;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
assert (Client != NULL);
|
||||
assert (Req != NULL);
|
||||
|
||||
if(( Client_Type( Client ) != CLIENT_SERVER ) &&
|
||||
( ! Client_OperByMe( Client )))
|
||||
{
|
||||
/* The originator of the KILL is neither an IRC operator of
|
||||
* this server nor a server. */
|
||||
return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG,
|
||||
Client_ID( Client ));
|
||||
}
|
||||
if (Client_Type(Client) != CLIENT_SERVER && !Client_OperByMe(Client))
|
||||
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
|
||||
Client_ID(Client));
|
||||
|
||||
if( Req->argc != 2 )
|
||||
{
|
||||
/* This command requires exactly 2 parameters! */
|
||||
return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID( Client ), Req->command );
|
||||
}
|
||||
if (Req->argc != 2)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
if( Req->prefix ) prefix = Client_Search( Req->prefix );
|
||||
else prefix = Client;
|
||||
if( ! prefix )
|
||||
{
|
||||
Log( LOG_WARNING, "Got KILL with invalid prefix: \"%s\"!",
|
||||
Req->prefix );
|
||||
prefix = Client_ThisServer( );
|
||||
}
|
||||
|
||||
if( Client != Client_ThisServer( ))
|
||||
{
|
||||
/* This is a "real" KILL received from the network. */
|
||||
Log( LOG_NOTICE|LOG_snotice, "Got KILL command from \"%s\" for \"%s\": %s",
|
||||
Client_Mask( prefix ), Req->argv[0], Req->argv[1] );
|
||||
}
|
||||
|
||||
/* Build reason string */
|
||||
if( Client_Type( Client ) == CLIENT_USER )
|
||||
{
|
||||
/* Prefix the "reason" if the originator is a regular user,
|
||||
* so users can't spoof KILLs of servers. */
|
||||
snprintf( reason, sizeof( reason ), "KILLed by %s: %s",
|
||||
Client_ID( Client ), Req->argv[1] );
|
||||
}
|
||||
/* Get prefix (origin); use the client if no prefix is given. */
|
||||
if (Req->prefix)
|
||||
prefix = Client_Search(Req->prefix);
|
||||
else
|
||||
strlcpy( reason, Req->argv[1], sizeof( reason ));
|
||||
prefix = Client;
|
||||
|
||||
/* Log a warning message and use this server as origin when the
|
||||
* prefix (origin) is invalid. */
|
||||
if (!prefix) {
|
||||
Log(LOG_WARNING, "Got KILL with invalid prefix: \"%s\"!",
|
||||
Req->prefix );
|
||||
prefix = Client_ThisServer();
|
||||
}
|
||||
|
||||
if (Client != Client_ThisServer())
|
||||
Log(LOG_NOTICE|LOG_snotice,
|
||||
"Got KILL command from \"%s\" for \"%s\": %s",
|
||||
Client_Mask(prefix), Req->argv[0], Req->argv[1]);
|
||||
|
||||
/* Build reason string: Prefix the "reason" if the originator is a
|
||||
* regular user, so users can't spoof KILLs of servers. */
|
||||
if (Client_Type(Client) == CLIENT_USER)
|
||||
snprintf(reason, sizeof(reason), "KILLed by %s: %s",
|
||||
Client_ID(Client), Req->argv[1]);
|
||||
else
|
||||
strlcpy(reason, Req->argv[1], sizeof(reason));
|
||||
|
||||
/* Inform other servers */
|
||||
IRC_WriteStrServersPrefix( Client, prefix, "KILL %s :%s",
|
||||
Req->argv[0], reason );
|
||||
IRC_WriteStrServersPrefix(Client, prefix, "KILL %s :%s",
|
||||
Req->argv[0], reason);
|
||||
|
||||
/* Save ID of this connection */
|
||||
my_conn = Client_Conn( Client );
|
||||
@@ -320,6 +349,7 @@ static bool
|
||||
Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
|
||||
{
|
||||
CLIENT *cl, *from;
|
||||
CL2CHAN *cl2chan;
|
||||
CHANNEL *chan;
|
||||
char *currentTarget = Req->argv[0];
|
||||
char *lastCurrentTarget = NULL;
|
||||
@@ -410,8 +440,8 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
|
||||
Client_Type(cl) != CLIENT_SERVICE)
|
||||
continue;
|
||||
if (nick != NULL && host != NULL) {
|
||||
if (strcmp(nick, Client_ID(cl)) == 0 &&
|
||||
strcmp(user, Client_User(cl)) == 0 &&
|
||||
if (strcasecmp(nick, Client_ID(cl)) == 0 &&
|
||||
strcasecmp(user, Client_User(cl)) == 0 &&
|
||||
strcasecmp(host, Client_HostnameCloaked(cl)) == 0)
|
||||
break;
|
||||
else
|
||||
@@ -439,11 +469,11 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
|
||||
#else
|
||||
if (Client_Type(cl) != ForceType) {
|
||||
#endif
|
||||
if (!SendErrors)
|
||||
return CONNECTED;
|
||||
return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(from),
|
||||
currentTarget);
|
||||
if (SendErrors && !IRC_WriteStrClient(
|
||||
from, ERR_NOSUCHNICK_MSG,Client_ID(from),
|
||||
currentTarget))
|
||||
return DISCONNECTED;
|
||||
goto send_next_target;
|
||||
}
|
||||
|
||||
#ifndef STRICT_RFC
|
||||
@@ -456,6 +486,23 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Client_HasMode(cl, 'C')) {
|
||||
cl2chan = Channel_FirstChannelOf(cl);
|
||||
while (cl2chan) {
|
||||
chan = Channel_GetChannel(cl2chan);
|
||||
if (Channel_IsMemberOf(chan, from))
|
||||
break;
|
||||
cl2chan = Channel_NextChannelOf(cl, cl2chan);
|
||||
}
|
||||
if (!cl2chan) {
|
||||
if (SendErrors && !IRC_WriteStrClient(
|
||||
from, ERR_NOTONSAMECHANNEL_MSG,
|
||||
Client_ID(from), Client_ID(cl)))
|
||||
return DISCONNECTED;
|
||||
goto send_next_target;
|
||||
}
|
||||
}
|
||||
|
||||
if (SendErrors && (Client_Type(Client) != CLIENT_SERVER)
|
||||
&& strchr(Client_Modes(cl), 'a')) {
|
||||
/* Target is away */
|
||||
@@ -493,7 +540,10 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
send_next_target:
|
||||
currentTarget = strtok_r(NULL, ",", &lastCurrentTarget);
|
||||
if (currentTarget)
|
||||
Conn_SetPenalty(Client_Conn(Client), 1);
|
||||
}
|
||||
|
||||
return CONNECTED;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,6 +17,9 @@
|
||||
* IRC commands (header)
|
||||
*/
|
||||
|
||||
GLOBAL bool IRC_CheckListTooBig PARAMS((CLIENT *From, const int Count,
|
||||
const int Limit, const char *Name));
|
||||
|
||||
GLOBAL bool IRC_ERROR PARAMS((CLIENT *Client, REQUEST *Req));
|
||||
GLOBAL bool IRC_KILL PARAMS((CLIENT *Client, REQUEST *Req));
|
||||
GLOBAL bool IRC_NOTICE PARAMS((CLIENT *Client, REQUEST *Req));
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2005 Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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,89 +37,178 @@
|
||||
#define MASK_LEN (2*CLIENT_HOST_LEN)
|
||||
|
||||
struct list_elem {
|
||||
struct list_elem *next;
|
||||
char mask[MASK_LEN];
|
||||
bool onlyonce;
|
||||
struct list_elem *next; /** pointer to next list element */
|
||||
char mask[MASK_LEN]; /** IRC mask */
|
||||
char *reason; /** Optional "reason" text */
|
||||
time_t valid_until; /** 0: unlimited; 1: once; t(>1): until t */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get IRC mask stored in list element.
|
||||
*
|
||||
* @param list_elem List element.
|
||||
* @return Pointer to IRC mask
|
||||
*/
|
||||
GLOBAL const char *
|
||||
Lists_GetMask(const struct list_elem *e)
|
||||
{
|
||||
assert(e != NULL);
|
||||
return e->mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get optional "reason" text stored in list element.
|
||||
*
|
||||
* @param list_elem List element.
|
||||
* @return Pointer to "reason" text or empty string ("").
|
||||
*/
|
||||
GLOBAL const char *
|
||||
Lists_GetReason(const struct list_elem *e)
|
||||
{
|
||||
assert(e != NULL);
|
||||
return e->reason ? e->reason : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "validity" value stored in list element.
|
||||
*
|
||||
* @param list_elem List element.
|
||||
* @return Validity: 0=unlimited, 1=once, >1 until this time stamp.
|
||||
*/
|
||||
GLOBAL time_t
|
||||
Lists_GetValidity(const struct list_elem *e)
|
||||
{
|
||||
assert(e != NULL);
|
||||
return e->valid_until;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get first list element of a list.
|
||||
*
|
||||
* @param h List head.
|
||||
* @return Pointer to first list element.
|
||||
*/
|
||||
GLOBAL struct list_elem*
|
||||
Lists_GetFirst(const struct list_head *h)
|
||||
{
|
||||
assert(h != NULL);
|
||||
return h->first;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get next list element of a list.
|
||||
*
|
||||
* @param e Current list element.
|
||||
* @return Pointer to next list element.
|
||||
*/
|
||||
GLOBAL struct list_elem*
|
||||
Lists_GetNext(const struct list_elem *e)
|
||||
{
|
||||
assert(e != NULL);
|
||||
return e->next;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a new mask to a list.
|
||||
*
|
||||
* @param h List head.
|
||||
* @param Mask The IRC mask to add to the list.
|
||||
* @param ValidUntil 0: unlimited, 1: only once, t>1: until given time_t.
|
||||
* @param Reason Reason string or NULL, if no reason should be saved.
|
||||
* @return true on success, false otherwise.
|
||||
*/
|
||||
bool
|
||||
Lists_Add(struct list_head *header, const char *Mask, bool OnlyOnce )
|
||||
Lists_Add(struct list_head *h, const char *Mask, time_t ValidUntil,
|
||||
const char *Reason)
|
||||
{
|
||||
struct list_elem *e, *newelem;
|
||||
|
||||
assert( header != NULL );
|
||||
assert( Mask != NULL );
|
||||
assert(h != NULL);
|
||||
assert(Mask != NULL);
|
||||
|
||||
if (Lists_CheckDupeMask(header, Mask )) return true;
|
||||
e = Lists_CheckDupeMask(h, Mask);
|
||||
if (e) {
|
||||
e->valid_until = ValidUntil;
|
||||
if (Reason) {
|
||||
free(e->reason);
|
||||
e->reason = strdup(Reason);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
e = Lists_GetFirst(header);
|
||||
e = Lists_GetFirst(h);
|
||||
|
||||
newelem = malloc(sizeof(struct list_elem));
|
||||
if( ! newelem ) {
|
||||
Log( LOG_EMERG, "Can't allocate memory for new Ban/Invite entry!" );
|
||||
if (!newelem) {
|
||||
Log(LOG_EMERG,
|
||||
"Can't allocate memory for new list entry!");
|
||||
return false;
|
||||
}
|
||||
|
||||
strlcpy( newelem->mask, Mask, sizeof( newelem->mask ));
|
||||
newelem->onlyonce = OnlyOnce;
|
||||
strlcpy(newelem->mask, Mask, sizeof(newelem->mask));
|
||||
if (Reason) {
|
||||
newelem->reason = malloc(strlen(Reason) + 1);
|
||||
if (newelem->reason)
|
||||
strlcpy(newelem->reason, Reason, strlen(Reason) + 1);
|
||||
else
|
||||
Log(LOG_EMERG,
|
||||
"Can't allocate memory for new list reason text!");
|
||||
}
|
||||
else
|
||||
newelem->reason = NULL;
|
||||
newelem->valid_until = ValidUntil;
|
||||
newelem->next = e;
|
||||
header->first = newelem;
|
||||
h->first = newelem;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a list element from a list.
|
||||
*
|
||||
* @param h List head.
|
||||
* @param p Pointer to previous list element or NULL, if there is none.
|
||||
* @param victim List element to delete.
|
||||
*/
|
||||
static void
|
||||
Lists_Unlink(struct list_head *header, struct list_elem *p, struct list_elem *victim)
|
||||
Lists_Unlink(struct list_head *h, struct list_elem *p, struct list_elem *victim)
|
||||
{
|
||||
assert(victim != NULL);
|
||||
assert(header != NULL);
|
||||
assert(h != NULL);
|
||||
|
||||
if (p) p->next = victim->next;
|
||||
else header->first = victim->next;
|
||||
if (p)
|
||||
p->next = victim->next;
|
||||
else
|
||||
h->first = victim->next;
|
||||
|
||||
if (victim->reason)
|
||||
free(victim->reason);
|
||||
|
||||
free(victim);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a given IRC mask from a list.
|
||||
*
|
||||
* @param h List head.
|
||||
* @param Mask IRC mask to delete from the list.
|
||||
*/
|
||||
GLOBAL void
|
||||
Lists_Del(struct list_head *header, const char *Mask)
|
||||
Lists_Del(struct list_head *h, const char *Mask)
|
||||
{
|
||||
struct list_elem *e, *last, *victim;
|
||||
|
||||
assert( header != NULL );
|
||||
assert( Mask != NULL );
|
||||
assert(h != NULL);
|
||||
assert(Mask != NULL);
|
||||
|
||||
last = NULL;
|
||||
e = Lists_GetFirst(header);
|
||||
while( e ) {
|
||||
if(strcasecmp( e->mask, Mask ) == 0 ) {
|
||||
e = Lists_GetFirst(h);
|
||||
while (e) {
|
||||
if (strcasecmp(e->mask, Mask) == 0) {
|
||||
LogDebug("Deleted \"%s\" from list", e->mask);
|
||||
victim = e;
|
||||
e = victim->next;
|
||||
Lists_Unlink(header, last, victim);
|
||||
Lists_Unlink(h, last, victim);
|
||||
continue;
|
||||
}
|
||||
last = e;
|
||||
@@ -127,7 +216,11 @@ Lists_Del(struct list_head *header, const char *Mask)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free a complete list.
|
||||
*
|
||||
* @param head List head.
|
||||
*/
|
||||
GLOBAL void
|
||||
Lists_Free(struct list_head *head)
|
||||
{
|
||||
@@ -138,101 +231,193 @@ Lists_Free(struct list_head *head)
|
||||
e = head->first;
|
||||
head->first = NULL;
|
||||
while (e) {
|
||||
LogDebug("Deleted \"%s\" from invite list" , e->mask);
|
||||
LogDebug("Deleted \"%s\" from list" , e->mask);
|
||||
victim = e;
|
||||
e = e->next;
|
||||
free( victim );
|
||||
if (victim->reason)
|
||||
free(victim->reason);
|
||||
free(victim);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GLOBAL bool
|
||||
/**
|
||||
* Check if an IRC mask is already contained in a list.
|
||||
*
|
||||
* @param h List head.
|
||||
* @param Mask IRC mask to test.
|
||||
* @return true if mask is already stored in the list, false otherwise.
|
||||
*/
|
||||
GLOBAL struct list_elem *
|
||||
Lists_CheckDupeMask(const struct list_head *h, const char *Mask )
|
||||
{
|
||||
struct list_elem *e;
|
||||
e = h->first;
|
||||
while (e) {
|
||||
if (strcasecmp( e->mask, Mask ) == 0 )
|
||||
return true;
|
||||
if (strcasecmp(e->mask, Mask) == 0)
|
||||
return e;
|
||||
e = e->next;
|
||||
}
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate a valid IRC mask from "any" string given.
|
||||
*
|
||||
* Attention: This mask is only valid until the next call to Lists_MakeMask(),
|
||||
* because a single global buffer ist used! You have to copy the generated
|
||||
* mask to some sane location yourself!
|
||||
*
|
||||
* @param Pattern Source string to generate an IRC mask for.
|
||||
* @return Pointer to global result buffer.
|
||||
*/
|
||||
GLOBAL const char *
|
||||
Lists_MakeMask(const char *Pattern)
|
||||
{
|
||||
/* This function generats a valid IRC mask of "any" string. This
|
||||
* mask is only valid until the next call to Lists_MakeMask(),
|
||||
* because a single global buffer is used. You have to copy the
|
||||
* generated mask to some sane location yourself! */
|
||||
|
||||
static char TheMask[MASK_LEN];
|
||||
char *excl, *at;
|
||||
|
||||
assert( Pattern != NULL );
|
||||
assert(Pattern != NULL);
|
||||
|
||||
excl = strchr( Pattern, '!' );
|
||||
at = strchr( Pattern, '@' );
|
||||
excl = strchr(Pattern, '!');
|
||||
at = strchr(Pattern, '@');
|
||||
|
||||
if(( at ) && ( at < excl )) excl = NULL;
|
||||
if (at && at < excl)
|
||||
excl = NULL;
|
||||
|
||||
if(( ! at ) && ( ! excl ))
|
||||
{
|
||||
if (!at && !excl) {
|
||||
/* Neither "!" nor "@" found: use string as nick name */
|
||||
strlcpy( TheMask, Pattern, sizeof( TheMask ) - 5 );
|
||||
strlcat( TheMask, "!*@*", sizeof( TheMask ));
|
||||
strlcpy(TheMask, Pattern, sizeof(TheMask) - 5);
|
||||
strlcat(TheMask, "!*@*", sizeof(TheMask));
|
||||
return TheMask;
|
||||
}
|
||||
|
||||
if(( ! at ) && ( excl ))
|
||||
{
|
||||
if (!at && excl) {
|
||||
/* Domain part is missing */
|
||||
strlcpy( TheMask, Pattern, sizeof( TheMask ) - 3 );
|
||||
strlcat( TheMask, "@*", sizeof( TheMask ));
|
||||
strlcpy(TheMask, Pattern, sizeof(TheMask) - 3);
|
||||
strlcat(TheMask, "@*", sizeof(TheMask));
|
||||
return TheMask;
|
||||
}
|
||||
|
||||
if(( at ) && ( ! excl ))
|
||||
{
|
||||
if (at && !excl) {
|
||||
/* User name is missing */
|
||||
*at = '\0'; at++;
|
||||
strlcpy( TheMask, Pattern, sizeof( TheMask ) - 5 );
|
||||
strlcat( TheMask, "!*@", sizeof( TheMask ));
|
||||
strlcat( TheMask, at, sizeof( TheMask ));
|
||||
strlcpy(TheMask, Pattern, sizeof(TheMask) - 5);
|
||||
strlcat(TheMask, "!*@", sizeof(TheMask));
|
||||
strlcat(TheMask, at, sizeof(TheMask));
|
||||
return TheMask;
|
||||
}
|
||||
|
||||
/* All parts (nick, user and domain name) are given */
|
||||
strlcpy( TheMask, Pattern, sizeof( TheMask ));
|
||||
strlcpy(TheMask, Pattern, sizeof(TheMask));
|
||||
return TheMask;
|
||||
} /* Lists_MakeMask */
|
||||
|
||||
|
||||
/**
|
||||
* Check if a client is listed in a list.
|
||||
*
|
||||
* @param h List head.
|
||||
* @param Client Client to check.
|
||||
* @return true if client is listed, false if not.
|
||||
*/
|
||||
bool
|
||||
Lists_Check( struct list_head *header, CLIENT *Client)
|
||||
Lists_Check(struct list_head *h, CLIENT *Client)
|
||||
{
|
||||
struct list_elem *e, *last;
|
||||
return Lists_CheckReason(h, Client) != NULL;
|
||||
}
|
||||
|
||||
assert( header != NULL );
|
||||
/**
|
||||
* Check if a client is listed in a list and return the "reason".
|
||||
*
|
||||
* @param h List head.
|
||||
* @param Client Client to check.
|
||||
* @return true if client is listed, false if not.
|
||||
*/
|
||||
char *
|
||||
Lists_CheckReason(struct list_head *h, CLIENT *Client)
|
||||
{
|
||||
struct list_elem *e, *last, *next;
|
||||
|
||||
e = header->first;
|
||||
assert(h != NULL);
|
||||
|
||||
e = h->first;
|
||||
last = NULL;
|
||||
|
||||
while( e ) {
|
||||
if( Match( e->mask, Client_Mask( Client ))) {
|
||||
if( e->onlyonce ) { /* delete entry */
|
||||
LogDebug("Deleted \"%s\" from list", e->mask);
|
||||
Lists_Unlink(header, last, e);
|
||||
while (e) {
|
||||
next = e->next;
|
||||
if (Match(e->mask, Client_Mask(Client))) {
|
||||
if (e->valid_until == 1) {
|
||||
/* Entry is valid only once, delete it */
|
||||
LogDebug("Deleted \"%s\" from list (used).",
|
||||
e->mask);
|
||||
Lists_Unlink(h, last, e);
|
||||
}
|
||||
return true;
|
||||
return e->reason ? e->reason : "";
|
||||
}
|
||||
last = e;
|
||||
e = e->next;
|
||||
e = next;
|
||||
}
|
||||
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check list and purge expired entries.
|
||||
*
|
||||
* @param h List head.
|
||||
*/
|
||||
GLOBAL void
|
||||
Lists_Expire(struct list_head *h, const char *ListName)
|
||||
{
|
||||
struct list_elem *e, *last, *next;
|
||||
time_t now;
|
||||
|
||||
assert(h != NULL);
|
||||
|
||||
e = h->first;
|
||||
last = NULL;
|
||||
now = time(NULL);
|
||||
|
||||
while (e) {
|
||||
next = e->next;
|
||||
if (e->valid_until > 1 && e->valid_until < now) {
|
||||
/* Entry is expired, delete it */
|
||||
if (e->reason)
|
||||
Log(LOG_INFO,
|
||||
"Deleted \"%s\" (\"%s\") from %s list (expired).",
|
||||
e->mask, e->reason, ListName);
|
||||
else
|
||||
Log(LOG_INFO,
|
||||
"Deleted \"%s\" from %s list (expired).",
|
||||
e->mask, ListName);
|
||||
Lists_Unlink(h, last, e);
|
||||
e = next;
|
||||
continue;
|
||||
}
|
||||
last = e;
|
||||
e = next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of entries of a list.
|
||||
*
|
||||
* @param h List head.
|
||||
* @return Number of items.
|
||||
*/
|
||||
GLOBAL unsigned long
|
||||
Lists_Count(struct list_head *h)
|
||||
{
|
||||
struct list_elem *e;
|
||||
unsigned long count = 0;
|
||||
|
||||
assert(h != NULL);
|
||||
|
||||
e = h->first;
|
||||
while (e) {
|
||||
count++;
|
||||
e = e->next;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* -eof- */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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,18 +29,24 @@ struct list_head {
|
||||
GLOBAL struct list_elem *Lists_GetFirst PARAMS((const struct list_head *));
|
||||
GLOBAL struct list_elem *Lists_GetNext PARAMS((const struct list_elem *));
|
||||
|
||||
GLOBAL bool Lists_Check PARAMS((struct list_head *head, CLIENT *client ));
|
||||
GLOBAL bool Lists_CheckDupeMask PARAMS((const struct list_head *head, const char *mask ));
|
||||
GLOBAL bool Lists_Check PARAMS((struct list_head *head, CLIENT *client));
|
||||
GLOBAL char *Lists_CheckReason PARAMS((struct list_head *head, CLIENT *client));
|
||||
GLOBAL struct list_elem *Lists_CheckDupeMask PARAMS((const struct list_head *head,
|
||||
const char *mask));
|
||||
|
||||
GLOBAL bool Lists_Add PARAMS((struct list_head *header, const char *Mask, bool OnlyOnce ));
|
||||
GLOBAL void Lists_Del PARAMS((struct list_head *head, const char *Mask ));
|
||||
GLOBAL bool Lists_Add PARAMS((struct list_head *h, const char *Mask,
|
||||
time_t ValidUntil, const char *Reason));
|
||||
GLOBAL void Lists_Del PARAMS((struct list_head *head, const char *Mask));
|
||||
GLOBAL unsigned long Lists_Count PARAMS((struct list_head *h));
|
||||
|
||||
GLOBAL bool Lists_AlreadyRegistered PARAMS(( const struct list_head *head, const char *Mask));
|
||||
|
||||
GLOBAL void Lists_Free PARAMS(( struct list_head *head ));
|
||||
GLOBAL void Lists_Free PARAMS((struct list_head *head));
|
||||
|
||||
GLOBAL const char *Lists_MakeMask PARAMS((const char *Pattern));
|
||||
GLOBAL const char *Lists_GetMask PARAMS(( const struct list_elem *e ));
|
||||
GLOBAL const char *Lists_GetMask PARAMS((const struct list_elem *e));
|
||||
GLOBAL const char *Lists_GetReason PARAMS((const struct list_elem *e));
|
||||
GLOBAL time_t Lists_GetValidity PARAMS((const struct list_elem *e));
|
||||
|
||||
GLOBAL void Lists_Expire PARAMS((struct list_head *h, const char *ListName));
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2012 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
|
||||
@@ -44,7 +44,6 @@
|
||||
#include "log.h"
|
||||
|
||||
|
||||
static char Init_Txt[127];
|
||||
static bool Is_Daemon;
|
||||
|
||||
|
||||
@@ -65,11 +64,17 @@ Log_Message(int Level, const char *msg)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialitze logging.
|
||||
* This function is called before the configuration file is read in.
|
||||
*
|
||||
* @param Daemon_Mode Set to true if ngIRCd is running as daemon.
|
||||
*/
|
||||
GLOBAL void
|
||||
Log_Init( bool Daemon_Mode )
|
||||
Log_Init(bool Daemon_Mode)
|
||||
{
|
||||
Is_Daemon = Daemon_Mode;
|
||||
|
||||
|
||||
#ifdef SYSLOG
|
||||
#ifndef LOG_CONS /* Kludge: mips-dec-ultrix4.5 has no LOG_CONS */
|
||||
#define LOG_CONS 0
|
||||
@@ -77,37 +82,27 @@ Log_Init( bool Daemon_Mode )
|
||||
openlog(PACKAGE_NAME, LOG_CONS|LOG_PID, Conf_SyslogFacility);
|
||||
#endif
|
||||
|
||||
Log( LOG_NOTICE, "%s started.", NGIRCd_Version );
|
||||
|
||||
/* Information about "Operation Mode" */
|
||||
Init_Txt[0] = '\0';
|
||||
#ifdef DEBUG
|
||||
if( NGIRCd_Debug )
|
||||
{
|
||||
strlcpy( Init_Txt, "debug-mode", sizeof Init_Txt );
|
||||
}
|
||||
#endif
|
||||
if( ! Is_Daemon )
|
||||
{
|
||||
if( Init_Txt[0] ) strlcat( Init_Txt, ", ", sizeof Init_Txt );
|
||||
strlcat( Init_Txt, "no-daemon-mode", sizeof Init_Txt );
|
||||
}
|
||||
if( NGIRCd_Passive )
|
||||
{
|
||||
if( Init_Txt[0] ) strlcat( Init_Txt, ", ", sizeof Init_Txt );
|
||||
strlcat( Init_Txt, "passive-mode", sizeof Init_Txt );
|
||||
}
|
||||
#ifdef SNIFFER
|
||||
if( NGIRCd_Sniffer )
|
||||
{
|
||||
if( Init_Txt[0] ) strlcat( Init_Txt, ", ", sizeof Init_Txt );
|
||||
strlcat( Init_Txt, "network sniffer", sizeof Init_Txt );
|
||||
}
|
||||
#endif
|
||||
if( Init_Txt[0] ) Log( LOG_INFO, "Activating: %s.", Init_Txt );
|
||||
Log(LOG_NOTICE, "%s started.", NGIRCd_Version);
|
||||
} /* Log_Init */
|
||||
|
||||
|
||||
/**
|
||||
* Re-init logging after reading the configuration file.
|
||||
*/
|
||||
GLOBAL void
|
||||
Log_ReInit(void)
|
||||
{
|
||||
#ifdef SYSLOG
|
||||
#ifndef LOG_CONS /* Kludge: mips-dec-ultrix4.5 has no LOG_CONS */
|
||||
#define LOG_CONS 0
|
||||
#endif
|
||||
closelog();
|
||||
openlog(PACKAGE_NAME, LOG_CONS|LOG_PID, Conf_SyslogFacility);
|
||||
#endif
|
||||
Log(LOG_NOTICE, "%s started.", NGIRCd_Version);
|
||||
}
|
||||
|
||||
|
||||
GLOBAL void
|
||||
Log_Exit( void )
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2012 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,6 +36,7 @@ GLOBAL void Log_Init PARAMS(( bool Daemon_Mode ));
|
||||
GLOBAL void Log_Exit PARAMS(( void ));
|
||||
|
||||
GLOBAL void Log PARAMS(( int Level, const char *Format, ... ));
|
||||
GLOBAL void Log_ReInit PARAMS((void));
|
||||
|
||||
GLOBAL void Log_ServerNotice PARAMS((char UserMode, const char *Format, ...));
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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
|
||||
@@ -21,14 +21,15 @@
|
||||
#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 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_ISUPPORT1_MSG "005 %s RFC2812 IRCD=ngIRCd CASEMAPPING=ascii PREFIX=(ov)@+ CHANTYPES=#&+ CHANMODES=beI,k,l,imnOPRstz CHANLIMIT=#&+:%d :are supported on this server"
|
||||
#define RPL_ISUPPORT2_MSG "005 %s CHANNELLEN=%d NICKLEN=%d TOPICLEN=%d AWAYLEN=%d KICKLEN=%d MODES=%d MAXLIST=beI:%d EXCEPTS=e INVEX=I PENALTY :are supported on this server"
|
||||
|
||||
#define RPL_TRACELINK_MSG "200 %s Link %s-%s %s %s V%s %ld %d %d"
|
||||
#define RPL_TRACEOPERATOR_MSG "204 %s Oper 2 :%s"
|
||||
#define RPL_TRACESERVER_MSG "206 %s Serv 1 0S 0C %s[%s@%s] *!*@%s :V%s"
|
||||
#define RPL_STATSLINKINFO_MSG "211 %s %s %d %ld %ld %ld %ld :%ld"
|
||||
#define RPL_STATSCOMMANDS_MSG "212 %s %s %ld %ld %ld"
|
||||
#define RPL_STATSXLINE_MSG "216 %s %c %s %ld :%s"
|
||||
#define RPL_ENDOFSTATS_MSG "219 %s %c :End of STATS report"
|
||||
#define RPL_UMODEIS_MSG "221 %s +%s"
|
||||
#define RPL_SERVLIST_MSG "234 %s %s %s %s %d %d :%s"
|
||||
@@ -55,6 +56,7 @@
|
||||
#define RPL_ISON_MSG "303 %s :"
|
||||
#define RPL_UNAWAY_MSG "305 %s :You are no longer marked as being away"
|
||||
#define RPL_NOWAWAY_MSG "306 %s :You have been marked as being away"
|
||||
#define RPL_WHOISREGNICK_MSG "307 %s %s :is a registered nick"
|
||||
#define RPL_WHOISUSER_MSG "311 %s %s %s %s * :%s"
|
||||
#define RPL_WHOISSERVER_MSG "312 %s %s %s :%s"
|
||||
#define RPL_WHOISOPERATOR_MSG "313 %s %s :is an IRC operator"
|
||||
@@ -73,6 +75,8 @@
|
||||
#define RPL_INVITING_MSG "341 %s %s %s%s"
|
||||
#define RPL_INVITELIST_MSG "346 %s %s %s"
|
||||
#define RPL_ENDOFINVITELIST_MSG "347 %s %s :End of channel invite list"
|
||||
#define RPL_EXCEPTLIST_MSG "348 %s %s %s"
|
||||
#define RPL_ENDOFEXCEPTLIST_MSG "349 %s %s :End of channel exception list"
|
||||
#define RPL_VERSION_MSG "351 %s %s-%s.%s %s :%s"
|
||||
#define RPL_WHOREPLY_MSG "352 %s %s %s %s %s %s %s :%d %s"
|
||||
#define RPL_NAMREPLY_MSG "353 %s %s %s :"
|
||||
@@ -87,6 +91,7 @@
|
||||
#define RPL_MOTD_MSG "372 %s :- %s"
|
||||
#define RPL_MOTDSTART_MSG "375 %s :- %s message of the day"
|
||||
#define RPL_ENDOFMOTD_MSG "376 %s :End of MOTD command"
|
||||
#define RPL_WHOISHOST_MSG "378 %s %s :is connecting from *@%s %s"
|
||||
#define RPL_YOUREOPER_MSG "381 %s :You are now an IRC Operator"
|
||||
#define RPL_YOURESERVICE_MSG "383 %s :You are service %s"
|
||||
#define RPL_TIME_MSG "391 %s %s :%s"
|
||||
@@ -105,12 +110,13 @@
|
||||
#define ERR_NOMOTD_MSG "422 %s :MOTD file is missing"
|
||||
#define ERR_NONICKNAMEGIVEN_MSG "431 %s :No nickname given"
|
||||
#define ERR_ERRONEUSNICKNAME_MSG "432 %s %s :Erroneous nickname"
|
||||
#define ERR_NICKNAMETOOLONG_MSG "432 %s %s :Nickname too long, max. %u characters"
|
||||
#define ERR_NICKNAMEINUSE_MSG "433 %s %s :Nickname already in use"
|
||||
#define ERR_USERNOTINCHANNEL_MSG "441 %s %s %s :They aren't on that channel"
|
||||
#define ERR_NOTONCHANNEL_MSG "442 %s %s :You are not on that channel"
|
||||
#define ERR_USERONCHANNEL_MSG "443 %s %s %s :is already on channel"
|
||||
#define ERR_SUMMONDISABLED_MSG "445 %s %s :SUMMON has been disabled"
|
||||
#define ERR_USERSDISABLED_MSG "446 %s %s :USERS has been disabled"
|
||||
#define ERR_SUMMONDISABLED_MSG "445 %s :SUMMON has been disabled"
|
||||
#define ERR_USERSDISABLED_MSG "446 %s :USERS has been disabled"
|
||||
#define ERR_NOTREGISTERED_MSG "451 %s :Connection not registered"
|
||||
#define ERR_NOTREGISTEREDSERVER_MSG "451 %s :Connection not registered as server link"
|
||||
#define ERR_NEEDMOREPARAMS_MSG "461 %s %s :Syntax error"
|
||||
@@ -119,16 +125,19 @@
|
||||
#define ERR_CHANNELISFULL_MSG "471 %s %s :Cannot join channel (+l)"
|
||||
#define ERR_SECURECHANNEL_MSG "471 %s %s :Cannot join channel (+z)"
|
||||
#define ERR_OPONLYCHANNEL_MSG "471 %s %s :Cannot join channel (+O)"
|
||||
#define ERR_UNKNOWNMODE_MSG "472 %s: %c :is unknown mode char for %s"
|
||||
#define ERR_REGONLYCHANNEL_MSG "471 %s %s :Cannot join channel (+R)"
|
||||
#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)"
|
||||
#define ERR_BADCHANNELKEY_MSG "475 %s %s :Cannot join channel (+k)"
|
||||
#define ERR_NOCHANMODES_MSG "477 %s %s :Channel doesn't support modes"
|
||||
#define ERR_LISTFULL_MSG "478 %s %s %s: Channel list is full (%d)"
|
||||
#define ERR_NOPRIVILEGES_MSG "481 %s :Permission denied"
|
||||
#define ERR_CHANOPRIVSNEEDED_MSG "482 %s %s :You are not channel operator"
|
||||
#define ERR_CANTKILLSERVER_MSG "483 %s :You can't kill a server!"
|
||||
#define ERR_RESTRICTED_MSG "484 %s :Your connection is restricted"
|
||||
#define ERR_NOOPERHOST_MSG "491 %s :Not configured for your host"
|
||||
#define ERR_NOTONSAMECHANNEL_MSG "493 %s :You must share a common channel with %s"
|
||||
|
||||
#define ERR_UMODEUNKNOWNFLAG_MSG "501 %s :Unknown mode"
|
||||
#define ERR_UMODEUNKNOWNFLAG2_MSG "501 %s :Unknown mode \"%c%c\""
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include "defines.h"
|
||||
#include "conn.h"
|
||||
#include "class.h"
|
||||
#include "conf-ssl.h"
|
||||
#include "channel.h"
|
||||
#include "conf.h"
|
||||
@@ -73,12 +74,12 @@ static bool NGIRCd_Init PARAMS(( bool ));
|
||||
* Here all starts: this function is called by the operating system loader,
|
||||
* it is the first portion of code executed of ngIRCd.
|
||||
*
|
||||
* @param argc The number of arguments passed to ngIRCd on the command line.
|
||||
* @param argv An array containing all the arguments passed to ngIRCd.
|
||||
* @return Global exit code of ngIRCd, zero on success.
|
||||
* @param argc The number of arguments passed to ngIRCd on the command line.
|
||||
* @param argv An array containing all the arguments passed to ngIRCd.
|
||||
* @return Global exit code of ngIRCd, zero on success.
|
||||
*/
|
||||
GLOBAL int
|
||||
main( int argc, const char *argv[] )
|
||||
main(int argc, const char *argv[])
|
||||
{
|
||||
bool ok, configtest = false;
|
||||
bool NGIRCd_NoDaemon = false;
|
||||
@@ -91,7 +92,7 @@ main( int argc, const char *argv[] )
|
||||
mtrace();
|
||||
#endif
|
||||
|
||||
umask( 0077 );
|
||||
umask(0077);
|
||||
|
||||
NGIRCd_SignalQuit = NGIRCd_SignalRestart = false;
|
||||
NGIRCd_Passive = false;
|
||||
@@ -101,75 +102,62 @@ main( int argc, const char *argv[] )
|
||||
#ifdef SNIFFER
|
||||
NGIRCd_Sniffer = false;
|
||||
#endif
|
||||
strlcpy( NGIRCd_ConfFile, SYSCONFDIR, sizeof( NGIRCd_ConfFile ));
|
||||
strlcat( NGIRCd_ConfFile, CONFIG_FILE, sizeof( NGIRCd_ConfFile ));
|
||||
strlcpy(NGIRCd_ConfFile, SYSCONFDIR, sizeof(NGIRCd_ConfFile));
|
||||
strlcat(NGIRCd_ConfFile, CONFIG_FILE, sizeof(NGIRCd_ConfFile));
|
||||
|
||||
Fill_Version( );
|
||||
Fill_Version();
|
||||
|
||||
/* parse conmmand line */
|
||||
for( i = 1; i < argc; i++ )
|
||||
{
|
||||
for (i = 1; i < argc; i++) {
|
||||
ok = false;
|
||||
if(( argv[i][0] == '-' ) && ( argv[i][1] == '-' ))
|
||||
{
|
||||
if (argv[i][0] == '-' && argv[i][1] == '-') {
|
||||
/* long option */
|
||||
if( strcmp( argv[i], "--config" ) == 0 )
|
||||
{
|
||||
if( i + 1 < argc )
|
||||
{
|
||||
if (strcmp(argv[i], "--config") == 0) {
|
||||
if (i + 1 < argc) {
|
||||
/* Ok, there's an parameter left */
|
||||
strlcpy( NGIRCd_ConfFile, argv[i + 1], sizeof( NGIRCd_ConfFile ));
|
||||
|
||||
strlcpy(NGIRCd_ConfFile, argv[i+1],
|
||||
sizeof(NGIRCd_ConfFile));
|
||||
/* next parameter */
|
||||
i++; ok = true;
|
||||
}
|
||||
}
|
||||
if( strcmp( argv[i], "--configtest" ) == 0 )
|
||||
{
|
||||
if (strcmp(argv[i], "--configtest") == 0) {
|
||||
configtest = true;
|
||||
ok = true;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if( strcmp( argv[i], "--debug" ) == 0 )
|
||||
{
|
||||
if (strcmp(argv[i], "--debug") == 0) {
|
||||
NGIRCd_Debug = true;
|
||||
ok = true;
|
||||
}
|
||||
#endif
|
||||
if( strcmp( argv[i], "--help" ) == 0 )
|
||||
{
|
||||
Show_Version( );
|
||||
puts( "" ); Show_Help( ); puts( "" );
|
||||
exit( 1 );
|
||||
if (strcmp(argv[i], "--help") == 0) {
|
||||
Show_Version();
|
||||
puts(""); Show_Help( ); puts( "" );
|
||||
exit(1);
|
||||
}
|
||||
if( strcmp( argv[i], "--nodaemon" ) == 0 )
|
||||
{
|
||||
if (strcmp(argv[i], "--nodaemon") == 0) {
|
||||
NGIRCd_NoDaemon = true;
|
||||
ok = true;
|
||||
}
|
||||
if( strcmp( argv[i], "--passive" ) == 0 )
|
||||
{
|
||||
if (strcmp(argv[i], "--passive") == 0) {
|
||||
NGIRCd_Passive = true;
|
||||
ok = true;
|
||||
}
|
||||
#ifdef SNIFFER
|
||||
if( strcmp( argv[i], "--sniffer" ) == 0 )
|
||||
{
|
||||
if (strcmp(argv[i], "--sniffer") == 0) {
|
||||
NGIRCd_Sniffer = true;
|
||||
ok = true;
|
||||
}
|
||||
#endif
|
||||
if( strcmp( argv[i], "--version" ) == 0 )
|
||||
{
|
||||
Show_Version( );
|
||||
exit( 1 );
|
||||
if (strcmp(argv[i], "--version") == 0) {
|
||||
Show_Version();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else if(( argv[i][0] == '-' ) && ( argv[i][1] != '-' ))
|
||||
{
|
||||
else if(argv[i][0] == '-' && argv[i][1] != '-') {
|
||||
/* short option */
|
||||
for( n = 1; n < strlen( argv[i] ); n++ )
|
||||
{
|
||||
for (n = 1; n < strlen(argv[i]); n++) {
|
||||
ok = false;
|
||||
#ifdef DEBUG
|
||||
if (argv[i][n] == 'd') {
|
||||
@@ -178,14 +166,14 @@ main( int argc, const char *argv[] )
|
||||
}
|
||||
#endif
|
||||
if (argv[i][n] == 'f') {
|
||||
if(( ! argv[i][n + 1] ) && ( i + 1 < argc ))
|
||||
{
|
||||
if (!argv[i][n+1] && i+1 < argc) {
|
||||
/* Ok, next character is a blank */
|
||||
strlcpy( NGIRCd_ConfFile, argv[i + 1], sizeof( NGIRCd_ConfFile ));
|
||||
strlcpy(NGIRCd_ConfFile, argv[i+1],
|
||||
sizeof(NGIRCd_ConfFile));
|
||||
|
||||
/* go to the following parameter */
|
||||
i++;
|
||||
n = strlen( argv[i] );
|
||||
n = strlen(argv[i]);
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
@@ -220,55 +208,58 @@ main( int argc, const char *argv[] )
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (! ok) {
|
||||
printf( "%s: invalid option \"-%c\"!\n", PACKAGE_NAME, argv[i][n] );
|
||||
printf( "Try \"%s --help\" for more information.\n", PACKAGE_NAME );
|
||||
exit( 1 );
|
||||
if (!ok) {
|
||||
printf("%s: invalid option \"-%c\"!\n",
|
||||
PACKAGE_NAME, argv[i][n]);
|
||||
printf("Try \"%s --help\" for more information.\n",
|
||||
PACKAGE_NAME);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if( ! ok )
|
||||
{
|
||||
printf( "%s: invalid option \"%s\"!\n", PACKAGE_NAME, argv[i] );
|
||||
printf( "Try \"%s --help\" for more information.\n", PACKAGE_NAME );
|
||||
exit( 1 );
|
||||
if (!ok) {
|
||||
printf("%s: invalid option \"%s\"!\n",
|
||||
PACKAGE_NAME, argv[i]);
|
||||
printf("Try \"%s --help\" for more information.\n",
|
||||
PACKAGE_NAME);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Debug level for "VERSION" command */
|
||||
NGIRCd_DebugLevel[0] = '\0';
|
||||
#ifdef DEBUG
|
||||
if( NGIRCd_Debug ) strcpy( NGIRCd_DebugLevel, "1" );
|
||||
if (NGIRCd_Debug)
|
||||
strcpy(NGIRCd_DebugLevel, "1");
|
||||
#endif
|
||||
#ifdef SNIFFER
|
||||
if( NGIRCd_Sniffer )
|
||||
{
|
||||
if (NGIRCd_Sniffer) {
|
||||
NGIRCd_Debug = true;
|
||||
strcpy( NGIRCd_DebugLevel, "2" );
|
||||
strcpy(NGIRCd_DebugLevel, "2");
|
||||
}
|
||||
#endif
|
||||
|
||||
if( configtest )
|
||||
{
|
||||
Show_Version( ); puts( "" );
|
||||
exit( Conf_Test( ));
|
||||
if (configtest) {
|
||||
Show_Version(); puts("");
|
||||
exit(Conf_Test());
|
||||
}
|
||||
|
||||
while( ! NGIRCd_SignalQuit )
|
||||
{
|
||||
|
||||
while (!NGIRCd_SignalQuit) {
|
||||
/* Initialize global variables */
|
||||
NGIRCd_Start = time( NULL );
|
||||
(void)strftime( NGIRCd_StartStr, 64, "%a %b %d %Y at %H:%M:%S (%Z)", localtime( &NGIRCd_Start ));
|
||||
NGIRCd_Start = time(NULL);
|
||||
(void)strftime(NGIRCd_StartStr, 64,
|
||||
"%a %b %d %Y at %H:%M:%S (%Z)",
|
||||
localtime(&NGIRCd_Start));
|
||||
|
||||
NGIRCd_SignalRestart = false;
|
||||
NGIRCd_SignalQuit = false;
|
||||
|
||||
Random_Init();
|
||||
|
||||
/* Initialize modules, part I */
|
||||
Log_Init( ! NGIRCd_NoDaemon );
|
||||
Conf_Init( );
|
||||
Log_Init(!NGIRCd_NoDaemon);
|
||||
Random_Init();
|
||||
Conf_Init();
|
||||
Log_ReInit();
|
||||
|
||||
/* Initialize the "main program": chroot environment, user and
|
||||
* group ID, ... */
|
||||
@@ -279,17 +270,22 @@ main( int argc, const char *argv[] )
|
||||
|
||||
/* Initialize modules, part II: these functions are eventually
|
||||
* called with already dropped privileges ... */
|
||||
Channel_Init( );
|
||||
Client_Init( );
|
||||
Conn_Init( );
|
||||
Channel_Init();
|
||||
Client_Init();
|
||||
Conn_Init();
|
||||
Class_Init();
|
||||
|
||||
if (!io_library_init(CONNECTION_POOL)) {
|
||||
Log(LOG_ALERT, "Fatal: Cannot initialize IO routines: %s", strerror(errno));
|
||||
Log(LOG_ALERT,
|
||||
"Fatal: Could not initialize IO routines: %s",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!Signals_Init()) {
|
||||
Log(LOG_ALERT, "Fatal: Could not set up signal handlers: %s", strerror(errno));
|
||||
Log(LOG_ALERT,
|
||||
"Fatal: Could not set up signal handlers: %s",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -297,39 +293,45 @@ main( int argc, const char *argv[] )
|
||||
* used by ngIRCd in PASS commands and the known "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 );
|
||||
snprintf(NGIRCd_ProtoID, sizeof NGIRCd_ProtoID, "%s%s %s|%s:%s",
|
||||
PROTOVER, PROTOIRCPLUS, PACKAGE_NAME, PACKAGE_VERSION,
|
||||
IRCPLUSFLAGS);
|
||||
#ifdef ZLIB
|
||||
strcat( NGIRCd_ProtoID, "Z" );
|
||||
strcat(NGIRCd_ProtoID, "Z");
|
||||
#endif
|
||||
if( Conf_OperCanMode ) strcat( NGIRCd_ProtoID, "o" );
|
||||
#else
|
||||
snprintf( NGIRCd_ProtoID, sizeof NGIRCd_ProtoID, "%s%s %s|%s", PROTOVER, PROTOIRC, PACKAGE_NAME, PACKAGE_VERSION );
|
||||
#endif
|
||||
strlcat( NGIRCd_ProtoID, " P", sizeof NGIRCd_ProtoID );
|
||||
if (Conf_OperCanMode)
|
||||
strcat(NGIRCd_ProtoID, "o");
|
||||
#else /* IRCPLUS */
|
||||
snprintf(NGIRCd_ProtoID, sizeof NGIRCd_ProtoID, "%s%s %s|%s",
|
||||
PROTOVER, PROTOIRC, PACKAGE_NAME, PACKAGE_VERSION);
|
||||
#endif /* IRCPLUS */
|
||||
strlcat(NGIRCd_ProtoID, " P", sizeof NGIRCd_ProtoID);
|
||||
#ifdef ZLIB
|
||||
strlcat( NGIRCd_ProtoID, "Z", sizeof NGIRCd_ProtoID );
|
||||
strlcat(NGIRCd_ProtoID, "Z", sizeof NGIRCd_ProtoID);
|
||||
#endif
|
||||
LogDebug("Protocol and server ID is \"%s\".", NGIRCd_ProtoID);
|
||||
|
||||
Channel_InitPredefined( );
|
||||
Channel_InitPredefined();
|
||||
|
||||
if( Conn_InitListeners( ) < 1 )
|
||||
{
|
||||
Log( LOG_ALERT, "Server isn't listening on a single port!" );
|
||||
Log( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME );
|
||||
Pidfile_Delete( );
|
||||
exit( 1 );
|
||||
if (Conn_InitListeners() < 1) {
|
||||
Log(LOG_ALERT,
|
||||
"Server isn't listening on a single port!" );
|
||||
Log(LOG_ALERT,
|
||||
"%s exiting due to fatal errors!", PACKAGE_NAME);
|
||||
Pidfile_Delete();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Main Run Loop */
|
||||
Conn_Handler( );
|
||||
Conn_Handler();
|
||||
|
||||
Conn_Exit( );
|
||||
Client_Exit( );
|
||||
Channel_Exit( );
|
||||
Log_Exit( );
|
||||
Conn_Exit();
|
||||
Client_Exit();
|
||||
Channel_Exit();
|
||||
Class_Exit();
|
||||
Log_Exit();
|
||||
}
|
||||
Pidfile_Delete( );
|
||||
Pidfile_Delete();
|
||||
|
||||
return 0;
|
||||
} /* main */
|
||||
@@ -421,7 +423,7 @@ static void
|
||||
Show_Version( void )
|
||||
{
|
||||
puts( NGIRCd_Version );
|
||||
puts( "Copyright (c)2001-2011 Alexander Barton (<alex@barton.de>) and Contributors." );
|
||||
puts( "Copyright (c)2001-2012 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." );
|
||||
@@ -553,9 +555,10 @@ NGIRCd_getNobodyID(uid_t *uid, gid_t *gid )
|
||||
#endif
|
||||
|
||||
pwd = getpwnam("nobody");
|
||||
if (!pwd) return false;
|
||||
if (!pwd)
|
||||
return false;
|
||||
|
||||
if ( !pwd->pw_uid || !pwd->pw_gid)
|
||||
if (!pwd->pw_uid || !pwd->pw_gid)
|
||||
return false;
|
||||
|
||||
*uid = pwd->pw_uid;
|
||||
@@ -593,19 +596,19 @@ Random_Init(void)
|
||||
return;
|
||||
if (Random_Init_Kern("/dev/arandom"))
|
||||
return;
|
||||
srand(rand() ^ getpid() ^ time(NULL));
|
||||
srand(rand() ^ (unsigned)getpid() ^ (unsigned)time(NULL));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize ngIRCd daemon.
|
||||
*
|
||||
* @param NGIRCd_NoDaemon Set to true if ngIRCd should run in the
|
||||
* foreground and not as a daemon.
|
||||
* @return true on success.
|
||||
* @param NGIRCd_NoDaemon Set to true if ngIRCd should run in the
|
||||
* foreground (and not as a daemon).
|
||||
* @return true on success.
|
||||
*/
|
||||
static bool
|
||||
NGIRCd_Init( bool NGIRCd_NoDaemon )
|
||||
NGIRCd_Init(bool NGIRCd_NoDaemon)
|
||||
{
|
||||
static bool initialized;
|
||||
bool chrooted = false;
|
||||
@@ -621,57 +624,74 @@ NGIRCd_Init( bool 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));
|
||||
Log(LOG_WARNING, "Could not open /dev/null: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
/* SSL initialization */
|
||||
if (!ConnSSL_InitLibrary())
|
||||
Log(LOG_WARNING,
|
||||
"Warning: Error during SSL initialization, continuing ...");
|
||||
|
||||
if( Conf_Chroot[0] ) {
|
||||
if( chdir( Conf_Chroot ) != 0 ) {
|
||||
Log( LOG_ERR, "Can't chdir() in ChrootDir (%s): %s", Conf_Chroot, strerror( errno ));
|
||||
/* Change root */
|
||||
if (Conf_Chroot[0]) {
|
||||
if (chdir(Conf_Chroot) != 0) {
|
||||
Log(LOG_ERR, "Can't chdir() in ChrootDir (%s): %s",
|
||||
Conf_Chroot, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if( chroot( Conf_Chroot ) != 0 ) {
|
||||
if (chroot(Conf_Chroot) != 0) {
|
||||
if (errno != EPERM) {
|
||||
Log( LOG_ERR, "Can't change root directory to \"%s\": %s",
|
||||
Conf_Chroot, strerror( errno ));
|
||||
Log(LOG_ERR,
|
||||
"Can't change root directory to \"%s\": %s",
|
||||
Conf_Chroot, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
chrooted = true;
|
||||
Log( LOG_INFO, "Changed root and working directory to \"%s\".", Conf_Chroot );
|
||||
Log(LOG_INFO,
|
||||
"Changed root and working directory to \"%s\".",
|
||||
Conf_Chroot);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check user ID */
|
||||
if (Conf_UID == 0) {
|
||||
Log(LOG_INFO, "ServerUID must not be 0, using \"nobody\" instead.", Conf_UID);
|
||||
|
||||
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" );
|
||||
pwd = getpwuid(0);
|
||||
Log(LOG_INFO,
|
||||
"ServerUID must not be %s(0), using \"nobody\" instead.",
|
||||
pwd ? pwd->pw_name : "?");
|
||||
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" );
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Change group ID */
|
||||
if (getgid() != Conf_GID) {
|
||||
/* Change group ID */
|
||||
if (setgid(Conf_GID) != 0) {
|
||||
real_errno = errno;
|
||||
Log( LOG_ERR, "Can't change group ID to %u: %s", Conf_GID, strerror( errno ));
|
||||
grp = getgrgid(Conf_GID);
|
||||
Log(LOG_ERR, "Can't change group ID to %s(%u): %s",
|
||||
grp ? grp->gr_name : "?", Conf_GID,
|
||||
strerror(errno));
|
||||
if (real_errno != EPERM)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Change user ID */
|
||||
if (getuid() != Conf_UID) {
|
||||
/* Change user ID */
|
||||
if (setuid(Conf_UID) != 0) {
|
||||
real_errno = errno;
|
||||
Log(LOG_ERR, "Can't change user ID to %u: %s", Conf_UID, strerror(errno));
|
||||
if (real_errno != EPERM)
|
||||
pwd = getpwuid(Conf_UID);
|
||||
Log(LOG_ERR, "Can't change user ID to %s(%u): %s",
|
||||
pwd ? pwd->pw_name : "?", Conf_UID,
|
||||
strerror(errno));
|
||||
if (real_errno != EPERM)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -681,26 +701,27 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
|
||||
/* Normally a child process is forked which isn't any longer
|
||||
* connected to ther controlling terminal. Use "--nodaemon"
|
||||
* to disable this "daemon mode" (useful for debugging). */
|
||||
if ( ! NGIRCd_NoDaemon ) {
|
||||
pid = fork( );
|
||||
if( pid > 0 ) {
|
||||
if (!NGIRCd_NoDaemon) {
|
||||
pid = fork();
|
||||
if (pid > 0) {
|
||||
/* "Old" process: exit. */
|
||||
exit( 0 );
|
||||
exit(0);
|
||||
}
|
||||
if( pid < 0 ) {
|
||||
if (pid < 0) {
|
||||
/* Error!? */
|
||||
fprintf( stderr, "%s: Can't fork: %s!\nFatal error, exiting now ...\n",
|
||||
PACKAGE_NAME, strerror( errno ));
|
||||
exit( 1 );
|
||||
fprintf(stderr,
|
||||
"%s: Can't fork: %s!\nFatal error, exiting now ...\n",
|
||||
PACKAGE_NAME, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* New child process */
|
||||
#ifndef NeXT
|
||||
(void)setsid( );
|
||||
(void)setsid();
|
||||
#else
|
||||
setpgrp(0, getpid());
|
||||
#endif
|
||||
if (chdir( "/" ) != 0)
|
||||
if (chdir("/") != 0)
|
||||
Log(LOG_ERR, "Can't change directory to '/': %s",
|
||||
strerror(errno));
|
||||
|
||||
@@ -711,19 +732,19 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
|
||||
}
|
||||
pid = getpid();
|
||||
|
||||
Pidfile_Create( pid );
|
||||
Pidfile_Create(pid);
|
||||
|
||||
/* Check UID/GID we are running as, can be different from values
|
||||
* configured (e. g. if we were already started with a UID>0. */
|
||||
Conf_UID = getuid();
|
||||
Conf_GID = getgid();
|
||||
|
||||
pwd = getpwuid( Conf_UID );
|
||||
grp = getgrgid( Conf_GID );
|
||||
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", (long)Conf_UID,
|
||||
grp ? grp->gr_name : "unknown", (long)Conf_GID, (long)pid);
|
||||
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\".",
|
||||
@@ -732,20 +753,23 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
|
||||
} else
|
||||
Log(LOG_INFO, "Not running with changed root directory.");
|
||||
|
||||
/* Change working directory to home directory of the user
|
||||
* we are running as (only when running in daemon mode and not in chroot) */
|
||||
/* Change working directory to home directory of the user we are
|
||||
* running as (only when running in daemon mode and not in chroot) */
|
||||
|
||||
if (NGIRCd_NoDaemon)
|
||||
return true;
|
||||
|
||||
if (pwd) {
|
||||
if (!NGIRCd_NoDaemon ) {
|
||||
if( chdir( pwd->pw_dir ) == 0 )
|
||||
Log( LOG_DEBUG, "Changed working directory to \"%s\" ...", pwd->pw_dir );
|
||||
else
|
||||
Log( LOG_INFO, "Notice: Can't change working directory to \"%s\": %s",
|
||||
pwd->pw_dir, strerror( errno ));
|
||||
}
|
||||
} else {
|
||||
Log( LOG_ERR, "Can't get user informaton for UID %d!?", Conf_UID );
|
||||
}
|
||||
if (chdir(pwd->pw_dir) == 0)
|
||||
Log(LOG_DEBUG,
|
||||
"Changed working directory to \"%s\" ...",
|
||||
pwd->pw_dir);
|
||||
else
|
||||
Log(LOG_INFO,
|
||||
"Notice: Can't change working directory to \"%s\": %s",
|
||||
pwd->pw_dir, strerror(errno));
|
||||
} else
|
||||
Log(LOG_ERR, "Can't get user informaton for UID %d!?", Conf_UID);
|
||||
|
||||
return true;
|
||||
out:
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "conn.h"
|
||||
#include "conn-func.h"
|
||||
#include "channel.h"
|
||||
#include "class.h"
|
||||
#include "irc-write.h"
|
||||
#include "lists.h"
|
||||
#include "log.h"
|
||||
@@ -194,8 +195,10 @@ Announce_User(CLIENT * Client, CLIENT * User)
|
||||
#ifdef IRCPLUS
|
||||
|
||||
/**
|
||||
* Synchronize invite and ban lists between servers
|
||||
* @param Client New server
|
||||
* Synchronize invite, ban, G- and K-Line lists between servers.
|
||||
*
|
||||
* @param Client New server.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
static bool
|
||||
Synchronize_Lists(CLIENT * Client)
|
||||
@@ -206,6 +209,18 @@ Synchronize_Lists(CLIENT * Client)
|
||||
|
||||
assert(Client != NULL);
|
||||
|
||||
/* g-lines */
|
||||
head = Class_GetList(CLASS_GLINE);
|
||||
elem = Lists_GetFirst(head);
|
||||
while (elem) {
|
||||
if (!IRC_WriteStrClient(Client, "GLINE %s %ld :%s",
|
||||
Lists_GetMask(elem),
|
||||
Lists_GetValidity(elem) - time(NULL),
|
||||
Lists_GetReason(elem)))
|
||||
return DISCONNECTED;
|
||||
elem = Lists_GetNext(elem);
|
||||
}
|
||||
|
||||
c = Channel_First();
|
||||
while (c) {
|
||||
/* ban list */
|
||||
@@ -369,6 +384,10 @@ IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!IRC_WriteStrClient(Client, "PING :%s",
|
||||
Client_ID(Client_ThisServer())))
|
||||
return DISCONNECTED;
|
||||
|
||||
return CONNECTED;
|
||||
} /* IRC_Num_ENDOFMOTD */
|
||||
|
||||
|
@@ -58,9 +58,15 @@ Op_NoPrivileges(CLIENT * Client, REQUEST * Req)
|
||||
|
||||
|
||||
/**
|
||||
* Check that the client is an IRC operator allowed to administer this server.
|
||||
* Check that the originator of a request is an IRC operator and allowed
|
||||
* to administer this server.
|
||||
*
|
||||
* @param CLient Client from which the command has been received.
|
||||
* @param Req Request structure.
|
||||
* @return CLIENT structure of the client that initiated the command or
|
||||
* NULL if client is not allowed to execute operator commands.
|
||||
*/
|
||||
GLOBAL bool
|
||||
GLOBAL CLIENT *
|
||||
Op_Check(CLIENT * Client, REQUEST * Req)
|
||||
{
|
||||
CLIENT *c;
|
||||
@@ -72,15 +78,20 @@ Op_Check(CLIENT * Client, REQUEST * Req)
|
||||
c = Client_Search(Req->prefix);
|
||||
else
|
||||
c = Client;
|
||||
|
||||
if (!c)
|
||||
return false;
|
||||
return NULL;
|
||||
if (Client_Type(Client) == CLIENT_SERVER
|
||||
&& Client_Type(c) == CLIENT_SERVER)
|
||||
return c;
|
||||
if (!Client_HasMode(c, 'o'))
|
||||
return false;
|
||||
return NULL;
|
||||
if (!Client_OperByMe(c) && !Conf_AllowRemoteOper)
|
||||
return false;
|
||||
return NULL;
|
||||
|
||||
/* The client is an local IRC operator, or this server is configured
|
||||
* to trust remote operators. */
|
||||
return true;
|
||||
return c;
|
||||
} /* Op_Check */
|
||||
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2009 Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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,7 @@
|
||||
*/
|
||||
|
||||
GLOBAL bool Op_NoPrivileges PARAMS((CLIENT * Client, REQUEST * Req));
|
||||
GLOBAL bool Op_Check PARAMS((CLIENT * Client, REQUEST * Req));
|
||||
GLOBAL CLIENT *Op_Check PARAMS((CLIENT * Client, REQUEST * Req));
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -103,7 +103,7 @@ PAM_Authenticate(CLIENT *Client) {
|
||||
if (password)
|
||||
free(password);
|
||||
password = strdup(Client_Password(Client));
|
||||
conv.appdata_ptr = password;
|
||||
conv.appdata_ptr = Client_Password(Client);
|
||||
|
||||
/* Initialize PAM */
|
||||
retval = pam_start("ngircd", Client_OrigUser(Client), &conv, &pam);
|
||||
|
@@ -63,6 +63,7 @@ static COMMAND My_Commands[] =
|
||||
{ "DIE", IRC_DIE, CLIENT_USER, 0, 0, 0 },
|
||||
{ "DISCONNECT", IRC_DISCONNECT, CLIENT_USER, 0, 0, 0 },
|
||||
{ "ERROR", IRC_ERROR, 0xFFFF, 0, 0, 0 },
|
||||
{ "GLINE", IRC_xLINE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
|
||||
{ "HELP", IRC_HELP, CLIENT_USER, 0, 0, 0 },
|
||||
{ "INFO", IRC_INFO, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
|
||||
{ "INVITE", IRC_INVITE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
|
||||
@@ -70,6 +71,7 @@ static COMMAND My_Commands[] =
|
||||
{ "JOIN", IRC_JOIN, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
|
||||
{ "KICK", IRC_KICK, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
|
||||
{ "KILL", IRC_KILL, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
|
||||
{ "KLINE", IRC_xLINE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
|
||||
{ "LINKS", IRC_LINKS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
|
||||
{ "LIST", IRC_LIST, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
|
||||
{ "LUSERS", IRC_LUSERS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
|
||||
@@ -325,13 +327,21 @@ Validate_Prefix( CONN_ID Idx, REQUEST *Req, bool *Closed )
|
||||
/* check if the client named in the prefix is expected
|
||||
* to come from that direction */
|
||||
if (Client_NextHop(c) != client) {
|
||||
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;
|
||||
if (Client_Type(c) != CLIENT_SERVER) {
|
||||
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;
|
||||
} else {
|
||||
Log(LOG_INFO,
|
||||
"Ignoring spoofed prefix \"%s\" from \"%s\" (connection %d, command \"%s\").",
|
||||
Req->prefix, Client_Mask(Conn_GetClient(Idx)), Idx,
|
||||
Req->command);
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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
|
||||
@@ -79,7 +79,6 @@ Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout
|
||||
signal(SIGALRM, Proc_GenericSignalHandler);
|
||||
close(pipefds[0]);
|
||||
alarm(timeout);
|
||||
Conn_CloseAllSockets();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -138,14 +137,28 @@ Proc_Read(PROC_STAT *proc, void *buffer, size_t buflen)
|
||||
return 0;
|
||||
Log(LOG_CRIT, "Can't read from child process %ld: %s",
|
||||
proc->pid, strerror(errno));
|
||||
Proc_Close(proc);
|
||||
bytes_read = 0;
|
||||
} else if (bytes_read == 0) {
|
||||
/* EOF: clean up */
|
||||
LogDebug("Child process %ld: EOF reached, closing pipe.",
|
||||
proc->pid);
|
||||
Proc_Close(proc);
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close pipe to a forked child process.
|
||||
*/
|
||||
GLOBAL void
|
||||
Proc_Close(PROC_STAT *proc)
|
||||
{
|
||||
/* Close socket, if it exists */
|
||||
if (proc->pipe_fd >= 0)
|
||||
io_close(proc->pipe_fd);
|
||||
|
||||
Proc_InitStruct(proc);
|
||||
}
|
||||
|
||||
/* -eof- */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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
|
||||
@@ -38,6 +38,9 @@ GLOBAL void Proc_GenericSignalHandler PARAMS((int Signal));
|
||||
|
||||
GLOBAL size_t Proc_Read PARAMS((PROC_STAT *proc, void *buffer, size_t buflen));
|
||||
|
||||
GLOBAL void Proc_Close PARAMS((PROC_STAT *proc));
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* -eof- */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2009 by Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* 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
|
||||
@@ -75,7 +75,8 @@ Resolve_Addr(PROC_STAT * s, const ng_ipaddr_t *Addr, int identsock,
|
||||
} else if( pid == 0 ) {
|
||||
/* Sub process */
|
||||
Log_Init_Subprocess("Resolver");
|
||||
Do_ResolveAddr( Addr, identsock, pipefd[1]);
|
||||
Conn_CloseAllSockets(identsock);
|
||||
Do_ResolveAddr(Addr, identsock, pipefd[1]);
|
||||
Log_Exit_Subprocess("Resolver");
|
||||
exit(0);
|
||||
}
|
||||
@@ -104,6 +105,7 @@ Resolve_Name( PROC_STAT *s, const char *Host, void (*cbfunc)(int, short))
|
||||
} else if( pid == 0 ) {
|
||||
/* Sub process */
|
||||
Log_Init_Subprocess("Resolver");
|
||||
Conn_CloseAllSockets(NONE);
|
||||
Do_ResolveName(Host, pipefd[1]);
|
||||
Log_Exit_Subprocess("Resolver");
|
||||
exit(0);
|
||||
|
@@ -164,6 +164,10 @@ extern char * strtok_r PARAMS((char *str, const char *delim, char **saveptr));
|
||||
extern int vsnprintf PARAMS(( char *str, size_t count, const char *fmt, va_list args ));
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GAI_STRERROR
|
||||
#define gai_strerror(r) "unknown error"
|
||||
#endif
|
||||
|
||||
#ifndef PACKAGE_NAME
|
||||
#define PACKAGE_NAME PACKAGE
|
||||
#endif
|
||||
|
@@ -16,7 +16,7 @@ elif [ $UNAME = "GNU" ]; then
|
||||
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_FLAGS="-af"; PS_PIDCOL="2"; HEAD_FLAGS="-n 1"
|
||||
ps $PS_FLAGS > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then PS_FLAGS="a"; PS_PIDCOL="1"; fi
|
||||
fi
|
||||
|
@@ -35,7 +35,7 @@ expect {
|
||||
"@* PRIVMSG nick :test\r*@* PRIVMSG nick :test"
|
||||
}
|
||||
|
||||
send "privmsg nick,#testChannel,nick :test\r"
|
||||
send "privmsg Nick,#testChannel,nick :test\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"@* PRIVMSG nick :test\r*401*@* PRIVMSG nick :test"
|
||||
@@ -47,7 +47,7 @@ expect {
|
||||
"401"
|
||||
}
|
||||
|
||||
send "privmsg ~user@ngircd.test.server :test\r"
|
||||
send "privmsg ~UsEr@ngIRCd.Test.Server :test\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"@* PRIVMSG nick :test"
|
||||
@@ -65,7 +65,7 @@ expect {
|
||||
# "@* PRIVMSG nick :test"
|
||||
#}
|
||||
#
|
||||
#send "privmsg nick!~user@localhost :test\r"
|
||||
#send "privmsg Nick!~User@LocalHost :test\r"
|
||||
#expect {
|
||||
# timeout { exit 1 }
|
||||
# "@* PRIVMSG nick :test"
|
||||
|
@@ -4,6 +4,7 @@
|
||||
[Global]
|
||||
Name = ngircd.test.server
|
||||
Info = ngIRCd Test-Server 1
|
||||
Listen = 127.0.0.1
|
||||
Ports = 6789
|
||||
MotdFile = ngircd-test1.motd
|
||||
AdminEMail = admin@irc.server
|
||||
|
@@ -4,6 +4,7 @@
|
||||
[Global]
|
||||
Name = ngircd.test.server2
|
||||
Info = ngIRCd Test-Server 2
|
||||
Listen = 127.0.0.1
|
||||
Ports = 6790
|
||||
MotdFile = ngircd-test2.motd
|
||||
AdminEMail = admin@irc.server2
|
||||
@@ -23,7 +24,7 @@
|
||||
|
||||
[Server]
|
||||
Name = ngircd.test.server
|
||||
Host = localhost
|
||||
Host = 127.0.0.1
|
||||
Port = 6789
|
||||
MyPassword = pwd2
|
||||
PeerPassword = pwd1
|
||||
|
@@ -14,19 +14,13 @@ expect {
|
||||
send "who\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick \* * ngircd.test.server nick H :0 Real Name"
|
||||
}
|
||||
|
||||
send "join #channel\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"@* JOIN :#channel"
|
||||
":ngircd.test.server 352 nick \* * * ngircd.test.server nick H :0 Real Name"
|
||||
}
|
||||
|
||||
send "who 0\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick #channel * ngircd.test.server nick H@ :0 Real Name"
|
||||
":ngircd.test.server 352 nick \* * * ngircd.test.server nick H :0 Real Name"
|
||||
}
|
||||
|
||||
send "away :testing\r"
|
||||
@@ -38,7 +32,19 @@ expect {
|
||||
send "who *\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick #channel * ngircd.test.server nick G@ :0 Real Name"
|
||||
":ngircd.test.server 352 nick \* * * ngircd.test.server nick G :0 Real Name"
|
||||
}
|
||||
|
||||
send "join #channel\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"@* JOIN :#channel"
|
||||
}
|
||||
|
||||
send "who #channel\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick #channel * * ngircd.test.server nick G@ :0 Real Name"
|
||||
}
|
||||
|
||||
send "mode #channel +v nick\r"
|
||||
@@ -47,10 +53,16 @@ expect {
|
||||
"@* MODE #channel +v nick\r"
|
||||
}
|
||||
|
||||
send "who #channel\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick #channel * * ngircd.test.server nick G@ :0 Real Name"
|
||||
}
|
||||
|
||||
send "who localhos*\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick #channel * ngircd.test.server nick G@ :0 Real Name"
|
||||
":ngircd.test.server 352 nick \* * * ngircd.test.server nick G :0 Real Name"
|
||||
}
|
||||
|
||||
send "mode #channel -o nick\r"
|
||||
@@ -59,10 +71,16 @@ expect {
|
||||
"@* MODE #channel -o nick\r"
|
||||
}
|
||||
|
||||
send "who #channel\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick #channel * * ngircd.test.server nick G+ :0 Real Name"
|
||||
}
|
||||
|
||||
send "who ngircd.test.server\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick #channel * ngircd.test.server nick G+ :0 Real Name"
|
||||
":ngircd.test.server 352 nick \* * * ngircd.test.server nick G :0 Real Name"
|
||||
}
|
||||
|
||||
send "part #channel\r"
|
||||
@@ -74,7 +92,7 @@ expect {
|
||||
send "who Real?Name\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick \* * ngircd.test.server nick G :0 Real Name"
|
||||
":ngircd.test.server 352 nick \* * * ngircd.test.server nick G :0 Real Name"
|
||||
}
|
||||
|
||||
send "oper TestOp 123\r"
|
||||
@@ -90,7 +108,7 @@ expect {
|
||||
send "who 0 o\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick \* * ngircd.test.server nick G* :0 Real Name"
|
||||
":ngircd.test.server 352 nick \* * * ngircd.test.server nick G* :0 Real Name"
|
||||
}
|
||||
|
||||
send "away\r"
|
||||
@@ -102,7 +120,7 @@ expect {
|
||||
send "who ??cal*ho*\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick \* * ngircd.test.server nick H* :0 Real Name"
|
||||
":ngircd.test.server 352 nick \* * * ngircd.test.server nick H* :0 Real Name"
|
||||
}
|
||||
|
||||
send "join #opers\r"
|
||||
@@ -114,7 +132,13 @@ expect {
|
||||
send "who #opers\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick #opers * ngircd.test.server nick H*@ :0 Real Name"
|
||||
":ngircd.test.server 352 nick #opers * * ngircd.test.server nick H*@ :0 Real Name"
|
||||
}
|
||||
|
||||
send "who Re*me\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick \* * * ngircd.test.server nick H* :0 Real Name"
|
||||
}
|
||||
|
||||
send "mode #opers -o nick\r"
|
||||
@@ -123,10 +147,16 @@ expect {
|
||||
"@* MODE #opers -o nick\r"
|
||||
}
|
||||
|
||||
send "who #opers\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick #opers * * ngircd.test.server nick H* :0 Real Name"
|
||||
}
|
||||
|
||||
send "who *.server\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick #opers * ngircd.test.server nick H* :0 Real Name"
|
||||
":ngircd.test.server 352 nick \* * * ngircd.test.server nick H* :0 Real Name"
|
||||
}
|
||||
|
||||
send "mode #opers +v nick\r"
|
||||
@@ -135,10 +165,10 @@ expect {
|
||||
"@* MODE #opers +v nick\r"
|
||||
}
|
||||
|
||||
send "who Real*me\r"
|
||||
send "who #opers\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":ngircd.test.server 352 nick #opers * ngircd.test.server nick H*+ :0 Real Name"
|
||||
":ngircd.test.server 352 nick #opers * * ngircd.test.server nick H*+ :0 Real Name"
|
||||
}
|
||||
|
||||
send "mode #opers +s\r"
|
||||
|
@@ -17,31 +17,31 @@ expect {
|
||||
send "whois nick\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"311 nick nick ~user localhost \* :Real Name\r"
|
||||
"311 nick nick ~user localhost* \* :Real Name\r"
|
||||
}
|
||||
|
||||
send "whois *\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"311 nick nick ~user localhost \* :Real Name\r"
|
||||
"311 nick nick ~user localhost* \* :Real Name\r"
|
||||
}
|
||||
|
||||
send "whois n*\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"311 nick nick ~user localhost \* :Real Name\r"
|
||||
"311 nick nick ~user localhost* \* :Real Name\r"
|
||||
}
|
||||
|
||||
send "whois ?ick\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"311 nick nick ~user localhost \* :Real Name\r"
|
||||
"311 nick nick ~user localhost* \* :Real Name\r"
|
||||
}
|
||||
|
||||
send "whois ????,n?*k\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"311 nick nick ~user localhost \* :Real Name\r"
|
||||
"311 nick nick ~user localhost* \* :Real Name\r"
|
||||
}
|
||||
|
||||
send "quit\r"
|
||||
|
Reference in New Issue
Block a user