is the Erlang/OTP system log, with the messages reported by Erlang/OTP using SASL (System Architecture Support Libraries)
@@ -3575,12 +3506,12 @@ The ejabberdctl command reopen-log
(please refer to section 4.1.1)
reopens the log files,
and also renames the old ones if you didn’t rename them.
-
The Debug Console is an Erlang shell attached to an already running ejabberd server.
+
The Debug Console is an Erlang shell attached to an already running ejabberd server.
With this Erlang shell, an experienced administrator can perform complex tasks.
This shell gives complete control over the ejabberd server,
so it is important to use it with extremely care.
There are some simple and safe examples in the article
Interconnecting Erlang Nodes
To exit the shell, close the window or press the keys: control+c control+c.
-
+
ejabberd includes a watchdog mechanism that may be useful to developers
when troubleshooting a problem related to memory usage.
If a process in the ejabberd server consumes more memory than the configured threshold,
@@ -3598,7 +3529,7 @@ or in a conversation with the watchdog alert bot.
Example configuration:
To remove all watchdog admins, set the option with an empty list:
{watchdog_admins, []}.
-
+
The source code of ejabberd supports localization.
The translators can edit the
gettext .po files
@@ -3633,9 +3564,9 @@ HTTP header ‘Accept-Language: ru’
-
+
Release notes are available from ejabberd Home Page
-
Thanks to all people who contributed to this guide:
+
Thanks to all people who contributed to this guide:
-
Ejabberd Installation and Operation Guide.
+
Ejabberd Installation and Operation Guide.
Copyright © 2003 — 2009 ProcessOne
This document 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
diff --git a/doc/guide.tex b/doc/guide.tex
index a0bb82eb1..3901db633 100644
--- a/doc/guide.tex
+++ b/doc/guide.tex
@@ -68,7 +68,6 @@
\newcommand{\modconfigure}{\module{mod\_configure}}
\newcommand{\moddisco}{\module{mod\_disco}}
\newcommand{\modecho}{\module{mod\_echo}}
-\newcommand{\modirc}{\module{mod\_irc}}
\newcommand{\modlast}{\module{mod\_last}}
\newcommand{\modlastodbc}{\module{mod\_last\_odbc}}
\newcommand{\modmuc}{\module{mod\_muc}}
@@ -304,7 +303,6 @@ To compile \ejabberd{} on a `Unix-like' operating system, you need:
\item Erlang mysql library. Optional. For MySQL authentication or storage. See section \ref{compilemysql}.
\item Erlang pgsql library. Optional. For PostgreSQL authentication or storage. See section \ref{compilepgsql}.
\item PAM library. Optional. For Pluggable Authentication Modules (PAM). See section \ref{pam}.
-\item GNU Iconv 1.8 or higher, for the IRC Transport (mod\_irc). Optional. Not needed on systems with GNU Libc. See section \ref{modirc}.
\item ImageMagick's Convert program. Optional. For CAPTCHA challenges. See section \ref{captcha}.
\end{itemize}
@@ -486,9 +484,6 @@ To compile \ejabberd{} on a Microsoft Windows system, you need:
\item MS Visual C++ 6.0 Compiler
\item \footahref{http://www.erlang.org/download.html}{Erlang/OTP R11B-5}
\item \footahref{http://sourceforge.net/project/showfiles.php?group\_id=10127\&package\_id=11277}{Expat 2.0.0 or higher}
-\item
-\footahref{http://www.gnu.org/software/libiconv/}{GNU Iconv 1.9.2}
-(optional)
\item \footahref{http://www.slproweb.com/products/Win32OpenSSL.html}{Shining Light OpenSSL 0.9.8d or higher}
(to enable SSL connections)
\item \footahref{http://www.zlib.net/}{Zlib 1.2.3 or higher}
@@ -507,21 +502,12 @@ We assume that we will try to put as much library as possible into \verb|C:\sdk\
Copy file \verb|C:\sdk\Expat-2.0.0\Libs\libexpat.dll|
to your Windows system directory (for example, \verb|C:\WINNT| or
\verb|C:\WINNT\System32|)
-\item Build and install the Iconv library into the directory
- \verb|C:\sdk\GnuWin32|.
-
- Copy file \verb|C:\sdk\GnuWin32\bin\lib*.dll| to your
- Windows system directory (more installation instructions can be found in the
- file README.woe32 in the iconv distribution).
-
- Note: instead of copying libexpat.dll and iconv.dll to the Windows
- directory, you can add the directories
- \verb|C:\sdk\Expat-2.0.0\Libs| and
- \verb|C:\sdk\GnuWin32\bin| to the \verb|PATH| environment
- variable.
+ Note: instead of copying libexpat.dll to the Windows
+ directory, you can add the directory \verb|C:\sdk\Expat-2.0.0\Libs|
+ to the \verb|PATH| environment variable.
\item Install OpenSSL in \verb|C:\sdk\OpenSSL| and add \verb|C:\sdk\OpenSSL\lib\VC| to your path or copy the binaries to your system directory.
\item Install ZLib in \verb|C:\sdk\gnuWin32|. Copy
- \verb|C:\sdk\GnuWin32\bin\zlib1.dll| to your system directory. If you change your path it should already be set after libiconv install.
+ \verb|C:\sdk\GnuWin32\bin\zlib1.dll| to your system directory.
\item Make sure the you can access Erlang binaries from your path. For example: \verb|set PATH=%PATH%;"C:\sdk\erl5.6.5\bin"|
\item Depending on how you end up actually installing the library you might need to check and tweak the paths in the file configure.erl.
\item While in the directory \verb|ejabberd\src| run:
@@ -2367,7 +2353,6 @@ The following table lists all modules included in \ejabberd{}.
\hline \modconfigure{} & Server configuration using Ad-Hoc & \modadhoc{} \\
\hline \ahrefloc{moddisco}{\moddisco{}} & Service Discovery (\xepref{0030}) & \\
\hline \ahrefloc{modecho}{\modecho{}} & Echoes Jabber packets & \\
- \hline \ahrefloc{modirc}{\modirc{}} & IRC transport & \\
\hline \ahrefloc{modlast}{\modlast{}} & Last Activity (\xepref{0012}) & \\
\hline \ahrefloc{modlast}{\modlastodbc{}} & Last Activity (\xepref{0012}) & supported DB (*) \\
\hline \ahrefloc{modmuc}{\modmuc{}} & Multi-User Chat (\xepref{0045}) & \\
@@ -2667,72 +2652,6 @@ Example: Mirror, mirror, on the wall, who is the most beautiful
\ifthenelse{\boolean{modhttpfileserver}}{\input{mod_http_fileserver.tex}}{}
-\makesubsection{modirc}{\modirc{}}
-\ind{modules!\modirc{}}\ind{IRC}
-
-This module is an IRC transport that can be used to join channels on IRC
-servers.
-
-End user information:
-\ind{protocols!groupchat 1.0}\ind{protocols!XEP-0045: Multi-User Chat}
-\begin{itemize}
-\item A \Jabber{} client with `groupchat 1.0' support or Multi-User
- Chat support (\xepref{0045}) is necessary to join IRC channels.
-\item An IRC channel can be joined in nearly the same way as joining a
- \Jabber{} Multi-User Chat room. The difference is that the room name will
- be `channel\%\jid{irc.example.org}' in case \jid{irc.example.org} is
- the IRC server hosting `channel'. And of course the host should point
- to the IRC transport instead of the Multi-User Chat service.
-\item You can register your nickame by sending `IDENTIFY password' to \\
- \jid{nickserver!irc.example.org@irc.jabberserver.org}.
-\item Entering your password is possible by sending `LOGIN nick password' \\
- to \jid{nickserver!irc.example.org@irc.jabberserver.org}.
-\item When using a popular \Jabber{} server, it can occur that no
- connection can be achieved with some IRC servers because they limit the
- number of conections from one IP.
-\end{itemize}
-
-Options:
-\begin{description}
-\hostitem{irc}
-\titem{access} \ind{options!access}This option can be used to specify who
- may use the IRC transport (default value: \term{all}).
-\titem{default\_encoding} \ind{options!defaultencoding}Set the default IRC encoding (default value: \term{"koi8-r"}).
-\end{description}
-
-Examples:
-\begin{itemize}
-\item In the first example, the IRC transport is available on (all) your
- virtual host(s) with the prefix `\jid{irc.}'. Furthermore, anyone is
- able to use the transport. The default encoding is set to "iso8859-15".
-\begin{verbatim}
-{modules,
- [
- ...
- {mod_irc, [{access, all}, {default_encoding, "iso8859-15"}]},
- ...
- ]}.
-\end{verbatim}
-\item In next example the IRC transport is available with JIDs with prefix \jid{irc-t.net}.
- Moreover, the transport is only accessible to two users
- of \term{example.org}, and any user of \term{example.com}:
-\begin{verbatim}
-{acl, paying_customers, {user, "customer1", "example.org"}}.
-{acl, paying_customers, {user, "customer2", "example.org"}}.
-{acl, paying_customers, {server, "example.com"}}.
-
-{access, irc_users, [{allow, paying_customers}, {deny, all}]}.
-
-{modules,
- [
- ...
- {mod_irc, [{access, irc_users},
- {host, "irc.example.net"}]},
- ...
- ]}.
-\end{verbatim}
-\end{itemize}
-
\makesubsection{modlast}{\modlast{}}
\ind{modules!\modlast{}}\ind{protocols!XEP-0012: Last Activity}
@@ -4612,7 +4531,7 @@ mnesia:change_table_copy_type(schema, node(), disc_copies).
\item Now run \ejabberd{} on \term{second} with a configuration similar as
on \term{first}: you probably do not need to duplicate `\verb|acl|'
and `\verb|access|' options because they will be taken from
- \term{first}; and \verb|mod_irc| should be
+ \term{first}. If you installed \verb|mod_irc|, notice that it should be
enabled only on one machine in the cluster.
\end{enumerate}
diff --git a/doc/introduction.tex b/doc/introduction.tex
index 1991c93ec..6cedbd161 100644
--- a/doc/introduction.tex
+++ b/doc/introduction.tex
@@ -127,7 +127,6 @@ Moreover, \ejabberd{} comes with a wide range of other state-of-the-art features
\item Users Directory based on users vCards.
\item \txepref{0060}{Publish-Subscribe} component with support for \txepref{0163}{Personal Eventing via Pubsub}.
\item Support for web clients: \txepref{0025}{HTTP Polling} and \txepref{0206}{HTTP Binding (BOSH)} services.
-\item IRC transport.
\item Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
\end{itemize}
\end{itemize}
diff --git a/examples/mtr/ejabberd-netbsd.sh b/examples/mtr/ejabberd-netbsd.sh
index 9896c9bc4..31d01b6b8 100644
--- a/examples/mtr/ejabberd-netbsd.sh
+++ b/examples/mtr/ejabberd-netbsd.sh
@@ -70,7 +70,7 @@ done
echo '7. compile ejabberd'
gmake
-for A in mod_irc mod_muc mod_pubsub; do
+for A in mod_muc mod_pubsub; do
(cd $A; gmake)
done
diff --git a/src/Makefile.in b/src/Makefile.in
index 8ba622d54..24b12e301 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -63,7 +63,7 @@ endif
prefix = @prefix@
exec_prefix = @exec_prefix@
-SUBDIRS = @mod_irc@ @mod_pubsub@ @mod_muc@ @mod_proxy65@ @eldap@ @pam@ @web@ stringprep @tls@ @odbc@ @ejabberd_zlib@
+SUBDIRS = @mod_pubsub@ @mod_muc@ @mod_proxy65@ @eldap@ @pam@ @web@ stringprep @tls@ @odbc@ @ejabberd_zlib@
ERLSHLIBS = expat_erl.so
ERLBEHAVS = cyrsasl.erl gen_mod.erl p1_fsm.erl
SOURCES_ALL = $(wildcard *.erl)
diff --git a/src/Makefile.win32 b/src/Makefile.win32
index 9d21e896a..b866f11ff 100644
--- a/src/Makefile.win32
+++ b/src/Makefile.win32
@@ -52,9 +52,6 @@ release : build release_clean
mkdir $(SRC_DIR)\eldap
copy eldap\eldap.* $(SRC_DIR)\eldap
copy eldap\ELDAPv3.asn $(SRC_DIR)\eldap
- mkdir $(SRC_DIR)\mod_irc
- copy mod_irc\*.erl $(SRC_DIR)\mod_irc
- copy mod_irc\*.c $(SRC_DIR)\mod_irc
mkdir $(SRC_DIR)\mod_muc
copy mod_muc\*.erl $(SRC_DIR)\mod_muc
mkdir $(SRC_DIR)\mod_pubsub
@@ -91,8 +88,6 @@ build : $(DLL) compile-beam all-recursive
all-recursive :
cd eldap
nmake -nologo -f Makefile.win32
- cd ..\mod_irc
- nmake -nologo -f Makefile.win32
cd ..\mod_muc
nmake -nologo -f Makefile.win32
cd ..\mod_pubsub
@@ -132,8 +127,6 @@ clean-local :
clean-recursive :
cd eldap
nmake -nologo -f Makefile.win32 clean
- cd ..\mod_irc
- nmake -nologo -f Makefile.win32 clean
cd ..\mod_muc
nmake -nologo -f Makefile.win32 clean
cd ..\mod_pubsub
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 5365443f0..c1f354bb9 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -226,96 +226,6 @@ AC_SUBST(make_$1)
])
-
-dnl From Bruno Haible.
-
-AC_DEFUN([AM_ICONV],
-[
- dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
- dnl those with the standalone portable GNU libiconv installed).
- AC_ARG_WITH([libiconv-prefix],
- [AC_HELP_STRING([--with-libiconv-prefix=PREFIX], [prefix where libiconv is installed])], [
- for dir in `echo "$withval" | tr : ' '`; do
- if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi
- if test -d $dir/include; then CFLAGS="$CFLAGS -I$dir/include"; fi
- if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi
- done
- ])
-
- AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [
- am_cv_func_iconv="no, consider installing GNU libiconv"
- am_cv_lib_iconv=no
- AC_TRY_LINK([#include
-#include ],
- [iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);],
- am_cv_func_iconv=yes)
- if test "$am_cv_func_iconv" != yes; then
- am_save_LIBS="$LIBS"
- LIBS="$LIBS -liconv"
- AC_TRY_LINK([#include
-#include ],
- [iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);],
- am_cv_lib_iconv=yes
- am_cv_func_iconv=yes)
- LIBS="$am_save_LIBS"
- fi
- dnl trying /usr/local
- if test "$am_cv_func_iconv" != yes; then
- am_save_LIBS="$LIBS"
- am_save_CFLAGS="$CFLAGS"
- am_save_LDFLAGS="$LDFLAGS"
- LIBS="$LIBS -liconv"
- LDFLAGS="$LDFLAGS -L/usr/local/lib"
- CFLAGS="$CFLAGS -I/usr/local/include"
- AC_TRY_LINK([#include
-#include ],
- [iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);],
- am_cv_lib_iconv=yes
- am_cv_func_iconv=yes
- CPPFLAGS="$CPPFLAGS -I/usr/local/include",
- LDFLAGS="$am_save_LDFLAGS"
- CFLAGS="$am_save_CFLAGS")
- LIBS="$am_save_LIBS"
- fi
-
- ])
- if test "$am_cv_func_iconv" = yes; then
- AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.])
- AC_MSG_CHECKING([for iconv declaration])
- AC_CACHE_VAL(am_cv_proto_iconv, [
- AC_TRY_COMPILE([
-#include
-#include
-extern
-#ifdef __cplusplus
-"C"
-#endif
-#if defined(__STDC__) || defined(__cplusplus)
-size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
-#else
-size_t iconv();
-#endif
-], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const")
- am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
- am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
- AC_MSG_RESULT([$]{ac_t:-
- }[$]am_cv_proto_iconv)
- AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1,
- [Define as const if the declaration of iconv() needs const.])
- fi
- LIBICONV=
- if test "$am_cv_lib_iconv" = yes; then
- LIBICONV="-liconv"
- fi
- AC_SUBST(LIBICONV)
-])
-
dnl
AC_DEFUN(AM_WITH_OPENSSL,
[ AC_ARG_WITH(openssl,
diff --git a/src/configure b/src/configure
index ec6bd6d91..468877f3b 100755
--- a/src/configure
+++ b/src/configure
@@ -666,15 +666,12 @@ ERLANG_CFLAGS
ERLANG_LIBS
ERLANG_SSL39
ERLANG_EXMPP
-LIBICONV
CPP
GREP
EGREP
EXPAT_CFLAGS
EXPAT_LIBS
LIBOBJS
-mod_irc
-make_mod_irc
mod_muc
make_mod_muc
mod_proxy65
@@ -1286,7 +1283,6 @@ if test -n "$ac_init_help"; then
Optional Features:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --enable-mod_irc enable mod_irc (default: yes)
--enable-mod_muc enable mod_muc (default: yes)
--enable-mod_proxy65 enable mod_proxy65 (default: yes)
--enable-mod_pubsub enable mod_pubsub (default: yes)
@@ -1315,8 +1311,6 @@ Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-erlang=PREFIX path to erlc and erl
- --with-libiconv-prefix=PREFIX
- prefix where libiconv is installed
--with-expat=PREFIX prefix where EXPAT is installed
--with-zlib=PREFIX prefix where zlib is installed
--with-pam=PREFIX prefix where PAM is installed
@@ -3040,277 +3034,8 @@ echo "$as_me: error: erlang program was not properly executed, (conftest.out was
-#locating iconv
-
-
-
-# Check whether --with-libiconv-prefix was given.
-if test "${with_libiconv_prefix+set}" = set; then
- withval=$with_libiconv_prefix;
- for dir in `echo "$withval" | tr : ' '`; do
- if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi
- if test -d $dir/include; then CFLAGS="$CFLAGS -I$dir/include"; fi
- if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi
- done
-
-fi
-
-
- { echo "$as_me:$LINENO: checking for iconv" >&5
-echo $ECHO_N "checking for iconv... $ECHO_C" >&6; }
-if test "${am_cv_func_iconv+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- am_cv_func_iconv="no, consider installing GNU libiconv"
- am_cv_lib_iconv=no
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include
-#include
-int
-main ()
-{
-iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- am_cv_func_iconv=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- if test "$am_cv_func_iconv" != yes; then
- am_save_LIBS="$LIBS"
- LIBS="$LIBS -liconv"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include
-#include
-int
-main ()
-{
-iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- am_cv_lib_iconv=yes
- am_cv_func_iconv=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- LIBS="$am_save_LIBS"
- fi
- if test "$am_cv_func_iconv" != yes; then
- am_save_LIBS="$LIBS"
- am_save_CFLAGS="$CFLAGS"
- am_save_LDFLAGS="$LDFLAGS"
- LIBS="$LIBS -liconv"
- LDFLAGS="$LDFLAGS -L/usr/local/lib"
- CFLAGS="$CFLAGS -I/usr/local/include"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include
-#include
-int
-main ()
-{
-iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- am_cv_lib_iconv=yes
- am_cv_func_iconv=yes
- CPPFLAGS="$CPPFLAGS -I/usr/local/include"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- LDFLAGS="$am_save_LDFLAGS"
- CFLAGS="$am_save_CFLAGS"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- LIBS="$am_save_LIBS"
- fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $am_cv_func_iconv" >&5
-echo "${ECHO_T}$am_cv_func_iconv" >&6; }
- if test "$am_cv_func_iconv" = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_ICONV 1
-_ACEOF
-
- { echo "$as_me:$LINENO: checking for iconv declaration" >&5
-echo $ECHO_N "checking for iconv declaration... $ECHO_C" >&6; }
- if test "${am_cv_proto_iconv+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-#include
-#include
-extern
-#ifdef __cplusplus
-"C"
-#endif
-#if defined(__STDC__) || defined(__cplusplus)
-size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
-#else
-size_t iconv();
-#endif
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- am_cv_proto_iconv_arg1=""
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- am_cv_proto_iconv_arg1="const"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"
-fi
-
- am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
- { echo "$as_me:$LINENO: result: ${ac_t:-
- }$am_cv_proto_iconv" >&5
-echo "${ECHO_T}${ac_t:-
- }$am_cv_proto_iconv" >&6; }
-
-cat >>confdefs.h <<_ACEOF
-#define ICONV_CONST $am_cv_proto_iconv_arg1
-_ACEOF
-
- fi
- LIBICONV=
- if test "$am_cv_lib_iconv" = yes; then
- LIBICONV="-liconv"
- fi
-
-
#locating libexpat
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -4723,28 +4448,6 @@ fi
-mod_irc=
-make_mod_irc=
-{ echo "$as_me:$LINENO: checking whether build mod_irc" >&5
-echo $ECHO_N "checking whether build mod_irc... $ECHO_C" >&6; }
-# Check whether --enable-mod_irc was given.
-if test "${enable_mod_irc+set}" = set; then
- enableval=$enable_mod_irc; mr_enable_mod_irc="$enableval"
-else
- mr_enable_mod_irc=yes
-fi
-
-if test "$mr_enable_mod_irc" = "yes"; then
-mod_irc=mod_irc
-make_mod_irc=mod_irc/Makefile
-fi
-{ echo "$as_me:$LINENO: result: $mr_enable_mod_irc" >&5
-echo "${ECHO_T}$mr_enable_mod_irc" >&6; }
-
-
-
-
-
mod_muc=
make_mod_muc=
{ echo "$as_me:$LINENO: checking whether build mod_muc" >&5
@@ -5523,7 +5226,7 @@ fi
-ac_config_files="$ac_config_files Makefile $make_mod_irc $make_mod_muc $make_mod_pubsub $make_mod_proxy65 $make_eldap $make_pam $make_web stringprep/Makefile $make_tls $make_odbc $make_ejabberd_zlib"
+ac_config_files="$ac_config_files Makefile $make_mod_muc $make_mod_pubsub $make_mod_proxy65 $make_eldap $make_pam $make_web stringprep/Makefile $make_tls $make_odbc $make_ejabberd_zlib"
#openssl
@@ -6510,7 +6213,6 @@ for ac_config_target in $ac_config_targets
do
case $ac_config_target in
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
- "$make_mod_irc") CONFIG_FILES="$CONFIG_FILES $make_mod_irc" ;;
"$make_mod_muc") CONFIG_FILES="$CONFIG_FILES $make_mod_muc" ;;
"$make_mod_pubsub") CONFIG_FILES="$CONFIG_FILES $make_mod_pubsub" ;;
"$make_mod_proxy65") CONFIG_FILES="$CONFIG_FILES $make_mod_proxy65" ;;
@@ -6632,15 +6334,12 @@ ERLANG_CFLAGS!$ERLANG_CFLAGS$ac_delim
ERLANG_LIBS!$ERLANG_LIBS$ac_delim
ERLANG_SSL39!$ERLANG_SSL39$ac_delim
ERLANG_EXMPP!$ERLANG_EXMPP$ac_delim
-LIBICONV!$LIBICONV$ac_delim
CPP!$CPP$ac_delim
GREP!$GREP$ac_delim
EGREP!$EGREP$ac_delim
EXPAT_CFLAGS!$EXPAT_CFLAGS$ac_delim
EXPAT_LIBS!$EXPAT_LIBS$ac_delim
LIBOBJS!$LIBOBJS$ac_delim
-mod_irc!$mod_irc$ac_delim
-make_mod_irc!$make_mod_irc$ac_delim
mod_muc!$mod_muc$ac_delim
make_mod_muc!$make_mod_muc$ac_delim
mod_proxy65!$mod_proxy65$ac_delim
@@ -6674,7 +6373,7 @@ INSTALLUSER!$INSTALLUSER$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 91; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 88; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/src/configure.ac b/src/configure.ac
index c325c3f54..dc2359e47 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -14,8 +14,6 @@ fi
#locating erlang
AM_WITH_ERLANG
-#locating iconv
-AM_ICONV
#locating libexpat
AM_WITH_EXPAT
@@ -32,7 +30,6 @@ AC_PREFIX_DEFAULT(/)
AC_FUNC_MALLOC
AC_HEADER_STDC
-AC_MOD_ENABLE(mod_irc, yes)
AC_MOD_ENABLE(mod_muc, yes)
AC_MOD_ENABLE(mod_proxy65, yes)
AC_MOD_ENABLE(mod_pubsub, yes)
@@ -95,7 +92,6 @@ esac],[full_xml=false])
AC_SUBST(full_xml)
AC_CONFIG_FILES([Makefile
- $make_mod_irc
$make_mod_muc
$make_mod_pubsub
$make_mod_proxy65
diff --git a/src/configure.erl b/src/configure.erl
index cd7e48710..bd5e3e995 100644
--- a/src/configure.erl
+++ b/src/configure.erl
@@ -44,15 +44,11 @@ start() ->
true ->
ExpatLib = "EXPAT_LIB = $(EXPAT_DIR)\\StaticLibs\\libexpatMT.lib\n",
ExpatFlag = "EXPAT_FLAG = -DXML_STATIC\n",
- IconvDir = "ICONV_DIR = c:\\sdk\\GnuWin32\n",
- IconvLib = "ICONV_LIB = $(ICONV_DIR)\\lib\\libiconv.lib\n",
ZlibDir = "ZLIB_DIR = c:\\sdk\\GnuWin32\n",
ZlibLib = "ZLIB_LIB = $(ZLIB_DIR)\\lib\\zlib.lib\n";
false ->
ExpatLib = "EXPAT_LIB = $(EXPAT_DIR)\\Libs\\libexpat.lib\n",
ExpatFlag = "",
- IconvDir = "ICONV_DIR = c:\\sdk\\GnuWin32\n",
- IconvLib = "ICONV_LIB = $(ICONV_DIR)\\lib\\libiconv.lib\n",
ZlibDir = "ZLIB_DIR = c:\\sdk\\GnuWin32\n",
ZlibLib = "ZLIB_LIB = $(ZLIB_DIR)\\lib\\zlib.lib\n"
end,
@@ -82,8 +78,6 @@ start() ->
ExpatDir ++
ExpatLib ++
ExpatFlag ++
- IconvDir ++
- IconvLib ++
ZlibDir ++
ZlibLib)),
halt().
diff --git a/src/ejabberd.app b/src/ejabberd.app
index 7f0948f04..c80650df3 100644
--- a/src/ejabberd.app
+++ b/src/ejabberd.app
@@ -61,7 +61,6 @@
gen_mod,
gen_pubsub_node,
gen_pubsub_nodetree,
- iconv,
idna,
jd2ejd,
jlib,
@@ -74,8 +73,6 @@
mod_echo,
mod_http_bind,
mod_http_fileserver,
- mod_irc,
- mod_irc_connection,
mod_last,
mod_last_odbc,
mod_muc,
@@ -142,7 +139,6 @@
ejabberd_mod_roster,
ejabberd_mod_echo,
ejabberd_mod_pubsub,
- ejabberd_mod_irc,
ejabberd_mod_muc,
ejabberd_offline,
random_generator
diff --git a/src/ejabberd.cfg.example b/src/ejabberd.cfg.example
index cb07c89e1..4b16b89b5 100644
--- a/src/ejabberd.cfg.example
+++ b/src/ejabberd.cfg.example
@@ -474,7 +474,6 @@
{mod_configure,[]}, % requires mod_adhoc
{mod_disco, []},
%%{mod_echo, [{host, "echo.localhost"}]},
- {mod_irc, []},
{mod_last, []},
{mod_muc, [
%%{host, "conference.@HOST@"},
diff --git a/src/mod_irc/Makefile.in b/src/mod_irc/Makefile.in
deleted file mode 100644
index 9dcf9f182..000000000
--- a/src/mod_irc/Makefile.in
+++ /dev/null
@@ -1,60 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@ @LIBICONV@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-# Assume Linux-style dynamic library flags
-DYNAMIC_LIB_CFLAGS = -fpic -shared
-ifeq ($(shell uname),Darwin)
- DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
-endif
-ifeq ($(shell uname),SunOs)
- DYNAMIC_LIB_CFLAGS = -KPIC -G -z text
-endif
-
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
- EFLAGS+=+debug_info
-endif
-
-ERLSHLIBS = ../iconv_erl.so
-OUTDIR = ..
-SOURCES = $(wildcard *.erl)
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-all: $(BEAMS) $(ERLSHLIBS)
-
-$(OUTDIR)/%.beam: %.erl
- @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-#all: $(ERLSHLIBS)
-# erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt
-
-$(ERLSHLIBS): ../%.so: %.c
- $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) \
- $(subst ../,,$(subst .so,.c,$@)) \
- $(LIBS) \
- $(ERLANG_CFLAGS) \
- $(ERLANG_LIBS) \
- -o $@ \
- $(DYNAMIC_LIB_CFLAGS)
-
-clean:
- rm -f $(BEAMS) $(ERLSHLIBS)
-
-distclean: clean
- rm -f Makefile
-
-TAGS:
- etags *.erl
-
diff --git a/src/mod_irc/Makefile.win32 b/src/mod_irc/Makefile.win32
deleted file mode 100644
index 9c22f43f1..000000000
--- a/src/mod_irc/Makefile.win32
+++ /dev/null
@@ -1,42 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS = ..\iconv.beam ..\mod_irc.beam ..\mod_irc_connection.beam
-
-SOURCE = iconv_erl.c
-OBJECT = iconv_erl.o
-DLL = $(OUTDIR)\iconv_erl.dll
-
-ALL : $(DLL) $(BEAMS)
-
-CLEAN :
- -@erase $(DLL)
- -@erase $(OUTDIR)\iconv_erl.exp
- -@erase $(OUTDIR)\iconv_erl.lib
- -@erase $(OBJECT)
- -@erase $(BEAMS)
-
-$(OUTDIR)\iconv.beam : iconv.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) iconv.erl
-
-$(OUTDIR)\mod_irc.beam : mod_irc.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) mod_irc.erl
-
-$(OUTDIR)\mod_irc_connection.beam : mod_irc_connection.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) mod_irc_connection.erl
-
-CC=cl.exe
-CC_FLAGS=-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT -MD -Ox -I"$(ERLANG_DIR)\usr\include" -I"$(EI_DIR)\include" -I"$(ICONV_DIR)\include"
-
-LD=link.exe
-LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.lib" "$(ICONV_LIB)" MSVCRT.LIB kernel32.lib advapi32.lib gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib
-
-$(DLL) : $(OBJECT)
- $(LD) $(LD_FLAGS) -out:$(DLL) $(OBJECT)
-
-$(OBJECT) : $(SOURCE)
- $(CC) $(CC_FLAGS) -c -Fo$(OBJECT) $(SOURCE)
-
diff --git a/src/mod_irc/iconv.erl b/src/mod_irc/iconv.erl
deleted file mode 100644
index 8cccf2df8..000000000
--- a/src/mod_irc/iconv.erl
+++ /dev/null
@@ -1,94 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : iconv.erl
-%%% Author : Alexey Shchepin
-%%% Purpose : Interface to libiconv
-%%% Created : 16 Feb 2003 by Alexey Shchepin
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
-%%%
-%%% 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.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(iconv).
--author('alexey@process-one.net').
-
--behaviour(gen_server).
-
--export([start/0, start_link/0, convert/3]).
-
-%% Internal exports, call-back functions.
--export([init/1,
- handle_call/3,
- handle_cast/2,
- handle_info/2,
- code_change/3,
- terminate/2]).
-
-
-
-start() ->
- gen_server:start({local, ?MODULE}, ?MODULE, [], []).
-
-start_link() ->
- gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-
-init([]) ->
- case erl_ddll:load_driver(ejabberd:get_so_path(), iconv_erl) of
- ok -> ok;
- {error, already_loaded} -> ok
- end,
- Port = open_port({spawn, iconv_erl}, []),
- ets:new(iconv_table, [set, public, named_table]),
- ets:insert(iconv_table, {port, Port}),
- {ok, Port}.
-
-
-%%% --------------------------------------------------------
-%%% The call-back functions.
-%%% --------------------------------------------------------
-
-handle_call(_, _, State) ->
- {noreply, State}.
-
-handle_cast(_, State) ->
- {noreply, State}.
-
-handle_info({'EXIT', Port, Reason}, Port) ->
- {stop, {port_died, Reason}, Port};
-handle_info({'EXIT', _Pid, _Reason}, Port) ->
- {noreply, Port};
-handle_info(_, State) ->
- {noreply, State}.
-
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-
-terminate(_Reason, Port) ->
- Port ! {self, close},
- ok.
-
-
-
-convert(From, To, String) ->
- [{port, Port} | _] = ets:lookup(iconv_table, port),
- Bin = term_to_binary({From, To, String}),
- BRes = port_control(Port, 1, Bin),
- binary_to_list(BRes).
-
-
-
diff --git a/src/mod_irc/iconv_erl.c b/src/mod_irc/iconv_erl.c
deleted file mode 100644
index e845635b3..000000000
--- a/src/mod_irc/iconv_erl.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * ejabberd, Copyright (C) 2002-2009 ProcessOne
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-
-typedef struct {
- ErlDrvPort port;
- iconv_t cd;
-} iconv_data;
-
-
-static ErlDrvData iconv_erl_start(ErlDrvPort port, char *buff)
-{
- iconv_data* d = (iconv_data*)driver_alloc(sizeof(iconv_data));
- d->port = port;
- d->cd = NULL;
-
- set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
-
- return (ErlDrvData)d;
-}
-
-static void iconv_erl_stop(ErlDrvData handle)
-{
- driver_free((char*)handle);
-}
-
-static int iconv_erl_control(ErlDrvData drv_data,
- unsigned int command,
- char *buf, int len,
- char **rbuf, int rlen)
-{
- int i;
- int size;
- int index = 0;
- int avail;
- size_t inleft, outleft;
- ErlDrvBinary *b;
- char *from, *to, *string, *stmp, *rstring, *rtmp;
- iconv_t cd;
-
- ei_decode_version(buf, &index, &i);
- ei_decode_tuple_header(buf, &index, &i);
- ei_get_type(buf, &index, &i, &size);
- from = malloc(size + 1);
- ei_decode_string(buf, &index, from);
-
- ei_get_type(buf, &index, &i, &size);
- to = malloc(size + 1);
- ei_decode_string(buf, &index, to);
-
- ei_get_type(buf, &index, &i, &size);
- stmp = string = malloc(size + 1);
- ei_decode_string(buf, &index, string);
-
- cd = iconv_open(to, from);
-
- if (cd == (iconv_t) -1) {
- cd = iconv_open("ascii", "ascii");
- if (cd == (iconv_t) -1) {
- *rbuf = (char*)(b = driver_alloc_binary(size));
- memcpy(b->orig_bytes, string, size);
-
- free(from);
- free(to);
- free(string);
-
- return size;
- }
- }
-
- outleft = avail = 4*size;
- inleft = size;
- rtmp = rstring = malloc(avail);
- while (inleft > 0) {
- if (iconv(cd, &stmp, &inleft, &rtmp, &outleft) == (size_t) -1) {
- stmp++;
- inleft--;
- }
- }
-
- size = rtmp - rstring;
-
- *rbuf = (char*)(b = driver_alloc_binary(size));
- memcpy(b->orig_bytes, rstring, size);
-
- free(from);
- free(to);
- free(string);
- free(rstring);
- iconv_close(cd);
-
- return size;
-}
-
-
-
-ErlDrvEntry iconv_driver_entry = {
- NULL, /* F_PTR init, N/A */
- iconv_erl_start, /* L_PTR start, called when port is opened */
- iconv_erl_stop, /* F_PTR stop, called when port is closed */
- NULL, /* F_PTR output, called when erlang has sent */
- NULL, /* F_PTR ready_input, called when input descriptor ready */
- NULL, /* F_PTR ready_output, called when output descriptor ready */
- "iconv_erl", /* char *driver_name, the argument to open_port */
- NULL, /* F_PTR finish, called when unloaded */
- NULL, /* handle */
- iconv_erl_control, /* F_PTR control, port_command callback */
- NULL, /* F_PTR timeout, reserved */
- NULL /* F_PTR outputv, reserved */
-};
-
-DRIVER_INIT(iconv_erl) /* must match name in driver_entry */
-{
- return &iconv_driver_entry;
-}
-
-
diff --git a/src/mod_irc/mod_irc.erl b/src/mod_irc/mod_irc.erl
deleted file mode 100644
index a12853d33..000000000
--- a/src/mod_irc/mod_irc.erl
+++ /dev/null
@@ -1,593 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_irc.erl
-%%% Author : Alexey Shchepin
-%%% Purpose : IRC transport
-%%% Created : 15 Feb 2003 by Alexey Shchepin
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
-%%%
-%%% 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.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(mod_irc).
--author('alexey@process-one.net').
-
--behaviour(gen_server).
--behaviour(gen_mod).
-
-%% API
--export([start_link/2,
- start/2,
- stop/1,
- closed_connection/3]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--include_lib("exmpp/include/exmpp.hrl").
-
--include("ejabberd.hrl").
-
--record(irc_connection, {jid_server_host, pid}).
--record(irc_custom, {us_host, data}).
-
--record(state, {host, server_host, default_encoding, access}).
-
--define(PROCNAME, ejabberd_mod_irc).
-
-%%====================================================================
-%% API
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the server
-%%--------------------------------------------------------------------
-start_link(Host, Opts) ->
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
-
-start(Host, Opts) ->
- start_supervisor(Host),
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- ChildSpec =
- {Proc,
- {?MODULE, start_link, [Host, Opts]},
- temporary,
- 1000,
- worker,
- [?MODULE]},
- supervisor:start_child(ejabberd_sup, ChildSpec).
-
-stop(Host) ->
- stop_supervisor(Host),
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- gen_server:call(Proc, stop),
- supervisor:delete_child(ejabberd_sup, Proc).
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% Description: Initiates the server
-%%--------------------------------------------------------------------
-init([Host, Opts]) ->
- iconv:start(),
- mnesia:create_table(irc_custom,
- [{disc_copies, [node()]},
- {attributes, record_info(fields, irc_custom)}]),
- MyHost = gen_mod:get_opt_host(Host, Opts, "irc.@HOST@"),
- update_table(MyHost),
- Access = gen_mod:get_opt(access, Opts, all),
- DefaultEncoding = gen_mod:get_opt(default_encoding, Opts, "koi8-r"),
- catch ets:new(irc_connection, [named_table,
- public,
- {keypos, #irc_connection.jid_server_host}]),
- ejabberd_router:register_route(MyHost),
- {ok, #state{host = MyHost,
- server_host = Host,
- default_encoding = DefaultEncoding,
- access = Access}}.
-
-%%--------------------------------------------------------------------
-%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
-%% {reply, Reply, State, Timeout} |
-%% {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, Reply, State} |
-%% {stop, Reason, State}
-%% Description: Handling call messages
-%%--------------------------------------------------------------------
-handle_call(stop, _From, State) ->
- {stop, normal, ok, State}.
-
-%%--------------------------------------------------------------------
-%% Function: handle_cast(Msg, State) -> {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State}
-%% Description: Handling cast messages
-%%--------------------------------------------------------------------
-handle_cast(_Msg, State) ->
- {noreply, State}.
-
-%%--------------------------------------------------------------------
-%% Function: handle_info(Info, State) -> {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State}
-%% Description: Handling all non call/cast messages
-%%--------------------------------------------------------------------
-handle_info({route, From, To, Packet},
- #state{host = Host,
- server_host = ServerHost,
- default_encoding = DefEnc,
- access = Access} = State) ->
- case catch do_route(Host, ServerHost, Access, From, To, Packet, DefEnc) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]);
- _ ->
- ok
- end,
- {noreply, State};
-handle_info(_Info, State) ->
- {noreply, State}.
-
-%%--------------------------------------------------------------------
-%% Function: terminate(Reason, State) -> void()
-%% Description: This function is called by a gen_server when it is about to
-%% terminate. It should be the opposite of Module:init/1 and do any necessary
-%% cleaning up. When it returns, the gen_server terminates with Reason.
-%% The return value is ignored.
-%%--------------------------------------------------------------------
-terminate(_Reason, State) ->
- ejabberd_router:unregister_route(State#state.host),
- ok.
-
-%%--------------------------------------------------------------------
-%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
-%% Description: Convert process state when code is changed
-%%--------------------------------------------------------------------
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-
-%%--------------------------------------------------------------------
-%%% Internal functions
-%%--------------------------------------------------------------------
-start_supervisor(Host) ->
- Proc = gen_mod:get_module_proc(Host, ejabberd_mod_irc_sup),
- ChildSpec =
- {Proc,
- {ejabberd_tmp_sup, start_link,
- [Proc, mod_irc_connection]},
- permanent,
- infinity,
- supervisor,
- [ejabberd_tmp_sup]},
- supervisor:start_child(ejabberd_sup, ChildSpec).
-
-stop_supervisor(Host) ->
- Proc = gen_mod:get_module_proc(Host, ejabberd_mod_irc_sup),
- supervisor:terminate_child(ejabberd_sup, Proc),
- supervisor:delete_child(ejabberd_sup, Proc).
-
-do_route(Host, ServerHost, Access, From, To, Packet, DefEnc) ->
- case acl:match_rule(ServerHost, Access, From) of
- allow ->
- do_route1(Host, ServerHost, From, To, Packet, DefEnc);
- _ ->
- Lang = exmpp_stanza:get_lang(Packet),
- ErrText = translate:translate(Lang,
- "Access denied by service policy"),
- Err = exmpp_stanza:reply_with_error(Packet,
- exmpp_stanza:error(Packet#xmlel.ns,
- 'forbidden', {Lang, ErrText})),
- ejabberd_router:route(To, From, Err)
- end.
-
-do_route1(Host, ServerHost, From, To, Packet, DefEnc) ->
- ChanServ = exmpp_jid:node_as_list(To),
- Resource = exmpp_jid:resource_as_list(To),
- case ChanServ of
- undefined ->
- case Resource of
- undefined ->
- case exmpp_iq:xmlel_to_iq(Packet) of
- #iq{type = get, ns = ?NS_DISCO_INFO = XMLNS,
- lang = Lang} = IQ_Rec ->
- Result = #xmlel{ns = XMLNS, name = 'query',
- children = iq_disco(Lang)},
- Res = exmpp_iq:result(IQ_Rec, Result),
- ejabberd_router:route(To,
- From,
- exmpp_iq:iq_to_xmlel(Res));
- #iq{type = get, ns = ?NS_DISCO_ITEMS = XMLNS} = IQ_Rec ->
- Result = #xmlel{ns = XMLNS, name = 'query'},
- Res = exmpp_iq:result(IQ_Rec, Result),
- ejabberd_router:route(To,
- From,
- exmpp_iq:iq_to_xmlel(Res));
- #iq{kind = request, ns = ?NS_INBAND_REGISTER} = IQ_Rec ->
- process_register(Host, From, To, DefEnc, IQ_Rec);
- #iq{type = get, ns = ?NS_VCARD = XMLNS,
- lang = Lang} = IQ_Rec ->
- Result = #xmlel{ns = XMLNS, name = 'vCard',
- children = iq_get_vcard(Lang)},
- Res = exmpp_iq:result(IQ_Rec, Result),
- ejabberd_router:route(To,
- From,
- exmpp_iq:iq_to_xmlel(Res));
- #iq{} = _IQ_Rec ->
- Err = exmpp_iq:error(
- Packet, 'feature-not-implemented'),
- ejabberd_router:route(To, From, Err);
- _ ->
- ok
- end;
- _ ->
- Err = exmpp_stanza:reply_with_error(Packet, 'bad-request'),
- ejabberd_router:route(To, From, Err)
- end;
- _ ->
- case string:tokens(ChanServ, "%") of
- [[_ | _] = Channel, [_ | _] = Server] ->
- case ets:lookup(irc_connection, {From, Server, Host}) of
- [] ->
- ?DEBUG("open new connection~n", []),
- {Username, Encoding} = get_user_and_encoding(
- Host, From, Server, DefEnc),
- {ok, Pid} = mod_irc_connection:start(
- From, Host, ServerHost, Server,
- Username, Encoding),
- ets:insert(
- irc_connection,
- #irc_connection{jid_server_host = {From, Server, Host},
- pid = Pid}),
- mod_irc_connection:route_chan(
- Pid, Channel, Resource, Packet),
- ok;
- [R] ->
- Pid = R#irc_connection.pid,
- ?DEBUG("send to process ~p~n",
- [Pid]),
- mod_irc_connection:route_chan(
- Pid, Channel, Resource, Packet),
- ok
- end;
- _ ->
- case string:tokens(ChanServ, "!") of
- [[_ | _] = Nick, [_ | _] = Server] ->
- case ets:lookup(irc_connection, {From, Server, Host}) of
- [] ->
- Err = exmpp_stanza:reply_with_error(
- Packet, 'service-unavailable'),
- ejabberd_router:route(To, From, Err);
- [R] ->
- Pid = R#irc_connection.pid,
- ?DEBUG("send to process ~p~n",
- [Pid]),
- mod_irc_connection:route_nick(
- Pid, Nick, Packet),
- ok
- end;
- _ ->
- Err = exmpp_stanza:reply_with_error(
- Packet, 'bad-request'),
- ejabberd_router:route(To, From, Err)
- end
- end
- end.
-
-
-closed_connection(Host, From, Server) ->
- ets:delete(irc_connection, {From, Server, Host}).
-
-
-iq_disco(Lang) ->
- [#xmlel{ns = ?NS_DISCO_INFO, name = 'identity', attrs =
- [?XMLATTR('category', <<"conference">>),
- ?XMLATTR('type', <<"irc">>),
- ?XMLATTR('name', translate:translate(Lang, "IRC Transport"))]},
- #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs =
- [?XMLATTR('var', ?NS_DISCO_INFO_s)]},
- #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs =
- [?XMLATTR('var', ?NS_MUC_s)]},
- #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs =
- [?XMLATTR('var', ?NS_INBAND_REGISTER_s)]},
- #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs =
- [?XMLATTR('var', ?NS_VCARD_s)]}].
-
-iq_get_vcard(Lang) ->
- [#xmlel{ns = ?NS_VCARD, name = 'FN', children =
- [#xmlcdata{cdata = <<"ejabberd/mod_irc">>}]},
- #xmlel{ns = ?NS_VCARD, name = 'URL', children =
- [#xmlcdata{cdata = list_to_binary(?EJABBERD_URI)}]},
- #xmlel{ns = ?NS_VCARD, name = 'DESC', children =
- [#xmlcdata{cdata = list_to_binary(translate:translate(Lang, "ejabberd IRC module") ++
- "\nCopyright (c) 2003-2009 Alexey Shchepin")}]}].
-
-process_register(Host, From, To, DefEnc, #iq{} = IQ_Rec) ->
- case catch process_irc_register(Host, From, To, DefEnc, IQ_Rec) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]);
- ResIQ ->
- if
- ResIQ /= ignore ->
- ejabberd_router:route(To, From,
- exmpp_iq:iq_to_xmlel(ResIQ));
- true ->
- ok
- end
- end.
-
-find_xdata_el(#xmlel{children = SubEls}) ->
- find_xdata_el1(SubEls).
-
-find_xdata_el1([]) ->
- false;
-
-find_xdata_el1([#xmlel{ns = ?NS_DATA_FORMS} = El | _Els]) ->
- El;
-
-find_xdata_el1([_ | Els]) ->
- find_xdata_el1(Els).
-
-process_irc_register(Host, From, _To, DefEnc,
- #iq{type = get, ns = XMLNS,
- lang = Lang, payload = SubEl} = IQ_Rec) ->
- Node =
- string:tokens(exmpp_xml:get_attribute_as_list(SubEl, 'node', ""), "/"),
- case get_form(Host, From, Node, Lang ,DefEnc) of
- {result, Res} ->
- Result = #xmlel{ns = XMLNS, name = 'query', children = Res},
- exmpp_iq:result(IQ_Rec, Result);
- {error, Error} ->
- exmpp_iq:error(IQ_Rec, Error)
- end;
-process_irc_register(Host, From, _To, _DefEnc,
- #iq{type = set, ns = XMLNS,
- lang = Lang, payload = SubEl} = IQ_Rec) ->
- XDataEl = find_xdata_el(SubEl),
- case XDataEl of
- false ->
- exmpp_iq:error(IQ_Rec, 'not-acceptable');
- _ ->
- case exmpp_stanza:get_type(XDataEl) of
- <<"cancel">> ->
- Result = #xmlel{ns = XMLNS, name = 'query'},
- exmpp_iq:result(IQ_Rec, Result);
- <<"submit">> ->
- XData = jlib:parse_xdata_submit(XDataEl),
- case XData of
- invalid ->
- exmpp_iq:error(IQ_Rec, 'bad-request');
- _ ->
- Node = string:tokens(
- exmpp_xml:get_attribute_as_list(SubEl, "node", ""),
- "/"),
- case set_form(
- Host, From, Node, Lang, XData) of
- {result, Res} ->
- Result = #xmlel{ns = XMLNS, name = 'query',
- children = Res},
- exmpp_iq:result(IQ_Rec, Result);
- {error, Error} ->
- exmpp_iq:error(IQ_Rec, Error)
- end
- end;
- _ ->
- exmpp_iq:error(IQ_Rec, 'bad-request')
- end
- end.
-
-
-
-get_form(Host, From, [], Lang, DefEnc) ->
- User = exmpp_jid:node_as_list(From),
- Server = exmpp_jid:domain_as_list(From),
- LUser = exmpp_jid:prep_node_as_list(From),
- LServer = exmpp_jid:prep_domain_as_list(From),
- US = {LUser, LServer},
- Customs =
- case catch mnesia:dirty_read({irc_custom, {US, Host}}) of
- {'EXIT', _Reason} ->
- {error, 'internal-server-error'};
- [] ->
- {User, []};
- [#irc_custom{data = Data}] ->
- {proplists:get_value(username, Data, ""),
- proplists:get_value(encodings, Data, "")}
- end,
- case Customs of
- {error, _Error} ->
- Customs;
- {Username, Encodings} ->
- {result,
- [#xmlel{ns = ?NS_INBAND_REGISTER, name = 'instructions', children =
- [#xmlcdata{cdata = list_to_binary(
- translate:translate(
- Lang,
- "You need an x:data capable client "
- "to configure mod_irc settings"))}]},
- #xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
- [#xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
- [#xmlcdata{cdata = list_to_binary(
- translate:translate(
- Lang,
- "Registration in mod_irc for ") ++ User ++ "@" ++ Server)}]},
- #xmlel{ns = ?NS_DATA_FORMS, name = 'instructions', children =
- [#xmlcdata{cdata = list_to_binary(
- translate:translate(
- Lang,
- "Enter username and encodings you wish to use for "
- "connecting to IRC servers"))}]},
- #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [?XMLATTR('type', <<"text-single">>),
- ?XMLATTR('label',
- translate:translate(
- Lang, "IRC Username")),
- ?XMLATTR('var', <<"username">>)], children =
- [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Username)}]}]},
- #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [?XMLATTR('type', <<"fixed">>)], children =
- [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children =
- [#xmlcdata{cdata = list_to_binary(
- lists:flatten(
- io_lib:format(
- translate:translate(
- Lang,
- "If you want to specify different encodings "
- "for IRC servers, fill this list with values "
- "in format '{\"irc server\", \"encoding\"}'. "
- "By default this service use \"~s\" encoding."),
- [DefEnc])))}]}]},
- #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [?XMLATTR('type', <<"fixed">>)], children =
- [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children =
- [#xmlcdata{cdata = list_to_binary(
- translate:translate(
- Lang,
- "Example: [{\"irc.lucky.net\", \"koi8-r\"}, "
- "{\"vendetta.fef.net\", \"iso8859-1\"}]."
- ))}]}]},
- #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [?XMLATTR('type', <<"text-multi">>),
- ?XMLATTR('label',
- translate:translate(Lang, "Encodings")),
- ?XMLATTR('var', <<"encodings">>)], children =
- lists:map(
- fun(S) ->
- #xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(S)}]}
- end,
- string:tokens(
- lists:flatten(
- io_lib:format("~p.", [Encodings])),
- "\n"))
- }
- ]}]}
- end;
-
-get_form(_Host, _, _, _Lang, _) ->
- {error, 'service-unavailable'}.
-
-
-
-
-set_form(Host, From, [], _Lang, XData) ->
- LUser = exmpp_jid:prep_node_as_list(From),
- LServer = exmpp_jid:prep_domain_as_list(From),
- US = {LUser, LServer},
- case {lists:keysearch("username", 1, XData),
- lists:keysearch("encodings", 1, XData)} of
- {{value, {_, [Username]}}, {value, {_, Strings}}} ->
- EncString = lists:foldl(fun(S, Res) ->
- Res ++ S ++ "\n"
- end, "", Strings),
- case erl_scan:string(EncString) of
- {ok, Tokens, _} ->
- case erl_parse:parse_term(Tokens) of
- {ok, Encodings} ->
- case mnesia:transaction(
- fun() ->
- mnesia:write(
- #irc_custom{us_host =
- {US, Host},
- data =
- [{username,
- Username},
- {encodings,
- Encodings}]})
- end) of
- {atomic, _} ->
- {result, []};
- _ ->
- {error, 'not-acceptable'}
- end;
- _ ->
- {error, 'not-acceptable'}
- end;
- _ ->
- {error, 'not-acceptable'}
- end;
- _ ->
- {error, 'not-acceptable'}
- end;
-
-
-set_form(_Host, _, _, _Lang, _XData) ->
- {error, 'service-unavailable'}.
-
-
-get_user_and_encoding(Host, From, IRCServer, DefEnc) ->
- User = exmpp_jid:node_as_list(From),
- LUser = exmpp_jid:prep_node_as_list(From),
- LServer = exmpp_jid:prep_domain_as_list(From),
- US = {LUser, LServer},
- case catch mnesia:dirty_read({irc_custom, {US, Host}}) of
- {'EXIT', _Reason} ->
- {User, DefEnc};
- [] ->
- {User, DefEnc};
- [#irc_custom{data = Data}] ->
- {proplists:get_value(username, Data, ""),
- case proplists:get_value(IRCServer, proplists:get_value(encodings, Data, ""), "") of
- "" -> DefEnc;
- E -> E
- end}
- end.
-
-
-update_table(Host) ->
- Fields = record_info(fields, irc_custom),
- case mnesia:table_info(irc_custom, attributes) of
- Fields ->
- ok;
- [userserver, data] ->
- ?INFO_MSG("Converting irc_custom table from "
- "{userserver, data} format", []),
- {atomic, ok} = mnesia:create_table(
- mod_irc_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, irc_custom},
- {attributes, record_info(fields, irc_custom)}]),
- mnesia:transform_table(irc_custom, ignore, Fields),
- F1 = fun() ->
- mnesia:write_lock_table(mod_irc_tmp_table),
- mnesia:foldl(
- fun(#irc_custom{us_host = US} = R, _) ->
- mnesia:dirty_write(
- mod_irc_tmp_table,
- R#irc_custom{us_host = {US, Host}})
- end, ok, irc_custom)
- end,
- mnesia:transaction(F1),
- mnesia:clear_table(irc_custom),
- F2 = fun() ->
- mnesia:write_lock_table(irc_custom),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_irc_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_irc_tmp_table);
- _ ->
- ?INFO_MSG("Recreating irc_custom table", []),
- mnesia:transform_table(irc_custom, ignore, Fields)
- end.
diff --git a/src/mod_irc/mod_irc_connection.erl b/src/mod_irc/mod_irc_connection.erl
deleted file mode 100644
index afcb91aa4..000000000
--- a/src/mod_irc/mod_irc_connection.erl
+++ /dev/null
@@ -1,1177 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_irc_connection.erl
-%%% Author : Alexey Shchepin
-%%% Purpose :
-%%% Created : 15 Feb 2003 by Alexey Shchepin
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
-%%%
-%%% 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.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(mod_irc_connection).
--author('alexey@process-one.net').
-
--behaviour(gen_fsm).
-
-%% External exports
--export([start_link/5, start/6, route_chan/4, route_nick/3]).
-
-%% gen_fsm callbacks
--export([init/1,
- open_socket/2,
- wait_for_registration/2,
- stream_established/2,
- handle_event/3,
- handle_sync_event/4,
- handle_info/3,
- terminate/3,
- code_change/4]).
-
--include_lib("exmpp/include/exmpp.hrl").
-
--include("ejabberd.hrl").
-
--define(SETS, gb_sets).
-
--record(state, {socket, encoding, queue,
- user, host, server, nick,
- channels = dict:new(),
- inbuf = "", outbuf = ""}).
-
-%-define(DBGFSM, true).
-
--ifdef(DBGFSM).
--define(FSMOPTS, [{debug, [trace]}]).
--else.
--define(FSMOPTS, []).
--endif.
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-start(From, Host, ServerHost, Server, Username, Encoding) ->
- Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_irc_sup),
- supervisor:start_child(
- Supervisor, [From, Host, Server, Username, Encoding]).
-
-start_link(From, Host, Server, Username, Encoding) ->
- gen_fsm:start_link(?MODULE, [From, Host, Server, Username, Encoding],
- ?FSMOPTS).
-
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_fsm
-%%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, StateName, StateData} |
-%% {ok, StateName, StateData, Timeout} |
-%% ignore |
-%% {stop, StopReason}
-%%----------------------------------------------------------------------
-init([From, Host, Server, Username, Encoding]) ->
- gen_fsm:send_event(self(), init),
- {ok, open_socket, #state{queue = queue:new(),
- encoding = Encoding,
- user = From,
- nick = Username,
- host = Host,
- server = Server}}.
-
-%%----------------------------------------------------------------------
-%% Func: StateName/2
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-open_socket(init, StateData) ->
- Addr = StateData#state.server,
- Port = 6667,
- ?DEBUG("connecting to ~s:~p~n", [Addr, Port]),
- case gen_tcp:connect(Addr, Port, [binary, {packet, 0}]) of
- {ok, Socket} ->
- NewStateData = StateData#state{socket = Socket},
- send_text(NewStateData,
- io_lib:format("NICK ~s\r\n", [StateData#state.nick])),
- send_text(NewStateData,
- io_lib:format(
- "USER ~s ~s ~s :~s\r\n",
- [StateData#state.nick,
- StateData#state.nick,
- StateData#state.host,
- StateData#state.nick])),
- send_text(NewStateData,
- io_lib:format("CODEPAGE ~s\r\n", [StateData#state.encoding])),
- {next_state, wait_for_registration,
- NewStateData};
- {error, Reason} ->
- ?DEBUG("connect return ~p~n", [Reason]),
- Text = case Reason of
- timeout -> <<"Server Connect Timeout">>;
- _ -> <<"Server Connect Failed">>
- end,
- bounce_messages(Text),
- {stop, normal, StateData}
- end.
-
-wait_for_registration(closed, StateData) ->
- {stop, normal, StateData}.
-
-stream_established({xmlstreamend, _Name}, StateData) ->
- {stop, normal, StateData};
-
-stream_established(timeout, StateData) ->
- {stop, normal, StateData};
-
-stream_established(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-
-%%----------------------------------------------------------------------
-%% Func: StateName/3
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {reply, Reply, NextStateName, NextStateData} |
-%% {reply, Reply, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData} |
-%% {stop, Reason, Reply, NewStateData}
-%%----------------------------------------------------------------------
-%state_name(Event, From, StateData) ->
-% Reply = ok,
-% {reply, Reply, state_name, StateData}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_event/3
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-handle_event(_Event, StateName, StateData) ->
- {next_state, StateName, StateData}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_sync_event/4
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {reply, Reply, NextStateName, NextStateData} |
-%% {reply, Reply, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData} |
-%% {stop, Reason, Reply, NewStateData}
-%%----------------------------------------------------------------------
-handle_sync_event(_Event, _From, StateName, StateData) ->
- Reply = ok,
- {reply, Reply, StateName, StateData}.
-
-code_change(_OldVsn, StateName, StateData, _Extra) ->
- {ok, StateName, StateData}.
-
--define(SEND(S),
- if
- StateName == stream_established ->
- send_text(StateData, S),
- StateData;
- true ->
- StateData#state{outbuf = StateData#state.outbuf ++ S}
- end).
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/3
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-handle_info({route_chan, Channel, Resource,
- El},
- StateName, StateData) when ?IS_PRESENCE(El) ->
- NewStateData =
- case exmpp_presence:get_type(El) of
- 'unavailable' ->
- S1 = ?SEND(io_lib:format("PART #~s\r\n", [Channel])),
- S1#state{channels =
- dict:erase(Channel, S1#state.channels)};
- 'subscribe' -> StateData;
- 'subscribed' -> StateData;
- 'unsubscribe' -> StateData;
- 'unsubscribed' -> StateData;
- 'error' -> stop;
- _ ->
- Nick = case Resource of
- undefined ->
- StateData#state.nick;
- _ ->
- Resource
- end,
- S1 = ?SEND(io_lib:format("NICK ~s\r\n"
- "JOIN #~s\r\n",
- [Nick, Channel])),
- case dict:is_key(Channel, S1#state.channels) of
- true ->
- S1#state{nick = Nick};
- _ ->
- S1#state{nick = Nick,
- channels =
- dict:store(Channel, ?SETS:new(),
- S1#state.channels)}
- end
- end,
- if
- NewStateData == stop ->
- {stop, normal, StateData};
- true ->
- case length(dict:fetch_keys(NewStateData#state.channels)) of
- 0 ->
- {stop, normal, NewStateData};
- _ ->
- {next_state, StateName, NewStateData}
- end
- end;
-
-handle_info({route_chan, Channel, Resource,
- El},
- StateName, StateData) when ?IS_MESSAGE(El) ->
- NewStateData =
- case exmpp_message:get_type(El) of
- 'groupchat' ->
- case exmpp_message:get_subject(El) of
- undefined ->
- ejabberd_router:route(
- exmpp_jid:make(
- lists:concat(
- [Channel, "%", StateData#state.server]),
- StateData#state.host, StateData#state.nick),
- StateData#state.user, El),
- Body = binary_to_list(exmpp_message:get_body(El)),
- case Body of
- "/quote " ++ Rest ->
- ?SEND(Rest ++ "\r\n");
- "/msg " ++ Rest ->
- ?SEND("PRIVMSG " ++ Rest ++ "\r\n");
- "/me " ++ Rest ->
- Strings = string:tokens(Rest, "\n"),
- Res = lists:concat(
- lists:map(
- fun(S) ->
- io_lib:format(
- "PRIVMSG #~s :\001ACTION ~s\001\r\n",
- [Channel, S])
- end, Strings)),
- ?SEND(Res);
- "/ctcp " ++ Rest ->
- Words = string:tokens(Rest, " "),
- case Words of
- [CtcpDest | _] ->
- CtcpCmd =
- toupper(
- string:substr(
- Rest,
- string:str(Rest, " ") + 1)),
- Res = io_lib:format(
- "PRIVMSG ~s :\001~s\001\r\n",
- [CtcpDest, CtcpCmd]),
- ?SEND(Res);
- _ ->
- ok
- end;
- _ ->
- Strings = string:tokens(Body, "\n"),
- Res = lists:concat(
- lists:map(
- fun(S) ->
- io_lib:format(
- "PRIVMSG #~s :~s\r\n",
- [Channel, S])
- end, Strings)),
- ?SEND(Res)
- end;
- Subject ->
- Strings = string:tokens(Subject, "\n"),
- Res = lists:concat(
- lists:map(
- fun(S) ->
- io_lib:format("TOPIC #~s :~s\r\n",
- [Channel, S])
- end, Strings)),
- ?SEND(Res)
- end;
- Type when Type == 'chat'; Type == 'normal' ->
- Body = binary_to_list(exmpp_message:get_body(El)),
- case Body of
- "/quote " ++ Rest ->
- ?SEND(Rest ++ "\r\n");
- "/msg " ++ Rest ->
- ?SEND("PRIVMSG " ++ Rest ++ "\r\n");
- "/me " ++ Rest ->
- Strings = string:tokens(Rest, "\n"),
- Res = lists:concat(
- lists:map(
- fun(S) ->
- io_lib:format(
- "PRIVMSG ~s :\001ACTION ~s\001\r\n",
- [Resource, S])
- end, Strings)),
- ?SEND(Res);
- "/ctcp " ++ Rest ->
- Words = string:tokens(Rest, " "),
- case Words of
- [CtcpDest | _ ] ->
- CtcpCmd =
- toupper(
- string:substr(
- Rest, string:str(Rest, " ") + 1)),
- Res = io_lib:format(
- "PRIVMSG ~s :~s\r\n",
- [CtcpDest, "\001" ++ CtcpCmd ++ "\001"]),
- ?SEND(Res);
- _ ->
- ok
- end;
- _ ->
- Strings = string:tokens(Body, "\n"),
- Res = lists:concat(
- lists:map(
- fun(S) ->
- io_lib:format("PRIVMSG ~s :~s\r\n",
- [Resource, S])
- end, Strings)),
- ?SEND(Res)
- end;
- 'error' ->
- stop;
- _ ->
- StateData
- end,
- if
- NewStateData == stop ->
- {stop, normal, StateData};
- true ->
- {next_state, StateName, NewStateData}
- end;
-
-
-handle_info({route_chan, Channel, Resource,
- El},
- StateName, StateData) when ?IS_IQ(El) ->
- From = StateData#state.user,
- To = exmpp_jid:make(lists:concat([Channel, "%", StateData#state.server]),
- StateData#state.host, StateData#state.nick),
- _ = case exmpp_iq:xmlel_to_iq(El) of
- #iq{kind = request, ns = ?NS_MUC_ADMIN} = IQ_Rec ->
- iq_admin(StateData, Channel, From, To, IQ_Rec);
- #iq{kind = request, ns = ?NS_SOFT_VERSION} ->
- Res = io_lib:format("PRIVMSG ~s :\001VERSION\001\r\n",
- [Resource]),
- _ = ?SEND(Res),
- Err = exmpp_iq:error(El, 'feature-not-implemented'),
- ejabberd_router:route(To, From, Err);
- #iq{kind = request, ns = ?NS_TIME_OLD} ->
- Res = io_lib:format("PRIVMSG ~s :\001TIME\001\r\n",
- [Resource]),
- _ = ?SEND(Res),
- Err = exmpp_iq:error(El, 'feature-not-implemented'),
- ejabberd_router:route(To, From, Err);
- #iq{kind = request, ns = ?NS_VCARD} ->
- Res = io_lib:format("WHOIS ~s \r\n",
- [Resource]),
- _ = ?SEND(Res),
- Err = exmpp_iq:error(El, 'feature-not-implemented'),
- ejabberd_router:route(To, From, Err);
- #iq{} ->
- Err = exmpp_iq:error(El, 'feature-not-implemented'),
- ejabberd_router:route(To, From, Err);
- _ ->
- ok
- end,
- {next_state, StateName, StateData};
-
-handle_info({route_chan, _Channel, _Resource, _Packet}, StateName, StateData) ->
- {next_state, StateName, StateData};
-
-
-handle_info({route_nick, Nick,
- El},
- StateName, StateData) when ?IS_MESSAGE(El) ->
- NewStateData =
- case exmpp_message:get_type(El) of
- 'chat' ->
- Body = binary_to_list(exmpp_message:get_body(El)),
- case Body of
- "/quote " ++ Rest ->
- ?SEND(Rest ++ "\r\n");
- "/msg " ++ Rest ->
- ?SEND("PRIVMSG " ++ Rest ++ "\r\n");
- "/me " ++ Rest ->
- Strings = string:tokens(Rest, "\n"),
- Res = lists:concat(
- lists:map(
- fun(S) ->
- io_lib:format(
- "PRIVMSG ~s :\001ACTION ~s\001\r\n",
- [Nick, S])
- end, Strings)),
- ?SEND(Res);
- "/ctcp " ++ Rest ->
- Words = string:tokens(Rest, " "),
- case Words of
- [CtcpDest | _ ] ->
- CtcpCmd = toupper(string:substr(Rest, string:str(Rest, " ")+1 )),
- Res = io_lib:format(
- "PRIVMSG ~s :~s\r\n",
- [CtcpDest, "\001" ++ CtcpCmd ++ "\001"]),
- ?SEND(Res);
- _ ->
- ok
- end;
- _ ->
- Strings = string:tokens(Body, "\n"),
- Res = lists:concat(
- lists:map(
- fun(S) ->
- io_lib:format("PRIVMSG ~s :~s\r\n",
- [Nick, S])
- end, Strings)),
- ?SEND(Res)
- end;
- 'error' ->
- stop;
- _ ->
- StateData
- end,
- if
- NewStateData == stop ->
- {stop, normal, StateData};
- true ->
- {next_state, StateName, NewStateData}
- end;
-
-handle_info({route_nick, _Nick, _Packet}, StateName, StateData) ->
- {next_state, StateName, StateData};
-
-
-handle_info({ircstring, [$P, $I, $N, $G, $ | ID]}, StateName, StateData) ->
- send_text(StateData, "PONG " ++ ID ++ "\r\n"),
- {next_state, StateName, StateData};
-
-handle_info({ircstring, [$: | String]}, _StateName, StateData) ->
- Words = string:tokens(String, " "),
- NewStateData =
- case Words of
- [_, "353" | Items] ->
- process_channel_list(StateData, Items);
- [_, "332", _Nick, [$# | Chan] | _] ->
- process_channel_topic(StateData, Chan, String),
- StateData;
- [_, "333", _Nick, [$# | Chan] | _] ->
- process_channel_topic_who(StateData, Chan, String),
- StateData;
- [_, "318", _, Nick | _] ->
- process_endofwhois(StateData, String, Nick),
- StateData;
- [_, "311", _, Nick, Ident, Irchost | _ ] ->
- process_whois311(StateData, String, Nick, Ident, Irchost),
- StateData;
- [_, "312", _, Nick, Ircserver | _ ] ->
- process_whois312(StateData, String, Nick, Ircserver),
- StateData;
- [_, "319", _, Nick | _ ] ->
- process_whois319(StateData, String, Nick),
- StateData;
- [From, "PRIVMSG", [$# | Chan] | _] ->
- process_chanprivmsg(StateData, Chan, From, String),
- StateData;
- [From, "NOTICE", [$# | Chan] | _] ->
- process_channotice(StateData, Chan, From, String),
- StateData;
- [From, "PRIVMSG", Nick, ":\001VERSION\001" | _] ->
- process_version(StateData, Nick, From),
- StateData;
- [From, "PRIVMSG", Nick, ":\001USERINFO\001" | _] ->
- process_userinfo(StateData, Nick, From),
- StateData;
- [From, "PRIVMSG", Nick | _] ->
- process_privmsg(StateData, Nick, From, String),
- StateData;
- [From, "NOTICE", Nick | _] ->
- process_notice(StateData, Nick, From, String),
- StateData;
- [From, "TOPIC", [$# | Chan] | _] ->
- process_topic(StateData, Chan, From, String),
- StateData;
- [From, "PART", [$# | Chan] | _] ->
- process_part(StateData, Chan, From, String);
- [From, "QUIT" | _] ->
- process_quit(StateData, From, String);
- [From, "JOIN", Chan | _] ->
- process_join(StateData, Chan, From, String);
- [From, "MODE", [$# | Chan], "+o", Nick | _] ->
- process_mode_o(StateData, Chan, From, Nick,
- "admin", "moderator"),
- StateData;
- [From, "MODE", [$# | Chan], "-o", Nick | _] ->
- process_mode_o(StateData, Chan, From, Nick,
- "member", "participant"),
- StateData;
- [From, "KICK", [$# | Chan], Nick | _] ->
- process_kick(StateData, Chan, From, Nick, String),
- StateData;
- [From, "NICK", Nick | _] ->
- process_nick(StateData, From, Nick);
- _ ->
- ?DEBUG("unknown irc command '~s'~n", [String]),
- StateData
- end,
- NewStateData1 =
- case StateData#state.outbuf of
- "" ->
- NewStateData;
- Data ->
- send_text(NewStateData, Data),
- NewStateData#state{outbuf = ""}
- end,
- {next_state, stream_established, NewStateData1};
-
-handle_info({ircstring, [$E, $R, $R, $O, $R | _] = String},
- StateName, StateData) ->
- process_error(StateData, String),
- {next_state, StateName, StateData};
-
-
-handle_info({ircstring, String}, StateName, StateData) ->
- ?DEBUG("unknown irc command '~s'~n", [String]),
- {next_state, StateName, StateData};
-
-
-handle_info({send_text, Text}, StateName, StateData) ->
- send_text(StateData, Text),
- {next_state, StateName, StateData};
-handle_info({tcp, _Socket, Data}, StateName, StateData) ->
- Buf = StateData#state.inbuf ++ binary_to_list(Data),
- {ok, Strings} = regexp:split([C || C <- Buf, C /= $\r], "\n"),
- ?DEBUG("strings=~p~n", [Strings]),
- NewBuf = process_lines(StateData#state.encoding, Strings),
- {next_state, StateName, StateData#state{inbuf = NewBuf}};
-handle_info({tcp_closed, _Socket}, StateName, StateData) ->
- gen_fsm:send_event(self(), closed),
- {next_state, StateName, StateData};
-handle_info({tcp_error, _Socket, _Reason}, StateName, StateData) ->
- gen_fsm:send_event(self(), closed),
- {next_state, StateName, StateData}.
-
-%%----------------------------------------------------------------------
-%% Func: terminate/3
-%% Purpose: Shutdown the fsm
-%% Returns: any
-%%----------------------------------------------------------------------
-terminate(_Reason, _StateName, StateData) ->
- mod_irc:closed_connection(StateData#state.host,
- StateData#state.user,
- StateData#state.server),
- bounce_messages(<<"Server Connect Failed">>),
- lists:foreach(
- fun(Chan) ->
- ejabberd_router:route(
- exmpp_jid:make(
- lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, StateData#state.nick),
- StateData#state.user,
- #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', attrs = [?XMLATTR('type', <<"error">>)], children =
- [#xmlel{ns = ?NS_JABBER_CLIENT, name = 'error', attrs = [?XMLATTR('code', <<"502">>)], children =
- [#xmlcdata{cdata = <<"Server Connect Failed">>}]}]})
- end, dict:fetch_keys(StateData#state.channels)),
- case StateData#state.socket of
- undefined ->
- ok;
- Socket ->
- gen_tcp:close(Socket)
- end,
- ok.
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-
-send_text(#state{socket = Socket, encoding = Encoding}, Text) ->
- CText = iconv:convert("utf-8", Encoding, lists:flatten(Text)),
- %?DEBUG("IRC OUTu: ~s~nIRC OUTk: ~s~n", [Text, CText]),
- gen_tcp:send(Socket, CText).
-
-
-%send_queue(Socket, Q) ->
-% case queue:out(Q) of
-% {{value, El}, Q1} ->
-% send_element(Socket, El),
-% send_queue(Socket, Q1);
-% {empty, Q1} ->
-% ok
-% end.
-
-bounce_messages(Reason) ->
- receive
- {send_element, El} ->
- case exmpp_stanza:get_type(El) of
- <<"error">> ->
- ok;
- _ ->
- Error = #xmlel{ns = ?NS_JABBER_CLIENT, name = 'error',
- attrs = [?XMLATTR('code', <<"502">>)],
- children = [#xmlcdata{cdata = Reason}]},
- Err = exmpp_stanza:reply_with_error(El, Error),
- From = exmpp_jid:parse(exmpp_stanza:get_sender(El)),
- To = exmpp_jid:parse(exmpp_stanza:get_recipient(El)),
- ejabberd_router:route(To, From, Err)
- end,
- bounce_messages(Reason)
- after 0 ->
- ok
- end.
-
-
-route_chan(Pid, Channel, Resource, Packet) ->
- Pid ! {route_chan, Channel, Resource, Packet}.
-
-route_nick(Pid, Nick, Packet) ->
- Pid ! {route_nick, Nick, Packet}.
-
-
-process_lines(_Encoding, [S]) ->
- S;
-process_lines(Encoding, [S | Ss]) ->
- self() ! {ircstring, iconv:convert(Encoding, "utf-8", S)},
- process_lines(Encoding, Ss).
-
-process_channel_list(StateData, Items) ->
- process_channel_list_find_chan(StateData, Items).
-
-process_channel_list_find_chan(StateData, []) ->
- StateData;
-process_channel_list_find_chan(StateData, [[$# | Chan] | Items]) ->
- process_channel_list_users(StateData, Chan, Items);
-process_channel_list_find_chan(StateData, [_ | Items]) ->
- process_channel_list_find_chan(StateData, Items).
-
-process_channel_list_users(StateData, _Chan, []) ->
- StateData;
-process_channel_list_users(StateData, Chan, [User | Items]) ->
- NewStateData = process_channel_list_user(StateData, Chan, User),
- process_channel_list_users(NewStateData, Chan, Items).
-
-process_channel_list_user(StateData, Chan, User) ->
- User1 = case User of
- [$: | U1] -> U1;
- _ -> User
- end,
- {User2, Affiliation, Role} =
- case User1 of
- [$@ | U2] -> {U2, <<"admin">>, <<"moderator">>};
- [$+ | U2] -> {U2, <<"member">>, <<"participant">>};
- [$\% | U2] -> {U2, <<"admin">>, <<"moderator">>};
- [$& | U2] -> {U2, <<"admin">>, <<"moderator">>};
- [$~ | U2] -> {U2, <<"admin">>, <<"moderator">>};
- _ -> {User1, <<"member">>, <<"participant">>}
- end,
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, User2),
- StateData#state.user,
- #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'x', children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs =
- [?XMLATTR('affiliation', Affiliation),
- ?XMLATTR('role', Role)]}]}]}),
- case catch dict:update(Chan,
- fun(Ps) ->
- ?SETS:add_element(User2, Ps)
- end, StateData#state.channels) of
- {'EXIT', _} ->
- StateData;
- NS ->
- StateData#state{channels = NS}
- end.
-
-
-process_channel_topic(StateData, Chan, String) ->
- {ok, Msg, _} = regexp:sub(String, ".*332[^:]*:", ""),
- Msg1 = filter_message(Msg),
- ejabberd_router:route(
- exmpp_jid:make(
- lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- exmpp_message:groupchat(Msg1, "Topic for #" ++ Chan ++ ": " ++ Msg1)).
-
-process_channel_topic_who(StateData, Chan, String) ->
- Words = string:tokens(String, " "),
- Msg1 = case Words of
- [_, "333", _, _Chan, Whoset , Timeset] ->
- case string:to_integer(Timeset) of
- {Unixtimeset, _Rest} ->
- "Topic for #" ++ Chan ++ " set by " ++ Whoset ++
- " at " ++ unixtime2string(Unixtimeset);
- _->
- "Topic for #" ++ Chan ++ " set by " ++ Whoset
- end;
- [_, "333", _, _Chan, Whoset | _] ->
- "Topic for #" ++ Chan ++ " set by " ++ Whoset;
- _ ->
- String
- end,
- Msg2 = filter_message(Msg1),
-
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- exmpp_message:groupchat(Msg2)).
-
-
-
-process_endofwhois(StateData, _String, Nick) ->
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([Nick, "!", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- exmpp_message:chat("End of WHOIS")).
-
-process_whois311(StateData, String, Nick, Ident, Irchost) ->
- {ok, Fullname, _} = regexp:sub(String, ".*311[^:]*:", ""),
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([Nick, "!", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- exmpp_message:chat(lists:concat(
- ["WHOIS: ", Nick, " is ",
- Ident, "@" , Irchost, " : " , Fullname]))).
-
-process_whois312(StateData, String, Nick, Ircserver) ->
- {ok, Ircserverdesc, _} = regexp:sub(String, ".*312[^:]*:", ""),
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([Nick, "!", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- exmpp_message:chat(lists:concat(["WHOIS: ", Nick, " use ",
- Ircserver, " : ", Ircserverdesc]))).
-
-process_whois319(StateData, String, Nick) ->
- {ok, Chanlist, _} = regexp:sub(String, ".*319[^:]*:", ""),
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([Nick, "!", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- exmpp_message:chat(lists:concat(["WHOIS: ", Nick, " is on ",
- Chanlist]))).
-
-
-
-process_chanprivmsg(StateData, Chan, From, String) ->
- [FromUser | _] = string:tokens(From, "!"),
- {ok, Msg, _} = regexp:sub(String, ".*PRIVMSG[^:]*:", ""),
- Msg1 = case Msg of
- [1, $A, $C, $T, $I, $O, $N, $ | Rest] ->
- "/me " ++ Rest;
- _ ->
- Msg
- end,
- Msg2 = filter_message(Msg1),
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, FromUser),
- StateData#state.user,
- exmpp_message:groupchat(Msg2)).
-
-
-
-process_channotice(StateData, Chan, From, String) ->
- [FromUser | _] = string:tokens(From, "!"),
- {ok, Msg, _} = regexp:sub(String, ".*NOTICE[^:]*:", ""),
- Msg1 = case Msg of
- [1, $A, $C, $T, $I, $O, $N, $ | Rest] ->
- "/me " ++ Rest;
- _ ->
- "/me NOTICE: " ++ Msg
- end,
- Msg2 = filter_message(Msg1),
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, FromUser),
- StateData#state.user,
- exmpp_message:groupchat(Msg2)).
-
-
-
-
-process_privmsg(StateData, _Nick, From, String) ->
- [FromUser | _] = string:tokens(From, "!"),
- {ok, Msg, _} = regexp:sub(String, ".*PRIVMSG[^:]*:", ""),
- Msg1 = case Msg of
- [1, $A, $C, $T, $I, $O, $N, $ | Rest] ->
- "/me " ++ Rest;
- _ ->
- Msg
- end,
- Msg2 = filter_message(Msg1),
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([FromUser, "!", StateData#state.server]),
- StateData#state.host, undefined),
- StateData#state.user,
- exmpp_message:chat(Msg2)).
-
-
-process_notice(StateData, _Nick, From, String) ->
- [FromUser | _] = string:tokens(From, "!"),
- {ok, Msg, _} = regexp:sub(String, ".*NOTICE[^:]*:", ""),
- Msg1 = case Msg of
- [1, $A, $C, $T, $I, $O, $N, $ | Rest] ->
- "/me " ++ Rest;
- _ ->
- "/me NOTICE: " ++ Msg
- end,
- Msg2 = filter_message(Msg1),
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([FromUser, "!", StateData#state.server]),
- StateData#state.host, undefined),
- StateData#state.user,
- exmpp_message:chat(Msg2)).
-
-
-process_version(StateData, _Nick, From) ->
- [FromUser | _] = string:tokens(From, "!"),
- send_text(
- StateData,
- io_lib:format("NOTICE ~s :\001VERSION "
- "ejabberd IRC transport ~s (c) Alexey Shchepin"
- "\001\r\n",
- [FromUser, ?VERSION]) ++
- io_lib:format("NOTICE ~s :\001VERSION "
- ?EJABBERD_URI
- "\001\r\n",
- [FromUser])).
-
-
-process_userinfo(StateData, _Nick, From) ->
- [FromUser | _] = string:tokens(From, "!"),
- send_text(
- StateData,
- io_lib:format("NOTICE ~s :\001USERINFO "
- "xmpp:~s"
- "\001\r\n",
- [FromUser,
- exmpp_jid:to_list(StateData#state.user)])).
-
-
-process_topic(StateData, Chan, From, String) ->
- [FromUser | _] = string:tokens(From, "!"),
- {ok, Msg, _} = regexp:sub(String, ".*TOPIC[^:]*:", ""),
- Msg1 = filter_message(Msg),
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, FromUser),
- StateData#state.user,
- exmpp_message:groupchat(Msg1,
- "/me has changed the subject to: " ++ Msg1)).
-
-process_part(StateData, Chan, From, String) ->
- [FromUser | FromIdent] = string:tokens(From, "!"),
- {ok, Msg, _} = regexp:sub(String, ".*PART[^:]*:", ""),
- Msg1 = filter_message(Msg),
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, FromUser),
- StateData#state.user,
- #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', attrs = [?XMLATTR('type', <<"unavailable">>)], children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'x', children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs =
- [?XMLATTR('affiliation', <<"member">>),
- ?XMLATTR('role', <<"none">>)]}]},
- #xmlel{ns = ?NS_MUC_USER, name = 'status', children =
- [#xmlcdata{cdata = list_to_binary(Msg1 ++ " (" ++ FromIdent ++ ")")}]}]
- }),
- case catch dict:update(Chan,
- fun(Ps) ->
- remove_element(FromUser, Ps)
- end, StateData#state.channels) of
- {'EXIT', _} ->
- StateData;
- NS ->
- StateData#state{channels = NS}
- end.
-
-
-process_quit(StateData, From, String) ->
- [FromUser | FromIdent] = string:tokens(From, "!"),
-
- {ok, Msg, _} = regexp:sub(String, ".*QUIT[^:]*:", ""),
- Msg1 = filter_message(Msg),
- %%NewChans =
- dict:map(
- fun(Chan, Ps) ->
- case ?SETS:is_member(FromUser, Ps) of
- true ->
- ejabberd_router:route(
- exmpp_jid:make(
- lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, FromUser),
- StateData#state.user,
- #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', attrs = [?XMLATTR('type', <<"unavailable">>)], children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'x', children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs =
- [?XMLATTR('affiliation', <<"member">>),
- ?XMLATTR('role', <<"none">>)]}]},
- #xmlel{ns = ?NS_MUC_USER, name = 'status', children =
- [#xmlcdata{cdata = list_to_binary(Msg1 ++ " (" ++ FromIdent ++ ")")}]}
- ]}),
- remove_element(FromUser, Ps);
- _ ->
- Ps
- end
- end, StateData#state.channels),
- StateData.
-
-
-process_join(StateData, Channel, From, _String) ->
- [FromUser | FromIdent] = string:tokens(From, "!"),
- Chan = lists:subtract(Channel, ":#"),
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, FromUser),
- StateData#state.user,
- #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'x', children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs =
- [?XMLATTR('affiliation', <<"member">>),
- ?XMLATTR('role', <<"participant">>)]}]},
- #xmlel{ns = ?NS_MUC_USER, name = 'status', children =
- [#xmlcdata{cdata = list_to_binary(FromIdent)}]}]}),
-
- case catch dict:update(Chan,
- fun(Ps) ->
- ?SETS:add_element(FromUser, Ps)
- end, StateData#state.channels) of
- {'EXIT', _} ->
- StateData;
- NS ->
- StateData#state{channels = NS}
- end.
-
-
-
-process_mode_o(StateData, Chan, _From, Nick, Affiliation, Role) ->
- %Msg = lists:last(string:tokens(String, ":")),
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, Nick),
- StateData#state.user,
- #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'x', children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs =
- [?XMLATTR('affiliation', Affiliation),
- ?XMLATTR('role', Role)]}]}]}).
-
-process_kick(StateData, Chan, From, Nick, String) ->
- Msg = lists:last(string:tokens(String, ":")),
- Msg2 = Nick ++ " kicked by " ++ From ++ " (" ++ filter_message(Msg) ++ ")",
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, undefined),
- StateData#state.user,
- exmpp_message:groupchat(Msg2)),
- ejabberd_router:route(
- exmpp_jid:make(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, Nick),
- StateData#state.user,
- #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', attrs = [?XMLATTR('type', <<"unavailable">>)], children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'x', children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs =
- [?XMLATTR('affiliation', <<"none">>),
- ?XMLATTR('role', <<"none">>)]},
- #xmlel{ns = ?NS_MUC_USER, name = 'status', attrs = [?XMLATTR('code', <<"307">>)]}
- ]}]}).
-
-process_nick(StateData, From, NewNick) ->
- [FromUser | _] = string:tokens(From, "!"),
- Nick = lists:subtract(NewNick, ":"),
- NewChans =
- dict:map(
- fun(Chan, Ps) ->
- case ?SETS:is_member(FromUser, Ps) of
- true ->
- ejabberd_router:route(
- exmpp_jid:make(
- lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, FromUser),
- StateData#state.user,
- #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', attrs = [?XMLATTR('type', <<"unavailable">>)], children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'x', children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs =
- [?XMLATTR('affiliation', <<"member">>),
- ?XMLATTR('role', <<"participant">>),
- ?XMLATTR('nick', Nick)]},
- #xmlel{ns = ?NS_MUC_USER, name = 'status', attrs = [?XMLATTR('code', <<"303">>)]}
- ]}]}),
- ejabberd_router:route(
- exmpp_jid:make(
- lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, Nick),
- StateData#state.user,
- #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'x', children =
- [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs =
- [?XMLATTR('affiliation', <<"member">>),
- ?XMLATTR('role', <<"participant">>)]}
- ]}]}),
- ?SETS:add_element(Nick,
- remove_element(FromUser, Ps));
- _ ->
- Ps
- end
- end, StateData#state.channels),
- StateData#state{channels = NewChans}.
-
-
-process_error(StateData, String) ->
- lists:foreach(
- fun(Chan) ->
- ejabberd_router:route(
- exmpp_jid:make(
- lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, StateData#state.nick),
- StateData#state.user,
- #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', attrs = [?XMLATTR('type', <<"error">>)], children =
- [#xmlel{ns = ?NS_JABBER_CLIENT, name = 'error', attrs = [?XMLATTR('code', <<"502">>)], children =
- [#xmlcdata{cdata = list_to_binary(String)}]}]})
- end, dict:fetch_keys(StateData#state.channels)).
-
-
-
-
-remove_element(E, Set) ->
- case ?SETS:is_element(E, Set) of
- true ->
- ?SETS:del_element(E, Set);
- _ ->
- Set
- end.
-
-
-
-iq_admin(StateData, Channel, From, To,
- #iq{type = Type, ns = XMLNS, payload = SubEl} = IQ_Rec) ->
- case catch process_iq_admin(StateData, Channel, Type, SubEl) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]);
- Res ->
- if
- Res /= ignore ->
- ResIQ = case Res of
- {result, ResEls} ->
- Result = #xmlel{ns = XMLNS, name = 'query',
- children = ResEls},
- exmpp_iq:result(IQ_Rec, Result);
- {error, Error} ->
- exmpp_iq:error(IQ_Rec, Error)
- end,
- ejabberd_router:route(To, From,
- exmpp_iq:iq_to_xmlel(ResIQ));
- true ->
- ok
- end
- end.
-
-
-process_iq_admin(StateData, Channel, set, SubEl) ->
- case exmpp_xml:get_element(SubEl, 'item') of
- false ->
- {error, 'bad-request'};
- ItemEl ->
- Nick = exmpp_xml:get_attribute_as_list(ItemEl, 'nick', ""),
- Affiliation = exmpp_xml:get_attribute_as_list(ItemEl, 'affiliation', ""),
- Role = exmpp_xml:get_attribute_as_list(ItemEl, 'role', ""),
- Reason = exmpp_xml:get_path(ItemEl, [{element, 'reason'}, cdata_as_list]),
- process_admin(StateData, Channel, Nick, Affiliation, Role, Reason)
- end;
-process_iq_admin(_StateData, _Channel, get, _SubEl) ->
- {error, 'feature-not-implemented'}.
-
-
-
-process_admin(_StateData, _Channel, "", _Affiliation, _Role, _Reason) ->
- {error, 'feature-not-implemented'};
-
-process_admin(StateData, Channel, Nick, _Affiliation, "none", Reason) ->
- case Reason of
- "" ->
- send_text(StateData,
- io_lib:format("KICK #~s ~s\r\n",
- [Channel, Nick]));
- _ ->
- send_text(StateData,
- io_lib:format("KICK #~s ~s :~s\r\n",
- [Channel, Nick, Reason]))
- end,
- {result, []};
-
-
-
-process_admin(_StateData, _Channel, _Nick, _Affiliation, _Role, _Reason) ->
- {error, 'feature-not-implemented'}.
-
-
-
-filter_message(Msg) ->
- lists:filter(
- fun(C) ->
- if (C < 32) and
- (C /= 9) and
- (C /= 10) and
- (C /= 13) ->
- false;
- true -> true
- end
- end, filter_mirc_colors(Msg)).
-
-filter_mirc_colors(Msg) ->
- case regexp:gsub(Msg, "(\\003[0-9]+)(,[0-9]+)?", "") of
- {ok, Msg2, _} ->
- Msg2;
- _ ->
- Msg
- end.
-
-unixtime2string(Unixtime) ->
- Secs = Unixtime + calendar:datetime_to_gregorian_seconds(
- {{1970, 1, 1}, {0,0,0}}),
- case calendar:universal_time_to_local_time(
- calendar:gregorian_seconds_to_datetime(Secs)) of
- {{Year, Month, Day}, {Hour, Minute, Second}} ->
- lists:flatten(
- io_lib:format("~4..0w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w",
- [Year, Month, Day, Hour, Minute, Second]));
- _->
- "0000-00-00 00:00:00"
- end.
-
-toupper([C | Cs]) ->
- if
- C >= $a, C =< $z ->
- [C - 32 | toupper(Cs)];
- true ->
- [C | toupper(Cs)]
- end;
-toupper([]) ->
- [].
-
diff --git a/src/win32/ejabberd.cfg b/src/win32/ejabberd.cfg
index 7ba191be0..a42b849d5 100644
--- a/src/win32/ejabberd.cfg
+++ b/src/win32/ejabberd.cfg
@@ -146,7 +146,6 @@
{mod_offline, []},
{mod_announce, [{access, announce}]},
{mod_private, []},
- {mod_irc, []},
% Default options for mod_muc:
% host: "conference." ++ ?MYNAME
% access: all