aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMickaël Rémond <mickael.remond@process-one.net>2006-09-27 20:47:56 +0000
committerMickaël Rémond <mickael.remond@process-one.net>2006-09-27 20:47:56 +0000
commite1eef9f84bc899118e91457b6e88fd3236b247e8 (patch)
treec10425d86837333809884b025d99d3e6447db617
parent* Last ejabberd 1.1.2 tag: Fixed release note. (diff)
parent* src/release_notes_1.1.2.txt: Fixed hanging paragraph (diff)
* ejabberd 1.1.2 finalv1.1.2
SVN Revision: 656
-rw-r--r--doc/guide.html4
-rw-r--r--doc/release_notes_1.1.2.txt4
-rw-r--r--ejabberd-1.1.2/COPYING343
-rw-r--r--ejabberd-1.1.2/ChangeLog3393
-rw-r--r--ejabberd-1.1.2/TODO14
-rw-r--r--ejabberd-1.1.2/contrib/extract_translations/README21
-rw-r--r--ejabberd-1.1.2/contrib/extract_translations/extract_translations.erl190
-rwxr-xr-xejabberd-1.1.2/contrib/extract_translations/prepare-translation.sh101
-rw-r--r--ejabberd-1.1.2/doc/Makefile46
-rw-r--r--ejabberd-1.1.2/doc/dev.html449
-rw-r--r--ejabberd-1.1.2/doc/dev.tex398
-rw-r--r--ejabberd-1.1.2/doc/disco.pngbin9360 -> 0 bytes
-rw-r--r--ejabberd-1.1.2/doc/discorus.pngbin10052 -> 0 bytes
-rw-r--r--ejabberd-1.1.2/doc/features.html163
-rw-r--r--ejabberd-1.1.2/doc/features.tex136
-rw-r--r--ejabberd-1.1.2/doc/flow.dot105
-rw-r--r--ejabberd-1.1.2/doc/guide.html4160
-rw-r--r--ejabberd-1.1.2/doc/guide.tex3159
-rw-r--r--ejabberd-1.1.2/doc/introduction.tex131
-rw-r--r--ejabberd-1.1.2/doc/logo.pngbin83054 -> 0 bytes
-rw-r--r--ejabberd-1.1.2/doc/release_note_1.1.2.txt0
-rw-r--r--ejabberd-1.1.2/doc/release_notes_0.9.1.txt62
-rw-r--r--ejabberd-1.1.2/doc/release_notes_0.9.8.txt99
-rw-r--r--ejabberd-1.1.2/doc/release_notes_0.9.txt88
-rw-r--r--ejabberd-1.1.2/doc/release_notes_1.0.0.txt120
-rw-r--r--ejabberd-1.1.2/doc/release_notes_1.1.0.txt115
-rw-r--r--ejabberd-1.1.2/doc/release_notes_1.1.1.txt119
-rw-r--r--ejabberd-1.1.2/doc/release_notes_1.1.2.txt119
-rw-r--r--ejabberd-1.1.2/doc/version.tex2
-rw-r--r--ejabberd-1.1.2/doc/webadmmain.pngbin15813 -> 0 bytes
-rw-r--r--ejabberd-1.1.2/doc/webadmmainru.pngbin16780 -> 0 bytes
-rw-r--r--ejabberd-1.1.2/doc/yozhikheader.pngbin160944 -> 0 bytes
-rw-r--r--ejabberd-1.1.2/examples/extauth/check_pass_null.pl50
-rw-r--r--ejabberd-1.1.2/examples/mtr/ejabberd75
-rw-r--r--ejabberd-1.1.2/examples/mtr/ejabberd-netbsd.sh81
-rw-r--r--ejabberd-1.1.2/examples/mtr/ejabberd.cfg66
-rw-r--r--ejabberd-1.1.2/examples/transport-configs/configs/aim-transport.xml77
-rw-r--r--ejabberd-1.1.2/examples/transport-configs/configs/ile.xml136
-rw-r--r--ejabberd-1.1.2/examples/transport-configs/configs/jabber-gg-transport.xml149
-rw-r--r--ejabberd-1.1.2/examples/transport-configs/configs/jit.xml128
-rw-r--r--ejabberd-1.1.2/examples/transport-configs/configs/msn-transport.xml118
-rw-r--r--ejabberd-1.1.2/examples/transport-configs/configs/yahoo-transport-2.xml86
-rwxr-xr-xejabberd-1.1.2/examples/transport-configs/init-scripts/aim-transport45
-rwxr-xr-xejabberd-1.1.2/examples/transport-configs/init-scripts/ile43
-rwxr-xr-xejabberd-1.1.2/examples/transport-configs/init-scripts/jabber-gg-transport47
-rwxr-xr-xejabberd-1.1.2/examples/transport-configs/init-scripts/jit45
-rwxr-xr-xejabberd-1.1.2/examples/transport-configs/init-scripts/msn-transport50
-rwxr-xr-xejabberd-1.1.2/examples/transport-configs/init-scripts/yahoo-transport-245
-rw-r--r--ejabberd-1.1.2/src/.cvsignore1
-rw-r--r--ejabberd-1.1.2/src/Makefile.in109
-rw-r--r--ejabberd-1.1.2/src/Makefile.win32163
-rw-r--r--ejabberd-1.1.2/src/XmppAddr.asn114
-rw-r--r--ejabberd-1.1.2/src/acl.erl203
-rw-r--r--ejabberd-1.1.2/src/aclocal.m4294
-rw-r--r--ejabberd-1.1.2/src/adhoc.erl111
-rw-r--r--ejabberd-1.1.2/src/adhoc.hrl15
-rwxr-xr-xejabberd-1.1.2/src/configure6558
-rw-r--r--ejabberd-1.1.2/src/configure.ac85
-rw-r--r--ejabberd-1.1.2/src/configure.bat20
-rw-r--r--ejabberd-1.1.2/src/configure.erl72
-rw-r--r--ejabberd-1.1.2/src/cyrsasl.erl149
-rw-r--r--ejabberd-1.1.2/src/cyrsasl_anonymous.erl39
-rw-r--r--ejabberd-1.1.2/src/cyrsasl_digest.erl163
-rw-r--r--ejabberd-1.1.2/src/cyrsasl_plain.erl57
-rw-r--r--ejabberd-1.1.2/src/ejabberd.app79
-rw-r--r--ejabberd-1.1.2/src/ejabberd.cfg.example187
-rw-r--r--ejabberd-1.1.2/src/ejabberd.erl34
-rw-r--r--ejabberd-1.1.2/src/ejabberd.hrl41
-rw-r--r--ejabberd-1.1.2/src/ejabberd_admin.erl59
-rw-r--r--ejabberd-1.1.2/src/ejabberd_app.erl104
-rw-r--r--ejabberd-1.1.2/src/ejabberd_auth.erl176
-rw-r--r--ejabberd-1.1.2/src/ejabberd_auth_anonymous.erl221
-rw-r--r--ejabberd-1.1.2/src/ejabberd_auth_external.erl72
-rw-r--r--ejabberd-1.1.2/src/ejabberd_auth_internal.erl243
-rw-r--r--ejabberd-1.1.2/src/ejabberd_auth_ldap.erl385
-rw-r--r--ejabberd-1.1.2/src/ejabberd_auth_odbc.erl215
-rw-r--r--ejabberd-1.1.2/src/ejabberd_c2s.erl1785
-rw-r--r--ejabberd-1.1.2/src/ejabberd_config.erl228
-rw-r--r--ejabberd-1.1.2/src/ejabberd_ctl.erl351
-rw-r--r--ejabberd-1.1.2/src/ejabberd_ctl.hrl12
-rw-r--r--ejabberd-1.1.2/src/ejabberd_hooks.erl199
-rw-r--r--ejabberd-1.1.2/src/ejabberd_listener.erl196
-rw-r--r--ejabberd-1.1.2/src/ejabberd_local.erl245
-rw-r--r--ejabberd-1.1.2/src/ejabberd_logger_h.erl206
-rw-r--r--ejabberd-1.1.2/src/ejabberd_receiver.erl272
-rw-r--r--ejabberd-1.1.2/src/ejabberd_router.erl285
-rw-r--r--ejabberd-1.1.2/src/ejabberd_s2s.erl277
-rw-r--r--ejabberd-1.1.2/src/ejabberd_s2s_in.erl686
-rw-r--r--ejabberd-1.1.2/src/ejabberd_s2s_out.erl857
-rw-r--r--ejabberd-1.1.2/src/ejabberd_service.erl347
-rw-r--r--ejabberd-1.1.2/src/ejabberd_sm.erl617
-rw-r--r--ejabberd-1.1.2/src/ejabberd_sup.erl151
-rw-r--r--ejabberd-1.1.2/src/ejabberd_tmp_sup.erl22
-rw-r--r--ejabberd-1.1.2/src/ejabberd_update.erl128
-rw-r--r--ejabberd-1.1.2/src/ejabberd_zlib/Makefile.in45
-rw-r--r--ejabberd-1.1.2/src/ejabberd_zlib/Makefile.win3237
-rw-r--r--ejabberd-1.1.2/src/ejabberd_zlib/ejabberd_zlib.erl134
-rw-r--r--ejabberd-1.1.2/src/ejabberd_zlib/ejabberd_zlib_drv.c171
-rw-r--r--ejabberd-1.1.2/src/ejd2odbc.erl310
-rw-r--r--ejabberd-1.1.2/src/eldap/ELDAPv3.asn291
-rw-r--r--ejabberd-1.1.2/src/eldap/Makefile.in39
-rw-r--r--ejabberd-1.1.2/src/eldap/Makefile.win3228
-rw-r--r--ejabberd-1.1.2/src/eldap/eldap.erl995
-rw-r--r--ejabberd-1.1.2/src/eldap/eldap.hrl13
-rw-r--r--ejabberd-1.1.2/src/eldap/eldap_filter.erl285
-rw-r--r--ejabberd-1.1.2/src/expat_erl.c265
-rw-r--r--ejabberd-1.1.2/src/extauth.erl77
-rw-r--r--ejabberd-1.1.2/src/gen_iq_handler.erl184
-rw-r--r--ejabberd-1.1.2/src/gen_mod.erl150
-rw-r--r--ejabberd-1.1.2/src/idna.erl179
-rw-r--r--ejabberd-1.1.2/src/jd2ejd.erl191
-rw-r--r--ejabberd-1.1.2/src/jlib.erl633
-rw-r--r--ejabberd-1.1.2/src/jlib.hrl287
-rw-r--r--ejabberd-1.1.2/src/mod_adhoc.erl250
-rw-r--r--ejabberd-1.1.2/src/mod_announce.erl757
-rw-r--r--ejabberd-1.1.2/src/mod_configure.erl1417
-rw-r--r--ejabberd-1.1.2/src/mod_configure2.erl153
-rw-r--r--ejabberd-1.1.2/src/mod_disco.erl480
-rw-r--r--ejabberd-1.1.2/src/mod_echo.erl126
-rw-r--r--ejabberd-1.1.2/src/mod_irc/Makefile.in48
-rw-r--r--ejabberd-1.1.2/src/mod_irc/Makefile.win3245
-rw-r--r--ejabberd-1.1.2/src/mod_irc/iconv.erl78
-rw-r--r--ejabberd-1.1.2/src/mod_irc/iconv_erl.c121
-rw-r--r--ejabberd-1.1.2/src/mod_irc/mod_irc.erl590
-rw-r--r--ejabberd-1.1.2/src/mod_irc/mod_irc_connection.erl1192
-rw-r--r--ejabberd-1.1.2/src/mod_last.erl196
-rw-r--r--ejabberd-1.1.2/src/mod_last_odbc.erl138
-rw-r--r--ejabberd-1.1.2/src/mod_muc/Makefile.in31
-rw-r--r--ejabberd-1.1.2/src/mod_muc/Makefile.win3224
-rw-r--r--ejabberd-1.1.2/src/mod_muc/mod_muc.erl694
-rw-r--r--ejabberd-1.1.2/src/mod_muc/mod_muc_log.erl749
-rw-r--r--ejabberd-1.1.2/src/mod_muc/mod_muc_room.erl2572
-rw-r--r--ejabberd-1.1.2/src/mod_offline.erl390
-rw-r--r--ejabberd-1.1.2/src/mod_offline_odbc.erl236
-rw-r--r--ejabberd-1.1.2/src/mod_privacy.erl718
-rw-r--r--ejabberd-1.1.2/src/mod_private.erl171
-rw-r--r--ejabberd-1.1.2/src/mod_pubsub/Makefile.in29
-rw-r--r--ejabberd-1.1.2/src/mod_pubsub/Makefile.win3216
-rw-r--r--ejabberd-1.1.2/src/mod_pubsub/mod_pubsub.erl1698
-rw-r--r--ejabberd-1.1.2/src/mod_register.erl228
-rw-r--r--ejabberd-1.1.2/src/mod_roster.erl766
-rw-r--r--ejabberd-1.1.2/src/mod_roster.hrl18
-rw-r--r--ejabberd-1.1.2/src/mod_roster_odbc.erl846
-rw-r--r--ejabberd-1.1.2/src/mod_service_log.erl59
-rw-r--r--ejabberd-1.1.2/src/mod_shared_roster.erl354
-rw-r--r--ejabberd-1.1.2/src/mod_stats.erl234
-rw-r--r--ejabberd-1.1.2/src/mod_time.erl44
-rw-r--r--ejabberd-1.1.2/src/mod_vcard.erl807
-rw-r--r--ejabberd-1.1.2/src/mod_vcard_ldap.erl803
-rw-r--r--ejabberd-1.1.2/src/mod_vcard_odbc.erl655
-rw-r--r--ejabberd-1.1.2/src/mod_version.erl67
-rw-r--r--ejabberd-1.1.2/src/msgs/cs.msg397
-rw-r--r--ejabberd-1.1.2/src/msgs/de.msg368
-rw-r--r--ejabberd-1.1.2/src/msgs/es.msg347
-rw-r--r--ejabberd-1.1.2/src/msgs/fr.msg347
-rw-r--r--ejabberd-1.1.2/src/msgs/nl.msg334
-rw-r--r--ejabberd-1.1.2/src/msgs/pl.msg425
-rw-r--r--ejabberd-1.1.2/src/msgs/pt-br.msg380
-rw-r--r--ejabberd-1.1.2/src/msgs/pt.msg243
-rw-r--r--ejabberd-1.1.2/src/msgs/ru.msg377
-rw-r--r--ejabberd-1.1.2/src/msgs/sk.msg463
-rw-r--r--ejabberd-1.1.2/src/msgs/sv.msg321
-rw-r--r--ejabberd-1.1.2/src/msgs/uk.msg377
-rw-r--r--ejabberd-1.1.2/src/odbc/Makefile.in33
-rw-r--r--ejabberd-1.1.2/src/odbc/Makefile.win3225
-rw-r--r--ejabberd-1.1.2/src/odbc/ejabberd_odbc.erl298
-rw-r--r--ejabberd-1.1.2/src/odbc/ejabberd_odbc_sup.erl48
-rw-r--r--ejabberd-1.1.2/src/odbc/mssql.sql899
-rw-r--r--ejabberd-1.1.2/src/odbc/mysql.sql96
-rw-r--r--ejabberd-1.1.2/src/odbc/odbc_queries.erl434
-rw-r--r--ejabberd-1.1.2/src/odbc/pg.sql104
-rw-r--r--ejabberd-1.1.2/src/randoms.erl42
-rw-r--r--ejabberd-1.1.2/src/sha.erl32
-rw-r--r--ejabberd-1.1.2/src/shaper.erl59
-rw-r--r--ejabberd-1.1.2/src/stringprep/Makefile.in46
-rw-r--r--ejabberd-1.1.2/src/stringprep/Makefile.win3235
-rw-r--r--ejabberd-1.1.2/src/stringprep/stringprep.erl97
-rw-r--r--ejabberd-1.1.2/src/stringprep/stringprep_drv.c392
-rw-r--r--ejabberd-1.1.2/src/stringprep/uni_data.c1257
-rw-r--r--ejabberd-1.1.2/src/stringprep/uni_norm.c3264
-rw-r--r--ejabberd-1.1.2/src/stringprep/uni_parse.tcl437
-rw-r--r--ejabberd-1.1.2/src/stringprep/uni_parse2.tcl702
-rw-r--r--ejabberd-1.1.2/src/tls/Makefile.in45
-rw-r--r--ejabberd-1.1.2/src/tls/Makefile.win3237
-rw-r--r--ejabberd-1.1.2/src/tls/tls.erl261
-rw-r--r--ejabberd-1.1.2/src/tls/tls_drv.c281
-rw-r--r--ejabberd-1.1.2/src/translate.erl145
-rw-r--r--ejabberd-1.1.2/src/web/Makefile.in34
-rw-r--r--ejabberd-1.1.2/src/web/Makefile.win3228
-rw-r--r--ejabberd-1.1.2/src/web/ejabberd_http.erl882
-rw-r--r--ejabberd-1.1.2/src/web/ejabberd_http.hrl18
-rw-r--r--ejabberd-1.1.2/src/web/ejabberd_http_poll.erl380
-rw-r--r--ejabberd-1.1.2/src/web/ejabberd_web.erl145
-rw-r--r--ejabberd-1.1.2/src/web/ejabberd_web_admin.erl2653
-rw-r--r--ejabberd-1.1.2/src/win32/CheckReqs.ini20
-rw-r--r--ejabberd-1.1.2/src/win32/CheckReqs1.ini28
-rw-r--r--ejabberd-1.1.2/src/win32/CheckReqs1H.ini29
-rw-r--r--ejabberd-1.1.2/src/win32/CheckService.ini19
-rw-r--r--ejabberd-1.1.2/src/win32/CheckUser.ini11
-rw-r--r--ejabberd-1.1.2/src/win32/CheckUserH.ini20
-rw-r--r--ejabberd-1.1.2/src/win32/ejabberd.cfg167
-rw-r--r--ejabberd-1.1.2/src/win32/ejabberd.icobin2238 -> 0 bytes
-rw-r--r--ejabberd-1.1.2/src/win32/ejabberd.nsi770
-rw-r--r--ejabberd-1.1.2/src/win32/ejabberd_header.bmpbin34254 -> 0 bytes
-rw-r--r--ejabberd-1.1.2/src/win32/ejabberd_intro.bmpbin26494 -> 0 bytes
-rw-r--r--ejabberd-1.1.2/src/win32/inetrc1
-rw-r--r--ejabberd-1.1.2/src/xml.erl233
-rw-r--r--ejabberd-1.1.2/src/xml_stream.erl164
-rwxr-xr-xejabberd-1.1.2/tools/ejabberdctl4
209 files changed, 2 insertions, 72681 deletions
diff --git a/doc/guide.html b/doc/guide.html
index fd3f0a75a..3c03f28ce 100644
--- a/doc/guide.html
+++ b/doc/guide.html
@@ -4058,9 +4058,6 @@ Binary Installer
- New binary installer for Windows including all requirements.
- Improved installers for Linux and MacOSX (PowerPC)
-
-- Anonymous login bugfixes.
-
XMPP Compliancy
- Some protocol compliance fix have been added, after the Portland XMPP
@@ -4076,6 +4073,7 @@ Miscelanous
Bugfixes
+ - Anonymous login bugfixes.
- Please refer to the ChangeLog file supplied with this release regarding
all improvements in ejabberd.
diff --git a/doc/release_notes_1.1.2.txt b/doc/release_notes_1.1.2.txt
index bca68127d..e7c8f3551 100644
--- a/doc/release_notes_1.1.2.txt
+++ b/doc/release_notes_1.1.2.txt
@@ -63,9 +63,6 @@ Binary Installer
- New binary installer for Windows including all requirements.
- Improved installers for Linux and MacOSX (PowerPC)
-
-- Anonymous login bugfixes.
-
XMPP Compliancy
- Some protocol compliance fix have been added, after the Portland XMPP
@@ -81,6 +78,7 @@ Miscelanous
Bugfixes
+ - Anonymous login bugfixes.
- Please refer to the ChangeLog file supplied with this release regarding
all improvements in ejabberd.
diff --git a/ejabberd-1.1.2/COPYING b/ejabberd-1.1.2/COPYING
deleted file mode 100644
index 8b325f530..000000000
--- a/ejabberd-1.1.2/COPYING
+++ /dev/null
@@ -1,343 +0,0 @@
-As a special exception, the authors give permission to link this program
-with the OpenSSL library and distribute the resulting binary.
-
- 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
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- 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
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- 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
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- 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
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-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
-Public License instead of this License.
diff --git a/ejabberd-1.1.2/ChangeLog b/ejabberd-1.1.2/ChangeLog
deleted file mode 100644
index 17c093ceb..000000000
--- a/ejabberd-1.1.2/ChangeLog
+++ /dev/null
@@ -1,3393 +0,0 @@
-2006-09-27 Mickael Remond <mickael.remond@process-one.net>
-
- * doc/release_notes_1.1.2.txt: Minor fixes.
-
- * doc/guide.tex: Fixed Latexish typos.
-
-2006-09-26 Mickael Remond <mickael.remond@process-one.net>
-
- * doc/release_notes_1.1.2.txt: Draft release notes.
-
- * src/msgs/pl.msg: Updated (thanks to Andrzej Smyk).
-
- * src/ejabberd_s2s.erl: Added incoming-s2s-number and
- outgoing-s2s-number ejabberdctl commands
-
- * src/mod_muc/mod_muc_room.erl: Minor english update.
- * src/msgs/pl.msg: Likewise.
- * src/msgs/uk.msg: Likewise.
- * src/msgs/pt-br.msg: Likewise.
- * src/msgs/cs.msg: Likewise.
- * src/msgs/ru.msg: Likewise.
- * src/msgs/es.msg: Likewise.
- * src/msgs/fr.msg: Likewise.
- * src/msgs/de.msg: Likewise.
- * src/msgs/nl.msg: Likewise.
-
- * src/msgs/pt-br.msg: Updated Brazilian translation (thanks to
- Renato Botelho) and clean-up.
-
-2006-09-25 Mickael Remond <mickael.remond@process-one.net>
-
- * src/msgs/de.msg: Updated German translation (thanks to Nikolaus
- Polak).
-
- * src/ejabberd.app: Version update for ejabberd 1.1.2.
-
- * src/msgs/pl.msg: Updated Polish translation (thanks to Zbyszek
- Zolkiewski).
-
- * src/msgs/de.msg: Updated German translation (thanks to Marvin
- Preuss).
-
- * src/msgs/nl.msg: Updated Dutch translation (thanks to Sander
- Devrieze).
-
- * src/msgs/cs.msg: Updated Czech translation and removed unused
- strings.
-
- * doc/introduction.tex: Minor doc updates for release 1.1.2.
-
-2006-09-24 Mickael Remond <mickael.remond@process-one.net>
-
- * src/msgs/es.msg: Updated Spanish translation (thanks to Badlop).
-
- * src/mod_muc/mod_muc_room.erl: Strings update (thanks to Serguei
- Golovan).
- * src/msgs/ru.msg: Updated Russian translation (thanks to Serguei
- Golovan).
- * src/msgs/uk.msg: Updated Ukrainian translation (thanks to Serguei
- Golovan).
- * src/msgs/fr.msg: Updated French translation.
-
- * src/doc/guide.html: Minor W3C compliance fix in an Hevea
- generated URL.
-
- * src/doc/features.html: Added to be consistent (guide.html is in the
- repository to make Latex optional, but still allow access to the doc).
-
-2006-09-23 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd.hrl: Updated to version 1.1.2
-
-2006-09-23 Alexey Shchepin <alexey@sevcom.net>
-
- * src/eldap/eldap.erl: Enable the keepalive socket option (thanks
- to Evgeniy Khramtsov)
-
- * src/ejabberd_auth_ldap.erl: Now uses two LDAP connections
- (thanks to Evgeniy Khramtsov)
-
- * src/eldap/eldap_filter.erl: Bugfix (thanks to Evgeniy Khramtsov)
- * src/mod_vcard_ldap.erl: Likewise
-
-2006-09-22 Mickael Remond <mickael.remond@process-one.net>
-
- * src/msgs/cs.msg: Added Czech translation (thanks to Milos Svasek).
-
- * src/mod_muc/mod_muc.erl: Component name is now more user friendly
- (thanks to Badlop).
- * src/mod_irc/mod_irc.erl: Likewise.
- * src/mod_pubsub/mod_pubsub.erl: Likewise.
-
- * src/msgs/fr.msg: updated French translation.
-
- * doc/guide.tex: Large improvements for ejabberd 1.1.2 (thanks to
- Sander Devrieze)
- * doc/version.tex: Likewise.
- * doc/features.tex: Likewise.
- * doc/Makefile: Likewise.
- * doc/dev.tex: Likewise.
-
-2006-09-14 Mickael Remond <mickael.remond@process-one.net>
-
- * doc/guide.tex: Minor fix on index generation.
-
-2006-09-14 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Updated (thanks to Evgeniy Khramtsov)
-
- * src/ejabberd_auth_ldap.erl: Better LDAP support (thanks to
- Evgeniy Khramtsov)
- * src/mod_vcard_ldap.erl: Likewise
- * src/eldap/eldap_filter.erl: Likewise
-
-2006-09-11 Mickael Remond <mickael.remond@process-one.net>
-
- * src/odbc/mssql.sql: Removed unused fields.
-
-2006-09-10 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejd2odbc.erl: Updated
-
- * src/mod_muc/mod_muc_log.erl: Fixed html special characters
- escaping, added new image buttons, chatroom titles now point to
- xmpp: URIs (thanks to Badlop)
-
-2006-09-05 Mickael Remond <mickael.remond@process-one.net>
-
- * src/mod_muc/mod_muc.erl: It is now possible to configure the MUC room
- history feature. A new option has been added in ejabberd muc module
- configuration (history_size) to define the size of the history. 0 is
- used to disable the feature.
- * src/mod_muc/mod_muc_room.erl: Likewise.
- * doc/guide.tex: Likewise.
-
-2006-09-05 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_shared_roster.erl: Bugfix
-
- * src/mod_roster_odbc.erl: Bugfix
-
-2006-09-03 Mickael Remond <mickael.remond@process-one.net>
-
- * src/odbc/odbc_queries.erl: Support for Microsoft SQL Server as a
- database backend (via ODBC).
- * src/odbc/ejabberd_odbc.erl: Likewise.
- * src/odbc/mssql.sql: Likewise.
- * src/odbc/Makefile.in: Likewise.
- * src/ejabberd_auth_odbc.erl: Likewise.
- * src/mod_offline_odbc.erl: Likewise.
- * src/mod_roster_odbc.erl: Likewise.
- * src/mod_last_odbc.erl: Likewise.
- * src/configure.ac: Likewise
- * doc/guide.tex: Likewise.
- * doc/introduction.tex: Likewise.
- * src/odbc/pg.sql: Minor fix.
-
-2006-08-28 Mickael Remond <mickael.remond@process-one.net>
-
- * Makefile.in: Fix for MacOSX compilation.
- * ejabberd_zlib/Makefile.in: Likewise.
- * mod_irc/Makefile.in: Likewise.
- * stringprep/Makefile.in: Likewise.
- * tls/Makefile.in: Likewise.
-
- * src/ejabberd.app: Updated to the current version.
-
-2006-08-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Fixed logging configuring
- permission check
-
-2006-08-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_router.erl: Now filter_packet hook works in
- 'global' context
-
-2006-08-04 Alexey Shchepin <alexey@sevcom.net>
-
- * src/tls/tls_drv.c: Report OpenSSL error messages (thanks to
- Magnus Henoch)
-
- * src/mod_muc/mod_muc_room.erl: Use standardized MUC room
- configuration fields (thanks to Magnus Henoch and Andy Turner)
-
-2006-08-02 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_roster_odbc.erl: Bugfix
-
-2006-07-28 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd_c2s.erl: Bugfix: added a missing catch and fixed the
- error code used on unknown namespace.
- * src/ejabberd_s2s_out.erl: Improved s2s connection negociation
- (dialback namespace usage) when using tls.
- * src/ejabberd_sm.erl: Fixed the error code used on unknown namespace.
- * src/mod_register.erl: ejabberd now sends iq result and stream end on
- user remove.
-
-2006-07-16 Mickael Remond <mickael.remond@process-one.net>
-
- * src/acl.erl: The server does not crash anymore on wrong acl rule. Add
- rule error message in log file.
-
-2006-07-07 Mickael Remond <mickael.remond@process-one.net>
-
- * src/web/ejabberd_web_admin.erl: User creation form now creates the
- user for the current virual host only and does not require to type
- the hostname.
- * src/jlib.erl: String to JID conversion now returns an error if the
- JID string contains two arobases.
-
-2006-07-06 Mickael Remond <mickael.remond@process-one.net>
-
- * src/mod_shared_roster.erl: Shared roster entries can now be moved or
- rename from a client without breaking current presence status.
- * src/mod_roster.erl: Likewise.
- * src/mod_roster_odbc.erl: Likewise.
-
- * src/mod_muc/mod_muc_room.erl: Fixed the order in which room presence
- packets are sent (First existing presence to new occupant, then new
- occupant presence to existing users.
-
-2006-07-05 Mickael Remond <mickael.remond@process-one.net>
-
- * src/web/ejabberd_web_admin.erl: More flexible parsing the shared
- roster members list from the configuration form.
- * src/mod_shared_roster.erl: Deletng a shared roster group now
- correctly deletes its user entries.
-
- * src/mod_shared_roster.erl: The logged user (self) is now removed from
- the shared roster list.
- * src/ejabberd_auth.erl: Better handling of errors when the server for
- authentication is unknown.
-
-2006-06-19 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_s2s_in.erl: Removed needless check for xmlns:db
- when starttls is enabled
-
-2006-06-15 Mickael Remond <mickael.remond@process-one.net>
-
- * src/web/ejabberd_http_poll.erl: Bugfix: using tuple instead of a Pid
- to send Erlang messages in a rarely used case.
-
-2006-06-13 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd_auth.erl: Fixed broken multiple connection with
- anonymous login problem.
- * src/ejabberd_auth_anonymous.erl: Likewise.
-
-2006-06-07 Mickael Remond <mickael.remond@process-one.net>
-
- * src/mod_pubsub/mod_pubsub.erl: Support for pubsub node creation
- ACL. It is now possible to limit the node creation rights using an
- ACL from ejabberd config file (Thanks to Christophe Romain).
- * doc/guide.tex: Likewise.
- * src/ejabberd.cfg.example.
-
- * src/mod_pubsub/mod_pubsub.erl: Discovery query on an item does
- no more return an "item not found error". Discovery stop correctly
- at the item level (Thanks to Christophe Romain).
-
-2006-06-02 Mickael Remond <mickael.remond@process-one.net>
-
- * src/web/ejabberd_http_poll.erl: Messages polled between the
- the last client request and the polling timeout were lost. Those
- messages are now resent using ejabberd routing mechanisms.
-
- * src/web/ejabberd_http.erl: The web module now accepts HTTP
- absolute URL (used behind a proxy). This apply to HTTP polling and
- to the web interface (Thanks to Jean-Sebastien Pedron).
-
-2006-05-29 Mickael Remond <mickael.remond@process-one.net>
-
- * src/mod_roster.erl: According to RFC3921 section 9.2, outbound
- subscribe presence packets must be sent, even if the user has already
- asked for subcription previously (subscription: none and pending: out).
- The mod_roster now conforms to this behaviour.
- * src/mod_roster_odbc.erl: Likewise.
-
-2006-05-27 Mickael Remond <mickael.remond@process-one.net>
-
- * src/configure.ac: Added an optional check for krb5.h in
- configure. ejabberd can now be build directly on RedHat and
- OpenBSD.
-
-2006-05-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/sk.msg: Slovak translation (thanks to Juraj Michalek
- and SkLUG)
-
-2006-05-26 Alexey Shchepin <alexey@sevcom.net>
-
- * src/odbc/pg.sql: Updated
-
- * src/mod_shared_roster.erl: Updated
-
- * src/ejabberd_sm.erl: Bugfix
-
- * src/mod_roster.erl: Bugfix
- * src/mod_roster_odbc.erl: Likewise
-
-2006-05-23 Mickael Remond <mickael.remond@process-one.net>
-
- * src/mod_roster.erl: The subscribe request are now resend at login as
- long as they have not been answered. mod_roster do no more depends on
- mod_offline.
- * src/ejabberd_sm.erl: Likewise.
- * src/ejabberd_c2s.erl: Likewise.
- * src/mod_roster_odbc.erl: Likewise (The ODBC/relational support has
- not yet been tested).
- * src/mod_roster.hrl: Likewise.
- * src/mod_offline.erl: Likewise.
- * src/mod_offline_odbc.erl: Likewise.
- * odbc/pg.sql: Likewise.
- * odbc/mysql.sql: Likewise.
-
-2006-05-22 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd_sm.erl: The max_user_sessions has been moved to
- host configuration.
- * src/ejabberd.cfg.example: Likewise.
- * doc/guide.tex: Likewise.
-
-2006-05-21 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd_sm.erl: An option to limit the number of opened sessions
- for a given user have been added. As a default, a given user can only
- log in 10 times with different resources. After that, new connections
- replace the older ones.
- * src/ejabberd.cfg.example: Likewise.
- * doc/guide.tex: Likewise.
-
-2006-05-15 Mickael Remond <mickael.remond@process-one.net>
-
- * src/web/ejabberd_http_poll.erl: Timeout disconnection were not
- properly handled after "active once" migration. This is now fixed.
-
-2006-05-07 Mickael Remond <mickael.remond@process-one.net>
-
- * src/mod_configure.erl: Unknown tables or tables from now unused
- modules are ignored during restore. The restore can now be performed in
- such case.
- * src/web/ejabberd_web_admin.erl: Likewise.
- * src/ejabberd_admin.erl: Code refactoring. Common Mnesia database
- restore function.
-
- * src/ejabberd_ctl.erl: Now prints a user-friendly when trying to
- restore a backup from a non-existent file.
-
- * src/ejabberd_ctl.erl: Added a way to delete the older message
- from the offline message table. This function is only available if
- offline message queue is stored in Mnesia internal database. The
- function delete_old_messages is not available in mod_offline_odbc.
-
-2006-05-01 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd_ctl.erl: Unknown tables or tables from now unused
- modules are ignored during restore. The restore can now be performed in
- such case.
-
-2006-04-28 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd.hrl: release 1.1.1
- * doc/version.tex: Likewise
- * doc/guide.tex: Likewise
-
-2006-04-28 Alexey Shchepin <alexey@sevcom.net>
-
- * src/cyrsasl.erl: Bugfix: anonymous authentication was always
- enabled
-
-2006-04-27 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd_ctl.erl: The status now only returns "started" if
- ejabberd is started and ready to accept requests.
-
-2006-04-24 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Added a documentation for max_stanza_size option
-
-2006-04-24 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd.hrl: Updated for version 1.1.0.
-
-2006-04-23 Alexey Shchepin <alexey@sevcom.net>
-
- * src/configure: Removed '==' bashism (thanks to Magnus Henoch)
- * src/aclocal.m4: Likewise
-
- * src/ejabberd_c2s.erl: Resend messages when leaving negative
- presence state (thanks to Magnus Henoch)
-
-2006-04-23 Mickael Remond <mickael.remond@process-one.net>
-
- * src/msgs/fr.msg: Updated
- * src/msgs/de.msg: Updated (thanks to Nikolaus Polak)
- * src/ejabberd_sm.erl: Now delivering messages to all resources with
- max equal priority when this priority is non-negative.
-
- * src/guide.tex: Added documentation for native database configuration.
-
-2006-04-22 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/pt-br.msg: Updated (thanks to Lucius Curado)
-
- * src/xml_stream.erl: Support for stanza size limit (thanks to
- Igor Goryachev)
- * src/ejabberd_receiver.erl: Likewise
- * src/ejabberd_c2s.erl: Likewise
- * src/ejabberd_s2s_in.erl: Likewise
- * src/ejabberd.cfg.example: Updated
-
- * src/ejabberd_auth.erl: Fixed try_register/3 behaviour
-
-2006-04-20 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd.cfg.example: Update of the example for anonymous.
- Removed unnecessary parameter.
- * src/ejabberd_auth_anonymous.erl: Removed unnecessary parameter /
- bugfix.
- * src/ejabberd_auth.erl: Bugfix: We now are forced to check is an
- anonymous user is log under a given user name before trying to
- register it.
- * doc/guide.tex: Updated (SASL anonymous and anonymous login).
-
-2006-04-19 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/pl.msg: Updated (thanks to Andrzej Smyk)
-
-2006-04-13 Alexey Shchepin <alexey@sevcom.net>
-
- * src/xml_stream.erl: Cleanup
-
- * src/ejabberd_service.erl: Updated to use ejabberd_receiver
-
-2006-04-12 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Minor fix
-
- * src/ejabberd_c2s.erl: Bugfix (thanks to Sergei Golovan)
-
- * doc/guide.tex: Updated (thanks to Sergei Golovan)
-
- * src/msgs/nl.msg: Updated (thanks to Sander Devrieze)
-
-2006-04-11 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/es.msg: Updated (thanks to Badlop)
-
- * src/ejabberd.cfg.example: Updated (thanks to Badlop)
-
- * doc/guide.tex: Updated (thanks to Badlop)
-
-2006-04-07 Mickael Remond <mickael.remond@process-one.net>
-
- * src/mod_pubsub/mod_pubsub.erl: Fixed pubsub root node creation
- (conflict error was send on node creation)
-
-2006-04-07 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_sm.erl: SASL Anonymous + Anonymous login support
- (thanks to Mickael Remond and Magnus Henoch)
- * src/ejabberd_c2s.erl: Likewise
- * src/ejabberd_auth.erl: Likewise
- * src/ejabberd_auth_anonymous.erl: Likewise
- * src/cyrsasl.erl: Likewise
- * src/cyrsasl_anonymous.erl: Likewise
- * src/ejabberd.cfg.example: Likewise
-
-2006-04-06 Alexey Shchepin <alexey@sevcom.net>
-
- * src/expat_erl.c: Use binaries for CDATA
- * src/xml.erl: Likewise
-
-2006-04-02 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
- * src/msgs/uk.msg: Likewise
-
- * src/mod_configure.erl: Updated translation strings (thanks to
- Sergei Golovan)
- * src/web/ejabberd_web_admin.erl: Likewise
-
- * src/ejabberd_s2s_in.erl: Changed a path to PKIX includes (thanks
- to Sergei Golovan)
-
-2006-04-01 Mickael Remond <mickael.remond@process-one.net>
-
- * src/Makefile.in: Added an option to compile ejabberd with debug
- print-out (make ejabberd_debug=true).
- * src/ejabberd_c2s.erl: Added a new debug printout: We can now print
- the XML packets send by the server.
-
-2006-03-31 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Bugfix
-
-2006-03-25 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Enable zlib only over TCP
-
-2006-03-18 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Bugfix (thanks to Sergei Golovan)
-
-2006-03-17 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_privacy.erl: Fixed privacy list pushing (thanks to
- Sergei Golovan)
- * src/ejabberd_c2s.erl: Likewise
-
-2006-03-16 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd_sm.erl: Remove unnecessary use delete_object, which can,
- in some context break indexes, when used on non bag table.
-
-2006-03-16 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Bugfix
-
-2006-03-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/xml_stream.erl: Added catching of gen_fsm:send_event errors
-
- * src/ejabberd_s2s_out.erl: Better support for multiple SRV
- records (thanks to Sergei Golovan)
-
- * src/mod_muc/mod_muc_log.erl: Support for chatroom logging
- (thanks to Badlop)
- * src/mod_muc/mod_muc_room.erl: Likewise
- * src/mod_muc/Makefile.in: Likewise
- * src/mod_muc/Makefile.win32: Likewise
-
-2006-03-11 Alexey Shchepin <alexey@sevcom.net>
-
- * src/gen_iq_handler.erl: Added support for {queues, N} IQ handler
- type
-
-2006-03-06 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Bugfix
-
-2006-03-05 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Bugfix
-
- * src/ejabberd_auth_odbc.erl: Bugfix
-
-2006-03-04 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd_logger_h.erl: reopen-log function now rename the log
- file if it has not been already renamed by a logrotate process. This
- change allow ejabberd administrators to rotate log files on Windows
- (EJAB-52).
-
-2006-02-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Added a interface for node
- updating
- * src/ejabberd_update.erl: Added function update_info/0
-
-2006-02-25 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
- * src/msgs/uk.msg: Likewise
-
- * contrib/extract_translations/extract_translations.erl: Minor
- update (thanks to Sergei Golovan)
-
- * src/ejabberd_zlib/Makefile.win32: Zlib support for Windows build
- (thanks to Sergei Golovan)
- * src/Makefile.win32: Likewise
- * src/configure.erl: Likewise
-
-2006-02-20 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_ctl.erl: Added API for virtual host specific
- commands, removed registered-users command
- * src/ejabberd_auth.erl: Added processing of registered-users
- command
- * src/ejabberd_auth_internal.erl: Likewise
- * src/ejabberd_auth_ldap.erl: Likewise
- * src/ejabberd_auth_odbc.erl: Likewise
- * src/ejabberd_app.erl: Added inititalization of ejabberd_ctl
- * src/ejabberd_sm.erl: Minor update
-
-2006-02-18 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/mod_irc_connection.erl: Added handling for "%", "&"
- and "~" prefixes in IRC nicknames (thanks to Vladimir Kulev)
-
- * src/mod_irc/mod_irc_connection.erl: Added /msg and /ctcp
- commands, improved handling of channel topic and kick, mirc colors
- now filtered, other minor improvements (thanks to Oleg V. Motienko
- and Magnus Henoch)
-
- * src/mod_configure.erl: Improved strings (thanks to Sander
- Devrieze)
- * src/mod_vcard.erl: Likewise
- * src/mod_vcard_ldap.erl: Likewise
- * src/mod_vcard_odbc.erl: Likewise
- * src/web/ejabberd_web_admin.erl: Likewise
-
-2006-02-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_service_log.erl: Bugfix (thanks to Badlop)
-
- * src/jd2ejd.erl: Use mod_vcard_odbc if it is loaded (thanks to
- Tomasz Sterna)
-
-2006-02-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_sm.erl: Added a few ejabberdctl commands
-
- * src/ejabberd_ctl.erl: New interface for command registration
-
-2006-02-13 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_ctl.erl: Partially rewritten
- * src/ejabberd_ctl.hrl: Definitions of exit status codes moved
- here
-
-2006-02-12 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_roster_odbc.erl: Bugfix
-
-2006-02-08 Alexey Shchepin <alexey@sevcom.net>
-
- * src/odbc/ejabberd_odbc.erl: Reconnect on ODBC connection closing
-
-2006-02-07 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd_auth.erl: plugin authentication modules can now
- be used in the configuration file: {auth_method, module} will now
- use the module ejabberd_auth_module.erl for authentication.
-
-2006-02-05 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Kick non-members when room
- reconfigured to be member-only or when membership is revoked in
- member-only room, allowed "true" and "false" in x:data forms
- (thanks to Sergei Golovan)
-
- * src/mod_configure.erl: Added "Host" parameter to get_form and
- set_form functions (thanks to Sergei Golovan)
-
- * src/ejabberd_s2s_out.erl: Bugfix
-
- * src/msgs/es.msg: Updated (thanks to Badlop)
-
- * src/web/ejabberd_web.erl: Bugfix (thanks to Badlop)
-
- * src/mod_irc/mod_irc.erl: Updated copyright dates
- * src/mod_muc/mod_muc.erl: Likewise
- * src/mod_pubsub/mod_pubsub.erl: Likewise
- * src/mod_vcard.erl: Likewise
- * src/mod_vcard_ldap.erl: Likewise
- * src/mod_vcard_odbc.erl: Likewise
- * src/web/ejabberd_web_admin.erl: Likewise
-
-2006-02-03 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_auth_odbc.erl: Added ejabberd_odbc_sup to ejabberd
- supervision tree
-
- * src/web/ejabberd_http.erl: Authentication check moved to
- ejabberd_web.erl
- * src/web/ejabberd_web.erl: Likewise
-
- * src/web/Makefile.in: Added ejabberd_http.hrl dependency
-
- * src/web/ejabberd_http_poll.erl: Updated to use {active, once}
- socket mode
-
- * src/mod_irc/mod_irc.erl: Updated to use gen_server behaviour and
- ejabberd supervision tree
- * src/mod_irc/mod_irc_connection.erl: Likewise
-
-2006-02-02 Mickael Remond <mickael.remond@process-one.net>
-
- * src/configure.ac: --prefix option can now override the default
- install dir
- * src/configure: Likewise
- * src/Makefile.in: Likewise
-
-2006-02-02 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_pubsub/mod_pubsub.erl: Updated to use gen_server
- behaviour and ejabberd supervision tree
- * src/mod_echo.erl: Likewise
-
-2006-02-01 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc.erl: Added a supervisor for conference room
- processes
- * src/mod_muc/mod_muc_room.erl: Likewise
-
-2006-01-29 Alexey Shchepin <alexey@sevcom.net>
-
- * src/odbc/pg.sql: Fixed syntax error
-
-2006-01-28 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_router.erl: Updated to use gen_server behaviour
- * src/ejabberd_sm.erl: Likewise
- * src/ejabberd_s2s.erl: Likewise
- * src/gen_iq_handler.erl: Likewise
-
- * src/ejabberd_sup.erl: Added supervisor for ejabberd_receiver
- * src/ejabberd_receiver.erl: Updated
-
-2006-01-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_update.erl: Support for run-time ejabberd updating
- (not completed)
- * src/ejabberd_c2s.erl: Added 'update_info' module attribute for
- testing ejabberd_update
-
-2006-01-25 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Remove top-level xmlns from incoming
- stanzas
- * src/ejabberd_s2s_in.erl: Likewise
- * src/ejabberd_service.erl: Likewise
-
- * src/ejabberd_c2s.erl: Better error handling for stream
- compression support (thanks to Sergei Golovan)
-
-2006-01-24 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_roster_odbc.erl: Bugfix
-
-2006-01-23 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_sm.erl: Partially rewritten to work more
- efficiently and avoid race conditions
- * src/ejabberd_c2s.erl: Likewise
-
-2006-01-21 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/mod_irc_connection.erl: Cleanup
-
-2006-01-20 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd_receiver.erl: Added new debugging trace: It is now
- possible to dump the XML stream received from a client (usefull for
- client debugging).
-
-2006-01-19 Alexey Shchepin <alexey@sevcom.net>
-
- * src/aclocal.m4: Updated for zlib support
- * src/configure.ac: Likewise
-
- * src/mod_muc/mod_muc_room.erl: Weakened presence filtering, added
- warning in non-anonymous rooms, room destroying updated to latest
- JEP-0045, added a number of occupants and room name in room's
- disco#info reply, miscellaneous internal changes (thanks to Sergei
- Golovan)
-
- * src/mod_muc/mod_muc.erl: Better support for nick unregistration
- (thanks to Sergei Golovan)
-
- * src/ejabberd_zlib/ejabberd_zlib.erl: Zlib support (thanks to
- Sergei Golovan)
- * src/ejabberd_zlib/ejabberd_zlib_drv.c: Likewise
- * src/ejabberd_zlib/Makefile.in: Likewise
- * src/ejabberd_c2s.erl: Stream compression support (JEP-0138)
- * src/ejabberd_receiver.erl: Likewise
-
- * src/mod_disco.erl: Don't split node name before calling hooks
- (thanks to Sergei Golovan)
-
- * src/mod_configure.erl: Support for configuration using ad-hoc
- commands (thanks to Sergei Golovan)
-
- * src/mod_announce.erl: Support for sending announce messages
- using ad-hoc commands (thanks to Sergei Golovan)
-
- * src/mod_adhoc.erl: Ad-hoc support (JEP-0050) (thanks to Magnus
- Henoch)
- * src/adhoc.erl: Likewise
- * src/adhoc.hrl: Likewise
-
- * src/jlib.hrl: Updated (thanks to Sergei Golovan)
-
- * src/gen_mod.erl: Added function is_loaded/2 (thanks to Sergei
- Golovan)
-
- * src/ejabberd_service.erl: Changed error message on handshake
- error (thanks to Sergei Golovan)
-
- * src/ejabberd.cfg.example: Updated (thanks to Sergei Golovan)
-
-2006-01-13 Mickael Remond <mickael.remond@process-one.net>
-
- * src/odbc/ejabberd_odbc.erl: underscore and percent are now only
- escaped in like queries. MySQL where not escaping those escaped
- characters in other context.
- * src/mod_vcard_odbc.erl: likewise.
- * src/odbc/mysql.sql: Fixed MySQL database creation script: Was
- not properly working with all MySQL version.
- * src/odbc/ejabberd_odbc.erl: Added a way to retry database
- connection connect for 5 minutes when the connection is lost. No
- further connection is retry after.
- * src/odbc/ejabberd_odbc_sup.erl: likewise.
-
-2006-01-13 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_service.erl: Bugfix
-
- * src/ejabberd_receiver.erl: Rewritten to use {active, once} mode
- for socket
- * src/ejabberd_c2s.erl: Update
- * src/ejabberd_listener.erl: Likewise
- * src/ejabberd_s2s_in.erl: Likewise
- * src/ejabberd_s2s_out.erl: Likewise
- * src/ejabberd_service.erl: Likewise
- * src/shaper.erl: Likewise
- * src/tls/tls.erl: Likewise
- * src/web/ejabberd_http.erl: Likewise
-
-2006-01-02 Mickael Remond <mickael.remond@process-one.net>
-
- * src/odbc/ejabberd_odbc.erl: Native MySQL support
-
-2005-12-24 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_logger_h.erl: Speed optimizations
-
-2005-12-22 Alexey Shchepin <alexey@sevcom.net>
-
- * src/Makefile.in: Clean results of ASN.1 compiler (thanks to
- Sergei Golovan)
-
- * src/win32/ejabberd.nsh: Removed (thanks to Sergei Golovan)
-
-2005-12-22 Mickael Remond <mickael.remond@process-one.net>
-
- * src/odbc/ejabberd_odbc.erl: Added error message on ODBC
- connection to help ODBC configuration troubleshooting.
-
-2005-12-22 Alexey Shchepin <alexey@sevcom.net>
-
- * src/Makefile.win32: Updated (thanks to Sergei Golovan)
- * src/configure.erl: Likewise
- * src/win32/CheckReqs.ini: Likewise
- * src/win32/CheckReqs1.ini: Likewise
- * src/win32/CheckReqs1H.ini: Likewise
- * src/win32/ejabberd.nsh: Likewise
- * src/win32/ejabberd.nsi: Likewise
-
- * src/odbc/ejabberd_odbc.erl: Bugfix
-
-2005-12-21 Mickael Remond <mickael.remond@process-one.net>
-
- * src/odbc/mysql.sql: Database description for MySQL Database 4.1
- (Max version, with Innodb)
- * src/ejabberd_auth_odbc.erl: MySQL ODBC support
- * src/mod_offline_odbc.erl: Likewise
- * src/mod_vcard_odbc.erl: Likewsie
- * src/mod_roster_odbc.erl: Likewise
- * src/odbc/ejabberd_odbc.erl: Likewise
- * src/mod_last_odbc.erl: Likewise
-
-2005-12-16 Mickael Remond <mickael.remond@process-one.net>
-
- * doc/Makefile: Added helper to generate the docs (Thanks to Sander
- Devrieze)
- * doc/guide.tex: Added ejabberd 1.0.0 release notes.
- * doc/dev.tex: Code clean-up (Thanks to Sander Devrieze)
-
-2005-12-16 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/features.tex: Added feature sheet (Thanks to Sander
- Devrieze)
-
-2005-12-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/iconv_erl.c: Bugfix (thanks to Tomas Janousek)
-
-2005-12-13 Alexey Shchepin <alexey@sevcom.net>
-
- * src/win32/ejabberd.nsi: Updated (thanks to Maxim Ryazanov)
-
- * src/ejabberd.hrl: Updated version
- * src/ejabberd.app: Likewise
- * doc/version.tex: Likewise
-
-2005-12-13 Mickael Remond <mickael.remond@process-one.net>
-
- * doc/release_notes_1.0.0.txt: Added preliminary version of ejabberd
- 1.0.0 release notes.
- * doc/guide.html: Generated the updated HTML version of the documentation.
-
-2005-12-11 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_roster.erl: Workaround for gateway subscriptions now
- should be enabled with --enable-roster-gateway-workaround
- * src/mod_roster_odbc.erl: Likewise
- * src/configure.ac: Likewise
- * src/Makefile.in: Likewise
-
-2005-12-10 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_service.erl: Added logging of termination
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
- * src/msgs/uk.msg: Likewise
-
- * src/msgs/*.msg: Updated (thanks to Badlop)
-
-2005-12-08 Mickael Remond <mickael.remond@process-one.net>
-
- * contribs/contrib/extract_translations/prepare-translation.sh:
- Small improvements.
- * src/msgs/fr.msg: Updated
-
-2005-12-07 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/pl.msg: Fixed syntax error
-
- * src/mod_offline.erl: Don't store headline messages
- * src/mod_offline_odbc.erl: Likewise
-
-2005-12-06 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Updated
-
-2005-12-06 Mickael Remond <mickael.remond@process-one.net>
-
- * src/ejabberd.cfg.example: Updated
-
- * src/Makefile.*: Can now be build when the Erlang environment is
- not Erlang/OTP but the Erlang REPOS CDROM. Still compatible with
- standard Erlang/OTP install
- * aclocal.m4: Likewise
- * src/Makefile.*: Can now be build with Erlang debug_info with
- 'make debug=true'
-
-2005-12-06 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/pt-br.msg: Updated (thanks to Victor Hugo dos Santos)
-
- * src/msgs/pl.msg: Updated (thanks to Andrzej Smyk)
-
- * src/msgs/sv.msg: Updated (thanks to Magnus Henoch)
-
- * src/msgs/de.msg: Updated (thanks to Patrick Dreker)
-
-2005-11-30 Mickael Remond <mickael.remond@process-one.net>
-
- * doc/yozhikheader.png: Added feature sheet header (Thanks to Sander
- Devrieze)
-
-2005-11-28 Mickael Remond <mickael.remond@process-one.net>
-
- * doc/guide.tex: Improved and updated documentation (Thanks to Sander
- Devrieze)
- * doc/guide.html: Likewise
- * doc/features.tex: Likewise
- * doc/introduction.tex: Likewise
- * doc/version.tex: Likewise
- * doc/logo.png: New logo for ejabberd doc (Thanks to Sander Devrieze)
-
-2005-11-26 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_http.erl: Now web interface is compliant to
- XHTML 1.0 Transitional (thanks to Sander Devrieze)
- * src/web/ejabberd_web_admin.erl: Likewise
-
-2005-11-25 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/Makefile: Now really added
-
-2005-11-22 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_roster.erl: The "id" attribute of roster push packet was
- missed (thanks to Maxim Ryazanov)
- * src/mod_roster_odbc.erl: Likewise
-
- * src/web/ejabberd_web_admin.erl: Fixed encoding of user names in
- URLs
-
- * src/web/ejabberd_http.erl: Added url_encode function from yaws
-
- * src/ejabberd_c2s.erl: Send stream error when connection is
- replaced (thanks to Maxim Ryazanov)
-
-2005-11-19 Mickael Remond <mickael.remond@process-one.net>
-
- * contrib/extract_translations/prepare-translation.sh: Added
- wrapper to extract_translation.erl (thanks to Badlop)
-
-2005-11-19 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_vcard.erl: Fixed xmlns in disco items replies (thanks to
- Maxim Ryazanov)
- * src/mod_vcard_ldap.erl: Likewise
- * src/mod_vcard_odbc.erl: Likewise
-
- * src/tls/Makefile.in: Use CPPFLAGS (thanks to Magnus Henoch)
-
-2005-11-17 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_s2s_in.erl: Support for dNSName certificate field
- and DNS name matching
- * src/XmppAddr.asn1: Moved here from src/tls/XmppAddr.asn1
- * src/tls/XmppAddr.asn1: Likewise
- * src/Makefile.in: Updated
- * src/tls/Makefile.in: Updated
-
-2005-11-16 Alexey Shchepin <alexey@sevcom.net>
-
- * src/odbc/ejabberd_odbc.erl: Support for mnesia-like transaction
- interface
- * src/mod_roster_odbc.erl: Updated to use
- ejabberd_odbc:sql_transaction/2
-
-2005-11-12 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_s2s_out.erl: Fixed invalid behaviour upon
- connecting to host with invalid domain
- * src/ejabberd_s2s.erl: Likewise
-
-2005-11-05 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_config.erl: Support for per host certificates
- * src/ejabberd_c2s.erl: Likewise
- * src/ejabberd_s2s_out.erl: Likewise
- * src/ejabberd.cfg.example: Updated
-
- * src/ejabberd_s2s_in.erl: Fixed id-on-xmppAddr processing
-
-2005-11-03 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_disco.erl: Fixed extra_domains option processing
-
- * src/ejabberd_s2s_out.erl: Support for STARTTLS+SASL EXTERNAL
- (not well-tested yet)
- * src/ejabberd_s2s_in.erl: Likewise
- * src/tls/tls.erl: Likewise
- * src/tls/tls_drv.c: Likewise
- * src/tls/XmppAddr.asn1: Likewise
- * src/tls/Makefile.in: Likewise
-
-2005-10-30 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_disco.erl: Minor fix
-
-2005-10-29 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_roster_odbc.erl: Bugfix
-
-2005-10-25 Alexey Shchepin <alexey@sevcom.net>
-
- * src/tls/tls.erl: Accept {error,already_loaded} from
- erl_ddll:load_driver/2
- * src/stringprep/stringprep.erl: Likewise
- * src/mod_irc/iconv.erl: Likewise
- * src/ejabberd_app.erl: Likewise
-
- * src/tls/tls_drv.c: Support for "connect" method
- * src/tls/tls.erl: Likewise
-
- * src/ejabberd_s2s_in.erl: Support for STARTTLS+Dialback
- * src/ejabberd_s2s_out.erl: Likewise
- * src/ejabberd_receiver.erl: Added a few hacks ({active,once} mode
- should be used instead of recv/3 call to avoid them)
- * src/ejabberd_config.erl: Added s2s_use_starttls and s2s_certfile
- options
- * src/ejabberd.cfg.example: Likewise
-
-2005-10-22 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_app.erl: Try to load tls_drv at startup to avoid
- unloading of libssl (thanks to Brian Campbell)
-
-2005-10-20 Alexey Shchepin <alexey@sevcom.net>
-
- * src/odbc/pg.sql: Added spool.seq field for offline messages
- sorting
- * src/mod_offline_odbc.erl: Likewise
-
-2005-10-18 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_roster_odbc.erl: Bugfix
-
-2005-10-16 Alexey Shchepin <alexey@sevcom.net>
-
- * src/gen_iq_handler.erl: Bugfix
-
-2005-10-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_auth_odbc.erl: Minor fix
-
- * src/odbc/ejabberd_odbc.erl: Updated pgsql support
-
- * src/mod_roster_odbc.erl: Bugfix
-
- * src/ejabberd_c2s.erl: Updated to work correctly with
- mod_vcard_odbc
-
-2005-10-13 Alexey Shchepin <alexey@sevcom.net>
-
- * src/odbc/ejabberd_odbc.erl: Experimental support for pgsql
- library
-
- * src/ejabberd_auth_odbc.erl: Bugfix
-
- * src/mod_roster_odbc.erl: Bugfix
-
-2005-10-07 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejd2odbc.erl: Added vCard converter
-
- * src/mod_vcard_odbc.erl: vCard support via ODBC
-
- * src/odbc/pg.sql: Updated
-
-2005-09-18 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Updated API for better
- integration with J-EAI web interface
-
- * src/mod_shared_roster.erl: Now possible to specify all users on
- virtual host in group
- * src/web/ejabberd_web_admin.erl: Likewise
-
-2005-09-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/jlib.erl: Bugfix
-
-2005-09-10 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejd2odbc.erl: Updated
-
-2005-09-04 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_disco.erl: Disco publishing support (thanks to Magnus
- Henoch)
-
- * src/mod_disco.erl: Functions register_sm_feature and
- register_sm_node replaced with hooks (thanks to Sergei Golovan)
- * src/mod_vcard.erl: Updated
- * src/mod_vcard_ldap.erl: Likewise
-
- * src/mod_disco.erl: Now mod_disco doesn't depend on mod_configure
- (thanks to Sergei Golovan)
- * src/mod_configure.erl: Likewise
-
-2005-08-29 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejd2odbc.erl: Converter from mnesia to ODBC
-
- * src/mod_offline_odbc.erl: Minor fix
-
-2005-08-25 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_vcard_ldap.erl: Bugfix
-
- * src/mod_vcard.erl: Bugfix
-
-2005-08-23 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_auth_odbc.erl: Bugfix
-
-2005-08-21 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/dev.tex: Updated
-
-2005-08-11 Alexey Shchepin <alexey@sevcom.net>
-
- * src/cyrsasl_digest.erl: Fixed challenge/response parsing (thanks
- to Martin Pokorny)
-
-2005-08-07 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/pl.msg: Updated (thanks to Andrew Smyk)
-
- * src/web/ejabberd_web_admin.erl: Bugfix (thanks to Badlop)
-
-2005-08-05 Alexey Shchepin <alexey@sevcom.net>
-
- * src/win32/inetrc: Added (thanks to Sergei Golovan)
-
- * src/Makefile.win32: Updated (thanks to Sergei Golovan)
- * src/win32/ejabberd.cfg: Likewise
- * src/win32/ejabberd.nsi: Likewise
-
- * doc/guide.tex: Updated
-
- * src/ejabberd.hrl: Updated version
-
-2005-08-01 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
- * src/msgs/uk.msg: Likewise
-
- * src/msgs/es.msg: Updated (thanks to Badlop)
-
- * src/msgs/nl.msg: Updated (thanks to Sander Devrieze)
-
-2005-08-01 Mickael Remond <mremond@erlang-fr.org>
-
- * (all): ejabberd-0.9.8 released
-
- * src/msgs/fr.msg: Updated
-
-2005-07-31 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_config.erl: Added host_config option
- * doc/guide.tex: Updated
-
- * src/ejabberd_auth_ldap.erl: Bugfix
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
- * src/msgs/uk.msg: Likewise
-
- * src/msgs/de.msg: Updated (thanks to Torsten Werner)
-
- * src/web/ejabberd_web_admin.erl: Fixed CSS style sheet to be
- standards compliant (thanks to Sander Devrieze)
-
-2005-07-29 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Added "Virtual Hosts" page
-
-2005-07-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_router.erl: Added filter_packet hook
-
-2005-07-26 Alexey Shchepin <alexey@sevcom.net>
-
- * src/jd2ejd.erl: Updated to work with ODBC
-
- * src/mod_roster_odbc.erl: Updated
-
-2005-07-22 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_offline_odbc.erl: Bugfix
-
- * src/mod_last_odbc.erl: Bugfix
-
-2005-07-20 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_pubsub/mod_pubsub.erl: Updated to J-EAI version
-
-2005-07-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/acl.erl: Slightly changed "access" option processing
-
- * src/mod_disco.erl: Fixed processing of host features and
- extra_domains option
-
- * src/ejabberd_c2s.erl: Processing of jabber:iq:register totally
- moved to mod_register.erl (thanks to Sergei Golovan)
- * src/mod_register.erl: Likewise
-
- * src/win32/ejabberd.nsi: Added two pictures in installer (thanks
- to Maxim Ryazanov)
- * src/win32/ejabberd_header.bmp: Likewise
- * src/win32/ejabberd_intro.bmp: Likewise
-
- * src/web/ejabberd_web_admin.erl: Fixed spelling of word
- "authentication"
- * src/ejabberd_c2s.erl: Likewise
-
-2005-07-13 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_register.erl: Bugfix
-
- * src/mod_vcard.erl: Bugfix
-
- * src/ejabberd_app.erl: Updated to allow different authentication
- methods for different virtual hosts
- * src/ejabberd_auth.erl: Likewise
- * src/ejabberd_auth_external.erl: Likewise
- * src/ejabberd_auth_internal.erl: Likewise
- * src/ejabberd_auth_ldap.erl: Likewise
- * src/ejabberd_auth_odbc.erl: Likewise
- * src/cyrsasl.erl: Likewise
- * src/cyrsasl_digest.erl: Likewise
- * src/cyrsasl_plain.erl: Likewise
- * src/ejabberd_c2s.erl: Likewise
- * src/ejabberd_config.erl: Likewise
- * src/extauth.erl: Likewise
- * src/mod_last_odbc.erl: Likewise
- * src/mod_offline_odbc.erl: Likewise
- * src/mod_roster_odbc.erl: Likewise
- * src/odbc/ejabberd_odbc.erl: Likewise
- * src/odbc/ejabberd_odbc_sup.erl: Likewise
-
-2005-07-03 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_app.erl: Bugfix
-
- * src/ejabberd_config.erl: Bugfix
-
-2005-06-30 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_offline.erl: Bugfix
-
-2005-06-20 Alexey Shchepin <alexey@sevcom.net>
-
- * (all): Enhanced virtual hosting support
-
-2005-05-28 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Bugfix
-
-2005-05-25 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/pt-br.msg: New Brazilian Portuguese translation (thanks
- to Felipe Brito Vasconcellos)
-
-2005-05-23 Alexey Shchepin <alexey@sevcom.net>
-
- * (all): ejabberd-0.9.1 released
-
- * src/msgs/fr.msg: Updated (thanks to Mickael Remond)
-
- * src/odbc/Makefile.in: Added
-
- * src/configure.ac: Updated for odbc support
- * src/Makefile.in: Likewise
-
- * src/aclocal.m4: Bugfix
-
- * src/mod_last_odbc.erl: Added store_last_info/4 function (thanks
- to Sergei Golovan)
- * src/mod_last.erl: Likewise
-
- * src/jd2ejd.erl: Support for exporting iq:last information,
- better error handling (thanks to Sergei Golovan)
-
- * src/ejabberd_ctl.erl: Added "import-file" and "import-dir"
- commands (thanks to Sergei Golovan)
-
- * doc/guide.tex: Updated (thanks to Sergei Golovan)
- * doc/dev.tex: Likewise
- * doc/disco.png: Likewise
- * doc/discorus.png: Likewise
- * doc/webadmin.png: Likewise
- * doc/webadminru.png: Likewise
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
- * src/msgs/uk.msg: Likewise
-
- * src/web/ejabberd_web_admin.erl: Updated CSS, added modules
- management, fixed bug with configuring of listened ports on
- different nodes (thanks to Sergei Golovan)
-
- * src/gen_mod.erl: Added function loaded_modules_with_opts/0, new
- API for module stopping (thanks to Sergei Golovan)
- * src/mod_muc/mod_muc.erl: Moved a process name to a macros,
- updated module stopping (thanks to Sergei Golovan)
- * src/mod_irc/mod_irc.erl: Likewise
- * src/mod_pubsub/mod_pubsub.erl: Likewise
- * src/mod_announce.erl: Updated module stopping (thanks to Sergei
- Golovan)
- * src/mod_echo.erl: Likewise
- * src/mod_offline.erl: Likewise
-
- * src/web/ejabberd_http.erl: "Connection:" header value now
- matched case-insensitive, and returned to client, replaced
- duplicate is_space($\r) with is_space($\t) (thanks to Maxim
- Ryazanov)
-
-2005-05-21 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_pubsub/mod_pubsub.erl: Fixed XML element name for
- pubsub#event namespace (thanks to Magnus Henoch)
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
- * src/msgs/uk.msg: Likewise
-
- * src/msgs/es.msg: Updated (thanks to Badlop)
-
-2005-05-19 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_pubsub/mod_pubsub.erl: Now possible to subscribe to a
- pubsub node with a JID that includes a resource (thanks to Martijn
- van Beers)
-
- * src/stringprep/uni_parse2.tcl: Bugfix
- * src/stringprep/stringprep_drv.c: Likewise
- * src/stringprep/uni_norm.c: Regenerated
-
-2005-05-18 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/mod_irc_connection.erl: Added support for WHOIS
- requests and reply to USERINFO (thanks to Oleg V. Motienko)
-
-2005-05-17 Alexey Shchepin <alexey@sevcom.net>
-
- * src/stringprep/stringprep_drv.c: Bugfix
-
-2005-05-16 Alexey Shchepin <alexey@sevcom.net>
-
- * src/win32/ejabberd.cfg: Updated (thanks to Sergei Golovan)
-
- * src/odbc/Makefile.win32: Added (thanks to Sergei Golovan)
-
- * src/Makefile.win32: Updated (thanks to Sergei Golovan)
-
-2005-05-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/jd2ejd.erl: Fixed private xml setting
-
- * src/mod_last.erl: Bugfix
- * src/mod_last_odbc.erl: Likewise
-
- * src/mod_pubsub/mod_pubsub.erl: Fixed service stopping
-
-2005-05-09 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Fixed bug with storing
- affiliations of invited users in members-only room (thanks to
- Sergei Golovan)
-
- * src/ejabberd_c2s.erl: Fixed starttls_required behaviour for
- legacy connections (thanks to Brian Campbell)
-
- * src/web/ejabberd_web_admin.erl: Images now specified via CSS,
- design slightly updated, added last activity statistics (thanks to
- Sergei Golovan)
-
-2005-05-07 Alexey Shchepin <alexey@sevcom.net>
-
- * src/stringprep/stringprep_drv.c: Added check for bidi
-
- * src/stringprep/uni_parse.tcl: Now handle all Unicode code points
- up to U+10FFFF
- * src/stringprep/uni_parse2.tcl: Likewise
- * src/stringprep/uni_data.c: Regenerated
- * src/stringprep/uni_norm.c: Likewise
-
-2005-05-06 Alexey Shchepin <alexey@sevcom.net>
-
- * src/stringprep/uni_norm.c: Regenerated with Unicode 3.2 tables
- as required by RFC3454
-
- * src/stringprep/uni_parse2.tcl: Bugfixes
-
- * src/stringprep/stringprep_drv.c: Bugfixes, added hangul
- composition
-
-2005-05-05 Mickael Remond <mremond@erlang-fr.org>
-
- * src/msgs/fr.msg: Added missing version 0.9 fields and removed unused
- ones.
-
-2005-05-04 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Store ban reasons for outcast
- items, updated affiliation matching rules to latest JEP-0045
-
-2005-05-02 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Updated changing roles and
- affiliations tables to latest JEP-0045
-
-2005-05-01 Mickael Remond <mremond@erlang-fr.org>
-
- * src/msgs/fr.msg: Updated
-
-2005-05-01 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/sw.msg: Renamed to sv.msg
- * src/msgs/sv.msg: Likewise
-
- * src/msgs/pl.msg: Updated (thanks to Andrew Smyk)
-
- * contrib/extract_translations/README: Better phrasing (thanks to
- Sergei Golovan)
-
- * contrib/extract_translations/extract_translations.erl: Fix to
- avoid duplication of lines (thanks to Sergei Golovan)
-
- * src/msgs/sw.msg: New Swedish translation (thanks to Magnus
- Henoch)
-
- * src/msgs/pt.msg: New Portuguese translation (thanks to iceburn)
-
- * src/msgs/es.msg: Updated (thanks to Badlop)
-
- * src/msgs/nl.msg: Updated (thanks to Sander Devrieze)
-
-2005-04-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_auth_ldap.erl: Added listing of users support
-
- * src/ejabberd.cfg.example: Updated LDAP options
-
- * src/ejabberd_ctl.erl: Better spelling, now prints full file
- paths, fixed checking of mnesia:install_fallback result, now
- "dump" command dumps only persistent tables
-
- * contrib/extract_translations/: A tool for extracting of
- translation strings from ejabberd code (thanks to Sergei Golovan)
-
-2005-04-26 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_vcard_ldap.erl: Bugfix (thanks to Mickael Remond)
-
-2005-04-24 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Added translation to submit
- button and "shared roster groups" header (thanks to iceburn and
- Sergei Golovan)
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
- * src/msgs/uk.msg: Likewise
-
- * src/mod_muc/mod_muc_room.erl: Minor update to simplify
- translation (thanks to Sergei Golovan)
-
- * src/tls/tls_drv.c: Reverted previous patch
-
-2005-04-22 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Added mod_shared_roster documentation
-
- * src/ejabberd.hrl: Updated version
-
-2005-04-21 Alexey Shchepin <alexey@sevcom.net>
-
- * src/jd2ejd.erl: Bugfix
-
-2005-04-20 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_auth.erl: Added check for domain of registered user
-
- * src/web/ejabberd_web_admin.erl: Fixed user registration via web
- interface, fixed path to user's offline messages (thanks to
- Mickael Remond)
-
- * src/mod_disco.erl: Fixed domain listing when one virtual host is
- a subdomain of another
-
-2005-04-18 Alexey Shchepin <alexey@sevcom.net>
-
- * (all): ejabberd-0.9 released
-
- * src/web/ejabberd_web_admin.erl: Added link to shared roster page
-
- * src/odbc/ejabberd_odbc.erl: ODBC connection string can be
- specified via odbc_server option now
- * src/ejabberd.cfg.example: Added ODBC usage example
-
- * doc/guide.tex: Updated
-
- * src/msgs/pl.msg: New Polish translation (thanks to Andrew Smyk)
-
-2005-04-17 Alexey Shchepin <alexey@sevcom.net>
-
- * (all): Merged virtual hosting support
-
-2005-04-09 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Send new id for each new stream inside one
- session (thanks to Maxim Ryazanov)
-
- * src/tls/tls_drv.c: Now reads all certificates from certificate
- file instead of reading only first one (thanks to Karl-Johan
- Karlsson)
-
-2005-04-06 Alexey Shchepin <alexey@sevcom.net>
-
- * examples/transport-configs/init-scripts/jabber-gg-transport:
- Fixed typo (thanks to Sander Devrieze)
-
-2005-04-05 Alexey Shchepin <alexey@sevcom.net>
-
- * examples/transport-configs/configs/msn-transport.xml: Fixed typo
- (thanks to Sander Devrieze)
-
-2005-04-02 Alexey Shchepin <alexey@sevcom.net>
-
- * examples/transport-configs/: Updated (thanks to Sander Devrieze)
-
-2005-03-31 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_ctl.erl: Bugfix
-
-2005-03-17 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Bugfix
-
-2005-03-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_sm.erl: Bugfix
-
-2005-03-12 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_router.erl: Bugfix
-
-2005-01-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/mod_irc_connection.erl: Added filtering of quit
- status
-
-2005-01-04 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Copyright update
- * src/mod_vcard_ldap.erl: Likewise
- * src/mod_vcard.erl: Likewise
- * src/mod_pubsub/mod_pubsub.erl: Likewise
- * src/mod_muc/mod_muc.erl: Likewise
- * src/mod_irc/mod_irc.erl: Likewise
-
-2004-12-30 Alexey Shchepin <alexey@sevcom.net>
-
- * src/odbc/ejabberd_odbc.erl: Load-balance ODBC requests between
- several connections
-
- * src/odbc/ejabberd_odbc_sup.erl: Supervisor for ODBC connections
-
- * src/mod_muc/mod_muc_room.erl: Added missed type='form' attribute
- in room configuration response (thanks to Badlop)
-
-2004-12-19 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_roster_odbc.erl: Roster support via ODBC (not completed)
-
- * src/ejabberd_auth_internal.erl: Added remove_user hook
- * src/ejabberd_auth_odbc.erl: Likewise
- * src/mod_roster.erl: Use remove_user hook
- * src/mod_offline.erl: Likewise
- * src/mod_offline_odbc.erl: Likewise
- * src/mod_last.erl: Likewise
- * src/mod_last_odbc.erl: Likewise
- * src/mod_vcard.erl: Likewise
- * src/mod_private.erl: Likewise
-
- * src/mod_roster.erl: Added hooks for functions exported by
- mod_roster
- * src/ejabberd_c2s.erl: Likewise
- * src/ejabberd_sm.erl: Likewise
- * src/mod_privacy.erl: Likewise
- * src/mod_last.erl: Likewise
- * src/mod_last_odbc.erl: Likewise
-
-2004-12-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_sm.erl: Updated missed message passing from
- previous patch
-
-2004-12-13 Alexey Shchepin <alexey@sevcom.net>
-
- * src/odbc/pg.sql: DB creation script for postgres
-
- * src/odbc/ejabberd_odbc.erl: Experimental support for ODBC
- * src/mod_last_odbc.erl: Likewise
- * src/mod_offline_odbc.erl: Likewise
- * src/ejabberd_auth_odbc.erl: Likewise
- * src/ejabberd_auth.erl: Likewise
-
-2004-12-12 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_stats.erl: Minor optimizations
-
- * src/ejabberd_sm.erl: Added unset_presence_hook
- * src/mod_last.erl: Use unset_presence_hook instead of direct call
-
- * src/ejabberd_auth.erl: Splitted into ejabberd_auth_internal.erl,
- ejabberd_auth_ldap.erl, and ejabberd_auth_external.erl,
- * src/ejabberd_auth_internal.erl: Likewise
- * src/ejabberd_auth_ldap.erl: Likewise
- * src/ejabberd_auth_external.erl: Likewise
-
-2004-12-05 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Changed type of password field
- to "password"
-
- * src/jlib.hrl: More stream error defines (thanks to Sergei
- Golovan)
-
- * src/ejabberd_c2s.erl: Support for starttls_required option
- (thanks to Sergei Golovan)
-
- * src/mod_muc/mod_muc_room.erl: Fixed mistake in case condition
- (thanks to Sergei Golovan)
-
- * src/xml_stream.erl: Added function parse_element/1
-
- * src/expat_erl.c: Added PARSE_FINAL_COMMAND
-
-2004-12-03 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_listener.erl: Enable keepalive option
-
- * src/xml_stream.erl: Added API for managing xml streams without
- creating process
- * src/ejabberd_receiver.erl: Use this API, now 2 processes are
- created per C2S connection
-
-2004-12-01 Alexey Shchepin <alexey@sevcom.net>
-
- * src/expat_erl.c: Now uses port control instead of port output
- * src/xml_stream.erl: Likewise
-
-2004-11-30 Alexey Shchepin <alexey@sevcom.net>
-
- * src/stringprep/stringprep.erl: Now register port instead of
- storing it in ets table
-
-2004-11-28 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Updated URLs to R10C release
-
-2004-11-20 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_vcard.erl: Added missed index
-
-2004-11-08 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Updated (thanks to Sander Devrieze)
-
-2004-11-05 Alexey Shchepin <alexey@sevcom.net>
-
- * src/aclocal.m4: Fixed headers detecting in AM_WITH_OPENSSL
- (thanks to Leif Johansson)
-
- * src/ejabberd_auth.erl: Added support for ldap_rootdn and
- ldap_password options (thanks to Stefan de Konink)
- * src/mod_vcard_ldap.erl: Likewise
-
- * src/ejabberd_router.erl: Now possible to route packet via
- function call instead of message sending
- * src/ejabberd_sm.erl: Added function route/3, use it in route
- table
- * src/ejabberd_local.erl: Likewise
- * src/ejabberd_s2s.erl: Likewise
-
-2004-10-23 Alexey Shchepin <alexey@sevcom.net>
-
- * (all): Fixed spelling of word "authentication"
-
- * src/*/Makefile.in: Replaced erlc with @ERLC@
-
-2004-10-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_s2s.erl: Added remove_connection/1
- * src/ejabberd_s2s_out.erl: Use ejabberd_s2s:remove_connection/1
-
- * src/ejabberd_s2s_in.erl: Minor cleanup
-
- * examples/transport-configs/: Transport config examples (thanks
- to Sander Devrieze)
-
- * src/msgs/de.msg: German translation (thanks to Marina Hahn)
-
-2004-10-12 Alexey Shchepin <alexey@sevcom.net>
-
- * src/win32/: Updated (thanks to Sergei Golovan)
-
- * src/msgs/es.msg: Updated (thanks to Badlop)
-
- * src/mod_irc/iconv_erl.c: Bugfix (thanks to Jacek Konieczny)
-
-2004-10-10 Alexey Shchepin <alexey@sevcom.net>
-
- * (all): ejabberd-0.7.5 released
-
- * src/tls/Makefile.win32: Added (thanks to Sergei Golovan)
-
- * src/win32/: Updated (thanks to Sergei Golovan)
-
-2004-10-09 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Fixed user listing
-
- * src/msgs/uk.msg: Updated (thanks to Sergei Golovan)
-
- * src/msgs/nl.msg: Updated (thanks to Sander Devrieze)
-
- * src/msgs/ua.msg: Renamed to uk.msg
-
- * COPYING: Added permission to link with OpenSSL
-
-2004-10-08 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/ua.msg: Updated (thanks to Sergei Golovan)
-
- * src/mod_muc/mod_muc_room.erl: Fixed room destroying
-
- * src/ejabberd.cfg.example: Updated
-
- * src/ejabberd_sm.erl: Fixed message routing when all resources
- have negative priority
-
- * src/msgs/*.msg: Updated (thanks to Sergei Golovan)
-
- * src/web/ejabberd_web_admin.erl: Table titles now bold (thanks to
- Sergei Golovan)
-
-2004-10-06 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Updated
-
- * src/ejabberd_s2s_out.erl: Fixed socket closing condition
-
-2004-10-05 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_http_poll.erl: Properly handle bad requests
-
- * src/web/ejabberd_web_admin.erl: Ported features from J-EAI
-
-2004-09-30 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_http.erl: Fixed processing of POST body for
- HTTP Polling
-
- * src/web/ejabberd_http.erl: Support for "Connection" HTTP header
- (thanks to Sergei Golovan)
-
- * src/translate.erl: Much better handling of xml:lang (thanks to
- Sergei Golovan)
-
-2004-09-29 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_listener.erl: Check result of controlling_process
-
- * src/web/ejabberd_http.erl: Bugfix
-
-2004-09-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/Makefile.in: Updated (thanks to Badlop)
-
-2004-09-26 Alexey Shchepin <alexey@sevcom.net>
-
- * src/aclocal.m4: Better expat and openssl detection (thanks to
- Anton Vanin)
-
- * src/**/Makefile.in: Updated (thanks to Anton Vanin)
- * src/configure.ac: Likewise
-
-2004-09-25 Alexey Shchepin <alexey@sevcom.net>
-
- * src/jlib.hrl: Added namespace for iq-register stream feature
- * src/ejabberd_c2s.erl: Send iq-register feature
-
- * src/ejabberd_config.erl: Config file can be configured via
- environment variable (thanks to Mickael Remond)
-
- * src/web/ejabberd_http.erl: Added SSL support (thanks to Sergei
- Golovan)
-
- * src/msgs/*.msg: Updated (thanks to Sergei Golovan)
-
- * src/jlib.hrl: Updated error codes (thanks to Sergei Golovan)
- * src/ejabberd_c2s.erl: Likewise
-
-2004-09-17 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Send password in room invitation
- (thanks to Sergei Golovan)
-
- * src/mod_disco.erl: Added registration of sm features and nodes
- (thanks to Sergei Golovan)
- * src/mod_vcard.erl: Register vcard-temp feature (thanks to Sergei
- Golovan)
-
- * src/jlib.erl: Added functions now_to_utc_string/1,
- now_to_local_string/1, and datetime_string_to_timestamp/1 (thanks
- to Sergei Golovan)
- * src/mod_muc/mod_muc_room.erl: Use time parsing functions from
- jlib (thanks to Sergei Golovan)
-
-2004-09-16 Alexey Shchepin <alexey@sevcom.net>
-
- * ejabberd/src/mod_pubsub/mod_pubsub.erl: Bugfix (thanks to
- Mickael Remond)
-
-2004-09-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_pubsub/mod_pubsub.erl: Bugfix
-
-2004-09-10 Alexey Shchepin <alexey@sevcom.net>
-
- * tools/ejabberdctl: Added call to "exec" (thanks to Sergei
- Golovan)
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
-
- * src/mod_vcard.erl: Support for searching of prefix substring and
- limiting of result items (thanks to Sergei Golovan)
-
- * src/mod_offline.erl: Support for message expiration (JEP-0023)
- (thanks to Sergei Golovan)
- * src/jlib.hrl: Added NS_EXPIRE macros (thanks to Sergei Golovan)
-
- * src/ejabberd_logger_h.erl: Added reopen_log/0 (thanks to Sergei
- Golovan)
-
- * src/ejabberd_ctl.erl: Added return codes, updated "reopen-log"
- command, added "delete-expired-messages" and "status" commands
- (thanks to Sergei Golovan)
-
- * doc/guide.tex: Updated (thanks to Sergei Golovan)
-
-2004-09-04 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_roster.erl: Removed useless transactions
-
-2004-08-28 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Fix (thanks to Sander Devrieze)
-
-2004-08-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/xml_stream.erl: Few optimizations
-
-2004-08-24 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_service_log.erl: Support for logging of user packets via
- external service (e.g. bandersnatch)
- * doc/guide.tex: Updated
-
-2004-08-23 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_offline.erl: Added entire table locking on large message
- queue
-
- * src/ejabberd_sm.erl: Added offline_subscription_hook
- * src/mod_offline.erl: Use offline_subscription_hook
-
- * src/configure.erl: Updated (thanks to Sergei Golovan)
- * src/Makefile.win32: Likewise
- * src/tls/Makefile.win32: Likewise
- * src/win32/: Likewise
-
- * src/mod_announce.erl: Added announce to all users (thanks to
- Sergei Golovan)
- * doc/guide.tex: Updated (thanks to Sergei Golovan)
-
-2004-08-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/nl.msg: Updated (thanks to Sander Devrieze)
-
- * src/web/ejabberd_http_poll.erl: Fixed sending of Set-Cookie
- header
-
-2004-08-12 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Bugfix in resend_offline_messages/1
-
- * src/mod_announce.erl: New module to manage announce messages
- (thanks to Sergei Golovan)
-
- * src/ejabberd_local.erl: Moved processing of announce messages to
- mod_announce (thanks to Sergei Golovan)
-
- * src/ejabberd_c2s.erl: Added several hooks
-
- * src/ejabberd_hooks.erl: Fixed run_fold (thanks to Sergei
- Golovan)
-
- * src/ejabberd.cfg.example: Updated (thanks to Sergei Golovan)
-
- * doc/guide.tex: Updated (thanks to Sergei Golovan)
-
-2004-08-08 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Use resend_offline_messages_hook to fetch
- offline messages
- * src/mod_offline.erl: Likewise
-
- * src/mod_offline.erl: Added table locking in
- remove_old_messages/1
-
- * src/ejabberd_sm.erl: Use offline_message_hook to store offline
- messages
- * src/mod_offline.erl: Likewise
-
- * src/ejabberd_hooks.erl: Hooks support
- * src/ejabberd_sup.erl: Added ejabberd_hooks
-
- * doc/guide.tex: Updated
-
- * src/ejabberd.cfg.example: Updated
-
- * src/ejabberd_c2s.erl: Changed TLS options (thanks to Sergei
- Golovan)
-
-2004-08-05 Alexey Shchepin <alexey@sevcom.net>
-
- * src/aclocal.m4: Updated to check for openssl library (thanks to
- AV)
- * src/configure.ac: Likewise
- * src/configure: Likewise
- * src/Makefile.in: Likewise
- * src/tls/Makefile.in: Likewise
-
-2004-08-03 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Added user's roster page
-
- * src/mod_irc/mod_irc_connection.erl: Bugfix
-
-2004-08-01 Alexey Shchepin <alexey@sevcom.net>
-
- * src/tls/tls.erl: Added recv_data/2 function
-
- * src/jlib.erl: Added NS_TLS macro
-
- * src/ejabberd_receiver.erl: Support for STARTTLS
- * src/ejabberd_c2s.erl: Likewise
-
-2004-07-30 Alexey Shchepin <alexey@sevcom.net>
-
- * examples/extauth/check_pass_null.pl: A reference "null"
- implementation of external authentication script (thanks to Leif
- Johansson)
-
- * src/extauth.erl: Support for external authentication
- (thanks to Leif Johansson)
- * src/ejabberd_auth.erl: Likewise
-
- * src/mod_vcard_ldap.erl: A drop-in replacement for mod_vcard.erl
- which uses ldap for JUD and vCard (thanks to Leif Johansson)
-
-2004-07-28 Alexey Shchepin <alexey@sevcom.net>
-
- * src/tls/tls_drv.c: Added freeing of SSL stuff
-
- * src/xml_stream.erl: Added start/2 function
- * src/ejabberd_receiver.erl: Now using xml_stream:start/2
-
-2004-07-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Support for TLS library (not completed)
-
- * src/tls/tls_drv.c: Updated to return binaries instead of lists
- * src/tls/tls.erl: Likewise
-
-2004-07-26 Alexey Shchepin <alexey@sevcom.net>
-
- * src/tls/tls.erl: Updated
-
-2004-07-25 Alexey Shchepin <alexey@sevcom.net>
-
- * src/tls/: Library for TLS support (not completed)
-
- * src/ejabberd_auth.erl: Now uses two LDAP connections
-
- * src/ejabberd_c2s.erl: Return resource on get_presence request
- (thanks to Mickael Remond)
-
- * src/mod_configure2.erl: Bugfix (thanks to Sergei Golovan)
-
- * src/msgs/ua.msg: New Ukrainian translation (thanks to usercard)
-
- * src/msgs/nl.msg: Updated (thanks to Sander Devrieze)
-
-2004-07-23 Alexey Shchepin <alexey@sevcom.net>
-
- * src/eldap/eldap.erl: Bugfix
-
-2004-07-13 Alexey Shchepin <alexey@sevcom.net>
-
- * (all): ejabberd-0.7 released
-
- * src/web/ejabberd_web_admin.erl: Better i18n support (thanks to
- Sergei Golovan)
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
-
- * src/msgs/fr.msg: Added missed entries (thanks to Sergei Golovan)
- * src/msgs/nl.msg: Likewise
-
- * src/msgs/es.msg: New spanish translation (thanks to Badlop)
-
-2004-07-11 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_last.erl: Supprot for storing status from latest
- unavailable presence (thanks to Sergei Golovan)
- * src/ejabberd_sm.erl: Likewise
- * src/ejabberd_c2s.erl: Likewise
-
- * src/mod_vcard.erl: Minor update (thanks to Sergei Golovan)
-
- * src/mod_register.erl: Added "access" option (thanks to Sergei
- Golovan)
- * src/mod_irc/mod_irc.erl: Likewise
- * src/ejabberd.cfg.example: Updated
- * src/win32/ejabberd.cfg: Likewise
-
- * src/mod_privacy.erl: Fixed module stopping (thanks to Sergei
- Golovan)
- * src/mod_private.erl: Likewise
-
- * src/gen_mod.erl: Added function get_module_opt/3 (thanks to
- Sergei Golovan)
-
- * src/ejabberd_local.erl: Minor fix (thanks to Sergei Golovan)
-
- * doc/guide.tex: Updated (thanks to Sergei Golovan)
-
-2004-07-10 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_roster.erl: Removed superfluous include_lib line
-
- * doc/guide.tex: Updated
-
- * src/msgs/fr.msg: Updated (thanks to Sergei Golovan)
-
- * src/mod_irc/mod_irc.erl: Added handler for disco items requests
- (thanks to Sergei Golovan)
-
- * src/mod_vcard.erl: Added option for JUD disabling (thanks to
- Sergei Golovan)
-
- * src/mod_configure2.erl: Fixed module stopping (thanks to Sergei
- Golovan)
- * src/mod_last.erl: Likewise
- * src/mod_privacy.erl: Likewise
- * src/mod_register.erl: Likewise
- * src/mod_roster.erl: Likewise
- * src/mod_vcard.erl: Likewise
-
- * src/jd2ejd.erl: Added emergency catches (thanks to Sergei
- Golovan)
- * src/mod_last.erl: Likewise
-
- * src/ejabberd_sm.erl: Removed needless call to
- mod_disco:unregister_feature (thanks to Sergei Golovan)
-
- * src/ejabberd_local.erl: Better support for mod_disco (thanks to
- Sergei Golovan)
- * src/mod_disco.erl: Likewise
-
- * src/translate.erl: Suport for "default language" option (thanks
- to Sergei Golovan)
- * src/ejabberd_config.erl: Likewise
- * src/ejabberd_c2s.erl: Likewise
- * src/ejabberd.hrl: Added 'MYLANG' macros
-
- * src/ejabberd.cfg.example: Updated (thanks to Sergei Golovan)
-
- * doc/guide.tex: Updated (thanks to Sergei Golovan)
-
-2004-07-09 Alexey Shchepin <alexey@sevcom.net>
-
- * src/win32/ejabberd.cfg: Updated (thanks to Sergei Golovan)
-
-2004-07-07 Alexey Shchepin <alexey@sevcom.net>
-
- * src/Makefile.win32: Updated (thanks to Sergei Golovan)
-
- * src/Makefile.in: Added installation of ejabberd.cfg (thanks to
- Sergei Golovan)
-
- * src/web/ejabberd_http.erl: Fixed support for HTTP/1.0 clients
-
-2004-07-06 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Updated (thanks to Sergei Golovan)
-
- * src/ejabberd_auth.erl: Minor fix
-
- * src/ejabberd_c2s.erl: Fixed sending of presence to own resources
-
-2004-06-18 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Added configuration of listened
- ports
- * src/ejabberd_listener.erl: Added API for configuration of port
- listeners
-
- * src/web/ejabberd_web_admin.erl: Fixed "Stop" button on node
- management page
-
-2004-05-22 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/nl.msg: Dutch translation (thanks to Sander Devrieze)
-
- * src/web/ejabberd_http.erl: Added options for enabling HTTP
- polling and admin interface
- * src/web/ejabberd_web.erl: Likewise
- * src/ejabberd.cfg.example: Updated
-
- * src/web/ejabberd_web_admin.erl: Updated
-
- * doc/guide.tex: Updated
-
-2004-05-17 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc.erl: Added access rules for using serveice
- and creating rooms (thanks to Sergei Golovan)
-
- * src/win32/ejabberd.nsi: Updated (thanks to Sergei Golovan)
- * src/win32/CheckUserH.ini: Likewise
-
- * src/translate.erl: Search translations in priv_dir instead of
- lib_dir (thanks to Sergei Golovan)
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
-
- * src/ejabberd.cfg.example: Updated (thanks to Sergei Golovan)
-
- * src/**/Makefile.in: Updated (thanks to Sergei Golovan)
- * src/**/Makefile.win32: Likewise
-
-2004-05-16 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Updated
-
-2004-05-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Updated
-
-2004-05-09 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Updated
-
- * src/ejabberd_listener.erl: Added API for adding/removing
- listeners
-
-2004-05-08 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Updated
-
- * src/ejabberd_listener.erl: Now possible to specify interface on
- which one socket will be listened, also added another way to
- specify SSL options
- * src/ejabberd.cfg.example: Updated
-
-2004-05-07 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Updated (thanks to Andrey
- Zamaraev)
-
-2004-05-05 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_ctl.erl: Added command for listing all registered
- users
-
- * src/ejabberd_ctl.erl: Bugfix, support for text-load and restore
- (thanks to Leif Johansson)
-
-2004-05-04 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Updated
-
-2004-05-01 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_http.erl: 'Accept-Language' header support
- * src/web/ejabberd_web_admin.erl: Likewise
- * src/msgs/ru.msg: Updated
-
- * src/mod_muc/mod_muc_room.erl: Send status code "201" on room
- creation
-
-2004-04-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/translate.erl: Search translations directory in priv_dir
- instead of lib_dir (thanks to Sergei Golovan)
-
- * src/**/Makefile.in: Updated (thanks to Sergei Golovan)
-
- * src/win32/: Win32 installer stuff (thanks to Sergei Golovan)
-
- * src/**/Makefile.win32: Updated (thanks to Sergei Golovan)
- * src/configure.bat: Likewise
- * src/configure.erl: Likewise
-
- * doc/guide.tex: Updated (thanks to Sergei Golovan)
-
-2004-04-26 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web_admin.erl: Better design for administration
- interface (not completed) (thanks to Andrey Zamaraev)
- * src/web/ejabberd_http.erl: Updated
- * src/web/ejabberd_web.erl: Likewise
-
-2004-04-17 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_http.erl: Increased receive buffer
-
- * src/mod_irc/mod_irc_connection.erl: Support for "/quote" command
-
-2004-04-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd.erl: Added searching of files in code:priv_lib
- (thanks to Sergei Golovan)
- * src/translate.erl: Likewise
-
- * src/ejabberd_app.erl: Added "log_path" configuration parameter
- (thanks to Sergei Golovan)
-
- * src/**/Makefile.win32: Updated (thanks to Sergei Golovan)
-
- * src/**/*.c: Updated (thanks to Sergei Golovan)
-
- * src/configure.erl: Added writing of version to Makefile.inc
- (thanks to Sergei Golovan)
-
- * doc/guide.tex: Updated link to expat (thanks to Sergei Golovan)
-
-2004-04-10 Alexey Shchepin <alexey@sevcom.net>
-
- * src/idna.erl: Support for IDNA (RFC3490)
- * src/ejabberd_s2s_out.erl: Likewise
-
-2004-04-03 Alexey Shchepin <alexey@sevcom.net>
-
- * src/xml.erl: element_to_string/1 and crypt/1 now returns deep
- list
- * src/mod_muc/mod_muc_room.erl (add_message_to_history): Replaced
- string:len with lists:flatlength
-
-2004-03-21 Alexey Shchepin <alexey@sevcom.net>
-
- * (all): Updated win32 stuff (thanks to Sergei Golovan)
-
- * src/web/ejabberd_web.erl: Added interface for access rules
- configuration
-
-2004-03-20 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Updated
-
- * src/web/ejabberd_web.erl: Updated
-
- * src/web/ejabberd_http.erl: Bugfix
-
-2004-03-16 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_roster.erl: Bugfix
-
- * src/ejabberd_s2s.erl: More verbose error handling
-
-2004-03-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web.erl: Minor update
-
-2004-03-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web.erl: Added interface for users listsing and
- statistics
-
-2004-03-13 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web.erl: New interface for ACLs editing
-
- * src/web/ejabberd_http_poll.erl: Fixed "Content-Type" header,
- "Set-Cookie" is included only in first response in session, added
- missed behaviour definition
-
- * src/web/ejabberd_http.erl: "Content-Type" header now can be
- changed
-
-2004-03-12 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_web.erl: Experiments with web-interface
-
- * src/configure.ac: Updated
- * src/Makefile.in: Likewise
-
-2004-03-10 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_http.erl: Removed debugging output
-
- * src/ejabberd_c2s.erl: Fixed processing of get_presence request
- (thanks to Mickael Remond)
-
-2004-03-08 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
-
- * src/mod_muc/mod_muc_room.erl: Now private conferences are
- visible to admins and owners of this conference (thanks to Sergei
- Golovan)
-
- * src/mod_muc/mod_muc.erl: More xml:lang support (thanks to Sergei
- Golovan)
-
- * src/mod_vcard.erl: Better processing of EMAIL tag (thanks to
- Sergei Golovan)
-
- * src/ejabberd_s2s_out.erl: Added "catch" to "open_socket" (thanks
- to Sergei Golovan)
-
-2004-03-07 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/ejabberd_http_poll.erl: Completed
-
-2004-03-06 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/: Support for HTTP Polling (JEP-0025) (almost complete)
-
-2004-03-04 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/: Updated
-
-2004-03-03 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/: Minor update
-
-2004-03-02 Alexey Shchepin <alexey@sevcom.net>
-
- * src/web/: Small HTTP server and admin web-interface to ejabberd
- (not completed yet)
- * src/ejabberd_sup.erl: Added HTTP processes supervisor
-
- * src/ejabberd_c2s.erl: Added API to ask presence (thanks to
- Mickael Remond)
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
-
- * src/mod_muc/mod_muc_room.erl: Updated date parser (thanks to
- Sergei Golovan)
-
- * src/mod_muc/mod_muc.erl: Added error descriptions (thanks to
- Sergei Golovan)
- * src/mod_muc/mod_muc_room.erl: Likewise
-
- * src/mod_vcard.erl: Fixed vCard tag (thanks to Sergei Golovan)
- * src/mod_irc/mod_irc.erl: Likewise
- * src/mod_pubsub/mod_pubsub.erl: Likewise
-
- * src/jlib.hrl: Added macros for errors with <text/> (thanks to
- Sergei Golovan)
-
-2004-02-26 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
-
- * src/mod_muc/mod_muc_room.erl: Updated error codes, removed
- trailing "-" in history. updated subject sending, added <title/>
- in configuration form (thanks to Sergei Golovan)
-
- * src/mod_irc/mod_irc.erl: Added vCard, ejabberd:configure
- replaced with jabber:iq:register (thanks to Sergei Golovan)
-
- * src/mod_configure.erl: Updated "xml:lang" usage, updated some
- messages (thanks to Sergei Golovan)
- * src/mod_configure2.erl: Likewise
- * src/mod_disco.erl: Likewise
- * src/mod_register.erl: Likewise
- * src/mod_vcard.erl: Likewise
- * src/mod_irc/mod_irc.erl: Likewise
- * src/mod_muc/mod_muc.erl: Likewise
- * src/mod_muc/mod_muc_room.erl: Likewise
- * src/mod_pubsub/mod_pubsub.erl: Likewise
-
- * src/jlib.hrl: Added "lang" field in "iq" record (thanks to
- Sergei Golovan)
- * src/jlib.erl: Likewise
-
- * src/ejabberd_c2s.erl: Updated to latest JEP-0078 (thanks to
- Sergei Golovan)
-
-2004-02-18 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_sm.erl: Bugfix
-
-2004-02-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Support for history management
- (thanks to Sergei Golovan)
-
- * src/mod_stats.erl: Updated error codes (thanks to Sergei
- Golovan)
- * src/mod_irc/mod_irc.erl: Likewise
-
- * src/mod_configure.erl: "jabber:iq:data" replaced with
- "ejabberd:config" namespace (thanks to Sergei Golovan)
- * src/mod_disco.erl: Likewise
-
-2004-02-12 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Added <session/> to stream features
-
-2004-02-10 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
-
- * src/mod_irc/mod_irc.erl: Now uses "ejabberd:config" namespace
- (thanks to Sergei Golovan)
-
- * src/mod_disco.erl: Fixed disco category and type (thanks to
- Sergei Golovan)
- * src/mod_pubsub/mod_pubsub.erl: Likewise
-
- * src/jlib.hrl: Added "ejabberd:config" namespace (thanks to
- Sergei Golovan)
-
-2004-01-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_ctl.erl: Added command for log reopening
-
-2004-01-18 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_ctl.erl: Added commands for backup processing
-
- * src/ejabberd_c2s.erl: Added processing of xml:lang according to
- latest XMPP-IM draft
-
- * src/xml.erl: Added replace_tag_attr/3 function
-
- * src/mod_roster.erl: Added auto-reply on incoming subscription
- request according to latest XMPP-IM draft
-
- * src/mod_offline.erl: Added pop_offline_messages/1 function
- * src/ejabberd_c2s.erl: Updated sending of offline messages
-
-2004-01-17 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Bugfix, updated error codes
- (thanks to Sergei Golovan)
-
- * src/jlib.hrl: Updated error codes (thanks to Sergei Golovan)
-
-2004-01-11 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Fixed bind namespace
-
- * src/ejabberd_ctl.erl: New module for ejabberd administration
- * tools/ejabberdctl: Shell script for ejabberd administration
-
- * src/mod_vcard.erl: Copyright update
-
- * src/ejabberd_service.erl: Now possible to specify access rules
- for service
- * src/ejabberd.cfg.example: Updated
-
-2004-01-06 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_router.erl: Added monitoring of processess that
- serve domains
-
- * src/ejabberd_app.erl: Bugfix
-
-2004-01-03 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_router.erl (do_route/3): Slightly changed behaviour
-
-2004-01-01 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_sm.erl (do_route/3): Minor fix
-
- * src/ejabberd_sm.erl (route_message/3): Minor changes
-
-2003-12-28 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_app.erl: Now possible to specify path to log file
- via "EJABBERD_LOG_PATH" environment variable
-
- * src/translate.erl: Now possible to specify path to "msgs"
- directory via "EJABBERD_MSGS_PATH" environment variable
-
- * src/ejabberd.erl: Added get_so_path/0 function
- * src/ejabberd_app.erl: Use ejabberd:get_so_path/0 to load .so
- * src/mod_irc/iconv.erl: Likewise
- * src/stringprep/stringprep.erl: Likewise
-
-2003-12-24 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Presence probe now sended from full JID
-
- * src/mod_roster.erl: Bugfix
-
-2003-12-23 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Bugfix
-
-2003-12-21 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_roster.erl: Added workaround for legacy gateways
- (passing of "subscribed" presence)
-
- * src/ejabberd_sm.erl: Minor fix in subscription processing
-
-2003-12-17 Alexey Shchepin <alexey@sevcom.net>
-
- * src/jlib.hrl: Added declaration of "iq" record
- * (all): Updated to use "iq" record
-
-2003-12-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_local.erl: Replaced register_local_route to
- register_route
- * src/ejabberd_service.erl: Likewise
- * src/mod_echo.erl: Likewise
- * src/mod_vcard.erl: Likewise
-
- * src/ejabberd_router.erl: Partially rewrited
- * src/ejabberd_sm.erl: Likewise
-
-2003-12-13 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_s2s.erl: Partially rewrited
-
- * src/mod_roster.erl: Removed debugging code
-
-2003-12-12 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_s2s_out.erl: Bugfix
-
-2003-12-11 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_roster.erl: Updated subscription handling to latest
- XMPP-IM draft
-
-2003-12-06 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_s2s_in.erl: Changed timeout processing, bugfix
-
- * src/ejabberd_s2s_out.erl: Changed timeout processing
-
- * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
-
- * src/mod_muc/mod_muc.erl: Better i18n support, added support for
- <registered/> field in iq:register replies (thanks to Sergei
- Golovan)
-
- * src/mod_register.erl: More i18n support (thanks to Sergei
- Golovan)
-
-2003-12-02 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Bugfix in processing of connection
- replacement
-
-2003-11-28 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Added workaround for some Java clients
-
-2003-11-27 Alexey Shchepin <alexey@sevcom.net>
-
- * examples/mtr/ejabberd.cfg: Updated (thanks to Marshall T. Rose)
-
- * src/ejabberd_auth.erl: LDAP attribute that holds user ID now
- configurable
- * src/ejabberd.cfg.example: Updated
-
-2003-11-26 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Fixed processing of presence probe from
- client
-
-2003-11-23 Alexey Shchepin <alexey@sevcom.net>
-
- * src/cyrsasl_digest.erl: Bugfix (thanks to Sergei Golovan)
-
- * src/ejabberd.cfg.example: Updated
-
- * src/ejabberd_auth.erl: Support for LDAP authentication
- * src/cyrsasl_digest.erl: Likewise
- * src/mod_register.erl: Likewise
- * src/ejabberd_c2s.erl: Likewise
-
- * src/eldap/: Imported "eldap" package
-
- * src/ejabberd_sm.erl: Bugfix
-
-2003-11-16 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Bugfixes
-
- * (all): Version 0.5 released
-
-2003-11-13 Alexey Shchepin <alexey@sevcom.net>
-
- * examples/mtr/ejabberd: Updated (thanks to Marshall T. Rose)
-
- * src/Makefile.in: Added installation of msgs/ directory
-
-2003-11-11 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/dev.tex: Developers documentation (not completed)
-
- * src/ejabberd_c2s.erl: Better handling of malformed JIDs
-
- * src/mod_register.erl (try_register/2): Now returns "jid
- malformed" error if user name is invalid
-
-2003-11-10 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd.cfg.example: Updated
-
- * src/ejabberd_s2s_in.erl: Added support for shapers
-
- * src/ejabberd_c2s.erl: Moved receiver functions to
- ejabberd_receiver module
- * src/ejabberd_s2s_in.erl: Likewise
- * src/ejabberd_receiver.erl: Likewise
-
- * src/mod_muc/mod_muc_room.erl: Bugfix
-
- * src/ejabberd_sm.erl (route_message/3): Bugfix
-
-2003-11-09 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_sm.erl: Bugfix for previous resource handling
- change
-
- * src/mod_configure.erl: Password changing now implemented
-
-2003-11-07 Alexey Shchepin <alexey@sevcom.net>
-
- * src/cyrsasl.erl: Updated SASL authentication
- * src/ejabberd_c2s.erl: Likewise
-
- * src/ejabberd_sm.erl: Better resource handling
-
- * src/jlib.hrl: Added NS_BIND macros
-
-2003-11-06 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_configure2.erl: Added reporting of outgoing S2S
- connections number
-
- * src/mod_disco.erl (get_outgoing_s2s): Minor fix
-
-2003-11-02 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_configure2.erl: Yet another configure interface (not
- completed yet)
-
-2003-11-01 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_last.erl: Added remove_user/1 function
-
- * src/mod_configure.erl: Removing of user's stuff moved to
- ejabberd_auth
- * src/ejabberd_auth.erl: Likewise
-
-2003-10-31 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/mod_irc_connection.erl: Updated to work more
- correctly with latest jlib
-
-2003-10-30 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: More strong check for authenticated JID
-
- * src/mod_roster.erl: Bugfix
-
-2003-10-29 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_listener.erl: Fixed starting of SSL connection
-
- * src/ejabberd_s2s_in.erl: Partially rewriten
-
- * src/ejabberd_router.erl: More verbose error report
- * src/ejabberd_local.erl: Likewise
- * src/ejabberd_sm.erl: Likewise
-
- * src/ejabberd_s2s_out.erl: Updated to be compatible with R9C
-
- * src/ejabberd_c2s.erl: Minor fix
-
-2003-10-28 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_listener.erl: Added handling of accept errors,
- added timeout value to ssl:accept
-
- * src/mod_vcard.erl: Added checks for all empty input fields
-
- * src/mod_offline.erl: More strong checks for stored packets
-
- * src/ejabberd_sm.erl: Bugfix
-
-2003-10-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_auth.erl: Minor change in check_password/4
-
- * src/mod_roster.erl: Workaround for PSI bug with roster
-
- * src/ejabberd_logger_h.erl: Added support for log rotation
-
-2003-10-24 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_offline.erl: Added function remove_old_messages/1
-
- * src/mod_last.erl: jabber:iq:last support (JEP-0012)
- * src/ejabberd_sm.erl: Likewise
-
- * src/jlib.hrl: Added NS_LAST macros
-
-2003-10-23 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_logger_h.erl: New error_logger handler
- * src/ejabberd_app.erl: Now uses ejabberd_logger_h.erl
-
-2003-10-21 Alexey Shchepin <alexey@sevcom.net>
-
- * src/Makefile.in: Added install rule
-
- * src/jlib.erl: Added checks for JID parts length
-
-2003-10-20 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_vcard.erl: Added checks for stringprep results
-
- * src/expat_erl.c: Workaround for EI encode_string bug
-
- * src/xml_stream.erl: Slightly changed protocol to expat driver
- * src/expat_erl.c: Likewise
-
- * src/mod_configure.erl: Minor fix
-
-2003-10-19 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Fixed typo
-
- * src/ejabberd_local.erl: Added support for announce/online
- messages
-
- * src/ejabberd.cfg.example: Updated
-
- * src/mod_register.erl: Added support for sending registration
- notifications
-
-2003-10-18 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_service.erl: Added supports for multiple hosts per
- service
-
- * src/Makefile.in: Minor fix
-
-2003-10-17 Alexey Shchepin <alexey@sevcom.net>
-
- * src/configure.ac: Build system now done using autoconf (thanks
- to Balabanov Dmitry)
- * src/aclocal.m4: Likewise
- * src/**/Makefile.in: Likewise
-
- * src/mod_roster.erl (process_item_set_t): Slightly improved
- performance
-
- * src/jd2ejd.erl: Added missed closing of XML stream process,
- removed timeout value from import_file/1
-
- * src/ejabberd_auth.erl: Added checks for invalid user name
-
-2003-10-16 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_configure.erl: Fixed some error codes
-
- * src/cyrsasl_digest.erl: Bugfix (thanks to Justin Karneges)
-
-2003-10-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_local.erl: Bugfix
-
- * src/mod_register.erl: Added support for sending of "welcome"
- message
- * src/ejabberd.cfg.example: Updated
-
- * src/ejabberd_s2s_out.erl: Replaced "_jabber-server" with
- "_xmpp-server"
-
-2003-10-12 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Updated
-
- * src/ejabberd_s2s_out.erl: Added support for IPv6 and
- "_jabber-server.tcp" lookups
-
- * src/jlib.erl (string_to_jid1): Bugfix
-
- * src/ejabberd_config.erl: Now possible to specify path to config
- file in command line
-
-2003-10-11 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Updated
-
- * src/ejabberd.cfg: Added "register" rule, added some comments,
- this file renamed to ejabberd.cfg.example
-
- * src/mod_register.erl (try_register): Fixed error reply, added
- check for "register" access rule
-
-2003-10-10 Alexey Shchepin <alexey@sevcom.net>
-
- * src/stringprep/Makefile.win32: Added Makefile for Win32 (thanks
- to Sergei Golovan)
-
- * src/stringprep/stringprep_drv.c: Removed needless iconv.h
- include
-
- * src/ejabberd_c2s.erl: Added filtering of presence packets with
- privacy rules
-
- * src/mod_roster.erl (get_jid_info): Bugfix
-
- * src/ejabberd_app.erl: Removed periodical dumping of opened ports
-
-2003-10-09 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Added authentication logging
-
- * src/ejabberd_listener.erl: Added logging of accepted connections
-
- * src/stringprep/stringprep_drv.c: Cleanup
-
- * src/jd2ejd.erl: Added support for iq:private importing
-
- * src/mod_configure.erl: Fixed user removal
-
- * src/mod_private.erl: Added remove_user/1
-
- * doc/guide.tex: Updated
-
- * src/mod_disco.erl: Added "extra_domains" option
-
-2003-10-08 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Added support for "jid-malformed" error
-
- * src/stringprep/stringprep_drv.c: Bugfix
-
-2003-10-07 Alexey Shchepin <alexey@sevcom.net>
-
- * (all): Changed JID storage format, added support for stringprep
-
- * src/stringprep/: Added support for Unicode normalization form KC
-
-2003-10-05 Alexey Shchepin <alexey@sevcom.net>
-
- * src/stringprep/: Added support for case convertion to multiple
- characters
-
- * src/cyrsasl_digest.erl: Temporary removed "auth-int" QOP
-
-2003-09-28 Alexey Shchepin <alexey@sevcom.net>
-
- * src/stringprep/stringprep_drv.c: Added support for nameprep,
- nodeprep and resourceprep
- * src/stringprep/stringprep.erl: Likewise
-
- * src/ejabberd_sup.erl: Added loading of stringprep
-
- * src/ejabberd_sm.erl: Cleanup
-
-2003-09-26 Alexey Shchepin <alexey@sevcom.net>
-
- * src/stringprep/: Support for stringprep (not completed yet)
-
-2003-09-24 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc.erl: Replaced io:format calls to ?DEBUG ones
-
-2003-09-19 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Debug output switched off
-
- * src/mod_disco.erl: Server identity changed to "service/im"
-
- * src/mod_register.erl: Fixed jabber:iq:register handler
- registration, fixed registration removal processing
-
-2003-09-16 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_disco.erl: Now only admin can discovery some nodes,
- fixed "node" attribute in replies
-
-2003-09-10 Alexey Shchepin <alexey@sevcom.net>
-
- * examples/mtr/ejabberd.cfg: Updated (thanks to Marshall T. Rose)
- * examples/mtr/ejabberd: Likewise
-
-2003-09-06 Alexey Shchepin <alexey@sevcom.net>
-
- * examples/mtr/ejabberd.cfg: Updated (thanks to Marshall T. Rose)
-
-2003-09-04 Alexey Shchepin <alexey@sevcom.net>
-
- * examples/mtr/*: Example config and scripts for NetBSD (thanks to
- Marshall T. Rose)
-
-2003-09-03 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_s2s_in.erl: Fixed "id" attribute processing
- * src/ejabberd_s2s_out.erl: Likewise
-
- * src/ejabberd_c2s.erl: Added sending of empty <stream:features/>
- element after opening of authenticated stream
-
-2003-09-02 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_s2s_in.erl: Temporary hack for "id" attribute
- processing
- * src/ejabberd_s2s_out.erl: Likewise
-
-2003-08-30 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_listener.erl: Fixed SSL options
-
-2003-08-18 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Support for filtering of incoming messages
- and IQs, presence filtering will be after some xmpp-im
- clarifications
-
-2003-08-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc.erl: Fixed handling of room names with
- uppercase letters
-
- * src/mod_muc/mod_muc_room.erl: Added support for
- password-protected rooms
-
-2003-08-12 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/mod_irc_connection.erl: Added handling for
- jabber:iq:version and jabber:iq:time requests, participant address
- now added to presence status
-
-2003-08-03 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_privacy.erl: Privacy rules support (not completed yet)
- * src/ejabberd_c2s.erl: Likewise
- * src/mod_roster.erl: Likewise
-
-2003-07-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_pubsub/mod_pubsub.erl (create_new_node): Bugfix
-
-2003-07-21 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_vcard.erl: Bugfix
-
- * src/mod_roster.erl: Bugfix
-
- * src/jlib.hrl: Added iq:privacy namespace
-
- * src/mod_irc/mod_irc_connection.erl: Added support for NOTICE and
- CODEPAGE commands, better support for QUIT and PART commands
- (thanks to Oleg V. Motienko)
-
-2003-07-20 Alexey Shchepin <alexey@sevcom.net>
-
- * (all): Reorganized supervision tree
-
-2003-07-19 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_register.erl: Bugfix
-
-2003-07-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_s2s_out.erl: Close connection after key
- verification
-
- * src/ejabberd_c2s.erl: start replaced with start_link
- * src/ejabberd_s2s_in.erl: Likewise
- * src/ejabberd_s2s_out.erl: Likewise
- * src/ejabberd_service.erl: Likewise
-
- * src/ejabberd_listener.erl: Now uses proc_lib to spawn listeners,
- removed 3rd parameter in listener configuration (assumed to equal
- start_link)
-
- * src/ejabberd.rel: Updated
-
- * doc/guide.tex: Small changes
-
- * doc/Makefile: Added implicit charset specification to hevea
-
-2003-07-12 Alexey Shchepin <alexey@sevcom.net>
-
- * doc/guide.tex: Updated (thanks to Sergei Golovan)
-
- * src/expat_erl.c: Added #ifdef for WIN32 (thanks to Sergei
- Golovan)
- * src/mod_irc/iconv_erl.c: Likewise
-
- * src/configure.erl: Defines ERLANG_DIR variable (thanks to Sergei
- Golovan)
- * **/Makefile: Use ERLANG_DIR (thanks to Sergei Golovan)
-
- * **/Makefile.win32: Makefiles for windows build (thanks to Sergei
- Golovan)
- * src/configure.bat: Configuration script for windows (thanks to
- Sergei Golovan)
-
-2003-07-09 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_pubsub/mod_pubsub.erl: Added suport for meta-node
- "pubsub/nodes"
-
-2003-07-08 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_pubsub/mod_pubsub.erl: Most of functions now works
-
-2003-07-07 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_pubsub/mod_pubsub.erl: Pub/sub implementation (not
- completed yet)
-
-2003-07-05 Alexey Shchepin <alexey@sevcom.net>
-
- * src/jlib.hrl: Added pub/sub namespaces
-
-2003-07-03 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/iconv_erl.c (iconv_erl_control): Bugfix
-
-2003-06-30 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Fixed room destroying
- * src/mod_muc/mod_muc.erl: Likewise
-
-2003-06-29 Alexey Shchepin <alexey@sevcom.net>
-
- * src/jlib.hrl: Error stanzas updated to confirm latest xmpp-core
-
-2003-06-20 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Returned stream restarting
-
-2003-06-10 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Removed stream restarting
-
-2003-06-07 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: SASL support updated to xmpp-core-13
-
-2003-06-06 Alexey Shchepin <alexey@sevcom.net>
-
- * src/cyrsasl*.erl: Support for authzid
-
-2003-06-03 Alexey Shchepin <alexey@sevcom.net>
-
- * src/msgs/fr.msg: New french translation (thanks to Vincent Ricard)
-
-2003-05-31 Alexey Shchepin <alexey@sevcom.net>
-
- * src/jlib.hrl: Updated SASL namespace
-
-2003-05-29 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_service.erl: Proper handling of bad XML
-
- * src/mod_muc/mod_muc_room.erl: Append number of participants in
- disco replies if requester allowed to see participant list
-
- * src/mod_muc/mod_muc.erl (iq_disco_items): Pass requester JID to
- room process
-
- * src/mod_irc/mod_irc_connection.erl: Exit on receiving of
- presence or message error
-
- * src/mod_irc/mod_irc_connection.erl (handle_info): Return
- "feature not implemented" on iq request with unknown namespace
-
-2003-05-18 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc.erl: Now body of message from admin to MUC
- service is broadcasted to all conferences
- * src/mod_muc/mod_muc_room.erl: Likewise
-
-2003-05-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_s2s.erl: Added error catching for do_route/3
- * src/ejabberd_local.erl: Likewise for do_route/4
-
- * src/msgs/ru.msg: Updated
-
- * src/mod_muc/mod_muc_room.erl: New option to allow to view list
- of participants for non-ones via disco#items
-
- * src/mod_muc/mod_muc_room.erl: Store room subject with
- configuration options
-
-2003-05-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Remove user from room on receiving
- of message or presence error from him
-
-2003-05-12 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_s2s_out.erl: Fixed error replies, added timeouts
- * src/ejabberd_s2s_in.erl: Likewise
-
-2003-05-09 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_local.erl: Updated missed errors to new style
- * src/mod_register.erl: Likewise
- * src/mod_version.erl: Likewise
- * src/mod_time.erl: Likewise
- * src/mod_stats.erl: Likewise
- * src/mod_register.erl: Likewise
- * src/mod_private.erl: Likewise
- * src/mod_configure.erl: Likewise
- * src/ejabberd_sm.erl: Likewise
- * src/ejabberd_service.erl: Likewise
- * src/ejabberd_c2s.erl: Likewise
- * src/ejabberd_s2s_out.erl: Likewise
- * src/mod_vcard.erl: Likewise
- * src/mod_roster.erl: Likewise
-
- * src/mod_muc/mod_muc.erl: Added vcard to mod_muc module
-
- * src/ejabberd_app.erl: Dump list of opened ports every hour
-
- * src/ejabberd.hrl: Added INFO_MSG macros, ERROR_LOG_PATH renamed
- to LOG_PATH
-
-2003-05-08 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc.erl: Denied usage of empty nick
-
-2003-05-07 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc.erl: Return bad-request if no x:data form
- submited with nick registration
-
- * src/mod_muc/mod_muc_room.erl: Don't check permissions on disco
- info query processing
-
-2003-04-29 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Workaround to make SSL work properly
-
-2003-04-28 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/mod_irc_connection.erl: Fixed URL to ejabberd
-
-2003-04-17 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc.erl: Support for nick registration
-
-2003-04-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Some fixes in work with socket
-
-2003-04-13 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Support for members-only
- conferences, invitations. Bugfix in affiliation change processing
-
- * src/jlib.hrl: Added jabber:x:conference namespace definition
-
-2003-04-07 Alexey Shchepin <alexey@sevcom.net>
-
- * src/jlib.hrl: Added jaber:iq:auth:error namespace and
- appropriate errors
- * src/ejabberd_c2s.erl: Use auth:error in appropriate places
-
- * src/jlib.hrl: Changed stream error and stanza error namespace
- names due to last XMPP Core changes
-
-2003-03-28 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/mod_muc_room.erl: Added support for grant/revoke
- administrative/owner priveledges, fixed work with affiliations
-
-2003-03-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd.cfg: Updated
-
- * src/mod_muc/mod_muc_room.erl: Support for service admin,
- kick/ban reasons, more options
-
- * src/msgs/ru.msg: Added translations for MUC messages
-
- * src/ejabberd_s2s_in.erl: Bugfix
-
- * src/mod_muc/: Small fixes in discovering
-
-2003-03-26 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/: Support for discovering service and more
- configuration options
-
-2003-03-25 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/: Support for more configuration options and
- persistent rooms
-
-2003-03-23 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_muc/: MUC support (not completed yet)
-
-2003-03-15 Alexey Shchepin <alexey@sevcom.net>
-
- * src/xml_stream.erl: Removed "link" which cause not improper
- closing of xml connections
-
-2003-03-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/jlib.hrl: Added "invalid-namespace" error
- * src/ejabberd_c2s.erl: Likewise
-
-2003-03-12 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_s2s_out.erl: Fixed ports leak
- * src/ejabberd_listener.erl: Likewise
-
- * src/ejabberd_c2s.erl: Fixes for SASL support
-
- * src/cyrsasl.erl: Fixes
-
- * src/cyrsasl_digest.erl: DIGEST-MD5 SASL mechanism support
-
-2003-03-09 Alexey Shchepin <alexey@sevcom.net>
-
- * src/cyrsasl*.erl: SASL support (currently support only PLAIN
- mechanism)
- * src/ejabberd_c2s.erl: Likewise
-
- (all): Support for new-style error elements (except old errors
- "Not Acceptable", "Not Found", "Invalid Namespace" and "Server
- Connect Failed", so ejabberd may work unstable)
-
-2003-03-02 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: More correct stream closing
-
-2003-02-27 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/mod_irc_connection.erl: Support for topic changes
-
-2003-02-24 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/mod_irc_connection.erl: /kick support
-
-2003-02-23 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/: Added configuration interface
-
- * src/mod_configure.erl: Use jabber:iq:data instead of
- jabber:x:data
- * src/mod_disco.erl: Likewise
-
-2003-02-22 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_configure.erl: Backup management support
- * src/mod_disco.erl: Likewise
-
-2003-02-21 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_offline.erl: Now possible to unload this module
- * src/ejabberd_sm.erl: Added checks to work correctly when
- mod_offline not loaded
- * src/ejabberd_c2s.erl: Likewise
-
- * src/mod_register.erl: Added support for users removal
-
- * src/ejabberd_auth.erl: Added function to remove user only if
- specified password correct
-
- * src/mod_irc/mod_irc_connection.erl: Fixed bug with changing
- availability status, added processing of "QUIT" message
-
-2003-02-20 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_roster.erl: Fixed bug with handling of roster set
- stanzas which contains CDATA
-
- * src/mod_irc/mod_irc_connection.erl (handle_info/3): Fixed
- parsing of string that have "\n" line separators (not "\r\n")
-
-2003-02-18 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/: Added support for private chats, nicks changes and
- error handling
-
-2003-02-17 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/: Still not completed...
-
-2003-02-16 Alexey Shchepin <alexey@sevcom.net>
-
- * src/mod_irc/: New IRC transport (not completed yet)
-
-2003-02-14 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_service.erl: Answer "Bad Request" on unknown tags
-
-2003-02-13 Alexey Shchepin <alexey@sevcom.net>
-
- * src/ejabberd_c2s.erl: Bugfix: close socket when stream is closed
-
- * src/mod_offline.erl: Now all offline packets processed in
- separate queue to avoid delaying of other packets transmission.
- Also all packets in queue processed in one transaction.
-
-2003-02-11 Alexey Shchepin <alexey@sevcom.net>
-
- * (all): Version 0.1-alpha released
-
diff --git a/ejabberd-1.1.2/TODO b/ejabberd-1.1.2/TODO
deleted file mode 100644
index a98d63f0a..000000000
--- a/ejabberd-1.1.2/TODO
+++ /dev/null
@@ -1,14 +0,0 @@
-Win32 build: Make it possible to compile with +debug_info flag.
-
-admin interface
- users management
- statistics about each user
- statistics about each connection
-
-S2S:
- check "id" attributes in db:verify packets
-
-make roster set to work in one transaction
-add traffic shapers to c2s connection before authentification
-more traffic shapers
-SNMP
diff --git a/ejabberd-1.1.2/contrib/extract_translations/README b/ejabberd-1.1.2/contrib/extract_translations/README
deleted file mode 100644
index 9278dd106..000000000
--- a/ejabberd-1.1.2/contrib/extract_translations/README
+++ /dev/null
@@ -1,21 +0,0 @@
-extract_translations - auxiliary tool that extracts lines to be translated
-from ejabberd source tree.
-
-Building:
- erlc extract_translations.erl
-
-Invoking 1:
- erl -noinput -s extract_translations -extra dirname message_file
-
- where dirname is the directory "src" in ejabberd's source tree root,
- message_file is a file with translated messages (src/msgs/*.msg).
-
- Result is a list of messages from source files which aren't contained in
- message file.
-
-Invoking 2:
- erl -noinput -s extract_translations -extra -unused dirname message_file
-
- Result is a list of messages from message file which aren't in source
- files anymore.
-
diff --git a/ejabberd-1.1.2/contrib/extract_translations/extract_translations.erl b/ejabberd-1.1.2/contrib/extract_translations/extract_translations.erl
deleted file mode 100644
index 01788c504..000000000
--- a/ejabberd-1.1.2/contrib/extract_translations/extract_translations.erl
+++ /dev/null
@@ -1,190 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : extract_translations.erl
-%%% Author : Sergei Golovan <sgolovan@nes.ru>
-%%% Purpose : Auxiliary tool for interface/messages translators
-%%% Created : 23 Apr 2005 by Sergei Golovan <sgolovan@nes.ru>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(extract_translations).
--author('sgolovan@nes.ru').
-
--export([start/0]).
-
--define(STATUS_SUCCESS, 0).
--define(STATUS_ERROR, 1).
--define(STATUS_USAGE, 2).
-
--include_lib("kernel/include/file.hrl").
-
-
-start() ->
- ets:new(translations, [named_table, public]),
- ets:new(files, [named_table, public]),
- ets:new(vars, [named_table, public]),
- case init:get_plain_arguments() of
- ["-unused", Dir, File] ->
- Status = process(Dir, File, unused),
- halt(Status);
- [Dir, File] ->
- Status = process(Dir, File, used),
- halt(Status);
- _ ->
- print_usage(),
- halt(?STATUS_USAGE)
- end.
-
-
-process(Dir, File, Used) ->
- case load_file(File) of
- {error, Reason} ->
- io:format("~s: ~s~n", [File, file:format_error(Reason)]),
- ?STATUS_ERROR;
- _ ->
- FileList = find_src_files(Dir),
- lists:foreach(
- fun(F) ->
- parse_file(Dir, F, Used)
- end, FileList),
- case Used of
- unused ->
- ets:foldl(fun({Key, _}, _) ->
- io:format("~p~n", [Key])
- end, ok, translations);
- _ ->
- ok
- end,
- ?STATUS_SUCCESS
- end.
-
-parse_file(Dir, File, Used) ->
- ets:delete_all_objects(vars),
- case epp:parse_file(File, [Dir, filename:dirname(File)], []) of
- {ok, Forms} ->
- lists:foreach(
- fun(F) ->
- parse_form(Dir, File, F, Used)
- end, Forms);
- _ ->
- ok
- end.
-
-parse_form(Dir, File, Form, Used) ->
- case Form of
- {call,
- _,
- {remote, _, {atom, _, translate}, {atom, _, translate}},
- [_, {string, _, Str}]
- } ->
- process_string(Dir, File, Str, Used);
- {call,
- _,
- {remote, _, {atom, _, translate}, {atom, _, translate}},
- [_, {var, _, Name}]
- } ->
- case ets:lookup(vars, Name) of
- [{_Name, Value}] ->
- process_string(Dir, File, Value, Used);
- _ ->
- ok
- end;
- {match,
- _,
- {var, _, Name},
- {string, _, Value}
- } ->
- ets:insert(vars, {Name, Value});
- L when is_list(L) ->
- lists:foreach(
- fun(F) ->
- parse_form(Dir, File, F, Used)
- end, L);
- T when is_tuple(T) ->
- lists:foreach(
- fun(F) ->
- parse_form(Dir, File, F, Used)
- end, tuple_to_list(T));
- _ ->
- ok
- end.
-
-process_string(_Dir, File, Str, Used) ->
- case {ets:lookup(translations, Str), Used} of
- {[{_Key, _Trans}], unused} ->
- ets:delete(translations, Str);
- {[{_Key, _Trans}], used} ->
- ok;
- {_, used} ->
- case ets:lookup(files, File) of
- [{_}] ->
- ok;
- _ ->
- io:format("~n% ~s~n", [File]),
- ets:insert(files, {File})
- end,
- io:format("{~p, \"\"}.~n", [Str]),
- ets:insert(translations, {Str, ""});
- _ ->
- ok
- end.
-
-load_file(File) ->
- case file:consult(File) of
- {ok, Terms} ->
- lists:foreach(
- fun({Orig, Trans}) ->
- case Trans of
- "" ->
- ok;
- _ ->
- ets:insert(translations, {Orig, Trans})
- end
- end, Terms);
- Err ->
- Err
- end.
-
-find_src_files(Dir) ->
- case file:list_dir(Dir) of
- {ok, FileList} ->
- recurse_filelist(
- lists:map(
- fun(F) ->
- filename:join(Dir, F)
- end, FileList));
- _ ->
- []
- end.
-
-recurse_filelist(FileList) ->
- recurse_filelist(FileList, []).
-
-recurse_filelist([], Acc) ->
- lists:reverse(Acc);
-
-recurse_filelist([H | T], Acc) ->
- case file:read_file_info(H) of
- {ok, #file_info{type = directory}} ->
- recurse_filelist(T, lists:reverse(find_src_files(H)) ++ Acc);
- {ok, #file_info{type = regular}} ->
- case string:substr(H, string:len(H) - 3) of
- ".erl" ->
- recurse_filelist(T, [H | Acc]);
- ".hrl" ->
- recurse_filelist(T, [H | Acc]);
- _ ->
- recurse_filelist(T, Acc)
- end;
- _ ->
- recurse_filelist(T, Acc)
- end.
-
-
-print_usage() ->
- io:format(
- "Usage: extract_translations [-unused] dir file~n"
- "~n"
- "Example:~n"
- " extract_translations . ./msgs/ru.msg~n"
- ).
-
diff --git a/ejabberd-1.1.2/contrib/extract_translations/prepare-translation.sh b/ejabberd-1.1.2/contrib/extract_translations/prepare-translation.sh
deleted file mode 100755
index 64bd03993..000000000
--- a/ejabberd-1.1.2/contrib/extract_translations/prepare-translation.sh
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/bin/bash
-
-# Frontend for ejabberd's extract_translations.erl
-# by Badlop
-# last updated: 8 December 2005
-
-while [ "$1" != "" ]
-do
- case "$1" in
- -help)
- echo "Options:"
- echo " -lang LANGUAGE"
- echo " -src FULL_PATH_EJABBERD"
- echo ""
- echo "Example:"
- echo " ./prepare-translation.sh -lang es -src /home/admin/ejabberd"
- exit 0
- ;;
- -lang)
- # This is the language to be extracted
- LANGU=$2
- shift
- shift
- ;;
- -src)
- # This is the path to the ejabberd source dir
- EJA_DIR=$2
- shift
- shift
- ;;
- *)
- echo "unknown option: '$1 $2'"
- shift
- shift
- ;;
- esac
-done
-
-# Where is Erlang binary
-ERL=`which erl`
-
-EXTRACT_DIR=$EJA_DIR/contrib/extract_translations/
-EXTRACT_ERL=extract_translations.erl
-EXTRACT_BEAM=extract_translations.beam
-SRC_DIR=$EJA_DIR/src
-MSGS_DIR=$SRC_DIR/msgs
-MSGS_FILE=$LANGU.msg
-MSGS_FILE2=$LANGU.msg.translate
-MSGS_PATH=$MSGS_DIR/$MSGS_FILE
-MSGS_PATH2=$MSGS_DIR/$MSGS_FILE2
-
-if !([[ -n $EJA_DIR ]])
-then
-echo "ejabberd dir does not exist: $EJA_DIR"
-fi
-
-if !([[ -x $EXTRACT_BEAM ]])
-then
-echo -n "Compiling extract_translations.erl: "
-sh -c "cd $EXTRACT_DIR; $ERL -compile $EXTRACT_ERL"
-fi
-
-echo ""
-echo -n "Extracting language strings for '$LANGU':"
-
-echo -n " new..."
-$ERL -pa $EXTRACT_DIR -noinput -noshell -s extract_translations -s init stop -extra $SRC_DIR $MSGS_PATH >$MSGS_PATH.new
-
-echo -n " old..."
-$ERL -pa $EXTRACT_DIR -noinput -noshell -s extract_translations -s init stop -extra -unused $SRC_DIR $MSGS_PATH >$MSGS_PATH.unused
-
-cat $MSGS_PATH >$MSGS_PATH2
-
-echo "" >>$MSGS_PATH2
-
-cat $MSGS_PATH.new >>$MSGS_PATH2
-rm $MSGS_PATH.new
-echo "" >>$MSGS_PATH2
-
-cat $MSGS_PATH.unused >>$MSGS_PATH2
-rm $MSGS_PATH.unused
-
-echo " ok"
-
-echo ""
-echo "Process completed."
-
-echo ""
-echo " A new file has been created for you, with the current, the new and the deprecated strings:"
-echo " $MSGS_PATH2"
-echo ""
-echo " At the end of that file you will find the strings you must update:"
-echo " - Untranslated strings are like this: {"March", ""}."
-echo " To translate the string, add the text inside the commas. Example:"
-echo " {"March", "Marzo"}."
-echo " - Old strings that are not used: "Woowoa""
-echo " Search the entire file for those strings and remove them"
-echo ""
-echo " Once you have translated all the strings and removed all the old ones,"
-echo " rename the file to overwrite the previous one:"
-echo " $MSGS_PATH"
diff --git a/ejabberd-1.1.2/doc/Makefile b/ejabberd-1.1.2/doc/Makefile
deleted file mode 100644
index 7736855f3..000000000
--- a/ejabberd-1.1.2/doc/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-# $Id$
-
-all: release pdf html
-
-release:
- @echo "Notes for the releaser:"
- @echo "* Do not forget to add a link to the release notes in guide.tex"
- @echo "* Do not forget to change the version number in version.tex"
- @echo "* Do not forget to update the features in introduction.tex (including \new{} and \improved{} tags)."
- @read -p "press any key to continue"
-
-html: guide.html dev.html features.html
-
-pdf: guide.pdf features.pdf
-
-clean:
- rm -f *.aux
- rm -f *.haux
- rm -f *.html
- rm -f *.htoc
- rm -f *.idx
- rm -f *.ilg
- rm -f *.ind
- rm -f *.log
- rm -f *.out
- rm -f *.pdf
- rm -f *.toc
-
-guide.html: guide.tex
- hevea -fix -noiso -pedantic guide.tex
-
-dev.html: dev.tex
- hevea -fix -noiso -pedantic dev.tex
-
-features.html: features.tex
- hevea -fix -noiso -pedantic features.tex
-
-guide.pdf: guide.tex
- pdflatex guide.tex
- pdflatex guide.tex
- pdflatex guide.tex
- makeindex guide.idx
- pdflatex guide.tex
-
-features.pdf: features.tex
- pdflatex features.tex
diff --git a/ejabberd-1.1.2/doc/dev.html b/ejabberd-1.1.2/doc/dev.html
deleted file mode 100644
index 0c0472f76..000000000
--- a/ejabberd-1.1.2/doc/dev.html
+++ /dev/null
@@ -1,449 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
- "http://www.w3.org/TR/REC-html40/loose.dtd">
-<HTML>
-
-<HEAD>
-
-<TITLE>Ejabberd 1.1.2 Developers Guide</TITLE>
-
-<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-<META name="GENERATOR" content="hevea 1.08">
-<STYLE type="text/css">
-.toc{list-style:none;}
-.title{margin:auto;text-align:center}
-.center{text-align:center;margin-left:auto;margin-right:auto;}
-.flushleft{text-align:left;margin-left:0ex;margin-right:auto;}
-.flushright{text-align:right;margin-left:auto;margin-right:0ex;}
-DIV TABLE{margin-left:inherit;margin-right:inherit;}
-PRE{text-align:left;margin-left:0ex;margin-right:auto;}
-BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
-.part{margin:auto;text-align:center}
-</STYLE>
-</HEAD>
-
-<BODY >
-<!--HEVEA command line is: hevea -fix -noiso -pedantic dev.tex -->
-<!--HTMLHEAD-->
-<!--ENDHTML-->
-<!--PREFIX <ARG ></ARG>-->
-<!--CUT DEF section 1 -->
-
-<BR>
-<BR>
-<A NAME="sec:titlepage"></A>
-
- <TABLE CLASS="title">
-<TR><TD>
-<H1 CLASS="titlemain">Ejabberd 1.1.2 Developers Guide</H1>
-<H3 CLASS="titlerest">Alexey Shchepin<BR>
-<A HREF="mailto:alexey@sevcom.net"><TT>mailto:alexey@sevcom.net</TT></A><BR>
-<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT></A></H3></TD>
-</TR></TABLE><BR>
-<BR>
-<DIV CLASS="center">
-
- <IMG SRC="logo.png" ALT="logo.png">
-
-
- <BR>
-<BR>
-
- </DIV>
-<BLOCKQUOTE CLASS="quotation"><I>I can thoroughly recommend ejabberd for ease of setup &ndash;
- Kevin Smith, Current maintainer of the Psi project</I></BLOCKQUOTE>
-<!--TOC section Contents-->
-
-<H2 CLASS="section">Contents</H2><!--SEC END -->
-
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc1">1&nbsp;&nbsp;Introduction</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc2">1.1&nbsp;&nbsp;Key Features</A>
-<LI CLASS="li-toc"><A HREF="#htoc3">1.2&nbsp;&nbsp;Additional Features</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc4">2&nbsp;&nbsp;How it Works</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc5">2.1&nbsp;&nbsp;Router</A>
-<LI CLASS="li-toc"><A HREF="#htoc6">2.2&nbsp;&nbsp;Local Router</A>
-<LI CLASS="li-toc"><A HREF="#htoc7">2.3&nbsp;&nbsp;Session Manager</A>
-<LI CLASS="li-toc"><A HREF="#htoc8">2.4&nbsp;&nbsp;S2S Manager</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc9">3&nbsp;&nbsp;XML Representation</A>
-<LI CLASS="li-toc"><A HREF="#htoc10">4&nbsp;&nbsp;Module <TT>xml</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc11">5&nbsp;&nbsp;Module <TT>xml_stream</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc12">6&nbsp;&nbsp;Modules</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc13">6.1&nbsp;&nbsp;Module gen_iq_handler</A>
-<LI CLASS="li-toc"><A HREF="#htoc14">6.2&nbsp;&nbsp;Services</A>
-</UL>
-</UL>
-
-<!--TOC section Introduction-->
-
-<H2 CLASS="section"><A NAME="htoc1">1</A>&nbsp;&nbsp;<A NAME="intro">Introduction</A></H2><!--SEC END -->
-
-<A NAME="sec:intro"></A>
-
-<TT>ejabberd</TT> is a free and open source instant messaging server written in <A HREF="http://www.erlang.org/">Erlang</A>.<BR>
-<BR>
-<TT>ejabberd</TT> is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication.<BR>
-<BR>
-<TT>ejabberd</TT> is designed to be a rock-solid and feature rich XMPP server.<BR>
-<BR>
-<TT>ejabberd</TT> is suitable for small deployments, whether they need to be scalable or not, as well as extremely big deployments.<BR>
-<BR>
-<!--TOC subsection Key Features-->
-
-<H3 CLASS="subsection"><A NAME="htoc2">1.1</A>&nbsp;&nbsp;<A NAME="keyfeatures">Key Features</A></H3><!--SEC END -->
-
-<A NAME="sec:keyfeatures"></A>
-
-<TT>ejabberd</TT> is:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Cross-platform: <TT>ejabberd</TT> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.<BR>
-<BR>
-<LI CLASS="li-itemize">Distributed: You can run <TT>ejabberd</TT> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.<BR>
-<BR>
-<LI CLASS="li-itemize">Fault-tolerant: You can deploy an <TT>ejabberd</TT> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced `on the fly'.<BR>
-<BR>
-<LI CLASS="li-itemize">Administrator Friendly: <TT>ejabberd</TT> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Comprehensive documentation.
-<LI CLASS="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows.
-<LI CLASS="li-itemize">Web interface for administration tasks.
-<LI CLASS="li-itemize">Shared Roster Groups.
-<LI CLASS="li-itemize">Command line administration tool.
-<LI CLASS="li-itemize">Can integrate with existing authentication mechanisms.
-<LI CLASS="li-itemize">Capability to send announce messages.
-</UL><BR>
-<BR>
-<LI CLASS="li-itemize">Internationalized: <TT>ejabberd</TT> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Translated in 12 languages.
-<LI CLASS="li-itemize">Support for <A HREF="http://www.ietf.org/rfc/rfc3490.txt">IDNA</A>.
-</UL><BR>
-<BR>
-<LI CLASS="li-itemize">Open Standards: <TT>ejabberd</TT> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Fully XMPP compliant.
-<LI CLASS="li-itemize">XML-based protocol.
-<LI CLASS="li-itemize"><A HREF="http://ejabberd.jabber.ru/protocols">Many JEPs supported</A>.
-</UL></UL>
-<!--TOC subsection Additional Features-->
-
-<H3 CLASS="subsection"><A NAME="htoc3">1.2</A>&nbsp;&nbsp;<A NAME="addfeatures">Additional Features</A></H3><!--SEC END -->
-
-<A NAME="sec:addfeatures"></A>
-
-Moreover, <TT>ejabberd</TT> comes with a wide range of other state-of-the-art features:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Modular
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Load only the modules you want.
-<LI CLASS="li-itemize">Extend <TT>ejabberd</TT> with your own custom modules.
-</UL>
-<LI CLASS="li-itemize">Security
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-SASL and STARTTLS for c2s and s2s connections.
-<LI CLASS="li-itemize">STARTTLS and Dialback s2s connections.
-<LI CLASS="li-itemize">Web interface accessible via HTTPS secure access.
-</UL>
-<LI CLASS="li-itemize">Databases
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Native MySQL support.
-<LI CLASS="li-itemize">Native PostgreSQL support.
-<LI CLASS="li-itemize">Mnesia.
-<LI CLASS="li-itemize">ODBC data storage support.
-<LI CLASS="li-itemize">Microsoft SQL Server support.
-</UL>
-<LI CLASS="li-itemize">Authentication
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-LDAP and ODBC.
-<LI CLASS="li-itemize">External Authentication script.
-<LI CLASS="li-itemize">Internal Authentication.
-</UL>
-<LI CLASS="li-itemize">Others
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Compressing XML streams with Stream Compression (<A HREF="http://www.jabber.org/jeps/jep-0138.html">JEP-0138</A>).
-<LI CLASS="li-itemize">Interface with networks such as AIM, ICQ and MSN.
-<LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A>).
-<LI CLASS="li-itemize">IPv6 support both for c2s and s2s connections.
-<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0045.html">Multi-User Chat</A> module with logging.
-<LI CLASS="li-itemize">Users Directory based on users vCards.
-<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0060.html">Publish-Subscribe</A> component.
-<LI CLASS="li-itemize">Support for virtual hosting.
-<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0025.html">HTTP Polling</A> service.
-<LI CLASS="li-itemize">IRC transport.
-</UL>
-</UL>
-<!--TOC section How it Works-->
-
-<H2 CLASS="section"><A NAME="htoc4">2</A>&nbsp;&nbsp;How it Works</H2><!--SEC END -->
-
-<A NAME="sec:howitworks"></A>
-A Jabber domain is served by one or more <TT>ejabberd</TT> nodes. These nodes can
-be run on different machines that are connected via a network. They all must
-have the ability to connect to port 4369 of all another nodes, and must have
-the same magic cookie (see Erlang/OTP documentation, in other words the file
-<TT>~ejabberd/.erlang.cookie</TT> must be the same on all nodes). This is
-needed because all nodes exchange information about connected users, S2S
-connections, registered services, etc...<BR>
-<BR>
-Each <TT>ejabberd</TT> node have following modules:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-router;
-<LI CLASS="li-itemize">local router.
-<LI CLASS="li-itemize">session manager;
-<LI CLASS="li-itemize">S2S manager;
-</UL>
-<!--TOC subsection Router-->
-
-<H3 CLASS="subsection"><A NAME="htoc5">2.1</A>&nbsp;&nbsp;Router</H3><!--SEC END -->
-
-This module is the main router of Jabber packets on each node. It routes
-them based on their destinations domains. It has two tables: local and global
-routes. First, domain of packet destination searched in local table, and if it
-found, then the packet is routed to appropriate process. If no, then it
-searches in global table, and is routed to the appropriate <TT>ejabberd</TT> node or
-process. If it does not exists in either tables, then it sent to the S2S
-manager.<BR>
-<BR>
-<!--TOC subsection Local Router-->
-
-<H3 CLASS="subsection"><A NAME="htoc6">2.2</A>&nbsp;&nbsp;Local Router</H3><!--SEC END -->
-
-This module routes packets which have a destination domain equal to this server
-name. If destination JID has a non-empty user part, then it routed to the
-session manager, else it is processed depending on it's content.<BR>
-<BR>
-<!--TOC subsection Session Manager-->
-
-<H3 CLASS="subsection"><A NAME="htoc7">2.3</A>&nbsp;&nbsp;Session Manager</H3><!--SEC END -->
-
-This module routes packets to local users. It searches for what user resource
-packet must be sended via presence table. If this resource is connected to
-this node, it is routed to C2S process, if it connected via another node, then
-the packet is sent to session manager on that node.<BR>
-<BR>
-<!--TOC subsection S2S Manager-->
-
-<H3 CLASS="subsection"><A NAME="htoc8">2.4</A>&nbsp;&nbsp;S2S Manager</H3><!--SEC END -->
-
-This module routes packets to other Jabber servers. First, it checks if an
-open S2S connection from the domain of the packet source to the domain of
-packet destination already exists. If it is open on another node, then it
-routes the packet to S2S manager on that node, if it is open on this node, then
-it is routed to the process that serves this connection, and if a connection
-does not exist, then it is opened and registered.<BR>
-<BR>
-<!--TOC section XML Representation-->
-
-<H2 CLASS="section"><A NAME="htoc9">3</A>&nbsp;&nbsp;XML Representation</H2><!--SEC END -->
-
-<A NAME="sec:xmlrepr"></A>
-Each XML stanza is represented as the following tuple:
-<PRE CLASS="verbatim">
-XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
- Name = string()
- Attrs = [Attr]
- Attr = {Key, Val}
- Key = string()
- Val = string()
- ElementOrCDATA = XMLElement | CDATA
- CDATA = {xmlcdata, string()}
-</PRE>E.&nbsp;g. this stanza:
-<PRE CLASS="verbatim">
-&lt;message to='test@conference.example.org' type='groupchat'&gt;
- &lt;body&gt;test&lt;/body&gt;
-&lt;/message&gt;
-</PRE>is represented as the following structure:
-<PRE CLASS="verbatim">
-{xmlelement, "message",
- [{"to", "test@conference.example.org"},
- {"type", "groupchat"}],
- [{xmlelement, "body",
- [],
- [{xmlcdata, "test"}]}]}}
-</PRE>
-<!--TOC section Module <TT>xml</TT>-->
-
-<H2 CLASS="section"><A NAME="htoc10">4</A>&nbsp;&nbsp;Module <TT>xml</TT></H2><!--SEC END -->
-
-<A NAME="sec:xmlmod"></A>
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description"><DD CLASS="dd-description"><CODE>element_to_string(El) -&gt; string()</CODE>
-<PRE CLASS="verbatim">
-El = XMLElement
-</PRE>Returns string representation of XML stanza <TT>El</TT>.<BR>
-<BR>
-<DT CLASS="dt-description"><DD CLASS="dd-description"><CODE>crypt(S) -&gt; string()</CODE>
-<PRE CLASS="verbatim">
-S = string()
-</PRE>Returns string which correspond to <TT>S</TT> with encoded XML special
- characters.<BR>
-<BR>
-<DT CLASS="dt-description"><DD CLASS="dd-description"><CODE>remove_cdata(ECList) -&gt; EList</CODE>
-<PRE CLASS="verbatim">
-ECList = [ElementOrCDATA]
-EList = [XMLElement]
-</PRE><TT>EList</TT> is a list of all non-CDATA elements of ECList.<BR>
-<BR>
-<DT CLASS="dt-description"><DD CLASS="dd-description"><CODE>get_path_s(El, Path) -&gt; Res</CODE>
-<PRE CLASS="verbatim">
-El = XMLElement
-Path = [PathItem]
-PathItem = PathElem | PathAttr | PathCDATA
-PathElem = {elem, Name}
-PathAttr = {attr, Name}
-PathCDATA = cdata
-Name = string()
-Res = string() | XMLElement
-</PRE>If <TT>Path</TT> is empty, then returns <TT>El</TT>. Else sequentially
- consider elements of <TT>Path</TT>. Each element is one of:
- <DL CLASS="description" COMPACT=compact><DT CLASS="dt-description"><DD CLASS="dd-description"><CODE>{elem, Name}</CODE> <TT>Name</TT> is name of subelement of
- <TT>El</TT>, if such element exists, then this element considered in
- following steps, else returns empty string.
- <DT CLASS="dt-description"><DD CLASS="dd-description"><CODE>{attr, Name}</CODE> If <TT>El</TT> have attribute <TT>Name</TT>, then
- returns value of this attribute, else returns empty string.
- <DT CLASS="dt-description"><DD CLASS="dd-description"><CODE>cdata</CODE> Returns CDATA of <TT>El</TT>.
- </DL><BR>
-<BR>
-<DT CLASS="dt-description"><DD CLASS="dd-description">TODO:
-<PRE CLASS="verbatim">
- get_cdata/1, get_tag_cdata/1
- get_attr/2, get_attr_s/2
- get_tag_attr/2, get_tag_attr_s/2
- get_subtag/2
-</PRE></DL>
-<!--TOC section Module <TT>xml_stream</TT>-->
-
-<H2 CLASS="section"><A NAME="htoc11">5</A>&nbsp;&nbsp;Module <TT>xml_stream</TT></H2><!--SEC END -->
-
-<A NAME="sec:xmlstreammod"></A>
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description"><DD CLASS="dd-description"><CODE>parse_element(Str) -&gt; XMLElement | {error, Err}</CODE>
-<PRE CLASS="verbatim">
-Str = string()
-Err = term()
-</PRE>Parses <TT>Str</TT> using XML parser, returns either parsed element or error
- tuple.
-</DL>
-<!--TOC section Modules-->
-
-<H2 CLASS="section"><A NAME="htoc12">6</A>&nbsp;&nbsp;Modules</H2><!--SEC END -->
-
-<A NAME="sec:emods"></A>
-<!--TOC subsection Module gen_iq_handler-->
-
-<H3 CLASS="subsection"><A NAME="htoc13">6.1</A>&nbsp;&nbsp;Module gen_iq_handler</H3><!--SEC END -->
-
-<A NAME="sec:geniqhandl"></A>
-The module <CODE>gen_iq_handler</CODE> allows to easily write handlers for IQ packets
-of particular XML namespaces that addressed to server or to users bare JIDs.<BR>
-<BR>
-In this module the following functions are defined:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description"><DD CLASS="dd-description"><CODE>add_iq_handler(Component, Host, NS, Module, Function, Type)</CODE>
-<PRE CLASS="verbatim">
-Component = Module = Function = atom()
-Host = NS = string()
-Type = no_queue | one_queue | parallel
-</PRE>Registers function <CODE>Module:Function</CODE> as handler for IQ packets on
- virtual host <CODE>Host</CODE> that contain child of namespace <CODE>NS</CODE> in
- <CODE>Component</CODE>. Queueing discipline is <CODE>Type</CODE>. There are at least
- two components defined:
- <DL CLASS="description" COMPACT=compact><DT CLASS="dt-description"><DD CLASS="dd-description"><CODE>ejabberd_local</CODE> Handles packets that addressed to server JID;
- <DT CLASS="dt-description"><DD CLASS="dd-description"><CODE>ejabberd_sm</CODE> Handles packets that addressed to users bare JIDs.
- </DL>
-<DT CLASS="dt-description"><DD CLASS="dd-description"><CODE>remove_iq_handler(Component, Host, NS)</CODE>
-<PRE CLASS="verbatim">
-Component = atom()
-Host = NS = string()
-</PRE>Removes IQ handler on virtual host <CODE>Host</CODE> for namespace <CODE>NS</CODE> from
- <CODE>Component</CODE>.
-</DL>
-Handler function must have the following type:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description"><DD CLASS="dd-description"><CODE>Module:Function(From, To, IQ)</CODE>
-<PRE CLASS="verbatim">
-From = To = jid()
-</PRE></DL>
-<PRE CLASS="verbatim">
--module(mod_cputime).
-
--behaviour(gen_mod).
-
--export([start/2,
- stop/1,
- process_local_iq/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--define(NS_CPUTIME, "ejabberd:cputime").
-
-start(Host, Opts) -&gt;
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_CPUTIME,
- ?MODULE, process_local_iq, IQDisc).
-
-stop(Host) -&gt;
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_CPUTIME).
-
-process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -&gt;
- case Type of
- set -&gt;
- {iq, ID, error, XMLNS,
- [SubEl, ?ERR_NOT_ALLOWED]};
- get -&gt;
- CPUTime = element(1, erlang:statistics(runtime))/1000,
- SCPUTime = lists:flatten(io_lib:format("~.3f", CPUTime)),
- {iq, ID, result, XMLNS,
- [{xmlelement, "query",
- [{"xmlns", ?NS_CPUTIME}],
- [{xmlelement, "cputime", [], [{xmlcdata, SCPUTime}]}]}]}
- end.
-</PRE>
-<!--TOC subsection Services-->
-
-<H3 CLASS="subsection"><A NAME="htoc14">6.2</A>&nbsp;&nbsp;Services</H3><!--SEC END -->
-
-<A NAME="sec:services"></A>
-<PRE CLASS="verbatim">
--module(mod_echo).
-
--behaviour(gen_mod).
-
--export([start/2, init/1, stop/1]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
-start(Host, Opts) -&gt;
- MyHost = gen_mod:get_opt(host, Opts, "echo." ++ Host),
- register(gen_mod:get_module_proc(Host, ?PROCNAME),
- spawn(?MODULE, init, [MyHost])).
-
-init(Host) -&gt;
- ejabberd_router:register_local_route(Host),
- loop(Host).
-
-loop(Host) -&gt;
- receive
- {route, From, To, Packet} -&gt;
- ejabberd_router:route(To, From, Packet),
- loop(Host);
- stop -&gt;
- ejabberd_router:unregister_route(Host),
- ok;
- _ -&gt;
- loop(Host)
- end.
-
-stop(Host) -&gt;
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- Proc ! stop,
- {wait, Proc}.
-</PRE>
-<!--HTMLFOOT-->
-<!--ENDHTML-->
-<!--FOOTER-->
-<HR SIZE=2><BLOCKQUOTE CLASS="quote"><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
-</EM><A HREF="http://pauillac.inria.fr/~maranget/hevea/index.html"><EM>H<FONT SIZE=2><sup>E</sup></FONT>V<FONT SIZE=2><sup>E</sup></FONT>A</EM></A><EM>.</EM></BLOCKQUOTE></BODY>
-</HTML>
diff --git a/ejabberd-1.1.2/doc/dev.tex b/ejabberd-1.1.2/doc/dev.tex
deleted file mode 100644
index 3b0764311..000000000
--- a/ejabberd-1.1.2/doc/dev.tex
+++ /dev/null
@@ -1,398 +0,0 @@
-\documentclass[a4paper,10pt]{article}
-
-%% Packages
-\usepackage{graphics}
-\usepackage{hevea}
-\usepackage{makeidx}
-\usepackage{verbatim}
-
-%% Index
-\makeindex
-% Remove the index anchors from the HTML version to save size and bandwith.
-\newcommand{\ind}[1]{\begin{latexonly}\index{#1}\end{latexonly}}
-
-%% Images
-\newcommand{\logoscale}{0.7}
-\newcommand{\imgscale}{0.58}
-\newcommand{\insimg}[1]{\insscaleimg{\imgscale}{#1}}
-\newcommand{\insscaleimg}[2]{
- \imgsrc{#2}{}
- \begin{latexonly}
- \scalebox{#1}{\includegraphics{#2}}
- \end{latexonly}
-}
-
-%% Various
-\newcommand{\ns}[1]{\texttt{#1}}
-\newcommand{\ejabberd}{\texttt{ejabberd}}
-\newcommand{\Jabber}{Jabber}
-
-%% Modules
-\newcommand{\module}[1]{\texttt{#1}}
-\newcommand{\modadhoc}{\module{mod\_adhoc}}
-\newcommand{\modannounce}{\module{mod\_announce}}
-\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}}
-\newcommand{\modmuclog}{\module{mod\_muc\_log}}
-\newcommand{\modoffline}{\module{mod\_offline}}
-\newcommand{\modofflineodbc}{\module{mod\_offline\_odbc}}
-\newcommand{\modprivacy}{\module{mod\_privacy}}
-\newcommand{\modprivate}{\module{mod\_private}}
-\newcommand{\modpubsub}{\module{mod\_pubsub}}
-\newcommand{\modregister}{\module{mod\_register}}
-\newcommand{\modroster}{\module{mod\_roster}}
-\newcommand{\modrosterodbc}{\module{mod\_roster\_odbc}}
-\newcommand{\modservicelog}{\module{mod\_service\_log}}
-\newcommand{\modsharedroster}{\module{mod\_shared\_roster}}
-\newcommand{\modstats}{\module{mod\_stats}}
-\newcommand{\modtime}{\module{mod\_time}}
-\newcommand{\modvcard}{\module{mod\_vcard}}
-\newcommand{\modvcardldap}{\module{mod\_vcard\_ldap}}
-\newcommand{\modvcardodbc}{\module{mod\_vcard\_odbc}}
-\newcommand{\modversion}{\module{mod\_version}}
-
-%% Title page
-\include{version}
-\title{Ejabberd \version\ Developers Guide}
-\author{Alexey Shchepin \\
- \ahrefurl{mailto:alexey@sevcom.net} \\
- \ahrefurl{xmpp:aleksey@jabber.ru}}
-
-%% Options
-\newcommand{\marking}[1]{#1} % Marking disabled
-\newcommand{\quoting}[2][yozhik]{} % Quotes disabled
-\newcommand{\new}{\begin{latexonly}\marginpar{\textsc{new}}\end{latexonly}} % Highlight new features
-\newcommand{\improved}{\begin{latexonly}\marginpar{\textsc{improved}}\end{latexonly}} % Highlight improved features
-\newcommand{\moreinfo}[1]{} % Hide details
-
-%% Footnotes
-\newcommand{\tjepref}[2]{\footahref{http://www.jabber.org/jeps/jep-#1.html}{#2}}
-\newcommand{\jepref}[1]{\tjepref{#1}{JEP-#1}}
-
-\begin{document}
-
-\label{sec:titlepage}
-\begin{titlepage}
- \maketitle{}
-
- \begin{center}
- {\insscaleimg{\logoscale}{logo.png}
- \par
- }
- \end{center}
-
- \begin{quotation}\textit{I can thoroughly recommend ejabberd for ease of setup --
- Kevin Smith, Current maintainer of the Psi project}\end{quotation}
-
-\end{titlepage}
-
-\tableofcontents{}
-
-% Input introduction.tex
-\input{introduction}
-
-\section{How it Works}
-\label{sec:howitworks}
-
-
-A \Jabber{} domain is served by one or more \ejabberd{} nodes. These nodes can
-be run on different machines that are connected via a network. They all must
-have the ability to connect to port 4369 of all another nodes, and must have
-the same magic cookie (see Erlang/OTP documentation, in other words the file
-\texttt{\~{}ejabberd/.erlang.cookie} must be the same on all nodes). This is
-needed because all nodes exchange information about connected users, S2S
-connections, registered services, etc\ldots
-
-
-
-Each \ejabberd{} node have following modules:
-\begin{itemize}
-\item router;
-\item local router.
-\item session manager;
-\item S2S manager;
-\end{itemize}
-
-
-\subsection{Router}
-
-This module is the main router of \Jabber{} packets on each node. It routes
-them based on their destinations domains. It has two tables: local and global
-routes. First, domain of packet destination searched in local table, and if it
-found, then the packet is routed to appropriate process. If no, then it
-searches in global table, and is routed to the appropriate \ejabberd{} node or
-process. If it does not exists in either tables, then it sent to the S2S
-manager.
-
-
-\subsection{Local Router}
-
-This module routes packets which have a destination domain equal to this server
-name. If destination JID has a non-empty user part, then it routed to the
-session manager, else it is processed depending on it's content.
-
-
-\subsection{Session Manager}
-
-This module routes packets to local users. It searches for what user resource
-packet must be sended via presence table. If this resource is connected to
-this node, it is routed to C2S process, if it connected via another node, then
-the packet is sent to session manager on that node.
-
-
-\subsection{S2S Manager}
-
-This module routes packets to other \Jabber{} servers. First, it checks if an
-open S2S connection from the domain of the packet source to the domain of
-packet destination already exists. If it is open on another node, then it
-routes the packet to S2S manager on that node, if it is open on this node, then
-it is routed to the process that serves this connection, and if a connection
-does not exist, then it is opened and registered.
-
-
-
-
-\section{XML Representation}
-\label{sec:xmlrepr}
-
-Each XML stanza is represented as the following tuple:
-\begin{verbatim}
-XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
- Name = string()
- Attrs = [Attr]
- Attr = {Key, Val}
- Key = string()
- Val = string()
- ElementOrCDATA = XMLElement | CDATA
- CDATA = {xmlcdata, string()}
-\end{verbatim}
-E.\,g. this stanza:
-\begin{verbatim}
-<message to='test@conference.example.org' type='groupchat'>
- <body>test</body>
-</message>
-\end{verbatim}
-is represented as the following structure:
-\begin{verbatim}
-{xmlelement, "message",
- [{"to", "test@conference.example.org"},
- {"type", "groupchat"}],
- [{xmlelement, "body",
- [],
- [{xmlcdata, "test"}]}]}}
-\end{verbatim}
-
-
-
-\section{Module \texttt{xml}}
-\label{sec:xmlmod}
-
-\begin{description}
-\item{\verb|element_to_string(El) -> string()|}
-\begin{verbatim}
-El = XMLElement
-\end{verbatim}
- Returns string representation of XML stanza \texttt{El}.
-
-\item{\verb|crypt(S) -> string()|}
-\begin{verbatim}
-S = string()
-\end{verbatim}
- Returns string which correspond to \texttt{S} with encoded XML special
- characters.
-
-\item{\verb|remove_cdata(ECList) -> EList|}
-\begin{verbatim}
-ECList = [ElementOrCDATA]
-EList = [XMLElement]
-\end{verbatim}
- \texttt{EList} is a list of all non-CDATA elements of ECList.
-
-
-
-\item{\verb|get_path_s(El, Path) -> Res|}
-\begin{verbatim}
-El = XMLElement
-Path = [PathItem]
-PathItem = PathElem | PathAttr | PathCDATA
-PathElem = {elem, Name}
-PathAttr = {attr, Name}
-PathCDATA = cdata
-Name = string()
-Res = string() | XMLElement
-\end{verbatim}
- If \texttt{Path} is empty, then returns \texttt{El}. Else sequentially
- consider elements of \texttt{Path}. Each element is one of:
- \begin{description}
- \item{\verb|{elem, Name}|} \texttt{Name} is name of subelement of
- \texttt{El}, if such element exists, then this element considered in
- following steps, else returns empty string.
- \item{\verb|{attr, Name}|} If \texttt{El} have attribute \texttt{Name}, then
- returns value of this attribute, else returns empty string.
- \item{\verb|cdata|} Returns CDATA of \texttt{El}.
- \end{description}
-
-\item{TODO:}
-\begin{verbatim}
- get_cdata/1, get_tag_cdata/1
- get_attr/2, get_attr_s/2
- get_tag_attr/2, get_tag_attr_s/2
- get_subtag/2
-\end{verbatim}
-\end{description}
-
-
-\section{Module \texttt{xml\_stream}}
-\label{sec:xmlstreammod}
-
-\begin{description}
-\item{\verb!parse_element(Str) -> XMLElement | {error, Err}!}
-\begin{verbatim}
-Str = string()
-Err = term()
-\end{verbatim}
- Parses \texttt{Str} using XML parser, returns either parsed element or error
- tuple.
-\end{description}
-
-
-\section{Modules}
-\label{sec:emods}
-
-
-%\subsection{gen\_mod behaviour}
-%\label{sec:genmod}
-
-%TBD
-
-\subsection{Module gen\_iq\_handler}
-\label{sec:geniqhandl}
-
-The module \verb|gen_iq_handler| allows to easily write handlers for IQ packets
-of particular XML namespaces that addressed to server or to users bare JIDs.
-
-In this module the following functions are defined:
-\begin{description}
-\item{\verb|add_iq_handler(Component, Host, NS, Module, Function, Type)|}
-\begin{verbatim}
-Component = Module = Function = atom()
-Host = NS = string()
-Type = no_queue | one_queue | parallel
-\end{verbatim}
- Registers function \verb|Module:Function| as handler for IQ packets on
- virtual host \verb|Host| that contain child of namespace \verb|NS| in
- \verb|Component|. Queueing discipline is \verb|Type|. There are at least
- two components defined:
- \begin{description}
- \item{\verb|ejabberd_local|} Handles packets that addressed to server JID;
- \item{\verb|ejabberd_sm|} Handles packets that addressed to users bare JIDs.
- \end{description}
-\item{\verb|remove_iq_handler(Component, Host, NS)|}
-\begin{verbatim}
-Component = atom()
-Host = NS = string()
-\end{verbatim}
- Removes IQ handler on virtual host \verb|Host| for namespace \verb|NS| from
- \verb|Component|.
-\end{description}
-
-Handler function must have the following type:
-\begin{description}
-\item{\verb|Module:Function(From, To, IQ)|}
-\begin{verbatim}
-From = To = jid()
-\end{verbatim}
-\end{description}
-
-
-
-\begin{verbatim}
--module(mod_cputime).
-
--behaviour(gen_mod).
-
--export([start/2,
- stop/1,
- process_local_iq/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--define(NS_CPUTIME, "ejabberd:cputime").
-
-start(Host, Opts) ->
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_CPUTIME,
- ?MODULE, process_local_iq, IQDisc).
-
-stop(Host) ->
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_CPUTIME).
-
-process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
- case Type of
- set ->
- {iq, ID, error, XMLNS,
- [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- CPUTime = element(1, erlang:statistics(runtime))/1000,
- SCPUTime = lists:flatten(io_lib:format("~.3f", CPUTime)),
- {iq, ID, result, XMLNS,
- [{xmlelement, "query",
- [{"xmlns", ?NS_CPUTIME}],
- [{xmlelement, "cputime", [], [{xmlcdata, SCPUTime}]}]}]}
- end.
-\end{verbatim}
-
-
-\subsection{Services}
-\label{sec:services}
-
-%TBD
-
-
-%TODO: use \verb|proc_lib|
-\begin{verbatim}
--module(mod_echo).
-
--behaviour(gen_mod).
-
--export([start/2, init/1, stop/1]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
-start(Host, Opts) ->
- MyHost = gen_mod:get_opt(host, Opts, "echo." ++ Host),
- register(gen_mod:get_module_proc(Host, ?PROCNAME),
- spawn(?MODULE, init, [MyHost])).
-
-init(Host) ->
- ejabberd_router:register_local_route(Host),
- loop(Host).
-
-loop(Host) ->
- receive
- {route, From, To, Packet} ->
- ejabberd_router:route(To, From, Packet),
- loop(Host);
- stop ->
- ejabberd_router:unregister_route(Host),
- ok;
- _ ->
- loop(Host)
- end.
-
-stop(Host) ->
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- Proc ! stop,
- {wait, Proc}.
-\end{verbatim}
-
-
-
-\end{document}
diff --git a/ejabberd-1.1.2/doc/disco.png b/ejabberd-1.1.2/doc/disco.png
deleted file mode 100644
index 6e6d2a702..000000000
--- a/ejabberd-1.1.2/doc/disco.png
+++ /dev/null
Binary files differ
diff --git a/ejabberd-1.1.2/doc/discorus.png b/ejabberd-1.1.2/doc/discorus.png
deleted file mode 100644
index 982f88182..000000000
--- a/ejabberd-1.1.2/doc/discorus.png
+++ /dev/null
Binary files differ
diff --git a/ejabberd-1.1.2/doc/features.html b/ejabberd-1.1.2/doc/features.html
deleted file mode 100644
index 0904a2969..000000000
--- a/ejabberd-1.1.2/doc/features.html
+++ /dev/null
@@ -1,163 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
- "http://www.w3.org/TR/REC-html40/loose.dtd">
-<HTML>
-
-<HEAD>
-
-<TITLE>Ejabberd 1.1.2 Feature Sheet</TITLE>
-
-<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-<META name="GENERATOR" content="hevea 1.08">
-<STYLE type="text/css">
-.toc{list-style:none;}
-.title{margin:auto;text-align:center}
-.center{text-align:center;margin-left:auto;margin-right:auto;}
-.flushleft{text-align:left;margin-left:0ex;margin-right:auto;}
-.flushright{text-align:right;margin-left:auto;margin-right:0ex;}
-DIV TABLE{margin-left:inherit;margin-right:inherit;}
-PRE{text-align:left;margin-left:0ex;margin-right:auto;}
-BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
-.part{margin:auto;text-align:center}
-SPAN{width:20%; float:right; text-align:left; margin-left:auto;}
-</STYLE>
-</HEAD>
-
-<BODY >
-<!--HEVEA command line is: hevea -fix -noiso -pedantic features.tex -->
-<!--HTMLHEAD-->
-<!--ENDHTML-->
-<!--PREFIX <ARG ></ARG>-->
-<!--CUT DEF section 1 -->
-
-<BR>
-<BR>
-<A NAME="titlepage"></A>
-
- <TABLE CLASS="title">
-<TR><TD>
-<H1 CLASS="titlemain">Ejabberd 1.1.2 Feature Sheet</H1>
-<H3 CLASS="titlerest">Sander Devrieze<BR>
-<A HREF="mailto:s.devrieze@pandora.be"><TT>mailto:s.devrieze@pandora.be</TT></A><BR>
-<A HREF="xmpp:sander@devrieze.dyndns.org"><TT>xmpp:sander@devrieze.dyndns.org</TT></A></H3></TD>
-</TR></TABLE><BR>
-<BR>
-<DIV CLASS="center">
-
- <IMG SRC="logo.png" ALT="logo.png">
-
-
- <BR>
-<BR>
-
- </DIV>
- <BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>I can thoroughly recommend ejabberd for ease of setup &ndash;
- Kevin Smith, Current maintainer of the Psi project</I></FONT></BLOCKQUOTE>
-<!--TOC section Introduction-->
-
-<H2 CLASS="section"><A NAME="intro">Introduction</A></H2><!--SEC END -->
-
-<A NAME="sec:intro"></A>
-<BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>I just tried out ejabberd and was impressed both by ejabberd itself and the language it is written in, Erlang. &mdash;
-Joeri</I></FONT></BLOCKQUOTE>
-<TT>ejabberd</TT> is a <B><FONT SIZE=4><FONT COLOR="#001376">free and open source</FONT></FONT></B> instant messaging server written in <A HREF="http://www.erlang.org/">Erlang</A>.<BR>
-<BR>
-<TT>ejabberd</TT> is <B><FONT SIZE=4><FONT COLOR="#001376">cross-platform</FONT></FONT></B>, distributed, fault-tolerant, and based on open standards to achieve real-time communication.<BR>
-<BR>
-<TT>ejabberd</TT> is designed to be a <B><FONT SIZE=4><FONT COLOR="#001376">rock-solid and feature rich</FONT></FONT></B> XMPP server.<BR>
-<BR>
-<TT>ejabberd</TT> is suitable for small deployments, whether they need to be <B><FONT SIZE=4><FONT COLOR="#001376">scalable</FONT></FONT></B> or not, as well as extremely big deployments.<BR>
-<BR>
-<!--TOC subsection Key Features-->
-
-<H3 CLASS="subsection"><A NAME="keyfeatures">Key Features</A></H3><!--SEC END -->
-
-<A NAME="sec:keyfeatures"></A>
-
-<BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>Erlang seems to be tailor-made for writing stable, robust servers. &mdash;
-Peter Saint-Andr&eacute;, Executive Director of the Jabber Software Foundation</I></FONT></BLOCKQUOTE>
-<TT>ejabberd</TT> is:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-<B><FONT SIZE=4><FONT COLOR="#001376">Cross-platform:</FONT></FONT></B> <TT>ejabberd</TT> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.<BR>
-<BR>
-<LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Distributed:</FONT></FONT></B> You can run <TT>ejabberd</TT> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.<BR>
-<BR>
-<LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Fault-tolerant:</FONT></FONT></B> You can deploy an <TT>ejabberd</TT> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced `on the fly'.<BR>
-<BR>
-<LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Administrator Friendly:</FONT></FONT></B> <TT>ejabberd</TT> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Comprehensive documentation.
-<LI CLASS="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows.<FONT COLOR="#FFAA00"><SPAN STYLE="font-variant:small-caps">improved</SPAN></FONT>
-<LI CLASS="li-itemize">Web interface for administration tasks.
-<LI CLASS="li-itemize">Shared Roster Groups.
-<LI CLASS="li-itemize">Command line administration tool.<FONT COLOR="#FFAA00"><SPAN STYLE="font-variant:small-caps">improved</SPAN></FONT>
-<LI CLASS="li-itemize">Can integrate with existing authentication mechanisms.
-<LI CLASS="li-itemize">Capability to send announce messages.
-</UL><BR>
-<BR>
-<LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Internationalized:</FONT></FONT></B> <TT>ejabberd</TT> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Translated in 12 languages.<FONT COLOR="#FFAA00"><SPAN STYLE="font-variant:small-caps">improved</SPAN></FONT>
-<LI CLASS="li-itemize">Support for <A HREF="http://www.ietf.org/rfc/rfc3490.txt">IDNA</A>.
-</UL><BR>
-<BR>
-<LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Open Standards:</FONT></FONT></B> <TT>ejabberd</TT> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Fully XMPP compliant.
-<LI CLASS="li-itemize">XML-based protocol.
-<LI CLASS="li-itemize"><A HREF="http://ejabberd.jabber.ru/protocols">Many JEPs supported</A>.
-</UL></UL>
-<!--TOC subsection Additional Features-->
-
-<H3 CLASS="subsection"><A NAME="addfeatures">Additional Features</A></H3><!--SEC END -->
-
-<A NAME="sec:addfeatures"></A>
-
-<BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>ejabberd is making inroads to solving the "buggy incomplete server" problem &mdash;
-Justin Karneges, Founder of the Psi and the Delta projects</I></FONT></BLOCKQUOTE>
-Moreover, <TT>ejabberd</TT> comes with a wide range of other state-of-the-art features:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Modular
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Load only the modules you want.
-<LI CLASS="li-itemize">Extend <TT>ejabberd</TT> with your own custom modules.
-</UL>
-<LI CLASS="li-itemize">Security
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-SASL and STARTTLS for c2s and s2s connections.
-<LI CLASS="li-itemize">STARTTLS and Dialback s2s connections.
-<LI CLASS="li-itemize">Web interface accessible via HTTPS secure access.
-</UL>
-<LI CLASS="li-itemize">Databases
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Native MySQL support.
-<LI CLASS="li-itemize">Native PostgreSQL support.
-<LI CLASS="li-itemize">Mnesia.
-<LI CLASS="li-itemize">ODBC data storage support.
-<LI CLASS="li-itemize">Microsoft SQL Server support.<FONT COLOR="red"><SPAN STYLE="font-variant:small-caps">new</SPAN></FONT>
-</UL>
-<LI CLASS="li-itemize">Authentication
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-LDAP and ODBC.<FONT COLOR="#FFAA00"><SPAN STYLE="font-variant:small-caps">improved</SPAN></FONT>
-<LI CLASS="li-itemize">External Authentication script.
-<LI CLASS="li-itemize">Internal Authentication.
-</UL>
-<LI CLASS="li-itemize">Others
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Compressing XML streams with Stream Compression (<A HREF="http://www.jabber.org/jeps/jep-0138.html">JEP-0138</A>).
-<LI CLASS="li-itemize">Interface with networks such as AIM, ICQ and MSN.
-<LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A>).
-<LI CLASS="li-itemize">IPv6 support both for c2s and s2s connections.
-<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0045.html">Multi-User Chat</A> module with logging.<FONT COLOR="#FFAA00"><SPAN STYLE="font-variant:small-caps">improved</SPAN></FONT>
-<LI CLASS="li-itemize">Users Directory based on users vCards.
-<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0060.html">Publish-Subscribe</A> component.
-<LI CLASS="li-itemize">Support for virtual hosting.
-<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0025.html">HTTP Polling</A> service.
-<LI CLASS="li-itemize">IRC transport.
-</UL>
-</UL>
-<!--HTMLFOOT-->
-<!--ENDHTML-->
-<!--FOOTER-->
-<HR SIZE=2><BLOCKQUOTE CLASS="quote"><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
-</EM><A HREF="http://pauillac.inria.fr/~maranget/hevea/index.html"><EM>H<FONT SIZE=2><sup>E</sup></FONT>V<FONT SIZE=2><sup>E</sup></FONT>A</EM></A><EM>.</EM></BLOCKQUOTE></BODY>
-</HTML>
diff --git a/ejabberd-1.1.2/doc/features.tex b/ejabberd-1.1.2/doc/features.tex
deleted file mode 100644
index f5579cf42..000000000
--- a/ejabberd-1.1.2/doc/features.tex
+++ /dev/null
@@ -1,136 +0,0 @@
-\documentclass[a4paper,10pt]{article}
-
-%% Packages
-\usepackage{epsfig}
-\usepackage{fancyhdr}
-\usepackage{graphics}
-\usepackage{hevea}
-\usepackage[pdftex,colorlinks,unicode,urlcolor=blue,linkcolor=blue,pdftitle=Ejabberd\
- Feature\ Sheet,pdfauthor=Sander\
- Devrieze,pdfsubject=ejabberd,pdfkeywords=ejabberd]{hyperref}
-\usepackage{verbatim}
-\usepackage{color}
-
-%% Index
-% Remove the index anchors from the HTML version to save size and bandwith.
-\newcommand{\ind}[1]{\begin{latexonly}\index{#1}\end{latexonly}}
-
-%% Images
-\newcommand{\logoscale}{0.7}
-\newcommand{\imgscale}{0.58}
-\newcommand{\insimg}[1]{\insscaleimg{\imgscale}{#1}}
-\newcommand{\insscaleimg}[2]{
- \imgsrc{#2}{}
- \begin{latexonly}
- \scalebox{#1}{\includegraphics{#2}}
- \end{latexonly}
-}
-
-%% Various
-\newcommand{\bracehack}{\def\{{\char"7B}\def\}{\char"7D}}
-\newcommand{\titem}[1]{\item[\bracehack\texttt{#1}]}
-\newcommand{\ns}[1]{\texttt{#1}}
-\newcommand{\jid}[1]{\texttt{#1}}
-\newcommand{\option}[1]{\texttt{#1}}
-\newcommand{\poption}[1]{{\bracehack\texttt{#1}}}
-\newcommand{\node}[1]{\texttt{#1}}
-\newcommand{\term}[1]{\texttt{#1}}
-\newcommand{\shell}[1]{\texttt{#1}}
-\newcommand{\ejabberd}{\texttt{ejabberd}}
-\newcommand{\Jabber}{Jabber}
-
-%% Title page
-\include{version}
-\title{Ejabberd \version\ Feature Sheet}
-\author{Sander Devrieze \\
- \ahrefurl{mailto:s.devrieze@pandora.be} \\
- \ahrefurl{xmpp:sander@devrieze.dyndns.org}}
-
-% Options
-\newcommand{\marking}[1]{\textbf{\begin{large}\textcolor{ejblue}{#1}\end{large}}} % Marking enabled
-\newcommand{\quoting}[2][yozhik]{\begin{quotation}\textcolor{#1}{\textit{#2}}\end{quotation}} % Quotes enabled
-\newcommand{\new}{\marginpar{\textcolor{red}{\textsc{new}}}} % Highlight new features
-\newcommand{\improved}{\marginpar{\textcolor{orange}{\textsc{improved}}}} % Highlight improved features
-\setcounter{secnumdepth}{-1} % Disable section numbering
-
-%% To by-pass errors in the HTML version.
-\newstyle{SPAN}{width:20\%; float:right; text-align:left; margin-left:auto;}
-\definecolor{orange} {cmyk}{0.000,0.333,1.000,0.000}
-
-%% Footnotes
-\begin{latexonly}
-\global\parskip=9pt plus 3pt minus 1pt
-\global\parindent=0pt
-\gdef\ahrefurl#1{\href{#1}{\texttt{#1}}}
-\gdef\footahref#1#2{#2\footnote{\href{#1}{\texttt{#1}}}}
-\end{latexonly}
-\newcommand{\tjepref}[2]{\footahref{http://www.jabber.org/jeps/jep-#1.html}{#2}}
-\newcommand{\jepref}[1]{\tjepref{#1}{JEP-#1}}
-
-%% Fancy header
-\fancyhf{}
-\pagestyle{fancy}
-\rhead{\textcolor{ejblue}{The Expandable Jabber Daemon.}}
-\renewcommand{\headrule}{{\color{ejblue}%
-\hrule width\headwidth height\headrulewidth \vskip-\headrulewidth}}
-\lhead{\setlength{\unitlength}{-6mm}
- \begin{picture}(0,0)
- \put(5.8,3.25){\includegraphics[width=1.3\textwidth]{yozhikheader.png}}
- \end{picture}}
-
-% Official ejabberd colours
-\definecolor{ejblue} {cmyk}{1.000,0.831,0.000,0.537} %RGB: 0,0,118 HTML: 000076
-\definecolor{ejgreenyellow}{cmyk}{0.079,0.000,0.275,0.102} %RGB: 209,229,159 HTML: d1e59f
-\definecolor{ejgreendark} {cmyk}{0.131,0.000,0.146,0.220} %RGB: 166,199,162 HTML: a6c7a2
-\definecolor{ejgreen} {cmyk}{0.077,0.000,0.081,0.078} %RGB: 216,236,215 HTML: d8ecd7
-\definecolor{ejgreenwhite} {cmyk}{0.044,0.000,0.048,0.020} %RGB: 239,250,238 HTML: effaee
-\definecolor{yozhik} {cmyk}{0.000,0.837,1.000,0.424} %RGB: 147,0,0 HTML: 930000
-
-\begin{document}
-
-\label{titlepage}
-\begin{titlepage}
- \maketitle{}
-
- \thispagestyle{empty}
-
- \begin{center}
- {\insscaleimg{\logoscale}{logo.png}
- \par
- }
- \end{center}
- \quoting{I can thoroughly recommend ejabberd for ease of setup --
- Kevin Smith, Current maintainer of the Psi project}
-
-\end{titlepage}
-
-\newpage
-% Set the page counter to 2 so that the titlepage and the second page do not
-% have the same page number. This fixes the PDFLaTeX warning "destination with
-% the same identifier".
-\begin{latexonly}
-\setcounter{page}{2}
-\pagecolor{ejgreenwhite}
-\end{latexonly}
-
-% Input introduction.tex
-\input{introduction}
-
-\end{document}
-
-%% TODO
-% * illustrations (e.g. screenshot from web interface)
-% * commented parts
-% * slides, guide and html version
-% * cleaning and improving LaTeX code
-% * key features: something like this (shorter)? (more focussed on Erlang now): "To reach the goal of high
-% availability, performance and clustering, ejabberd is written in Erlang, a programming language perfectly
-% suited for this. Besides that, some parts are written in C to also incude the advantages of this language. In
-% short, ejabberd is a perfect mix of mainly Erlang code, peppered with some C code to get the final touch!"
-% <picture of a cocktail>
-% * key features: saying that ejabberd the only XMPP server is that can do real clustering:
-% http://www.jivesoftware.org/forums/thread.jspa?threadID=14602
-% "What I find interesting is that *no* XMPP servers truly provide clustering. This includes all the commercial
-% servers. The one partial exception appears to be ejabberd, which can cluster certain data such as sessions,
-% but not all services such as MUC."
-% * try it today: links to migration tutorials \ No newline at end of file
diff --git a/ejabberd-1.1.2/doc/flow.dot b/ejabberd-1.1.2/doc/flow.dot
deleted file mode 100644
index b1a8affb8..000000000
--- a/ejabberd-1.1.2/doc/flow.dot
+++ /dev/null
@@ -1,105 +0,0 @@
-digraph messages {
- //concentrate=true;
- subgraph clusterclients {
- client1 [shape = box];
- client2 [shape = box];
- client3 [shape = box];
-
- style = dashed;
- label = "Clients";
- }
-
- subgraph clusternode1 {
- subgraph clusterc2s1 {
- c2s11;
- c2s12;
- style = invis;
- }
- subgraph clusterservices1 {
- service11;
- service12;
- service13;
- style = invis;
- }
- //subgraph clusters2s1 {
- //s2s11;
- //s2s12;
- //style = invis;
- //}
- c2s11 -> auth1;
- c2s12 -> auth1;
- auth1 -> c2s11;
- auth1 -> c2s12;
- c2s11 -> sm1;
- c2s11 -> router1;
- c2s12 -> sm1;
- c2s12 -> router1;
- router1 -> local1;
- router1 -> service11;
- router1 -> service12;
- router1 -> service13;
- router1 -> s2s11;
- router1 -> s2s12;
- service11 -> router1;
- service12 -> router1;
- service13 -> router1;
- s2s11 -> router1;
- s2s12 -> router1;
- local1 -> sm1;
- sm1 -> c2s11;
- sm1 -> c2s12;
-
- style = dashed;
- label = "Node1";
- }
-
- subgraph clusternode2 {
- c2s2 -> auth2;
- auth2 -> c2s2;
- c2s2 -> sm2;
- c2s2 -> router2;
- router2 -> local2;
- router2 -> service21;
- router2 -> s2s21;
- service21 -> router2;
- s2s21 -> router2;
- local2 -> sm2;
- sm2 -> c2s2;
-
- style = dashed;
- label = "Node2";
- }
-
-
-
- subgraph clusterservers {
- server1 [shape = box];
- server2 [shape = box];
- server3 [shape = box];
-
- style = dashed;
- label = "Servers";
- }
-
-
- client1 -> c2s11;
- client2 -> c2s12;
- client3 -> c2s2;
- c2s11 -> client1 [constraint=false];
- c2s12 -> client2 [constraint=false];
- c2s2 -> client3 [constraint=false];
-
- s2s11 -> server1 [minlen = 2];
- s2s12 -> server2 [minlen = 2];
- s2s21 -> server3 [minlen = 2];
- server1 -> s2s11 [constraint=false];
- server2 -> s2s12 [constraint=false];
- server3 -> s2s21 [constraint=false];
-
- router1 -> router2;
- router2 -> router1;
- sm1 -> sm2;
- sm2 -> sm1;
-
- label = "Data Flows";
-}
diff --git a/ejabberd-1.1.2/doc/guide.html b/ejabberd-1.1.2/doc/guide.html
deleted file mode 100644
index 3c03f28ce..000000000
--- a/ejabberd-1.1.2/doc/guide.html
+++ /dev/null
@@ -1,4160 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
- "http://www.w3.org/TR/REC-html40/loose.dtd">
-<HTML>
-
-<HEAD>
-
-<TITLE>Ejabberd 1.1.2 Installation and Operation Guide</TITLE>
-
-<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-<META name="GENERATOR" content="hevea 1.08">
-<STYLE type="text/css">
-.toc{list-style:none;}
-.title{margin:auto;text-align:center}
-.center{text-align:center;margin-left:auto;margin-right:auto;}
-.flushleft{text-align:left;margin-left:0ex;margin-right:auto;}
-.flushright{text-align:right;margin-left:auto;margin-right:0ex;}
-DIV TABLE{margin-left:inherit;margin-right:inherit;}
-PRE{text-align:left;margin-left:0ex;margin-right:auto;}
-BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
-.part{margin:auto;text-align:center}
-SPAN{width:20%; float:right; text-align:left; margin-left:auto;}
-</STYLE>
-</HEAD>
-
-<BODY >
-<!--HEVEA command line is: hevea -fix -noiso -pedantic guide.tex -->
-<!--HTMLHEAD-->
-<!--ENDHTML-->
-<!--PREFIX <ARG ></ARG>-->
-<!--CUT DEF section 1 -->
-
-<BR>
-<BR>
-<A NAME="titlepage"></A>
-
- <TABLE CLASS="title">
-<TR><TD>
-<H1 CLASS="titlemain">Ejabberd 1.1.2 Installation and Operation Guide</H1>
-<H3 CLASS="titlerest">Alexey Shchepin<BR>
-<A HREF="mailto:alexey@sevcom.net"><TT>mailto:alexey@sevcom.net</TT></A><BR>
-<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT></A></H3></TD>
-</TR></TABLE><BR>
-<BR>
-<DIV CLASS="center">
-
- <IMG SRC="logo.png" ALT="logo.png">
-
-
- <BR>
-<BR>
-
- </DIV>
-<BLOCKQUOTE CLASS="quotation"><I>I can thoroughly recommend ejabberd for ease of setup &mdash;
- Kevin Smith, Current maintainer of the Psi project</I></BLOCKQUOTE>
-<!--TOC section Contents-->
-
-<H2 CLASS="section">Contents</H2><!--SEC END -->
-
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc1">1&nbsp;&nbsp;Introduction</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc2">1.1&nbsp;&nbsp;Key Features</A>
-<LI CLASS="li-toc"><A HREF="#htoc3">1.2&nbsp;&nbsp;Additional Features</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc4">2&nbsp;&nbsp;Installation from Source</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc5">2.1&nbsp;&nbsp;Installation Requirements</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc6">2.1.1&nbsp;&nbsp;`Unix-like' operating systems</A>
-<LI CLASS="li-toc"><A HREF="#htoc7">2.1.2&nbsp;&nbsp;Windows</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc8">2.2&nbsp;&nbsp;Obtaining <TT>ejabberd</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc9">2.3&nbsp;&nbsp;Compilation</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc10">2.3.1&nbsp;&nbsp;`Unix-like' operating systems</A>
-<LI CLASS="li-toc"><A HREF="#htoc11">2.3.2&nbsp;&nbsp;Windows</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc12">2.4&nbsp;&nbsp;Starting</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc13">3&nbsp;&nbsp;Basic Configuration</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc14">3.1&nbsp;&nbsp;Host Names</A>
-<LI CLASS="li-toc"><A HREF="#htoc15">3.2&nbsp;&nbsp;Virtual Hosting</A>
-<LI CLASS="li-toc"><A HREF="#htoc16">3.3&nbsp;&nbsp;Listened Sockets</A>
-<LI CLASS="li-toc"><A HREF="#htoc17">3.4&nbsp;&nbsp;Authentication</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc18">3.4.1&nbsp;&nbsp;Internal</A>
-<LI CLASS="li-toc"><A HREF="#htoc19">3.4.2&nbsp;&nbsp;SASL Anonymous and Anonymous Login</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc20">3.5&nbsp;&nbsp;Access Rules</A>
-<LI CLASS="li-toc"><A HREF="#htoc21">3.6&nbsp;&nbsp;Shapers</A>
-<LI CLASS="li-toc"><A HREF="#htoc22">3.7&nbsp;&nbsp;Limiting Opened Sessions</A>
-<LI CLASS="li-toc"><A HREF="#htoc23">3.8&nbsp;&nbsp;Default Language</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc24">4&nbsp;&nbsp;Database Configuration</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc25">4.1&nbsp;&nbsp;MySQL</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc26">4.1.1&nbsp;&nbsp;Driver Compilation</A>
-<LI CLASS="li-toc"><A HREF="#htoc27">4.1.2&nbsp;&nbsp;Authentication</A>
-<LI CLASS="li-toc"><A HREF="#htoc28">4.1.3&nbsp;&nbsp;Storage</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc29">4.2&nbsp;&nbsp;Microsoft SQL Server</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc30">4.2.1&nbsp;&nbsp;Driver Compilation</A>
-<LI CLASS="li-toc"><A HREF="#htoc31">4.2.2&nbsp;&nbsp;Authentication</A>
-<LI CLASS="li-toc"><A HREF="#htoc32">4.2.3&nbsp;&nbsp;Storage</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc33">4.3&nbsp;&nbsp;PostgreSQL</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc34">4.3.1&nbsp;&nbsp;Driver Compilation</A>
-<LI CLASS="li-toc"><A HREF="#htoc35">4.3.2&nbsp;&nbsp;Authentication</A>
-<LI CLASS="li-toc"><A HREF="#htoc36">4.3.3&nbsp;&nbsp;Storage</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc37">4.4&nbsp;&nbsp;ODBC Compatible</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc38">4.4.1&nbsp;&nbsp;Compilation</A>
-<LI CLASS="li-toc"><A HREF="#htoc39">4.4.2&nbsp;&nbsp;Authentication</A>
-<LI CLASS="li-toc"><A HREF="#htoc40">4.4.3&nbsp;&nbsp;Storage</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc41">4.5&nbsp;&nbsp;LDAP</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc42">4.5.1&nbsp;&nbsp;Connection</A>
-<LI CLASS="li-toc"><A HREF="#htoc43">4.5.2&nbsp;&nbsp;Authentication</A>
-<LI CLASS="li-toc"><A HREF="#htoc44">4.5.3&nbsp;&nbsp;Examples</A>
-</UL>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc45">5&nbsp;&nbsp;Modules Configuration</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc46">5.1&nbsp;&nbsp;Overview</A>
-<LI CLASS="li-toc"><A HREF="#htoc47">5.2&nbsp;&nbsp;Common Options</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc48">5.2.1&nbsp;&nbsp;<TT>iqdisc</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc49">5.2.2&nbsp;&nbsp;<TT>hosts</TT></A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc50">5.3&nbsp;&nbsp;<TT>mod_announce</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc51">5.4&nbsp;&nbsp;<TT>mod_disco</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc52">5.5&nbsp;&nbsp;<TT>mod_echo</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc53">5.6&nbsp;&nbsp;<TT>mod_irc</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc54">5.7&nbsp;&nbsp;<TT>mod_last</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc55">5.8&nbsp;&nbsp;<TT>mod_muc</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc56">5.9&nbsp;&nbsp;<TT>mod_muc_log</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc57">5.10&nbsp;&nbsp;<TT>mod_offline</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc58">5.11&nbsp;&nbsp;<TT>mod_privacy</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc59">5.12&nbsp;&nbsp;<TT>mod_private</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc60">5.13&nbsp;&nbsp;<TT>mod_pubsub</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc61">5.14&nbsp;&nbsp;<TT>mod_register</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc62">5.15&nbsp;&nbsp;<TT>mod_roster</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc63">5.16&nbsp;&nbsp;<TT>mod_service_log</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc64">5.17&nbsp;&nbsp;<TT>mod_shared_roster</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc65">5.18&nbsp;&nbsp;<TT>mod_stats</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc66">5.19&nbsp;&nbsp;<TT>mod_time</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc67">5.20&nbsp;&nbsp;<TT>mod_vcard</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc68">5.21&nbsp;&nbsp;<TT>mod_vcard_ldap</TT></A>
-<LI CLASS="li-toc"><A HREF="#htoc69">5.22&nbsp;&nbsp;<TT>mod_version</TT></A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc70">6&nbsp;&nbsp;Creating an Initial Administrator</A>
-<LI CLASS="li-toc"><A HREF="#htoc71">7&nbsp;&nbsp;Online Configuration and Monitoring</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc72">7.1&nbsp;&nbsp;Web Interface</A>
-<LI CLASS="li-toc"><A HREF="#htoc73">7.2&nbsp;&nbsp;<TT>ejabberdctl</TT></A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc74">8&nbsp;&nbsp;Firewall Settings</A>
-<LI CLASS="li-toc"><A HREF="#htoc75">9&nbsp;&nbsp;SRV Records</A>
-<LI CLASS="li-toc"><A HREF="#htoc76">10&nbsp;&nbsp;Clustering</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc77">10.1&nbsp;&nbsp;How it Works</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc78">10.1.1&nbsp;&nbsp;Router</A>
-<LI CLASS="li-toc"><A HREF="#htoc79">10.1.2&nbsp;&nbsp;Local Router</A>
-<LI CLASS="li-toc"><A HREF="#htoc80">10.1.3&nbsp;&nbsp;Session Manager</A>
-<LI CLASS="li-toc"><A HREF="#htoc81">10.1.4&nbsp;&nbsp;s2s Manager</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc82">10.2&nbsp;&nbsp;Clustering Setup</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc83">A&nbsp;&nbsp;Internationalization and Localization</A>
-<LI CLASS="li-toc"><A HREF="#htoc84">B&nbsp;&nbsp;Release Notes</A>
-<UL CLASS="toc"><LI CLASS="li-toc">
-<A HREF="#htoc85">B.1&nbsp;&nbsp;ejabberd 0.9</A>
-<LI CLASS="li-toc"><A HREF="#htoc86">B.2&nbsp;&nbsp;ejabberd 0.9.1</A>
-<LI CLASS="li-toc"><A HREF="#htoc87">B.3&nbsp;&nbsp;ejabberd 0.9.8</A>
-<LI CLASS="li-toc"><A HREF="#htoc88">B.4&nbsp;&nbsp;ejabberd 1.0.0</A>
-<LI CLASS="li-toc"><A HREF="#htoc89">B.5&nbsp;&nbsp;ejabberd 1.1.0</A>
-<LI CLASS="li-toc"><A HREF="#htoc90">B.6&nbsp;&nbsp;ejabberd 1.1.1</A>
-<LI CLASS="li-toc"><A HREF="#htoc91">B.7&nbsp;&nbsp;ejabberd 1.1.2</A>
-</UL>
-<LI CLASS="li-toc"><A HREF="#htoc92">C&nbsp;&nbsp;Acknowledgements</A>
-<LI CLASS="li-toc"><A HREF="#htoc93">D&nbsp;&nbsp;Copyright Information</A>
-</UL>
-
-<!--TOC section Introduction-->
-
-<H2 CLASS="section"><A NAME="htoc1">1</A>&nbsp;&nbsp;<A NAME="intro">Introduction</A></H2><!--SEC END -->
-
-<A NAME="sec:intro"></A>
-
-<TT>ejabberd</TT> is a free and open source instant messaging server written in <A HREF="http://www.erlang.org/">Erlang</A>.<BR>
-<BR>
-<TT>ejabberd</TT> is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication.<BR>
-<BR>
-<TT>ejabberd</TT> is designed to be a rock-solid and feature rich XMPP server.<BR>
-<BR>
-<TT>ejabberd</TT> is suitable for small deployments, whether they need to be scalable or not, as well as extremely big deployments.<BR>
-<BR>
-<!--TOC subsection Key Features-->
-
-<H3 CLASS="subsection"><A NAME="htoc2">1.1</A>&nbsp;&nbsp;<A NAME="keyfeatures">Key Features</A></H3><!--SEC END -->
-
-<A NAME="sec:keyfeatures"></A>
-
-<TT>ejabberd</TT> is:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Cross-platform: <TT>ejabberd</TT> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.<BR>
-<BR>
-<LI CLASS="li-itemize">Distributed: You can run <TT>ejabberd</TT> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.<BR>
-<BR>
-<LI CLASS="li-itemize">Fault-tolerant: You can deploy an <TT>ejabberd</TT> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced `on the fly'.<BR>
-<BR>
-<LI CLASS="li-itemize">Administrator Friendly: <TT>ejabberd</TT> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Comprehensive documentation.
-<LI CLASS="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows.<SPAN STYLE="font-variant:small-caps">improved</SPAN>
-<LI CLASS="li-itemize">Web interface for administration tasks.
-<LI CLASS="li-itemize">Shared Roster Groups.
-<LI CLASS="li-itemize">Command line administration tool.<SPAN STYLE="font-variant:small-caps">improved</SPAN>
-<LI CLASS="li-itemize">Can integrate with existing authentication mechanisms.
-<LI CLASS="li-itemize">Capability to send announce messages.
-</UL><BR>
-<BR>
-<LI CLASS="li-itemize">Internationalized: <TT>ejabberd</TT> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Translated in 12 languages.<SPAN STYLE="font-variant:small-caps">improved</SPAN>
-<LI CLASS="li-itemize">Support for <A HREF="http://www.ietf.org/rfc/rfc3490.txt">IDNA</A>.
-</UL><BR>
-<BR>
-<LI CLASS="li-itemize">Open Standards: <TT>ejabberd</TT> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Fully XMPP compliant.
-<LI CLASS="li-itemize">XML-based protocol.
-<LI CLASS="li-itemize"><A HREF="http://ejabberd.jabber.ru/protocols">Many JEPs supported</A>.
-</UL></UL>
-<!--TOC subsection Additional Features-->
-
-<H3 CLASS="subsection"><A NAME="htoc3">1.2</A>&nbsp;&nbsp;<A NAME="addfeatures">Additional Features</A></H3><!--SEC END -->
-
-<A NAME="sec:addfeatures"></A>
-
-Moreover, <TT>ejabberd</TT> comes with a wide range of other state-of-the-art features:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Modular
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Load only the modules you want.
-<LI CLASS="li-itemize">Extend <TT>ejabberd</TT> with your own custom modules.
-</UL>
-<LI CLASS="li-itemize">Security
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-SASL and STARTTLS for c2s and s2s connections.
-<LI CLASS="li-itemize">STARTTLS and Dialback s2s connections.
-<LI CLASS="li-itemize">Web interface accessible via HTTPS secure access.
-</UL>
-<LI CLASS="li-itemize">Databases
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Native MySQL support.
-<LI CLASS="li-itemize">Native PostgreSQL support.
-<LI CLASS="li-itemize">Mnesia.
-<LI CLASS="li-itemize">ODBC data storage support.
-<LI CLASS="li-itemize">Microsoft SQL Server support.<SPAN STYLE="font-variant:small-caps">new</SPAN>
-</UL>
-<LI CLASS="li-itemize">Authentication
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-LDAP and ODBC.<SPAN STYLE="font-variant:small-caps">improved</SPAN>
-<LI CLASS="li-itemize">External Authentication script.
-<LI CLASS="li-itemize">Internal Authentication.
-</UL>
-<LI CLASS="li-itemize">Others
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Compressing XML streams with Stream Compression (<A HREF="http://www.jabber.org/jeps/jep-0138.html">JEP-0138</A>).
-<LI CLASS="li-itemize">Interface with networks such as AIM, ICQ and MSN.
-<LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A>).
-<LI CLASS="li-itemize">IPv6 support both for c2s and s2s connections.
-<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0045.html">Multi-User Chat</A> module with logging.<SPAN STYLE="font-variant:small-caps">improved</SPAN>
-<LI CLASS="li-itemize">Users Directory based on users vCards.
-<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0060.html">Publish-Subscribe</A> component.
-<LI CLASS="li-itemize">Support for virtual hosting.
-<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0025.html">HTTP Polling</A> service.
-<LI CLASS="li-itemize">IRC transport.
-</UL>
-</UL>
-<!--TOC section Installation from Source-->
-
-<H2 CLASS="section"><A NAME="htoc4">2</A>&nbsp;&nbsp;<A NAME="installsource">Installation from Source</A></H2><!--SEC END -->
-
-<A NAME="sec:installsource"></A>
-
-<!--TOC subsection Installation Requirements-->
-
-<H3 CLASS="subsection"><A NAME="htoc5">2.1</A>&nbsp;&nbsp;<A NAME="installreq">Installation Requirements</A></H3><!--SEC END -->
-
-<A NAME="sec:installreq"></A>
-
-<!--TOC subsubsection `Unix-like' operating systems-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc6">2.1.1</A>&nbsp;&nbsp;<A NAME="installrequnix">`Unix-like' operating systems</A></H4><!--SEC END -->
-
-<A NAME="sec:installrequnix"></A>
-To compile <TT>ejabberd</TT> on a `Unix-like' operating system, you need:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-GNU Make
-<LI CLASS="li-itemize">GCC
-<LI CLASS="li-itemize">libexpat 1.95 or higher
-<LI CLASS="li-itemize">Erlang/OTP R9C-2 or higher
-<LI CLASS="li-itemize">OpenSSL 0.9.6 or higher (optional)
-<LI CLASS="li-itemize">Zlib 1.2.3 or higher (optional)
-<LI CLASS="li-itemize">GNU Iconv 1.8 or higher (optional, not needed on systems with GNU libc)
-</UL>
-<!--TOC subsubsection Windows-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc7">2.1.2</A>&nbsp;&nbsp;<A NAME="installreqwin">Windows</A></H4><!--SEC END -->
-
-<A NAME="sec:installreqwin"></A>
-To compile <TT>ejabberd</TT> on a Windows flavour, you need:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-MS Visual C++ 6.0 Compiler
-<LI CLASS="li-itemize"><A HREF="http://erlang.org/download.html">Erlang/OTP R9C-2 or higher</A>
-<LI CLASS="li-itemize"><A HREF="http://sourceforge.net/project/showfiles.php?group_id=10127&package_id=11277">Expat 1.95.7 or higher</A>
-<LI CLASS="li-itemize"><A HREF="http://www.gnu.org/software/libiconv/">GNU Iconv 1.9.1</A>
-(optional)
-<LI CLASS="li-itemize"><A HREF="http://www.slproweb.com/products/Win32OpenSSL.html">Shining Light OpenSSL</A>
-(to enable SSL connections)
-<LI CLASS="li-itemize"><A HREF="http://www.zlib.net/">Zlib 1.2.3 or higher</A>
-</UL>
-<!--TOC subsection Obtaining <TT>ejabberd</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc8">2.2</A>&nbsp;&nbsp;<A NAME="obtaining">Obtaining <TT>ejabberd</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:obtaining"></A>
-
-Released versions of <TT>ejabberd</TT> can be obtained from <BR>
-<A HREF="http://www.process-one.net/en/projects/ejabberd/download.html"><TT>http://www.process-one.net/en/projects/ejabberd/download.html</TT></A>.<BR>
-<BR>
-
-The latest development version can be retrieved from the Subversion repository.
-<PRE CLASS="verbatim">
- svn co http://svn.process-one.net/ejabberd/trunk ejabberd
-</PRE>
-<!--TOC subsection Compilation-->
-
-<H3 CLASS="subsection"><A NAME="htoc9">2.3</A>&nbsp;&nbsp;<A NAME="compile">Compilation</A></H3><!--SEC END -->
-
-<A NAME="sec:compile"></A>
-
-<!--TOC subsubsection `Unix-like' operating systems-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc10">2.3.1</A>&nbsp;&nbsp;<A NAME="compileunix">`Unix-like' operating systems</A></H4><!--SEC END -->
-
-<A NAME="sec:compileunix"></A>
-Compile <TT>ejabberd</TT> on a `Unix-like' operating system by executing:
-<PRE CLASS="verbatim">
- ./configure
- make
- su
- make install
-</PRE>
-These commands will:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-install <TT>ejabberd</TT> into the directory <CODE>/var/lib/ejabberd</CODE>,
-<LI CLASS="li-itemize">install the configuration file into <CODE>/etc/ejabberd</CODE>,
-<LI CLASS="li-itemize">create a directory called <CODE>/var/log/ejabberd</CODE> to store log files.
-</UL>
-Note: if you want to use an external database, you need to execute the configure
-script with the option(s) <TT>&ndash;enable-odbc</TT> or <TT>&ndash;enable-odbc
-&ndash;enable-mssql</TT>. See section&nbsp;<A HREF="#sec:database">4</A> for more information.<BR>
-<BR>
-<!--TOC subsubsection Windows-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc11">2.3.2</A>&nbsp;&nbsp;<A NAME="compilewin">Windows</A></H4><!--SEC END -->
-
-<A NAME="sec:compilewin"></A>
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Install Erlang emulator (for example, into <CODE>C:\Program Files\erl5.3</CODE>).
-<LI CLASS="li-itemize">Install Expat library into <CODE>C:\Program Files\Expat-1.95.7</CODE>
- directory.<BR>
-<BR>
-Copy file <CODE>C:\Program Files\Expat-1.95.7\Libs\libexpat.dll</CODE>
- to your Windows system directory (for example, <CODE>C:\WINNT</CODE> or
- <CODE>C:\WINNT\System32</CODE>)
-<LI CLASS="li-itemize">Build and install the Iconv library into the directory
- <CODE>C:\Program Files\iconv-1.9.1</CODE>.<BR>
-<BR>
-Copy file <CODE>C:\Program Files\iconv-1.9.1\bin\iconv.dll</CODE> to your
- Windows system directory (more installation instructions can be found in the
- file README.woe32 in the iconv distribution).<BR>
-<BR>
-Note: instead of copying libexpat.dll and iconv.dll to the Windows
- directory, you can add the directories
- <CODE>C:\Program Files\Expat-1.95.7\Libs</CODE> and
- <CODE>C:\Program Files\iconv-1.9.1\bin</CODE> to the <CODE>PATH</CODE> environment
- variable.
-<LI CLASS="li-itemize">While in the directory <CODE>ejabberd\src</CODE> run:
-<PRE CLASS="verbatim">
-configure.bat
-nmake -f Makefile.win32
-</PRE><LI CLASS="li-itemize">Edit the file <CODE>ejabberd\src\ejabberd.cfg</CODE> and run
-<PRE CLASS="verbatim">
-werl -s ejabberd -name ejabberd
-</PRE></UL>
-<!--TOC subsection Starting-->
-
-<H3 CLASS="subsection"><A NAME="htoc12">2.4</A>&nbsp;&nbsp;<A NAME="start">Starting</A></H3><!--SEC END -->
-
-<A NAME="sec:start"></A>
-
-
-Execute the following command to start <TT>ejabberd</TT>:
-<PRE CLASS="verbatim">
- erl -pa /var/lib/ejabberd/ebin -name ejabberd -s ejabberd
-</PRE>or
-<PRE CLASS="verbatim">
- erl -pa /var/lib/ejabberd/ebin -sname ejabberd -s ejabberd
-</PRE>In the latter case the Erlang node will be identified using only the first part
-of the host name, i.&nbsp;e. other Erlang nodes outside this domain cannot contact
-this node.<BR>
-<BR>
-Note that when using the above command, <TT>ejabberd</TT> will search for the
-configuration file in the current directory and will use the current directory
-for storing its user database and for logging.<BR>
-<BR>
-To specify the path to the configuration file, the log files and the Mnesia
-database directory, you may use the following command:
-<PRE CLASS="verbatim">
- erl -pa /var/lib/ejabberd/ebin \
- -sname ejabberd \
- -s ejabberd \
- -ejabberd config \"/etc/ejabberd/ejabberd.cfg\" \
- log_path \"/var/log/ejabberd/ejabberd.log\" \
- -sasl sasl_error_logger \{file,\"/var/log/ejabberd/sasl.log\"\} \
- -mnesia dir \"/var/lib/ejabberd/spool\"
-</PRE>
-You can find other useful options in the Erlang manual page
-(<TT>erl -man erl</TT>).<BR>
-<BR>
-To use more than 1024 connections, you should set the environment variable
-<CODE>ERL_MAX_PORTS</CODE>:
-<PRE CLASS="verbatim">
- export ERL_MAX_PORTS=32000
-</PRE>Note that with this value, <TT>ejabberd</TT> will use more memory (approximately 6&nbsp;MB
-more).<BR>
-<BR>
-To reduce memory usage, you may set the environment variable
-<CODE>ERL_FULLSWEEP_AFTER</CODE>:
-<PRE CLASS="verbatim">
- export ERL_FULLSWEEP_AFTER=0
-</PRE>But in this case <TT>ejabberd</TT> can start to work slower.<BR>
-<BR>
-<!--TOC section Basic Configuration-->
-
-<H2 CLASS="section"><A NAME="htoc13">3</A>&nbsp;&nbsp;<A NAME="basicconfig">Basic Configuration</A></H2><!--SEC END -->
-
-<A NAME="sec:basicconfig"></A>
-
-The configuration file will be loaded the first time you start <TT>ejabberd</TT>. The
-content from this file will be parsed and stored in a database. Subsequently the
-configuration will be loaded from the database and any commands in the
-configuration file are appended to the entries in the database. The
-configuration file contains a sequence of Erlang terms. Lines beginning with a
-<TT>`%'</TT> sign are ignored. Each term is a tuple of which the first element is
-the name of an option, and any further elements are that option's values. If the
-configuration file do not contain for instance the `hosts' option, the old
-host name(s) stored in the database will be used.<BR>
-<BR>
-You can override the old values stored in the database by adding next lines to
-the configuration file:
-<PRE CLASS="verbatim">
- override_global.
- override_local.
- override_acls.
-</PRE>With these lines the old global options, local options and ACLs will be removed
-before new ones are added.<BR>
-<BR>
-<!--TOC subsection Host Names-->
-
-<H3 CLASS="subsection"><A NAME="htoc14">3.1</A>&nbsp;&nbsp;<A NAME="hostnames">Host Names</A></H3><!--SEC END -->
-
-<A NAME="sec:hostnames"></A>
-
-The option <TT>hosts</TT> defines a list containing one or more domains that
-<TT>ejabberd</TT> will serve.<BR>
-<BR>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Serving one domain:
- <PRE CLASS="verbatim">
- {hosts, ["example.org"]}.
-</PRE><LI CLASS="li-itemize">Serving one domain, and backwards compatible with older <TT>ejabberd</TT>
- versions:
- <PRE CLASS="verbatim">
- {host, "example.org"}.
-</PRE><LI CLASS="li-itemize">Serving two domains:
-<PRE CLASS="verbatim">
- {hosts, ["example.net", "example.com"]}.
-</PRE></UL>
-<!--TOC subsection Virtual Hosting-->
-
-<H3 CLASS="subsection"><A NAME="htoc15">3.2</A>&nbsp;&nbsp;<A NAME="virtualhost">Virtual Hosting</A></H3><!--SEC END -->
-
-<A NAME="sec:virtualhost"></A>
-
-Options can be defined separately for every virtual host using the
-<TT>host_config</TT> option. It has the following
-syntax:
-<PRE CLASS="verbatim">
- {host_config, &lt;hostname&gt;, [&lt;option&gt;, &lt;option&gt;, ...]}.
-</PRE>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Domain <TT>example.net</TT> is using the internal authentication method while
- domain <TT>example.com</TT> is using the LDAP server running on the
- domain <TT>localhost</TT> to perform authentication:
-<PRE CLASS="verbatim">
-{host_config, "example.net", [{auth_method, internal}]}.
-
-{host_config, "example.com", [{auth_method, ldap},
- {ldap_servers, ["localhost"]},
- {ldap_uidattr, "uid"},
- {ldap_rootdn, "dc=localdomain"},
- {ldap_rootdn, "dc=example,dc=com"},
- {ldap_password, ""}]}.
-</PRE><LI CLASS="li-itemize">Domain <TT>example.net</TT> is using ODBC to perform authentication
- while domain <TT>example.com</TT> is using the LDAP servers running on the domains
- <TT>localhost</TT> and <TT>otherhost</TT>:
-<PRE CLASS="verbatim">
-{host_config, "example.net", [{auth_method, odbc},
- {odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}]}.
-
-{host_config, "example.com", [{auth_method, ldap},
- {ldap_servers, ["localhost", "otherhost"]},
- {ldap_uidattr, "uid"},
- {ldap_rootdn, "dc=localdomain"},
- {ldap_rootdn, "dc=example,dc=com"},
- {ldap_password, ""}]}.
-</PRE></UL>
-<!--TOC subsection Listened Sockets-->
-
-<H3 CLASS="subsection"><A NAME="htoc16">3.3</A>&nbsp;&nbsp;<A NAME="listened">Listened Sockets</A></H3><!--SEC END -->
-
-<A NAME="sec:listened"></A>
-
-The option <TT>listen</TT> defines for which addresses and ports <TT>ejabberd</TT>
-will listen and what services will be run on them. Each element of the list is a
-tuple with the following elements:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Port number.
-<LI CLASS="li-itemize">Module that serves this port.
-<LI CLASS="li-itemize">Options to this module.
-</UL>
-
-Currently next modules are implemented:
-<BLOCKQUOTE CLASS="table"><DIV CLASS="center"><DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV>
-
- <TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
-<TR><TD VALIGN=top ALIGN=left NOWRAP><TT>ejabberd_c2s</TT></TD>
-<TD VALIGN=top ALIGN=left NOWRAP>Description</TD>
-<TD VALIGN=top ALIGN=left>Handles c2s connections.</TD>
-</TR>
-<TR><TD VALIGN=top ALIGN=left NOWRAP>&nbsp;</TD>
-<TD VALIGN=top ALIGN=left NOWRAP>Options</TD>
-<TD VALIGN=top ALIGN=left><TT>access</TT>, <TT>certfile</TT>, <TT>inet6</TT>,
- <TT>ip</TT>, <TT>max_stanza_size</TT>, <TT>shaper</TT>, <TT>ssl</TT>,
- <TT>tls</TT>, <TT>starttls</TT>, <TT>starttls_required</TT>,
- <TT>zlib</TT></TD>
-</TR>
-<TR><TD VALIGN=top ALIGN=left NOWRAP><TT>ejabberd_s2s_in</TT></TD>
-<TD VALIGN=top ALIGN=left NOWRAP>Description</TD>
-<TD VALIGN=top ALIGN=left>Handles incoming s2s
- connections.</TD>
-</TR>
-<TR><TD VALIGN=top ALIGN=left NOWRAP>&nbsp;</TD>
-<TD VALIGN=top ALIGN=left NOWRAP>Options</TD>
-<TD VALIGN=top ALIGN=left><TT>inet6</TT>, <TT>ip</TT>,
- <TT>max_stanza_size</TT></TD>
-</TR>
-<TR><TD VALIGN=top ALIGN=left NOWRAP><TT>ejabberd_service</TT></TD>
-<TD VALIGN=top ALIGN=left NOWRAP>Description</TD>
-<TD VALIGN=top ALIGN=left>Interacts with external
- components (*).</TD>
-</TR>
-<TR><TD VALIGN=top ALIGN=left NOWRAP>&nbsp;</TD>
-<TD VALIGN=top ALIGN=left NOWRAP>Options</TD>
-<TD VALIGN=top ALIGN=left><TT>access</TT>, <TT>hosts</TT>, <TT>inet6</TT>,
- <TT>ip</TT>, <TT>shaper</TT></TD>
-</TR>
-<TR><TD VALIGN=top ALIGN=left NOWRAP><TT>ejabberd_http</TT></TD>
-<TD VALIGN=top ALIGN=left NOWRAP>Description</TD>
-<TD VALIGN=top ALIGN=left>Handles incoming HTTP
- connections.</TD>
-</TR>
-<TR><TD VALIGN=top ALIGN=left NOWRAP>&nbsp;</TD>
-<TD VALIGN=top ALIGN=left NOWRAP>Options</TD>
-<TD VALIGN=top ALIGN=left><TT>certfile</TT>, <TT>http_poll</TT>,
- <TT>inet6</TT>, <TT>ip</TT>, <TT>tls</TT>, <TT>web_admin</TT></TD>
-</TR></TABLE>
-<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></DIV></BLOCKQUOTE>
-(*) The mechanism for <A HREF="http://ejabberd.jabber.ru/tutorials-transports">external components</A> is defined in Jabber Component Protocol (<A HREF="http://www.jabber.org/jeps/jep-0114.html">JEP-0114</A>).<BR>
-<BR>
-The following options are available:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
- <B><TT>{access, &lt;access rule&gt;}</TT></B><DD CLASS="dd-description"> This option defines
- access to the port. The default value is <TT>all</TT>.
- <DT CLASS="dt-description"><B><TT>{certfile, Path}</TT></B><DD CLASS="dd-description"> Path to a file containing the SSL certificate.
- <DT CLASS="dt-description"><B><TT>{hosts, [Hostnames], [HostOptions]}</TT></B><DD CLASS="dd-description"> This option
- defines one or more hostnames of connected services and enables you to
- specify additional options including <TT>{password, Secret}</TT>.
- <DT CLASS="dt-description"><B><TT>http_poll</TT></B><DD CLASS="dd-description">
- This option enables HTTP Polling (<A HREF="http://www.jabber.org/jeps/jep-0025.html">JEP-0025</A>) support. HTTP Polling
- enables access via HTTP requests to <TT>ejabberd</TT> from behind firewalls which
- do not allow outgoing sockets on port 5222.<BR>
-<BR>
-If HTTP Polling is enabled, it will be available at
- <CODE>http://server:port/http-poll/</CODE>. Be aware that support for HTTP Polling
- is also needed in the Jabber client. Remark also that HTTP Polling can be
- interesting to host a web-based Jabber client such as
- <A HREF="http://jwchat.sourceforge.net/">JWChat</A> (there is a tutorial to
- <A HREF="http://ejabberd.jabber.ru/jwchat">install JWChat</A> with
- instructions for <TT>ejabberd</TT>).
- <DT CLASS="dt-description"><B><TT>inet6</TT></B><DD CLASS="dd-description"> Set up the socket for IPv6.
- <DT CLASS="dt-description"><B><TT>{ip, IPAddress}</TT></B><DD CLASS="dd-description"> This option specifies which network
- interface to listen for. For example <CODE>{ip, {192, 168, 1, 1}}</CODE>.
- <DT CLASS="dt-description"><B><TT>{max_stanza_size, Size}</TT></B><DD CLASS="dd-description"> This
- option specifies an approximate maximum size in bytes of XML stanzas.
- Approximate, because it is calculated with the precision of one block of
- readed data. For example <CODE>{max_stanza_size, 65536}</CODE>. The default
- value is <TT>infinity</TT>.
- <DT CLASS="dt-description"><B><TT>{shaper, &lt;access rule&gt;}</TT></B><DD CLASS="dd-description"> This option defines a
- shaper for the port (see section&nbsp;<A HREF="#sec:shapers">3.6</A>). The default value
- is <TT>none</TT>.
- <DT CLASS="dt-description"><B><TT>ssl</TT></B><DD CLASS="dd-description"> This option specifies that traffic on
- the port will be encrypted using SSL. You should also set the
- <TT>certfile</TT> option. It is recommended to use the <TT>tls</TT> option
- instead.
- <DT CLASS="dt-description"><B><TT>starttls</TT></B><DD CLASS="dd-description"> This option
- specifies that STARTTLS encryption is available on connections to the port.
- You should also set the <TT>certfile</TT> option.
- <DT CLASS="dt-description"><B><TT>starttls_required</TT></B><DD CLASS="dd-description"> This option
- specifies that STARTTLS encryption is required on connections to the port.
- No unencrypted connections will be allowed. You should also set the
- <TT>certfile</TT> option.
- <DT CLASS="dt-description"><B><TT>tls</TT></B><DD CLASS="dd-description"> This option specifies that traffic on
- the port will be encrypted using SSL immediately after connecting. You
- should also set the <TT>certfile</TT> option.
- <DT CLASS="dt-description"><B><TT>zlib</TT></B><DD CLASS="dd-description"> This
- option specifies that Zlib stream compression (as defined in <A HREF="http://www.jabber.org/jeps/jep-0138.html">JEP-0138</A>)
- is available on connections to the port. Client connections cannot use
- stream compression and stream encryption simultaneously. Hence, if you
- specify both <TT>tls</TT> (or <TT>ssl</TT>) and <TT>zlib</TT>, the latter
- option will not affect connections (there will be no stream compression).
- <DT CLASS="dt-description"><B><TT>web_admin</TT></B><DD CLASS="dd-description"> This option
- enables the web interface for <TT>ejabberd</TT> administration which is available
- at <CODE>http://server:port/admin/</CODE>. Login and password are the username and
- password of one of the registered users who are granted access by the
- `configure' access rule.
-</DL>
-In addition, the following options are available for s2s connections:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
- <B><TT>{s2s_use_starttls, true|false}</TT></B><DD CLASS="dd-description">
- This option defines whether to
- use STARTTLS for s2s connections.
- <DT CLASS="dt-description"><B><TT>{s2s_certfile, Path}</TT></B><DD CLASS="dd-description"> Path to a
- file containing a SSL certificate.
- <DT CLASS="dt-description"><B><TT>{domain_certfile, Domain, Path}</TT></B><DD CLASS="dd-description"> Path
- to the file containing the SSL certificate for the specified domain.
-</DL>
-For instance, the following configuration defines that:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-c2s connections are listened for on port 5222 and 5223 (SSL) and denied
- for the user called `<TT>bad</TT>'.
-<LI CLASS="li-itemize">s2s connections are listened for on port 5269 with STARTTLS for secured
- traffic enabled.
-<LI CLASS="li-itemize">Port 5280 is serving the web interface and the HTTP Polling service. Note
- that it is also possible to serve them on different ports. The second
- example in section&nbsp;<A HREF="#sec:webinterface">7.1</A> shows how exactly this can be done.
-<LI CLASS="li-itemize">All users except for the administrators have a traffic of limit
- 1,000&nbsp;Bytes/second
-<LI CLASS="li-itemize">The
- <A HREF="http://ejabberd.jabber.ru/pyaimt">AIM transport</A>
- <TT>aim.example.org</TT> is connected to port 5233 with password
- `<TT>aimsecret</TT>'.
-<LI CLASS="li-itemize">The ICQ transport JIT (<TT>icq.example.org</TT> and
- <TT>sms.example.org</TT>) is connected to port 5234 with password
- `<TT>jitsecret</TT>'.
-<LI CLASS="li-itemize">The
- <A HREF="http://ejabberd.jabber.ru/pymsnt">MSN transport</A>
- <TT>msn.example.org</TT> is connected to port 5235 with password
- `<TT>msnsecret</TT>'.
-<LI CLASS="li-itemize">The
- <A HREF="http://ejabberd.jabber.ru/yahoo-transport-2">Yahoo! transport</A>
- <TT>yahoo.example.org</TT> is connected to port 5236 with password
- `<TT>yahoosecret</TT>'.
-<LI CLASS="li-itemize">The <A HREF="http://ejabberd.jabber.ru/jabber-gg-transport">Gadu-Gadu transport</A> <TT>gg.example.org</TT> is
- connected to port 5237 with password `<TT>ggsecret</TT>'.
-<LI CLASS="li-itemize">The
- <A HREF="http://ejabberd.jabber.ru/jmc">Jabber Mail Component</A>
- <TT>jmc.example.org</TT> is connected to port 5238 with password
- `<TT>jmcsecret</TT>'.
-</UL>
-<PRE CLASS="verbatim">
- {acl, blocked, {user, "bad"}}.
- {access, c2s, [{deny, blocked},
- {allow, all}]}.
- {shaper, normal, {maxrate, 1000}}.
- {access, c2s_shaper, [{none, admin},
- {normal, all}]}.
- {listen,
- [{5222, ejabberd_c2s, [{access, c2s}, {shaper, c2s_shaper}]},
- {5223, ejabberd_c2s, [{access, c2s},
- ssl, {certfile, "/path/to/ssl.pem"}]},
- {5269, ejabberd_s2s_in, []},
- {5280, ejabberd_http, [http_poll, web_admin]},
- {5233, ejabberd_service, [{host, "aim.example.org",
- [{password, "aimsecret"}]}]},
- {5234, ejabberd_service, [{hosts, ["icq.example.org", "sms.example.org"],
- [{password, "jitsecret"}]}]},
- {5235, ejabberd_service, [{host, "msn.example.org",
- [{password, "msnsecret"}]}]},
- {5236, ejabberd_service, [{host, "yahoo.example.org",
- [{password, "yahoosecret"}]}]},
- {5237, ejabberd_service, [{host, "gg.example.org",
- [{password, "ggsecret"}]}]},
- {5238, ejabberd_service, [{host, "jmc.example.org",
- [{password, "jmcsecret"}]}]}
- ]
- }.
- {s2s_use_starttls, true}.
- {s2s_certfile, "/path/to/ssl.pem"}.
-</PRE>Note, that for jabberd 1.4- or WPJabber-based
-services you have to make the transports log and do XDB by themselves:
-<PRE CLASS="verbatim">
- &lt;!--
- You have to add elogger and rlogger entries here when using ejabberd.
- In this case the transport will do the logging.
- --&gt;
-
- &lt;log id='logger'&gt;
- &lt;host/&gt;
- &lt;logtype/&gt;
- &lt;format&gt;%d: [%t] (%h): %s&lt;/format&gt;
- &lt;file&gt;/var/log/jabber/service.log&lt;/file&gt;
- &lt;/log&gt;
-
- &lt;!--
- Some Jabber server implementations do not provide
- XDB services (for example, jabberd2 and ejabberd).
- xdb_file.so is loaded in to handle all XDB requests.
- --&gt;
-
- &lt;xdb id="xdb"&gt;
- &lt;host/&gt;
- &lt;load&gt;
- &lt;!-- this is a lib of wpjabber or jabberd --&gt;
- &lt;xdb_file&gt;/usr/lib/jabber/xdb_file.so&lt;/xdb_file&gt;
- &lt;/load&gt;
- &lt;xdb_file xmlns="jabber:config:xdb_file"&gt;
- &lt;spool&gt;&lt;jabberd:cmdline flag='s'&gt;/var/spool/jabber&lt;/jabberd:cmdline&gt;&lt;/spool&gt;
- &lt;/xdb_file&gt;
- &lt;/xdb&gt;
-</PRE>
-<!--TOC subsection Authentication-->
-
-<H3 CLASS="subsection"><A NAME="htoc17">3.4</A>&nbsp;&nbsp;<A NAME="auth">Authentication</A></H3><!--SEC END -->
-
-<A NAME="sec:auth"></A>
-
-The option <TT>auth_method</TT> defines the authentication method that is used
-for user authentication:
-<PRE CLASS="verbatim">
- {auth_method, [&lt;method&gt;]}.
-</PRE>
-The following authentication methods are supported by <TT>ejabberd</TT>:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-internal (default) &mdash; See section&nbsp;<A HREF="#sec:internalauth">3.4.1</A>.
-<LI CLASS="li-itemize">external &mdash; There are <A HREF="http://ejabberd.jabber.ru/extauth">some
- example authentication scripts</A>.
-<LI CLASS="li-itemize">ldap &mdash; See section&nbsp;<A HREF="#sec:ldap">4.5</A>.
-<LI CLASS="li-itemize">odbc &mdash; See section&nbsp;<A HREF="#sec:mysql">4.1</A>, <A HREF="#sec:pgsql">4.3</A>,
- <A HREF="#sec:mssql">4.2</A> and <A HREF="#sec:odbc">4.4</A>.
-<LI CLASS="li-itemize">anonymous &mdash; See section&nbsp;<A HREF="#sec:saslanonymous">3.4.2</A>.
-</UL>
-<!--TOC subsubsection Internal-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc18">3.4.1</A>&nbsp;&nbsp;<A NAME="internalauth">Internal</A></H4><!--SEC END -->
-
-<A NAME="sec:internalauth"></A>
-
-<TT>ejabberd</TT> uses its internal Mnesia database as the default authentication method.
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-<TT>auth_method</TT>: The value <TT>internal</TT> will enable the internal
- authentication method.
-</UL>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-To use internal authentication on <TT>example.org</TT> and LDAP
- authentication on <TT>example.net</TT>:
- <PRE CLASS="verbatim">
-{host_config, "example.org", [{auth_method, [internal]}]}.
-{host_config, "example.net", [{auth_method, [ldap]}]}.
-</PRE><LI CLASS="li-itemize">To use internal authentication on all virtual hosts:
- <PRE CLASS="verbatim">
-{auth_method, internal}.
-</PRE></UL>
-<!--TOC subsubsection SASL Anonymous and Anonymous Login-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc19">3.4.2</A>&nbsp;&nbsp;<A NAME="saslanonymous">SASL Anonymous and Anonymous Login</A></H4><!--SEC END -->
-
-<A NAME="sec:saslanonymous"></A>
-
-The anonymous authentication method can be configured with the following
-options. Remember that you can use the <TT>host_config</TT> option to set virtual
-host specific options (see section&nbsp;<A HREF="#sec:virtualhost">3.2</A>). Note that there also
-is a detailed tutorial regarding <A HREF="http://support.process-one.net/doc/display/MESSENGER/Anonymous+users+support">SASL
-Anonymous and anonymous login configuration</A>.
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-<TT>auth_method</TT>: The value <TT>anonymous</TT> will enable the anonymous
- authentication method.
-<LI CLASS="li-itemize"><TT>allow_multiple_connections</TT>: This value for this option can be
- either <TT>true</TT> or <TT>false</TT> and is only used when the anonymous mode is
- enabled. Setting it to <TT>true</TT> means that the same username can be taken
- multiple times in anonymous login mode if different resource are used to
- connect. This option is only useful in very special occasions. The default
- value is <TT>false</TT>.
-<LI CLASS="li-itemize"><TT>anonymous_protocol</TT>: This option can take three values:
- <TT>sasl_anon</TT>, <TT>login_anon</TT> or <TT>both</TT>. <TT>sasl_anon</TT> means
- that the SASL Anonymous method will be used. <TT>login_anon</TT> means that the
- anonymous login method will be used. <TT>both</TT> means that SASL Anonymous and
- login anonymous are both enabled.
-</UL>
-Those options are defined for each virtual host with the <TT>host_config</TT>
-parameter (see section&nbsp;<A HREF="#sec:virtualhost">3.2</A>).<BR>
-<BR>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-To enable anonymous login on all virtual hosts:
- <PRE CLASS="verbatim">
-{auth_method, [anonymous]}.
-{anonymous_protocol, login_anon}.
- </PRE><LI CLASS="li-itemize">Similar as previous example, but limited to <TT>public.example.org</TT>:
- <PRE CLASS="verbatim">
-{host_config, "public.example.org", [{auth_method, [anonymous]},
- {anonymous_protocol, login_anon}]}.
-</PRE><LI CLASS="li-itemize">To enable anonymous login and internal authentication on a virtual host:
- <PRE CLASS="verbatim">
-{host_config, "public.example.org", [{auth_method, [anonymous,internal]},
- {anonymous_protocol, login_anon}]}.
-</PRE><LI CLASS="li-itemize">To enable SASL Anonymous on a virtual host:
- <PRE CLASS="verbatim">
-{host_config, "public.example.org", [{auth_method, [anonymous]},
- {anonymous_protocol, sasl_anon}]}.
-</PRE><LI CLASS="li-itemize">To enable SASL Anonymous and anonymous login on a virtual host:
- <PRE CLASS="verbatim">
-{host_config, "public.example.org", [{auth_method, [anonymous]},
- {anonymous_protocol, both}]}.
-</PRE><LI CLASS="li-itemize">To enable SASL Anonymous, anonymous login, and internal authentication on
-a virtual host:
- <PRE CLASS="verbatim">
-{host_config, "public.example.org", [{auth_method, [anonymous,internal]},
- {anonymous_protocol, both}]}.
-</PRE></UL>
-<!--TOC subsection Access Rules-->
-
-<H3 CLASS="subsection"><A NAME="htoc20">3.5</A>&nbsp;&nbsp;<A NAME="accessrules">Access Rules</A></H3><!--SEC END -->
-
-<A NAME="sec:accessrules"></A>
-
-Access control in <TT>ejabberd</TT> is performed via Access Control Lists (ACLs). The
-declarations of ACLs in the configuration file have the following syntax:
-<PRE CLASS="verbatim">
- {acl, &lt;aclname&gt;, {&lt;acltype&gt;, ...}}.
-</PRE>
-<TT>&lt;acltype&gt;</TT> can be one of the following:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>all</TT></B><DD CLASS="dd-description"> Matches all JIDs. Example:
-<PRE CLASS="verbatim">
-{acl, all, all}.
-</PRE><DT CLASS="dt-description"><B><TT>{user, &lt;username&gt;}</TT></B><DD CLASS="dd-description"> Matches the user with the name
- <TT>&lt;username&gt;</TT> at the first virtual host. Example:
-<PRE CLASS="verbatim">
-{acl, admin, {user, "yozhik"}}.
-</PRE><DT CLASS="dt-description"><B><TT>{user, &lt;username&gt;, &lt;server&gt;}</TT></B><DD CLASS="dd-description"> Matches the user with the JID
- <TT>&lt;username&gt;@&lt;server&gt;</TT> and any resource. Example:
-<PRE CLASS="verbatim">
-{acl, admin, {user, "yozhik", "example.org"}}.
-</PRE><DT CLASS="dt-description"><B><TT>{server, &lt;server&gt;}</TT></B><DD CLASS="dd-description"> Matches any JID from server
- <TT>&lt;server&gt;</TT>. Example:
-<PRE CLASS="verbatim">
-{acl, exampleorg, {server, "example.org"}}.
-</PRE><DT CLASS="dt-description"><B><TT>{user_regexp, &lt;regexp&gt;}</TT></B><DD CLASS="dd-description"> Matches any local user with a name that
- matches <TT>&lt;regexp&gt;</TT> at the first virtual host. Example:
-<PRE CLASS="verbatim">
-{acl, tests, {user, "^test[0-9]*$"}}.
-</PRE><DT CLASS="dt-description"><B><TT>{user_regexp, &lt;regexp&gt;, &lt;server&gt;}</TT></B><DD CLASS="dd-description"> Matches any user with a name
- that matches <TT>&lt;regexp&gt;</TT> at server <TT>&lt;server&gt;</TT>. Example:
-<PRE CLASS="verbatim">
-{acl, tests, {user, "^test", "example.org"}}.
-</PRE><DT CLASS="dt-description"><B><TT>{server_regexp, &lt;regexp&gt;}</TT></B><DD CLASS="dd-description"> Matches any JID from the server that
- matches <TT>&lt;regexp&gt;</TT>. Example:
-<PRE CLASS="verbatim">
-{acl, icq, {server, "^icq\\."}}.
-</PRE><DT CLASS="dt-description"><B><TT>{node_regexp, &lt;user_regexp&gt;, &lt;server_regexp&gt;}</TT></B><DD CLASS="dd-description"> Matches any user
- with a name that matches <TT>&lt;user_regexp&gt;</TT> at any server that matches
- <TT>&lt;server_regexp&gt;</TT>. Example:
-<PRE CLASS="verbatim">
-{acl, yohzik, {node_regexp, "^yohzik$", "^example.(com|org)$"}}.
-</PRE><DT CLASS="dt-description"><B><TT>{user_glob, &lt;glob&gt;}</TT></B><DD CLASS="dd-description">
-<DT CLASS="dt-description"><B><TT>{user_glob, &lt;glob&gt;, &lt;server&gt;}</TT></B><DD CLASS="dd-description">
-<DT CLASS="dt-description"><B><TT>{server_glob, &lt;glob&gt;}</TT></B><DD CLASS="dd-description">
-<DT CLASS="dt-description"><B><TT>{node_glob, &lt;user_glob&gt;, &lt;server_glob&gt;}</TT></B><DD CLASS="dd-description"> This is the same as
- above. However, it uses shell glob patterns instead of regexp. These patterns
- can have the following special characters:
- <DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
- <B><TT>*</TT></B><DD CLASS="dd-description"> matches any string including the null string.
- <DT CLASS="dt-description"><B><TT>?</TT></B><DD CLASS="dd-description"> matches any single character.
- <DT CLASS="dt-description"><B><TT>[...]</TT></B><DD CLASS="dd-description"> matches any of the enclosed characters. Character
- ranges are specified by a pair of characters separated by a <TT>`-'</TT>.
- If the first character after <TT>`['</TT> is a <TT>`!'</TT>, any
- character not enclosed is matched.
- </DL>
-</DL>
-The following ACLs are pre-defined:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>all</TT></B><DD CLASS="dd-description"> Matches any JID.
-<DT CLASS="dt-description"><B><TT>none</TT></B><DD CLASS="dd-description"> Matches no JID.
-</DL>
-An entry allowing or denying access to different services looks similar to
-this:
-<PRE CLASS="verbatim">
- {access, &lt;accessname&gt;, [{allow, &lt;aclname&gt;},
- {deny, &lt;aclname&gt;},
- ...
- ]}.
-</PRE>When a JID is checked to have access to <TT>&lt;accessname&gt;</TT>, the server
-sequentially checks if that JID mathes any of the ACLs that are named in the
-second elements of the tuples in the list. If it matches, the first element of
-the first matched tuple is returned, otherwise the value `<TT>deny</TT>' is
-returned.<BR>
-<BR>
-Example:
-<PRE CLASS="verbatim">
- {access, configure, [{allow, admin}]}.
- {access, something, [{deny, badmans},
- {allow, all}]}.
-</PRE>
-The following access rules are pre-defined:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>all</TT></B><DD CLASS="dd-description"> Always returns the value `<TT>allow</TT>'.
-<DT CLASS="dt-description"><B><TT>none</TT></B><DD CLASS="dd-description"> Always returns the value `<TT>deny</TT>'.
-</DL>
-<!--TOC subsection Shapers-->
-
-<H3 CLASS="subsection"><A NAME="htoc21">3.6</A>&nbsp;&nbsp;<A NAME="shapers">Shapers</A></H3><!--SEC END -->
-
-<A NAME="sec:shapers"></A>
-
-Shapers enable you to limit connection traffic. The syntax of
-shapers is like this:
-<PRE CLASS="verbatim">
- {shaper, &lt;shapername&gt;, &lt;kind&gt;}.
-</PRE>Currently only one kind of shaper called <TT>maxrate</TT> is available. It has the
-following syntax:
-<PRE CLASS="verbatim">
- {maxrate, &lt;rate&gt;}
-</PRE>where <TT>&lt;rate&gt;</TT> stands for the maximum allowed incomig rate in bytes per
-second.<BR>
-<BR>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-To define a shaper named `<TT>normal</TT>' with traffic speed limited to
-1,000&nbsp;bytes/second:
-<PRE CLASS="verbatim">
- {shaper, normal, {maxrate, 1000}}.
-</PRE><LI CLASS="li-itemize">To define a shaper named `<TT>fast</TT>' with traffic speed limited to
-50,000&nbsp;bytes/second:
-<PRE CLASS="verbatim">
- {shaper, fast, {maxrate, 50000}}.
-</PRE></UL>
-<!--TOC subsection Limiting Opened Sessions-->
-
-<H3 CLASS="subsection"><A NAME="htoc22">3.7</A>&nbsp;&nbsp;Limiting Opened Sessions</H3><!--SEC END -->
-
-<A NAME="sec:configmaxsessions"></A>
-
-This option specifies the maximum number of sessions (authenticated
-connections) per user. If a user tries to open more sessions by using different
-resources, the first opened session will be disconnected. The error
-<TT>session replaced</TT> will be sent to the disconnected session. The value
-for this option can be either a number, or <TT>infinity</TT>. The default
-value is <TT>10</TT>.<BR>
-<BR>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-To limit the number of sessions per user to 10 on all virtual
-hosts:
-<PRE CLASS="verbatim">
- {max_user_sessions, 10}.
-</PRE><LI CLASS="li-itemize">This option can be defined per virtual host (see
-section&nbsp;<A HREF="#sec:virtualhost">3.2</A>). In next example the number of
-sessions per user on the first host is six, while there is no limit on the
-second host:
-<PRE CLASS="verbatim">
- {host_config, "example.net", [{max_user_sessions, 6}]}.
- {host_config, "example.com", [{max_user_sessions, infinity}]}.
-</PRE></UL>
-<!--TOC subsection Default Language-->
-
-<H3 CLASS="subsection"><A NAME="htoc23">3.8</A>&nbsp;&nbsp;<A NAME="language">Default Language</A></H3><!--SEC END -->
-
-<A NAME="sec:language"></A>
-
-The option <TT>language</TT> defines the default language of server strings that
-can be seen by Jabber clients. If a Jabber client do not support
-<TT>xml:lang</TT>, the specified language is used. The default value is
-<TT>en</TT>. In order to take effect there must be a translation file
-<TT>&lt;language&gt;.msg</TT> in <TT>ejabberd</TT>'s <TT>msgs</TT> directory.<BR>
-<BR>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-To set Russian as default language:
-<PRE CLASS="verbatim">
- {language, "ru"}.
-</PRE><LI CLASS="li-itemize">To set Spanish as default language:
-<PRE CLASS="verbatim">
- {language, "es"}.
-</PRE></UL>
-<!--TOC section Database Configuration-->
-
-<H2 CLASS="section"><A NAME="htoc24">4</A>&nbsp;&nbsp;<A NAME="database">Database Configuration</A></H2><!--SEC END -->
-
-<A NAME="sec:database"></A>
-
-
-<TT>ejabberd</TT> uses its internal Mnesia database by default. However, it is
-possible to use a relational database or an LDAP server to store persistant,
-long-living data. <TT>ejabberd</TT> is very flexible: you can configure different
-authentication methods for different virtual hosts, you can configure different
-authentication mechanisms for the same virtual host (fallback), you can set
-different storage systems for modules, and so forth.<BR>
-<BR>
-The following databases are supported by <TT>ejabberd</TT>:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-<A HREF="http://www.microsoft.com/sql/">Microsoft SQL Server</A>
-<LI CLASS="li-itemize"><A HREF="http://www.erlang.org/doc/doc-5.5.1/lib/mnesia-4.3.2/doc/">Mnesia</A>
-<LI CLASS="li-itemize"><A HREF="http://mysql.com/">MySQL</A>
-<LI CLASS="li-itemize"><A HREF="http://en.wikipedia.org/wiki/Open_Database_Connectivity">Any ODBC compatible database</A>
-<LI CLASS="li-itemize"><A HREF="http://www.postgresql.org/">PostgreSQL</A>
-</UL>
-The following LDAP servers are tested with <TT>ejabberd</TT>:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-<A HREF="http://www.microsoft.com/activedirectory/">Active Directory</A>
- (see section&nbsp;<A HREF="#sec:ad">4.5.3</A>)
-<LI CLASS="li-itemize"><A HREF="http://www.openldap.org/">OpenLDAP</A>
-<LI CLASS="li-itemize">Normally any LDAP compatible server should work; inform us about your
- success with a not-listed server so that we can list it here.
-</UL>
-<!--TOC subsection MySQL-->
-
-<H3 CLASS="subsection"><A NAME="htoc25">4.1</A>&nbsp;&nbsp;<A NAME="mysql">MySQL</A></H3><!--SEC END -->
-
-<A NAME="sec:mysql"></A>
-
-Although this section will describe <TT>ejabberd</TT>'s configuration when you want to
-use the native MySQL driver, it does not describe MySQL's installation and
-database creation. Check the MySQL documentation and the tutorial <A HREF="http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver">Using ejabberd with MySQL native driver</A> for information regarding these topics.
-Note that the tutorial contains information about <TT>ejabberd</TT>'s configuration
-which is duplicate to this section.<BR>
-<BR>
-Moreover, the file mysql.sql in the directory src/odbc might be interesting for
-you. This file contains the ejabberd schema for MySQL. At the end of the file
-you can find information to update your database schema.<BR>
-<BR>
-<!--TOC subsubsection Driver Compilation-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc26">4.1.1</A>&nbsp;&nbsp;<A NAME="compilemysql">Driver Compilation</A></H4><!--SEC END -->
-
-<A NAME="sec:compilemysql"></A>
-
-You can skip this step if you installed <TT>ejabberd</TT> using a binary installer or
-if the binary packages of <TT>ejabberd</TT> you are using include support for MySQL.
-<OL CLASS="enumerate" type=1><LI CLASS="li-enumerate">
-First, install the <A HREF="http://support.process-one.net/doc/display/CONTRIBS/Yxa">Erlang
- MySQL library</A>. Make sure the compiled files are in your Erlang path; you can
- put them for example in the same directory as your ejabberd .beam files.
-<LI CLASS="li-enumerate">Then, configure and install <TT>ejabberd</TT> with ODBC support enabled (this is
- also needed for native MySQL support!). This can be done, by using next
- commands:
- <PRE CLASS="verbatim">
-./configure --enable-odbc &amp;&amp; make install
-</PRE></OL>
-<!--TOC subsubsection Authentication-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc27">4.1.2</A>&nbsp;&nbsp;<A NAME="mysqlauth">Authentication</A></H4><!--SEC END -->
-
-<A NAME="sec:mysqlauth"></A>
-
-The option value name may be misleading, as the <TT>auth_method</TT> name is used
-for access to a relational database through ODBC, as well as through the native
-MySQL interface. Anyway, the first configuration step is to define the odbc
-<TT>auth_method</TT>. For example:
-<PRE CLASS="verbatim">
-{host_config, "public.example.org", [{auth_method, [odbc]}]}.
-</PRE>
-The actual database access is defined in the option <TT>odbc_server</TT>. Its
-value is used to define if we want to use ODBC, or one of the two native
-interface available, PostgreSQL or MySQL.<BR>
-<BR>
-To use the native MySQL interface, you can pass a tuple of the following form as
-parameter:
-<PRE CLASS="verbatim">
-{mysql, "Server", "Database", "Username", "Password"}
-</PRE>
-<TT>mysql</TT> is a keyword that should be kept as is. For example:
-<PRE CLASS="verbatim">
-{odbc_server, {mysql, "localhost", "test", "root", "password"}}.
-</PRE>
-<!--TOC subsubsection Storage-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc28">4.1.3</A>&nbsp;&nbsp;<A NAME="mysqlstorage">Storage</A></H4><!--SEC END -->
-
-<A NAME="sec:mysqlstorage"></A>
-
-MySQL also can be used to store information into from several <TT>ejabberd</TT>
-modules. See section&nbsp;<A HREF="#sec:modoverview">5.1</A> to see which modules have a version
-with the `_odbc'. This suffix indicates that the module can be used with
-relational databases like MySQL. To enable storage to your database, just make
-sure that your database is running well (see previous sections), and replace the
-suffix-less or ldap module variant with the odbc module variant. Keep in mind
-that you cannot have several variants of the same module loaded!<BR>
-<BR>
-<!--TOC subsection Microsoft SQL Server-->
-
-<H3 CLASS="subsection"><A NAME="htoc29">4.2</A>&nbsp;&nbsp;<A NAME="mssql">Microsoft SQL Server</A></H3><!--SEC END -->
-
-<A NAME="sec:mssql"></A>
-
-Although this section will describe <TT>ejabberd</TT>'s configuration when you want to
-use Microsoft SQL Server, it does not describe Microsoft SQL Server's
-installation and database creation. Check the MySQL documentation and the
-tutorial <A HREF="http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver">Using ejabberd with MySQL native driver</A> for information regarding these topics.
-Note that the tutorial contains information about <TT>ejabberd</TT>'s configuration
-which is duplicate to this section.<BR>
-<BR>
-Moreover, the file mssql.sql in the directory src/odbc might be interesting for
-you. This file contains the ejabberd schema for Microsoft SQL Server. At the end
-of the file you can find information to update your database schema.<BR>
-<BR>
-<!--TOC subsubsection Driver Compilation-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc30">4.2.1</A>&nbsp;&nbsp;<A NAME="compilemssql">Driver Compilation</A></H4><!--SEC END -->
-
-<A NAME="sec:compilemssql"></A>
-
-You can skip this step if you installed <TT>ejabberd</TT> using a binary installer or
-if the binary packages of <TT>ejabberd</TT> you are using include support for ODBC.<BR>
-<BR>
-If you want to use Microsoft SQL Server with ODBC, you need to configure,
-compile and install <TT>ejabberd</TT> with support for ODBC and Microsoft SQL Server
-enabled. This can be done, by using next commands:
-<PRE CLASS="verbatim">
-./configure --enable-odbc --enable-mssql &amp;&amp; make install
-</PRE>
-<!--TOC subsubsection Authentication-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc31">4.2.2</A>&nbsp;&nbsp;<A NAME="mssqlauth">Authentication</A></H4><!--SEC END -->
-
-<A NAME="sec:mssqlauth"></A>
-
-The configuration of Microsoft SQL Server is the same as the configuration of
-ODBC compatible serers (see section&nbsp;<A HREF="#sec:odbcauth">4.4.2</A>).<BR>
-<BR>
-<!--TOC subsubsection Storage-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc32">4.2.3</A>&nbsp;&nbsp;<A NAME="mssqlstorage">Storage</A></H4><!--SEC END -->
-
-<A NAME="sec:mssqlstorage"></A>
-
-Microsoft SQL Server also can be used to store information into from several
-<TT>ejabberd</TT> modules. See section&nbsp;<A HREF="#sec:modoverview">5.1</A> to see which modules have
-a version with the `_odbc'. This suffix indicates that the module can be used
-with relational databases like Microsoft SQL Server. To enable storage to your
-database, just make sure that your database is running well (see previous
-sections), and replace the suffix-less or ldap module variant with the odbc
-module variant. Keep in mind that you cannot have several variants of the same
-module loaded!<BR>
-<BR>
-<!--TOC subsection PostgreSQL-->
-
-<H3 CLASS="subsection"><A NAME="htoc33">4.3</A>&nbsp;&nbsp;<A NAME="pgsql">PostgreSQL</A></H3><!--SEC END -->
-
-<A NAME="sec:pgsql"></A>
-
-Although this section will describe <TT>ejabberd</TT>'s configuration when you want to
-use the native PostgreSQL driver, it does not describe PostgreSQL's installation
-and database creation. Check the PostgreSQL documentation and the tutorial <A HREF="http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver">Using ejabberd with MySQL native driver</A> for information regarding these topics.
-Note that the tutorial contains information about <TT>ejabberd</TT>'s configuration
-which is duplicate to this section.<BR>
-<BR>
-Also the file pg.sql in the directory src/odbc might be interesting for you.
-This file contains the ejabberd schema for PostgreSQL. At the end of the file
-you can find information to update your database schema.<BR>
-<BR>
-<!--TOC subsubsection Driver Compilation-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc34">4.3.1</A>&nbsp;&nbsp;<A NAME="compilepgsql">Driver Compilation</A></H4><!--SEC END -->
-
-<A NAME="sec:compilepgsql"></A>
-
-You can skip this step if you installed <TT>ejabberd</TT> using a binary installer or
-if the binary packages of <TT>ejabberd</TT> you are using include support for
-PostgreSQL.
-<OL CLASS="enumerate" type=1><LI CLASS="li-enumerate">
-First, install the Erlang PgSQL library from
- <A HREF="http://jungerl.sourceforge.net/">Jungerl</A>. Make sure the compiled
- files are in your Erlang path; you can put them for example in the same
- directory as your ejabberd .beam files.
-<LI CLASS="li-enumerate">Then, configure, compile and install <TT>ejabberd</TT> with ODBC support enabled
- (this is also needed for native PostgreSQL support!). This can be done, by
- using next commands:
- <PRE CLASS="verbatim">
-./configure --enable-odbc &amp;&amp; make install
-</PRE></OL>
-<!--TOC subsubsection Authentication-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc35">4.3.2</A>&nbsp;&nbsp;<A NAME="pgsqlauth">Authentication</A></H4><!--SEC END -->
-
-<A NAME="sec:pgsqlauth"></A>
-
-The option value name may be misleading, as the <TT>auth_method</TT> name is used
-for access to a relational database through ODBC, as well as through the native
-PostgreSQL interface. Anyway, the first configuration step is to define the odbc
-<TT>auth_method</TT>. For example:
-<PRE CLASS="verbatim">
-{host_config, "public.example.org", [{auth_method, [odbc]}]}.
-</PRE>
-The actual database access is defined in the option <TT>odbc_server</TT>. Its
-value is used to define if we want to use ODBC, or one of the two native
-interface available, PostgreSQL or MySQL.<BR>
-<BR>
-To use the native PostgreSQL interface, you can pass a tuple of the following
-form as parameter:
-<PRE CLASS="verbatim">
-{pgsql, "Server", "Database", "Username", "Password"}
-</PRE>
-<TT>pgsql</TT> is a keyword that should be kept as is. For example:
-<PRE CLASS="verbatim">
-{odbc_server, {pgsql, "localhost", "database", "ejabberd", "password"}}.
-</PRE>
-<!--TOC subsubsection Storage-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc36">4.3.3</A>&nbsp;&nbsp;<A NAME="pgsqlstorage">Storage</A></H4><!--SEC END -->
-
-<A NAME="sec:pgsqlstorage"></A>
-
-PostgreSQL also can be used to store information into from several <TT>ejabberd</TT>
-modules. See section&nbsp;<A HREF="#sec:modoverview">5.1</A> to see which modules have a version
-with the `_odbc'. This suffix indicates that the module can be used with
-relational databases like PostgreSQL. To enable storage to your database, just
-make sure that your database is running well (see previous sections), and
-replace the suffix-less or ldap module variant with the odbc module variant.
-Keep in mind that you cannot have several variants of the same module loaded!<BR>
-<BR>
-<!--TOC subsection ODBC Compatible-->
-
-<H3 CLASS="subsection"><A NAME="htoc37">4.4</A>&nbsp;&nbsp;<A NAME="odbc">ODBC Compatible</A></H3><!--SEC END -->
-
-<A NAME="sec:odbc"></A>
-
-Although this section will describe <TT>ejabberd</TT>'s configuration when you want to
-use the ODBC driver, it does not describe the installation and database creation
-of your database. Check the documentation of your database. The tutorial <A HREF="http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver">Using ejabberd with MySQL native driver</A> also can help you. Note that the tutorial
-contains information about <TT>ejabberd</TT>'s configuration which is duplicate to
-this section.<BR>
-<BR>
-<!--TOC subsubsection Compilation-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc38">4.4.1</A>&nbsp;&nbsp;<A NAME="compileodbc">Compilation</A></H4><!--SEC END -->
-
-<A NAME="sec:compileodbc"></A>
-You can skip this step if you installed <TT>ejabberd</TT> using a binary installer or
-if the binary packages of <TT>ejabberd</TT> you are using include support for
-ODBC.
-<OL CLASS="enumerate" type=1><LI CLASS="li-enumerate">
-First, install the <A HREF="http://support.process-one.net/doc/display/CONTRIBS/Yxa">Erlang
- MySQL library</A>. Make sure the compiled files are in your Erlang path; you can
- put them for example in the same directory as your ejabberd .beam files.
-<LI CLASS="li-enumerate">Then, configure, compile and install <TT>ejabberd</TT> with ODBC support
- enabled. This can be done, by using next commands:
- <PRE CLASS="verbatim">
-./configure --enable-odbc &amp;&amp; make install
-</PRE></OL>
-<!--TOC subsubsection Authentication-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc39">4.4.2</A>&nbsp;&nbsp;<A NAME="odbcauth">Authentication</A></H4><!--SEC END -->
-
-<A NAME="sec:odbcauth"></A>
-
-The first configuration step is to define the odbc <TT>auth_method</TT>. For
-example:
-<PRE CLASS="verbatim">
-{host_config, "public.example.org", [{auth_method, [odbc]}]}.
-</PRE>
-The actual database access is defined in the option <TT>odbc_server</TT>. Its
-value is used to defined if we want to use ODBC, or one of the two native
-interface available, PostgreSQL or MySQL.<BR>
-<BR>
-To use a relational database through ODBC, you can pass the ODBC connection
-string as <TT>odbc_server</TT> parameter. For example:
-<PRE CLASS="verbatim">
-{odbc_server, "DSN=database;UID=ejabberd;PWD=password"}.
-</PRE>
-<!--TOC subsubsection Storage-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc40">4.4.3</A>&nbsp;&nbsp;<A NAME="odbcstorage">Storage</A></H4><!--SEC END -->
-
-<A NAME="sec:odbcstorage"></A>
-
-An ODBC compatible database also can be used to store information into from
-several <TT>ejabberd</TT> modules. See section&nbsp;<A HREF="#sec:modoverview">5.1</A> to see which
-modules have a version with the `_odbc'. This suffix indicates that the module
-can be used with ODBC compatible relational databases. To enable storage to your
-database, just make sure that your database is running well (see previous
-sections), and replace the suffix-less or ldap module variant with the odbc
-module variant. Keep in mind that you cannot have several variants of the same
-module loaded!<BR>
-<BR>
-<!--TOC subsection LDAP-->
-
-<H3 CLASS="subsection"><A NAME="htoc41">4.5</A>&nbsp;&nbsp;<A NAME="ldap">LDAP</A></H3><!--SEC END -->
-
-<A NAME="sec:ldap"></A>
-
-<TT>ejabberd</TT> has built-in LDAP support. You can authenticate users against LDAP
-server and use LDAP directory as vCard storage. Shared rosters are not supported
-yet.<BR>
-<BR>
-<!--TOC subsubsection Connection-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc42">4.5.1</A>&nbsp;&nbsp;<A NAME="ldapconnection">Connection</A></H4><!--SEC END -->
-
-<A NAME="sec:ldapconnection"></A>
-Parameters:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>ldap_server</TT></B><DD CLASS="dd-description"> IP address or dns name of your
-LDAP server. This option is required.
-<DT CLASS="dt-description"><B><TT>ldap_port</TT></B><DD CLASS="dd-description"> Port to connect to your LDAP server.
- The default value is&nbsp;389.
-<DT CLASS="dt-description"><B><TT>ldap_rootdn</TT></B><DD CLASS="dd-description"> Bind DN. The default value
- is&nbsp;<TT>""</TT> which means `anonymous connection'.
-<DT CLASS="dt-description"><B><TT>ldap_password</TT></B><DD CLASS="dd-description"> Bind password. The default
- value is <TT>""</TT>.
-</DL>
-Example:
-<PRE CLASS="verbatim">
- {auth_method, ldap}.
- {ldap_servers, ["ldap.example.org"]}.
- {ldap_port, 389}.
- {ldap_rootdn, "cn=Manager,dc=domain,dc=org"}.
- {ldap_password, "secret"}.
-</PRE>
-Note that current LDAP implementation does not support SSL secured communication
-and SASL authentication.<BR>
-<BR>
-<!--TOC subsubsection Authentication-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc43">4.5.2</A>&nbsp;&nbsp;<A NAME="ldapauth">Authentication</A></H4><!--SEC END -->
-
-<A NAME="sec:ldapauth"></A>
-You can authenticate users against an LDAP directory. Available options are:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>ldap_base</TT></B><DD CLASS="dd-description">LDAP base directory which stores users
- accounts. This option is required.
-<DT CLASS="dt-description"><B><TT>ldap_uidattr</TT></B><DD CLASS="dd-description">LDAP attribute which holds
- the user's part of a JID. The default value is <TT>"uid"</TT>.
-<DT CLASS="dt-description"><B><TT>ldap_uidattr_format</TT></B><DD CLASS="dd-description">Format of the
- <TT>ldap_uidattr</TT> variable. The format <EM>must</EM> contain one and only one
- pattern variable <TT>"%u"</TT> which will be replaced by the user's part of a
- JID. For example, <TT>"%u@example.org"</TT>. The default value is <TT>"%u"</TT>.
-<DT CLASS="dt-description"><B><TT>ldap_filter</TT></B><DD CLASS="dd-description">
- <A HREF="http://www.faqs.org/rfcs/rfc2254.html">RFC 2254</A> LDAP filter. The
- default is <TT>none</TT>. Example:
- <TT>"(&amp;(objectClass=shadowAccount)(memberOf=Jabber Users))"</TT>. Please, do
- not forget to close brackets and do not use superfluous whitespaces. Also you
- <EM>must not</EM> use <TT>ldap_uidattr</TT> attribute in filter because this
- attribute will be substituted in LDAP filter automatically.
-</DL>
-<!--TOC subsubsection Examples-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc44">4.5.3</A>&nbsp;&nbsp;<A NAME="ldapexamples">Examples</A></H4><!--SEC END -->
-
-<A NAME="sec:ldapexamples"></A>
-<!--TOC paragraph Common example-->
-
-<H5 CLASS="paragraph"><A NAME="ldapcommonexample">Common example</A></H5><!--SEC END -->
-
-Let's say <TT>ldap.example.org</TT> is the name of our LDAP server. We have
-users with their passwords in <TT>"ou=Users,dc=example,dc=org"</TT> directory.
-Also we have addressbook, which contains users emails and their additional
-infos in <TT>"ou=AddressBook,dc=example,dc=org"</TT> directory. Corresponding
-authentication section should looks like this:
-<PRE CLASS="verbatim">
- %% authentication method
- {auth_method, ldap}.
- %% DNS name of our LDAP server
- {ldap_servers, ["ldap.example.org"]}.
- %% Bind to LDAP server as "cn=Manager,dc=example,dc=org" with password "secret"
- {ldap_rootdn, "cn=Manager,dc=example,dc=org"}.
- {ldap_password, "secret"}.
- %% define the user's base
- {ldap_base, "ou=Users,dc=example,dc=org"}.
- %% We want to authorize users from 'shadowAccount' object class only
- {ldap_filter, "(objectClass=shadowAccount)"}.
-</PRE>
-Now we want to use users LDAP-info as their vCards. We have four attributes
-defined in our LDAP schema: <TT>"mail"</TT> &mdash; email address, <TT>"givenName"</TT>
-&mdash; first name, <TT>"sn"</TT> &mdash; second name, <TT>"birthDay"</TT> &mdash; birthday.
-Also we want users to search each other. Let's see how we can set it up:
-<PRE CLASS="verbatim">
- {modules,
- ...
- {mod_vcard_ldap,
- [
- %% We use the same server and port, but want to bind anonymously because
- %% our LDAP server accepts anonymous requests to
- %% "ou=AddressBook,dc=example,dc=org" subtree.
- {ldap_rootdn, ""},
- {ldap_password, ""},
- %% define the addressbook's base
- {ldap_base, "ou=AddressBook,dc=example,dc=org"},
- %% user's part of JID is located in the "mail" attribute
- {ldap_uidattr, "mail"},
- %% common format for our emails
- {ldap_uidattr_format, "%u@mail.example.org"},
- %% We have to define empty filter here, because entries in addressbook does not
- %% belong to shadowAccount object class
- {ldap_filter, ""},
- %% Now we want to define vCard pattern
- {ldap_vcard_map,
- [{"NICKNAME", "%u", []}, % just use user's part of JID as his nickname
- {"GIVEN", "%s", ["givenName"]},
- {"FAMILY", "%s", ["sn"]},
- {"FN", "%s, %s", ["sn", "givenName"]}, % example: "Smith, John"
- {"EMAIL", "%s", ["mail"]},
- {"BDAY", "%s", ["birthDay"]}]},
- %% Search form
- {ldap_search_fields,
- [{"User", "%u"},
- {"Name", "givenName"},
- {"Family Name", "sn"},
- {"Email", "mail"},
- {"Birthday", "birthDay"}]},
- %% vCard fields to be reported
- %% Note that JID is always returned with search results
- {ldap_search_reported,
- [{"Full Name", "FN"},
- {"Nickname", "NICKNAME"},
- {"Birthday", "BDAY"}]}
- ]}
- ...
- }.
-</PRE>
-Note that <TT>mod_vcard_ldap</TT> module checks for the existence of the user before
-searching in his information in LDAP.<BR>
-<BR>
-<!--TOC paragraph Active Directory-->
-
-<H5 CLASS="paragraph"><A NAME="ad">Active Directory</A></H5><!--SEC END -->
-
-<A NAME="sec:ad"></A>
-
-Active Directory is just an LDAP-server with predefined attributes. A sample
-configuration is showed below:
-<PRE CLASS="verbatim">
- {auth_method, ldap}.
- {ldap_servers, ["office.org"]}. % List of LDAP servers
- {ldap_base, "DC=office,DC=org"}. % Search base of LDAP directory
- {ldap_rootdn, "CN=Administrator,CN=Users,DC=office,DC=org"}. % LDAP manager
- {ldap_password, "*******"}. % Password to LDAP manager
- {ldap_uidattr, "sAMAccountName"}.
- {ldap_filter, "(memberOf=*)"}.
-
- {mod_vcard_ldap,
- [{ldap_vcard_map,
- [{"NICKNAME", "%u", []},
- {"GIVEN", "%s", ["givenName"]},
- {"MIDDLE", "%s", ["initials"]},
- {"FAMILY", "%s", ["sn"]},
- {"FN", "%s", ["displayName"]},
- {"EMAIL", "%s", ["mail"]},
- {"ORGNAME", "%s", ["company"]},
- {"ORGUNIT", "%s", ["department"]},
- {"CTRY", "%s", ["c"]},
- {"LOCALITY", "%s", ["l"]},
- {"STREET", "%s", ["streetAddress"]},
- {"REGION", "%s", ["st"]},
- {"PCODE", "%s", ["postalCode"]},
- {"TITLE", "%s", ["title"]},
- {"URL", "%s", ["wWWHomePage"]},
- {"DESC", "%s", ["description"]},
- {"TEL", "%s", ["telephoneNumber"]}]},
- {ldap_search_fields,
- [{"User", "%u"},
- {"Name", "givenName"},
- {"Family Name", "sn"},
- {"Email", "mail"},
- {"Company", "company"},
- {"Department", "department"},
- {"Role", "title"},
- {"Description", "description"},
- {"Phone", "telephoneNumber"}]},
- {ldap_search_reported,
- [{"Full Name", "FN"},
- {"Nickname", "NICKNAME"},
- {"Email", "EMAIL"}]}
- ]
- }.
-</PRE>
-<!--TOC section Modules Configuration-->
-
-<H2 CLASS="section"><A NAME="htoc45">5</A>&nbsp;&nbsp;<A NAME="modules">Modules Configuration</A></H2><!--SEC END -->
-
-<A NAME="sec:modules"></A>
-
-The option <TT>modules</TT> defines the list of modules that will be loaded after
-<TT>ejabberd</TT>'s startup. Each entry in the list is a tuple in which the first
-element is the name of a module and the second is a list of options for that
-module.<BR>
-<BR>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-In this example only the module <TT>mod_echo</TT> is loaded and no module
- options are specified between the square brackets:
- <PRE CLASS="verbatim">
- {modules,
- [{mod_echo, []}
- ]}.
-</PRE><LI CLASS="li-itemize">In the second example the modules <TT>mod_echo</TT>, <TT>mod_time</TT>, and
- <TT>mod_version</TT> are loaded without options. Remark that, besides the last entry,
- all entries end with a comma:
- <PRE CLASS="verbatim">
- {modules,
- [{mod_echo, []},
- {mod_time, []},
- {mod_version, []}
- ]}.
-</PRE></UL>
-<!--TOC subsection Overview-->
-
-<H3 CLASS="subsection"><A NAME="htoc46">5.1</A>&nbsp;&nbsp;<A NAME="modoverview">Overview</A></H3><!--SEC END -->
-
-<A NAME="sec:modoverview"></A>
-
-The following table lists all modules available in the official <TT>ejabberd</TT>
-distribution. You can find more
-<A HREF="http://ejabberd.jabber.ru/contributions">contributed modules</A> on the
-<TT>ejabberd</TT> website. Please remember that these contributions might not work or
-that they can contain severe bugs and security leaks. Therefore, use them at
-your own risk!<BR>
-<BR>
-You can see which database backend each module needs by looking at the suffix:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-`_ldap', this means that the module needs an LDAP server as backend.
-<LI CLASS="li-itemize">`_odbc', this means that the module needs a supported database
- (see&nbsp;<A HREF="#sec:database">4</A>) as backend.
-<LI CLASS="li-itemize">No suffix, this means that the modules uses Erlang's built-in database
- Mnesia as backend.
-</UL>
-If you want to
-It is possible to use a relational database to store pieces of
-information. You can do this by changing the module name to a name with an
-<TT>_odbc</TT> suffix in <TT>ejabberd</TT> config file. You can use a relational
-database for the following data:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Last connection date and time: Use <TT>mod_last_odbc</TT> instead of
- <TT>mod_last</TT>.
-<LI CLASS="li-itemize">Offline messages: Use <TT>mod_offline_odbc</TT> instead of
- <TT>mod_offline</TT>.
-<LI CLASS="li-itemize">Rosters: Use <TT>mod_roster_odbc</TT> instead of <TT>mod_roster</TT>.
-<LI CLASS="li-itemize">Users' VCARD: Use <TT>mod_vcard_odbc</TT> instead of <TT>mod_vcard</TT>.
-</UL>
-<BLOCKQUOTE CLASS="table"><DIV CLASS="center"><DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV>
- <TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
-<TR><TD ALIGN=left NOWRAP>Module</TD>
-<TD ALIGN=left NOWRAP>Feature</TD>
-<TD ALIGN=left NOWRAP>Dependencies</TD>
-<TD ALIGN=left NOWRAP>Needed for XMPP?</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_adhoc</TT></TD>
-<TD ALIGN=left NOWRAP>Ad-Hoc Commands (<A HREF="http://www.jabber.org/jeps/jep-0050.html">JEP-0050</A>)</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_announce</TT></TD>
-<TD ALIGN=left NOWRAP>Manage announcements</TD>
-<TD ALIGN=left NOWRAP><TT>mod_adhoc</TT></TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_configure</TT></TD>
-<TD ALIGN=left NOWRAP>Support for online</TD>
-<TD ALIGN=left NOWRAP><TT>mod_adhoc</TT></TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>configuration of <TT>ejabberd</TT></TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_disco</TT></TD>
-<TD ALIGN=left NOWRAP>Service Discovery (<A HREF="http://www.jabber.org/jeps/jep-0030.html">JEP-0030</A>)</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_echo</TT></TD>
-<TD ALIGN=left NOWRAP>Echoes Jabber packets</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_irc</TT></TD>
-<TD ALIGN=left NOWRAP>IRC transport</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_last</TT></TD>
-<TD ALIGN=left NOWRAP>Last Activity (<A HREF="http://www.jabber.org/jeps/jep-0012.html">JEP-0012</A>)</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_last_odbc</TT></TD>
-<TD ALIGN=left NOWRAP>Last Activity (<A HREF="http://www.jabber.org/jeps/jep-0012.html">JEP-0012</A>)</TD>
-<TD ALIGN=left NOWRAP>supported database (*)</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_muc</TT></TD>
-<TD ALIGN=left NOWRAP>Multi-User Chat (<A HREF="http://www.jabber.org/jeps/jep-0045.html">JEP-0045</A>)</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_muc_log</TT></TD>
-<TD ALIGN=left NOWRAP>Multi-User Chat room logging</TD>
-<TD ALIGN=left NOWRAP><TT>mod_muc</TT></TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_offline</TT></TD>
-<TD ALIGN=left NOWRAP>Offline message storage</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_offline_odbc</TT></TD>
-<TD ALIGN=left NOWRAP>Offline message storage</TD>
-<TD ALIGN=left NOWRAP>supported database (*)</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_privacy</TT></TD>
-<TD ALIGN=left NOWRAP>Blocking Communication</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>Yes</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_private</TT></TD>
-<TD ALIGN=left NOWRAP>Private XML Storage (<A HREF="http://www.jabber.org/jeps/jep-0049.html">JEP-0049</A>)</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_pubsub</TT></TD>
-<TD ALIGN=left NOWRAP>Publish-Subscribe (<A HREF="http://www.jabber.org/jeps/jep-0060.html">JEP-0060</A>)</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_register</TT></TD>
-<TD ALIGN=left NOWRAP>In-Band Registration (<A HREF="http://www.jabber.org/jeps/jep-0077.html">JEP-0077</A>)</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_roster</TT></TD>
-<TD ALIGN=left NOWRAP>Roster management</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>Yes (**)</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_roster_odbc</TT></TD>
-<TD ALIGN=left NOWRAP>Roster management</TD>
-<TD ALIGN=left NOWRAP>supported database (*)</TD>
-<TD ALIGN=left NOWRAP>Yes (**)</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_service_log</TT></TD>
-<TD ALIGN=left NOWRAP>Copy user messages to logger service</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_shared_roster</TT></TD>
-<TD ALIGN=left NOWRAP>Shared roster management</TD>
-<TD ALIGN=left NOWRAP><TT>mod_roster</TT> or</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP><TT>mod_roster_odbc</TT></TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_stats</TT></TD>
-<TD ALIGN=left NOWRAP>Statistics Gathering (<A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A>)</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_time</TT></TD>
-<TD ALIGN=left NOWRAP>Entity Time (<A HREF="http://www.jabber.org/jeps/jep-0090.html">JEP-0090</A>)</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_vcard</TT></TD>
-<TD ALIGN=left NOWRAP>vcard-temp (<A HREF="http://www.jabber.org/jeps/jep-0054.html">JEP-0054</A>)</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_vcard_ldap</TT></TD>
-<TD ALIGN=left NOWRAP>vcard-temp (<A HREF="http://www.jabber.org/jeps/jep-0054.html">JEP-0054</A>)</TD>
-<TD ALIGN=left NOWRAP>LDAP server</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_vcard_odbc</TT></TD>
-<TD ALIGN=left NOWRAP>vcard-temp (<A HREF="http://www.jabber.org/jeps/jep-0054.html">JEP-0054</A>)</TD>
-<TD ALIGN=left NOWRAP>supported database (*)</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>mod_version</TT></TD>
-<TD ALIGN=left NOWRAP>Software Version (<A HREF="http://www.jabber.org/jeps/jep-0092.html">JEP-0092</A>)</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-<TD ALIGN=left NOWRAP>No</TD>
-</TR></TABLE>
-<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></DIV></BLOCKQUOTE>
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-(*) For a list of supported databases, see section&nbsp;<A HREF="#sec:database">4</A>.
-<LI CLASS="li-itemize">(**) This module or a similar one with another database backend is needed for
-XMPP compliancy.
-</UL>
-<!--TOC subsection Common Options-->
-
-<H3 CLASS="subsection"><A NAME="htoc47">5.2</A>&nbsp;&nbsp;<A NAME="modcommonoptions">Common Options</A></H3><!--SEC END -->
-
-<A NAME="sec:modcommonoptions"></A>
-The following options are used by many modules. Therefore, they are described in
-this separate section.<BR>
-<BR>
-<!--TOC subsubsection <TT>iqdisc</TT>-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc48">5.2.1</A>&nbsp;&nbsp;<A NAME="modiqdiscoption"><TT>iqdisc</TT></A></H4><!--SEC END -->
-
-<A NAME="sec:modiqdiscoption"></A>
-
-Many modules define handlers for processing IQ queries of different namespaces
-to this server or to a user (e.&nbsp;g. to <TT>example.org</TT> or to
-<TT>user@example.org</TT>). This option defines processing discipline for
-these queries. Possible values are:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>no_queue</TT></B><DD CLASS="dd-description"> All queries of a namespace with this processing discipline are
- processed immediately. This also means that no other packets can be processed
- until this one has been completely processed. Hence this discipline is not
- recommended if the processing of a query can take a relatively long time.
-<DT CLASS="dt-description"><B><TT>one_queue</TT></B><DD CLASS="dd-description"> In this case a separate queue is created for the processing
- of IQ queries of a namespace with this discipline. In addition, the processing
- of this queue is done in parallel with that of other packets. This discipline
- is most recommended.
-<DT CLASS="dt-description"><B><TT>parallel</TT></B><DD CLASS="dd-description"> For every packet with this discipline a separate Erlang process
- is spawned. Consequently, all these packets are processed in parallel.
- Although spawning of Erlang process has a relatively low cost, this can break
- the server's normal work, because the Erlang emulator has a limit on the
- number of processes (32000 by default).
-</DL>
-Example:
-<PRE CLASS="verbatim">
- {modules,
- [
- ...
- {mod_time, [{iqdisc, no_queue}]},
- ...
- ]}.
-</PRE>
-<!--TOC subsubsection <TT>hosts</TT>-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc49">5.2.2</A>&nbsp;&nbsp;<A NAME="modhostsoption"><TT>hosts</TT></A></H4><!--SEC END -->
-
-<A NAME="sec:modhostsoption"></A>
-
-A module acting as a service can have one or more hostnames. These hostnames
-can be defined with the <TT>hosts</TT> option.<BR>
-<BR>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Serving the echo module on one domain:
- <UL CLASS="itemize"><LI CLASS="li-itemize">
- <PRE CLASS="verbatim">
- {modules,
- [
- ...
- {mod_echo, [{hosts, ["echo.example.org"]}]},
- ...
- ]}.
-</PRE><LI CLASS="li-itemize">Backwards compatibility with older <TT>ejabberd</TT> versions can be retained
- with:
- <PRE CLASS="verbatim">
- {modules,
- [
- ...
- {mod_echo, [{host, "echo.example.org"}]},
- ...
- ]}.
-</PRE></UL>
- <LI CLASS="li-itemize">Serving the echo module on two domains:
- <PRE CLASS="verbatim">
- {modules,
- [
- ...
- {mod_echo, [{hosts, ["echo.example.net", "echo.example.com"]}]},
- ...
- ]}.
-</PRE></UL>
-<!--TOC subsection <TT>mod_announce</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc50">5.3</A>&nbsp;&nbsp;<A NAME="modannounce"><TT>mod_announce</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modannounce"></A>
-
-This module enables configured users to broadcast announcements and to set
-the message of the day (MOTD). Configured users can do these actions with their
-Jabber client by sending messages to specific JIDs. These JIDs are listed in
-next paragraph. The first JID in each entry will apply only to the virtual host
-<TT>example.org</TT>, while the JID between brackets will apply to all virtual
-hosts:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>example.org/announce/all (example.org/announce/all-hosts/all)</TT></B><DD CLASS="dd-description"> The
- message is sent to all registered users. If the user is online and connected
- to several resources, only the resource with the highest priority will receive
- the message. If the registered user is not connected, the message will be
- stored offline in assumption that offline storage
- (see section&nbsp;<A HREF="#sec:modoffline">5.10</A>) is enabled.
-<DT CLASS="dt-description"><B><TT>example.org/announce/online (example.org/announce/all-hosts/online)</TT></B><DD CLASS="dd-description">The
- message is sent to all connected users. If the user is online and connected
- to several resources, all resources will receive the message.
-<DT CLASS="dt-description"><B><TT>example.org/announce/motd (example.org/announce/all-hosts/motd)</TT></B><DD CLASS="dd-description">The
- message is set as the message of the day (MOTD) and is sent to users when they
- login. In addition the message is sent to all connected users (similar to
- <TT>announce/online</TT>).
-<DT CLASS="dt-description"><B><TT>example.org/announce/motd/update (example.org/announce/all-hosts/motd/update)</TT></B><DD CLASS="dd-description">
- The message is set as message of the day (MOTD) and is sent to users when they
- login. The message is <EM>not sent</EM> to any currently connected user.
-<DT CLASS="dt-description"><B><TT>example.org/announce/motd/delete (example.org/announce/all-hosts/motd/delete)</TT></B><DD CLASS="dd-description">
- Any message sent to this JID removes the existing message of the day (MOTD).
-</DL>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>access</TT></B><DD CLASS="dd-description"> This option specifies who is allowed to
- send announcements and to set the message of the day (by default, nobody is
- able to send such messages).
-</DL>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Only administrators can send announcements:
- <PRE CLASS="verbatim">
- {access, announce, [{allow, admins}]}.
-
- {modules,
- [
- ...
- {mod_announce, [{access, announce}]},
- ...
- ]}.
-</PRE><LI CLASS="li-itemize">Administrators as well as the direction can send announcements:
- <PRE CLASS="verbatim">
- {acl, direction, {user, "big_boss", "example.org"}}.
- {acl, direction, {user, "assistant", "example.org"}}.
- {acl, admins, {user, "admin", "example.org"}}.
- ...
- {access, announce, [{allow, admins},
- {allow, direction}]}.
- ...
- {modules,
- [
- ...
- {mod_announce, [{access, announce}]},
- ...
- ]}.
-</PRE></UL>
-<!--TOC subsection <TT>mod_disco</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc51">5.4</A>&nbsp;&nbsp;<A NAME="moddisco"><TT>mod_disco</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:moddisco"></A>
-
-This module adds support for Service Discovery (<A HREF="http://www.jabber.org/jeps/jep-0030.html">JEP-0030</A>). With
-this module enabled, services on your server can be discovered by
-Jabber clients. Note that <TT>ejabberd</TT> has no modules with support
-for the superseded Jabber Browsing (<A HREF="http://www.jabber.org/jeps/jep-0011.html">JEP-0011</A>) and Agent Information
-(<A HREF="http://www.jabber.org/jeps/jep-0094.html">JEP-0094</A>). Accordingly, Jabber clients need to have support for
-the newer Service Discovery protocol if you want them be able to discover
-the services you offer.<BR>
-<BR>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>iqdisc</TT></B><DD CLASS="dd-description"> This specifies
-the processing discipline for Service Discovery (<TT>http://jabber.org/protocol/disco#items</TT> and
- <TT>http://jabber.org/protocol/disco#info</TT>) IQ queries
-(see section&nbsp;<A HREF="#sec:modiqdiscoption">5.2.1</A>).
-<DT CLASS="dt-description"><B><TT>extra_domains</TT></B><DD CLASS="dd-description"> With this option,
- extra domains can be added to the Service Discovery item list.
-</DL>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-To serve a link to the Jabber User Directory on <TT>jabber.org</TT>:
- <PRE CLASS="verbatim">
- {modules,
- [
- ...
- {mod_disco, [{extra_domains, ["users.jabber.org"]}]},
- ...
- ]}.
-</PRE><LI CLASS="li-itemize">To serve a link to the transports on another server:
- <PRE CLASS="verbatim">
- {modules,
- [
- ...
- {mod_disco, [{extra_domains, ["icq.example.com",
- "msn.example.com"]}]},
- ...
- ]}.
-</PRE><LI CLASS="li-itemize">To serve a link to a few friendly servers:
- <PRE CLASS="verbatim">
- {modules,
- [
- ...
- {mod_disco, [{extra_domains, ["example.org",
- "example.com"]}]},
- ...
- ]}.
-</PRE></UL>
-<!--TOC subsection <TT>mod_echo</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc52">5.5</A>&nbsp;&nbsp;<A NAME="modecho"><TT>mod_echo</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modecho"></A>
-
-This module simply echoes any Jabber
-packet back to the sender. This mirror can be of interest for
-<TT>ejabberd</TT> and Jabber client debugging.<BR>
-<BR>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-
- <B><TT>hosts</TT></B><DD CLASS="dd-description"> This option defines the hostnames of the
- service (see section&nbsp;<A HREF="#sec:modhostsoption">5.2.2</A>). If neither <TT>hosts</TT> nor
- the old <TT>host</TT> is present, the prefix `<TT>echo.</TT>' is added to all
- <TT>ejabberd</TT> hostnames.
-
-</DL>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Mirror, mirror, on the wall, who is the most beautiful
- of them all?
- <PRE CLASS="verbatim">
- {modules,
- [
- ...
- {mod_echo, [{hosts, ["mirror.example.org"]}]},
- ...
- ]}.
-</PRE><LI CLASS="li-itemize">If you still do not understand the inner workings of <TT>mod_echo</TT>,
- you can find a few more examples in section&nbsp;<A HREF="#sec:modhostsoption">5.2.2</A>.
-</UL>
-<!--TOC subsection <TT>mod_irc</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc53">5.6</A>&nbsp;&nbsp;<A NAME="modirc"><TT>mod_irc</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modirc"></A>
-
-This module is an IRC transport that can be used to join channels on IRC
-servers.<BR>
-<BR>
-End user information:
-
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-A Jabber client with `groupchat 1.0' support or Multi-User
- Chat support (<A HREF="http://www.jabber.org/jeps/jep-0045.html">JEP-0045</A>) is necessary to join IRC channels.
-<LI CLASS="li-itemize">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%<TT>irc.example.org</TT>' in case <TT>irc.example.org</TT> is
- the IRC server hosting `channel'. And of course the host should point
- to the IRC transport instead of the Multi-User Chat service.
-<LI CLASS="li-itemize">You can register your nickame by sending `IDENTIFY password' to<BR>
-<TT>nickserver!irc.example.org@irc.jabberserver.org</TT>.
-<LI CLASS="li-itemize">Entering your password is possible by sending `LOGIN nick password'<BR>
-to <TT>nickserver!irc.example.org@irc.jabberserver.org</TT>.
-<LI CLASS="li-itemize">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.
-</UL>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-
- <B><TT>hosts</TT></B><DD CLASS="dd-description"> This option defines the hostnames of the
- service (see section&nbsp;<A HREF="#sec:modhostsoption">5.2.2</A>). If neither <TT>hosts</TT> nor
- the old <TT>host</TT> is present, the prefix `<TT>irc.</TT>' is added to all
- <TT>ejabberd</TT> hostnames.
-
-<DT CLASS="dt-description"><B><TT>access</TT></B><DD CLASS="dd-description"> This option can be used to specify who
- may use the IRC transport (default value: <TT>all</TT>).
-</DL>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-In the first example, the IRC transport is available on (all) your
- virtual host(s) with the prefix `<TT>irc.</TT>'. Furthermore, anyone is
- able to use the transport.
- <PRE CLASS="verbatim">
- {modules,
- [
- ...
- {mod_irc, [{access, all}]},
- ...
- ]}.
-</PRE><LI CLASS="li-itemize">In next example the IRC transport is available on the two virtual hosts
- <TT>example.net</TT> and <TT>example.com</TT> with different prefixes on each host.
- Moreover, the transport is only accessible by paying customers registered on
- our domains and on other servers.
- <PRE CLASS="verbatim">
- {acl, paying_customers, {user, "customer1", "example.net"}}.
- {acl, paying_customers, {user, "customer2", "example.com"}}.
- {acl, paying_customers, {user, "customer3", "example.org"}}.
- ...
- {access, paying_customers, [{allow, paying_customers},
- {deny, all}]}.
- ...
- {modules,
- [
- ...
- {mod_irc, [{access, paying_customers},
- {hosts, ["irc.example.net", "irc-transport.example.com"]}]},
- ...
- ]}.
-</PRE></UL>
-<!--TOC subsection <TT>mod_last</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc54">5.7</A>&nbsp;&nbsp;<A NAME="modlast"><TT>mod_last</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modlast"></A>
-
-This module adds support for Last Activity (<A HREF="http://www.jabber.org/jeps/jep-0012.html">JEP-0012</A>). It can be used to
-discover when a disconnected user last accessed the server, to know when a
-connected user was last active on the server, or to query the uptime of the
-<TT>ejabberd</TT> server.<BR>
-<BR>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>iqdisc</TT></B><DD CLASS="dd-description"> This specifies
-the processing discipline for Last activity (<TT>jabber:iq:last</TT>) IQ queries
-(see section&nbsp;<A HREF="#sec:modiqdiscoption">5.2.1</A>).
-</DL>
-<!--TOC subsection <TT>mod_muc</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc55">5.8</A>&nbsp;&nbsp;<A NAME="modmuc"><TT>mod_muc</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modmuc"></A>
-
-With this module enabled, your server will support Multi-User Chat
-(<A HREF="http://www.jabber.org/jeps/jep-0045.html">JEP-0045</A>). End users will be able to join text conferences. Notice
-that this module is not (yet) clusterable.<BR>
-<BR>
-Some of the features of Multi-User Chat:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Sending private messages to room participants.
-<LI CLASS="li-itemize">Inviting users.
-<LI CLASS="li-itemize">Setting a conference topic.
-<LI CLASS="li-itemize">Creating password protected rooms.
-<LI CLASS="li-itemize">Kicking and banning participants.
-</UL>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-
- <B><TT>hosts</TT></B><DD CLASS="dd-description"> This option defines the hostnames of the
- service (see section&nbsp;<A HREF="#sec:modhostsoption">5.2.2</A>). If neither <TT>hosts</TT> nor
- the old <TT>host</TT> is present, the prefix `<TT>conference.</TT>' is added to all
- <TT>ejabberd</TT> hostnames.
-
-<DT CLASS="dt-description"><B><TT>access</TT></B><DD CLASS="dd-description"> You can specify who is allowed to use
- the Multi-User Chat service (by default, everyone is allowed to use it).
-<DT CLASS="dt-description"><B><TT>access_create</TT></B><DD CLASS="dd-description"> To configure who is
- allowed to create new rooms at the Multi-User Chat service, this option
- can be used (by default, everybody is allowed to create rooms).
-<DT CLASS="dt-description"><B><TT>access_admin</TT></B><DD CLASS="dd-description"> This option specifies
- who is allowed to administrate the Multi-User Chat service (the default
- value is <TT>none</TT>, which means that only the room creator can
- administer his room). By sending a message to the service JID,
- administrators can send service messages that will be displayed in every
- active room.
-<DT CLASS="dt-description"><B><TT>history_size</TT></B><DD CLASS="dd-description"> A small history of the
- current discussion is sent to users when they enter the room. With this option
- you can define the number of history messages to keep and send to users
- joining the room. The value is an integer. Setting the value to <TT>0</TT>
- disables the history feature and, as a result, nothing is kept in memory. The
- default value is <TT>20</TT>. This value is global and thus affects all rooms on
- the server.
-</DL>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-In the first example everyone is allowed to use the Multi-User Chat
- service. Everyone will also be able to create new rooms but only the user
- <TT>admin@example.org</TT> is allowed to administrate any room. In this
- example he is also a global administrator. When <TT>admin@example.org</TT>
- sends a message such as `Tomorrow, the Jabber server will be moved
- to new hardware. This will involve service breakdowns around 23:00 UMT.
- We apologise for this inconvenience.' to <TT>conference.example.org</TT>,
- it will be displayed in all active rooms. In this example the history
- feature is disabled.
- <PRE CLASS="verbatim">
- {acl, admins, {user, "admin", "example.org"}}.
- ...
- {access, muc_admins, [{allow, admins}]}.
- ...
- {modules,
- [
- ...
- {mod_muc, [{access, all},
- {access_create, all},
- {access_admin, muc_admins},
- {history_size, 0}]},
- ...
- ]}.
-</PRE><LI CLASS="li-itemize">In the second example the Multi-User Chat service is only accessible by
- paying customers registered on our domains and on other servers. Of course
- the administrator is also allowed to access rooms. In addition, he is the
- only authority able to create and administer rooms. When
- <TT>admin@example.org</TT> sends a message such as `Tomorrow, the Jabber
- server will be moved to new hardware. This will involve service breakdowns
- around 23:00 UMT. We apologise for this inconvenience.' to
- <TT>conference.example.org</TT>, it will be displayed in all active rooms. No
- <TT>history_size</TT> option is used, this means that the feature is enabled
- and the default value of 20 history messages will be send to the users.
- <PRE CLASS="verbatim">
- {acl, paying_customers, {user, "customer1", "example.net"}}.
- {acl, paying_customers, {user, "customer2", "example.com"}}.
- {acl, paying_customers, {user, "customer3", "example.org"}}.
- {acl, admins, {user, "admin", "example.org"}}.
- ...
- {access, muc_admins, [{allow, admins},
- {deny, all}]}.
- {access, muc_access, [{allow, paying_customers},
- {allow, admins},
- {deny, all}]}.
- ...
- {modules,
- [
- ...
- {mod_muc, [{access, muc_access},
- {access_create, muc_admins},
- {access_admin, muc_admins}]},
- ...
- ]}.
-</PRE></UL>
-<!--TOC subsection <TT>mod_muc_log</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc56">5.9</A>&nbsp;&nbsp;<A NAME="modmuclog"><TT>mod_muc_log</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modmuclog"></A>
-
-This module enables optional logging of Multi-User Chat (MUC) conversations to
-HTML. Once you enable this module, users can join a chatroom using a MUC capable
-Jabber client, and if they have enough privileges, they can request the
-configuration form in which they can set the option to enable chatroom logging.<BR>
-<BR>
-Features:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Chatroom details are added on top of each page: room title, JID,
- author, subject and configuration.
-<LI CLASS="li-itemize">
- Room title and JID are links to join the chatroom (using
- <A HREF="http://www.ietf.org/rfc/rfc4622.txt">XMPP URIs</A>).
-<LI CLASS="li-itemize">Subject and chatroom configuration changes are tracked and displayed.
-<LI CLASS="li-itemize">Joins, leaves, nick changes, kicks, bans and `/me' are tracked and
- displayed, including the reason if available.
-<LI CLASS="li-itemize">Generated HTML files are XHTML 1.0 Transitional and CSS compliant.
-<LI CLASS="li-itemize">Timestamps are self-referencing links.
-<LI CLASS="li-itemize">Links on top for quicker navigation: Previous day, Next day, Up.
-<LI CLASS="li-itemize">CSS is used for style definition, and a custom CSS file can be used.
-<LI CLASS="li-itemize">URLs on messages and subjects are converted to hyperlinks.
-<LI CLASS="li-itemize">Timezone used on timestamps is shown on the log files.
-<LI CLASS="li-itemize">A custom link can be added on top of each page.
-</UL>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>access_log</TT></B><DD CLASS="dd-description">
- This option restricts which users are allowed to enable or disable chatroom
- logging. The default value is <TT>muc_admin</TT>. Note for this default setting
- you need to have an access rule for <TT>muc_admin</TT> in order to take effect.
-<DT CLASS="dt-description"><B><TT>cssfile</TT></B><DD CLASS="dd-description">
- With this option you can set whether the HTML files should have a custom CSS
- file or if they need to use the embedded CSS file. Allowed values are
- <TT>false</TT> and an URL to a CSS file. With the first value, HTML files will
- include the embedded CSS code. With the latter, you can specify the URL of the
- custom CSS file (for example: `http://example.com/my.css'). The default value
- is <TT>false</TT>.
-<DT CLASS="dt-description"><B><TT>dirtype</TT></B><DD CLASS="dd-description">
- The type of the created directories can be specified with this option. Allowed
- values are <TT>subdirs</TT> and <TT>plain</TT>. With the first value,
- subdirectories are created for each year and month. With the latter, the
- names of the log files contain the full date, and there are no subdirectories.
- The default value is <TT>subdirs</TT>.
-<DT CLASS="dt-description"><B><TT>outdir</TT></B><DD CLASS="dd-description">
- This option sets the full path to the directory in which the HTML files should
- be stored. Make sure the <TT>ejabberd</TT> daemon user has write access on that
- directory. The default value is <TT>"www/muc"</TT>.
-<DT CLASS="dt-description"><B><TT>timezone</TT></B><DD CLASS="dd-description">
- The time zone for the logs is configurable with this option. Allowed values
- are <TT>local</TT> and <TT>universal</TT>. With the first value, the local time,
- as reported to Erlang by the operating system, will be used. With the latter,
- GMT/UTC time will be used. The default value is <TT>local</TT>.
-<DT CLASS="dt-description"><B><TT>top_link</TT></B><DD CLASS="dd-description">
- With this option you can customize the link on the top right corner of each
- log file. The syntax of this option is <TT>{"URL", "Text"}</TT>. The default
- value is <TT>{"/", "Home"}</TT>.
-</DL>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-In the first example any chatroom owner can enable logging, and a
- custom CSS file will be used (http://example.com/my.css). Further, the names
- of the log files will contain the full date, and there will be no
- subdirectories. The log files will be stored in /var/www/muclogs, and the
- time zone will be GMT/UTC. Finally, the top link will be
- <CODE>&lt;a href="http://www.jabber.ru"&gt;Jabber.ru&lt;/a&gt;</CODE>.
- <PRE CLASS="verbatim">
- {access, muc, [{allow, all}]}.
- ...
- {modules,
- [
- ...
- {mod_muc_log, [
- {access_log, muc},
- {cssfile, "http://example.com/my.css"},
- {dirtype, plain},
- {outdir, "/var/www/muclogs"},
- {timezone, universal},
- {top_link, {"http://www.jabber.ru", "Jabber.ru"}}
- ]},
- ...
- ]}.
-</PRE><LI CLASS="li-itemize">In the second example only <TT>admin1@example.org</TT> and
- <TT>admin2@example.net</TT> can enable logging, and the embedded CSS file will be
- used. Further, the names of the log files will only contain the day (number),
- and there will be subdirectories for each year and month. The log files will
- be stored in /var/www/muclogs, and the local time will be used. Finally, the
- top link will be the default <CODE>&lt;a href="/"&gt;Home&lt;/a&gt;</CODE>.
- <PRE CLASS="verbatim">
- {acl, admins, {user, "admin1", "example.org"}}.
- {acl, admins, {user, "admin2", "example.net"}}.
- ...
- {access, muc_log, [{allow, admins},
- {deny, all}]}.
- ...
- {modules,
- [
- ...
- {mod_muc_log, [
- {access_log, muc_log},
- {cssfile, false},
- {dirtype, subdirs},
- {outdir, "/var/www/muclogs"},
- {timezone, local}
- ]},
- ...
- ]}.
-</PRE></UL>
-<!--TOC subsection <TT>mod_offline</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc57">5.10</A>&nbsp;&nbsp;<A NAME="modoffline"><TT>mod_offline</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modoffline"></A>
-
-This module implements offline message storage. This means that all messages
-sent to an offline user will be stored on the server until that user comes
-online again. Thus it is very similar to how email works. Note that
-<TT>ejabberdctl</TT> has a command to delete expired messages
-(see section&nbsp;<A HREF="#sec:ejabberdctl">7.2</A>).<BR>
-<BR>
-<!--TOC subsection <TT>mod_privacy</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc58">5.11</A>&nbsp;&nbsp;<A NAME="modprivacy"><TT>mod_privacy</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modprivacy"></A>
-
-This module implements Blocking Communication (also known as Privacy Rules)
-as defined in section 10 from XMPP IM. If end users have support for it in
-their Jabber client, they will be able to:
-<BLOCKQUOTE CLASS="quote">
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Retrieving one's privacy lists.
-<LI CLASS="li-itemize">Adding, removing, and editing one's privacy lists.
-<LI CLASS="li-itemize">Setting, changing, or declining active lists.
-<LI CLASS="li-itemize">Setting, changing, or declining the default list (i.e., the list that
- is active by default).
-<LI CLASS="li-itemize">Allowing or blocking messages based on JID, group, or subscription type
- (or globally).
-<LI CLASS="li-itemize">Allowing or blocking inbound presence notifications based on JID, group,
- or subscription type (or globally).
-<LI CLASS="li-itemize">Allowing or blocking outbound presence notifications based on JID, group,
- or subscription type (or globally).
-<LI CLASS="li-itemize">Allowing or blocking IQ stanzas based on JID, group, or subscription type
- (or globally).
-<LI CLASS="li-itemize">Allowing or blocking all communications based on JID, group, or
- subscription type (or globally).
-</UL>
-(from <A HREF="http://www.xmpp.org/specs/rfc3921.html#privacy"><TT>http://www.xmpp.org/specs/rfc3921.html#privacy</TT></A>)
-</BLOCKQUOTE>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>iqdisc</TT></B><DD CLASS="dd-description"> This specifies
-the processing discipline for Blocking Communication (<TT>jabber:iq:privacy</TT>) IQ queries
-(see section&nbsp;<A HREF="#sec:modiqdiscoption">5.2.1</A>).
-</DL>
-<!--TOC subsection <TT>mod_private</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc59">5.12</A>&nbsp;&nbsp;<A NAME="modprivate"><TT>mod_private</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modprivate"></A>
-
-This module adds support for Private XML Storage (<A HREF="http://www.jabber.org/jeps/jep-0049.html">JEP-0049</A>):
-<BLOCKQUOTE CLASS="quote">
-Using this method, Jabber entities can store private data on the server and
-retrieve it whenever necessary. The data stored might be anything, as long as
-it is valid XML. One typical usage for this namespace is the server-side storage
-of client-specific preferences; another is Bookmark Storage (<A HREF="http://www.jabber.org/jeps/jep-0048.html">JEP-0048</A>).
-</BLOCKQUOTE>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>iqdisc</TT></B><DD CLASS="dd-description"> This specifies
-the processing discipline for Private XML Storage (<TT>jabber:iq:private</TT>) IQ queries
-(see section&nbsp;<A HREF="#sec:modiqdiscoption">5.2.1</A>).
-</DL>
-<!--TOC subsection <TT>mod_pubsub</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc60">5.13</A>&nbsp;&nbsp;<A NAME="modpubsub"><TT>mod_pubsub</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modpubsub"></A>
-
-This module offers a Publish-Subscribe Service (<A HREF="http://www.jabber.org/jeps/jep-0060.html">JEP-0060</A>).
-Publish-Subscribe can be used to develop (examples are taken from the JEP):
-<BLOCKQUOTE CLASS="quote">
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-news feeds and content syndacation,
-<LI CLASS="li-itemize">avatar management,
-<LI CLASS="li-itemize">shared bookmarks,
-<LI CLASS="li-itemize">auction and trading systems,
-<LI CLASS="li-itemize">online catalogs,
-<LI CLASS="li-itemize">workflow systems,
-<LI CLASS="li-itemize">network management systems,
-<LI CLASS="li-itemize">NNTP gateways,
-<LI CLASS="li-itemize">vCard/profile management,
-<LI CLASS="li-itemize">and weblogs.
-</UL>
-</BLOCKQUOTE>
-
-Another example is <A HREF="http://www.process-one.net/en/projects/j-eai/">J-EAI</A>.
-This is an XMPP-based Enterprise Application Integration (EAI) platform (also
-known as ESB, the Enterprise Service Bus). The J-EAI project builts upon
-<TT>ejabberd</TT>'s codebase and has contributed several features to <TT>mod_pubsub</TT>.<BR>
-<BR>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-
- <B><TT>hosts</TT></B><DD CLASS="dd-description"> This option defines the hostnames of the
- service (see section&nbsp;<A HREF="#sec:modhostsoption">5.2.2</A>). If neither <TT>hosts</TT> nor
- the old <TT>host</TT> is present, the prefix `<TT>pubsub.</TT>' is added to all
- <TT>ejabberd</TT> hostnames.
-
-<DT CLASS="dt-description"><B><TT>served_hosts</TT></B><DD CLASS="dd-description"> To specify which hosts needs to
- be served, you can use this option. If absent, only the main <TT>ejabberd</TT>
- host is served. <DT CLASS="dt-description"><B><TT>access_createnode</TT></B><DD CLASS="dd-description">
- This option restricts which users are allowed to create pubsub nodes using
- ACL and ACCESS. The default value is <TT>pubsub_createnode</TT>. </DL>
-Example:
-<PRE CLASS="verbatim">
- {modules,
- [
- ...
- {mod_pubsub, [{served_hosts, ["example.com",
- "example.org"]},
- {access_createnode, pubsub_createnode}]}
- ...
- ]}.
-</PRE>
-<!--TOC subsection <TT>mod_register</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc61">5.14</A>&nbsp;&nbsp;<A NAME="modregister"><TT>mod_register</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modregister"></A>
-
-This module adds support for In-Band Registration (<A HREF="http://www.jabber.org/jeps/jep-0077.html">JEP-0077</A>). This protocol
-enables end users to use a Jabber client to:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Register a new account on the server.
-<LI CLASS="li-itemize">Change the password from an existing account on the server.
-<LI CLASS="li-itemize">Delete an existing account on the server.
-</UL>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>access</TT></B><DD CLASS="dd-description"> This option can be configured to specify
- rules to restrict registration. If a rule returns `deny' on the requested
- user name, registration for that user name is dennied. (there are no
- restrictions by default).
-<DT CLASS="dt-description"><B><TT>iqdisc</TT></B><DD CLASS="dd-description"> This specifies
-the processing discipline for In-Band Registration (<TT>jabber:iq:register</TT>) IQ queries
-(see section&nbsp;<A HREF="#sec:modiqdiscoption">5.2.1</A>).
-</DL>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Next example prohibits the registration of too short account names:
-<PRE CLASS="verbatim">
- {acl, shortname, {user_glob, "?"}}.
- {acl, shortname, {user_glob, "??"}}.
- % The same using regexp:
- %{acl, shortname, {user_regexp, "^..?$"}}.
- ...
- {access, register, [{deny, shortname},
- {allow, all}]}.
- ...
- {modules,
- [
- ...
- {mod_register, [{access, register}]},
- ...
- ]}.
-</PRE><LI CLASS="li-itemize">The in-band registration of new accounts can be prohibited by changing the
- <TT>access</TT> option. If you really want to disable all In-Band Registration
- functionality, that is changing passwords in-band and deleting accounts
- in-band, you have to remove <TT>mod_register</TT> from the modules list. In this
- example all In-Band Registration functionality is disabled:
- <PRE CLASS="verbatim">
- {access, register, [{deny, all}]}.
-
- {modules,
- [
- ...
-% {mod_register, [{access, register}]},
- ...
- ]}.
-</PRE></UL>
-<!--TOC subsection <TT>mod_roster</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc62">5.15</A>&nbsp;&nbsp;<A NAME="modroster"><TT>mod_roster</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modroster"></A>
-
-This module implements roster management as defined in <A HREF="http://www.xmpp.org/specs/rfc3921.html#roster">RFC 3921: XMPP IM</A>.<BR>
-<BR>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>iqdisc</TT></B><DD CLASS="dd-description"> This specifies
-the processing discipline for Roster Management (<TT>jabber:iq:roster</TT>) IQ queries
-(see section&nbsp;<A HREF="#sec:modiqdiscoption">5.2.1</A>).
-</DL>
-<!--TOC subsection <TT>mod_service_log</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc63">5.16</A>&nbsp;&nbsp;<A NAME="modservicelog"><TT>mod_service_log</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modservicelog"></A>
-
-This module adds support for logging end user packets via a Jabber message
-auditing service such as
-<A HREF="http://www.funkypenguin.co.za/bandersnatch/">Bandersnatch</A>. All user
-packets are encapsulated in a <CODE>&lt;route/&gt;</CODE> element and sent to the specified
-service(s).<BR>
-<BR>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>loggers</TT></B><DD CLASS="dd-description"> With this option a (list of) service(s)
- that will receive the packets can be specified.
-</DL>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-To log all end user packets to the Bandersnatch service running on
- <TT>bandersnatch.example.com</TT>:
- <PRE CLASS="verbatim">
- {modules,
- [
- ...
- {mod_service_log, [{loggers, ["bandersnatch.example.com"]}]},
- ...
- ]}.
-</PRE><LI CLASS="li-itemize">To log all end user packets to the Bandersnatch service running on
- <TT>bandersnatch.example.com</TT> and the backup service on
- <TT>bandersnatch.example.org</TT>:
- <PRE CLASS="verbatim">
- {modules,
- [
- ...
- {mod_service_log, [{loggers, ["bandersnatch.example.com",
- "bandersnatch.example.org"]}]},
- ...
- ]}.
-</PRE></UL>
-<!--TOC subsection <TT>mod_shared_roster</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc64">5.17</A>&nbsp;&nbsp;<A NAME="modsharedroster"><TT>mod_shared_roster</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modsharedroster"></A>
-
-This module enables you to create shared roster groups. This means that you can
-create groups of people that can see members from (other) groups in their
-rosters. The big advantages of this feature are that end users do not need to
-manually add all users to their rosters, and that they cannot permanently delete
-users from the shared roster groups.<BR>
-<BR>
-Shared roster groups can be edited <EM>only</EM> via the web interface. Each group
-has a unique identification and the following parameters:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B>Name</B><DD CLASS="dd-description"> The name of the group, which will be displayed in the roster.
-<DT CLASS="dt-description"><B>Description</B><DD CLASS="dd-description"> The description of the group. This parameter does not affect
- anything.
-<DT CLASS="dt-description"><B>Members</B><DD CLASS="dd-description"> A list of full JIDs of group members, entered one per line in
- the web interface.
-<DT CLASS="dt-description"><B>Displayed groups</B><DD CLASS="dd-description"> A list of groups that will be in the rosters of this
- group's members.
-</DL>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Take the case of a computer club that wants all its members seeing each
- other in their rosters. To achieve this, they need to create a shared roster
- group similar to next table:
-<BLOCKQUOTE CLASS="table"><DIV CLASS="center"><DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV>
- <TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
-<TR><TD ALIGN=left NOWRAP>Identification</TD>
-<TD ALIGN=left NOWRAP>Group `<TT>club_members</TT>'</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>Name</TD>
-<TD ALIGN=left NOWRAP>Club Members</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>Description</TD>
-<TD ALIGN=left NOWRAP>Members from the computer club</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>Members</TD>
-<TD ALIGN=left NOWRAP><TABLE CELLSPACING=2 CELLPADDING=0>
-<TR><TD ALIGN=left NOWRAP><TT>member1@example.org</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>member2@example.org</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>member3@example.org</TT></TD>
-</TR></TABLE></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>Displayed groups</TD>
-<TD ALIGN=left NOWRAP><TT>club_members</TT></TD>
-</TR></TABLE>
-<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></DIV></BLOCKQUOTE>
-<LI CLASS="li-itemize">In another case we have a company which has three divisions: Management,
- Marketing and Sales. All group members should see all other members in their
- rosters. Additonally, all managers should have all marketing and sales people
- in their roster. Simultaneously, all marketeers and the whole sales team
- should see all managers. This scenario can be achieved by creating shared
- roster groups as shown in the following table:
-<BLOCKQUOTE CLASS="table"><DIV CLASS="center"><DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV>
- <TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
-<TR><TD ALIGN=left NOWRAP>Identification</TD>
-<TD ALIGN=left NOWRAP>Group `<TT>management</TT>'</TD>
-<TD ALIGN=left NOWRAP>Group `<TT>marketing</TT>'</TD>
-<TD ALIGN=left NOWRAP>Group `<TT>sales</TT>'</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>Name</TD>
-<TD ALIGN=left NOWRAP>Management</TD>
-<TD ALIGN=left NOWRAP>Marketing</TD>
-<TD ALIGN=left NOWRAP>Sales</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>Description</TD>
-<TD ALIGN=left NOWRAP>&nbsp;</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>Members</TD>
-<TD ALIGN=left NOWRAP><TABLE CELLSPACING=2 CELLPADDING=0>
-<TR><TD ALIGN=left NOWRAP><TT>manager1@example.org</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>manager2@example.org</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>manager3@example.org</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>manager4@example.org</TT></TD>
-</TR></TABLE>
- </TD>
-<TD ALIGN=left NOWRAP><TABLE CELLSPACING=2 CELLPADDING=0>
-<TR><TD ALIGN=left NOWRAP><TT>marketeer1@example.org</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>marketeer2@example.org</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>marketeer3@example.org</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>marketeer4@example.org</TT></TD>
-</TR></TABLE>
- </TD>
-<TD ALIGN=left NOWRAP><TABLE CELLSPACING=2 CELLPADDING=0>
-<TR><TD ALIGN=left NOWRAP><TT>saleswoman1@example.org</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>salesman1@example.org</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>saleswoman2@example.org</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>salesman2@example.org</TT></TD>
-</TR></TABLE></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>Displayed groups</TD>
-<TD ALIGN=left NOWRAP><TABLE CELLSPACING=2 CELLPADDING=0>
-<TR><TD ALIGN=left NOWRAP><TT>management</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>marketing</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>sales</TT></TD>
-</TR></TABLE>
- </TD>
-<TD ALIGN=left NOWRAP><TABLE CELLSPACING=2 CELLPADDING=0>
-<TR><TD ALIGN=left NOWRAP><TT>management</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>marketing</TT></TD>
-</TR></TABLE>
- </TD>
-<TD ALIGN=left NOWRAP><TABLE CELLSPACING=2 CELLPADDING=0>
-<TR><TD ALIGN=left NOWRAP><TT>management</TT></TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP><TT>sales</TT></TD>
-</TR></TABLE></TD>
-</TR></TABLE>
-<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></DIV></BLOCKQUOTE>
-</UL>
-<!--TOC subsection <TT>mod_stats</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc65">5.18</A>&nbsp;&nbsp;<A NAME="modstats"><TT>mod_stats</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modstats"></A>
-
-This module adds support for Statistics Gathering (<A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A>). This protocol
-allows you to retrieve next statistics from your <TT>ejabberd</TT> deployment:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Total number of registered users on the current virtual host (users/total).
-<LI CLASS="li-itemize">Total number of registered users on all virtual hosts (users/all-hosts/total).
-<LI CLASS="li-itemize">Total number of online users on the current virtual host (users/online).
-<LI CLASS="li-itemize">Total number of online users on all virtual hosts (users/all-hosts/online).
-</UL>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>iqdisc</TT></B><DD CLASS="dd-description"> This specifies
-the processing discipline for Statistics Gathering (<TT>http://jabber.org/protocol/stats</TT>) IQ queries
-(see section&nbsp;<A HREF="#sec:modiqdiscoption">5.2.1</A>).
-</DL>
-As there are only a small amount of clients (for example
-<A HREF="http://tkabber.jabber.ru/">Tkabber</A>) and software libraries with
-support for this JEP, a few examples are given of the XML you need to send
-in order to get the statistics. Here they are:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-You can request the number of online users on the current virtual host
- (<TT>example.org</TT>) by sending:
- <PRE CLASS="verbatim">
-&lt;iq to='example.org' type='get'&gt;
- &lt;query xmlns='http://jabber.org/protocol/stats'&gt;
- &lt;stat name='users/online'/&gt;
- &lt;/query&gt;
-&lt;/iq&gt;
-</PRE><LI CLASS="li-itemize">You can request the total number of registered users on all virtual hosts
- by sending:
- <PRE CLASS="verbatim">
-&lt;iq to='example.org' type='get'&gt;
- &lt;query xmlns='http://jabber.org/protocol/stats'&gt;
- &lt;stat name='users/all-hosts/total'/&gt;
- &lt;/query&gt;
-&lt;/iq&gt;
-</PRE></UL>
-<!--TOC subsection <TT>mod_time</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc66">5.19</A>&nbsp;&nbsp;<A NAME="modtime"><TT>mod_time</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modtime"></A>
-
-This module features support for Entity Time (<A HREF="http://www.jabber.org/jeps/jep-0090.html">JEP-0090</A>). By using this JEP,
-you are able to discover the time at another entity's location.<BR>
-<BR>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>iqdisc</TT></B><DD CLASS="dd-description"> This specifies
-the processing discipline for Entity Time (<TT>jabber:iq:time</TT>) IQ queries
-(see section&nbsp;<A HREF="#sec:modiqdiscoption">5.2.1</A>).
-</DL>
-<!--TOC subsection <TT>mod_vcard</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc67">5.20</A>&nbsp;&nbsp;<A NAME="modvcard"><TT>mod_vcard</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modvcard"></A>
-
-This module allows end users to store and retrieve their vCard, and to retrieve
-other users vCards, as defined in vcard-temp (<A HREF="http://www.jabber.org/jeps/jep-0054.html">JEP-0054</A>). The module also
-implements an uncomplicated Jabber User Directory based on the vCards of
-these users. Moreover, it enables the server to send its vCard when queried.<BR>
-<BR>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-
- <B><TT>hosts</TT></B><DD CLASS="dd-description"> This option defines the hostnames of the
- service (see section&nbsp;<A HREF="#sec:modhostsoption">5.2.2</A>). If neither <TT>hosts</TT> nor
- the old <TT>host</TT> is present, the prefix `<TT>vjud.</TT>' is added to all
- <TT>ejabberd</TT> hostnames.
-
-<DT CLASS="dt-description"><B><TT>iqdisc</TT></B><DD CLASS="dd-description"> This specifies
-the processing discipline for <TT>vcard-temp</TT> IQ queries
-(see section&nbsp;<A HREF="#sec:modiqdiscoption">5.2.1</A>).
-<DT CLASS="dt-description"><B><TT>search</TT></B><DD CLASS="dd-description">This option specifies whether the search
- functionality is enabled (value: <TT>true</TT>) or disabled (value:
- <TT>false</TT>). If disabled, the option <TT>hosts</TT> will be ignored and the
- Jabber User Directory service will not appear in the Service Discovery item
- list. The default value is <TT>true</TT>.
-<DT CLASS="dt-description"><B><TT>matches</TT></B><DD CLASS="dd-description">With this option, the number of reported
- search results can be limited. If the option's value is set to <TT>infinity</TT>,
- all search results are reported. The default value is <TT>30</TT>.
-<DT CLASS="dt-description"><B><TT>allow_return_all</TT></B><DD CLASS="dd-description">This option enables
- you to specify if search operations with empty input fields should return all
- users who added some information to their vCard. The default value is
- <TT>false</TT>.
-<DT CLASS="dt-description"><B><TT>search_all_hosts</TT></B><DD CLASS="dd-description">If this option is set
- to <TT>true</TT>, search operations will apply to all virtual hosts. Otherwise
- only the current host will be searched. The default value is <TT>true</TT>.
-</DL>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-In this first situation, search results are limited to twenty items,
- every user who added information to their vCard will be listed when people
- do an empty search, and only users from the current host will be returned:
- <PRE CLASS="verbatim">
- {modules,
- [
- ...
- {mod_vcard, [{search, true},
- {matches, 20},
- {allow_return_all, true},
- {search_all_hosts, false}]},
- ...
- ]}.
-</PRE><LI CLASS="li-itemize">The second situation differs in a way that search results are not limited,
- and that all virtual hosts will be searched instead of only the current one:
- <PRE CLASS="verbatim">
- {modules,
- [
- ...
- {mod_vcard, [{search, true},
- {matches, infinity},
- {allow_return_all, true}]},
- ...
- ]}.
-</PRE></UL>
-<!--TOC subsection <TT>mod_vcard_ldap</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc68">5.21</A>&nbsp;&nbsp;<A NAME="modvcardldap"><TT>mod_vcard_ldap</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modvcardldap"></A>
-
-<TT>ejabberd</TT> can map LDAP attributes to vCard fields. This behaviour is
-implemented in the <TT>mod_vcard_ldap</TT> module. This module does not depend on the
-authentication method (see&nbsp;<A HREF="#sec:ldapauth">4.5.2</A>). The <TT>mod_vcard_ldap</TT> module
-has its own optional parameters. The first group of parameters has the same
-meaning as the top-level LDAP parameters to set the authentication method:
-<TT>ldap_servers</TT>, <TT>ldap_port</TT>, <TT>ldap_rootdn</TT>,
-<TT>ldap_password</TT>, <TT>ldap_base</TT>, <TT>ldap_uidattr</TT>,
-<TT>ldap_uidattr_format</TT> and <TT>ldap_filter</TT>. See
-section&nbsp;<A HREF="#sec:ldapauth">4.5.2</A> for detailed information about these options. If one
-of these options is not set, <TT>ejabberd</TT> will look for the top-level option with
-the same name. The second group of parameters consists of the following
-<TT>mod_vcard_ldap</TT>-specific options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-
- <B><TT>hosts</TT></B><DD CLASS="dd-description"> This option defines the hostnames of the
- service (see section&nbsp;<A HREF="#sec:modhostsoption">5.2.2</A>). If neither <TT>hosts</TT> nor
- the old <TT>host</TT> is present, the prefix `<TT>vjud.</TT>' is added to all
- <TT>ejabberd</TT> hostnames.
-
-<DT CLASS="dt-description"><B><TT>iqdisc</TT></B><DD CLASS="dd-description"> This specifies
-the processing discipline for <TT>vcard-temp</TT> IQ queries
-(see section&nbsp;<A HREF="#sec:modiqdiscoption">5.2.1</A>).
-<DT CLASS="dt-description"><B><TT>search</TT></B><DD CLASS="dd-description">This option specifies whether the search
- functionality is enabled (value: <TT>true</TT>) or disabled (value:
- <TT>false</TT>). If disabled, the option <TT>hosts</TT> will be ignored and the
- Jabber User Directory service will not appear in the Service Discovery item
- list. The default value is <TT>true</TT>.
-<DT CLASS="dt-description"><B><TT>ldap_vcard_map</TT></B><DD CLASS="dd-description">With this option you can
- set the table that maps LDAP attributes to vCard fields. The format is:
- <TT>[Name_of_vCard_field, Pattern, List_of_LDAP_attributes, ...]</TT>.
- <TT>Name_of_vcard_field</TT> is the type name of the vCard as defined in
- <A HREF="http://www.ietf.org/rfc/rfc2426.txt">RFC 2426</A>. <TT>Pattern</TT> is a
- string which contains pattern variables <TT>"%u"</TT>, <TT>"%d"</TT> or
- <TT>"%s"</TT>. <TT>List_of_LDAP_attributes</TT> is the list containing LDAP
- attributes. The pattern variables <TT>"%s"</TT> will be sequentially replaced
- with the values of LDAP attributes from <TT>List_of_LDAP_attributes</TT>,
- <TT>"%u"</TT> will be replaced with the user part of a JID, and <TT>"%d"</TT>
- will be replaced with the domain part of a JID. The default is:
- <PRE CLASS="verbatim">
- [{"NICKNAME", "%u", []},
- {"FN", "%s", ["displayName"]},
- {"FAMILY", "%s", ["sn"]},
- {"GIVEN", "%s", ["givenName"]},
- {"MIDDLE", "%s", ["initials"]},
- {"ORGNAME", "%s", ["o"]},
- {"ORGUNIT", "%s", ["ou"]},
- {"CTRY", "%s", ["c"]},
- {"LOCALITY", "%s", ["l"]},
- {"STREET", "%s", ["street"]},
- {"REGION", "%s", ["st"]},
- {"PCODE", "%s", ["postalCode"]},
- {"TITLE", "%s", ["title"]},
- {"URL", "%s", ["labeleduri"]},
- {"DESC", "%s", ["description"]},
- {"TEL", "%s", ["telephoneNumber"]},
- {"EMAIL", "%s", ["mail"]},
- {"BDAY", "%s", ["birthDay"]},
- {"ROLE", "%s", ["employeeType"]},
- {"PHOTO", "%s", ["jpegPhoto"]}]
-</PRE><DT CLASS="dt-description"><B><TT>ldap_search_fields</TT></B><DD CLASS="dd-description">This option
- defines the search form and the LDAP attributes to search within. The format
- is: <TT>[Name, Attribute, ...]</TT>. <TT>Name</TT> is the name of a search form
- field which will be automatically translated by using the translation
- files (see <TT>msgs/*.msg</TT> for available words). <TT>Attribute</TT> is the
- LDAP attribute or the pattern <TT>"%u"</TT>. The default is:
- <PRE CLASS="verbatim">
- [{"User", "%u"},
- {"Full Name", "displayName"},
- {"Given Name", "givenName"},
- {"Middle Name", "initials"},
- {"Family Name", "sn"},
- {"Nickname", "%u"},
- {"Birthday", "birthDay"},
- {"Country", "c"},
- {"City", "l"},
- {"Email", "mail"},
- {"Organization Name", "o"},
- {"Organization Unit", "ou"}]
-</PRE><DT CLASS="dt-description"><B><TT>ldap_search_reported</TT></B><DD CLASS="dd-description">This option
- defines which search fields should be reported. The format is:
- <TT>[Name, vCard_Name, ...]</TT>. <TT>Name</TT> is the name of a search form
- field which will be automatically translated by using the translation
- files (see <TT>msgs/*.msg</TT> for available words). <TT>vCard_Name</TT> is the
- vCard field name defined in the <TT>ldap_vcard_map</TT> option. The default
- is:
-<PRE CLASS="verbatim">
- [{"Full Name", "FN"},
- {"Given Name", "GIVEN"},
- {"Middle Name", "MIDDLE"},
- {"Family Name", "FAMILY"},
- {"Nickname", "NICKNAME"},
- {"Birthday", "BDAY"},
- {"Country", "CTRY"},
- {"City", "LOCALITY"},
- {"Email", "EMAIL"},
- {"Organization Name", "ORGNAME"},
- {"Organization Unit", "ORGUNIT"}]
-</PRE></DL>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-<BR>
-<BR>
-Let's say <TT>ldap.example.org</TT> is the name of our LDAP server. We have
-users with their passwords in <TT>"ou=Users,dc=example,dc=org"</TT> directory.
-Also we have addressbook, which contains users emails and their additional
-infos in <TT>"ou=AddressBook,dc=example,dc=org"</TT> directory. Corresponding
-authentication section should looks like this:
-<PRE CLASS="verbatim">
- %% authentication method
- {auth_method, ldap}.
- %% DNS name of our LDAP server
- {ldap_servers, ["ldap.example.org"]}.
- %% We want to authorize users from 'shadowAccount' object class only
- {ldap_filter, "(objectClass=shadowAccount)"}.
-</PRE>
-Now we want to use users LDAP-info as their vCards. We have four attributes
-defined in our LDAP schema: <TT>"mail"</TT> &mdash; email address, <TT>"givenName"</TT>
-&mdash; first name, <TT>"sn"</TT> &mdash; second name, <TT>"birthDay"</TT> &mdash; birthday.
-Also we want users to search each other. Let's see how we can set it up:
-<PRE CLASS="verbatim">
- {modules,
- ...
- {mod_vcard_ldap,
- [
- %% We use the same server and port, but want to bind anonymously because
- %% our LDAP server accepts anonymous requests to
- %% "ou=AddressBook,dc=example,dc=org" subtree.
- {ldap_rootdn, ""},
- {ldap_password, ""},
- %% define the addressbook's base
- {ldap_base, "ou=AddressBook,dc=example,dc=org"},
- %% user's part of JID is located in the "mail" attribute
- {ldap_uidattr, "mail"},
- %% common format for our emails
- {ldap_uidattr_format, "%u@mail.example.org"},
- %% We have to define empty filter here, because entries in addressbook does not
- %% belong to shadowAccount object class
- {ldap_filter, ""},
- %% Now we want to define vCard pattern
- {ldap_vcard_map,
- [{"NICKNAME", "%u", []}, % just use user's part of JID as his nickname
- {"GIVEN", "%s", ["givenName"]},
- {"FAMILY", "%s", ["sn"]},
- {"FN", "%s, %s", ["sn", "givenName"]}, % example: "Smith, John"
- {"EMAIL", "%s", ["mail"]},
- {"BDAY", "%s", ["birthDay"]}]},
- %% Search form
- {ldap_search_fields,
- [{"User", "%u"},
- {"Name", "givenName"},
- {"Family Name", "sn"},
- {"Email", "mail"},
- {"Birthday", "birthDay"}]},
- %% vCard fields to be reported
- %% Note that JID is always returned with search results
- {ldap_search_reported,
- [{"Full Name", "FN"},
- {"Nickname", "NICKNAME"},
- {"Birthday", "BDAY"}]}
- ]}
- ...
- }.
-</PRE>
-Note that <TT>mod_vcard_ldap</TT> module checks an existence of the user before
-searching his info in LDAP.<BR>
-<BR>
-<LI CLASS="li-itemize"><TT>ldap_vcard_map</TT> example:
-<PRE CLASS="verbatim">
- {ldap_vcard_map,
- [{"NICKNAME", "%u", []},
- {"FN", "%s", ["displayName"]},
- {"CTRY", "Russia", []},
- {"EMAIL", "%u@%d", []},
- {"DESC", "%s\n%s", ["title", "description"]}
- ]},
-</PRE><LI CLASS="li-itemize"><TT>ldap_search_fields</TT> example:
-<PRE CLASS="verbatim">
- {ldap_search_fields,
- [{"User", "uid"},
- {"Full Name", "displayName"},
- {"Email", "mail"}
- ]},
-</PRE><LI CLASS="li-itemize"><TT>ldap_search_reported</TT> example:
-<PRE CLASS="verbatim">
- {ldap_search_reported,
- [{"Full Name", "FN"},
- {"Email", "EMAIL"},
- {"Birthday", "BDAY"},
- {"Nickname", "NICKNAME"}
- ]},
-</PRE></UL>
-<!--TOC subsection <TT>mod_version</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc69">5.22</A>&nbsp;&nbsp;<A NAME="modversion"><TT>mod_version</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:modversion"></A>
-
-This module implements Software Version (<A HREF="http://www.jabber.org/jeps/jep-0092.html">JEP-0092</A>). Consequently, it
-answers <TT>ejabberd</TT>'s version when queried.<BR>
-<BR>
-Options:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>iqdisc</TT></B><DD CLASS="dd-description"> This specifies
-the processing discipline for Software Version (<TT>jabber:iq:version</TT>) IQ queries
-(see section&nbsp;<A HREF="#sec:modiqdiscoption">5.2.1</A>).
-</DL>
-<!--TOC section Creating an Initial Administrator-->
-
-<H2 CLASS="section"><A NAME="htoc70">6</A>&nbsp;&nbsp;<A NAME="initialadmin">Creating an Initial Administrator</A></H2><!--SEC END -->
-
-<A NAME="sec:initialadmin"></A>
-Before the web interface can be entered to perform administration tasks, an
-account with administrator rights is needed on your <TT>ejabberd</TT> deployment.<BR>
-<BR>
-Instructions to create an initial administrator account:
-<OL CLASS="enumerate" type=1><LI CLASS="li-enumerate">
-Register an account on your <TT>ejabberd</TT> deployment. An account can be
- created in two ways:
- <OL CLASS="enumerate" type=a><LI CLASS="li-enumerate">
- Using the tool <TT>ejabberdctl</TT> (see
- section&nbsp;<A HREF="#sec:ejabberdctl">7.2</A>):
- <PRE CLASS="verbatim">
-% ejabberdctl node@host register admin example.org password
-</PRE><LI CLASS="li-enumerate">Using In-Band Registration (see section&nbsp;<A HREF="#sec:modregister">5.14</A>): you can
- use a Jabber client to register an account.
- </OL>
-<LI CLASS="li-enumerate">Edit the configuration file to promote the account created in the previous
- step to an account with administrator rights. Note that if you want to add
- more administrators, a seperate acl entry is needed for each administrator.
- <PRE CLASS="verbatim">
- {acl, admins, {user, "admin", "example.org"}}.
- {access, configure, [{allow, admins}]}.
-</PRE><LI CLASS="li-enumerate">Restart <TT>ejabberd</TT> to load the new configuration.
-<LI CLASS="li-enumerate">Open the web interface (<CODE>http://server:port/admin/</CODE>) in your
- favourite browser. Make sure to enter the <EM>full</EM> JID as username (in this
- example: <TT>admin@example.org</TT>. The reason that you also need to enter the
- suffix, is because <TT>ejabberd</TT>'s virtual hosting support.
-</OL>
-<!--TOC section Online Configuration and Monitoring-->
-
-<H2 CLASS="section"><A NAME="htoc71">7</A>&nbsp;&nbsp;<A NAME="onlineconfig">Online Configuration and Monitoring</A></H2><!--SEC END -->
-
-<A NAME="sec:onlineconfig"></A>
-<!--TOC subsection Web Interface-->
-
-<H3 CLASS="subsection"><A NAME="htoc72">7.1</A>&nbsp;&nbsp;<A NAME="webinterface">Web Interface</A></H3><!--SEC END -->
-
-<A NAME="sec:webinterface"></A>
-
-To perform online configuration of <TT>ejabberd</TT> you need to enable the
-<TT>ejabberd_http</TT> listener with the option <TT>web_admin</TT> (see
-section&nbsp;<A HREF="#sec:listened">3.3</A>). Then you can open
-<CODE>http://server:port/admin/</CODE> in your favourite web browser. You
-will be asked to enter the username (the <EM>full</EM> Jabber ID) and password
-of an <TT>ejabberd</TT> user with administrator rights. After authentication
-you will see a page similar to figure&nbsp;<A HREF="#fig:webadmmain">1</A>.
-<BLOCKQUOTE CLASS="figure"><DIV CLASS="center"><DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV>
-
- <IMG SRC="webadmmain.png" ALT="webadmmain.png">
-
-
- <BR>
-<BR>
-<DIV CLASS="center">Figure 1: Top page from the web interface</DIV><BR>
-<BR>
-
- <A NAME="fig:webadmmain"></A>
-<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></DIV></BLOCKQUOTE>
-Here you can edit access restrictions, manage users, create backups,
-manage the database, enable/disable ports listened for, view server
-statistics,...<BR>
-<BR>
-Examples:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-You can serve the web interface on the same port as the
- HTTP Polling interface. In this example
- you should point your web browser to <CODE>http://example.org:5280/admin/</CODE> to
- administer all virtual hosts or to
- <CODE>http://example.org:5280/admin/server/example.com/</CODE> to administer only
- the virtual host <TT>example.com</TT>. Before you get access to the web interface
- you need to enter as username, the JID and password from a registered user
- that is allowed to configure <TT>ejabberd</TT>. In this example you can enter as
- username `<TT>admin@example.net</TT>' to administer all virtual hosts (first
- URL). If you log in with `<TT>admin@example.com</TT>' on<BR>
-<CODE>http://example.org:5280/admin/server/example.com/</CODE> you can only
- administer the virtual host <TT>example.com</TT>.
- <PRE CLASS="verbatim">
- ...
- {acl, admins, {user, "admin", "example.net"}}.
- {host_config, "example.com", [{acl, admins, {user, "admin", "example.com"}}]}.
- {access, configure, [{allow, admins}]}.
- ...
- {hosts, ["example.org"]}.
- ...
- {listen,
- [...
- {5280, ejabberd_http, [http_poll, web_admin]},
- ...
- ]
- }.
-</PRE><LI CLASS="li-itemize">For security reasons, you can serve the web interface on a secured
- connection, on a port differing from the HTTP Polling interface, and bind it
- to the internal LAN IP. The web interface will be accessible by pointing your
- web browser to <CODE>https://192.168.1.1:5280/admin/</CODE>:
- <PRE CLASS="verbatim">
- ...
- {hosts, ["example.org"]}.
- ...
- {listen,
- [...
- {5270, ejabberd_http, [http_poll]},
- {5280, ejabberd_http, [web_admin, {ip, {192, 168, 1, 1}},
- tls, {certfile, "/usr/local/etc/server.pem"}]},
- ...
- ]
- }.
-</PRE></UL>
-<!--TOC subsection <TT>ejabberdctl</TT>-->
-
-<H3 CLASS="subsection"><A NAME="htoc73">7.2</A>&nbsp;&nbsp;<A NAME="ejabberdctl"><TT>ejabberdctl</TT></A></H3><!--SEC END -->
-
-<A NAME="sec:ejabberdctl"></A>
-
-It is possible to do some administration operations using the command
-line tool <TT>ejabberdctl</TT>. You can list all available options by
-running <TT>ejabberdctl</TT> without arguments:
-<PRE CLASS="verbatim">
-% ejabberdctl
-Usage: ejabberdctl node command
-
-Available commands:
- status get ejabberd status
- stop stop ejabberd
- restart restart ejabberd
- reopen-log reopen log file
- register user server password register a user
- unregister user server unregister a user
- backup file store a database backup to file
- restore file restore a database backup from file
- install-fallback file install a database fallback from file
- dump file dump a database to a text file
- load file restore a database from a text file
- import-file file import user data from jabberd 1.4 spool file
- import-dir dir import user data from jabberd 1.4 spool directory
- registered-users list all registered users
- delete-expired-messages delete expired offline messages from database
-
-Example:
- ejabberdctl ejabberd@host restart
-</PRE>
-Additional information:
-<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
-<B><TT>reopen-log </TT></B><DD CLASS="dd-description"> If you use a tool to rotate logs, you have to configure it
- so that this command is executed after each rotation.
-<DT CLASS="dt-description"><B><TT>backup, restore, install-fallback, dump, load</TT></B><DD CLASS="dd-description"> You can use these
- commands to create and restore backups.
-<DT CLASS="dt-description"><B><TT>import-file, import-dir</TT></B><DD CLASS="dd-description">
- These options can be used to migrate from other Jabber/XMPP servers. There
- exist tutorials to <A HREF="http://ejabberd.jabber.ru/migrate-to-ejabberd">migrate from other software to ejabberd</A>.
-<DT CLASS="dt-description"><B><TT>delete-expired-messages</TT></B><DD CLASS="dd-description"> This option can be used to delete old messages
- in offline storage. This might be useful when the number of offline messages
- is very high.
-</DL>
-<!--TOC section Firewall Settings-->
-
-<H2 CLASS="section"><A NAME="htoc74">8</A>&nbsp;&nbsp;<A NAME="firewall">Firewall Settings</A></H2><!--SEC END -->
-
-<A NAME="sec:firewall"></A>
-
-You need to take the following TCP ports in mind when configuring your firewall:
-<BLOCKQUOTE CLASS="table"><DIV CLASS="center"><DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV>
- <TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
-<TR><TD ALIGN=left NOWRAP>Port</TD>
-<TD ALIGN=left NOWRAP>Description</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>5222</TD>
-<TD ALIGN=left NOWRAP>SASL and unencrypted c2s connections.</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>5223</TD>
-<TD ALIGN=left NOWRAP>Obsolete SSL c2s connections.</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>5269</TD>
-<TD ALIGN=left NOWRAP>s2s connections.</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>4369</TD>
-<TD ALIGN=left NOWRAP>Only for clustering (see&nbsp;<A HREF="#sec:clustering">10</A>).</TD>
-</TR>
-<TR><TD ALIGN=left NOWRAP>port range</TD>
-<TD ALIGN=left NOWRAP>Only for clustring (see&nbsp;<A HREF="#sec:clustering">10</A>). This range
- is configurable (see&nbsp;<A HREF="#sec:start">2.4</A>).</TD>
-</TR></TABLE>
-<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></DIV></BLOCKQUOTE>
-<!--TOC section SRV Records-->
-
-<H2 CLASS="section"><A NAME="htoc75">9</A>&nbsp;&nbsp;<A NAME="srv">SRV Records</A></H2><!--SEC END -->
-
-<A NAME="sec:srv"></A>
-
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-General information:
- <A HREF="http://en.wikipedia.org/wiki/SRV_record">SRV record</A>
-<LI CLASS="li-itemize">Practical information:
- <A HREF="http://jabberd.jabberstudio.org/2/docs/section05.html#5_7">Setting DNS SRV Records</A>
-</UL>
-<!--TOC section Clustering-->
-
-<H2 CLASS="section"><A NAME="htoc76">10</A>&nbsp;&nbsp;<A NAME="clustering">Clustering</A></H2><!--SEC END -->
-
-<A NAME="sec:clustering"></A>
-
-<!--TOC subsection How it Works-->
-
-<H3 CLASS="subsection"><A NAME="htoc77">10.1</A>&nbsp;&nbsp;<A NAME="howitworks">How it Works</A></H3><!--SEC END -->
-
-<A NAME="sec:howitworks"></A>
-
-A Jabber domain is served by one or more <TT>ejabberd</TT> nodes. These nodes can
-be run on different machines that are connected via a network. They all
-must have the ability to connect to port 4369 of all another nodes, and must
-have the same magic cookie (see Erlang/OTP documentation, in other words the
-file <TT>~ejabberd/.erlang.cookie</TT> must be the same on all nodes). This is
-needed because all nodes exchange information about connected users, s2s
-connections, registered services, etc...<BR>
-<BR>
-Each <TT>ejabberd</TT> node has the following modules:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-router,
-<LI CLASS="li-itemize">local router,
-<LI CLASS="li-itemize">session manager,
-<LI CLASS="li-itemize">s2s manager.
-</UL>
-<!--TOC subsubsection Router-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc78">10.1.1</A>&nbsp;&nbsp;<A NAME="router">Router</A></H4><!--SEC END -->
-
-<A NAME="sec:router"></A>
-
-This module is the main router of Jabber packets on each node. It
-routes them based on their destination's domains. It uses a global
-routing table. The domain of the packet's destination is searched in the
-routing table, and if it is found, the packet is routed to the
-appropriate process. If not, it is sent to the s2s manager.<BR>
-<BR>
-<!--TOC subsubsection Local Router-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc79">10.1.2</A>&nbsp;&nbsp;<A NAME="localrouter">Local Router</A></H4><!--SEC END -->
-
-<A NAME="sec:localrouter"></A>
-
-This module routes packets which have a destination domain equal to
-one of this server's host names. If the destination JID has a non-empty user
-part, it is routed to the session manager, otherwise it is processed depending
-on its content.<BR>
-<BR>
-<!--TOC subsubsection Session Manager-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc80">10.1.3</A>&nbsp;&nbsp;<A NAME="sessionmanager">Session Manager</A></H4><!--SEC END -->
-
-<A NAME="sec:sessionmanager"></A>
-
-This module routes packets to local users. It looks up to which user
-resource a packet must be sent via a presence table. Then the packet is
-either routed to the appropriate c2s process, or stored in offline
-storage, or bounced back.<BR>
-<BR>
-<!--TOC subsubsection s2s Manager-->
-
-<H4 CLASS="subsubsection"><A NAME="htoc81">10.1.4</A>&nbsp;&nbsp;<A NAME="s2smanager">s2s Manager</A></H4><!--SEC END -->
-
-<A NAME="sec:s2smanager"></A>
-
-This module routes packets to other Jabber servers. First, it
-checks if an opened s2s connection from the domain of the packet's
-source to the domain of the packet's destination exists. If that is the case,
-the s2s manager routes the packet to the process
-serving this connection, otherwise a new connection is opened.<BR>
-<BR>
-<!--TOC subsection Clustering Setup-->
-
-<H3 CLASS="subsection"><A NAME="htoc82">10.2</A>&nbsp;&nbsp;<A NAME="cluster">Clustering Setup</A></H3><!--SEC END -->
-
-<A NAME="sec:cluster"></A>
-
-Suppose you already configured <TT>ejabberd</TT> on one machine named (<TT>first</TT>),
-and you need to setup another one to make an <TT>ejabberd</TT> cluster. Then do
-following steps:
-<OL CLASS="enumerate" type=1><LI CLASS="li-enumerate">
-Copy <CODE>~ejabberd/.erlang.cookie</CODE> file from <TT>first</TT> to
- <TT>second</TT>.<BR>
-<BR>
-(alt) You can also add `<CODE>-cookie content_of_.erlang.cookie</CODE>'
- option to all `<TT>erl</TT>' commands below.<BR>
-<BR>
-<LI CLASS="li-enumerate">On <TT>second</TT> run the following command as the <TT>ejabberd</TT> daemon user,
- in the working directory of <TT>ejabberd</TT>:
-<PRE CLASS="verbatim">
-erl -sname ejabberd \
- -mnesia extra_db_nodes "['ejabberd@first']" \
- -s mnesia
-</PRE>
- This will start Mnesia serving the same database as <TT>ejabberd@first</TT>.
- You can check this by running the command `<CODE>mnesia:info().</CODE>'. You
- should see a lot of remote tables and a line like the following:
-<PRE CLASS="verbatim">
-running db nodes = [ejabberd@first, ejabberd@second]
-</PRE><BR>
-<BR>
-<LI CLASS="li-enumerate">Now run the following in the same `<TT>erl</TT>' session:
-<PRE CLASS="verbatim">
-mnesia:change_table_copy_type(schema, node(), disc_copies).
-</PRE>
- This will create local disc storage for the database.<BR>
-<BR>
-(alt) Change storage type of the <TT>scheme</TT> table to `RAM and disc
- copy' on the second node via the web interface.<BR>
-<BR>
-<LI CLASS="li-enumerate">Now you can add replicas of various tables to this node with
- `<CODE>mnesia:add_table_copy</CODE>' or
- `<CODE>mnesia:change_table_copy_type</CODE>' as above (just replace
- `<CODE>schema</CODE>' with another table name and `<CODE>disc_copies</CODE>'
- can be replaced with `<CODE>ram_copies</CODE>' or
- `<CODE>disc_only_copies</CODE>').<BR>
-<BR>
-Which tables to replicate is very dependant on your needs, you can get
- some hints from the command `<CODE>mnesia:info().</CODE>', by looking at the
- size of tables and the default storage type for each table on 'first'.<BR>
-<BR>
-Replicating a table makes lookups in this table faster on this node.
- Writing, on the other hand, will be slower. And of course if machine with one
- of the replicas is down, other replicas will be used.<BR>
-<BR>
-Also <A HREF="http://www.erlang.se/doc/doc-5.4.9/lib/mnesia-4.2.2/doc/html/Mnesia_chap5.html#5.3">section 5.3 (Table Fragmentation) of Mnesia User's Guide</A> can be helpful.
- <BR>
-<BR>
- (alt) Same as in previous item, but for other tables.<BR>
-<BR>
-<LI CLASS="li-enumerate">Run `<CODE>init:stop().</CODE>' or just `<CODE>q().</CODE>' to exit from
- the Erlang shell. This probably can take some time if Mnesia has not yet
- transfered and processed all data it needed from <TT>first</TT>.<BR>
-<BR>
-<LI CLASS="li-enumerate">Now run <TT>ejabberd</TT> on <TT>second</TT> with almost the same config as
- on <TT>first</TT> (you probably do not need to duplicate `<CODE>acl</CODE>'
- and `<CODE>access</CODE>' options &mdash; they will be taken from
- <TT>first</TT>, and <CODE>mod_muc</CODE> and <CODE>mod_irc</CODE> should be
- enabled only on one machine in the cluster).
-</OL>
-You can repeat these steps for other machines supposed to serve this
-domain.<BR>
-<BR>
-
-<!--TOC section Internationalization and Localization-->
-
-<H2 CLASS="section"><A NAME="htoc83">A</A>&nbsp;&nbsp;<A NAME="i18nl10n">Internationalization and Localization</A></H2><!--SEC END -->
-
-<A NAME="sec:i18nl10n"></A>
-
-All built-in modules support the <TT>xml:lang</TT> attribute inside IQ queries.
-Figure&nbsp;<A HREF="#fig:discorus">2</A>, for example, shows the reply to the following query:
-<PRE CLASS="verbatim">
- &lt;iq id='5'
- to='example.org'
- type='get'
- xml:lang='ru'&gt;
- &lt;query xmlns='http://jabber.org/protocol/disco#items'/&gt;
- &lt;/iq&gt;
-</PRE>
-<BLOCKQUOTE CLASS="figure"><DIV CLASS="center"><DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV>
-
- <IMG SRC="discorus.png" ALT="discorus.png">
-
-
- <BR>
-<BR>
-<DIV CLASS="center">Figure 2: Service Discovery when <TT>xml:lang='ru'</TT></DIV><BR>
-<BR>
-
- <A NAME="fig:discorus"></A>
-<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></DIV></BLOCKQUOTE>
-The web interface also supports the <CODE>Accept-Language</CODE> HTTP header (compare
-figure&nbsp;<A HREF="#fig:webadmmainru">3</A> with figure&nbsp;<A HREF="#fig:webadmmain">1</A>)
-<BLOCKQUOTE CLASS="figure"><DIV CLASS="center"><DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV>
-
- <IMG SRC="webadmmainru.png" ALT="webadmmainru.png">
-
-
- <BR>
-<BR>
-<DIV CLASS="center">Figure 3: Top page from the web interface with HTTP header
- `Accept-Language: ru'</DIV><BR>
-<BR>
-
- <A NAME="fig:webadmmainru"></A>
-<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></DIV></BLOCKQUOTE>
-<!--TOC section Release Notes-->
-
-<H2 CLASS="section"><A NAME="htoc84">B</A>&nbsp;&nbsp;<A NAME="releasenotes">Release Notes</A></H2><!--SEC END -->
-
-<A NAME="sec:releasenotes"></A>
-
-<!--TOC subsection ejabberd 0.9-->
-
-<H3 CLASS="subsection"><A NAME="htoc85">B.1</A>&nbsp;&nbsp;ejabberd 0.9</H3><!--SEC END -->
-
-<PRE CLASS="verbatim">
- Release notes
- ejabberd 0.9
-
- This document describes the major new features of and changes to
- ejabberd 0.9, compared to latest public release ejabber 0.7.5.
-
- For more detailed information, please refer to ejabberd User
- Guide.
-
-
-Virtual Hosting
-
- ejabberd now can host several domain on the same instance.
- This option is enabled by using:
-
- {hosts, ["erlang-projects.org", "erlang-fr.org"]}.
-
- instead of the previous host directive.
-
- Note that you are now using a list of hosts. The main one should
- be the first listed. See migration section further in this release
- note for details.
-
-
-Shared Roster
-
- Shared roster is a new feature that allow the ejabberd
- administrator to add jabber user that will be present in the
- roster of every users on the server.
- Shared roster are enabled by adding:
-
- {mod_shared_roster, []}
-
- at the end of your module list in your ejabberd.cfg file.
-
-
-PostgreSQL (ODBC) support
-
- This feature is experimental and not yet properly documented. This
- feature is released for testing purpose.
-
- You need to have Erlang/OTP R10 to compile with ODBC on various
- flavour of *nix. You should use Erlang/OTP R10B-4, as this task
- has became easier with this release. It comes already build in
- Erlang/OTP Microsoft Windows binary.
-
- PostgreSQL support is enabled by using the following module in
- ejabberd.cfg instead of their standard counterpart:
-
- mod_last_odbc.erl
- mod_offline_odbc.erl
- mod_roster_odbc.erl
-
- The database schema is located in the src/odbc/pq.sql file.
-
- Look at the src/ejabberd.cfg.example file for more information on
- how to configure ejabberd with odbc support. You can get support
- on how to configure ejabberd with a relational database.
-
-
-Migration from ejabberd 0.7.5
-
- Migration is pretty straightforward as Mnesia database schema
- conversions is handled automatically. Remember however that you
- must backup your ejabberd database before migration.
-
- Here are the following steps to proceed:
-
- 1. Stop your instance of ejabberd.
-
- 2. In ejabberd.cfg, define the host lists. Change the host
- directive to the hosts one:
- Before:
- {host, "erlang-projects.org"}.
- After:
- {hosts, ["erlang-projects.org", "erlang-fr.org"]}.
- Note that when you restart the server the existing users will be
- affected to the first virtual host, so the order is important. You
- should keep the previous hostname as the first virtual host.
-
- 3. Restart ejabberd.
-
-
-Bugfixes
-
- This release contains several bugfixes and architectural changes.
- Please refer to the Changelog file supplied with this release for
- details of all improvements in the ejabberd code.
-</PRE>
-<!--TOC subsection ejabberd 0.9.1-->
-
-<H3 CLASS="subsection"><A NAME="htoc86">B.2</A>&nbsp;&nbsp;ejabberd 0.9.1</H3><!--SEC END -->
-
-<PRE CLASS="verbatim">
- Release notes
- ejabberd 0.9.1
-
- This document describes the main changes from [25]ejabberd 0.9.
-
- The code can be downloaded from the [26]download page.
-
- For more detailed information, please refer to ejabberd [27]User Guide.
-
-
-Groupchat (Multi-user chat and IRC) improvements
-
- The multi-user chat code has been improved to comply with the latest version
- of Jabber Enhancement Proposal 0045.
-
- The IRC (Internet Relay Chat) features now support WHOIS and USERINFO
- requests.
-
-
-Web interface
-
- ejabberd modules management features have been added to the web interface.
- They now allow to start or stop extension module without restarting the
- ejabberd server.
-
-
-Publish and subscribe
-
- It is now possible to a subscribe node with a JabberID that includes a
- resource.
-
-
-Translations
-
- A new script has been included to help translate ejabberd into new languages
- and maintain existing translations.
-
- As a result, ejabberd is now translating into 10 languages:
- * Dutch
- * English
- * French
- * German
- * Polish
- * Portuguese
- * Russian
- * Spanish
- * Swedish
- * Ukrainian
-
-
-Migration
-
- No changes have been made to the database. No particular conversion steps
- are needed. However, you should backup your database before upgrading to a
- new ejabberd version.
-
-
-Bugfixes
-
- This release contains several bugfixes and architectural changes. Please
- refer to the Changelog file supplied with this release for details of all
- improvements in the ejabberd code.
-</PRE>
-<!--TOC subsection ejabberd 0.9.8-->
-
-<H3 CLASS="subsection"><A NAME="htoc87">B.3</A>&nbsp;&nbsp;ejabberd 0.9.8</H3><!--SEC END -->
-
-<PRE CLASS="verbatim">
- Release notes
- ejabberd 0.9.8
- 2005-08-01
-
- This document describes the main changes in ejabberd 0.9.8. This
- version prepares the way for the release of ejabberd 1.0, which
- is due later this year.
-
- The code can be downloaded from the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/
-
- For more detailed information, please refer to ejabberd User Guide
- on the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/docs.html
-
-
- Recent changes include....
-
-
-Enhanced virtual hosting
-
- Virtual hosting applies to many more setting options and
- features and is transparent. Virtual hosting accepts different
- parameters for different virtual hosts regarding the following
- features: authentication method, access control lists and access
- rules, users management, statistics, and shared roster. The web
- interface gives access to each virtual host's parameters.
-
-
-Enhanced Publish-Subscribe module
-
- ejabberd's Publish-Subscribe module integrates enhancements
- coming from J-EAI, an XMPP-based integration server built on
- ejabberd. ejabberd thus supports Publish-Subscribe node
- configuration. It is possible to define nodes that should be
- persistent, and the number of items to persist. Besides that, it
- is also possible to define various notification parameters, such
- as the delivery of the payload with the notifications, and the
- notification of subscribers when some changes occur on items.
- Other examples are: the maximum size of the items payload, the
- subscription approvers, the limitation of the notification to
- online users only, etc.
-
-
-Code reorganisation and update
-
- - The mod_register module has been cleaned up.
- - ODBC support has been updated and several bugs have been fixed.
-
-
-Development API
-
- To ease the work of Jabber/XMPP developers, a filter_packet hook
- has been added. As a result it is possible to develop plugins to
- filter or modify packets flowing through ejabberd.
-
-
-Translations
-
- - Translations have been updated to support the new Publish-Subscribe features.
- - A new Brazilian Portuguese translation has been contributed.
-
-
-Web interface
-
- - The CSS stylesheet from the web interface is W3C compliant.
-
-
-Installers
-
- Installers are provided for Microsoft Windows and Linux/x86. The
- Linux installer includes Erlang ASN.1 modules for LDAP
- authentication support.
-
-
-Bugfixes
-
- - This release contains several bugfixes and architectural
- changes. Among other bugfixes include improvements in LDAP
- authentication. Please refer to the ChangeLog file supplied
- with this release regarding all improvements in ejabberd.
-
-
-References
-
- The ejabberd feature sheet helps comparing with other Jabber/XMPP
- servers:
- http://www.process-one.net/en/projects/ejabberd/docs/features.pdf
-
- Contributed tutorials of interest are:
- - Migration from Jabberd1.4 to ejabberd:
- http://ejabberd.jabber.ru/jabberd1-to-ejabberd
- - Migration from Jabberd2 to ejabberd:
- http://ejabberd.jabber.ru/jabberd2-to-ejabberd
- - Transport configuration for connecting to other networks:
- http://ejabberd.jabber.ru/tutorials-transports
-
-END
-
-</PRE>
-<!--TOC subsection ejabberd 1.0.0-->
-
-<H3 CLASS="subsection"><A NAME="htoc88">B.4</A>&nbsp;&nbsp;ejabberd 1.0.0</H3><!--SEC END -->
-
-<PRE CLASS="verbatim">
- Release Notes
- ejabberd 1.0.0
- 14 December 2005
-
- This document describes the main changes in ejabberd 1.0.0. Unique in this
- version is the compliancy with the XMPP (eXtensible Messaging and Presence
- Protocol) standard. ejabberd is the first Open Source Jabber server claiming
- to fully comply to the XMPP standard.
-
- ejabberd can be downloaded from the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/
-
- Detailed information can be found in the ejabberd Feature Sheet and User
- Guide which are available on the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/docs.html
-
-
- Recent changes include:
-
-
-Server-to-server Encryption for Enhanced Security
-
- - Support for STARTTLS and SASL EXTERNAL to secure server-to-server traffic
- has been added.
- - Also, STARTTLS and Dialback has been implemented for server-to-server (s2s)
- connections. Detailed information about these new features can be found on
- http://ejabberd.jabber.ru/s2s-encryption
- - commonName and dNSName fields matching were introduced to ease the process
- of retrieving certificates.
- - Different certificates can be defined for each virtual host.
-
-ODBC Support
-
- - ODBC support has been improved to allow production use of ejabberd with
- relational databases.
- - Support for vCard storage in ODBC has been added.
- - ejd2odbc.erl is a tool to convert an installation from Erlang's database
- Mnesia to an ODBC compatible relational database.
-
-Native PostgreSQL Support
-
- - Native PostgreSQL support gives you a better performance when you use
- PostgreSQL.
-
-Shared Roster groups
-
- - Shared Roster groups support has been enhanced. New is the ability to add
- all registered users to everyone's roster. Detailed information about this
- new feature can be found on http://ejabberd.jabber.ru/shared-roster-all
-
-Web Interface
-
- - The web interface internal code has been modified for better integration
- and compliancy with J-EAI, an ejabberd-based Enterprise Application
- Integration platform.
- - More XHTML 1.0 Transitional compliancy work was done.
-
-Transports
-
- - A transport workaround can be enabled during compilation. To do this, you
- can pass the "--enable-roster-gateway-workaround" option to the configure
- script. (./configure --enable-roster-gateway-workaround)
- This option allows transports to add items with subscription "to" in the
- roster by sending &lt;presence type='subscribed'/&gt; stanza to user. This option
- is only needed for JIT ICQ transport.
- Warning: by enabling this option, ejabberd will not be fully XMPP compliant
- anymore.
-
-Documentation and Internationalization
-
- - Documentation has been extended to cover more topics.
- - Translations have been updated.
-
-Bugfixes
-
- - This release contains several bugfixes.
- - Among other bugfixes include improvements to the client-to-server (c2s)
- connection management module.
- - Please refer to the ChangeLog file supplied
- with this release regarding all improvements in ejabberd.
-
-
- Installation Notes
-
-
-Supported Erlang Version
-
- - You need at least Erlang/OTP R9C to run ejabberd 1.0.0.
-
-Installation
-
- Installers are provided for Microsoft Windows and Linux/x86.
- Installers can be retrieved from:
- http://www.process-one.net/en/projects/ejabberd/download.html
-
-Migration Notes
-
- - Before any migration, ejabberd system and database must be properly
- backed up.
- - When upgrading an ODBC-based installation, you will need to change the
- relational database schema. The following SQL commands must be run on the
- database:
- CREATE SEQUENCE spool_seq_seq;
- ALTER TABLE spool ADD COLUMN seq integer;
- ALTER TABLE spool ALTER COLUMN seq SET DEFAULT nextval('spool_seq_seq');
- UPDATE spool SET seq = DEFAULT;
- ALTER TABLE spool ALTER COLUMN seq SET NOT NULL;
-
-References
-
- Contributed tutorials of interest are:
- - Migration from Jabberd1.4 to ejabberd:
- http://ejabberd.jabber.ru/jabberd1-to-ejabberd
- - Migration from Jabberd2 to ejabberd:
- http://ejabberd.jabber.ru/jabberd2-to-ejabberd
- - Transport configuration for connecting to other networks:
- http://ejabberd.jabber.ru/tutorials-transports
-
-END
-
-</PRE>
-<!--TOC subsection ejabberd 1.1.0-->
-
-<H3 CLASS="subsection"><A NAME="htoc89">B.5</A>&nbsp;&nbsp;ejabberd 1.1.0</H3><!--SEC END -->
-
-<PRE CLASS="verbatim">
- Release Notes
- ejabberd 1.1.0
- 24 April 2006
-
- This document describes the main changes in ejabberd 1.1.0. This version
- introduce new features including support for new Jabber Enhancement
- Proposals and several performance improvements enabling deployments on an
- even larger scale than already possible.
-
- ejabberd can be downloaded from the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/
-
- Detailed information can be found in the ejabberd Feature Sheet and User
- Guide which are available on the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/docs.html
-
- A complete list of changes is available from:
- http://support.process-one.net/secure/ReleaseNote.jspa?projectId=10011&amp;styleName=Html&amp;version=10025
-
-
- Recent changes include:
-
-
-New Jabber Enhancement Proposal support:
-
- - JEP-0050: Ad-Hoc Commands.
- - JEP-0138: Stream Compression.
- - JEP-0175: SASL anonymous.
-
-Anonymous login
-
- - SASL anonymous.
- - Anonymous login for clients that do not yet support SASL Anonymous.
-
-Relational database Support
-
- - MySQL is now fully supported through ODBC and in native mode.
- - Various improvements to the native database interfaces.
- - The migration tool can use relational databases.
-
-Multi-User Chat improvements
-
- - Logging of room discussion to text file is now supported.
- - Better reconfiguration support.
- - Security oriented fixes.
- - Several improvements and updates to latest JEP-0045.
-
-Performance scalability improvements for large clusters
-
- - Improved session synchronisation management between cluster nodes.
- - Internal architecture has been reworked to use generalize Erlang/OTP
- framework usage.
- - Speed improvement on logger.
- - TCP/IP packet reception change for better network throttling and
- regulation.
- As a result, these improvements will reduce load on large scale deployments.
-
-XMPP Protocol related improvements
-
- - XML stanza size can be limited.
- - Messages are send to all resources with the same highest priority.
-
-Documentation and Internationalization
-
- - Documentation has been extended to cover more topics.
- - Translations have been updated.
-
-Web interface
-
- - XHTML 1.0 compliance.
-
-Bugfixes
-
- - This release contains many bugfixes on various areas such as Publish-Subscribe, build
- chain, installers, IRC gateway, ejabberdctl, amongst others.
- - Please refer to the ChangeLog file supplied with this release regarding
- all improvements in ejabberd.
-
-
-
- Installation Notes
-
-Supported Erlang Version
-
- - You need at least Erlang/OTP R9C-2 to run ejabberd 1.1.0.
-
-Installation
-
- Installers are provided for Microsoft Windows, Linux/x86 and MacOSX/PPC.
- Installers can be retrieved from:
- http://www.process-one.net/en/projects/ejabberd/download.html
-
-Migration Notes
-
- - Before any migration, ejabberd system and database must be properly
- backed up.
- - The database schema has not been changed comparing to version 1.0.0 and
- consequently it does not require any migration.
-
-
-References
-
- Contributed tutorials and documents of interest are:
- - Migration from Jabberd1.4, Jabberd2 and WPJabber to ejabberd:
- http://ejabberd.jabber.ru/migrate-to-ejabberd
- - Transport configuration for connecting to other networks:
- http://ejabberd.jabber.ru/tutorials-transports
- - Using ejabberd with MySQL native driver:
- http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver
- - Anonymous User Support:
- http://support.process-one.net/doc/display/MESSENGER/Anonymous+users+support
- - Frequently Asked Questions:
- http://ejabberd.jabber.ru/faq
-
-END
-</PRE>
-<!--TOC subsection ejabberd 1.1.1-->
-
-<H3 CLASS="subsection"><A NAME="htoc90">B.6</A>&nbsp;&nbsp;ejabberd 1.1.1</H3><!--SEC END -->
-
-<PRE CLASS="verbatim">
- Release Notes
- ejabberd 1.1.1
- 28 April 2006
-
- This document describes the main changes in ejabberd 1.1.x. This version
- introduce new features including support for new Jabber Enhancement
- Proposals and several performance improvements enabling deployments on an
- even larger scale than already possible.
-
- This release fix a security issue introduced in ejabberd 1.1.0. In SASL
- mode, anonymous login was enabled as a default. Upgrading ejabberd 1.1.0 to
- ejabberd 1.1.1 is highly recommended.
-
- ejabberd can be downloaded from the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/
-
- Detailed information can be found in the ejabberd Feature Sheet and User
- Guide which are available on the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/docs.html
-
- A complete list of changes is available from:
- http://support.process-one.net/secure/ReleaseNote.jspa?projectId=10011&amp;styleName=Html&amp;version=10025
-
-
- Recent changes include:
-
-
-New Jabber Enhancement Proposal support:
-
- - JEP-0050: Ad-Hoc Commands.
- - JEP-0138: Stream Compression.
- - JEP-0175: SASL anonymous.
-
-Anonymous login
-
- - SASL anonymous.
- - Anonymous login for clients that do not yet support SASL Anonymous.
-
-Relational database Support
-
- - MySQL is now fully supported through ODBC and in native mode.
- - Various improvements to the native database interfaces.
- - The migration tool can use relational databases.
-
-Multi-User Chat improvements
-
- - Logging of room discussion to text file is now supported.
- - Better reconfiguration support.
- - Security oriented fixes.
- - Several improvements and updates to latest JEP-0045.
-
-Performance scalability improvements for large clusters
-
- - Improved session synchronisation management between cluster nodes.
- - Internal architecture has been reworked to use generalize Erlang/OTP
- framework usage.
- - Speed improvement on logger.
- - TCP/IP packet reception change for better network throttling and
- regulation.
- As a result, these improvements will reduce load on large scale deployments.
-
-XMPP Protocol related improvements
-
- - XML stanza size can be limited.
- - Messages are send to all resources with the same highest priority.
-
-Documentation and Internationalization
-
- - Documentation has been extended to cover more topics.
- - Translations have been updated.
-
-Web interface
-
- - XHTML 1.0 compliance.
-
-Bugfixes
-
- - This release contains many bugfixes on various areas such as Publish-Subscribe, build
- chain, installers, IRC gateway, ejabberdctl, amongst others.
- - Please refer to the ChangeLog file supplied with this release regarding
- all improvements in ejabberd.
-
-
-
- Installation Notes
-
-Supported Erlang Version
-
- - You need at least Erlang/OTP R9C-2 to run ejabberd 1.1.0.
-
-Installation
-
- Installers are provided for Microsoft Windows, Linux/x86 and MacOSX/PPC.
- Installers can be retrieved from:
- http://www.process-one.net/en/projects/ejabberd/download.html
-
-Migration Notes
-
- - Before any migration, ejabberd system and database must be properly
- backed up.
- - The database schema has not been changed comparing to version 1.0.0 and
- consequently it does not require any migration.
-
-
-References
-
- Contributed tutorials and documents of interest are:
- - Migration from Jabberd1.4, Jabberd2 and WPJabber to ejabberd:
- http://ejabberd.jabber.ru/migrate-to-ejabberd
- - Transport configuration for connecting to other networks:
- http://ejabberd.jabber.ru/tutorials-transports
- - Using ejabberd with MySQL native driver:
- http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver
- - Anonymous User Support:
- http://support.process-one.net/doc/display/MESSENGER/Anonymous+users+support
- - Frequently Asked Questions:
- http://ejabberd.jabber.ru/faq
-
-END
-</PRE>
-<!--TOC subsection ejabberd 1.1.2-->
-
-<H3 CLASS="subsection"><A NAME="htoc91">B.7</A>&nbsp;&nbsp;ejabberd 1.1.2</H3><!--SEC END -->
-
-<PRE CLASS="verbatim">
- Release Notes
- ejabberd 1.1.2
- 27 September 2006
-
- This document describes the main changes in ejabberd 1.1.2.
-
- This version is a major improvement over ejabberd 1.1.1, improving the
- overall behaviour of the server in many areas. Users of ejabberd 1.1.1
- should upgrade to this new release for improved robustness and compliance.
-
- ejabberd can be downloaded from the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/
-
- Detailed information can be found in the Feature Sheet and in the
- Installation and Operation Guide which are both available on the
- Process-one website:
- http://www.process-one.net/en/projects/ejabberd/docs.html
-
- ejabberd includes 44 improvements. A complete list of changes can be
- retrieved from:
- http://redir.process-one.net/ejabberd-1.1.2
-
-
- Recent changes include:
-
-LDAP Improvements
-
- - Major improvements have been made on the LDAP module. It is now more
- flexible and more robust.
-
-HTTP Polling Fixes
-
- - The HTTP polling modules have been fixed and improved: the connections are
- closed properly and polled messages cannot be lost anymore.
-
-Roster Management Improvement
-
- - Roster management improvements increase reliability, especially in cases
- where users are on different servers.
- - Shared rosters are more reliable.
-
-Improved Robustness
-
- - It is now possible to limit the number of opened connections for a single
- user.
-
-Relational databases
-
- - Database support: Microsoft SQL Server is now officially supported in ODBC
- mode.
-
-Publish-Subscribe Improvement
-
- - Restricting node creation with a dedicated ACL rule is now possible.
-
-Localization
-
- - A Czech translation has been added.
- - Translations have been updated.
-
-Binary Installer
-
- - New binary installer for Windows including all requirements.
- - Improved installers for Linux and MacOSX (PowerPC)
-
-XMPP Compliancy
-
- - Some protocol compliance fix have been added, after the Portland XMPP
- Interop Meeting in July.
-
-Miscelanous
-
- - MUC have been improved (logging rendering).
- - The command line tool ejabberdctl has been improved.
- - The build chain has been improved, including MacOSX support.
- - The documentation has been improved and updated to describe the new
- features.
-
-Bugfixes
-
- - Anonymous login bugfixes.
- - Please refer to the ChangeLog file supplied with this release regarding
- all improvements in ejabberd.
-
-
- Installation Notes
-
-Supported Erlang Version
-
- - You need at least Erlang/OTP R9C-2 to run ejabberd 1.1.2.
- - The recommanded version is Erlang/OTP R10B-10.
- - Erlang/OTP R11B has not yet been fully certified for ejabberd.
-
-Installation
-
- Installers are provided for Microsoft Windows, Linux/x86 and MacOSX/PPC.
- They can be retrieved from:
- http://www.process-one.net/en/projects/ejabberd/download.html
-
-Migration Notes
-
- - Before any migration, ejabberd system and database must be properly
- backed up.
- - The relational database schema has changed between version 1.1.1 and
- 1.1.2. An "askmessage" column needs to be added in the "rosterusers" table
- to perform the migration.
-
-
-References
-
- Contributed tutorials and documents of interest are:
- - Migration from other XMPP servers to ejabberd:
- http://ejabberd.jabber.ru/migrate-to-ejabberd
- - Transport configuration for connecting to other networks:
- http://ejabberd.jabber.ru/tutorials-transports
- - Frequently Asked Questions:
- http://ejabberd.jabber.ru/faq
-
-END
-</PRE>
-<!--TOC section Acknowledgements-->
-
-<H2 CLASS="section"><A NAME="htoc92">C</A>&nbsp;&nbsp;<A NAME="acknowledgements">Acknowledgements</A></H2><!--SEC END -->
-
-<A NAME="sec:acknowledgements"></A>
-Thanks to all people who contributed to this guide:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-Alexey Shchepin (<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT></A>)
-<LI CLASS="li-itemize">Badlop (<A HREF="xmpp:badlop@jabberes.org"><TT>xmpp:badlop@jabberes.org</TT></A>)
-<LI CLASS="li-itemize">Evgeniy Khramtsov (<A HREF="xmpp:xram@jabber.ru"><TT>xmpp:xram@jabber.ru</TT></A>)
-<LI CLASS="li-itemize">Florian Zumbiehl (<A HREF="xmpp:florz@florz.de"><TT>xmpp:florz@florz.de</TT></A>)
-<LI CLASS="li-itemize">Michael Grigutsch (<A HREF="xmpp:migri@jabber.i-pobox.net"><TT>xmpp:migri@jabber.i-pobox.net</TT></A>)
-<LI CLASS="li-itemize">Mickael Remond (<A HREF="xmpp:mremond@erlang-projects.org"><TT>xmpp:mremond@erlang-projects.org</TT></A>)
-<LI CLASS="li-itemize">Sander Devrieze (<A HREF="xmpp:sander@devrieze.dyndns.org"><TT>xmpp:sander@devrieze.dyndns.org</TT></A>)
-<LI CLASS="li-itemize">Sergei Golovan (<A HREF="xmpp:sgolovan@nes.ru"><TT>xmpp:sgolovan@nes.ru</TT></A>)
-<LI CLASS="li-itemize">Vsevolod Pelipas (<A HREF="xmpp:vsevoload@jabber.ru"><TT>xmpp:vsevoload@jabber.ru</TT></A>)
-</UL>
-<!--TOC section Copyright Information-->
-
-<H2 CLASS="section"><A NAME="htoc93">D</A>&nbsp;&nbsp;<A NAME="copyright">Copyright Information</A></H2><!--SEC END -->
-
-<A NAME="sec:copyright"></A>
-Ejabberd Installation and Operation Guide.<BR>
-Copyright &copy; January 23, 2003 &mdash; Alexey Shchepin<BR>
-<BR>
-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
-of the License, or (at your option) any later version.<BR>
-<BR>
-This document 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.<BR>
-<BR>
-You should have received a copy of the GNU General Public License along with
-this document; if not, write to the Free Software Foundation, Inc., 51 Franklin
-Street, Fifth Floor, Boston, MA 02110-1301, USA.<BR>
-<BR>
-<!--HTMLFOOT-->
-<!--ENDHTML-->
-<!--FOOTER-->
-<HR SIZE=2><BLOCKQUOTE CLASS="quote"><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
-</EM><A HREF="http://pauillac.inria.fr/~maranget/hevea/index.html"><EM>H<FONT SIZE=2><sup>E</sup></FONT>V<FONT SIZE=2><sup>E</sup></FONT>A</EM></A><EM>.</EM></BLOCKQUOTE></BODY>
-</HTML>
diff --git a/ejabberd-1.1.2/doc/guide.tex b/ejabberd-1.1.2/doc/guide.tex
deleted file mode 100644
index 174dc95a6..000000000
--- a/ejabberd-1.1.2/doc/guide.tex
+++ /dev/null
@@ -1,3159 +0,0 @@
-\documentclass[a4paper,10pt]{article}
-
-%% Packages
-\usepackage{float}
-\usepackage{graphics}
-\usepackage{hevea}
-\usepackage[pdftex,colorlinks,unicode,urlcolor=blue,linkcolor=blue,
- pdftitle=Ejabberd\ Installation\ and\ Operation\ Guide,pdfauthor=Alexey\
- Shchepin,pdfsubject=ejabberd,pdfkeywords=ejabberd,
- pdfpagelabels=false]{hyperref}
-\usepackage{makeidx}
-%\usepackage{showidx} % Only for verifying the index entries.
-\usepackage{verbatim}
-\usepackage{geometry}
-
-%% Index
-\makeindex
-% Remove the index anchors from the HTML version to save size and bandwith.
-\newcommand{\ind}[1]{\begin{latexonly}\index{#1}\end{latexonly}}
-
-%% Images
-\newcommand{\logoscale}{0.7}
-\newcommand{\imgscale}{0.58}
-\newcommand{\insimg}[1]{\insscaleimg{\imgscale}{#1}}
-\newcommand{\insscaleimg}[2]{
- \imgsrc{#2}{}
- \begin{latexonly}
- \scalebox{#1}{\includegraphics{#2}}
- \end{latexonly}
-}
-
-%% Various
-\newcommand{\bracehack}{\def\{{\char"7B}\def\}{\char"7D}}
-\newcommand{\titem}[1]{\item[\bracehack\texttt{#1}]}
-\newcommand{\ns}[1]{\texttt{#1}}
-\newcommand{\jid}[1]{\texttt{#1}}
-\newcommand{\option}[1]{\texttt{#1}}
-\newcommand{\poption}[1]{{\bracehack\texttt{#1}}}
-\newcommand{\node}[1]{\texttt{#1}}
-\newcommand{\term}[1]{\texttt{#1}}
-\newcommand{\shell}[1]{\texttt{#1}}
-\newcommand{\ejabberd}{\texttt{ejabberd}}
-\newcommand{\Jabber}{Jabber}
-
-%% Modules
-\newcommand{\module}[1]{\texttt{#1}}
-\newcommand{\modadhoc}{\module{mod\_adhoc}}
-\newcommand{\modannounce}{\module{mod\_announce}}
-\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}}
-\newcommand{\modmuclog}{\module{mod\_muc\_log}}
-\newcommand{\modoffline}{\module{mod\_offline}}
-\newcommand{\modofflineodbc}{\module{mod\_offline\_odbc}}
-\newcommand{\modprivacy}{\module{mod\_privacy}}
-\newcommand{\modprivate}{\module{mod\_private}}
-\newcommand{\modpubsub}{\module{mod\_pubsub}}
-\newcommand{\modregister}{\module{mod\_register}}
-\newcommand{\modroster}{\module{mod\_roster}}
-\newcommand{\modrosterodbc}{\module{mod\_roster\_odbc}}
-\newcommand{\modservicelog}{\module{mod\_service\_log}}
-\newcommand{\modsharedroster}{\module{mod\_shared\_roster}}
-\newcommand{\modstats}{\module{mod\_stats}}
-\newcommand{\modtime}{\module{mod\_time}}
-\newcommand{\modvcard}{\module{mod\_vcard}}
-\newcommand{\modvcardldap}{\module{mod\_vcard\_ldap}}
-\newcommand{\modvcardodbc}{\module{mod\_vcard\_odbc}}
-\newcommand{\modversion}{\module{mod\_version}}
-
-%% Common options
-\newcommand{\iqdiscitem}[1]{\titem{iqdisc} \ind{options!iqdisc}This specifies
-the processing discipline for #1 IQ queries
-(see section~\ref{sec:modiqdiscoption}).}
-\newcommand{\hostitem}[1]{
- \titem{hosts} \ind{options!hosts} This option defines the hostnames of the
- service (see section~\ref{sec:modhostsoption}). If neither \texttt{hosts} nor
- the old \texttt{host} is present, the prefix `\jid{#1.}' is added to all
- \ejabberd{} hostnames.
-}
-
-%\newcommand{\quoting}[2][yozhik]{\begin{quotation}\textcolor{#1}{\textit{#2}}\end{quotation}} % Quotes enabled
-%\renewcommand{command}[args][default]{def}
-%\renewcommand{\headrule}{{\color{ejblue}%
-%\hrule width\headwidth height\headrulewidth \vskip-\headrulewidth}}
-
-%% Title page
-\include{version}
-\title{Ejabberd \version\ Installation and Operation Guide}
-\author{Alexey Shchepin \\
- \ahrefurl{mailto:alexey@sevcom.net} \\
- \ahrefurl{xmpp:aleksey@jabber.ru}}
-
-%% Options
-\newcommand{\marking}[1]{#1} % Marking disabled
-\newcommand{\quoting}[2][yozhik]{} % Quotes disabled
-\newcommand{\new}{\marginpar{\textsc{new}}} % Highlight new features
-\newcommand{\improved}{\marginpar{\textsc{improved}}} % Highlight improved features
-
-%% To by-pass errors in the HTML version.
-\newstyle{SPAN}{width:20\%; float:right; text-align:left; margin-left:auto;}
-
-%% Footnotes
-\begin{latexonly}
-\global\parskip=9pt plus 3pt minus 1pt
-\global\parindent=0pt
-\gdef\ahrefurl#1{\href{#1}{\texttt{#1}}}
-\gdef\footahref#1#2{#2\footnote{\href{#1}{\texttt{#1}}}}
-\end{latexonly}
-\newcommand{\tjepref}[2]{\footahref{http://www.jabber.org/jeps/jep-#1.html}{#2}}
-\newcommand{\jepref}[1]{\tjepref{#1}{JEP-#1}}
-
-\begin{document}
-
-\label{titlepage}
-\begin{titlepage}
- \maketitle{}
-
- \begin{center}
- {\insscaleimg{\logoscale}{logo.png}
- \par
- }
- \end{center}
-
- \begin{quotation}\textit{I can thoroughly recommend ejabberd for ease of setup ---
- Kevin Smith, Current maintainer of the Psi project}\end{quotation}
-
-\end{titlepage}
-
-% Set the page counter to 2 so that the titlepage and the second page do not
-% have the same page number. This fixes the PDFLaTeX warning "destination with
-% the same identifier".
-\begin{latexonly}
-\setcounter{page}{2}
-\end{latexonly}
-
-\tableofcontents{}
-
-% Input introduction.tex
-\input{introduction}
-
-\section{\aname{installsource}{Installation from Source}}
-\label{sec:installsource}
-\ind{installation}
-
-\subsection{\aname{installreq}{Installation Requirements}}
-\label{sec:installreq}
-\ind{installation!requirements}
-
-\subsubsection{\aname{installrequnix}{`Unix-like' operating systems}}
-\label{sec:installrequnix}
-
-To compile \ejabberd{} on a `Unix-like' operating system, you need:
-\begin{itemize}
-\item GNU Make
-\item GCC
-\item libexpat 1.95 or higher
-\item Erlang/OTP R9C-2 or higher
-\item OpenSSL 0.9.6 or higher (optional)
-\item Zlib 1.2.3 or higher (optional)
-\item GNU Iconv 1.8 or higher (optional, not needed on systems with GNU libc)
-\end{itemize}
-
-\subsubsection{\aname{installreqwin}{Windows}}
-\label{sec:installreqwin}
-
-To compile \ejabberd{} on a Windows flavour, you need:
-\begin{itemize}
-\item MS Visual C++ 6.0 Compiler
-\item \footahref{http://erlang.org/download.html}{Erlang/OTP R9C-2 or higher}
-\item \footahref{http://sourceforge.net/project/showfiles.php?group\_id=10127\&package\_id=11277}{Expat 1.95.7 or higher}
-\item
-\footahref{http://www.gnu.org/software/libiconv/}{GNU Iconv 1.9.1}
-(optional)
-\item \footahref{http://www.slproweb.com/products/Win32OpenSSL.html}{Shining Light OpenSSL}
-(to enable SSL connections)
-\item \footahref{http://www.zlib.net/}{Zlib 1.2.3 or higher}
-\end{itemize}
-
-\subsection{\aname{obtaining}{Obtaining \ejabberd{}}}
-\label{sec:obtaining}
-
-\ind{download}
-Released versions of \ejabberd{} can be obtained from \\
-\ahrefurl{http://www.process-one.net/en/projects/ejabberd/download.html}.
-
-\ind{Subversion repository}
-The latest development version can be retrieved from the Subversion repository\@.
-\begin{verbatim}
- svn co http://svn.process-one.net/ejabberd/trunk ejabberd
-\end{verbatim}
-
-\subsection{\aname{compile}{Compilation}}
-\label{sec:compile}
-\ind{installation!compilation}
-
-\subsubsection{\aname{compileunix}{`Unix-like' operating systems}}
-\label{sec:compileunix}
-
-Compile \ejabberd{} on a `Unix-like' operating system by executing:
-
-\begin{verbatim}
- ./configure
- make
- su
- make install
-\end{verbatim}
-
-These commands will:
-\begin{itemize}
-\item install \ejabberd{} into the directory \verb|/var/lib/ejabberd|,
-\item install the configuration file into \verb|/etc/ejabberd|,
-\item create a directory called \verb|/var/log/ejabberd| to store log files.
-\end{itemize}
-
-Note: if you want to use an external database, you need to execute the configure
-script with the option(s) \term{--enable-odbc} or \term{--enable-odbc
---enable-mssql}. See section~\ref{sec:database} for more information.
-
-\subsubsection{\aname{compilewin}{Windows}}
-\label{sec:compilewin}
-
-\begin{itemize}
-\item Install Erlang emulator (for example, into \verb|C:\Program Files\erl5.3|).
-\item Install Expat library into \verb|C:\Program Files\Expat-1.95.7|
- directory.
-
- Copy file \verb|C:\Program Files\Expat-1.95.7\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:\Program Files\iconv-1.9.1|.
-
- Copy file \verb|C:\Program Files\iconv-1.9.1\bin\iconv.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:\Program Files\Expat-1.95.7\Libs| and
- \verb|C:\Program Files\iconv-1.9.1\bin| to the \verb|PATH| environment
- variable.
-\item While in the directory \verb|ejabberd\src| run:
-\begin{verbatim}
-configure.bat
-nmake -f Makefile.win32
-\end{verbatim}
-\item Edit the file \verb|ejabberd\src\ejabberd.cfg| and run
-\begin{verbatim}
-werl -s ejabberd -name ejabberd
-\end{verbatim}
-\end{itemize}
-
-%TODO: how to compile database support on windows?
-
-\subsection{\aname{start}{Starting}}
-\label{sec:start}
-\ind{starting}
-%TODO: update when the ejabberdctl script is made more userfriendly
-
-Execute the following command to start \ejabberd{}:
-\begin{verbatim}
- erl -pa /var/lib/ejabberd/ebin -name ejabberd -s ejabberd
-\end{verbatim}
-or
-\begin{verbatim}
- erl -pa /var/lib/ejabberd/ebin -sname ejabberd -s ejabberd
-\end{verbatim}
-In the latter case the Erlang node will be identified using only the first part
-of the host name, i.\,e. other Erlang nodes outside this domain cannot contact
-this node.
-
-Note that when using the above command, \ejabberd{} will search for the
-configuration file in the current directory and will use the current directory
-for storing its user database and for logging.
-
-To specify the path to the configuration file, the log files and the Mnesia
-database directory, you may use the following command:
-\begin{verbatim}
- erl -pa /var/lib/ejabberd/ebin \
- -sname ejabberd \
- -s ejabberd \
- -ejabberd config \"/etc/ejabberd/ejabberd.cfg\" \
- log_path \"/var/log/ejabberd/ejabberd.log\" \
- -sasl sasl_error_logger \{file,\"/var/log/ejabberd/sasl.log\"\} \
- -mnesia dir \"/var/lib/ejabberd/spool\"
-\end{verbatim}
-
-You can find other useful options in the Erlang manual page
-(\shell{erl -man erl}).
-
-To use more than 1024 connections, you should set the environment variable
-\verb|ERL_MAX_PORTS|:
-\begin{verbatim}
- export ERL_MAX_PORTS=32000
-\end{verbatim}
-Note that with this value, \ejabberd{} will use more memory (approximately 6\,MB
-more).
-
-To reduce memory usage, you may set the environment variable
-\verb|ERL_FULLSWEEP_AFTER|:
-\begin{verbatim}
- export ERL_FULLSWEEP_AFTER=0
-\end{verbatim}
-But in this case \ejabberd{} can start to work slower.
-
-
-\section{\aname{basicconfig}{Basic Configuration}}
-\label{sec:basicconfig}
-\ind{configuration file}
-
-The configuration file will be loaded the first time you start \ejabberd{}. The
-content from this file will be parsed and stored in a database. Subsequently the
-configuration will be loaded from the database and any commands in the
-configuration file are appended to the entries in the database. The
-configuration file contains a sequence of Erlang terms. Lines beginning with a
-\term{`\%'} sign are ignored. Each term is a tuple of which the first element is
-the name of an option, and any further elements are that option's values. If the
-configuration file do not contain for instance the `hosts' option, the old
-host name(s) stored in the database will be used.
-
-
-You can override the old values stored in the database by adding next lines to
-the configuration file:
-\begin{verbatim}
- override_global.
- override_local.
- override_acls.
-\end{verbatim}
-With these lines the old global options, local options and ACLs will be removed
-before new ones are added.
-
-\subsection{\aname{hostnames}{Host Names}}
-\label{sec:hostnames}
-\ind{options!hosts}\ind{host names}
-
-The option \option{hosts} defines a list containing one or more domains that
-\ejabberd{} will serve.
-
-Examples:
-\begin{itemize}
-\item Serving one domain:
- \begin{verbatim}
- {hosts, ["example.org"]}.
-\end{verbatim}
-\item Serving one domain, and backwards compatible with older \ejabberd{}
- versions:
- \begin{verbatim}
- {host, "example.org"}.
-\end{verbatim}
-\item Serving two domains:
-\begin{verbatim}
- {hosts, ["example.net", "example.com"]}.
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{virtualhost}{Virtual Hosting}}
-\label{sec:virtualhost}
-\ind{virtual hosting}\ind{virtual hosts}\ind{virtual domains}
-
-Options can be defined separately for every virtual host using the
-\term{host\_config} option.\ind{options!host\_config} It has the following
-syntax:
-\begin{verbatim}
- {host_config, <hostname>, [<option>, <option>, ...]}.
-\end{verbatim}
-
-Examples:
-\begin{itemize}
-\item Domain \jid{example.net} is using the internal authentication method while
- domain \jid{example.com} is using the \ind{LDAP}LDAP server running on the
- domain \jid{localhost} to perform authentication:
-\begin{verbatim}
-{host_config, "example.net", [{auth_method, internal}]}.
-
-{host_config, "example.com", [{auth_method, ldap},
- {ldap_servers, ["localhost"]},
- {ldap_uidattr, "uid"},
- {ldap_rootdn, "dc=localdomain"},
- {ldap_rootdn, "dc=example,dc=com"},
- {ldap_password, ""}]}.
-\end{verbatim}
-\item Domain \jid{example.net} is using \ind{ODBC}ODBC to perform authentication
- while domain \jid{example.com} is using the LDAP servers running on the domains
- \jid{localhost} and \jid{otherhost}:
-\begin{verbatim}
-{host_config, "example.net", [{auth_method, odbc},
- {odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}]}.
-
-{host_config, "example.com", [{auth_method, ldap},
- {ldap_servers, ["localhost", "otherhost"]},
- {ldap_uidattr, "uid"},
- {ldap_rootdn, "dc=localdomain"},
- {ldap_rootdn, "dc=example,dc=com"},
- {ldap_password, ""}]}.
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{listened}{Listened Sockets}}
-\label{sec:listened}
-\ind{options!listen}
-
-The option \option{listen} defines for which addresses and ports \ejabberd{}
-will listen and what services will be run on them. Each element of the list is a
-tuple with the following elements:
-\begin{itemize}
-\item Port number.
-\item Module that serves this port.
-\item Options to this module.
-\end{itemize}
-
-\ind{modules!ejabberd\_c2s}\ind{modules!ejabberd\_s2s\_in}\ind{modules!ejabberd\_service}\ind{modules!ejabberd\_http}\ind{protocols!JEP-0114: Jabber Component Protocol}
-Currently next modules are implemented:
-\begin{table}[H]
- \centering
- \def\arraystretch{1.4}
- \begin{tabular}{|l|l|p{87mm}|}
- \hline \texttt{ejabberd\_c2s}& Description& Handles c2s connections.\\
- \cline{2-3} & Options& \texttt{access}, \texttt{certfile}, \texttt{inet6},
- \texttt{ip}, \texttt{max\_stanza\_size}, \texttt{shaper}, \texttt{ssl},
- \texttt{tls}, \texttt{starttls}, \texttt{starttls\_required},
- \texttt{zlib}\\
- \hline \texttt{ejabberd\_s2s\_in}& Description& Handles incoming s2s
- connections.\\
- \cline{2-3} & Options& \texttt{inet6}, \texttt{ip},
- \texttt{max\_stanza\_size}\\
- \hline \texttt{ejabberd\_service}& Description& Interacts with external
- components (*).\\
- \cline{2-3} & Options& \texttt{access}, \texttt{hosts}, \texttt{inet6},
- \texttt{ip}, \texttt{shaper}\\
- \hline \texttt{ejabberd\_http}& Description& Handles incoming HTTP
- connections.\\
- \cline{2-3} & Options& \texttt{certfile}, \texttt{http\_poll},
- \texttt{inet6}, \texttt{ip}, \texttt{tls}, \texttt{web\_admin}\\
- \hline
- \end{tabular}
-\end{table}
-
-(*) The mechanism for \footahref{http://ejabberd.jabber.ru/tutorials-transports}{external components} is defined in Jabber Component Protocol (\jepref{0114}).
-
-The following options are available:
-\begin{description}
- \titem{\{access, <access rule>\}} \ind{options!access}This option defines
- access to the port. The default value is \term{all}.
- \titem{\{certfile, Path\}} Path to a file containing the SSL certificate.
- \titem{\{hosts, [Hostnames], [HostOptions]\}} \ind{options!hosts}This option
- defines one or more hostnames of connected services and enables you to
- specify additional options including \poption{\{password, Secret\}}.
- \titem{http\_poll} \ind{options!http\_poll}\ind{protocols!JEP-0025: HTTP Polling}\ind{JWChat}\ind{web-based Jabber client}
- This option enables HTTP Polling (\jepref{0025}) support. HTTP Polling
- enables access via HTTP requests to \ejabberd{} from behind firewalls which
- do not allow outgoing sockets on port 5222.
-
- If HTTP Polling is enabled, it will be available at
- \verb|http://server:port/http-poll/|. Be aware that support for HTTP Polling
- is also needed in the \Jabber{} client. Remark also that HTTP Polling can be
- interesting to host a web-based \Jabber{} client such as
- \footahref{http://jwchat.sourceforge.net/}{JWChat} (there is a tutorial to
- \footahref{http://ejabberd.jabber.ru/jwchat}{install JWChat} with
- instructions for \ejabberd{}).
- \titem{inet6} \ind{options!inet6}\ind{IPv6}Set up the socket for IPv6.
- \titem{\{ip, IPAddress\}} \ind{options!ip}This option specifies which network
- interface to listen for. For example \verb|{ip, {192, 168, 1, 1}}|.
- \titem{\{max\_stanza\_size, Size\}} \ind{options!max\_stanza\_size}This
- option specifies an approximate maximum size in bytes of XML stanzas.
- Approximate, because it is calculated with the precision of one block of
- readed data. For example \verb|{max_stanza_size, 65536}|. The default
- value is \term{infinity}.
- \titem{\{shaper, <access rule>\}} \ind{options!shaper}This option defines a
- shaper for the port (see section~\ref{sec:shapers}). The default value
- is \term{none}.
- \titem{ssl} \ind{options!ssl}\ind{SSL}This option specifies that traffic on
- the port will be encrypted using SSL. You should also set the
- \option{certfile} option. It is recommended to use the \term{tls} option
- instead.
- \titem{starttls} \ind{options!starttls}\ind{STARTTLS}This option
- specifies that STARTTLS encryption is available on connections to the port.
- You should also set the \option{certfile} option.
- \titem{starttls\_required} \ind{options!starttls\_required}This option
- specifies that STARTTLS encryption is required on connections to the port.
- No unencrypted connections will be allowed. You should also set the
- \option{certfile} option.
- \titem{tls} \ind{options!tls}\ind{TLS}This option specifies that traffic on
- the port will be encrypted using SSL immediately after connecting. You
- should also set the \option{certfile} option.
- \titem{zlib} \ind{options!zlib}\ind{protocols!JEP-0138: Stream Compression}\ind{Zlib}This
- option specifies that Zlib stream compression (as defined in \jepref{0138})
- is available on connections to the port. Client connections cannot use
- stream compression and stream encryption simultaneously. Hence, if you
- specify both \option{tls} (or \option{ssl}) and \option{zlib}, the latter
- option will not affect connections (there will be no stream compression).
- \titem{web\_admin} \ind{options!web\_admin}\ind{web interface}This option
- enables the web interface for \ejabberd{} administration which is available
- at \verb|http://server:port/admin/|. Login and password are the username and
- password of one of the registered users who are granted access by the
- `configure' access rule.
-\end{description}
-
-In addition, the following options are available for s2s connections:
-\begin{description}
- \titem{\{s2s\_use\_starttls, true|false\}}
- \ind{options!s2s\_use\_starttls}\ind{STARTTLS}This option defines whether to
- use STARTTLS for s2s connections.
- \titem{\{s2s\_certfile, Path\}} \ind{options!s2s\_certificate}Path to a
- file containing a SSL certificate.
- \titem{\{domain\_certfile, Domain, Path\}} \ind{options!domain\_certfile}Path
- to the file containing the SSL certificate for the specified domain.
-\end{description}
-
-For instance, the following configuration defines that:
-\begin{itemize}
-\item c2s connections are listened for on port 5222 and 5223 (SSL) and denied
- for the user called `\term{bad}'.
-\item s2s connections are listened for on port 5269 with STARTTLS for secured
- traffic enabled.
-\item Port 5280 is serving the web interface and the HTTP Polling service. Note
- that it is also possible to serve them on different ports. The second
- example in section~\ref{sec:webinterface} shows how exactly this can be done.
-\item All users except for the administrators have a traffic of limit
- 1,000\,Bytes/second
-\item \ind{transports!AIM}The
- \footahref{http://ejabberd.jabber.ru/pyaimt}{AIM transport}
- \jid{aim.example.org} is connected to port 5233 with password
- `\term{aimsecret}'.
-\item \ind{transports!ICQ}The ICQ transport JIT (\jid{icq.example.org} and
- \jid{sms.example.org}) is connected to port 5234 with password
- `\term{jitsecret}'.
-\item \ind{transports!MSN}The
- \footahref{http://ejabberd.jabber.ru/pymsnt}{MSN transport}
- \jid{msn.example.org} is connected to port 5235 with password
- `\term{msnsecret}'.
-\item \ind{transports!Yahoo}The
- \footahref{http://ejabberd.jabber.ru/yahoo-transport-2}{Yahoo! transport}
- \jid{yahoo.example.org} is connected to port 5236 with password
- `\term{yahoosecret}'.
-\item \ind{transports!Gadu-Gadu}The \footahref{http://ejabberd.jabber.ru/jabber-gg-transport}{Gadu-Gadu transport} \jid{gg.example.org} is
- connected to port 5237 with password `\term{ggsecret}'.
-\item \ind{transports!email notifier}The
- \footahref{http://ejabberd.jabber.ru/jmc}{Jabber Mail Component}
- \jid{jmc.example.org} is connected to port 5238 with password
- `\term{jmcsecret}'.
-\end{itemize}
-\begin{verbatim}
- {acl, blocked, {user, "bad"}}.
- {access, c2s, [{deny, blocked},
- {allow, all}]}.
- {shaper, normal, {maxrate, 1000}}.
- {access, c2s_shaper, [{none, admin},
- {normal, all}]}.
- {listen,
- [{5222, ejabberd_c2s, [{access, c2s}, {shaper, c2s_shaper}]},
- {5223, ejabberd_c2s, [{access, c2s},
- ssl, {certfile, "/path/to/ssl.pem"}]},
- {5269, ejabberd_s2s_in, []},
- {5280, ejabberd_http, [http_poll, web_admin]},
- {5233, ejabberd_service, [{host, "aim.example.org",
- [{password, "aimsecret"}]}]},
- {5234, ejabberd_service, [{hosts, ["icq.example.org", "sms.example.org"],
- [{password, "jitsecret"}]}]},
- {5235, ejabberd_service, [{host, "msn.example.org",
- [{password, "msnsecret"}]}]},
- {5236, ejabberd_service, [{host, "yahoo.example.org",
- [{password, "yahoosecret"}]}]},
- {5237, ejabberd_service, [{host, "gg.example.org",
- [{password, "ggsecret"}]}]},
- {5238, ejabberd_service, [{host, "jmc.example.org",
- [{password, "jmcsecret"}]}]}
- ]
- }.
- {s2s_use_starttls, true}.
- {s2s_certfile, "/path/to/ssl.pem"}.
-\end{verbatim}
-Note, that for \ind{jabberd 1.4}jabberd 1.4- or \ind{WPJabber}WPJabber-based
-services you have to make the transports log and do \ind{XDB}XDB by themselves:
-\begin{verbatim}
- <!--
- You have to add elogger and rlogger entries here when using ejabberd.
- In this case the transport will do the logging.
- -->
-
- <log id='logger'>
- <host/>
- <logtype/>
- <format>%d: [%t] (%h): %s</format>
- <file>/var/log/jabber/service.log</file>
- </log>
-
- <!--
- Some Jabber server implementations do not provide
- XDB services (for example, jabberd2 and ejabberd).
- xdb_file.so is loaded in to handle all XDB requests.
- -->
-
- <xdb id="xdb">
- <host/>
- <load>
- <!-- this is a lib of wpjabber or jabberd -->
- <xdb_file>/usr/lib/jabber/xdb_file.so</xdb_file>
- </load>
- <xdb_file xmlns="jabber:config:xdb_file">
- <spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>
- </xdb_file>
- </xdb>
-\end{verbatim}
-
-\subsection{\aname{auth}{Authentication}}
-\label{sec:auth}
-\ind{authentication}\ind{options!auth\_method}
-
-The option \option{auth\_method} defines the authentication method that is used
-for user authentication:
-\begin{verbatim}
- {auth_method, [<method>]}.
-\end{verbatim}
-
-The following authentication methods are supported by \ejabberd{}:
-\begin{itemize}
-\item internal (default) --- See section~\ref{sec:internalauth}.
-\item external --- There are \footahref{http://ejabberd.jabber.ru/extauth}{some
- example authentication scripts}.
-\item ldap --- See section~\ref{sec:ldap}.
-\item odbc --- See section~\ref{sec:mysql}, \ref{sec:pgsql},
- \ref{sec:mssql} and \ref{sec:odbc}.
-\item anonymous --- See section~\ref{sec:saslanonymous}.
-\end{itemize}
-
-\subsubsection{\aname{internalauth}{Internal}}
-\label{sec:internalauth}
-\ind{internal authentication}\ind{Mnesia}
-
-\ejabberd{} uses its internal Mnesia database as the default authentication method.
-
-\begin{itemize}
-\item \term{auth\_method}: The value \term{internal} will enable the internal
- authentication method.
-\end{itemize}
-
-Examples:
-\begin{itemize}
-\item To use internal authentication on \jid{example.org} and LDAP
- authentication on \jid{example.net}:
- \begin{verbatim}
-{host_config, "example.org", [{auth_method, [internal]}]}.
-{host_config, "example.net", [{auth_method, [ldap]}]}.
-\end{verbatim}
-\item To use internal authentication on all virtual hosts:
- \begin{verbatim}
-{auth_method, internal}.
-\end{verbatim}
-\end{itemize}
-
-\subsubsection{\aname{saslanonymous}{SASL Anonymous and Anonymous Login}}
-\label{sec:saslanonymous}
-\ind{sasl anonymous}\ind{anonymous login}
-
-%TODO: introduction; tell what people can do with this
-The anonymous authentication method can be configured with the following
-options. Remember that you can use the \term{host\_config} option to set virtual
-host specific options (see section~\ref{sec:virtualhost}). Note that there also
-is a detailed tutorial regarding \footahref{http://support.process-one.net/doc/display/MESSENGER/Anonymous+users+support}{SASL
-Anonymous and anonymous login configuration}.
-
-\begin{itemize}
-\item \term{auth\_method}: The value \term{anonymous} will enable the anonymous
- authentication method.
-\item \term{allow\_multiple\_connections}: This value for this option can be
- either \term{true} or \term{false} and is only used when the anonymous mode is
- enabled. Setting it to \term{true} means that the same username can be taken
- multiple times in anonymous login mode if different resource are used to
- connect. This option is only useful in very special occasions. The default
- value is \term{false}.
-\item \term{anonymous\_protocol}: This option can take three values:
- \term{sasl\_anon}, \term{login\_anon} or \term{both}. \term{sasl\_anon} means
- that the SASL Anonymous method will be used. \term{login\_anon} means that the
- anonymous login method will be used. \term{both} means that SASL Anonymous and
- login anonymous are both enabled.
-\end{itemize}
-
-Those options are defined for each virtual host with the \term{host\_config}
-parameter (see section~\ref{sec:virtualhost}).
-
-Examples:
-\begin{itemize}
-\item To enable anonymous login on all virtual hosts:
- \begin{verbatim}
-{auth_method, [anonymous]}.
-{anonymous_protocol, login_anon}.
- \end{verbatim}
-\item Similar as previous example, but limited to \jid{public.example.org}:
- \begin{verbatim}
-{host_config, "public.example.org", [{auth_method, [anonymous]},
- {anonymous_protocol, login_anon}]}.
-\end{verbatim}
-\item To enable anonymous login and internal authentication on a virtual host:
- \begin{verbatim}
-{host_config, "public.example.org", [{auth_method, [anonymous,internal]},
- {anonymous_protocol, login_anon}]}.
-\end{verbatim}
-\item To enable SASL Anonymous on a virtual host:
- \begin{verbatim}
-{host_config, "public.example.org", [{auth_method, [anonymous]},
- {anonymous_protocol, sasl_anon}]}.
-\end{verbatim}
-\item To enable SASL Anonymous and anonymous login on a virtual host:
- \begin{verbatim}
-{host_config, "public.example.org", [{auth_method, [anonymous]},
- {anonymous_protocol, both}]}.
-\end{verbatim}
-\item To enable SASL Anonymous, anonymous login, and internal authentication on
-a virtual host:
- \begin{verbatim}
-{host_config, "public.example.org", [{auth_method, [anonymous,internal]},
- {anonymous_protocol, both}]}.
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{accessrules}{Access Rules}}
-\label{sec:accessrules}
-\ind{options!acl}\ind{access rules}\ind{ACL}\ind{Access Control List}
-
-Access control in \ejabberd{} is performed via Access Control Lists (ACLs). The
-declarations of ACLs in the configuration file have the following syntax:
-\begin{verbatim}
- {acl, <aclname>, {<acltype>, ...}}.
-\end{verbatim}
-
-\term{<acltype>} can be one of the following:
-\begin{description}
-\titem{all} Matches all JIDs. Example:
-\begin{verbatim}
-{acl, all, all}.
-\end{verbatim}
-\titem{\{user, <username>\}} Matches the user with the name
- \term{<username>} at the first virtual host. Example:
-\begin{verbatim}
-{acl, admin, {user, "yozhik"}}.
-\end{verbatim}
-\titem{\{user, <username>, <server>\}} Matches the user with the JID
- \term{<username>@<server>} and any resource. Example:
-\begin{verbatim}
-{acl, admin, {user, "yozhik", "example.org"}}.
-\end{verbatim}
-\titem{\{server, <server>\}} Matches any JID from server
- \term{<server>}. Example:
-\begin{verbatim}
-{acl, exampleorg, {server, "example.org"}}.
-\end{verbatim}
-\titem{\{user\_regexp, <regexp>\}} Matches any local user with a name that
- matches \term{<regexp>} at the first virtual host. Example:
-\begin{verbatim}
-{acl, tests, {user, "^test[0-9]*$"}}.
-\end{verbatim}
-%$
-\titem{\{user\_regexp, <regexp>, <server>\}} Matches any user with a name
- that matches \term{<regexp>} at server \term{<server>}. Example:
-\begin{verbatim}
-{acl, tests, {user, "^test", "example.org"}}.
-\end{verbatim}
-\titem{\{server\_regexp, <regexp>\}} Matches any JID from the server that
- matches \term{<regexp>}. Example:
-\begin{verbatim}
-{acl, icq, {server, "^icq\\."}}.
-\end{verbatim}
-\titem{\{node\_regexp, <user\_regexp>, <server\_regexp>\}} Matches any user
- with a name that matches \term{<user\_regexp>} at any server that matches
- \term{<server\_regexp>}. Example:
-\begin{verbatim}
-{acl, yohzik, {node_regexp, "^yohzik$", "^example.(com|org)$"}}.
-\end{verbatim}
-\titem{\{user\_glob, <glob>\}}
-\titem{\{user\_glob, <glob>, <server>\}}
-\titem{\{server\_glob, <glob>\}}
-\titem{\{node\_glob, <user\_glob>, <server\_glob>\}} This is the same as
- above. However, it uses shell glob patterns instead of regexp. These patterns
- can have the following special characters:
- \begin{description}
- \titem{*} matches any string including the null string.
- \titem{?} matches any single character.
- \titem{[...]} matches any of the enclosed characters. Character
- ranges are specified by a pair of characters separated by a \term{`-'}.
- If the first character after \term{`['} is a \term{`!'}, any
- character not enclosed is matched.
- \end{description}
-\end{description}
-
-The following ACLs are pre-defined:
-\begin{description}
-\titem{all} Matches any JID.
-\titem{none} Matches no JID.
-\end{description}
-
-An entry allowing or denying access to different services looks similar to
-this:
-\begin{verbatim}
- {access, <accessname>, [{allow, <aclname>},
- {deny, <aclname>},
- ...
- ]}.
-\end{verbatim}
-When a JID is checked to have access to \term{<accessname>}, the server
-sequentially checks if that JID mathes any of the ACLs that are named in the
-second elements of the tuples in the list. If it matches, the first element of
-the first matched tuple is returned, otherwise the value `\term{deny}' is
-returned.
-
-Example:
-\begin{verbatim}
- {access, configure, [{allow, admin}]}.
- {access, something, [{deny, badmans},
- {allow, all}]}.
-\end{verbatim}
-
-The following access rules are pre-defined:
-\begin{description}
-\titem{all} Always returns the value `\term{allow}'.
-\titem{none} Always returns the value `\term{deny}'.
-\end{description}
-
-\subsection{\aname{shapers}{Shapers}}
-\label{sec:shapers}
-\ind{options!shaper}\ind{options!maxrate}\ind{shapers}\ind{maxrate}\ind{traffic speed}
-
-Shapers enable you to limit connection traffic. The syntax of
-shapers is like this:
-\begin{verbatim}
- {shaper, <shapername>, <kind>}.
-\end{verbatim}
-Currently only one kind of shaper called \term{maxrate} is available. It has the
-following syntax:
-\begin{verbatim}
- {maxrate, <rate>}
-\end{verbatim}
-where \term{<rate>} stands for the maximum allowed incomig rate in bytes per
-second.
-
-Examples:
-\begin{itemize}
-\item To define a shaper named `\term{normal}' with traffic speed limited to
-1,000\,bytes/second:
-\begin{verbatim}
- {shaper, normal, {maxrate, 1000}}.
-\end{verbatim}
-\item To define a shaper named `\term{fast}' with traffic speed limited to
-50,000\,bytes/second:
-\begin{verbatim}
- {shaper, fast, {maxrate, 50000}}.
-\end{verbatim}
-\end{itemize}
-
-\subsection{Limiting Opened Sessions}
-\label{sec:configmaxsessions}
-\ind{options!max\_user\_sessions}
-
-This option specifies the maximum number of sessions (authenticated
-connections) per user. If a user tries to open more sessions by using different
-resources, the first opened session will be disconnected. The error
-\term{session replaced} will be sent to the disconnected session. The value
-for this option can be either a number, or \term{infinity}. The default
-value is \term{10}.
-
-Examples:
-\begin{itemize}
-\item To limit the number of sessions per user to 10 on all virtual
-hosts:
-\begin{verbatim}
- {max_user_sessions, 10}.
-\end{verbatim}
-\item This option can be defined per virtual host (see
-section~\ref{sec:virtualhost}). In next example the number of
-sessions per user on the first host is six, while there is no limit on the
-second host:
-\begin{verbatim}
- {host_config, "example.net", [{max_user_sessions, 6}]}.
- {host_config, "example.com", [{max_user_sessions, infinity}]}.
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{language}{Default Language}}
-\label{sec:language}
-\ind{options!language}\ind{language}
-
-The option \option{language} defines the default language of server strings that
-can be seen by \Jabber{} clients. If a \Jabber{} client do not support
-\option{xml:lang}, the specified language is used. The default value is
-\term{en}. In order to take effect there must be a translation file
-\term{<language>.msg} in \ejabberd{}'s \term{msgs} directory.
-
-Examples:
-\begin{itemize}
-\item To set Russian as default language:
-\begin{verbatim}
- {language, "ru"}.
-\end{verbatim}
-\item To set Spanish as default language:
-\begin{verbatim}
- {language, "es"}.
-\end{verbatim}
-\end{itemize}
-
-
-\section{\aname{database}{Database Configuration}}
-\label{sec:database}
-\ind{database}
-%TODO: this whole section is not yet 100% optimized
-
-\ejabberd{} uses its internal Mnesia database by default. However, it is
-possible to use a relational database or an LDAP server to store persistant,
-long-living data. \ejabberd{} is very flexible: you can configure different
-authentication methods for different virtual hosts, you can configure different
-authentication mechanisms for the same virtual host (fallback), you can set
-different storage systems for modules, and so forth.
-
-The following databases are supported by \ejabberd{}:
-\begin{itemize}
-\item \footahref{http://www.microsoft.com/sql/}{Microsoft SQL Server}
-\item \footahref{http://www.erlang.org/doc/doc-5.5.1/lib/mnesia-4.3.2/doc/}{Mnesia}
-\item \footahref{http://mysql.com/}{MySQL}
-\item \footahref{http://en.wikipedia.org/wiki/Open\_Database\_Connectivity}{Any ODBC compatible database}
-\item \footahref{http://www.postgresql.org/}{PostgreSQL}
-\end{itemize}
-
-The following LDAP servers are tested with \ejabberd{}:
-\begin{itemize}
-\item \footahref{http://www.microsoft.com/activedirectory/}{Active Directory}
- (see section~\ref{sec:ad})
-\item \footahref{http://www.openldap.org/}{OpenLDAP}
-\item Normally any LDAP compatible server should work; inform us about your
- success with a not-listed server so that we can list it here.
-\end{itemize}
-
-\subsection{\aname{mysql}{MySQL}}
-\label{sec:mysql}
-\ind{MySQL}\ind{MySQL!schema}
-
-Although this section will describe \ejabberd{}'s configuration when you want to
-use the native MySQL driver, it does not describe MySQL's installation and
-database creation. Check the MySQL documentation and the tutorial \footahref{http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver}{Using ejabberd with MySQL native driver} for information regarding these topics.
-Note that the tutorial contains information about \ejabberd{}'s configuration
-which is duplicate to this section.
-
-Moreover, the file mysql.sql in the directory src/odbc might be interesting for
-you. This file contains the ejabberd schema for MySQL. At the end of the file
-you can find information to update your database schema.
-
-\subsubsection{\aname{compilemysql}{Driver Compilation}}
-\label{sec:compilemysql}
-\ind{MySQL!Driver Compilation}
-
-You can skip this step if you installed \ejabberd{} using a binary installer or
-if the binary packages of \ejabberd{} you are using include support for MySQL.
-
-\begin{enumerate}
-\item First, install the \footahref{http://support.process-one.net/doc/display/CONTRIBS/Yxa}{Erlang
- MySQL library}. Make sure the compiled files are in your Erlang path; you can
- put them for example in the same directory as your ejabberd .beam files.
-\item Then, configure and install \ejabberd{} with ODBC support enabled (this is
- also needed for native MySQL support!). This can be done, by using next
- commands:
- \begin{verbatim}
-./configure --enable-odbc && make install
-\end{verbatim}
-\end{enumerate}
-
-\subsubsection{\aname{mysqlauth}{Authentication}}
-\label{sec:mysqlauth}
-\ind{MySQL!authentication}
-
-The option value name may be misleading, as the \term{auth\_method} name is used
-for access to a relational database through ODBC, as well as through the native
-MySQL interface. Anyway, the first configuration step is to define the odbc
-\term{auth\_method}. For example:
-\begin{verbatim}
-{host_config, "public.example.org", [{auth_method, [odbc]}]}.
-\end{verbatim}
-
-The actual database access is defined in the option \term{odbc\_server}. Its
-value is used to define if we want to use ODBC, or one of the two native
-interface available, PostgreSQL or MySQL.
-
-To use the native MySQL interface, you can pass a tuple of the following form as
-parameter:
-\begin{verbatim}
-{mysql, "Server", "Database", "Username", "Password"}
-\end{verbatim}
-
-\term{mysql} is a keyword that should be kept as is. For example:
-\begin{verbatim}
-{odbc_server, {mysql, "localhost", "test", "root", "password"}}.
-\end{verbatim}
-
-\subsubsection{\aname{mysqlstorage}{Storage}}
-\label{sec:mysqlstorage}
-\ind{MySQL!storage}
-
-MySQL also can be used to store information into from several \ejabberd{}
-modules. See section~\ref{sec:modoverview} to see which modules have a version
-with the `\_odbc'. This suffix indicates that the module can be used with
-relational databases like MySQL. To enable storage to your database, just make
-sure that your database is running well (see previous sections), and replace the
-suffix-less or ldap module variant with the odbc module variant. Keep in mind
-that you cannot have several variants of the same module loaded!
-
-\subsection{\aname{mssql}{Microsoft SQL Server}}
-\label{sec:mssql}
-\ind{Microsoft SQL Server}\ind{Microsoft SQL Server!schema}
-
-Although this section will describe \ejabberd{}'s configuration when you want to
-use Microsoft SQL Server, it does not describe Microsoft SQL Server's
-installation and database creation. Check the MySQL documentation and the
-tutorial \footahref{http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver}{Using ejabberd with MySQL native driver} for information regarding these topics.
-Note that the tutorial contains information about \ejabberd{}'s configuration
-which is duplicate to this section.
-
-Moreover, the file mssql.sql in the directory src/odbc might be interesting for
-you. This file contains the ejabberd schema for Microsoft SQL Server. At the end
-of the file you can find information to update your database schema.
-
-\subsubsection{\aname{compilemssql}{Driver Compilation}}
-\label{sec:compilemssql}
-\ind{Microsoft SQL Server!Driver Compilation}
-
-You can skip this step if you installed \ejabberd{} using a binary installer or
-if the binary packages of \ejabberd{} you are using include support for ODBC.
-
-If you want to use Microsoft SQL Server with ODBC, you need to configure,
-compile and install \ejabberd{} with support for ODBC and Microsoft SQL Server
-enabled. This can be done, by using next commands:
-\begin{verbatim}
-./configure --enable-odbc --enable-mssql && make install
-\end{verbatim}
-
-\subsubsection{\aname{mssqlauth}{Authentication}}
-\label{sec:mssqlauth}
-\ind{Microsoft SQL Server!authentication}
-
-%TODO: not sure if this section is right!!!!!!
-
-The configuration of Microsoft SQL Server is the same as the configuration of
-ODBC compatible serers (see section~\ref{sec:odbcauth}).
-
-\subsubsection{\aname{mssqlstorage}{Storage}}
-\label{sec:mssqlstorage}
-\ind{Microsoft SQL Server!storage}
-
-Microsoft SQL Server also can be used to store information into from several
-\ejabberd{} modules. See section~\ref{sec:modoverview} to see which modules have
-a version with the `\_odbc'. This suffix indicates that the module can be used
-with relational databases like Microsoft SQL Server. To enable storage to your
-database, just make sure that your database is running well (see previous
-sections), and replace the suffix-less or ldap module variant with the odbc
-module variant. Keep in mind that you cannot have several variants of the same
-module loaded!
-
-\subsection{\aname{pgsql}{PostgreSQL}}
-\label{sec:pgsql}
-\ind{PostgreSQL}\ind{PostgreSQL!schema}
-
-Although this section will describe \ejabberd{}'s configuration when you want to
-use the native PostgreSQL driver, it does not describe PostgreSQL's installation
-and database creation. Check the PostgreSQL documentation and the tutorial \footahref{http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver}{Using ejabberd with MySQL native driver} for information regarding these topics.
-Note that the tutorial contains information about \ejabberd{}'s configuration
-which is duplicate to this section.
-
-Also the file pg.sql in the directory src/odbc might be interesting for you.
-This file contains the ejabberd schema for PostgreSQL. At the end of the file
-you can find information to update your database schema.
-
-\subsubsection{\aname{compilepgsql}{Driver Compilation}}
-\label{sec:compilepgsql}
-\ind{PostgreSQL!Driver Compilation}
-
-You can skip this step if you installed \ejabberd{} using a binary installer or
-if the binary packages of \ejabberd{} you are using include support for
-PostgreSQL.
-
-\begin{enumerate}
-\item First, install the Erlang PgSQL library from
- \footahref{http://jungerl.sourceforge.net/}{Jungerl}. Make sure the compiled
- files are in your Erlang path; you can put them for example in the same
- directory as your ejabberd .beam files.
-\item Then, configure, compile and install \ejabberd{} with ODBC support enabled
- (this is also needed for native PostgreSQL support!). This can be done, by
- using next commands:
- \begin{verbatim}
-./configure --enable-odbc && make install
-\end{verbatim}
-\end{enumerate}
-
-\subsubsection{\aname{pgsqlauth}{Authentication}}
-\label{sec:pgsqlauth}
-\ind{PostgreSQL!authentication}
-
-The option value name may be misleading, as the \term{auth\_method} name is used
-for access to a relational database through ODBC, as well as through the native
-PostgreSQL interface. Anyway, the first configuration step is to define the odbc
-\term{auth\_method}. For example:
-\begin{verbatim}
-{host_config, "public.example.org", [{auth_method, [odbc]}]}.
-\end{verbatim}
-
-The actual database access is defined in the option \term{odbc\_server}. Its
-value is used to define if we want to use ODBC, or one of the two native
-interface available, PostgreSQL or MySQL.
-
-To use the native PostgreSQL interface, you can pass a tuple of the following
-form as parameter:
-\begin{verbatim}
-{pgsql, "Server", "Database", "Username", "Password"}
-\end{verbatim}
-
-\term{pgsql} is a keyword that should be kept as is. For example:
-\begin{verbatim}
-{odbc_server, {pgsql, "localhost", "database", "ejabberd", "password"}}.
-\end{verbatim}
-
-\subsubsection{\aname{pgsqlstorage}{Storage}}
-\label{sec:pgsqlstorage}
-\ind{PostgreSQL!storage}
-
-PostgreSQL also can be used to store information into from several \ejabberd{}
-modules. See section~\ref{sec:modoverview} to see which modules have a version
-with the `\_odbc'. This suffix indicates that the module can be used with
-relational databases like PostgreSQL. To enable storage to your database, just
-make sure that your database is running well (see previous sections), and
-replace the suffix-less or ldap module variant with the odbc module variant.
-Keep in mind that you cannot have several variants of the same module loaded!
-
-\subsection{\aname{odbc}{ODBC Compatible}}
-\label{sec:odbc}
-\ind{databases!ODBC}
-
-Although this section will describe \ejabberd{}'s configuration when you want to
-use the ODBC driver, it does not describe the installation and database creation
-of your database. Check the documentation of your database. The tutorial \footahref{http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver}{Using ejabberd with MySQL native driver} also can help you. Note that the tutorial
-contains information about \ejabberd{}'s configuration which is duplicate to
-this section.
-
-\subsubsection{\aname{compileodbc}{Compilation}}
-\label{sec:compileodbc}
-
-You can skip this step if you installed \ejabberd{} using a binary installer or
-if the binary packages of \ejabberd{} you are using include support for
-ODBC.
-
-\begin{enumerate}
-\item First, install the \footahref{http://support.process-one.net/doc/display/CONTRIBS/Yxa}{Erlang
- MySQL library}. Make sure the compiled files are in your Erlang path; you can
- put them for example in the same directory as your ejabberd .beam files.
-\item Then, configure, compile and install \ejabberd{} with ODBC support
- enabled. This can be done, by using next commands:
- \begin{verbatim}
-./configure --enable-odbc && make install
-\end{verbatim}
-\end{enumerate}
-
-\subsubsection{\aname{odbcauth}{Authentication}}
-\label{sec:odbcauth}
-\ind{ODBC!authentication}
-
-The first configuration step is to define the odbc \term{auth\_method}. For
-example:
-\begin{verbatim}
-{host_config, "public.example.org", [{auth_method, [odbc]}]}.
-\end{verbatim}
-
-The actual database access is defined in the option \term{odbc\_server}. Its
-value is used to defined if we want to use ODBC, or one of the two native
-interface available, PostgreSQL or MySQL.
-
-To use a relational database through ODBC, you can pass the ODBC connection
-string as \term{odbc\_server} parameter. For example:
-\begin{verbatim}
-{odbc_server, "DSN=database;UID=ejabberd;PWD=password"}.
-\end{verbatim}
-
-\subsubsection{\aname{odbcstorage}{Storage}}
-\label{sec:odbcstorage}
-\ind{ODBC!storage}
-
-An ODBC compatible database also can be used to store information into from
-several \ejabberd{} modules. See section~\ref{sec:modoverview} to see which
-modules have a version with the `\_odbc'. This suffix indicates that the module
-can be used with ODBC compatible relational databases. To enable storage to your
-database, just make sure that your database is running well (see previous
-sections), and replace the suffix-less or ldap module variant with the odbc
-module variant. Keep in mind that you cannot have several variants of the same
-module loaded!
-
-\subsection{\aname{ldap}{LDAP}}
-\label{sec:ldap}
-\ind{databases!LDAP}
-
-\ejabberd{} has built-in LDAP support. You can authenticate users against LDAP
-server and use LDAP directory as vCard storage. Shared rosters are not supported
-yet.
-
-\subsubsection{\aname{ldapconnection}{Connection}}
-\label{sec:ldapconnection}
-
-Parameters:
-\begin{description}
-\titem{ldap\_server} \ind{options!ldap\_server}IP address or dns name of your
-LDAP server. This option is required.
-\titem{ldap\_port} \ind{options!ldap\_port}Port to connect to your LDAP server.
- The default value is~389.
-\titem{ldap\_rootdn} \ind{options!ldap\_rootdn}Bind DN. The default value
- is~\term{""} which means `anonymous connection'.
-\titem{ldap\_password} \ind{options!ldap\_password}Bind password. The default
- value is \term{""}.
-\end{description}
-
-Example:
-\begin{verbatim}
- {auth_method, ldap}.
- {ldap_servers, ["ldap.example.org"]}.
- {ldap_port, 389}.
- {ldap_rootdn, "cn=Manager,dc=domain,dc=org"}.
- {ldap_password, "secret"}.
-\end{verbatim}
-
-Note that current LDAP implementation does not support SSL secured communication
-and SASL authentication.
-
-\subsubsection{\aname{ldapauth}{Authentication}}
-\label{sec:ldapauth}
-
-You can authenticate users against an LDAP directory. Available options are:
-
-\begin{description}
-\titem{ldap\_base}\ind{options!ldap\_base}LDAP base directory which stores users
- accounts. This option is required.
-\titem{ldap\_uidattr}\ind{options!ldap\_uidattr}LDAP attribute which holds
- the user's part of a JID. The default value is \term{"uid"}.
-\titem{ldap\_uidattr\_format}\ind{options!ldap\_uidattr\_format}Format of the
- \term{ldap\_uidattr} variable. The format \emph{must} contain one and only one
- pattern variable \term{"\%u"} which will be replaced by the user's part of a
- JID. For example, \term{"\%u@example.org"}. The default value is \term{"\%u"}.
-\titem{ldap\_filter}\ind{options!ldap\_filter}\ind{protocols!RFC 2254: The String Representation of LDAP Search Filters}
- \footahref{http://www.faqs.org/rfcs/rfc2254.html}{RFC 2254} LDAP filter. The
- default is \term{none}. Example:
- \term{"(\&(objectClass=shadowAccount)(memberOf=Jabber Users))"}. Please, do
- not forget to close brackets and do not use superfluous whitespaces. Also you
- \emph{must not} use \option{ldap\_uidattr} attribute in filter because this
- attribute will be substituted in LDAP filter automatically.
-\end{description}
-
-\subsubsection{\aname{ldapexamples}{Examples}}
-\label{sec:ldapexamples}
-
-\paragraph{\aname{ldapcommonexample}{Common example}}
-
-Let's say \term{ldap.example.org} is the name of our LDAP server. We have
-users with their passwords in \term{"ou=Users,dc=example,dc=org"} directory.
-Also we have addressbook, which contains users emails and their additional
-infos in \term{"ou=AddressBook,dc=example,dc=org"} directory. Corresponding
-authentication section should looks like this:
-
-\begin{verbatim}
- %% authentication method
- {auth_method, ldap}.
- %% DNS name of our LDAP server
- {ldap_servers, ["ldap.example.org"]}.
- %% Bind to LDAP server as "cn=Manager,dc=example,dc=org" with password "secret"
- {ldap_rootdn, "cn=Manager,dc=example,dc=org"}.
- {ldap_password, "secret"}.
- %% define the user's base
- {ldap_base, "ou=Users,dc=example,dc=org"}.
- %% We want to authorize users from 'shadowAccount' object class only
- {ldap_filter, "(objectClass=shadowAccount)"}.
-\end{verbatim}
-
-Now we want to use users LDAP-info as their vCards. We have four attributes
-defined in our LDAP schema: \term{"mail"} --- email address, \term{"givenName"}
---- first name, \term{"sn"} --- second name, \term{"birthDay"} --- birthday.
-Also we want users to search each other. Let's see how we can set it up:
-
-\begin{verbatim}
- {modules,
- ...
- {mod_vcard_ldap,
- [
- %% We use the same server and port, but want to bind anonymously because
- %% our LDAP server accepts anonymous requests to
- %% "ou=AddressBook,dc=example,dc=org" subtree.
- {ldap_rootdn, ""},
- {ldap_password, ""},
- %% define the addressbook's base
- {ldap_base, "ou=AddressBook,dc=example,dc=org"},
- %% user's part of JID is located in the "mail" attribute
- {ldap_uidattr, "mail"},
- %% common format for our emails
- {ldap_uidattr_format, "%u@mail.example.org"},
- %% We have to define empty filter here, because entries in addressbook does not
- %% belong to shadowAccount object class
- {ldap_filter, ""},
- %% Now we want to define vCard pattern
- {ldap_vcard_map,
- [{"NICKNAME", "%u", []}, % just use user's part of JID as his nickname
- {"GIVEN", "%s", ["givenName"]},
- {"FAMILY", "%s", ["sn"]},
- {"FN", "%s, %s", ["sn", "givenName"]}, % example: "Smith, John"
- {"EMAIL", "%s", ["mail"]},
- {"BDAY", "%s", ["birthDay"]}]},
- %% Search form
- {ldap_search_fields,
- [{"User", "%u"},
- {"Name", "givenName"},
- {"Family Name", "sn"},
- {"Email", "mail"},
- {"Birthday", "birthDay"}]},
- %% vCard fields to be reported
- %% Note that JID is always returned with search results
- {ldap_search_reported,
- [{"Full Name", "FN"},
- {"Nickname", "NICKNAME"},
- {"Birthday", "BDAY"}]}
- ]}
- ...
- }.
-\end{verbatim}
-
-Note that \modvcardldap{} module checks for the existence of the user before
-searching in his information in LDAP.
-
-
-\paragraph{\aname{ad}{Active Directory}}
-\label{sec:ad}
-\ind{databases!Active Directory}
-
-Active Directory is just an LDAP-server with predefined attributes. A sample
-configuration is showed below:
-
-\begin{verbatim}
- {auth_method, ldap}.
- {ldap_servers, ["office.org"]}. % List of LDAP servers
- {ldap_base, "DC=office,DC=org"}. % Search base of LDAP directory
- {ldap_rootdn, "CN=Administrator,CN=Users,DC=office,DC=org"}. % LDAP manager
- {ldap_password, "*******"}. % Password to LDAP manager
- {ldap_uidattr, "sAMAccountName"}.
- {ldap_filter, "(memberOf=*)"}.
-
- {mod_vcard_ldap,
- [{ldap_vcard_map,
- [{"NICKNAME", "%u", []},
- {"GIVEN", "%s", ["givenName"]},
- {"MIDDLE", "%s", ["initials"]},
- {"FAMILY", "%s", ["sn"]},
- {"FN", "%s", ["displayName"]},
- {"EMAIL", "%s", ["mail"]},
- {"ORGNAME", "%s", ["company"]},
- {"ORGUNIT", "%s", ["department"]},
- {"CTRY", "%s", ["c"]},
- {"LOCALITY", "%s", ["l"]},
- {"STREET", "%s", ["streetAddress"]},
- {"REGION", "%s", ["st"]},
- {"PCODE", "%s", ["postalCode"]},
- {"TITLE", "%s", ["title"]},
- {"URL", "%s", ["wWWHomePage"]},
- {"DESC", "%s", ["description"]},
- {"TEL", "%s", ["telephoneNumber"]}]},
- {ldap_search_fields,
- [{"User", "%u"},
- {"Name", "givenName"},
- {"Family Name", "sn"},
- {"Email", "mail"},
- {"Company", "company"},
- {"Department", "department"},
- {"Role", "title"},
- {"Description", "description"},
- {"Phone", "telephoneNumber"}]},
- {ldap_search_reported,
- [{"Full Name", "FN"},
- {"Nickname", "NICKNAME"},
- {"Email", "EMAIL"}]}
- ]
- }.
-\end{verbatim}
-
-
-\section{\aname{modules}{Modules Configuration}}
-\label{sec:modules}
-\ind{modules}
-
-The option \term{modules} defines the list of modules that will be loaded after
-\ejabberd{}'s startup. Each entry in the list is a tuple in which the first
-element is the name of a module and the second is a list of options for that
-module.
-
-Examples:
-\begin{itemize}
-\item In this example only the module \modecho{} is loaded and no module
- options are specified between the square brackets:
- \begin{verbatim}
- {modules,
- [{mod_echo, []}
- ]}.
-\end{verbatim}
-\item In the second example the modules \modecho{}, \modtime{}, and
- \modversion{} are loaded without options. Remark that, besides the last entry,
- all entries end with a comma:
- \begin{verbatim}
- {modules,
- [{mod_echo, []},
- {mod_time, []},
- {mod_version, []}
- ]}.
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{modoverview}{Overview}}
-\label{sec:modoverview}
-\ind{modules!overview}\ind{XMPP compliancy}
-
-The following table lists all modules available in the official \ejabberd{}
-distribution. You can find more
-\footahref{http://ejabberd.jabber.ru/contributions}{contributed modules} on the
-\ejabberd{} website. Please remember that these contributions might not work or
-that they can contain severe bugs and security leaks. Therefore, use them at
-your own risk!
-
-You can see which database backend each module needs by looking at the suffix:
-\begin{itemize}
-\item `\_ldap', this means that the module needs an LDAP server as backend.
-\item `\_odbc', this means that the module needs a supported database
- (see~\ref{sec:database}) as backend.
-\item No suffix, this means that the modules uses Erlang's built-in database
- Mnesia as backend.
-\end{itemize}
-
-If you want to
-It is possible to use a relational database to store pieces of
-information. You can do this by changing the module name to a name with an
-\term{\_odbc} suffix in \ejabberd{} config file. You can use a relational
-database for the following data:
-
-\begin{itemize}
-\item Last connection date and time: Use \term{mod\_last\_odbc} instead of
- \term{mod\_last}.
-\item Offline messages: Use \term{mod\_offline\_odbc} instead of
- \term{mod\_offline}.
-\item Rosters: Use \term{mod\_roster\_odbc} instead of \term{mod\_roster}.
-\item Users' VCARD: Use \term{mod\_vcard\_odbc} instead of \term{mod\_vcard}.
-\end{itemize}
-
-
-\begin{table}[H]
- \centering
- \begin{tabular}{|l|l|l|l|}
- \hline Module & Feature & Dependencies & Needed for XMPP? \\
- \hline \hline \modadhoc{} & Ad-Hoc Commands (\jepref{0050}) & & No \\
- \hline \modannounce{} & Manage announcements & \modadhoc{} & No \\
- \hline \modconfigure{} & Support for online & \modadhoc{} & No \\
- & configuration of \ejabberd{} & & \\
- \hline \moddisco{} & Service Discovery (\jepref{0030}) & & No \\
- \hline \modecho{} & Echoes Jabber packets & & No \\
- \hline \modirc{} & IRC transport & & No \\
- \hline \modlast{} & Last Activity (\jepref{0012}) & & No \\
- \hline \modlastodbc{} & Last Activity (\jepref{0012}) & supported database (*) & No \\
- \hline \modmuc{} & Multi-User Chat (\jepref{0045}) & & No \\
- \hline \modmuclog{} & Multi-User Chat room logging & \modmuc{} & No \\
- \hline \modoffline{} & Offline message storage & & No \\
- \hline \modofflineodbc{} & Offline message storage & supported database (*) & No \\
- \hline \modprivacy{} & Blocking Communication & & Yes \\
- \hline \modprivate{} & Private XML Storage (\jepref{0049}) & & No \\
- \hline \modpubsub{} & Publish-Subscribe (\jepref{0060}) & & No \\
- \hline \modregister{} & In-Band Registration (\jepref{0077}) & & No \\
- \hline \modroster{} & Roster management & & Yes (**) \\
- \hline \modrosterodbc{} & Roster management & supported database (*) & Yes (**) \\
- \hline \modservicelog{} & Copy user messages to logger service & & No \\
- \hline \modsharedroster{} & Shared roster management & \modroster{} or & No \\
- & & \modrosterodbc{} & \\
- \hline \modstats{} & Statistics Gathering (\jepref{0039}) & & No \\
- \hline \modtime{} & Entity Time (\jepref{0090}) & & No \\
- \hline \modvcard{} & vcard-temp (\jepref{0054}) & & No \\
- \hline \modvcardldap{} & vcard-temp (\jepref{0054}) & LDAP server & No \\
- \hline \modvcardodbc{} & vcard-temp (\jepref{0054}) & supported database (*) & No \\
- \hline \modversion{} & Software Version (\jepref{0092}) & & No\\
- \hline
- \end{tabular}
-\end{table}
-
-\begin{itemize}
-\item (*) For a list of supported databases, see section~\ref{sec:database}.
-\item (**) This module or a similar one with another database backend is needed for
-XMPP compliancy.
-\end{itemize}
-
-\subsection{\aname{modcommonoptions}{Common Options}}
-\label{sec:modcommonoptions}
-
-The following options are used by many modules. Therefore, they are described in
-this separate section.
-
-\subsubsection{\option{\aname{modiqdiscoption}{iqdisc}}}
-\label{sec:modiqdiscoption}
-\ind{options!iqdisc}
-
-Many modules define handlers for processing IQ queries of different namespaces
-to this server or to a user (e.\,g.\ to \jid{example.org} or to
-\jid{user@example.org}). This option defines processing discipline for
-these queries. Possible values are:
-\begin{description}
-\titem{no\_queue} All queries of a namespace with this processing discipline are
- processed immediately. This also means that no other packets can be processed
- until this one has been completely processed. Hence this discipline is not
- recommended if the processing of a query can take a relatively long time.
-\titem{one\_queue} In this case a separate queue is created for the processing
- of IQ queries of a namespace with this discipline. In addition, the processing
- of this queue is done in parallel with that of other packets. This discipline
- is most recommended.
-\titem{parallel} For every packet with this discipline a separate Erlang process
- is spawned. Consequently, all these packets are processed in parallel.
- Although spawning of Erlang process has a relatively low cost, this can break
- the server's normal work, because the Erlang emulator has a limit on the
- number of processes (32000 by default).
-\end{description}
-
-Example:
-\begin{verbatim}
- {modules,
- [
- ...
- {mod_time, [{iqdisc, no_queue}]},
- ...
- ]}.
-\end{verbatim}
-
-\subsubsection{\option{\aname{modhostsoption}{hosts}}}
-\label{sec:modhostsoption}
-\ind{options!hosts}
-
-A module acting as a service can have one or more hostnames. These hostnames
-can be defined with the \option{hosts} option.
-
-Examples:
-\begin{itemize}
-\item Serving the \ind{modules!\modecho{}}echo module on one domain:
- \begin{itemize}
- \item
- \begin{verbatim}
- {modules,
- [
- ...
- {mod_echo, [{hosts, ["echo.example.org"]}]},
- ...
- ]}.
-\end{verbatim}
- \item Backwards compatibility with older \ejabberd{} versions can be retained
- with:
- \begin{verbatim}
- {modules,
- [
- ...
- {mod_echo, [{host, "echo.example.org"}]},
- ...
- ]}.
-\end{verbatim}
- \end{itemize}
- \item Serving the echo module on two domains:
- \begin{verbatim}
- {modules,
- [
- ...
- {mod_echo, [{hosts, ["echo.example.net", "echo.example.com"]}]},
- ...
- ]}.
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{modannounce}{\modannounce{}}}
-\label{sec:modannounce}
-\ind{modules!\modannounce{}}\ind{MOTD}\ind{message of the day}\ind{announcements}
-
-This module enables configured users to broadcast announcements and to set
-the message of the day (MOTD). Configured users can do these actions with their
-\Jabber{} client by sending messages to specific JIDs. These JIDs are listed in
-next paragraph. The first JID in each entry will apply only to the virtual host
-\jid{example.org}, while the JID between brackets will apply to all virtual
-hosts:
-\begin{description}
-\titem{example.org/announce/all (example.org/announce/all-hosts/all)} The
- message is sent to all registered users. If the user is online and connected
- to several resources, only the resource with the highest priority will receive
- the message. If the registered user is not connected, the message will be
- stored offline in assumption that \ind{modules!\modoffline{}}offline storage
- (see section~\ref{sec:modoffline}) is enabled.
-\titem{example.org/announce/online (example.org/announce/all-hosts/online)}The
- message is sent to all connected users. If the user is online and connected
- to several resources, all resources will receive the message.
-\titem{example.org/announce/motd (example.org/announce/all-hosts/motd)}The
- message is set as the message of the day (MOTD) and is sent to users when they
- login. In addition the message is sent to all connected users (similar to
- \term{announce/online}).
-\titem{example.org/announce/motd/update (example.org/announce/all-hosts/motd/update)}
- The message is set as message of the day (MOTD) and is sent to users when they
- login. The message is \emph{not sent} to any currently connected user.
-\titem{example.org/announce/motd/delete (example.org/announce/all-hosts/motd/delete)}
- Any message sent to this JID removes the existing message of the day (MOTD).
-\end{description}
-
-Options:
-\begin{description}
-\titem{access} \ind{options!access}This option specifies who is allowed to
- send announcements and to set the message of the day (by default, nobody is
- able to send such messages).
-\end{description}
-
-Examples:
-\begin{itemize}
-\item Only administrators can send announcements:
- \begin{verbatim}
- {access, announce, [{allow, admins}]}.
-
- {modules,
- [
- ...
- {mod_announce, [{access, announce}]},
- ...
- ]}.
-\end{verbatim}
-\item Administrators as well as the direction can send announcements:
- \begin{verbatim}
- {acl, direction, {user, "big_boss", "example.org"}}.
- {acl, direction, {user, "assistant", "example.org"}}.
- {acl, admins, {user, "admin", "example.org"}}.
- ...
- {access, announce, [{allow, admins},
- {allow, direction}]}.
- ...
- {modules,
- [
- ...
- {mod_announce, [{access, announce}]},
- ...
- ]}.
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{moddisco}{\moddisco{}}}
-\label{sec:moddisco}
-\ind{modules!\moddisco{}}\ind{protocols!JEP-0030: Service Discovery}\ind{protocols!JEP-0011: Jabber Browsing}\ind{protocols!JEP-0094: Agent Information}
-
-This module adds support for Service Discovery (\jepref{0030}). With
-this module enabled, services on your server can be discovered by
-\Jabber{} clients. Note that \ejabberd{} has no modules with support
-for the superseded Jabber Browsing (\jepref{0011}) and Agent Information
-(\jepref{0094}). Accordingly, \Jabber{} clients need to have support for
-the newer Service Discovery protocol if you want them be able to discover
-the services you offer.
-
-Options:
-\begin{description}
-\iqdiscitem{Service Discovery (\ns{http://jabber.org/protocol/disco\#items} and
- \ns{http://jabber.org/protocol/disco\#info})}
-\titem{extra\_domains} \ind{options!extra\_domains}With this option,
- extra domains can be added to the Service Discovery item list.
-\end{description}
-
-Examples:
-\begin{itemize}
-\item To serve a link to the Jabber User Directory on \jid{jabber.org}:
- \begin{verbatim}
- {modules,
- [
- ...
- {mod_disco, [{extra_domains, ["users.jabber.org"]}]},
- ...
- ]}.
-\end{verbatim}
-\item To serve a link to the transports on another server:
- \begin{verbatim}
- {modules,
- [
- ...
- {mod_disco, [{extra_domains, ["icq.example.com",
- "msn.example.com"]}]},
- ...
- ]}.
-\end{verbatim}
-\item To serve a link to a few friendly servers:
- \begin{verbatim}
- {modules,
- [
- ...
- {mod_disco, [{extra_domains, ["example.org",
- "example.com"]}]},
- ...
- ]}.
-\end{verbatim}
-\end{itemize}
-
-
-\subsection{\aname{modecho}{\modecho{}}}
-\label{sec:modecho}
-\ind{modules!\modecho{}}\ind{debugging}
-
-This module simply echoes any \Jabber{}
-packet back to the sender. This mirror can be of interest for
-\ejabberd{} and \Jabber{} client debugging.
-
-Options:
-\begin{description}
-\hostitem{echo}
-\end{description}
-
-Examples:
-\begin{itemize}
-\item Mirror, mirror, on the wall, who is the most beautiful
- of them all?
- \begin{verbatim}
- {modules,
- [
- ...
- {mod_echo, [{hosts, ["mirror.example.org"]}]},
- ...
- ]}.
-\end{verbatim}
-\item If you still do not understand the inner workings of \modecho{},
- you can find a few more examples in section~\ref{sec:modhostsoption}.
-\end{itemize}
-
-\subsection{\aname{modirc}{\modirc{}}}
-\label{sec: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!JEP-0045: Multi-User Chat}
-\begin{itemize}
-\item A \Jabber{} client with `groupchat 1.0' support or Multi-User
- Chat support (\jepref{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}).
-\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.
- \begin{verbatim}
- {modules,
- [
- ...
- {mod_irc, [{access, all}]},
- ...
- ]}.
-\end{verbatim}
-%TODO: bug in current svn!: irc-transport.example.com will *not* show up in the
-% service discovery items; instead you will see irc.example.com
-\item In next example the IRC transport is available on the two virtual hosts
- \jid{example.net} and \jid{example.com} with different prefixes on each host.
- Moreover, the transport is only accessible by paying customers registered on
- our domains and on other servers.
- \begin{verbatim}
- {acl, paying_customers, {user, "customer1", "example.net"}}.
- {acl, paying_customers, {user, "customer2", "example.com"}}.
- {acl, paying_customers, {user, "customer3", "example.org"}}.
- ...
- {access, paying_customers, [{allow, paying_customers},
- {deny, all}]}.
- ...
- {modules,
- [
- ...
- {mod_irc, [{access, paying_customers},
- {hosts, ["irc.example.net", "irc-transport.example.com"]}]},
- ...
- ]}.
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{modlast}{\modlast{}}}
-\label{sec:modlast}
-\ind{modules!\modlast{}}\ind{protocols!JEP-0012: Last Activity}
-
-This module adds support for Last Activity (\jepref{0012}). It can be used to
-discover when a disconnected user last accessed the server, to know when a
-connected user was last active on the server, or to query the uptime of the
-\ejabberd{} server.
-
-Options:
-\begin{description}
-\iqdiscitem{Last activity (\ns{jabber:iq:last})}
-\end{description}
-
-\subsection{\aname{modmuc}{\modmuc{}}}
-\label{sec:modmuc}
-\ind{modules!\modmuc{}}\ind{protocols!JEP-0045: Multi-User Chat}\ind{conferencing}
-
-With this module enabled, your server will support Multi-User Chat
-(\jepref{0045}). End users will be able to join text conferences. Notice
-that this module is not (yet) clusterable.
-
-
-Some of the features of Multi-User Chat:
-\begin{itemize}
-\item Sending private messages to room participants.
-\item Inviting users.
-\item Setting a conference topic.
-\item Creating password protected rooms.
-\item Kicking and banning participants.
-\end{itemize}
-
-Options:
-\begin{description}
-\hostitem{conference}
-\titem{access} \ind{options!access}You can specify who is allowed to use
- the Multi-User Chat service (by default, everyone is allowed to use it).
-\titem{access\_create} \ind{options!access\_create}To configure who is
- allowed to create new rooms at the Multi-User Chat service, this option
- can be used (by default, everybody is allowed to create rooms).
-\titem{access\_admin} \ind{options!access\_admin}This option specifies
- who is allowed to administrate the Multi-User Chat service (the default
- value is \term{none}, which means that only the room creator can
- administer his room). By sending a message to the service JID,
- administrators can send service messages that will be displayed in every
- active room.
-\titem{history\_size} \ind{options!history\_size}A small history of the
- current discussion is sent to users when they enter the room. With this option
- you can define the number of history messages to keep and send to users
- joining the room. The value is an integer. Setting the value to \term{0}
- disables the history feature and, as a result, nothing is kept in memory. The
- default value is \term{20}. This value is global and thus affects all rooms on
- the server.
-\end{description}
-
-Examples:
-\begin{itemize}
-\item In the first example everyone is allowed to use the Multi-User Chat
- service. Everyone will also be able to create new rooms but only the user
- \jid{admin@example.org} is allowed to administrate any room. In this
- example he is also a global administrator. When \jid{admin@example.org}
- sends a message such as `Tomorrow, the \Jabber{} server will be moved
- to new hardware. This will involve service breakdowns around 23:00 UMT.
- We apologise for this inconvenience.' to \jid{conference.example.org},
- it will be displayed in all active rooms. In this example the history
- feature is disabled.
- \begin{verbatim}
- {acl, admins, {user, "admin", "example.org"}}.
- ...
- {access, muc_admins, [{allow, admins}]}.
- ...
- {modules,
- [
- ...
- {mod_muc, [{access, all},
- {access_create, all},
- {access_admin, muc_admins},
- {history_size, 0}]},
- ...
- ]}.
-\end{verbatim}
-\item In the second example the Multi-User Chat service is only accessible by
- paying customers registered on our domains and on other servers. Of course
- the administrator is also allowed to access rooms. In addition, he is the
- only authority able to create and administer rooms. When
- \jid{admin@example.org} sends a message such as `Tomorrow, the \Jabber{}
- server will be moved to new hardware. This will involve service breakdowns
- around 23:00 UMT. We apologise for this inconvenience.' to
- \jid{conference.example.org}, it will be displayed in all active rooms. No
- \term{history\_size} option is used, this means that the feature is enabled
- and the default value of 20 history messages will be send to the users.
- \begin{verbatim}
- {acl, paying_customers, {user, "customer1", "example.net"}}.
- {acl, paying_customers, {user, "customer2", "example.com"}}.
- {acl, paying_customers, {user, "customer3", "example.org"}}.
- {acl, admins, {user, "admin", "example.org"}}.
- ...
- {access, muc_admins, [{allow, admins},
- {deny, all}]}.
- {access, muc_access, [{allow, paying_customers},
- {allow, admins},
- {deny, all}]}.
- ...
- {modules,
- [
- ...
- {mod_muc, [{access, muc_access},
- {access_create, muc_admins},
- {access_admin, muc_admins}]},
- ...
- ]}.
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{modmuclog}{\modmuclog{}}}
-\label{sec:modmuclog}
-\ind{modules!\modmuclog{}}
-
-This module enables optional logging of Multi-User Chat (MUC) conversations to
-HTML. Once you enable this module, users can join a chatroom using a MUC capable
-Jabber client, and if they have enough privileges, they can request the
-configuration form in which they can set the option to enable chatroom logging.
-
-Features:
-\begin{itemize}
-\item Chatroom details are added on top of each page: room title, JID,
- author, subject and configuration.
-\item \ind{protocols!RFC 4622: Internationalized Resource Identifiers (IRIs) and Uniform Resource Identifiers (URIs) for the Extensible Messaging and Presence Protocol (XMPP)}
- Room title and JID are links to join the chatroom (using
- \footahref{http://www.ietf.org/rfc/rfc4622.txt}{XMPP URIs}).
-\item Subject and chatroom configuration changes are tracked and displayed.
-\item Joins, leaves, nick changes, kicks, bans and `/me' are tracked and
- displayed, including the reason if available.
-\item Generated HTML files are XHTML 1.0 Transitional and CSS compliant.
-\item Timestamps are self-referencing links.
-\item Links on top for quicker navigation: Previous day, Next day, Up.
-\item CSS is used for style definition, and a custom CSS file can be used.
-\item URLs on messages and subjects are converted to hyperlinks.
-\item Timezone used on timestamps is shown on the log files.
-\item A custom link can be added on top of each page.
-\end{itemize}
-
-Options:
-\begin{description}
-\titem{access\_log}\ind{options!access\_log}
- This option restricts which users are allowed to enable or disable chatroom
- logging. The default value is \term{muc\_admin}. Note for this default setting
- you need to have an access rule for \term{muc\_admin} in order to take effect.
-\titem{cssfile}\ind{options!cssfile}
- With this option you can set whether the HTML files should have a custom CSS
- file or if they need to use the embedded CSS file. Allowed values are
- \term{false} and an URL to a CSS file. With the first value, HTML files will
- include the embedded CSS code. With the latter, you can specify the URL of the
- custom CSS file (for example: `http://example.com/my.css'). The default value
- is \term{false}.
-\titem{dirtype}\ind{options!dirtype}
- The type of the created directories can be specified with this option. Allowed
- values are \term{subdirs} and \term{plain}. With the first value,
- subdirectories are created for each year and month. With the latter, the
- names of the log files contain the full date, and there are no subdirectories.
- The default value is \term{subdirs}.
-\titem{outdir}\ind{options!outdir}
- This option sets the full path to the directory in which the HTML files should
- be stored. Make sure the \ejabberd{} daemon user has write access on that
- directory. The default value is \term{"www/muc"}.
-\titem{timezone}\ind{options!timezone}
- The time zone for the logs is configurable with this option. Allowed values
- are \term{local} and \term{universal}. With the first value, the local time,
- as reported to Erlang by the operating system, will be used. With the latter,
- GMT/UTC time will be used. The default value is \term{local}.
-\titem{top\_link}\ind{options!top\_link}
- With this option you can customize the link on the top right corner of each
- log file. The syntax of this option is \term{\{"URL", "Text"\}}. The default
- value is \term{\{"/", "Home"\}}.
-\end{description}
-
-Examples:
-\begin{itemize}
-\item In the first example any chatroom owner can enable logging, and a
- custom CSS file will be used (http://example.com/my.css). Further, the names
- of the log files will contain the full date, and there will be no
- subdirectories. The log files will be stored in /var/www/muclogs, and the
- time zone will be GMT/UTC. Finally, the top link will be
- \verb|<a href="http://www.jabber.ru">Jabber.ru</a>|.
- \begin{verbatim}
- {access, muc, [{allow, all}]}.
- ...
- {modules,
- [
- ...
- {mod_muc_log, [
- {access_log, muc},
- {cssfile, "http://example.com/my.css"},
- {dirtype, plain},
- {outdir, "/var/www/muclogs"},
- {timezone, universal},
- {top_link, {"http://www.jabber.ru", "Jabber.ru"}}
- ]},
- ...
- ]}.
-\end{verbatim}
- \item In the second example only \jid{admin1@example.org} and
- \jid{admin2@example.net} can enable logging, and the embedded CSS file will be
- used. Further, the names of the log files will only contain the day (number),
- and there will be subdirectories for each year and month. The log files will
- be stored in /var/www/muclogs, and the local time will be used. Finally, the
- top link will be the default \verb|<a href="/">Home</a>|.
- \begin{verbatim}
- {acl, admins, {user, "admin1", "example.org"}}.
- {acl, admins, {user, "admin2", "example.net"}}.
- ...
- {access, muc_log, [{allow, admins},
- {deny, all}]}.
- ...
- {modules,
- [
- ...
- {mod_muc_log, [
- {access_log, muc_log},
- {cssfile, false},
- {dirtype, subdirs},
- {outdir, "/var/www/muclogs"},
- {timezone, local}
- ]},
- ...
- ]}.
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{modoffline}{\modoffline{}}}
-\label{sec:modoffline}
-\ind{modules!\modoffline{}}
-
-This module implements offline message storage. This means that all messages
-sent to an offline user will be stored on the server until that user comes
-online again. Thus it is very similar to how email works. Note that
-\term{ejabberdctl}\ind{ejabberdctl} has a command to delete expired messages
-(see section~\ref{sec:ejabberdctl}).
-
-\subsection{\aname{modprivacy}{\modprivacy{}}}
-\label{sec:modprivacy}
-\ind{modules!\modprivacy{}}\ind{Blocking Communication}\ind{Privacy Rules}\ind{protocols!RFC 3921: XMPP IM}
-
-This module implements Blocking Communication (also known as Privacy Rules)
-as defined in section 10 from XMPP IM. If end users have support for it in
-their \Jabber{} client, they will be able to:
-\begin{quote}
-\begin{itemize}
-\item Retrieving one's privacy lists.
-\item Adding, removing, and editing one's privacy lists.
-\item Setting, changing, or declining active lists.
-\item Setting, changing, or declining the default list (i.e., the list that
- is active by default).
-\item Allowing or blocking messages based on JID, group, or subscription type
- (or globally).
-\item Allowing or blocking inbound presence notifications based on JID, group,
- or subscription type (or globally).
-\item Allowing or blocking outbound presence notifications based on JID, group,
- or subscription type (or globally).
-\item Allowing or blocking IQ stanzas based on JID, group, or subscription type
- (or globally).
-\item Allowing or blocking all communications based on JID, group, or
- subscription type (or globally).
-\end{itemize}
-(from \ahrefurl{http://www.xmpp.org/specs/rfc3921.html\#privacy})
-\end{quote}
-
-Options:
-\begin{description}
-\iqdiscitem{Blocking Communication (\ns{jabber:iq:privacy})}
-\end{description}
-
-\subsection{\aname{modprivate}{\modprivate{}}}
-\label{sec:modprivate}
-\ind{modules!\modprivate{}}\ind{protocols!JEP-0049: Private XML Storage}\ind{protocols!JEP-0048: Bookmark Storage}
-
-This module adds support for Private XML Storage (\jepref{0049}):
-\begin{quote}
-Using this method, Jabber entities can store private data on the server and
-retrieve it whenever necessary. The data stored might be anything, as long as
-it is valid XML. One typical usage for this namespace is the server-side storage
-of client-specific preferences; another is Bookmark Storage (\jepref{0048}).
-\end{quote}
-
-Options:
-\begin{description}
-\iqdiscitem{Private XML Storage (\ns{jabber:iq:private})}
-\end{description}
-
-\subsection{\aname{modpubsub}{\modpubsub{}}}
-\label{sec:modpubsub}
-\ind{modules!\modpubsub{}}\ind{protocols!JEP-0060: Publish-Subscribe}
-
-This module offers a Publish-Subscribe Service (\jepref{0060}).
-Publish-Subscribe can be used to develop (examples are taken from the JEP):
-\begin{quote}
-\begin{itemize}
-\item news feeds and content syndacation,
-\item avatar management,
-\item shared bookmarks,
-\item auction and trading systems,
-\item online catalogs,
-\item workflow systems,
-\item network management systems,
-\item NNTP gateways,
-\item vCard/profile management,
-\item and weblogs.
-\end{itemize}
-\end{quote}
-
-\ind{J-EAI}\ind{EAI}\ind{ESB}\ind{Enterprise Application Integration}\ind{Enterprise Service Bus}
-Another example is \footahref{http://www.process-one.net/en/projects/j-eai/}{J-EAI}.
-This is an XMPP-based Enterprise Application Integration (EAI) platform (also
-known as ESB, the Enterprise Service Bus). The J-EAI project builts upon
-\ejabberd{}'s codebase and has contributed several features to \modpubsub{}.
-
-Options:
-\begin{description}
-\hostitem{pubsub}
-\titem{served\_hosts} \ind{options!served\_hosts}To specify which hosts needs to
- be served, you can use this option. If absent, only the main \ejabberd{}
- host is served. % Not a straigtforward description! This needs to be improved!
-\titem{access\_createnode} \ind{options!access\_createnode}
- This option restricts which users are allowed to create pubsub nodes using
- ACL and ACCESS. The default value is \term{pubsub\_createnode}. % Not clear enough + do not use abbreviations.
-\end{description}
-
-Example:
-\begin{verbatim}
- {modules,
- [
- ...
- {mod_pubsub, [{served_hosts, ["example.com",
- "example.org"]},
- {access_createnode, pubsub_createnode}]}
- ...
- ]}.
-\end{verbatim}
-
-\subsection{\aname{modregister}{\modregister{}}}
-\label{sec:modregister}
-\ind{modules!\modregister{}}\ind{protocols!JEP-0077: In-Band Registration}\ind{public registration}
-
-This module adds support for In-Band Registration (\jepref{0077}). This protocol
-enables end users to use a \Jabber{} client to:
-\begin{itemize}
-\item Register a new account on the server.
-\item Change the password from an existing account on the server.
-\item Delete an existing account on the server.
-\end{itemize}
-
-
-Options:
-\begin{description}
-\titem{access} \ind{options!access}This option can be configured to specify
- rules to restrict registration. If a rule returns `deny' on the requested
- user name, registration for that user name is dennied. (there are no
- restrictions by default).
-\iqdiscitem{In-Band Registration (\ns{jabber:iq:register})}
-\end{description}
-
-Examples:
-\begin{itemize}
-\item Next example prohibits the registration of too short account names:
-\begin{verbatim}
- {acl, shortname, {user_glob, "?"}}.
- {acl, shortname, {user_glob, "??"}}.
- % The same using regexp:
- %{acl, shortname, {user_regexp, "^..?$"}}.
- ...
- {access, register, [{deny, shortname},
- {allow, all}]}.
- ...
- {modules,
- [
- ...
- {mod_register, [{access, register}]},
- ...
- ]}.
-\end{verbatim}
-\item The in-band registration of new accounts can be prohibited by changing the
- \option{access} option. If you really want to disable all In-Band Registration
- functionality, that is changing passwords in-band and deleting accounts
- in-band, you have to remove \modregister{} from the modules list. In this
- example all In-Band Registration functionality is disabled:
- \begin{verbatim}
- {access, register, [{deny, all}]}.
-
- {modules,
- [
- ...
-% {mod_register, [{access, register}]},
- ...
- ]}.
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{modroster}{\modroster{}}}
-\label{sec:modroster}
-\ind{modules!\modroster{}}\ind{roster management}\ind{protocols!RFC 3921: XMPP IM}
-
-This module implements roster management as defined in \footahref{http://www.xmpp.org/specs/rfc3921.html\#roster}{RFC 3921: XMPP IM}.
-
-Options:
-\begin{description}
-\iqdiscitem{Roster Management (\ns{jabber:iq:roster})}
-\end{description}
-
-\subsection{\aname{modservicelog}{\modservicelog{}}}
-\label{sec:modservicelog}
-\ind{modules!\modservicelog{}}\ind{message auditing}\ind{Bandersnatch}
-
-This module adds support for logging end user packets via a \Jabber{} message
-auditing service such as
-\footahref{http://www.funkypenguin.co.za/bandersnatch/}{Bandersnatch}. All user
-packets are encapsulated in a \verb|<route/>| element and sent to the specified
-service(s).
-
-Options:
-\begin{description}
-\titem{loggers} \ind{options!loggers}With this option a (list of) service(s)
- that will receive the packets can be specified.
-\end{description}
-
-Examples:
-\begin{itemize}
-\item To log all end user packets to the Bandersnatch service running on
- \jid{bandersnatch.example.com}:
- \begin{verbatim}
- {modules,
- [
- ...
- {mod_service_log, [{loggers, ["bandersnatch.example.com"]}]},
- ...
- ]}.
-\end{verbatim}
-\item To log all end user packets to the Bandersnatch service running on
- \jid{bandersnatch.example.com} and the backup service on
- \jid{bandersnatch.example.org}:
- \begin{verbatim}
- {modules,
- [
- ...
- {mod_service_log, [{loggers, ["bandersnatch.example.com",
- "bandersnatch.example.org"]}]},
- ...
- ]}.
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{modsharedroster}{\modsharedroster{}}}
-\label{sec:modsharedroster}
-\ind{modules!\modsharedroster{}}\ind{shared roster groups}
-
-This module enables you to create shared roster groups. This means that you can
-create groups of people that can see members from (other) groups in their
-rosters. The big advantages of this feature are that end users do not need to
-manually add all users to their rosters, and that they cannot permanently delete
-users from the shared roster groups.
-
-Shared roster groups can be edited \emph{only} via the web interface. Each group
-has a unique identification and the following parameters:
-\begin{description}
-\item[Name] The name of the group, which will be displayed in the roster.
-\item[Description] The description of the group. This parameter does not affect
- anything.
-\item[Members] A list of full JIDs of group members, entered one per line in
- the web interface.
-\item[Displayed groups] A list of groups that will be in the rosters of this
- group's members.
-\end{description}
-
-Examples:
-\begin{itemize}
-\item Take the case of a computer club that wants all its members seeing each
- other in their rosters. To achieve this, they need to create a shared roster
- group similar to next table:
-\begin{table}[H]
- \centering
- \begin{tabular}{|l|l|}
- \hline Identification& Group `\texttt{club\_members}'\\
- \hline Name& Club Members\\
- \hline Description& Members from the computer club\\
- \hline Members&
- {\begin{tabular}{l}
- \jid{member1@example.org}\\
- \jid{member2@example.org}\\
- \jid{member3@example.org}
- \end{tabular}
- }\\
- \hline Displayed groups& \texttt{club\_members}\\
- \hline
- \end{tabular}
-\end{table}
-\item In another case we have a company which has three divisions: Management,
- Marketing and Sales. All group members should see all other members in their
- rosters. Additonally, all managers should have all marketing and sales people
- in their roster. Simultaneously, all marketeers and the whole sales team
- should see all managers. This scenario can be achieved by creating shared
- roster groups as shown in the following table:
-\begin{table}[H]
- \centering
- \begin{tabular}{|l|l|l|l|}
- \hline Identification&
- Group `\texttt{management}'&
- Group `\texttt{marketing}'&
- Group `\texttt{sales}'\\
- \hline Name& Management& Marketing& Sales\\
- \hline Description& \\
- Members&
- {\begin{tabular}{l}
- \jid{manager1@example.org}\\
- \jid{manager2@example.org}\\
- \jid{manager3@example.org}\\
- \jid{manager4@example.org}
- \end{tabular}
- }&
- {\begin{tabular}{l}
- \jid{marketeer1@example.org}\\
- \jid{marketeer2@example.org}\\
- \jid{marketeer3@example.org}\\
- \jid{marketeer4@example.org}
- \end{tabular}
- }&
- {\begin{tabular}{l}
- \jid{saleswoman1@example.org}\\
- \jid{salesman1@example.org}\\
- \jid{saleswoman2@example.org}\\
- \jid{salesman2@example.org}
- \end{tabular}
- }\\
- \hline Displayed groups&
- {\begin{tabular}{l}
- \texttt{management}\\
- \texttt{marketing}\\
- \texttt{sales}
- \end{tabular}
- }&
- {\begin{tabular}{l}
- \texttt{management}\\
- \texttt{marketing}
- \end{tabular}
- }&
- {\begin{tabular}{l}
- \texttt{management}\\
- \texttt{sales}
- \end{tabular}
- }\\
- \hline
- \end{tabular}
-\end{table}
-\end{itemize}
-
-\subsection{\aname{modstats}{\modstats{}}}
-\label{sec:modstats}
-\ind{modules!\modstats{}}\ind{protocols!JEP-0039: Statistics Gathering}\ind{statistics}
-
-This module adds support for Statistics Gathering (\jepref{0039}). This protocol
-allows you to retrieve next statistics from your \ejabberd{} deployment:
-\begin{itemize}
-\item Total number of registered users on the current virtual host (users/total).
-\item Total number of registered users on all virtual hosts (users/all-hosts/total).
-\item Total number of online users on the current virtual host (users/online).
-\item Total number of online users on all virtual hosts (users/all-hosts/online).
-\end{itemize}
-
-Options:
-\begin{description}
-\iqdiscitem{Statistics Gathering (\ns{http://jabber.org/protocol/stats})}
-\end{description}
-
-As there are only a small amount of clients (for \ind{Tkabber}example
-\footahref{http://tkabber.jabber.ru/}{Tkabber}) and software libraries with
-support for this JEP, a few examples are given of the XML you need to send
-in order to get the statistics. Here they are:
-\begin{itemize}
-\item You can request the number of online users on the current virtual host
- (\jid{example.org}) by sending:
- \begin{verbatim}
-<iq to='example.org' type='get'>
- <query xmlns='http://jabber.org/protocol/stats'>
- <stat name='users/online'/>
- </query>
-</iq>
-\end{verbatim}
-\item You can request the total number of registered users on all virtual hosts
- by sending:
- \begin{verbatim}
-<iq to='example.org' type='get'>
- <query xmlns='http://jabber.org/protocol/stats'>
- <stat name='users/all-hosts/total'/>
- </query>
-</iq>
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{modtime}{\modtime{}}}
-\label{sec:modtime}
-\ind{modules!\modtime{}}\ind{protocols!JEP-0090: Entity Time}
-
-This module features support for Entity Time (\jepref{0090}). By using this JEP,
-you are able to discover the time at another entity's location.
-
-Options:
-\begin{description}
-\iqdiscitem{Entity Time (\ns{jabber:iq:time})}
-\end{description}
-
-\subsection{\aname{modvcard}{\modvcard{}}}
-\label{sec:modvcard}
-\ind{modules!\modvcard{}}\ind{JUD}\ind{Jabber User Directory}\ind{vCard}\ind{protocols!JEP-0054: vcard-temp}
-
-This module allows end users to store and retrieve their vCard, and to retrieve
-other users vCards, as defined in vcard-temp (\jepref{0054}). The module also
-implements an uncomplicated \Jabber{} User Directory based on the vCards of
-these users. Moreover, it enables the server to send its vCard when queried.
-
-Options:
-\begin{description}
-\hostitem{vjud}
-\iqdiscitem{\ns{vcard-temp}}
-\titem{search}\ind{options!search}This option specifies whether the search
- functionality is enabled (value: \term{true}) or disabled (value:
- \term{false}). If disabled, the option \term{hosts} will be ignored and the
- \Jabber{} User Directory service will not appear in the Service Discovery item
- list. The default value is \term{true}.
-\titem{matches}\ind{options!matches}With this option, the number of reported
- search results can be limited. If the option's value is set to \term{infinity},
- all search results are reported. The default value is \term{30}.
-\titem{allow\_return\_all}\ind{options!allow\_return\_all}This option enables
- you to specify if search operations with empty input fields should return all
- users who added some information to their vCard. The default value is
- \term{false}.
-\titem{search\_all\_hosts}\ind{options!search\_all\_hosts}If this option is set
- to \term{true}, search operations will apply to all virtual hosts. Otherwise
- only the current host will be searched. The default value is \term{true}.
-\end{description}
-
-Examples:
-\begin{itemize}
-\item In this first situation, search results are limited to twenty items,
- every user who added information to their vCard will be listed when people
- do an empty search, and only users from the current host will be returned:
- \begin{verbatim}
- {modules,
- [
- ...
- {mod_vcard, [{search, true},
- {matches, 20},
- {allow_return_all, true},
- {search_all_hosts, false}]},
- ...
- ]}.
-\end{verbatim}
-\item The second situation differs in a way that search results are not limited,
- and that all virtual hosts will be searched instead of only the current one:
- \begin{verbatim}
- {modules,
- [
- ...
- {mod_vcard, [{search, true},
- {matches, infinity},
- {allow_return_all, true}]},
- ...
- ]}.
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{modvcardldap}{\modvcardldap{}}}
-\label{sec:modvcardldap}
-\ind{modules!\modvcardldap{}}\ind{JUD}\ind{Jabber User Directory}\ind{vCard}\ind{protocols!JEP-0054: vcard-temp}
-
-%TODO: verify if the referers to the LDAP section are still correct
-
-\ejabberd{} can map LDAP attributes to vCard fields. This behaviour is
-implemented in the \modvcardldap{} module. This module does not depend on the
-authentication method (see~\ref{sec:ldapauth}). The \modvcardldap{} module
-has its own optional parameters. The first group of parameters has the same
-meaning as the top-level LDAP parameters to set the authentication method:
-\option{ldap\_servers}, \option{ldap\_port}, \option{ldap\_rootdn},
-\option{ldap\_password}, \option{ldap\_base}, \option{ldap\_uidattr},
-\option{ldap\_uidattr\_format} and \option{ldap\_filter}. See
-section~\ref{sec:ldapauth} for detailed information about these options. If one
-of these options is not set, \ejabberd{} will look for the top-level option with
-the same name. The second group of parameters consists of the following
-\modvcardldap{}-specific options:
-
-\begin{description}
-\hostitem{vjud}
-\iqdiscitem{\ns{vcard-temp}}
-\titem{search}\ind{options!search}This option specifies whether the search
- functionality is enabled (value: \term{true}) or disabled (value:
- \term{false}). If disabled, the option \term{hosts} will be ignored and the
- \Jabber{} User Directory service will not appear in the Service Discovery item
- list. The default value is \term{true}.
-\titem{ldap\_vcard\_map}\ind{options!ldap\_vcard\_map}With this option you can
- set the table that maps LDAP attributes to vCard fields. The format is:
- \term{[{Name\_of\_vCard\_field, Pattern, List\_of\_LDAP\_attributes}, ...]}.\ind{protocols!RFC 2426: vCard MIME Directory Profile}
- \term{Name\_of\_vcard\_field} is the type name of the vCard as defined in
- \footahref{http://www.ietf.org/rfc/rfc2426.txt}{RFC 2426}. \term{Pattern} is a
- string which contains pattern variables \term{"\%u"}, \term{"\%d"} or
- \term{"\%s"}. \term{List\_of\_LDAP\_attributes} is the list containing LDAP
- attributes. The pattern variables \term{"\%s"} will be sequentially replaced
- with the values of LDAP attributes from \term{List\_of\_LDAP\_attributes},
- \term{"\%u"} will be replaced with the user part of a JID, and \term{"\%d"}
- will be replaced with the domain part of a JID. The default is:
- \begin{verbatim}
- [{"NICKNAME", "%u", []},
- {"FN", "%s", ["displayName"]},
- {"FAMILY", "%s", ["sn"]},
- {"GIVEN", "%s", ["givenName"]},
- {"MIDDLE", "%s", ["initials"]},
- {"ORGNAME", "%s", ["o"]},
- {"ORGUNIT", "%s", ["ou"]},
- {"CTRY", "%s", ["c"]},
- {"LOCALITY", "%s", ["l"]},
- {"STREET", "%s", ["street"]},
- {"REGION", "%s", ["st"]},
- {"PCODE", "%s", ["postalCode"]},
- {"TITLE", "%s", ["title"]},
- {"URL", "%s", ["labeleduri"]},
- {"DESC", "%s", ["description"]},
- {"TEL", "%s", ["telephoneNumber"]},
- {"EMAIL", "%s", ["mail"]},
- {"BDAY", "%s", ["birthDay"]},
- {"ROLE", "%s", ["employeeType"]},
- {"PHOTO", "%s", ["jpegPhoto"]}]
-\end{verbatim}
-\titem{ldap\_search\_fields}\ind{options!ldap\_search\_fields}This option
- defines the search form and the LDAP attributes to search within. The format
- is: \term{[{Name, Attribute}, ...]}. \term{Name} is the name of a search form
- field which will be automatically translated by using the translation
- files (see \term{msgs/*.msg} for available words). \term{Attribute} is the
- LDAP attribute or the pattern \term{"\%u"}. The default is:
- \begin{verbatim}
- [{"User", "%u"},
- {"Full Name", "displayName"},
- {"Given Name", "givenName"},
- {"Middle Name", "initials"},
- {"Family Name", "sn"},
- {"Nickname", "%u"},
- {"Birthday", "birthDay"},
- {"Country", "c"},
- {"City", "l"},
- {"Email", "mail"},
- {"Organization Name", "o"},
- {"Organization Unit", "ou"}]
-\end{verbatim}
-\titem{ldap\_search\_reported}\ind{options!ldap\_search\_reported}This option
- defines which search fields should be reported. The format is:
- \term{[{Name, vCard\_Name}, ...]}. \term{Name} is the name of a search form
- field which will be automatically translated by using the translation
- files (see \term{msgs/*.msg} for available words). \term{vCard\_Name} is the
- vCard field name defined in the \option{ldap\_vcard\_map} option. The default
- is:
-\begin{verbatim}
- [{"Full Name", "FN"},
- {"Given Name", "GIVEN"},
- {"Middle Name", "MIDDLE"},
- {"Family Name", "FAMILY"},
- {"Nickname", "NICKNAME"},
- {"Birthday", "BDAY"},
- {"Country", "CTRY"},
- {"City", "LOCALITY"},
- {"Email", "EMAIL"},
- {"Organization Name", "ORGNAME"},
- {"Organization Unit", "ORGUNIT"}]
-\end{verbatim}
-\end{description}
-
-%TODO: this examples still should be organised better
-Examples:
-\begin{itemize}
-\item
-
-Let's say \term{ldap.example.org} is the name of our LDAP server. We have
-users with their passwords in \term{"ou=Users,dc=example,dc=org"} directory.
-Also we have addressbook, which contains users emails and their additional
-infos in \term{"ou=AddressBook,dc=example,dc=org"} directory. Corresponding
-authentication section should looks like this:
-
-\begin{verbatim}
- %% authentication method
- {auth_method, ldap}.
- %% DNS name of our LDAP server
- {ldap_servers, ["ldap.example.org"]}.
- %% We want to authorize users from 'shadowAccount' object class only
- {ldap_filter, "(objectClass=shadowAccount)"}.
-\end{verbatim}
-
-Now we want to use users LDAP-info as their vCards. We have four attributes
-defined in our LDAP schema: \term{"mail"} --- email address, \term{"givenName"}
---- first name, \term{"sn"} --- second name, \term{"birthDay"} --- birthday.
-Also we want users to search each other. Let's see how we can set it up:
-
-\begin{verbatim}
- {modules,
- ...
- {mod_vcard_ldap,
- [
- %% We use the same server and port, but want to bind anonymously because
- %% our LDAP server accepts anonymous requests to
- %% "ou=AddressBook,dc=example,dc=org" subtree.
- {ldap_rootdn, ""},
- {ldap_password, ""},
- %% define the addressbook's base
- {ldap_base, "ou=AddressBook,dc=example,dc=org"},
- %% user's part of JID is located in the "mail" attribute
- {ldap_uidattr, "mail"},
- %% common format for our emails
- {ldap_uidattr_format, "%u@mail.example.org"},
- %% We have to define empty filter here, because entries in addressbook does not
- %% belong to shadowAccount object class
- {ldap_filter, ""},
- %% Now we want to define vCard pattern
- {ldap_vcard_map,
- [{"NICKNAME", "%u", []}, % just use user's part of JID as his nickname
- {"GIVEN", "%s", ["givenName"]},
- {"FAMILY", "%s", ["sn"]},
- {"FN", "%s, %s", ["sn", "givenName"]}, % example: "Smith, John"
- {"EMAIL", "%s", ["mail"]},
- {"BDAY", "%s", ["birthDay"]}]},
- %% Search form
- {ldap_search_fields,
- [{"User", "%u"},
- {"Name", "givenName"},
- {"Family Name", "sn"},
- {"Email", "mail"},
- {"Birthday", "birthDay"}]},
- %% vCard fields to be reported
- %% Note that JID is always returned with search results
- {ldap_search_reported,
- [{"Full Name", "FN"},
- {"Nickname", "NICKNAME"},
- {"Birthday", "BDAY"}]}
- ]}
- ...
- }.
-\end{verbatim}
-
-Note that \modvcardldap{} module checks an existence of the user before
-searching his info in LDAP.
-
-\item \term{ldap\_vcard\_map} example:
-\begin{verbatim}
- {ldap_vcard_map,
- [{"NICKNAME", "%u", []},
- {"FN", "%s", ["displayName"]},
- {"CTRY", "Russia", []},
- {"EMAIL", "%u@%d", []},
- {"DESC", "%s\n%s", ["title", "description"]}
- ]},
-\end{verbatim}
-\item \term{ldap\_search\_fields} example:
-\begin{verbatim}
- {ldap_search_fields,
- [{"User", "uid"},
- {"Full Name", "displayName"},
- {"Email", "mail"}
- ]},
-\end{verbatim}
-\item \term{ldap\_search\_reported} example:
-\begin{verbatim}
- {ldap_search_reported,
- [{"Full Name", "FN"},
- {"Email", "EMAIL"},
- {"Birthday", "BDAY"},
- {"Nickname", "NICKNAME"}
- ]},
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{modversion}{\modversion{}}}
-\label{sec:modversion}
-\ind{modules!\modversion{}}\ind{protocols!JEP-0092: Software Version}
-
-This module implements Software Version (\jepref{0092}). Consequently, it
-answers \ejabberd{}'s version when queried.
-
-Options:
-\begin{description}
-\iqdiscitem{Software Version (\ns{jabber:iq:version})}
-\end{description}
-
-
-\section{\aname{initialadmin}{Creating an Initial Administrator}}
-\label{sec:initialadmin}
-
-Before the web interface can be entered to perform administration tasks, an
-account with administrator rights is needed on your \ejabberd{} deployment.
-
-Instructions to create an initial administrator account:
-\begin{enumerate}
-\item Register an account on your \ejabberd{} deployment. An account can be
- created in two ways:
- \begin{enumerate}
- \item Using the tool \term{ejabberdctl}\ind{ejabberdctl} (see
- section~\ref{sec:ejabberdctl}):
- \begin{verbatim}
-% ejabberdctl node@host register admin example.org password
-\end{verbatim}
- \item Using In-Band Registration (see section~\ref{sec:modregister}): you can
- use a \Jabber{} client to register an account.
- \end{enumerate}
-\item Edit the configuration file to promote the account created in the previous
- step to an account with administrator rights. Note that if you want to add
- more administrators, a seperate acl entry is needed for each administrator.
- \begin{verbatim}
- {acl, admins, {user, "admin", "example.org"}}.
- {access, configure, [{allow, admins}]}.
-\end{verbatim}
-\item Restart \ejabberd{} to load the new configuration.
-\item Open the web interface (\verb|http://server:port/admin/|) in your
- favourite browser. Make sure to enter the \emph{full} JID as username (in this
- example: \jid{admin@example.org}. The reason that you also need to enter the
- suffix, is because \ejabberd{}'s virtual hosting support.
-\end{enumerate}
-
-
-\section{\aname{onlineconfig}{Online Configuration and Monitoring}}
-\label{sec:onlineconfig}
-
-\subsection{\aname{webinterface}{Web Interface}}
-\label{sec:webinterface}
-\ind{web interface}
-
-To perform online configuration of \ejabberd{} you need to enable the
-\term{ejabberd\_http} listener with the option \term{web\_admin} (see
-section~\ref{sec:listened}). Then you can open
-\verb|http://server:port/admin/| in your favourite web browser. You
-will be asked to enter the username (the \emph{full} \Jabber{} ID) and password
-of an \ejabberd{} user with administrator rights. After authentication
-you will see a page similar to figure~\ref{fig:webadmmain}.
-
-\begin{figure}[htbp]
- \centering
- \insimg{webadmmain.png}
- \caption{Top page from the web interface}
- \label{fig:webadmmain}
-\end{figure}
-Here you can edit access restrictions, manage users, create backups,
-manage the database, enable/disable ports listened for, view server
-statistics,\ldots
-
-Examples:
-\begin{itemize}
-\item You can serve the web interface on the same port as the
- \ind{protocols!JEP-0025: HTTP Polling}HTTP Polling interface. In this example
- you should point your web browser to \verb|http://example.org:5280/admin/| to
- administer all virtual hosts or to
- \verb|http://example.org:5280/admin/server/example.com/| to administer only
- the virtual host \jid{example.com}. Before you get access to the web interface
- you need to enter as username, the JID and password from a registered user
- that is allowed to configure \ejabberd{}. In this example you can enter as
- username `\jid{admin@example.net}' to administer all virtual hosts (first
- URL). If you log in with `\jid{admin@example.com}' on \\
- \verb|http://example.org:5280/admin/server/example.com/| you can only
- administer the virtual host \jid{example.com}.
- \begin{verbatim}
- ...
- {acl, admins, {user, "admin", "example.net"}}.
- {host_config, "example.com", [{acl, admins, {user, "admin", "example.com"}}]}.
- {access, configure, [{allow, admins}]}.
- ...
- {hosts, ["example.org"]}.
- ...
- {listen,
- [...
- {5280, ejabberd_http, [http_poll, web_admin]},
- ...
- ]
- }.
-\end{verbatim}
-\item For security reasons, you can serve the web interface on a secured
- connection, on a port differing from the HTTP Polling interface, and bind it
- to the internal LAN IP. The web interface will be accessible by pointing your
- web browser to \verb|https://192.168.1.1:5280/admin/|:
- \begin{verbatim}
- ...
- {hosts, ["example.org"]}.
- ...
- {listen,
- [...
- {5270, ejabberd_http, [http_poll]},
- {5280, ejabberd_http, [web_admin, {ip, {192, 168, 1, 1}},
- tls, {certfile, "/usr/local/etc/server.pem"}]},
- ...
- ]
- }.
-\end{verbatim}
-\end{itemize}
-
-\subsection{\aname{ejabberdctl}{\term{ejabberdctl}}}
-\label{sec:ejabberdctl}
-%TODO: update when the ejabberdctl script is made more userfriendly
-
-It is possible to do some administration operations using the command
-line tool \term{ejabberdctl}. You can list all available options by
-running \term{ejabberdctl} without arguments:
-\begin{verbatim}
-% ejabberdctl
-Usage: ejabberdctl node command
-
-Available commands:
- status get ejabberd status
- stop stop ejabberd
- restart restart ejabberd
- reopen-log reopen log file
- register user server password register a user
- unregister user server unregister a user
- backup file store a database backup to file
- restore file restore a database backup from file
- install-fallback file install a database fallback from file
- dump file dump a database to a text file
- load file restore a database from a text file
- import-file file import user data from jabberd 1.4 spool file
- import-dir dir import user data from jabberd 1.4 spool directory
- registered-users list all registered users
- delete-expired-messages delete expired offline messages from database
-
-Example:
- ejabberdctl ejabberd@host restart
-\end{verbatim}
-
-Additional information:
-\begin{description}
-\titem{reopen-log } If you use a tool to rotate logs, you have to configure it
- so that this command is executed after each rotation.
-\titem {backup, restore, install-fallback, dump, load} You can use these
- commands to create and restore backups.
-%%More information about backuping can
-%% be found in section~\ref{sec:backup}.
-\titem{import-file, import-dir} \ind{migration from other software}
- These options can be used to migrate from other \Jabber{}/XMPP servers. There
- exist tutorials to \footahref{http://ejabberd.jabber.ru/migrate-to-ejabberd}{migrate from other software to ejabberd}.
-\titem{delete-expired-messages} This option can be used to delete old messages
- in offline storage. This might be useful when the number of offline messages
- is very high.
-\end{description}
-
-
-\section{\aname{firewall}{Firewall Settings}}
-\label{sec:firewall}
-\ind{firewall}\ind{ports}\ind{SASL}\ind{TLS}\ind{clustering!ports}
-
-You need to take the following TCP ports in mind when configuring your firewall:
-\begin{table}[H]
- \centering
- \begin{tabular}{|l|l|}
- \hline Port& Description\\
- \hline \hline 5222& SASL and unencrypted c2s connections.\\
- \hline 5223& Obsolete SSL c2s connections.\\
- \hline 5269& s2s connections.\\
- \hline 4369& Only for clustering (see~\ref{sec:clustering}).\\
- \hline port range& Only for clustring (see~\ref{sec:clustering}). This range
- is configurable (see~\ref{sec:start}).\\
- \hline
- \end{tabular}
-\end{table}
-
-
-\section{\aname{srv}{SRV Records}}
-\label{sec:srv}
-\ind{SRV Records}\ind{clustering!SRV Records}
-
-\begin{itemize}
-\item General information:
- \footahref{http://en.wikipedia.org/wiki/SRV\_record}{SRV record}
-\item Practical information:
- \footahref{http://jabberd.jabberstudio.org/2/docs/section05.html\#5\_7}{Setting DNS SRV Records}
-\end{itemize}
-
-
-\section{\aname{clustering}{Clustering}}
-\label{sec:clustering}
-\ind{clustering}
-
-\subsection{\aname{howitworks}{How it Works}}
-\label{sec:howitworks}
-\ind{clustering!how it works}
-
-A \Jabber{} domain is served by one or more \ejabberd{} nodes. These nodes can
-be run on different machines that are connected via a network. They all
-must have the ability to connect to port 4369 of all another nodes, and must
-have the same magic cookie (see Erlang/OTP documentation, in other words the
-file \term{\~{}ejabberd/.erlang.cookie} must be the same on all nodes). This is
-needed because all nodes exchange information about connected users, s2s
-connections, registered services, etc\ldots
-
-Each \ejabberd{} node has the following modules:
-\begin{itemize}
-\item router,
-\item local router,
-\item session manager,
-\item s2s manager.
-\end{itemize}
-
-\subsubsection{\aname{router}{Router}}
-\label{sec:router}
-\ind{clustering!router}
-
-This module is the main router of \Jabber{} packets on each node. It
-routes them based on their destination's domains. It uses a global
-routing table. The domain of the packet's destination is searched in the
-routing table, and if it is found, the packet is routed to the
-appropriate process. If not, it is sent to the s2s manager.
-
-\subsubsection{\aname{localrouter}{Local Router}}
-\label{sec:localrouter}
-\ind{clustering!local router}
-
-This module routes packets which have a destination domain equal to
-one of this server's host names. If the destination JID has a non-empty user
-part, it is routed to the session manager, otherwise it is processed depending
-on its content.
-
-\subsubsection{\aname{sessionmanager}{Session Manager}}
-\label{sec:sessionmanager}
-\ind{clustering!session manager}
-
-This module routes packets to local users. It looks up to which user
-resource a packet must be sent via a presence table. Then the packet is
-either routed to the appropriate c2s process, or stored in offline
-storage, or bounced back.
-
-\subsubsection{\aname{s2smanager}{s2s Manager}}
-\label{sec:s2smanager}
-\ind{clustering!s2s manager}
-
-This module routes packets to other \Jabber{} servers. First, it
-checks if an opened s2s connection from the domain of the packet's
-source to the domain of the packet's destination exists. If that is the case,
-the s2s manager routes the packet to the process
-serving this connection, otherwise a new connection is opened.
-
-\subsection{\aname{cluster}{Clustering Setup}}
-\label{sec:cluster}
-\ind{clustering!setup}
-
-Suppose you already configured \ejabberd{} on one machine named (\term{first}),
-and you need to setup another one to make an \ejabberd{} cluster. Then do
-following steps:
-
-\begin{enumerate}
-\item Copy \verb|~ejabberd/.erlang.cookie| file from \term{first} to
- \term{second}.
-
- (alt) You can also add `\verb|-cookie content_of_.erlang.cookie|'
- option to all `\shell{erl}' commands below.
-
-\item On \term{second} run the following command as the \ejabberd{} daemon user,
- in the working directory of \ejabberd{}:
-
-\begin{verbatim}
-erl -sname ejabberd \
- -mnesia extra_db_nodes "['ejabberd@first']" \
- -s mnesia
-\end{verbatim}
-
- This will start Mnesia serving the same database as \node{ejabberd@first}.
- You can check this by running the command `\verb|mnesia:info().|'. You
- should see a lot of remote tables and a line like the following:
-
-\begin{verbatim}
-running db nodes = [ejabberd@first, ejabberd@second]
-\end{verbatim}
-
-
-\item Now run the following in the same `\shell{erl}' session:
-
-\begin{verbatim}
-mnesia:change_table_copy_type(schema, node(), disc_copies).
-\end{verbatim}
-
- This will create local disc storage for the database.
-
- (alt) Change storage type of the \term{scheme} table to `RAM and disc
- copy' on the second node via the web interface.
-
-
-\item Now you can add replicas of various tables to this node with
- `\verb|mnesia:add_table_copy|' or
- `\verb|mnesia:change_table_copy_type|' as above (just replace
- `\verb|schema|' with another table name and `\verb|disc_copies|'
- can be replaced with `\verb|ram_copies|' or
- `\verb|disc_only_copies|').
-
- Which tables to replicate is very dependant on your needs, you can get
- some hints from the command `\verb|mnesia:info().|', by looking at the
- size of tables and the default storage type for each table on 'first'.
-
- Replicating a table makes lookups in this table faster on this node.
- Writing, on the other hand, will be slower. And of course if machine with one
- of the replicas is down, other replicas will be used.
-
- Also \footahref{http://www.erlang.se/doc/doc-5.4.9/lib/mnesia-4.2.2/doc/html/Mnesia\_chap5.html\#5.3}
- {section 5.3 (Table Fragmentation) of Mnesia User's Guide} can be helpful.
- % The above URL needs update every Erlang release!
-
- (alt) Same as in previous item, but for other tables.
-
-
-\item Run `\verb|init:stop().|' or just `\verb|q().|' to exit from
- the Erlang shell. This probably can take some time if Mnesia has not yet
- transfered and processed all data it needed from \term{first}.
-
-
-\item Now run \ejabberd{} on \term{second} with almost the same config as
- on \term{first} (you probably do not need to duplicate `\verb|acl|'
- and `\verb|access|' options --- they will be taken from
- \term{first}, and \verb|mod_muc| and \verb|mod_irc| should be
- enabled only on one machine in the cluster).
-\end{enumerate}
-
-You can repeat these steps for other machines supposed to serve this
-domain.
-
-% TODO
-% See also the section about ejabberdctl!!!!
-%\section{Backup and Restore}
-%\label{sec:backup}
-%\ind{backup}
-
-\appendix{}
-\section{\aname{i18nl10n}{Internationalization and Localization}}
-\label{sec:i18nl10n}
-\ind{xml:lang}\ind{internationalization}\ind{localization}\ind{i18n}\ind{l10n}
-
-All built-in modules support the \texttt{xml:lang} attribute inside IQ queries.
-Figure~\ref{fig:discorus}, for example, shows the reply to the following query:
-\begin{verbatim}
- <iq id='5'
- to='example.org'
- type='get'
- xml:lang='ru'>
- <query xmlns='http://jabber.org/protocol/disco#items'/>
- </iq>
-\end{verbatim}
-
-\begin{figure}[htbp]
- \centering
- \insimg{discorus.png}
- \caption{Service Discovery when \texttt{xml:lang='ru'}}
- \label{fig:discorus}
-\end{figure}
-
-The web interface also supports the \verb|Accept-Language| HTTP header (compare
-figure~\ref{fig:webadmmainru} with figure~\ref{fig:webadmmain})
-
-\begin{figure}[htbp]
- \centering
- \insimg{webadmmainru.png}
- \caption{Top page from the web interface with HTTP header
- `Accept-Language: ru'}
- \label{fig:webadmmainru}
-\end{figure}
-
-
-%\section{\aname{ultracomplexexample}{Ultra Complex Example}}
-%\label{sec:ultracomplexexample}
-%TODO: a very big example covering the whole guide, with a good explanation before the example: different authenticaton mechanisms, transports, ACLs, multple virtual hosts, virtual host specific settings and general settings, modules,...
-
-\newpage
-\section{\aname{releasenotes}{Release Notes}}
-\label{sec:releasenotes}
-\ind{release notes}
-
-\subsection{ejabberd 0.9}
-\verbatiminput{release_notes_0.9.txt}
-
-\subsection{ejabberd 0.9.1}
-\verbatiminput{release_notes_0.9.1.txt}
-
-\subsection{ejabberd 0.9.8}
-\verbatiminput{release_notes_0.9.8.txt}
-
-\subsection{ejabberd 1.0.0}
-\verbatiminput{release_notes_1.0.0.txt}
-
-\subsection{ejabberd 1.1.0}
-\verbatiminput{release_notes_1.1.0.txt}
-
-\subsection{ejabberd 1.1.1}
-\verbatiminput{release_notes_1.1.1.txt}
-
-\subsection{ejabberd 1.1.2}
-\verbatiminput{release_notes_1.1.2.txt}
-
-\section{\aname{acknowledgements}{Acknowledgements}}
-\label{sec:acknowledgements}
-Thanks to all people who contributed to this guide:
-\begin{itemize}
-\item Alexey Shchepin (\ahrefurl{xmpp:aleksey@jabber.ru})
-\item Badlop (\ahrefurl{xmpp:badlop@jabberes.org})
-\item Evgeniy Khramtsov (\ahrefurl{xmpp:xram@jabber.ru})
-\item Florian Zumbiehl (\ahrefurl{xmpp:florz@florz.de})
-\item Michael Grigutsch (\ahrefurl{xmpp:migri@jabber.i-pobox.net})
-\item Mickael Remond (\ahrefurl{xmpp:mremond@erlang-projects.org})
-\item Sander Devrieze (\ahrefurl{xmpp:sander@devrieze.dyndns.org})
-\item Sergei Golovan (\ahrefurl{xmpp:sgolovan@nes.ru})
-\item Vsevolod Pelipas (\ahrefurl{xmpp:vsevoload@jabber.ru})
-\end{itemize}
-
-
-\section{\aname{copyright}{Copyright Information}}
-\label{sec:copyright}
-
-Ejabberd Installation and Operation Guide.\\
-Copyright \copyright{} January 23, 2003 --- \today{} Alexey Shchepin
-
-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
-of the License, or (at your option) any later version.
-
-This document 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 document; if not, write to the Free Software Foundation, Inc., 51 Franklin
-Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-%TODO: a glossary describing common terms
-%\section{\aname{glossary}{Glossary}}
-%\label{sec:glossary}
-%\ind{glossary}
-
-%\begin{description}
-%\titem{c2s}
-%\titem{s2s}
-%\titem{STARTTLS}
-%\titem{JEP} (\Jabber{} Enhancement Proposal)
-%\titem{Resource}
-%\titem{Roster}
-%\titem{Transport}
-%\titem{JID} (\Jabber{} ID) <Wikipedia>
-%\titem{JUD} (\Jabber{} User Directory)
-%\titem{vCard} <Wikipedia>
-%\titem{Publish-Subscribe}
-%\titem{Namespace}
-%\titem{Erlang} <Wikipedia>
-%\titem{Fault-tolerant}
-%\titem{Distributed} <Wikipedia>
-%\titem{Node} <Wikipedia>
-%\titem{Tuple} <Wikipedia>
-%\titem{Regular Expression}
-%\titem{ACL} (Access Control List) <Wikipedia>
-%\titem{IPv6} <Wikipedia>
-%\titem{Jabber}
-%\titem{LDAP} (Lightweight Directory Access Protocol) <Wikipedia>
-%\titem{ODBC} (Open Database Connectivity) <Wikipedia>
-%\titem{Virtual Hosting} <Wikipedia>
-
-%\end{description}
-
-
-
-% Remove the index from the HTML version to save size and bandwith.
-\begin{latexonly}
-\printindex
-\end{latexonly}
-
-\end{document}
diff --git a/ejabberd-1.1.2/doc/introduction.tex b/ejabberd-1.1.2/doc/introduction.tex
deleted file mode 100644
index 359f86929..000000000
--- a/ejabberd-1.1.2/doc/introduction.tex
+++ /dev/null
@@ -1,131 +0,0 @@
-\section{\aname{intro}{Introduction}}
-\label{sec:intro}
-
-\quoting{I just tried out ejabberd and was impressed both by ejabberd itself and the language it is written in, Erlang. ---
-Joeri}
-
-%ejabberd is a free and open source instant messaging server written in Erlang. ejabberd is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication (Jabber/XMPP).
-
-\ejabberd{} is a \marking{free and open source} instant messaging server written in \footahref{http://www.erlang.org/}{Erlang}.
-
-\ejabberd{} is \marking{cross-platform}, distributed, fault-tolerant, and based on open standards to achieve real-time communication.
-
-\ejabberd{} is designed to be a \marking{rock-solid and feature rich} XMPP server.
-
-\ejabberd{} is suitable for small deployments, whether they need to be \marking{scalable} or not, as well as extremely big deployments.
-
-%\subsection{\aname{layout}{Layout with example deployment (title needs a better name)}}
-%\label{sec:layout}
-
-%In this section there will be a graphical overview like these:\\
-%\verb|http://www.tipic.com/var/timp/timp_dep.gif| \\
-%\verb|http://www.jabber.com/images/jabber_Com_Platform.jpg| \\
-%\verb|http://www.antepo.com/files/OPN45systemdatasheet.pdf| \\
-
-%A page full with names of Jabber client that are known to work with ejabberd. \begin{tiny}tiny font\end{tiny}
-
-%\subsection{\aname{trytoday}{Try It Today}}
-%\label{sec:trytoday}
-
-%(Not sure if I will include/finish this section for the next version.)
-
-%\begin{itemize}
-%\item Erlang REPOS
-%\item Packages in distributions
-%\item Windows binary
-%\item source tar.gz
-%\item Migration from Jabberd14 (and so also Jabberd2 because you can migrate from version 2 back to 14) and Jabber Inc. XCP possible.
-%\end{itemize}
-
-\newpage
-\subsection{\aname{keyfeatures}{Key Features}}
-\label{sec:keyfeatures}
-\ind{features!key features}
-
-\quoting{Erlang seems to be tailor-made for writing stable, robust servers. ---
-Peter Saint-Andr\'e, Executive Director of the Jabber Software Foundation}
-
-\ejabberd{} is:
-\begin{itemize}
-\item \marking{Cross-platform:} \ejabberd{} runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.
-
-\item \marking{Distributed:} You can run \ejabberd{} on a cluster of machines and all of them will serve the same \Jabber{} domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.
-
-\item \marking{Fault-tolerant:} You can deploy an \ejabberd{} cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced `on the fly'.
-
-\item \marking{Administrator Friendly:} \ejabberd{} is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
-\begin{itemize}
-\item Comprehensive documentation.
-\item Straightforward installers for Linux, Mac OS X, and Windows.\improved{}
-\item Web interface for administration tasks.
-\item Shared Roster Groups.
-\item Command line administration tool.\improved{}
-\item Can integrate with existing authentication mechanisms.
-\item Capability to send announce messages.
-\end{itemize}
-
-\item \marking{Internationalized:} \ejabberd{} leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
-\begin{itemize}
-\item Translated in 12 languages.\improved{}
-\item Support for \footahref{http://www.ietf.org/rfc/rfc3490.txt}{IDNA}.
-\end{itemize}
-
-\item \marking{Open Standards:} \ejabberd{} is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
-\begin{itemize}
-\item Fully XMPP compliant.
-\item XML-based protocol.
-\item \footahref{http://ejabberd.jabber.ru/protocols}{Many JEPs supported}.
-\end{itemize}
-
-\end{itemize}
-
-\newpage
-
-\subsection{\aname{addfeatures}{Additional Features}}
-\label{sec:addfeatures}
-\ind{features!additional features}
-
-\quoting{ejabberd is making inroads to solving the "buggy incomplete server" problem ---
-Justin Karneges, Founder of the Psi and the Delta projects}
-
-Moreover, \ejabberd{} comes with a wide range of other state-of-the-art features:
-\begin{itemize}
-\item Modular
-\begin{itemize}
-\item Load only the modules you want.
-\item Extend \ejabberd{} with your own custom modules.
-\end{itemize}
-\item Security
-\begin{itemize}
-\item SASL and STARTTLS for c2s and s2s connections.
-\item STARTTLS and Dialback s2s connections.
-\item Web interface accessible via HTTPS secure access.
-\end{itemize}
-\item Databases
-\begin{itemize}
-\item Native MySQL support.
-\item Native PostgreSQL support.
-\item Mnesia.
-\item ODBC data storage support.
-\item Microsoft SQL Server support.\new{}
-\end{itemize}
-\item Authentication
-\begin{itemize}
-\item LDAP and ODBC.\improved{}
-\item External Authentication script.
-\item Internal Authentication.
-\end{itemize}
-\item Others
-\begin{itemize}
-\item Compressing XML streams with Stream Compression (\jepref{0138}).
-\item Interface with networks such as AIM, ICQ and MSN.
-\item Statistics via Statistics Gathering (\jepref{0039}).
-\item IPv6 support both for c2s and s2s connections.
-\item \tjepref{0045}{Multi-User Chat} module with logging.\improved{}
-\item Users Directory based on users vCards.
-\item \tjepref{0060}{Publish-Subscribe} component.
-\item Support for virtual hosting.
-\item \tjepref{0025}{HTTP Polling} service.
-\item IRC transport.
-\end{itemize}
-\end{itemize} \ No newline at end of file
diff --git a/ejabberd-1.1.2/doc/logo.png b/ejabberd-1.1.2/doc/logo.png
deleted file mode 100644
index b8d17ebfd..000000000
--- a/ejabberd-1.1.2/doc/logo.png
+++ /dev/null
Binary files differ
diff --git a/ejabberd-1.1.2/doc/release_note_1.1.2.txt b/ejabberd-1.1.2/doc/release_note_1.1.2.txt
deleted file mode 100644
index e69de29bb..000000000
--- a/ejabberd-1.1.2/doc/release_note_1.1.2.txt
+++ /dev/null
diff --git a/ejabberd-1.1.2/doc/release_notes_0.9.1.txt b/ejabberd-1.1.2/doc/release_notes_0.9.1.txt
deleted file mode 100644
index 39637e4fb..000000000
--- a/ejabberd-1.1.2/doc/release_notes_0.9.1.txt
+++ /dev/null
@@ -1,62 +0,0 @@
- Release notes
- ejabberd 0.9.1
-
- This document describes the main changes from [25]ejabberd 0.9.
-
- The code can be downloaded from the [26]download page.
-
- For more detailed information, please refer to ejabberd [27]User Guide.
-
-
-Groupchat (Multi-user chat and IRC) improvements
-
- The multi-user chat code has been improved to comply with the latest version
- of Jabber Enhancement Proposal 0045.
-
- The IRC (Internet Relay Chat) features now support WHOIS and USERINFO
- requests.
-
-
-Web interface
-
- ejabberd modules management features have been added to the web interface.
- They now allow to start or stop extension module without restarting the
- ejabberd server.
-
-
-Publish and subscribe
-
- It is now possible to a subscribe node with a JabberID that includes a
- resource.
-
-
-Translations
-
- A new script has been included to help translate ejabberd into new languages
- and maintain existing translations.
-
- As a result, ejabberd is now translating into 10 languages:
- * Dutch
- * English
- * French
- * German
- * Polish
- * Portuguese
- * Russian
- * Spanish
- * Swedish
- * Ukrainian
-
-
-Migration
-
- No changes have been made to the database. No particular conversion steps
- are needed. However, you should backup your database before upgrading to a
- new ejabberd version.
-
-
-Bugfixes
-
- This release contains several bugfixes and architectural changes. Please
- refer to the Changelog file supplied with this release for details of all
- improvements in the ejabberd code.
diff --git a/ejabberd-1.1.2/doc/release_notes_0.9.8.txt b/ejabberd-1.1.2/doc/release_notes_0.9.8.txt
deleted file mode 100644
index b9b65b63b..000000000
--- a/ejabberd-1.1.2/doc/release_notes_0.9.8.txt
+++ /dev/null
@@ -1,99 +0,0 @@
- Release notes
- ejabberd 0.9.8
- 2005-08-01
-
- This document describes the main changes in ejabberd 0.9.8. This
- version prepares the way for the release of ejabberd 1.0, which
- is due later this year.
-
- The code can be downloaded from the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/
-
- For more detailed information, please refer to ejabberd User Guide
- on the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/docs.html
-
-
- Recent changes include....
-
-
-Enhanced virtual hosting
-
- Virtual hosting applies to many more setting options and
- features and is transparent. Virtual hosting accepts different
- parameters for different virtual hosts regarding the following
- features: authentication method, access control lists and access
- rules, users management, statistics, and shared roster. The web
- interface gives access to each virtual host's parameters.
-
-
-Enhanced Publish-Subscribe module
-
- ejabberd's Publish-Subscribe module integrates enhancements
- coming from J-EAI, an XMPP-based integration server built on
- ejabberd. ejabberd thus supports Publish-Subscribe node
- configuration. It is possible to define nodes that should be
- persistent, and the number of items to persist. Besides that, it
- is also possible to define various notification parameters, such
- as the delivery of the payload with the notifications, and the
- notification of subscribers when some changes occur on items.
- Other examples are: the maximum size of the items payload, the
- subscription approvers, the limitation of the notification to
- online users only, etc.
-
-
-Code reorganisation and update
-
- - The mod_register module has been cleaned up.
- - ODBC support has been updated and several bugs have been fixed.
-
-
-Development API
-
- To ease the work of Jabber/XMPP developers, a filter_packet hook
- has been added. As a result it is possible to develop plugins to
- filter or modify packets flowing through ejabberd.
-
-
-Translations
-
- - Translations have been updated to support the new Publish-Subscribe features.
- - A new Brazilian Portuguese translation has been contributed.
-
-
-Web interface
-
- - The CSS stylesheet from the web interface is W3C compliant.
-
-
-Installers
-
- Installers are provided for Microsoft Windows and Linux/x86. The
- Linux installer includes Erlang ASN.1 modules for LDAP
- authentication support.
-
-
-Bugfixes
-
- - This release contains several bugfixes and architectural
- changes. Among other bugfixes include improvements in LDAP
- authentication. Please refer to the ChangeLog file supplied
- with this release regarding all improvements in ejabberd.
-
-
-References
-
- The ejabberd feature sheet helps comparing with other Jabber/XMPP
- servers:
- http://www.process-one.net/en/projects/ejabberd/docs/features.pdf
-
- Contributed tutorials of interest are:
- - Migration from Jabberd1.4 to ejabberd:
- http://ejabberd.jabber.ru/jabberd1-to-ejabberd
- - Migration from Jabberd2 to ejabberd:
- http://ejabberd.jabber.ru/jabberd2-to-ejabberd
- - Transport configuration for connecting to other networks:
- http://ejabberd.jabber.ru/tutorials-transports
-
-END
-
diff --git a/ejabberd-1.1.2/doc/release_notes_0.9.txt b/ejabberd-1.1.2/doc/release_notes_0.9.txt
deleted file mode 100644
index 6bdce830f..000000000
--- a/ejabberd-1.1.2/doc/release_notes_0.9.txt
+++ /dev/null
@@ -1,88 +0,0 @@
- Release notes
- ejabberd 0.9
-
- This document describes the major new features of and changes to
- ejabberd 0.9, compared to latest public release ejabber 0.7.5.
-
- For more detailed information, please refer to ejabberd User
- Guide.
-
-
-Virtual Hosting
-
- ejabberd now can host several domain on the same instance.
- This option is enabled by using:
-
- {hosts, ["erlang-projects.org", "erlang-fr.org"]}.
-
- instead of the previous host directive.
-
- Note that you are now using a list of hosts. The main one should
- be the first listed. See migration section further in this release
- note for details.
-
-
-Shared Roster
-
- Shared roster is a new feature that allow the ejabberd
- administrator to add jabber user that will be present in the
- roster of every users on the server.
- Shared roster are enabled by adding:
-
- {mod_shared_roster, []}
-
- at the end of your module list in your ejabberd.cfg file.
-
-
-PostgreSQL (ODBC) support
-
- This feature is experimental and not yet properly documented. This
- feature is released for testing purpose.
-
- You need to have Erlang/OTP R10 to compile with ODBC on various
- flavour of *nix. You should use Erlang/OTP R10B-4, as this task
- has became easier with this release. It comes already build in
- Erlang/OTP Microsoft Windows binary.
-
- PostgreSQL support is enabled by using the following module in
- ejabberd.cfg instead of their standard counterpart:
-
- mod_last_odbc.erl
- mod_offline_odbc.erl
- mod_roster_odbc.erl
-
- The database schema is located in the src/odbc/pq.sql file.
-
- Look at the src/ejabberd.cfg.example file for more information on
- how to configure ejabberd with odbc support. You can get support
- on how to configure ejabberd with a relational database.
-
-
-Migration from ejabberd 0.7.5
-
- Migration is pretty straightforward as Mnesia database schema
- conversions is handled automatically. Remember however that you
- must backup your ejabberd database before migration.
-
- Here are the following steps to proceed:
-
- 1. Stop your instance of ejabberd.
-
- 2. In ejabberd.cfg, define the host lists. Change the host
- directive to the hosts one:
- Before:
- {host, "erlang-projects.org"}.
- After:
- {hosts, ["erlang-projects.org", "erlang-fr.org"]}.
- Note that when you restart the server the existing users will be
- affected to the first virtual host, so the order is important. You
- should keep the previous hostname as the first virtual host.
-
- 3. Restart ejabberd.
-
-
-Bugfixes
-
- This release contains several bugfixes and architectural changes.
- Please refer to the Changelog file supplied with this release for
- details of all improvements in the ejabberd code.
diff --git a/ejabberd-1.1.2/doc/release_notes_1.0.0.txt b/ejabberd-1.1.2/doc/release_notes_1.0.0.txt
deleted file mode 100644
index 426ba63fa..000000000
--- a/ejabberd-1.1.2/doc/release_notes_1.0.0.txt
+++ /dev/null
@@ -1,120 +0,0 @@
- Release Notes
- ejabberd 1.0.0
- 14 December 2005
-
- This document describes the main changes in ejabberd 1.0.0. Unique in this
- version is the compliancy with the XMPP (eXtensible Messaging and Presence
- Protocol) standard. ejabberd is the first Open Source Jabber server claiming
- to fully comply to the XMPP standard.
-
- ejabberd can be downloaded from the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/
-
- Detailed information can be found in the ejabberd Feature Sheet and User
- Guide which are available on the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/docs.html
-
-
- Recent changes include:
-
-
-Server-to-server Encryption for Enhanced Security
-
- - Support for STARTTLS and SASL EXTERNAL to secure server-to-server traffic
- has been added.
- - Also, STARTTLS and Dialback has been implemented for server-to-server (s2s)
- connections. Detailed information about these new features can be found on
- http://ejabberd.jabber.ru/s2s-encryption
- - commonName and dNSName fields matching were introduced to ease the process
- of retrieving certificates.
- - Different certificates can be defined for each virtual host.
-
-ODBC Support
-
- - ODBC support has been improved to allow production use of ejabberd with
- relational databases.
- - Support for vCard storage in ODBC has been added.
- - ejd2odbc.erl is a tool to convert an installation from Erlang's database
- Mnesia to an ODBC compatible relational database.
-
-Native PostgreSQL Support
-
- - Native PostgreSQL support gives you a better performance when you use
- PostgreSQL.
-
-Shared Roster groups
-
- - Shared Roster groups support has been enhanced. New is the ability to add
- all registered users to everyone's roster. Detailed information about this
- new feature can be found on http://ejabberd.jabber.ru/shared-roster-all
-
-Web Interface
-
- - The web interface internal code has been modified for better integration
- and compliancy with J-EAI, an ejabberd-based Enterprise Application
- Integration platform.
- - More XHTML 1.0 Transitional compliancy work was done.
-
-Transports
-
- - A transport workaround can be enabled during compilation. To do this, you
- can pass the "--enable-roster-gateway-workaround" option to the configure
- script. (./configure --enable-roster-gateway-workaround)
- This option allows transports to add items with subscription "to" in the
- roster by sending <presence type='subscribed'/> stanza to user. This option
- is only needed for JIT ICQ transport.
- Warning: by enabling this option, ejabberd will not be fully XMPP compliant
- anymore.
-
-Documentation and Internationalization
-
- - Documentation has been extended to cover more topics.
- - Translations have been updated.
-
-Bugfixes
-
- - This release contains several bugfixes.
- - Among other bugfixes include improvements to the client-to-server (c2s)
- connection management module.
- - Please refer to the ChangeLog file supplied
- with this release regarding all improvements in ejabberd.
-
-
- Installation Notes
-
-
-Supported Erlang Version
-
- - You need at least Erlang/OTP R9C to run ejabberd 1.0.0.
-
-Installation
-
- Installers are provided for Microsoft Windows and Linux/x86.
- Installers can be retrieved from:
- http://www.process-one.net/en/projects/ejabberd/download.html
-
-Migration Notes
-
- - Before any migration, ejabberd system and database must be properly
- backed up.
- - When upgrading an ODBC-based installation, you will need to change the
- relational database schema. The following SQL commands must be run on the
- database:
- CREATE SEQUENCE spool_seq_seq;
- ALTER TABLE spool ADD COLUMN seq integer;
- ALTER TABLE spool ALTER COLUMN seq SET DEFAULT nextval('spool_seq_seq');
- UPDATE spool SET seq = DEFAULT;
- ALTER TABLE spool ALTER COLUMN seq SET NOT NULL;
-
-References
-
- Contributed tutorials of interest are:
- - Migration from Jabberd1.4 to ejabberd:
- http://ejabberd.jabber.ru/jabberd1-to-ejabberd
- - Migration from Jabberd2 to ejabberd:
- http://ejabberd.jabber.ru/jabberd2-to-ejabberd
- - Transport configuration for connecting to other networks:
- http://ejabberd.jabber.ru/tutorials-transports
-
-END
-
diff --git a/ejabberd-1.1.2/doc/release_notes_1.1.0.txt b/ejabberd-1.1.2/doc/release_notes_1.1.0.txt
deleted file mode 100644
index fbef6a934..000000000
--- a/ejabberd-1.1.2/doc/release_notes_1.1.0.txt
+++ /dev/null
@@ -1,115 +0,0 @@
- Release Notes
- ejabberd 1.1.0
- 24 April 2006
-
- This document describes the main changes in ejabberd 1.1.0. This version
- introduce new features including support for new Jabber Enhancement
- Proposals and several performance improvements enabling deployments on an
- even larger scale than already possible.
-
- ejabberd can be downloaded from the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/
-
- Detailed information can be found in the ejabberd Feature Sheet and User
- Guide which are available on the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/docs.html
-
- A complete list of changes is available from:
- http://support.process-one.net/secure/ReleaseNote.jspa?projectId=10011&styleName=Html&version=10025
-
-
- Recent changes include:
-
-
-New Jabber Enhancement Proposal support:
-
- - JEP-0050: Ad-Hoc Commands.
- - JEP-0138: Stream Compression.
- - JEP-0175: SASL anonymous.
-
-Anonymous login
-
- - SASL anonymous.
- - Anonymous login for clients that do not yet support SASL Anonymous.
-
-Relational database Support
-
- - MySQL is now fully supported through ODBC and in native mode.
- - Various improvements to the native database interfaces.
- - The migration tool can use relational databases.
-
-Multi-User Chat improvements
-
- - Logging of room discussion to text file is now supported.
- - Better reconfiguration support.
- - Security oriented fixes.
- - Several improvements and updates to latest JEP-0045.
-
-Performance scalability improvements for large clusters
-
- - Improved session synchronisation management between cluster nodes.
- - Internal architecture has been reworked to use generalize Erlang/OTP
- framework usage.
- - Speed improvement on logger.
- - TCP/IP packet reception change for better network throttling and
- regulation.
- As a result, these improvements will reduce load on large scale deployments.
-
-XMPP Protocol related improvements
-
- - XML stanza size can be limited.
- - Messages are send to all resources with the same highest priority.
-
-Documentation and Internationalization
-
- - Documentation has been extended to cover more topics.
- - Translations have been updated.
-
-Web interface
-
- - XHTML 1.0 compliance.
-
-Bugfixes
-
- - This release contains many bugfixes on various areas such as Publish-Subscribe, build
- chain, installers, IRC gateway, ejabberdctl, amongst others.
- - Please refer to the ChangeLog file supplied with this release regarding
- all improvements in ejabberd.
-
-
-
- Installation Notes
-
-Supported Erlang Version
-
- - You need at least Erlang/OTP R9C-2 to run ejabberd 1.1.0.
-
-Installation
-
- Installers are provided for Microsoft Windows, Linux/x86 and MacOSX/PPC.
- Installers can be retrieved from:
- http://www.process-one.net/en/projects/ejabberd/download.html
-
-Migration Notes
-
- - Before any migration, ejabberd system and database must be properly
- backed up.
- - The database schema has not been changed comparing to version 1.0.0 and
- consequently it does not require any migration.
-
-
-References
-
- Contributed tutorials and documents of interest are:
- - Migration from Jabberd1.4, Jabberd2 and WPJabber to ejabberd:
- http://ejabberd.jabber.ru/migrate-to-ejabberd
- - Transport configuration for connecting to other networks:
- http://ejabberd.jabber.ru/tutorials-transports
- - Using ejabberd with MySQL native driver:
- http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver
- - Anonymous User Support:
- http://support.process-one.net/doc/display/MESSENGER/Anonymous+users+support
- - Frequently Asked Questions:
- http://ejabberd.jabber.ru/faq
-
-END
diff --git a/ejabberd-1.1.2/doc/release_notes_1.1.1.txt b/ejabberd-1.1.2/doc/release_notes_1.1.1.txt
deleted file mode 100644
index e2f4273da..000000000
--- a/ejabberd-1.1.2/doc/release_notes_1.1.1.txt
+++ /dev/null
@@ -1,119 +0,0 @@
- Release Notes
- ejabberd 1.1.1
- 28 April 2006
-
- This document describes the main changes in ejabberd 1.1.x. This version
- introduce new features including support for new Jabber Enhancement
- Proposals and several performance improvements enabling deployments on an
- even larger scale than already possible.
-
- This release fix a security issue introduced in ejabberd 1.1.0. In SASL
- mode, anonymous login was enabled as a default. Upgrading ejabberd 1.1.0 to
- ejabberd 1.1.1 is highly recommended.
-
- ejabberd can be downloaded from the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/
-
- Detailed information can be found in the ejabberd Feature Sheet and User
- Guide which are available on the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/docs.html
-
- A complete list of changes is available from:
- http://support.process-one.net/secure/ReleaseNote.jspa?projectId=10011&styleName=Html&version=10025
-
-
- Recent changes include:
-
-
-New Jabber Enhancement Proposal support:
-
- - JEP-0050: Ad-Hoc Commands.
- - JEP-0138: Stream Compression.
- - JEP-0175: SASL anonymous.
-
-Anonymous login
-
- - SASL anonymous.
- - Anonymous login for clients that do not yet support SASL Anonymous.
-
-Relational database Support
-
- - MySQL is now fully supported through ODBC and in native mode.
- - Various improvements to the native database interfaces.
- - The migration tool can use relational databases.
-
-Multi-User Chat improvements
-
- - Logging of room discussion to text file is now supported.
- - Better reconfiguration support.
- - Security oriented fixes.
- - Several improvements and updates to latest JEP-0045.
-
-Performance scalability improvements for large clusters
-
- - Improved session synchronisation management between cluster nodes.
- - Internal architecture has been reworked to use generalize Erlang/OTP
- framework usage.
- - Speed improvement on logger.
- - TCP/IP packet reception change for better network throttling and
- regulation.
- As a result, these improvements will reduce load on large scale deployments.
-
-XMPP Protocol related improvements
-
- - XML stanza size can be limited.
- - Messages are send to all resources with the same highest priority.
-
-Documentation and Internationalization
-
- - Documentation has been extended to cover more topics.
- - Translations have been updated.
-
-Web interface
-
- - XHTML 1.0 compliance.
-
-Bugfixes
-
- - This release contains many bugfixes on various areas such as Publish-Subscribe, build
- chain, installers, IRC gateway, ejabberdctl, amongst others.
- - Please refer to the ChangeLog file supplied with this release regarding
- all improvements in ejabberd.
-
-
-
- Installation Notes
-
-Supported Erlang Version
-
- - You need at least Erlang/OTP R9C-2 to run ejabberd 1.1.0.
-
-Installation
-
- Installers are provided for Microsoft Windows, Linux/x86 and MacOSX/PPC.
- Installers can be retrieved from:
- http://www.process-one.net/en/projects/ejabberd/download.html
-
-Migration Notes
-
- - Before any migration, ejabberd system and database must be properly
- backed up.
- - The database schema has not been changed comparing to version 1.0.0 and
- consequently it does not require any migration.
-
-
-References
-
- Contributed tutorials and documents of interest are:
- - Migration from Jabberd1.4, Jabberd2 and WPJabber to ejabberd:
- http://ejabberd.jabber.ru/migrate-to-ejabberd
- - Transport configuration for connecting to other networks:
- http://ejabberd.jabber.ru/tutorials-transports
- - Using ejabberd with MySQL native driver:
- http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver
- - Anonymous User Support:
- http://support.process-one.net/doc/display/MESSENGER/Anonymous+users+support
- - Frequently Asked Questions:
- http://ejabberd.jabber.ru/faq
-
-END
diff --git a/ejabberd-1.1.2/doc/release_notes_1.1.2.txt b/ejabberd-1.1.2/doc/release_notes_1.1.2.txt
deleted file mode 100644
index e7c8f3551..000000000
--- a/ejabberd-1.1.2/doc/release_notes_1.1.2.txt
+++ /dev/null
@@ -1,119 +0,0 @@
- Release Notes
- ejabberd 1.1.2
- 27 September 2006
-
- This document describes the main changes in ejabberd 1.1.2.
-
- This version is a major improvement over ejabberd 1.1.1, improving the
- overall behaviour of the server in many areas. Users of ejabberd 1.1.1
- should upgrade to this new release for improved robustness and compliance.
-
- ejabberd can be downloaded from the Process-one website:
- http://www.process-one.net/en/projects/ejabberd/
-
- Detailed information can be found in the Feature Sheet and in the
- Installation and Operation Guide which are both available on the
- Process-one website:
- http://www.process-one.net/en/projects/ejabberd/docs.html
-
- ejabberd includes 44 improvements. A complete list of changes can be
- retrieved from:
- http://redir.process-one.net/ejabberd-1.1.2
-
-
- Recent changes include:
-
-LDAP Improvements
-
- - Major improvements have been made on the LDAP module. It is now more
- flexible and more robust.
-
-HTTP Polling Fixes
-
- - The HTTP polling modules have been fixed and improved: the connections are
- closed properly and polled messages cannot be lost anymore.
-
-Roster Management Improvement
-
- - Roster management improvements increase reliability, especially in cases
- where users are on different servers.
- - Shared rosters are more reliable.
-
-Improved Robustness
-
- - It is now possible to limit the number of opened connections for a single
- user.
-
-Relational databases
-
- - Database support: Microsoft SQL Server is now officially supported in ODBC
- mode.
-
-Publish-Subscribe Improvement
-
- - Restricting node creation with a dedicated ACL rule is now possible.
-
-Localization
-
- - A Czech translation has been added.
- - Translations have been updated.
-
-Binary Installer
-
- - New binary installer for Windows including all requirements.
- - Improved installers for Linux and MacOSX (PowerPC)
-
-XMPP Compliancy
-
- - Some protocol compliance fix have been added, after the Portland XMPP
- Interop Meeting in July.
-
-Miscelanous
-
- - MUC have been improved (logging rendering).
- - The command line tool ejabberdctl has been improved.
- - The build chain has been improved, including MacOSX support.
- - The documentation has been improved and updated to describe the new
- features.
-
-Bugfixes
-
- - Anonymous login bugfixes.
- - Please refer to the ChangeLog file supplied with this release regarding
- all improvements in ejabberd.
-
-
- Installation Notes
-
-Supported Erlang Version
-
- - You need at least Erlang/OTP R9C-2 to run ejabberd 1.1.2.
- - The recommanded version is Erlang/OTP R10B-10.
- - Erlang/OTP R11B has not yet been fully certified for ejabberd.
-
-Installation
-
- Installers are provided for Microsoft Windows, Linux/x86 and MacOSX/PPC.
- They can be retrieved from:
- http://www.process-one.net/en/projects/ejabberd/download.html
-
-Migration Notes
-
- - Before any migration, ejabberd system and database must be properly
- backed up.
- - The relational database schema has changed between version 1.1.1 and
- 1.1.2. An "askmessage" column needs to be added in the "rosterusers" table
- to perform the migration.
-
-
-References
-
- Contributed tutorials and documents of interest are:
- - Migration from other XMPP servers to ejabberd:
- http://ejabberd.jabber.ru/migrate-to-ejabberd
- - Transport configuration for connecting to other networks:
- http://ejabberd.jabber.ru/tutorials-transports
- - Frequently Asked Questions:
- http://ejabberd.jabber.ru/faq
-
-END
diff --git a/ejabberd-1.1.2/doc/version.tex b/ejabberd-1.1.2/doc/version.tex
deleted file mode 100644
index 90a3dcf92..000000000
--- a/ejabberd-1.1.2/doc/version.tex
+++ /dev/null
@@ -1,2 +0,0 @@
-% Define ejabberd version here.
-\newcommand{\version}{1.1.2}
diff --git a/ejabberd-1.1.2/doc/webadmmain.png b/ejabberd-1.1.2/doc/webadmmain.png
deleted file mode 100644
index fd7d50b19..000000000
--- a/ejabberd-1.1.2/doc/webadmmain.png
+++ /dev/null
Binary files differ
diff --git a/ejabberd-1.1.2/doc/webadmmainru.png b/ejabberd-1.1.2/doc/webadmmainru.png
deleted file mode 100644
index 51fc2d8ea..000000000
--- a/ejabberd-1.1.2/doc/webadmmainru.png
+++ /dev/null
Binary files differ
diff --git a/ejabberd-1.1.2/doc/yozhikheader.png b/ejabberd-1.1.2/doc/yozhikheader.png
deleted file mode 100644
index f2a4e4f00..000000000
--- a/ejabberd-1.1.2/doc/yozhikheader.png
+++ /dev/null
Binary files differ
diff --git a/ejabberd-1.1.2/examples/extauth/check_pass_null.pl b/ejabberd-1.1.2/examples/extauth/check_pass_null.pl
deleted file mode 100644
index 7291abf0f..000000000
--- a/ejabberd-1.1.2/examples/extauth/check_pass_null.pl
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/local/bin/perl
-
-use Unix::Syslog qw(:macros :subs);
-
-my $domain = $ARGV[0] || "example.com";
-
-while(1)
- {
- # my $rin = '',$rout;
- # vec($rin,fileno(STDIN),1) = 1;
- # $ein = $rin;
- # my $nfound = select($rout=$rin,undef,undef,undef);
-
- my $buf = "";
- syslog LOG_INFO,"waiting for packet";
- my $nread = sysread STDIN,$buf,2;
- do { syslog LOG_INFO,"port closed"; exit; } unless $nread == 2;
- my $len = unpack "n",$buf;
- my $nread = sysread STDIN,$buf,$len;
-
- my ($op,$user,$password) = split /:/,$buf;
- #$user =~ s/\./\//og;
- my $jid = "$user\@$domain";
- my $result;
-
- syslog(LOG_INFO,"request (%s)", $op);
-
- SWITCH:
- {
- $op eq 'auth' and do
- {
- $result = 1;
- },last SWITCH;
-
- $op eq 'setpass' and do
- {
- $result = 1;
- },last SWITCH;
-
- $op eq 'isuser' and do
- {
- # password is null. Return 1 if the user $user\@$domain exitst.
- $result = 1;
- },last SWITCH;
- };
- my $out = pack "nn",2,$result ? 1 : 0;
- syswrite STDOUT,$out;
- }
-
-closelog;
diff --git a/ejabberd-1.1.2/examples/mtr/ejabberd b/ejabberd-1.1.2/examples/mtr/ejabberd
deleted file mode 100644
index 4328b0697..000000000
--- a/ejabberd-1.1.2/examples/mtr/ejabberd
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/bin/sh
-#
-# PROVIDE: ejabberd
-# REQUIRE: DAEMON
-# KEYWORD: shutdown
-#
-
-HOME=/usr/pkg/jabber D=/usr/pkg/jabber/ejabberd export HOME
-
-name="ejabberd"
-rcvar=$name
-
-if [ -r /etc/rc.conf ]
-then
- . /etc/rc.conf
-else
- eval ${rcvar}=YES
-fi
-
-# $flags from environment overrides ${rcvar}_flags
-if [ -n "${flags}" ]
-then
- eval ${rcvar}_flags="${flags}"
-fi
-
-checkyesno()
-{
- eval _value=\$${1}
- case $_value in
- [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) return 0 ;;
- [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) return 1 ;;
- *)
- echo "\$${1} is not set properly."
- return 1
- ;;
- esac
-}
-
-cmd=${1:-start}
-case ${cmd} in
-force*)
- cmd=${cmd#force}
- eval ${rcvar}=YES
- ;;
-esac
-
-if checkyesno ${rcvar}
-then
-else
- exit 0
-fi
-
-case ${cmd} in
-start)
- if [ -x $D/src ]; then
- echo "Starting ${name}."
- cd $D/src
- ERL_MAX_PORTS=32000 export ERL_MAX_PORTS
- ulimit -n $ERL_MAX_PORTS
- su jabber -c "/usr/pkg/bin/erl -sname ejabberd -s ejabberd -heart -detached -sasl sasl_error_logger '{file, \"ejabberd-sasl.log\"}' &" \
- 1>/dev/null 2>&1
- fi
- ;;
-stop)
- echo "rpc:call('ejabberd@`hostname -s`', init, stop, [])." | \
- su jabber -c "/usr/pkg/bin/erl -sname ejabberdstop"
- ;;
-restart)
- echo "rpc:call('ejabberd@`hostname -s`', init, restart, [])." | \
- su jabber -c "/usr/pkg/bin/erl -sname ejabberdrestart"
- ;;
-*)
- echo "Usage: $0 {start|stop|restart}"
- exit 1
-esac
diff --git a/ejabberd-1.1.2/examples/mtr/ejabberd-netbsd.sh b/ejabberd-1.1.2/examples/mtr/ejabberd-netbsd.sh
deleted file mode 100644
index 9896c9bc4..000000000
--- a/ejabberd-1.1.2/examples/mtr/ejabberd-netbsd.sh
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/bin/sh
-
-echo '1. fetch, compile, and install erlang'
-
-if [ ! pkg_info erlang 1>/dev/null 2>&1 ]; then
- cd /usr/pkgsrc/lang/erlang
- make fetch-list|sh
- make
- make install
-fi
-if pkg_info erlang | grep -q erlang-9.1nb1; then
-else
- echo "erlang-9.1nb1 not installed" 1>&2
- exit 1
-fi
-
-
-echo '2. install crypt_drv.so'
-
-if [ ! -d /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib ] ; then
- mkdir -p /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib
-fi
-if [ ! -f /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib/crypto_drv.so ]; then
- cp work/otp*/lib/crypto/priv/*/*/crypto_drv.so \
- /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib
-fi
-
-
-echo '3. compile and install elibcrypto.so'
-
-if [ ! -f /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib/elibcrypto.so ]; then
-cd /usr/pkgsrc/lang/erlang/work/otp_src_R9B-1/lib/crypto/c_src
-ld -r -u CRYPTO_set_mem_functions -u MD5 -u MD5_Init -u MD5_Update \
- -u MD5_Final -u SHA1 -u SHA1_Init -u SHA1_Update -u SHA1_Final \
- -u des_set_key -u des_ncbc_encrypt -u des_ede3_cbc_encrypt \
- -L/usr/lib -lcrypto -o ../priv/obj/i386--netbsdelf/elibcrypto.o
-cc -shared \
- -L/usr/pkgsrc/lang/erlang/work/otp_src_R9B-1/lib/erl_interface/obj/i386--netbsdelf \
- -o ../priv/obj/i386--netbsdelf/elibcrypto.so \
- ../priv/obj/i386--netbsdelf/elibcrypto.o -L/usr/lib -lcrypto
-cp ../priv/obj/i386--netbsdelf/elibcrypto.so \
- /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib
-fi
-
-
-echo '4. compile and install ssl_esock'
-
-if [ ! -f /usr/pkg/lib/erlang/lib/ssl-2.3.5/priv/bin/ssl_esock ]; then
- cd /usr/pkg/lib/erlang/lib/ssl-2.3.5/priv/obj/
- make
-fi
-
-
-echo '5. initial ejabberd configuration'
-
-cd /usr/pkg/jabber/ejabberd/src
-./configure
-
-
-echo '6. edit ejabberd Makefiles'
-
-for M in Makefile mod_*/Makefile; do
- if [ ! -f $M.orig ]; then
- mv $M $M.orig
- sed -e s%/usr/local%/usr/pkg%g < $M.orig > $M
- fi
-done
-
-
-echo '7. compile ejabberd'
-
-gmake
-for A in mod_irc mod_muc mod_pubsub; do
- (cd $A; gmake)
-done
-
-
-echo ''
-echo 'now edit ejabberd.cfg'
-echo ''
-echo 'to start ejabberd: erl -sname ejabberd -s ejabberd'
diff --git a/ejabberd-1.1.2/examples/mtr/ejabberd.cfg b/ejabberd-1.1.2/examples/mtr/ejabberd.cfg
deleted file mode 100644
index 6f4f4b284..000000000
--- a/ejabberd-1.1.2/examples/mtr/ejabberd.cfg
+++ /dev/null
@@ -1,66 +0,0 @@
-% jabber.dbc.mtview.ca.us
-
-override_acls.
-
-{acl, admin, {user, "mrose", "jabber.dbc.mtview.ca.us"}}.
-
-
-{access, announce, [{allow, admin},
- {deny, all}]}.
-{access, c2s, [{deny, blocked},
- {allow, all}]}.
-{access, c2s_shaper, [{none, admin},
- {normal, all}]}.
-{access, configure, [{allow, admin},
- {deny, all}]}.
-{access, disco_admin, [{allow, admin},
- {deny, all}]}.
-{access, muc_admin, [{allow, admin},
- {deny, all}]}.
-{access, register, [{deny, all}]}.
-{access, s2s_shaper, [{fast, all}]}.
-
-
-{auth_method, internal}.
-{host, "jabber.dbc.mtview.ca.us"}.
-{outgoing_s2s_port, 5269}.
-{shaper, normal, {maxrate, 1000}}.
-{shaper, fast, {maxrate, 50000}}.
-{welcome_message, none}.
-
-
-{listen, [{5222, ejabberd_c2s,
- [{access, c2s},
- {shaper, c2s_shaper}]},
- {5223, ejabberd_c2s,
- [{access, c2s},
- {shaper, c2s_shaper},
- {ssl, [{certfile, "/etc/openssl/certs/ejabberd.pem"}]}]},
- {5269, ejabberd_s2s_in,
- [{shaper, s2s_shaper}]}]}.
-
-
-{modules, [
- {mod_register, []},
- {mod_roster, []},
- {mod_privacy, []},
- {mod_configure, []},
- {mod_disco, []},
- {mod_stats, []},
- {mod_vcard, []},
- {mod_offline, []},
- {mod_echo, [{host, "echo.jabber.dbc.mtview.ca.us"}]},
- {mod_private, []},
-% {mod_irc, []},
- {mod_muc, []},
- {mod_pubsub, []},
- {mod_time, []},
- {mod_last, []},
- {mod_version, []}
- ]}.
-
-
-
-% Local Variables:
-% mode: erlang
-% End:
diff --git a/ejabberd-1.1.2/examples/transport-configs/configs/aim-transport.xml b/ejabberd-1.1.2/examples/transport-configs/configs/aim-transport.xml
deleted file mode 100644
index 41804c69d..000000000
--- a/ejabberd-1.1.2/examples/transport-configs/configs/aim-transport.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-<!-- aim-transport.xml -->
-
-<jabber>
-
- <!--
- You need to add elogger and rlogger entries when using ejabberd.
- In this case the transport will do the logging.
- -->
-
- <log id='elogger'>
- <host/>
- <logtype/>
- <format>%d: [%t] (%h): %s</format>
- <file>/var/log/jabber/aim-transport-error.log</file>
- </log>
-
- <log id='rlogger'>
- <host/>
- <logtype>record</logtype>
- <format>%d %h %s</format>
- <file>/var/log/jabber/aim-transport-record.log</file>
- </log>
-
- <!--
- ejabberd do not provide XDB services.
- xdb_file.so is loaded in to handle all XDB requests.
- -->
-
- <xdb id="xdb">
- <host/>
- <load>
- <xdb_file>/usr/local/lib/jabber/libjabberdxdbfile.so</xdb_file> <!-- This file is part of jabberd-1.4.x. -->
- </load>
- <xdb_file xmlns="jabber:config:xdb_file">
- <spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>
- </xdb_file>
- </xdb>
-
- <!--
- Make sure that all host names here are resolveable via DNS if you
- want the transport to be available to the public.
- -->
-
- <service id='aim.SERVER.COM'>
- <!-- aim-transport configuration. -->
- <aimtrans xmlns='jabber:config:aimtrans'>
- <vCard>
- <FN>AIM/ICQ Transport</FN>
- <DESC>This is the AIM/ICQ Transport.</DESC>
- <MAIL>EMAIL@ADDRESS.COM</MAIL>
- <URL>http://aim-transport.jabberstudio.org/</URL>
- </vCard>
- <charset>cp1252</charset>
- </aimtrans>
- <!-- aim-transport module. -->
- <load>
- <aim_transport>/usr/local/lib/jabber/aim-transport.so</aim_transport>
- </load>
- </service>
-
- <!--
- The settings below have to match the settings you made
- in your ejabberd.cfg configuration file.
- -->
-
- <service id="icq-linker">
- <uplink/>
- <connect>
- <ip>127.0.0.1</ip>
- <port>5233</port>
- <secret>SECRET</secret>
- </connect>
- </service>
-
- <pidfile>/var/run/jabber/aim-transport.pid</pidfile>
-
-</jabber>
diff --git a/ejabberd-1.1.2/examples/transport-configs/configs/ile.xml b/ejabberd-1.1.2/examples/transport-configs/configs/ile.xml
deleted file mode 100644
index 5999f0fbd..000000000
--- a/ejabberd-1.1.2/examples/transport-configs/configs/ile.xml
+++ /dev/null
@@ -1,136 +0,0 @@
-<!-- ile.xml -->
-
-<config>
- <jabber>
- <server>127.0.0.1</server>
- <port>5238</port>
- <secret>SECRET</secret>
- <service>ile.SERVER.COM</service>
- <connectsleep>7</connectsleep> <!-- seconds to wait if we get disconnected -->
- <language>en</language>
- <vCard>
- <FN>I Love Email</FN>
- <DESC>With this service you can receive email notifications.
-
-Security warning: Be careful when using this. Your password will travel in clear from your client to your jabber server if you don't use SSL and it will probably travel in clear from the jabber server to your email server. Use with care. This shouldn't be an issue in your Intranet, but it is if you use an ILE installed in a foreign jabber server.</DESC>
- <MAIL>EMAIL@ADDRESS.COM</MAIL>
- <URL>http://ile.jabberstudio.org/</URL>
- </vCard>
- </jabber>
-
- <debug>
- <file>/var/log/jabber/ile.log</file>
- <level>1</level> <!-- man Net::Jabber::Debug -->
- </debug>
-
- <mail>
- <checkinterval>10</checkinterval> <!-- in minutes -->
- <timeout>20</timeout> <!-- timeout for IMAP/POP connection, in seconds -->
- </mail>
-
- <files>
- <users>/var/spool/jabber/ile.SERVER.COM/users.db</users>
- <passwords>/var/spool/jabber/ile.SERVER.COM/passwords.db</passwords>
- <hosts>/var/spool/jabber/ile.SERVER.COM/hosts.db</hosts>
- <types>/var/spool/jabber/ile.SERVER.COM/types.db</types>
- <notifyxa>/var/spool/jabber/ile.SERVER.COM/notifyxa.db</notifyxa>
- <notifydnd>/var/spool/jabber/ile.SERVER.COM/notifydnd.db</notifydnd>
- <urls>/var/spool/jabber/ile.SERVER.COM/urls.db</urls>
- </files>
-
- <form>
- <en>
- <instructions>Please fill in the fields,according to your email account settings and notification preferences</instructions>
- <title>ILE: Email notification service</title>
- <email_options>Email account settings</email_options>
- <user>Username</user>
- <pass>Password</pass>
- <host>Hostname</host>
- <type>Type</type>
- <newmail>You have received NUM email messages since last time I checked, which was CHECKINTERVAL minutes ago.</newmail>
- <errorcheck>There was an error while trying to check mail for ACCOUNT.</errorcheck>
- <notify_options>Notification Options</notify_options>
- <notifyxa>Notify even when Xtended Away (XA)</notifyxa>
- <notifydnd>Notify even when Do Not Disturb (DND)</notifydnd>
- <webmail_url>Webmail URL</webmail_url>
- <webmail_login>Login to ACCOUNT</webmail_login>
- <iledesc>ILE: an email notifier component: http://ile.jabberstudio.org</iledesc>
- </en>
-
- <es>
- <instructions>Por favor, rellene los campos del formulario.</instructions>
- <title>ILE: Servicio de notificación de correo</title>
- <email_options>Configuración de la cuenta de correo</email_options>
- <user>Usuario</user>
- <pass>Clave</pass>
- <host>Host</host>
- <type>Tipo</type>
- <newmail>Ha recibido NUM email(s) desde la última comprobación que fue hace CHECKINTERVAL minutos</newmail>
- <errorcheck>Ha habido un error en la comprobación del correo para la cuenta ACCOUNT.</errorcheck>
- <notify_options>Opciones de notificación</notify_options>
- <notifyxa>Notificar incluso si muy ausente (XA)</notifyxa>
- <notifydnd>Notificar incluso si no molestar (DND)</notifydnd>
- <webmail_url>Webmail URL</webmail_url>
- <webmail_login>Leer correo de ACCOUNT</webmail_login>
- <iledesc>ILE: un notificador de nuevo email - http://ile.jabberstudio.org</iledesc>
- </es>
-
- <ca>
- <instructions>Ompli els camps del formulari.</instructions>
- <title>ILE: Servei de notificació de nou email</title>
- <email_options>Dades del compte de mail</email_options>
- <user>Usuari</user>
- <pass>Clau</pass>
- <host>Host</host>
- <type>Tipus</type>
- <newmail>Ha rebut NUM email(s) des de la última comprobació que va ser fa CHECKINTERVAL minuts.</newmail>
- <errorcheck>S'ha produit un error en la comprobació del correu per al compte ACCOUNT.</errorcheck>
- <notify_options>Opcions de notificació</notify_options>
- <notifyxa>Notificar si molt absent (XA)</notifyxa>
- <notifydnd>Notificar si no molestar (DND)</notifydnd>
- <webmail_url>Webmail URL</webmail_url>
- <webmail_login>Llegir correu de ACCOUNT</webmail_login>
- <iledesc>ILE: un notificador de nou email - http://ile.jabberstudio.org</iledesc>
- </ca>
-
- <ro>
- <!-- Contributed by Adrian Rappa -->
- <instructions>Va rog completati urmatoarele campuri</instructions>
- <title>I Love Email: new email notification service</title>
- <email_options>Email account settings</email_options>
- <user>Nume utilizator</user>
- <pass>Parola</pass>
- <host>Nume gazda</host>
- <type>Tip</type>
- <newmail>Ati primit NUM mesaj(e) de la ultima verificare, care a fost acum CHECKINTERVAL minute.</newmail>
- <errorcheck>A fost eroare in timp ce incercam sa verific posta pentru ACCOUNT.</errorcheck>
- <notify_options>Notification Options</notify_options>
- <notifyxa>Notify even when Xtended Away (XA)</notifyxa>
- <notifydnd>Notify even when Do Not Disturb (DND)</notifydnd>
- <webmail_url>Webmail URL</webmail_url>
- <webmail_login>Login to ACCOUNT</webmail_login>
- <iledesc>ILE: an email notifier component: http://ile.jabberstudio.org</iledesc>
- </ro>
-
- <nl>
- <!-- Contributed by Sander Devrieze -->
- <instructions>Vul volgende velden in.</instructions>
- <title>ILE: Dienst voor e-mailnotificaties</title>
- <email_options>Instellingen van e-mailaccount</email_options>
- <user>Gebruikersnaam</user>
- <pass>Wachtwoord</pass>
- <host>Inkomende mailserver</host>
- <type>Type verbinding</type>
- <newmail>U hebt NUM berichten ontvangen sinds CHECKINTERVAL minuten geleden.</newmail>
- <errorcheck>Fout tijdens controle op nieuwe e-mails bij ACCOUNT. ILE zal deze account niet meer opnieuw controleren tot u uw registratiegegevens wijzigt of opnieuw aanmeldt.</errorcheck>
- <notify_options>Notificatie-instellingen</notify_options>
- <notifyxa>Notificeer ook in de status Niet Beschikbaar (XA)</notifyxa>
- <notifydnd>Notificeer ook in de status Niet Storen (DND)</notifydnd>
- <webmail_url>URL van webmail</webmail_url>
- <webmail_login>Aanmelden op ACCOUNT</webmail_login>
- <iledesc>ILE: een dienst om e-mailnotificaties te ontvangen: http://ile.jabberstudio.org</iledesc>
- </nl>
-
- </form>
-
-</config> \ No newline at end of file
diff --git a/ejabberd-1.1.2/examples/transport-configs/configs/jabber-gg-transport.xml b/ejabberd-1.1.2/examples/transport-configs/configs/jabber-gg-transport.xml
deleted file mode 100644
index 39d8c0b64..000000000
--- a/ejabberd-1.1.2/examples/transport-configs/configs/jabber-gg-transport.xml
+++ /dev/null
@@ -1,149 +0,0 @@
-<jggtrans>
-
- <service jid="gg.SERVER.COM"/>
-
- <!-- This connects the jabber-gg-transport process to ejabberd. -->
- <connect id="gglinker">
- <ip>127.0.0.1</ip>
- <port>5237</port>
- <secret>SECRET</secret>
- </connect>
-
- <register>
- <!-- This tag contains the message displayed to users at registration time.
- You can use <p/> and/or <br/> to break lines. Multiple spaces and newlines
- are converted to just one, so formatting of config file doesn't really matter. -->
- <instructions>
- Fill in your GG number (after "username")
- and password to register on the transport.
- <p/>To change your information in the GaduGadu directory you need to fill in the other fields.
- <p/>To remove registration you need to leave the form blank.
- </instructions>
- </register>
-
- <search>
- <!-- This tag contains the message displayed to users at search time. -->
- <instructions>
- To search people:<br/>
- First fill in surname or family name, nickname, city, birthyear or range of birthyears (eg. 1950-1960)
- and gender (you may fill in more fields at once).<br/>
- or<br/>
- Fill in phone number<br/>
- or<br/>
- Fill in the GG number of the person you are searching.
- </instructions>
- </search>
-
- <gateway>
- <!-- This is message, that may be displayed to user when adding gg contact. -->
- <desc>Please fill in the GaduGadu number of the person you want to add.</desc>
- <!-- And this is the prompt for GG number. -->
- <prompt>GG Nummer</prompt>
- </gateway>
-
- <vCard>
- <FN>Gadu-Gadu Transport</FN>
- <DESC>This is the Gadu-Gadu Transport.</DESC>
- <EMAIL>EMAIL@ADDRESS.COM</EMAIL>
- <URL>http://www.jabberstudio.org/projects/jabber-gg-transport/</URL>
- </vCard>
-
- <!-- Default user locale (language).
- Empty means system locale setting,
- no (or commented-out) <default_locale> tag means no translations. -->
- <!-- <default_locale>pl_PL</default_locale> -->
-
- <!-- Logger configuration.
- You may configure one logger of type "syslog" and/or one of type "file".
- You may also not configure logging at all. -->
- <log type="syslog" facility="local0"/>
- <log type="file">/var/log/jabber/jabber-gg-transport.log</log>
-
- <!-- Uncomment this, if you want proxy to be used for Gadu-Gadu connection. -->
- <!--
- <proxy>
- <ip>127.0.0.1</ip>
- <port>8080</port>
- </proxy>
- -->
-
- <!-- You can change these values according to your needs. -->
- <conn_timeout>60</conn_timeout>
- <ping_interval>10</ping_interval>
-
- <!-- Gadu-Gadu server doesn't seem to answer pings anymore :-(
- So let's give it 10 year :-) -->
- <pong_timeout>315360000</pong_timeout>
-
- <!-- This time after disconnection from Gadu-Gadu server the transport
- will try to connect again. -->
- <reconnect>300</reconnect>
-
- <!-- How long to wait before restart, after jabber server connection is broken
- negative value means, that jggtrans should terminate. -->
- <restart_timeout>60</restart_timeout>
-
- <!-- Delay between the unavailable presence is received from user and loggin out
- from Gadu-Gadu - for nice <presence type="invisible"/> support. -->
- <disconnect_delay>5</disconnect_delay>
-
- <!-- list of Gadu-Gadu servers to use.
- <hub/> means "use GG hub to find server"
- <server/> tag should contain server address and may contain "port"
- attribute with port number. When TLS is available (supported by libgadu)
- it will be used unless "tls" attribute is set to "no". Please notice,
- that not all servers will accept TLS connections.
- Servers (including hub) are tried in order as they appear in <servers/>
- element.
- A reasonable default server list is hardcoded in jggtrans.
- -->
- <!--
- <servers>
- <hub/>
- <server port="443">217.17.41.90</server>
- <server tls="no">217.17.41.85</server>
- <server tls="no">217.17.41.88</server>
- </servers>
- -->
-
- <!-- Spool directory. This is the place, where user info will be stored. -->
- <!-- Be careful about permissions - users' Gadu-Gadu passwords are stored there. -->
- <spool>/var/spool/jabber/gg.SERVER.COM/</spool>
-
- <!-- Where to store pid file. This tag is optional. -->
- <pidfile>/var/run/jabber/jabber-gg-transport.pid</pidfile>
-
- <!-- jid allowed to do some administrative task (eg. discovering online users).
- May be used multiple times. -->
- <admin>GG_TRANSPORT_ADMIN@SERVER.COM</admin>
-
- <!-- ACL gives detailed access control to the transport. -->
- <acl>
- <!-- Example entries: -->
-
- <allow who="admin@SERVER.COM" what="iq/query?xmlns=http://jabber.org/protocol/stats"/>
- <!-- will allow statistics gathering to admin@SERVER.COM -->
-
- <deny who="*" what="iq/query?xmlns=http://jabber.org/protocol/stats"/>
- <!-- will deny statistics gathering for anybody else -->
-
- <!-- <allow who="*@SERVER.COM"/> -->
- <!-- will allow anything else to users from "SERVER.COM" -->
-
- <!-- <deny what="iq/query?xmlns=jabber:x:register"/> -->
- <!-- will deny registration for all other users -->
-
- <!-- <allow what="presence"/> -->
- <!-- allow presence from anybody -->
-
- <!-- <allow what="iq"/> -->
- <!-- allow iq from anybody -->
-
- <!-- <allow what="message"/> -->
- <!-- allow message from anybody -->
-
- <!-- <deny/> -->
- <!-- will deny anything else -->
- </acl>
-
-</jggtrans>
diff --git a/ejabberd-1.1.2/examples/transport-configs/configs/jit.xml b/ejabberd-1.1.2/examples/transport-configs/configs/jit.xml
deleted file mode 100644
index c0d78c40a..000000000
--- a/ejabberd-1.1.2/examples/transport-configs/configs/jit.xml
+++ /dev/null
@@ -1,128 +0,0 @@
-<!-- jit.xml -->
-
-<jabber>
-
- <!--
- You need to add elogger and rlogger entries here when using ejabberd.
- In this case the transport will do the logging.
- -->
-
- <log id='elogger'>
- <host/>
- <logtype/>
- <file>/var/log/jabber/jit-error</file> <!-- WPJabber logs with date. -->
- </log>
-
- <log id='rlogger'>
- <host/>
- <logtype>record</logtype>
- <file>/var/log/jabber/jit-record</file> <!-- WPJabber logs with date. -->
- </log>
-
- <!--
- ejabberd do not provide XDB services.
- xdb_file-jit.so (the renamed xdb_file.so from WPJabber) is
- loaded in to handle all XDB requests.
- Read also the documentation in xdb_file/README from the JIT package.
- -->
-
- <xdb id="xdb">
- <host/>
- <load>
- <xdb_file>/usr/local/lib/jabber/xdb_file.so</xdb_file> <!-- The xdb_file.so from WPJabber/JIT. -->
- </load>
- <xdb_file xmlns="jabber:config:xdb_file">
- <spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>
- </xdb_file>
- </xdb>
-
- <!--
- Make sure that all host names here are resolveable via DNS if you
- want the transport to be available to the public.
- -->
-
- <service id="icq.SERVER.COM">
- <!--
- Replace SERVER.COM with the same as above to enable sms.
- -->
- <host>sms.icq.SERVER.COM</host>
- <!-- JIT configuration. -->
- <icqtrans xmlns="jabber:config:icqtrans">
- <sms>
- <host>sms.icq.SERVER.COM</host>
- <!-- Status of virtual "sms-contacts". -->
- <show>away</show>
- <status/>
- </sms>
- <instructions>Fill in your UIN and password.</instructions>
- <search>Search ICQ users.</search>
- <vCard>
- <FN>ICQ Transport (JIT)</FN>
- <DESC>This is the Jabber ICQ Transport.</DESC>
- <MAIL>EMAIL@ADDRESS.COM</MAIL>
- <URL>http://jit.jabberstudio.org/</URL>
- </vCard>
- <!-- Hashtable for users. -->
- <prime>3907</prime>
- <!-- Send messages from ICQ as chat to Jabber clients. -->
- <chat/>
- <!-- Enable this for ICQ web presence. -->
- <web/>
- <!--
- If you don't want jabber:x:data forms
- in reg and search uncomment this tag
- (Not recomended).
- -->
- <no_xdata/>
- <!--
- This tag is necessary when using ejabberd.
- In this way JIT will have its own contact list.
- -->
- <own_roster/>
- <!--
- When present, this tag will tell JIT not to try to
- get the user's roster (which will take a bit of time
- to fail in scenarios described above).
- -->
- <no_jabber_roster/>
- <!-- File with stats. -->
- <user_count_file>/var/spool/jabber/jit-count</user_count_file>
- <!--
- Interval beetween checking sessions: ping, messages, acks.
- -->
- <session_check>5</session_check>
- <!-- Reconnect retries. -->
- <reconnects>5</reconnects>
- <!--
- Time in sec when session can be inactive, 0=disabled.
- -->
- <session_timeout>18000</session_timeout>
- <charset>windows-1252</charset>
- <server>
- <host port="5190">login.icq.com</host>
- </server>
- </icqtrans>
- <!-- JIT module. -->
- <load>
- <icqtrans>/usr/local/lib/jabber/jit.so</icqtrans>
- </load>
- </service>
-
- <!--
- The settings below have to match the settings you made
- in your ejabberd.cfg configuration file.
- -->
-
- <service id="icq-linker">
- <host>SERVER.COM</host>
- <uplink/>
- <connect>
- <ip>127.0.0.1</ip>
- <port>5234</port>
- <secret>SECRET</secret>
- </connect>
- </service>
-
- <pidfile>/var/run/jabber/jit.pid</pidfile>
-
-</jabber>
diff --git a/ejabberd-1.1.2/examples/transport-configs/configs/msn-transport.xml b/ejabberd-1.1.2/examples/transport-configs/configs/msn-transport.xml
deleted file mode 100644
index a6f1391db..000000000
--- a/ejabberd-1.1.2/examples/transport-configs/configs/msn-transport.xml
+++ /dev/null
@@ -1,118 +0,0 @@
-<!-- msn-transport.xml -->
-
-<jabber>
-
- <!--
- You need to add elogger and rlogger entries here when using ejabberd.
- In this case the transport will do the logging.
- -->
-
- <log id='elogger'>
- <host/>
- <logtype/>
- <format>%d: [%t] (%h): %s</format>
- <file>/var/log/jabber/msn-transport-error.log</file>
- </log>
-
- <log id='rlogger'>
- <host/>
- <logtype>record</logtype>
- <format>%d %h %s</format>
- <file>/var/log/jabber/msn-transport-record.log</file>
- </log>
-
- <!--
- ejabberd do not provide XDB services.
- xdb_file.so is loaded in to handle all XDB requests.
- -->
-
- <xdb id="xdb">
- <host/>
- <load>
- <xdb_file>/usr/local/lib/jabber/libjabberdxdbfile.so</xdb_file>
- </load>
- <xdb_file xmlns="jabber:config:xdb_file">
- <spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>
- </xdb_file>
- </xdb>
-
- <!--
- Make sure that all host names here are resolveable via DNS if you
- want the transport to be available to the public.
- -->
-
- <service id="msn.SERVER.COM">
- <!-- msn-transport configuration. -->
- <msntrans xmlns="jabber:config:msntrans">
- <instructions>Fill in your MSN account and password (eg: user1@hotmail.com). A nickname is optional.</instructions>
- <vCard>
- <FN>MSN Transport</FN>
- <DESC>This is the MSN Transport.</DESC>
- <EMAIL>EMAIL@ADDRESS.COM</EMAIL>
- <URL>http://msn-transport.jabberstudio.org/</URL>
- </vCard>
- <!--
- Conference support allows you to create groupchat rooms on the
- msn-transport and invite MSN users to join.
- -->
- <conference id="conference.msn.SERVER.COM">
- <!--
- This will make MSN transport invite you to a special groupchat
- room when more then one user joins a normal one-on-one session.
- Joining this room will make MSN transport "switch" the session
- into groupchat mode. If you ignore it, MSN transport will
- continue to send the messages as one-on-one chats.
- -->
- <invite>More than one user entered this chat session. Enter this room to switch to groupchat modus.</invite>
- <notice>
- <join> is available</join>
- <leave> has leaved the room</leave>
- </notice>
- </conference>
- <!-- Enable Hotmail inbox notification. -->
- <headlines/>
- <!--
- Enable fancy friendly names
- If the user enters a nickname upon registration, and the user has
- a status message, their MSN friendly name will be "nickname - status message".
-
- If the user does not enter a nickname on registration, but they do have
- a status message, their friendly name will just be their status message.
-
- If the user did enter a nickname on registration, but they have a blank status message,
- then their friendly name will just be the registered nickname.
-
- If the user did not enter a nickname on registration, and they have a blank status message,
- their nickname will just be the username portion of their JID.
-
- If the above chosen friendly name is too long, then it will be truncated and "..." placed
- at the end. MSN only supports friendly names of 128 characters, so this is unavoidable.
-
- If this is disabled, then the registered nick is always sent as the MSN friendly name,
- or if that is blank, the username portion of their JID is sent instead.
- -->
- <fancy_friendly/>
- </msntrans>
- <!-- msn-transport module. -->
- <load>
- <msntrans>/usr/local/lib/jabber/msn-transport.so</msntrans>
- </load>
- </service>
-
- <!--
- The settings below have to match the settings you made
- in your ejabberd.cfg configuration file.
- -->
-
- <service id="msn-linker">
- <uplink/>
- <connect>
- <ip>127.0.0.1</ip>
- <port>5235</port>
- <secret>SECRET</secret>
- </connect>
- </service>
-
- <pidfile>/var/run/jabber/msn-transport.pid</pidfile>
-
-</jabber>
diff --git a/ejabberd-1.1.2/examples/transport-configs/configs/yahoo-transport-2.xml b/ejabberd-1.1.2/examples/transport-configs/configs/yahoo-transport-2.xml
deleted file mode 100644
index 2d077aa7a..000000000
--- a/ejabberd-1.1.2/examples/transport-configs/configs/yahoo-transport-2.xml
+++ /dev/null
@@ -1,86 +0,0 @@
-<!-- yahoo-transport-2.xml -->
-
-<jabber>
-
- <!--
- You need to add the elogger entry here when using ejabberd.
- In this case the transport will do the logging.
- -->
-
- <log id='elogger'>
- <host/>
- <logtype/>
- <format>%d: [%t] (%h): %s</format>
- <file>/var/log/jabber/yahoo-transport-2-error.log</file>
- <stderr/>
- </log>
-
- <!--
- ejabberd do not provide XDB services.
- xdb_file.so is loaded in to handle all XDB requests.
- -->
-
- <xdb id="xdb">
- <host/>
- <load>
- <xdb_file>/usr/local/lib/jabber/libjabberdxdbfile.so</xdb_file>
- </load>
- <xdb_file xmlns="jabber:config:xdb_file">
- <spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>
- </xdb_file>
- </xdb>
-
- <!--
- Make sure that all host names here are resolveable via DNS if you
- want the transport to be available to the public.
- -->
-
- <service id="yahoo.SERVER.COM">
- <!-- yahoo-transport-2 configuration. -->
- <config xmlns="jabber:config:yahoo">
- <vCard>
- <NAME>Yahoo! Transport</NAME>
- <FN>vCard not implemented in current version</FN>
- <DESC>This is the Yahoo! transport.</DESC>
- <MAIL>EMAIL@ADDRESS.COM</MAIL>
- <URL>http://yahoo-transport-2.jabberstudio.org/</URL>
- </vCard>
- <instructions>Fill in your YAHOO! Messenger username and password to register on this transport.</instructions>
- <server>scs.msg.yahoo.com</server>
- <port>5050</port>
- <!--
- The character map. This provides character set translation from UTF-8
- to the indicated character map. See the man page for 'iconv' for available
- character maps on your platform. CP1252 is the standard Windows character
- set.
- -->
- <charmap>CP1252</charmap>
- <!--
- When this element exists, the transport will send new mail notifications as
- well as a count of unread messages when the user initially logs in.
- -->
- <newmail/>
- </config>
- <!-- yahoo-transport-2 module. -->
- <load>
- <yahoo_transport>/usr/local/lib/jabber/yahoo-transport-2.so</yahoo_transport>
- </load>
- </service>
-
- <!--
- The settings below have to match the settings you made
- in your ejabberd.cfg configuration file.
- -->
-
- <service id="yahoo-linker">
- <uplink/>
- <connect>
- <ip>127.0.0.1</ip>
- <port>5236</port>
- <secret>SECRET</secret>
- </connect>
- </service>
-
- <pidfile>/var/run/jabber/yahoo-transport-2.pid</pidfile>
-
-</jabber>
diff --git a/ejabberd-1.1.2/examples/transport-configs/init-scripts/aim-transport b/ejabberd-1.1.2/examples/transport-configs/init-scripts/aim-transport
deleted file mode 100755
index e13d6572f..000000000
--- a/ejabberd-1.1.2/examples/transport-configs/init-scripts/aim-transport
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-#########################################################
-#
-# aim-transport -- script to start aim-transport.
-#
-#########################################################
-
-DAEMON=/usr/local/sbin/jabberd-aim-transport
-CONF=/etc/jabber/aim-transport.xml
-NAME=jabberd-aim-transport
-HOME=/etc/jabber/
-USER=ejabberd
-
-#########################################################
-
-if [ "`/usr/bin/whoami`" != "$USER" ]; then
-
- echo "You need to be" $USER "user to run this script."
- exit 1
-fi
-
-case "$1" in
- debug)
- test -f $DAEMON -a -f $CONF || exit 0
- echo "Starting $NAME in debugging mode."
- $DAEMON -D -H $HOME -c $CONF &
- ;;
- start)
- test -f $DAEMON -a -f $CONF || exit 0
- echo "Starting $NAME."
- $DAEMON -H $HOME -c $CONF &
- ;;
- stop)
- echo "Stopping $NAME."
- killall $NAME &
- ;;
- restart|reload)
- $0 stop
- sleep 3
- $0 start
- ;;
- *)
- echo "Usage: $0 {debug|start|stop|restart}"
- exit 1
-esac
diff --git a/ejabberd-1.1.2/examples/transport-configs/init-scripts/ile b/ejabberd-1.1.2/examples/transport-configs/init-scripts/ile
deleted file mode 100755
index a1e072f2c..000000000
--- a/ejabberd-1.1.2/examples/transport-configs/init-scripts/ile
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-#########################################################
-#
-# ile -- script to start ILE.
-#
-#########################################################
-
-DAEMON=/usr/local/sbin/ile.pl
-NAME=ile.pl
-CONF=/etc/jabber/ile.xml
-USER=ejabberd
-
-#########################################################
-
-if [ "`/usr/bin/whoami`" != "$USER" ]; then
-
- echo "You need to be" $USER "user to run this script."
- exit 1
-fi
-
-case "$1" in
- debug)
- echo "Not implemented yet. Starting in normal mode"
- $0 start
- ;;
- start)
- test -f $DAEMON || exit 0
- echo "Starting $NAME."
- $DAEMON $CONF &
- ;;
- stop)
- echo "Stopping $NAME."
- killall $NAME &
- ;;
- restart|reload)
- $0 stop
- sleep 3
- $0 start
- ;;
- *)
- echo "Usage: $0 {debug|start|stop|status|restart}"
- exit 1
-esac
diff --git a/ejabberd-1.1.2/examples/transport-configs/init-scripts/jabber-gg-transport b/ejabberd-1.1.2/examples/transport-configs/init-scripts/jabber-gg-transport
deleted file mode 100755
index 269685d0d..000000000
--- a/ejabberd-1.1.2/examples/transport-configs/init-scripts/jabber-gg-transport
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/sh
-#########################################################
-#
-# jabber-gg-transport -- script to start jabber-gg-transport.
-#
-#########################################################
-
-DAEMON=/usr/local/sbin/jggtrans
-CONF=/etc/jabber/jabber-gg-transport.xml
-NAME=jggtrans
-HOME=/etc/jabber/
-USER=ejabberd
-
-#########################################################
-
-if [ "`/usr/bin/whoami`" != "$USER" ]; then
-
- echo "You need to be" $USER "user to run this script."
- exit 1
-fi
-
-case "$1" in
- debug)
- test -f $DAEMON -a -f $CONF || exit 0
- echo "Starting $NAME in debugging mode."
- $DAEMON -D -H $HOME -c $CONF &
- ;;
- start)
- test -f $DAEMON -a -f $CONF || exit 0
- echo "Starting $NAME."
- $DAEMON $CONF &
- ;;
- stop)
- echo "Stopping $NAME."
- killall $NAME &
- rm /var/run/jabber/jabber-gg-transport.pid
- ;;
-
- restart|reload)
- $0 stop
- sleep 3
- $0 start
- ;;
- *)
- echo "Usage: $0 {debug|start|stop|restart}"
- exit 1
-esac
diff --git a/ejabberd-1.1.2/examples/transport-configs/init-scripts/jit b/ejabberd-1.1.2/examples/transport-configs/init-scripts/jit
deleted file mode 100755
index 55e000ee8..000000000
--- a/ejabberd-1.1.2/examples/transport-configs/init-scripts/jit
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-#########################################################
-#
-# jit -- script to start JIT.
-#
-#########################################################
-
-DAEMON=/usr/local/sbin/wpjabber-jit
-CONF=/etc/jabber/jit.xml
-NAME=wpjabber-jit
-HOME=/etc/jabber/
-USER=ejabberd
-
-#########################################################
-
-if [ "`/usr/bin/whoami`" != "$USER" ]; then
-
- echo "You need to be" $USER "user to run this script."
- exit 1
-fi
-
-case "$1" in
- debug)
- test -f $DAEMON -a -f $CONF || exit 0
- echo "Starting $NAME in debugging mode."
- $DAEMON -D -H $HOME -c $CONF &
- ;;
- start)
- test -f $DAEMON -a -f $CONF || exit 0
- echo "Starting $NAME."
- $DAEMON -H $HOME -c $CONF &
- ;;
- stop)
- echo "Stopping $NAME."
- killall $NAME &
- ;;
- restart|reload)
- $0 stop
- sleep 3
- $0 start
- ;;
- *)
- echo "Usage: $0 {debug|start|stop|restart}"
- exit 1
-esac
diff --git a/ejabberd-1.1.2/examples/transport-configs/init-scripts/msn-transport b/ejabberd-1.1.2/examples/transport-configs/init-scripts/msn-transport
deleted file mode 100755
index 555ba2b0f..000000000
--- a/ejabberd-1.1.2/examples/transport-configs/init-scripts/msn-transport
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/bin/sh
-#########################################################
-#
-# msn-transport -- script to start MSN Transport.
-#
-#########################################################
-
-DAEMON=/usr/local/sbin/jabberd-msn-transport
-CONF=/etc/jabber/msn-transport.xml
-NAME=jabberd-msn-transport
-HOME=/etc/jabber/
-USER=ejabberd
-
-#########################################################
-
-if [ "`/usr/bin/whoami`" != "$USER" ]; then
-
- echo "You need to be" $USER "user to run this script."
- exit 1
-fi
-
-case "$1" in
- strace)
- test -f $DAEMON -a -f $CONF || exit 0
- echo "Starting $NAME in strace mode."
- strace -o /opt/ejabberd/var/log/jabber/strace.log $DAEMON -H $HOME -c $CONF &
- ;;
- debug)
- test -f $DAEMON -a -f $CONF || exit 0
- echo "Starting $NAME in debugging mode."
- $DAEMON -D -H $HOME -c $CONF &
- ;;
- start)
- test -f $DAEMON -a -f $CONF || exit 0
- echo "Starting $NAME."
- $DAEMON -H $HOME -c $CONF &
- ;;
- stop)
- echo "Stopping $NAME."
- killall $NAME &
- ;;
- restart|reload)
- $0 stop
- sleep 3
- $0 start
- ;;
- *)
- echo "Usage: $0 {debug|start|stop|restart}"
- exit 1
-esac
diff --git a/ejabberd-1.1.2/examples/transport-configs/init-scripts/yahoo-transport-2 b/ejabberd-1.1.2/examples/transport-configs/init-scripts/yahoo-transport-2
deleted file mode 100755
index fde78a913..000000000
--- a/ejabberd-1.1.2/examples/transport-configs/init-scripts/yahoo-transport-2
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-##############################################################
-#
-# yahoo-transport-2 -- script to start Yahoo-transport-2.
-#
-#############################################################
-
-DAEMON=/usr/local/sbin/jabberd-yahoo-transport-2
-CONF=/etc/jabber/yahoo-transport-2.xml
-NAME=jabberd-yahoo-transport-2
-HOME=/etc/jabber/
-USER=ejabberd
-
-#############################################################
-
-if [ "`/usr/bin/whoami`" != "$USER" ]; then
-
- echo "You need to be" $USER "user to run this script."
- exit 1
-fi
-
-case "$1" in
- debug)
- test -f $DAEMON -a -f $CONF || exit 0
- echo "Starting $NAME in debugging mode."
- $DAEMON -D -H $HOME -c $CONF &
- ;;
- start)
- test -f $DAEMON -a -f $CONF || exit 0
- echo "Starting $NAME."
- $DAEMON -H $HOME -c $CONF &
- ;;
- stop)
- echo "Stopping $NAME."
- killall $NAME &
- ;;
- restart|reload)
- $0 stop
- sleep 3
- $0 start
- ;;
- *)
- echo "Usage: $0 {debug|start|stop|restart}"
- exit 1
-esac
diff --git a/ejabberd-1.1.2/src/.cvsignore b/ejabberd-1.1.2/src/.cvsignore
deleted file mode 100644
index 17278c08c..000000000
--- a/ejabberd-1.1.2/src/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-*.beam
diff --git a/ejabberd-1.1.2/src/Makefile.in b/ejabberd-1.1.2/src/Makefile.in
deleted file mode 100644
index 9b6095be0..000000000
--- a/ejabberd-1.1.2/src/Makefile.in
+++ /dev/null
@@ -1,109 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-EXPAT_CFLAGS = @EXPAT_CFLAGS@
-ERLANG_CFLAGS= @ERLANG_CFLAGS@
-
-EXPAT_LIBS = @EXPAT_LIBS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
- ERLC_FLAGS+=+debug_info
-endif
-
-ifdef ejabberd_debug
- ERLC_FLAGS+=-Dejabberd_debug
-endif
-
-ifeq (@roster_gateway_workaround@, true)
- ERLC_FLAGS+=-DROSTER_GATEWAY_WORKAROUND
-endif
-
-prefix = @prefix@
-
-SUBDIRS = @mod_irc@ @mod_pubsub@ @mod_muc@ @eldap@ @web@ stringprep @tls@ @odbc@ @ejabberd_zlib@
-ERLSHLIBS = expat_erl.so
-SOURCES = $(wildcard *.erl)
-BEAMS = $(SOURCES:.erl=.beam)
-
-DESTDIR =
-
-EJABBERDDIR = $(DESTDIR)@prefix@/var/lib/ejabberd
-BEAMDIR = $(EJABBERDDIR)/ebin
-PRIVDIR = $(EJABBERDDIR)/priv
-SODIR = $(PRIVDIR)/lib
-MSGSDIR = $(PRIVDIR)/msgs
-LOGDIR = $(DESTDIR)@prefix@/var/log/ejabberd
-ETCDIR = $(DESTDIR)@prefix@/etc/ejabberd
-
-ASN_FLAGS = -bber_bin +der +compact_bit_string +optimize +noobj
-
-ifeq ($(shell uname),Darwin)
-DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
-else
-# Assume Linux-style dynamic library flags
-DYNAMIC_LIB_CFLAGS = -fpic -shared
-endif
-
-all: $(ERLSHLIBS) compile-beam all-recursive
-
-compile-beam: XmppAddr.hrl $(BEAMS)
-
-%.beam: %.erl
- @ERLC@ -W $(ERLC_FLAGS) $<
-
-
-all-recursive install-recursive uninstall-recursive \
-clean-recursive distclean-recursive \
-mostlyclean-recursive maintainer-clean-recursive:
- @subdirs="$(SUBDIRS)"; for subdir in $$subdirs; do \
- target=`echo $@|sed 's,-recursive,,'`; \
- echo making $$target in $$subdir; \
- (cd $$subdir && $(MAKE) $$target) || exit 1; \
- done
-
-
-%.hrl: %.asn1
- @ERLC@ $(ASN_FLAGS) $<
-
-$(ERLSHLIBS): %.so: %.c
- gcc -Wall $(CFLAGS) $(LDFLAGS) $(LIBS) \
- $(subst ../,,$(subst .so,.c,$@)) \
- $(EXPAT_LIBS) $(EXPAT_CFLAGS) \
- $(ERLANG_LIBS) $(ERLANG_CFLAGS) \
- -o $@ $(DYNAMIC_LIB_CFLAGS)
-
-install: all
- install -d $(BEAMDIR)
- install -m 644 *.beam $(BEAMDIR)
- rm -f $(BEAMDIR)/configure.beam
- install -m 644 *.app $(BEAMDIR)
- install -d $(SODIR)
- install -m 644 *.so $(SODIR)
- install -d $(MSGSDIR)
- install -m 644 msgs/*.msg $(MSGSDIR)
- install -d $(ETCDIR)
- install -b -m 644 ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg
- install -d $(LOGDIR)
-
-clean: clean-recursive clean-local
-
-clean-local:
- rm -f *.beam $(ERLSHLIBS)
- rm -f XmppAddr.asn1db XmppAddr.erl XmppAddr.hrl
-
-distclean: distclean-recursive clean-local
- rm -f config.status
- rm -f config.log
- rm -f Makefile
-
-TAGS:
- etags *.erl
-
-Makefile: Makefile.in
diff --git a/ejabberd-1.1.2/src/Makefile.win32 b/ejabberd-1.1.2/src/Makefile.win32
deleted file mode 100644
index a3366d05a..000000000
--- a/ejabberd-1.1.2/src/Makefile.win32
+++ /dev/null
@@ -1,163 +0,0 @@
-
-include Makefile.inc
-
-ALL : build
-
-REL=..\release
-EREL=$(REL)\ejabberd-$(EJABBERD_VERSION)
-EBIN_DIR=$(EREL)\ebin
-SRC_DIR=$(EREL)\src
-PRIV_DIR=$(EREL)\priv
-SO_DIR=$(EREL)
-MSGS_DIR=$(EREL)\msgs
-WIN32_DIR=$(EREL)\win32
-DOC_DIR=$(EREL)\doc
-
-NSIS_SCRIPT=win32\ejabberd.nsi
-NSIS_HEADER=win32\ejabberd.nsh
-
-installer : $(NSIS_SCRIPT) $(NSIS_HEADER)
- makensis $(NSIS_SCRIPT)
-
-$(NSIS_HEADER) : Makefile.inc
- echo !define OUTFILEDIR "..\$(REL)" >$(NSIS_HEADER)
- echo !define TESTDIR "..\$(REL)\ejabberd-$(EJABBERD_VERSION)" >>$(NSIS_HEADER)
- echo !define VERSION "$(EJABBERD_VERSION)" >>$(NSIS_HEADER)
-
-release_clean :
- if exist $(REL) rd /s /q $(REL)
-
-
-release : build release_clean
- mkdir $(REL)
- mkdir $(EREL)
- mkdir $(EBIN_DIR)
- copy *.beam $(EBIN_DIR)
- @erase $(EBIN_DIR)\configure.beam
- copy *.app $(EBIN_DIR)
- copy *.dll $(SO_DIR)
- mkdir $(MSGS_DIR)
- copy msgs\*.msg $(MSGS_DIR)
- mkdir $(WIN32_DIR)
- copy win32\ejabberd.cfg $(EREL)
- copy win32\inetrc $(EREL)
- copy $(SYSTEMROOT)\system32\libeay32.dll $(EREL)
- copy $(SYSTEMROOT)\system32\ssleay32.dll $(EREL)
- copy win32\ejabberd.ico $(WIN32_DIR)
- mkdir $(SRC_DIR)
- copy *.app $(SRC_DIR)
- copy *.erl $(SRC_DIR)
- copy *.hrl $(SRC_DIR)
- copy *.c $(SRC_DIR)
- 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
- copy mod_pubsub\*.erl $(SRC_DIR)\mod_pubsub
- mkdir $(SRC_DIR)\stringprep
- copy stringprep\*.erl $(SRC_DIR)\stringprep
- copy stringprep\*.c $(SRC_DIR)\stringprep
- copy stringprep\*.tcl $(SRC_DIR)\stringprep
- mkdir $(SRC_DIR)\tls
- copy tls\*.erl $(SRC_DIR)\tls
- copy tls\*.c $(SRC_DIR)\tls
- mkdir $(SRC_DIR)\ejabberd_zlib
- copy ejabberd_zlib\*.erl $(SRC_DIR)\ejabberd_zlib
- copy ejabberd_zlib\*.c $(SRC_DIR)\ejabberd_zlib
- mkdir $(SRC_DIR)\web
- copy web\*.erl $(SRC_DIR)\web
- mkdir $(SRC_DIR)\odbc
- copy odbc\*.erl $(SRC_DIR)\odbc
- copy odbc\*.sql $(EREL)
- mkdir $(DOC_DIR)
- copy ..\doc\*.txt $(DOC_DIR)
- copy ..\doc\*.html $(DOC_DIR)
- copy ..\doc\*.png $(DOC_DIR)
-
-SOURCE = expat_erl.c
-OBJECT = expat_erl.o
-DLL = expat_erl.dll
-
-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
- nmake -nologo -f Makefile.win32
- cd ..\stringprep
- nmake -nologo -f Makefile.win32
- cd ..\tls
- nmake -nologo -f Makefile.win32
- cd ..\ejabberd_zlib
- nmake -nologo -f Makefile.win32
- cd ..\web
- nmake -nologo -f Makefile.win32
- cd ..\odbc
- nmake -nologo -f Makefile.win32
- cd ..
-
-compile-beam : XmppAddr.hrl
- erl -s make all report -noinput -s erlang halt
-
-XmppAddr.hrl : XmppAddr.asn1
- erlc -bber_bin +der +compact_bit_string +optimize +noobj XmppAddr.asn1
-
-CLEAN : clean-recursive clean-local
-
-clean-local :
- -@erase $(OBJECT)
- -@erase $(DLL)
- -@erase expat_erl.exp
- -@erase expat_erl.lib
- -@erase *.beam
- -@erase XmppAddr.asn1db
- -@erase XmppAddr.erl
- -@erase XmppAddr.hrl
-
-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
- nmake -nologo -f Makefile.win32 clean
- cd ..\stringprep
- nmake -nologo -f Makefile.win32 clean
- cd ..\tls
- nmake -nologo -f Makefile.win32 clean
- cd ..\ejabberd_zlib
- nmake -nologo -f Makefile.win32 clean
- cd ..\web
- nmake -nologo -f Makefile.win32 clean
- cd ..\odbc
- nmake -nologo -f Makefile.win32 clean
- cd ..
-
-distclean : release_clean clean
- -@erase $(NSIS_HEADER)
- -@erase Makefile.inc
-
-CC=cl.exe
-CC_FLAGS=-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT $(EXPAT_FLAG) -MD -Ox -I"$(ERLANG_DIR)\usr\include" -I"$(EI_DIR)\include" -I"$(EXPAT_DIR)\source\lib"
-
-LD=link.exe
-LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.lib" "$(EXPAT_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/ejabberd-1.1.2/src/XmppAddr.asn1 b/ejabberd-1.1.2/src/XmppAddr.asn1
deleted file mode 100644
index 14f350d3d..000000000
--- a/ejabberd-1.1.2/src/XmppAddr.asn1
+++ /dev/null
@@ -1,14 +0,0 @@
-XmppAddr { iso(1) identified-organization(3)
- dod(6) internet(1) security(5) mechanisms(5) pkix(7)
- id-on(8) id-on-xmppAddr(5) }
-
-DEFINITIONS EXPLICIT TAGS ::=
-BEGIN
-
-id-on-xmppAddr OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
- dod(6) internet(1) security(5) mechanisms(5) pkix(7)
- id-on(8) 5 }
-
-XmppAddr ::= UTF8String
-
-END
diff --git a/ejabberd-1.1.2/src/acl.erl b/ejabberd-1.1.2/src/acl.erl
deleted file mode 100644
index a4417a59d..000000000
--- a/ejabberd-1.1.2/src/acl.erl
+++ /dev/null
@@ -1,203 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : acl.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : ACL support
-%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(acl).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([start/0,
- to_record/3,
- add/3,
- add_list/3,
- match_rule/3,
- % for debugging only
- match_acl/3]).
-
--include("ejabberd.hrl").
-
--record(acl, {aclname, aclspec}).
-
-start() ->
- mnesia:create_table(acl,
- [{disc_copies, [node()]},
- {type, bag},
- {attributes, record_info(fields, acl)}]),
- mnesia:add_table_copy(acl, node(), ram_copies),
- ok.
-
-to_record(Host, ACLName, ACLSpec) ->
- #acl{aclname = {ACLName, Host}, aclspec = ACLSpec}.
-
-add(Host, ACLName, ACLSpec) ->
- F = fun() ->
- mnesia:write(#acl{aclname = {ACLName, Host},
- aclspec = ACLSpec})
- end,
- mnesia:transaction(F).
-
-add_list(Host, ACLs, Clear) ->
- F = fun() ->
- if
- Clear ->
- Ks = mnesia:select(
- acl, [{{acl, {'$1', Host}, '$2'}, [], ['$1']}]),
- lists:foreach(fun(K) ->
- mnesia:delete({acl, {K, Host}})
- end, Ks);
- true ->
- ok
- end,
- lists:foreach(fun(ACL) ->
- case ACL of
- #acl{aclname = ACLName,
- aclspec = ACLSpec} ->
- mnesia:write(
- #acl{aclname = {ACLName, Host},
- aclspec = ACLSpec})
- end
- end, ACLs)
- end,
- case mnesia:transaction(F) of
- {atomic, _} ->
- ok;
- _ ->
- false
- end.
-
-
-
-match_rule(global, Rule, JID) ->
- case Rule of
- all -> allow;
- none -> deny;
- _ ->
- case ejabberd_config:get_global_option({access, Rule, global}) of
- undefined ->
- deny;
- GACLs ->
- match_acls(GACLs, JID, global)
- end
- end;
-
-match_rule(Host, Rule, JID) ->
- case Rule of
- all -> allow;
- none -> deny;
- _ ->
- case ejabberd_config:get_global_option({access, Rule, global}) of
- undefined ->
- case ejabberd_config:get_global_option({access, Rule, Host}) of
- undefined ->
- deny;
- ACLs ->
- match_acls(ACLs, JID, Host)
- end;
- GACLs ->
- case ejabberd_config:get_global_option({access, Rule, Host}) of
- undefined ->
- match_acls(GACLs, JID, Host);
- ACLs ->
- case lists:reverse(GACLs) of
- [{allow, all} | Rest] ->
- match_acls(
- lists:reverse(Rest) ++ ACLs ++
- [{allow, all}],
- JID, Host);
- _ ->
- match_acls(GACLs ++ ACLs, JID, Host)
- end
- end
- end
- end.
-
-match_acls([], _, Host) ->
- deny;
-match_acls([{Access, ACL} | ACLs], JID, Host) ->
- case match_acl(ACL, JID, Host) of
- true ->
- Access;
- _ ->
- match_acls(ACLs, JID, Host)
- end.
-
-match_acl(ACL, JID, Host) ->
- case ACL of
- all -> true;
- none -> false;
- _ ->
- {User, Server, Resource} = jlib:jid_tolower(JID),
- lists:any(fun(#acl{aclspec = Spec}) ->
- case Spec of
- all ->
- true;
- {user, U} ->
- (U == User)
- andalso
- ((Host == Server) orelse
- ((Host == global) andalso
- lists:member(Server, ?MYHOSTS)));
- {user, U, S} ->
- (U == User) andalso (S == Server);
- {server, S} ->
- S == Server;
- {user_regexp, UR} ->
- ((Host == Server) orelse
- ((Host == global) andalso
- lists:member(Server, ?MYHOSTS)))
- andalso is_regexp_match(User, UR);
- {user_regexp, UR, S} ->
- (S == Server) andalso
- is_regexp_match(User, UR);
- {server_regexp, SR} ->
- is_regexp_match(Server, SR);
- {node_regexp, UR, SR} ->
- is_regexp_match(Server, SR) andalso
- is_regexp_match(User, UR);
- {user_glob, UR} ->
- ((Host == Server) orelse
- ((Host == global) andalso
- lists:member(Server, ?MYHOSTS)))
- andalso
- is_glob_match(User, UR);
- {user_glob, UR, S} ->
- (S == Server) andalso
- is_glob_match(User, UR);
- {server_glob, SR} ->
- is_glob_match(Server, SR);
- {node_glob, UR, SR} ->
- is_glob_match(Server, SR) andalso
- is_glob_match(User, UR);
- WrongSpec ->
- ?ERROR_MSG(
- "Wrong ACL expression: ~p~n"
- "Check your config file and reload it with the override_acls option enabled",
- [WrongSpec]),
- false
- end
- end,
- ets:lookup(acl, {ACL, global}) ++
- ets:lookup(acl, {ACL, Host}))
- end.
-
-is_regexp_match(String, RegExp) ->
- case regexp:first_match(String, RegExp) of
- nomatch ->
- false;
- {match, _, _} ->
- true;
- {error, ErrDesc} ->
- ?ERROR_MSG(
- "Wrong regexp ~p in ACL: ~p",
- [RegExp, lists:flatten(regexp:format_error(ErrDesc))]),
- false
- end.
-
-is_glob_match(String, Glob) ->
- is_regexp_match(String, regexp:sh_to_awk(Glob)).
-
-
diff --git a/ejabberd-1.1.2/src/aclocal.m4 b/ejabberd-1.1.2/src/aclocal.m4
deleted file mode 100644
index e24d334c7..000000000
--- a/ejabberd-1.1.2/src/aclocal.m4
+++ /dev/null
@@ -1,294 +0,0 @@
-AC_DEFUN(AM_WITH_EXPAT,
-[ AC_ARG_WITH(expat,
- [ --with-expat=PREFIX prefix where EXPAT is installed])
-
- EXPAT_CFLAGS=
- EXPAT_LIBS=
- if test x"$with_expat" != x; then
- EXPAT_CFLAGS="-I$with_expat/include"
- EXPAT_LIBS="-L$with_expat/lib"
- fi
-
- AC_CHECK_LIB(expat, XML_ParserCreate,
- [ EXPAT_LIBS="$EXPAT_LIBS -lexpat"
- expat_found=yes ],
- [ expat_found=no ],
- "$EXPAT_LIBS")
- if test $expat_found = no; then
- AC_MSG_ERROR([Could not find the Expat library])
- fi
- expat_save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $EXPAT_CFLAGS"
- AC_CHECK_HEADERS(expat.h, , expat_found=no)
- if test $expat_found = no; then
- AC_MSG_ERROR([Could not find expat.h])
- fi
- CFLAGS="$expat_save_CFLAGS"
-
- AC_SUBST(EXPAT_CFLAGS)
- AC_SUBST(EXPAT_LIBS)
-])
-
-AC_DEFUN(AM_WITH_ZLIB,
-[ AC_ARG_WITH(zlib,
- [ --with-zlib=PREFIX prefix where zlib is installed])
-
- ZLIB_CFLAGS=
- ZLIB_LIBS=
- if test x"$with_zlib" != x; then
- ZLIB_CFLAGS="-I$with_zlib/include"
- ZLIB_LIBS="-L$with_zlib/lib"
- fi
-
- AC_CHECK_LIB(z, gzgets,
- [ ZLIB_LIBS="$ZLIB_LIBS -lz"
- zlib_found=yes ],
- [ zlib_found=no ],
- "$ZLIB_LIBS")
- if test $zlib_found = no; then
- AC_MSG_ERROR([Could not find the zlib library])
- fi
- zlib_save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $ZLIB_CFLAGS"
- AC_CHECK_HEADERS(zlib.h, , zlib_found=no)
- if test $zlib_found = no; then
- AC_MSG_ERROR([Could not find zlib.h])
- fi
- CFLAGS="$zlib_save_CFLAGS"
-
- AC_SUBST(ZLIB_CFLAGS)
- AC_SUBST(ZLIB_LIBS)
-])
-
-AC_DEFUN(AM_WITH_ERLANG,
-[ AC_ARG_WITH(erlang,
- [ --with-erlang=PREFIX path to erlc and erl ])
-
-
- AC_PATH_TOOL(ERLC, erlc, , $PATH:$with_erlang:$with_erlang/bin)
- AC_PATH_TOOL(ERL, erl, , $PATH:$with_erlang:$with_erlang/bin)
-
- if test "z$ERLC" = "z" || test "z$ERL" = "z"; then
- AC_MSG_ERROR([erlang not found])
- fi
-
-
- cat >>conftest.erl <<_EOF
-
--module(conftest).
--author('alexey@sevcom.net').
-
--export([[start/0]]).
-
-start() ->
- EIDirS = code:lib_dir("erl_interface") ++ "\n",
- EILibS = libpath("erl_interface") ++ "\n",
- RootDirS = code:root_dir() ++ "\n",
- file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ RootDirS)),
- halt().
-
-%% return physical architecture based on OS/Processor
-archname() ->
- ArchStr = erlang:system_info(system_architecture),
- case os:type() of
- {win32, _} -> "windows";
- {unix,UnixName} ->
- Specs = string:tokens(ArchStr,"-"),
- Cpu = case lists:nth(2,Specs) of
- "pc" -> "x86";
- _ -> hd(Specs)
- end,
- atom_to_list(UnixName) ++ "-" ++ Cpu;
- _ -> "generic"
- end.
-
-%% Return arch-based library path or a default value if this directory
-%% does not exist
-libpath(App) ->
- PrivDir = code:priv_dir(App),
- ArchDir = archname(),
- LibArchDir = filename:join([[PrivDir,"lib",ArchDir]]),
- case file:list_dir(LibArchDir) of
- %% Arch lib dir exists: We use it
- {ok, _List} -> LibArchDir;
- %% Arch lib dir does not exist: Return the default value
- %% ({error, enoent}):
- _Error -> code:lib_dir("erl_interface") ++ "/lib"
- end.
-
-_EOF
-
- if ! $ERLC conftest.erl; then
- AC_MSG_ERROR([could not compile sample program])
- fi
-
- if ! $ERL -s conftest -noshell; then
- AC_MSG_ERROR([could not run sample program])
- fi
-
- if ! test -f conftest.out; then
- AC_MSG_ERROR([erlang program was not properly executed, (conftest.out was not produced)])
- fi
-
- # First line
- ERLANG_EI_DIR=`cat conftest.out | head -n 1`
- # Second line
- ERLANG_EI_LIB=`cat conftest.out | head -n 2 | tail -n 1`
- # Third line
- ERLANG_DIR=`cat conftest.out | tail -n 1`
-
- ERLANG_CFLAGS="-I$ERLANG_EI_DIR/include -I$ERLANG_DIR/usr/include"
- ERLANG_LIBS="-L$ERLANG_EI_LIB -lerl_interface -lei"
-
- AC_SUBST(ERLANG_CFLAGS)
- AC_SUBST(ERLANG_LIBS)
- AC_SUBST(ERLC)
- AC_SUBST(ERL)
-])
-
-
-AC_DEFUN(AC_MOD_ENABLE,
-[
-$1=
-make_$1=
-AC_MSG_CHECKING([whether build $1])
-AC_ARG_ENABLE($1,
- [ --enable-$1 enable $1 (default: $2)],
- [mr_enable_$1="$enableval"],
- [mr_enable_$1=$2])
-if test "$mr_enable_$1" = "yes"; then
-$1=$1
-make_$1=$1/Makefile
-fi
-AC_MSG_RESULT($mr_enable_$1)
-AC_SUBST($1)
-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],
-[ --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 <stdlib.h>
-#include <iconv.h>],
- [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 <stdlib.h>
-#include <iconv.h>],
- [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 <stdlib.h>
-#include <iconv.h>],
- [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 <stdlib.h>
-#include <iconv.h>
-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 <openssl>
-AC_DEFUN(AM_WITH_OPENSSL,
-[ AC_ARG_WITH(openssl,
- [ --with-openssl=PREFIX prefix where OPENSSL is installed ])
-unset SSL_LIBS;
-unset SSL_CFLAGS;
-have_openssl=no
-if test x"$tls" != x; then
- for ssl_prefix in $withval /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr; do
- printf "looking for openssl in $ssl_prefix...\n"
- SSL_CFLAGS="-I$ssl_prefix/include/openssl"
- SSL_LIBS="-L$ssl_prefix/lib -lcrypto"
- AC_CHECK_LIB(ssl, SSL_new, [ have_openssl=yes ], [ have_openssl=no ], [ $SSL_LIBS $SSL_CFLAGS ])
- if test x"$have_openssl" = xyes; then
- save_CPPFLAGS=$CPPFLAGS
- CPPFLAGS="-I$ssl_prefix/lib $CPPFLAGS"
- AC_CHECK_HEADERS(openssl/ssl.h, have_openssl_h=yes)
- CPPFLAGS=$save_CPPFLAGS
- if test x"$have_openssl_h" = xyes; then
- have_openssl=yes
- printf "openssl found in $ssl_prefix\n";
- SSL_LIBS="-L$ssl_prefix/lib -lssl -lcrypto"
- CPPFLAGS="-I$ssl_prefix/lib $CPPFLAGS"
- SSL_CFLAGS="-DHAVE_SSL"
- break
- fi
- fi
- done
-if test x${have_openssl} != xyes; then
- AC_MSG_ERROR([openssl library cannot be found. Install openssl or disable `tls' module (--disable-tls).])
-fi
-AC_SUBST(SSL_LIBS)
-AC_SUBST(SSL_CFLAGS)
-fi
-])
-dnl <openssl/>
diff --git a/ejabberd-1.1.2/src/adhoc.erl b/ejabberd-1.1.2/src/adhoc.erl
deleted file mode 100644
index b6954d2ec..000000000
--- a/ejabberd-1.1.2/src/adhoc.erl
+++ /dev/null
@@ -1,111 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : adhoc.erl
-%%% Author : Magnus Henoch <henoch@dtek.chalmers.se>
-%%% Purpose : Provide helper functions for ad-hoc commands (JEP-0050)
-%%% Created : 31 Oct 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(adhoc).
--author('henoch@dtek.chalmers.se').
--vsn('$Revision$ ').
-
--export([parse_request/1,
- produce_response/2,
- produce_response/1]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include("adhoc.hrl").
-
-%% Parse an ad-hoc request. Return either an adhoc_request record or
-%% an {error, ErrorType} tuple.
-parse_request(#iq{type = set, lang = Lang, sub_el = SubEl, xmlns = ?NS_COMMANDS}) ->
- ?DEBUG("entering parse_request...", []),
- Node = xml:get_tag_attr_s("node", SubEl),
- SessionID = xml:get_tag_attr_s("sessionid", SubEl),
- Action = xml:get_tag_attr_s("action", SubEl),
- XData = find_xdata_el(SubEl),
- {xmlelement, _, _, AllEls} = SubEl,
- if XData ->
- Others = lists:delete(XData, AllEls);
- true ->
- Others = AllEls
- end,
-
- #adhoc_request{lang = Lang,
- node = Node,
- sessionid = SessionID,
- action = Action,
- xdata = XData,
- others = Others};
-parse_request(_) ->
- {error, ?ERR_BAD_REQUEST}.
-
-%% Borrowed from mod_vcard.erl
-find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) ->
- find_xdata_el1(SubEls).
-
-find_xdata_el1([]) ->
- false;
-find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_XDATA ->
- {xmlelement, Name, Attrs, SubEls};
- _ ->
- find_xdata_el1(Els)
- end;
-find_xdata_el1([_ | Els]) ->
- find_xdata_el1(Els).
-
-%% Produce a <command/> node to use as response from an adhoc_response
-%% record, filling in values for language, node and session id from
-%% the request.
-produce_response(#adhoc_request{lang = Lang,
- node = Node,
- sessionid = SessionID},
- Response) ->
- produce_response(Response#adhoc_response{lang = Lang,
- node = Node,
- sessionid = SessionID}).
-
-%% Produce a <command/> node to use as response from an adhoc_response
-%% record.
-produce_response(#adhoc_response{lang = _Lang,
- node = Node,
- sessionid = ProvidedSessionID,
- status = Status,
- defaultaction = DefaultAction,
- actions = Actions,
- notes = Notes,
- elements = Elements}) ->
- SessionID = if is_list(ProvidedSessionID), ProvidedSessionID /= "" ->
- ProvidedSessionID;
- true ->
- jlib:now_to_utc_string(now())
- end,
- case Actions of
- [] ->
- ActionsEls = [];
- _ ->
- case DefaultAction of
- "" ->
- ActionsElAttrs = [];
- _ ->
- ActionsElAttrs = [{"execute", DefaultAction}]
- end,
- ActionsEls = [{xmlelement, "actions",
- ActionsElAttrs,
- [{xmlelement, Action, [], []} || Action <- Actions]}]
- end,
- NotesEls = lists:map(fun({Type, Text}) ->
- {xmlelement, "note",
- [{"type", Type}],
- [{xmlcdata, Text}]}
- end, Notes),
- {xmlelement, "command",
- [{"xmlns", ?NS_COMMANDS},
- {"sessionid", SessionID},
- {"node", Node},
- {"status", atom_to_list(Status)}],
- ActionsEls ++ NotesEls ++ Elements}.
diff --git a/ejabberd-1.1.2/src/adhoc.hrl b/ejabberd-1.1.2/src/adhoc.hrl
deleted file mode 100644
index 2888a6639..000000000
--- a/ejabberd-1.1.2/src/adhoc.hrl
+++ /dev/null
@@ -1,15 +0,0 @@
--record(adhoc_request, {lang,
- node,
- sessionid,
- action,
- xdata,
- others}).
-
--record(adhoc_response, {lang,
- node,
- sessionid,
- status,
- defaultaction = "",
- actions = [],
- notes = [],
- elements = []}).
diff --git a/ejabberd-1.1.2/src/configure b/ejabberd-1.1.2/src/configure
deleted file mode 100755
index 3172e8e36..000000000
--- a/ejabberd-1.1.2/src/configure
+++ /dev/null
@@ -1,6558 +0,0 @@
-#! /bin/sh
-# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59d for FULL-PACKAGE-NAME VERSION.
-#
-# Report bugs to <BUG-REPORT-ADDRESS>.
-#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-## --------------------- ##
-## M4sh Initialization. ##
-## --------------------- ##
-
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
- as_unset=unset
-else
- as_unset=false
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-as_nl='
-'
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-case $0 in
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- { (exit 1); exit 1; }
-fi
-
-# Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-for as_var in \
- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
- LC_TELEPHONE LC_TIME
-do
- if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
- eval $as_var=C; export $as_var
- else
- ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
- fi
-done
-
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-
-# Name of the executable.
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# CDPATH.
-$as_unset CDPATH
-
-
-if test "x$CONFIG_SHELL" = x; then
- if (eval ":") 2>/dev/null; then
- as_have_required=yes
-else
- as_have_required=no
-fi
-
- if test $as_have_required = yes && (eval ":
-(as_func_return () {
- (exit \$1)
-}
-as_func_success () {
- as_func_return 0
-}
-as_func_failure () {
- as_func_return 1
-}
-as_func_ret_success () {
- return 0
-}
-as_func_ret_failure () {
- return 1
-}
-
-exitcode=0
-if as_func_success; then
- :
-else
- exitcode=1
- echo as_func_success failed.
-fi
-
-if as_func_failure; then
- exitcode=1
- echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
- :
-else
- exitcode=1
- echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
- exitcode=1
- echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
- :
-else
- exitcode=1
- echo positional parameters were not saved.
-fi
-
-test \$exitcode = 0) || { (exit 1); exit 1; }
-
-(
- as_lineno_1=\$LINENO
- as_lineno_2=\$LINENO
- test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
- test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
-") 2> /dev/null; then
- :
-else
- as_candidate_shells=
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- case $as_dir in
- /*)
- for as_base in sh bash ksh sh5; do
- as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
- done;;
- esac
-done
-IFS=$as_save_IFS
-
-
- for as_shell in $as_candidate_shells $SHELL; do
- # Try only shells which exist, to save several forks.
- if test -f "$as_shell" &&
- { ("$as_shell") 2> /dev/null <<\_ASEOF
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-:
-_ASEOF
-}; then
- CONFIG_SHELL=$as_shell
- as_have_required=yes
- if { "$as_shell" 2> /dev/null <<\_ASEOF
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-:
-(as_func_return () {
- (exit $1)
-}
-as_func_success () {
- as_func_return 0
-}
-as_func_failure () {
- as_func_return 1
-}
-as_func_ret_success () {
- return 0
-}
-as_func_ret_failure () {
- return 1
-}
-
-exitcode=0
-if as_func_success; then
- :
-else
- exitcode=1
- echo as_func_success failed.
-fi
-
-if as_func_failure; then
- exitcode=1
- echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
- :
-else
- exitcode=1
- echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
- exitcode=1
- echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = "$1" ); then
- :
-else
- exitcode=1
- echo positional parameters were not saved.
-fi
-
-test $exitcode = 0) || { (exit 1); exit 1; }
-
-(
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
-
-_ASEOF
-}; then
- break
-fi
-
-fi
-
- done
-
- if test "x$CONFIG_SHELL" != x; then
- for as_var in BASH_ENV ENV
- do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
- done
- export CONFIG_SHELL
- exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
-fi
-
-
- if test $as_have_required = no; then
- echo This script requires a shell more modern than all the
- echo shells that I found on your system. Please install a
- echo modern shell, or manually run the script under such a
- echo shell if you do have one.
- { (exit 1); exit 1; }
-fi
-
-
-fi
-
-fi
-
-
-
-(eval "as_func_return () {
- (exit \$1)
-}
-as_func_success () {
- as_func_return 0
-}
-as_func_failure () {
- as_func_return 1
-}
-as_func_ret_success () {
- return 0
-}
-as_func_ret_failure () {
- return 1
-}
-
-exitcode=0
-if as_func_success; then
- :
-else
- exitcode=1
- echo as_func_success failed.
-fi
-
-if as_func_failure; then
- exitcode=1
- echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
- :
-else
- exitcode=1
- echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
- exitcode=1
- echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
- :
-else
- exitcode=1
- echo positional parameters were not saved.
-fi
-
-test \$exitcode = 0") || {
- echo No shell found that supports shell functions.
- echo Please tell autoconf@gnu.org about your system,
- echo including any error possibly output before this
- echo message
-}
-
-
-
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
-
- # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
- # uniformly replaced by the line number. The first 'sed' inserts a
- # line-number line after each line using $LINENO; the second 'sed'
- # does the real work. The second script uses 'N' to pair each
- # line-number line with the line containing $LINENO, and appends
- # trailing '-' during substitution so that $LINENO is not a special
- # case at line end.
- # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
- # scripts with optimization help from Paolo Bonzini. Blame Lee
- # E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
- { (exit 1); exit 1; }; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-
-if (dirname -- /) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
--n*)
- case `echo 'x\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- *) ECHO_C='\c';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir
-fi
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
-elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p=:
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-# Find out whether ``test -x'' works. Don't use a zero-byte file, as
-# systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
- as_executable_p="test -x"
-else
- as_executable_p=:
-fi
-rm -f conf$$.file
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-
-exec 7<&0 </dev/null 6>&1
-
-# Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_clean_files=
-ac_config_libobj_dir=.
-LIBOBJS=
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-# Identity of this package.
-PACKAGE_NAME='FULL-PACKAGE-NAME'
-PACKAGE_TARNAME='full-package-name'
-PACKAGE_VERSION='VERSION'
-PACKAGE_STRING='FULL-PACKAGE-NAME VERSION'
-PACKAGE_BUGREPORT='BUG-REPORT-ADDRESS'
-
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include <stdio.h>
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#if STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# if HAVE_STDLIB_H
-# include <stdlib.h>
-# endif
-#endif
-#if HAVE_STRING_H
-# if !STDC_HEADERS && HAVE_MEMORY_H
-# include <memory.h>
-# endif
-# include <string.h>
-#endif
-#if HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif"
-
-ac_default_prefix=
-ac_subst_vars='SHELL
-PATH_SEPARATOR
-PACKAGE_NAME
-PACKAGE_TARNAME
-PACKAGE_VERSION
-PACKAGE_STRING
-PACKAGE_BUGREPORT
-exec_prefix
-prefix
-program_transform_name
-bindir
-sbindir
-libexecdir
-datarootdir
-datadir
-sysconfdir
-sharedstatedir
-localstatedir
-includedir
-oldincludedir
-docdir
-infodir
-htmldir
-dvidir
-pdfdir
-psdir
-libdir
-localedir
-mandir
-DEFS
-ECHO_C
-ECHO_N
-ECHO_T
-LIBS
-build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-CPPFLAGS
-ac_ct_CC
-EXEEXT
-OBJEXT
-SET_MAKE
-ERLC
-ERL
-ERLANG_CFLAGS
-ERLANG_LIBS
-LIBICONV
-CPP
-GREP
-EGREP
-EXPAT_CFLAGS
-EXPAT_LIBS
-ZLIB_CFLAGS
-ZLIB_LIBS
-LIBOBJS
-mod_pubsub
-make_mod_pubsub
-mod_irc
-make_mod_irc
-mod_muc
-make_mod_muc
-eldap
-make_eldap
-web
-make_web
-tls
-make_tls
-odbc
-make_odbc
-ejabberd_zlib
-make_ejabberd_zlib
-roster_gateway_workaround
-db_type
-SSL_LIBS
-SSL_CFLAGS
-LTLIBOBJS'
-ac_subst_files=''
- ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-CPPFLAGS
-CPP'
-
-
-# Initialize some variables set by options.
-ac_init_help=
-ac_init_version=false
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-cache_file=/dev/null
-exec_prefix=NONE
-no_create=
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-verbose=
-x_includes=NONE
-x_libraries=NONE
-
-# Installation directory options.
-# These are left unexpanded so users can "make install exec_prefix=/foo"
-# and all the variables that are supposed to be based on exec_prefix
-# by default will actually change.
-# Use braces instead of parens because sh, perl, etc. also accept them.
-# (The list follows the same order as the GNU Coding Standards.)
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datarootdir='${prefix}/share'
-datadir='${datarootdir}'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
-infodir='${datarootdir}/info'
-htmldir='${docdir}'
-dvidir='${docdir}'
-pdfdir='${docdir}'
-psdir='${docdir}'
-libdir='${exec_prefix}/lib'
-localedir='${datarootdir}/locale'
-mandir='${datarootdir}/man'
-
-ac_prev=
-ac_dashdash=
-for ac_option
-do
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval $ac_prev=\$ac_option
- ac_prev=
- continue
- fi
-
- case $ac_option in
- *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
- *) ac_optarg=yes ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case $ac_dashdash$ac_option in
- --)
- ac_dashdash=yes ;;
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir=$ac_optarg ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build_alias ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build_alias=$ac_optarg ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file=$ac_optarg ;;
-
- --config-cache | -C)
- cache_file=config.cache ;;
-
- -datadir | --datadir | --datadi | --datad)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=*)
- datadir=$ac_optarg ;;
-
- -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
- | --dataroo | --dataro | --datar)
- ac_prev=datarootdir ;;
- -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
- | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
- datarootdir=$ac_optarg ;;
-
- -disable-* | --disable-*)
- ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid feature name: $ac_feature" >&2
- { (exit 1); exit 1; }; }
- ac_feature=`echo $ac_feature | sed 's/-/_/g'`
- eval enable_$ac_feature=no ;;
-
- -docdir | --docdir | --docdi | --doc | --do)
- ac_prev=docdir ;;
- -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
- docdir=$ac_optarg ;;
-
- -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
- ac_prev=dvidir ;;
- -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
- dvidir=$ac_optarg ;;
-
- -enable-* | --enable-*)
- ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid feature name: $ac_feature" >&2
- { (exit 1); exit 1; }; }
- ac_feature=`echo $ac_feature | sed 's/-/_/g'`
- eval enable_$ac_feature=\$ac_optarg ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix=$ac_optarg ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he | -h)
- ac_init_help=long ;;
- -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
- ac_init_help=recursive ;;
- -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
- ac_init_help=short ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host_alias ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host_alias=$ac_optarg ;;
-
- -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
- ac_prev=htmldir ;;
- -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
- | --ht=*)
- htmldir=$ac_optarg ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir=$ac_optarg ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir=$ac_optarg ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir=$ac_optarg ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir=$ac_optarg ;;
-
- -localedir | --localedir | --localedi | --localed | --locale)
- ac_prev=localedir ;;
- -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
- localedir=$ac_optarg ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst | --locals)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
- localstatedir=$ac_optarg ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir=$ac_optarg ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c | -n)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir=$ac_optarg ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix=$ac_optarg ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix=$ac_optarg ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix=$ac_optarg ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name=$ac_optarg ;;
-
- -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
- ac_prev=pdfdir ;;
- -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
- pdfdir=$ac_optarg ;;
-
- -psdir | --psdir | --psdi | --psd | --ps)
- ac_prev=psdir ;;
- -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
- psdir=$ac_optarg ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir=$ac_optarg ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir=$ac_optarg ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site=$ac_optarg ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir=$ac_optarg ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir=$ac_optarg ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target_alias ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target_alias=$ac_optarg ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers | -V)
- ac_init_version=: ;;
-
- -with-* | --with-*)
- ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid package name: $ac_package" >&2
- { (exit 1); exit 1; }; }
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- eval with_$ac_package=\$ac_optarg ;;
-
- -without-* | --without-*)
- ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid package name: $ac_package" >&2
- { (exit 1); exit 1; }; }
- ac_package=`echo $ac_package | sed 's/-/_/g'`
- eval with_$ac_package=no ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes=$ac_optarg ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries=$ac_optarg ;;
-
- -*) { echo "$as_me: error: unrecognized option: $ac_option
-Try \`$0 --help' for more information." >&2
- { (exit 1); exit 1; }; }
- ;;
-
- *=*)
- ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
- # Reject names that are not valid shell variable names.
- expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
- { (exit 1); exit 1; }; }
- eval $ac_envvar=\$ac_optarg
- export $ac_envvar ;;
-
- *)
- # FIXME: should be removed in autoconf 3.0.
- echo "$as_me: WARNING: you should use --build, --host, --target" >&2
- expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- echo "$as_me: WARNING: invalid host type: $ac_option" >&2
- : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- { echo "$as_me: error: missing argument to $ac_option" >&2
- { (exit 1); exit 1; }; }
-fi
-
-# Be sure to have absolute directory names.
-for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
- datadir sysconfdir sharedstatedir localstatedir includedir \
- oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
-do
- eval ac_val=\$$ac_var
- case $ac_val in
- [\\/$]* | ?:[\\/]* ) continue;;
- NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
- esac
- { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
- { (exit 1); exit 1; }; }
-done
-
-# There might be people who depend on the old broken behavior: `$host'
-# used to hold the argument of --host etc.
-# FIXME: To remove some day.
-build=$build_alias
-host=$host_alias
-target=$target_alias
-
-# FIXME: To remove some day.
-if test "x$host_alias" != x; then
- if test "x$build_alias" = x; then
- cross_compiling=maybe
- echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used." >&2
- elif test "x$build_alias" != "x$host_alias"; then
- cross_compiling=yes
- fi
-fi
-
-ac_tool_prefix=
-test -n "$host_alias" && ac_tool_prefix=$host_alias-
-
-test "$silent" = yes && exec 6>/dev/null
-
-
-ac_pwd=`pwd` && test -n "$ac_pwd" &&
-ac_ls_di=`ls -di .` &&
-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
- { echo "$as_me: error: Working directory cannot be determined" >&2
- { (exit 1); exit 1; }; }
-test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
- { echo "$as_me: error: pwd does not report name of working directory" >&2
- { (exit 1); exit 1; }; }
-
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then the parent directory.
- ac_confdir=`$as_dirname -- "$0" ||
-$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$0" : 'X\(//\)[^/]' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$0" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- srcdir=$ac_confdir
- if test ! -r "$srcdir/$ac_unique_file"; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r "$srcdir/$ac_unique_file"; then
- test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
- { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
- { (exit 1); exit 1; }; }
-fi
-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
-ac_abs_confdir=`(
- cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
- { (exit 1); exit 1; }; }
- pwd)`
-# When building in place, set srcdir=.
-if test "$ac_abs_confdir" = "$ac_pwd"; then
- srcdir=.
-fi
-# Remove unnecessary trailing slashes from srcdir.
-# Double slashes in file names in object file debugging info
-# mess up M-x gdb in Emacs.
-case $srcdir in
-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
-esac
-for ac_var in $ac_precious_vars; do
- eval ac_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_env_${ac_var}_value=\$${ac_var}
- eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_cv_env_${ac_var}_value=\$${ac_var}
-done
-
-#
-# Report the --help message.
-#
-if test "$ac_init_help" = "long"; then
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat <<_ACEOF
-\`configure' configures FULL-PACKAGE-NAME VERSION to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE. See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
- -h, --help display this help and exit
- --help=short display options specific to this package
- --help=recursive display the short help of all the included packages
- -V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking...' messages
- --cache-file=FILE cache test results in FILE [disabled]
- -C, --config-cache alias for \`--cache-file=config.cache'
- -n, --no-create do not create output files
- --srcdir=DIR find the sources in DIR [configure dir or \`..']
-
-Installation directories:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
- --bindir=DIR user executables [EPREFIX/bin]
- --sbindir=DIR system admin executables [EPREFIX/sbin]
- --libexecdir=DIR program executables [EPREFIX/libexec]
- --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --libdir=DIR object code libraries [EPREFIX/lib]
- --includedir=DIR C header files [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc [/usr/include]
- --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
- --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
- --infodir=DIR info documentation [DATAROOTDIR/info]
- --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
- --mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root [DATAROOTDIR/doc/full-package-name]
- --htmldir=DIR html documentation [DOCDIR]
- --dvidir=DIR dvi documentation [DOCDIR]
- --pdfdir=DIR pdf documentation [DOCDIR]
- --psdir=DIR ps documentation [DOCDIR]
-_ACEOF
-
- cat <<\_ACEOF
-_ACEOF
-fi
-
-if test -n "$ac_init_help"; then
- case $ac_init_help in
- short | recursive ) echo "Configuration of FULL-PACKAGE-NAME VERSION:";;
- esac
- cat <<\_ACEOF
-
-Optional Features:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --enable-mod_pubsub enable mod_pubsub (default: yes)
- --enable-mod_irc enable mod_irc (default: yes)
- --enable-mod_muc enable mod_muc (default: yes)
- --enable-eldap enable eldap (default: yes)
- --enable-web enable web (default: yes)
- --enable-tls enable tls (default: yes)
- --enable-odbc enable odbc (default: no)
- --enable-ejabberd_zlib enable ejabberd_zlib (default: yes)
- --enable-roster-gateway-workaround Turn on workaround for processing gateway subscriptions (default: no)
- --enable-mssql Use Microsoft SQL Server database (default: no, requires --enable-odbc)
-
-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-openssl=PREFIX prefix where OPENSSL is installed
-
-Some influential environment variables:
- CC C compiler command
- CFLAGS C compiler flags
- LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
- nonstandard directory <lib dir>
- CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
- you have headers in a nonstandard directory <include dir>
- CPP C preprocessor
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-Report bugs to <BUG-REPORT-ADDRESS>.
-_ACEOF
-ac_status=$?
-fi
-
-if test "$ac_init_help" = "recursive"; then
- # If there are subdirs, report their specific --help.
- for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
- test -d "$ac_dir" || continue
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
- cd "$ac_dir" || { ac_status=$?; continue; }
- # Check for guested configure.
- if test -f "$ac_srcdir/configure.gnu"; then
- echo &&
- $SHELL "$ac_srcdir/configure.gnu" --help=recursive
- elif test -f "$ac_srcdir/configure"; then
- echo &&
- $SHELL "$ac_srcdir/configure" --help=recursive
- else
- echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
- fi || ac_status=$?
- cd "$ac_pwd" || { ac_status=$?; break; }
- done
-fi
-
-test -n "$ac_init_help" && exit $ac_status
-if $ac_init_version; then
- cat <<\_ACEOF
-FULL-PACKAGE-NAME configure VERSION
-generated by GNU Autoconf 2.59d
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
-_ACEOF
- exit
-fi
-cat >config.log <<_ACEOF
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-
-It was created by FULL-PACKAGE-NAME $as_me VERSION, which was
-generated by GNU Autoconf 2.59d. Invocation command line was
-
- $ $0 $@
-
-_ACEOF
-exec 5>>config.log
-{
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
-
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
-
-/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
-/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
-/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
-
-_ASUNAME
-
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- echo "PATH: $as_dir"
-done
-IFS=$as_save_IFS
-
-} >&5
-
-cat >&5 <<_ACEOF
-
-
-## ----------- ##
-## Core tests. ##
-## ----------- ##
-
-_ACEOF
-
-
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_sep=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
- for ac_arg
- do
- case $ac_arg in
- -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- continue ;;
- *\'*)
- ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- case $ac_pass in
- 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
- 2)
- ac_configure_args1="$ac_configure_args1 '$ac_arg'"
- if test $ac_must_keep_next = true; then
- ac_must_keep_next=false # Got value, back to normal.
- else
- case $ac_arg in
- *=* | --config-cache | -C | -disable-* | --disable-* \
- | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
- | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
- | -with-* | --with-* | -without-* | --without-* | --x)
- case "$ac_configure_args0 " in
- "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
- esac
- ;;
- -* ) ac_must_keep_next=true ;;
- esac
- fi
- ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
- # Get rid of the leading space.
- ac_sep=" "
- ;;
- esac
- done
-done
-$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
-$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
-
-# When interrupted or exit'd, cleanup temporary files, and complete
-# config.log. We remove comments because anyway the quotes in there
-# would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
-trap 'exit_status=$?
- # Save into config.log some information that might help in debugging.
- {
- echo
-
- cat <<\_ASBOX
-## ---------------- ##
-## Cache variables. ##
-## ---------------- ##
-_ASBOX
- echo
- # The following way of writing the cache mishandles newlines in values,
-(
- for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- *) $as_unset $ac_var ;;
- esac ;;
- esac
- done
- (set) 2>&1 |
- case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- sed -n \
- "s/'\''/'\''\\\\'\'''\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
- ;; #(
- *)
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-)
- echo
-
- cat <<\_ASBOX
-## ----------------- ##
-## Output variables. ##
-## ----------------- ##
-_ASBOX
- echo
- for ac_var in $ac_subst_vars
- do
- eval ac_val=\$$ac_var
- echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
-
- if test -n "$ac_subst_files"; then
- cat <<\_ASBOX
-## ------------------- ##
-## File substitutions. ##
-## ------------------- ##
-_ASBOX
- echo
- for ac_var in $ac_subst_files
- do
- eval ac_val=\$$ac_var
- echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
- fi
-
- if test -s confdefs.h; then
- cat <<\_ASBOX
-## ----------- ##
-## confdefs.h. ##
-## ----------- ##
-_ASBOX
- echo
- cat confdefs.h
- echo
- fi
- test "$ac_signal" != 0 &&
- echo "$as_me: caught signal $ac_signal"
- echo "$as_me: exit $exit_status"
- } >&5
- rm -f core *.core core.conftest.* &&
- rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
- exit $exit_status
-' 0
-for ac_signal in 1 2 13 15; do
- trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
-done
-ac_signal=0
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
-
-# Predefined preprocessor variables.
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
-
-
-# Let the site file select an alternate cache file if it wants to.
-# Prefer explicitly selected file to automatically selected ones.
-if test -n "$CONFIG_SITE"; then
- set x "$CONFIG_SITE"
-elif test "x$prefix" != xNONE; then
- set x "$prefix/share/config.site" "$prefix/etc/config.site"
-else
- set x "$ac_default_prefix/share/config.site" \
- "$ac_default_prefix/etc/config.site"
-fi
-shift
-for ac_site_file
-do
- if test -r "$ac_site_file"; then
- { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
-echo "$as_me: loading site script $ac_site_file" >&6;}
- sed 's/^/| /' "$ac_site_file" >&5
- . "$ac_site_file"
- fi
-done
-
-if test -r "$cache_file"; then
- # Some versions of bash will fail to source /dev/null (special
- # files actually), so we avoid doing that.
- if test -f "$cache_file"; then
- { echo "$as_me:$LINENO: loading cache $cache_file" >&5
-echo "$as_me: loading cache $cache_file" >&6;}
- case $cache_file in
- [\\/]* | ?:[\\/]* ) . "$cache_file";;
- *) . "./$cache_file";;
- esac
- fi
-else
- { echo "$as_me:$LINENO: creating cache $cache_file" >&5
-echo "$as_me: creating cache $cache_file" >&6;}
- >$cache_file
-fi
-
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
- eval ac_old_set=\$ac_cv_env_${ac_var}_set
- eval ac_new_set=\$ac_env_${ac_var}_set
- eval ac_old_val=\$ac_cv_env_${ac_var}_value
- eval ac_new_val=\$ac_env_${ac_var}_value
- case $ac_old_set,$ac_new_set in
- set,)
- { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,set)
- { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,);;
- *)
- if test "x$ac_old_val" != "x$ac_new_val"; then
- { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
-echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
- { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
-echo "$as_me: former value: $ac_old_val" >&2;}
- { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
-echo "$as_me: current value: $ac_new_val" >&2;}
- ac_cache_corrupted=:
- fi;;
- esac
- # Pass precious variables to config.status.
- if test "$ac_new_set" = set; then
- case $ac_new_val in
- *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
- *) ac_arg=$ac_var=$ac_new_val ;;
- esac
- case " $ac_configure_args " in
- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
- *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- esac
- fi
-done
-if $ac_cache_corrupted; then
- { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
-echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
-echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-# Checks for programs.
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="${ac_tool_prefix}gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CC="gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-else
- CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="${ac_tool_prefix}cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- fi
-fi
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# != 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
- fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- for ac_prog in cl.exe
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$CC" && break
- done
-fi
-if test -z "$CC"; then
- ac_ct_CC=$CC
- for ac_prog in cl.exe
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CC="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$ac_ct_CC" && break
-done
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-fi
-
-fi
-
-
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version >&5\"") >&5
- (eval $ac_compiler --version >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v >&5\"") >&5
- (eval $ac_compiler -v >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V >&5\"") >&5
- (eval $ac_compiler -V >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-
-
-# List of possible output files. We want to start from the most likely,
-# but we have to check foo.exe before foo, because Cygwin `test -f' looks
-# also for foo.exe. b.out is created by i960 compilers.
-# As a last resort, we also try wildcards: `conftest.*' and `a.*'.
-# But we are not allowed to rm a.*, and we do not want always remove
-# conftest.*, so we will list them literally, when appropriate.
-ac_outfiles="a_out.exe a.out conftest.exe conftest a.exe b.out"
-
-# The IRIX 6 linker writes into existing files which may not be
-# executable, retaining their permissions. Remove them first so a
-# subsequent execution test works.
-rm -f $ac_outfiles conftest.*
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $ac_outfiles"
-
-# The following tests should remove their output except files matching conftest.*.
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-
-if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
- (eval $ac_link_default) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- for ac_file in $ac_outfiles a.* conftest.* NO
-do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
- * ) break;;
- esac
-done
-if test "$ac_file" = NO; then
- { { echo "$as_me:$LINENO: error: no output file found
-See \`config.log' for more details." >&5
-echo "$as_me: error: no output file found
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
- { (exit 77); exit 77; }; }
-fi
-
-{ echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6; }
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; }
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
- if { ac_try='./$ac_file'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- cross_compiling=no
- else
- if test "$cross_compiling" = maybe; then
- cross_compiling=yes
- else
- { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
- fi
- fi
-fi
-{ echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-# Clean up; list also $ac_file, in case it matched a wildcard entry.
-rm -f $ac_outfiles $ac_file
-
-{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
-{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6; }
-
-{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
-if test "${ac_cv_exeext+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # If both `conftest.exe' and `conftest' are `present' (well, observable),
- # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
- # work properly (i.e., refer to `conftest.exe'), while it won't with `rm'.
- for ac_file in conftest.exe conftest conftest.* NO; do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- break;;
- * ) break;;
- esac
- done
- if test "$ac_file" = NO; then
- { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: no output file found
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: no output file found
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
- # Clean up; list also $ac_file, in case it matched conftest.*.
- rm -f $ac_outfiles $ac_file
-
-else
- { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6; }
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-
-
-ac_clean_files=$ac_clean_files_save
-
-{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
-if test "${ac_cv_objext+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- rm -f conftest.o conftest.obj
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- for ac_file in conftest.o conftest.obj conftest.*; do
- test -f "$ac_file" || continue;
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
- break;;
- esac
-done
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-
-
-rm -f conftest.*
-{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
-if test "${ac_cv_c_compiler_gnu+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. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_compiler_gnu=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_compiler_gnu=no
-fi
-
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_save_c_werror_flag=$ac_c_werror_flag
- ac_c_werror_flag=yes
- ac_cv_prog_cc_g=no
- CFLAGS="-g"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_prog_cc_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- CFLAGS=""
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_c_werror_flag=$ac_save_c_werror_flag
- CFLAGS="-g"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_prog_cc_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
-echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
- function prototypes and stuff, but not '\xHH' hex character constants.
- These don't provoke an error unfortunately, instead are silently treated
- as 'x'. The following induces an error, until -std is added to get
- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
- array size at least. It's necessary to write '\x00'==0 to get something
- that's true only with -std. */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_prog_cc_c89=$ac_arg
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f conftest.err conftest.$ac_objext
- test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
- x)
- { echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6; } ;;
- xno)
- { echo "$as_me:$LINENO: result: unsupported" >&5
-echo "${ECHO_T}unsupported" >&6; } ;;
- *)
- CC="$CC $ac_cv_prog_cc_c89"
- { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
-echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; }
-set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
-if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.make <<\_ACEOF
-SHELL = /bin/sh
-all:
- @echo 'ac_maketemp=X"$(MAKE)"'
-_ACEOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
-eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
-if test "$ac_maketemp" != X ; then
- eval ac_cv_prog_make_${ac_make}_set=yes
-else
- eval ac_cv_prog_make_${ac_make}_set=no
-fi
-rm -f conftest.make
-fi
-if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- SET_MAKE=
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- SET_MAKE="MAKE=${MAKE-make}"
-fi
-
-
-#locating erlang
-
-# Check whether --with-erlang was given.
-if test "${with_erlang+set}" = set; then
- withval=$with_erlang;
-fi
-
-
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}erlc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}erlc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_ERLC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $ERLC in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ERLC="$ERLC" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_dummy="$PATH:$with_erlang:$with_erlang/bin"
-for as_dir in $as_dummy
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ERLC="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-ERLC=$ac_cv_path_ERLC
-if test -n "$ERLC"; then
- { echo "$as_me:$LINENO: result: $ERLC" >&5
-echo "${ECHO_T}$ERLC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_path_ERLC"; then
- ac_pt_ERLC=$ERLC
- # Extract the first word of "erlc", so it can be a program name with args.
-set dummy erlc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_ac_pt_ERLC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $ac_pt_ERLC in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ac_pt_ERLC="$ac_pt_ERLC" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_dummy="$PATH:$with_erlang:$with_erlang/bin"
-for as_dir in $as_dummy
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ac_pt_ERLC="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-ac_pt_ERLC=$ac_cv_path_ac_pt_ERLC
-if test -n "$ac_pt_ERLC"; then
- { echo "$as_me:$LINENO: result: $ac_pt_ERLC" >&5
-echo "${ECHO_T}$ac_pt_ERLC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_pt_ERLC" = x; then
- ERLC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- ERLC=$ac_pt_ERLC
- fi
-else
- ERLC="$ac_cv_path_ERLC"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}erl", so it can be a program name with args.
-set dummy ${ac_tool_prefix}erl; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_ERL+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $ERL in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ERL="$ERL" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_dummy="$PATH:$with_erlang:$with_erlang/bin"
-for as_dir in $as_dummy
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ERL="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-ERL=$ac_cv_path_ERL
-if test -n "$ERL"; then
- { echo "$as_me:$LINENO: result: $ERL" >&5
-echo "${ECHO_T}$ERL" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_path_ERL"; then
- ac_pt_ERL=$ERL
- # Extract the first word of "erl", so it can be a program name with args.
-set dummy erl; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_ac_pt_ERL+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $ac_pt_ERL in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ac_pt_ERL="$ac_pt_ERL" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_dummy="$PATH:$with_erlang:$with_erlang/bin"
-for as_dir in $as_dummy
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ac_pt_ERL="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-ac_pt_ERL=$ac_cv_path_ac_pt_ERL
-if test -n "$ac_pt_ERL"; then
- { echo "$as_me:$LINENO: result: $ac_pt_ERL" >&5
-echo "${ECHO_T}$ac_pt_ERL" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_pt_ERL" = x; then
- ERL=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- ERL=$ac_pt_ERL
- fi
-else
- ERL="$ac_cv_path_ERL"
-fi
-
-
- if test "z$ERLC" = "z" || test "z$ERL" = "z"; then
- { { echo "$as_me:$LINENO: error: erlang not found" >&5
-echo "$as_me: error: erlang not found" >&2;}
- { (exit 1); exit 1; }; }
- fi
-
-
- cat >>conftest.erl <<_EOF
-
--module(conftest).
--author('alexey@sevcom.net').
-
--export([start/0]).
-
-start() ->
- EIDirS = code:lib_dir("erl_interface") ++ "\n",
- EILibS = libpath("erl_interface") ++ "\n",
- RootDirS = code:root_dir() ++ "\n",
- file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ RootDirS)),
- halt().
-
-%% return physical architecture based on OS/Processor
-archname() ->
- ArchStr = erlang:system_info(system_architecture),
- case os:type() of
- {win32, _} -> "windows";
- {unix,UnixName} ->
- Specs = string:tokens(ArchStr,"-"),
- Cpu = case lists:nth(2,Specs) of
- "pc" -> "x86";
- _ -> hd(Specs)
- end,
- atom_to_list(UnixName) ++ "-" ++ Cpu;
- _ -> "generic"
- end.
-
-%% Return arch-based library path or a default value if this directory
-%% does not exist
-libpath(App) ->
- PrivDir = code:priv_dir(App),
- ArchDir = archname(),
- LibArchDir = filename:join([PrivDir,"lib",ArchDir]),
- case file:list_dir(LibArchDir) of
- %% Arch lib dir exists: We use it
- {ok, _List} -> LibArchDir;
- %% Arch lib dir does not exist: Return the default value
- %% ({error, enoent}):
- _Error -> code:lib_dir("erl_interface") ++ "/lib"
- end.
-
-_EOF
-
- if ! $ERLC conftest.erl; then
- { { echo "$as_me:$LINENO: error: could not compile sample program" >&5
-echo "$as_me: error: could not compile sample program" >&2;}
- { (exit 1); exit 1; }; }
- fi
-
- if ! $ERL -s conftest -noshell; then
- { { echo "$as_me:$LINENO: error: could not run sample program" >&5
-echo "$as_me: error: could not run sample program" >&2;}
- { (exit 1); exit 1; }; }
- fi
-
- if ! test -f conftest.out; then
- { { echo "$as_me:$LINENO: error: erlang program was not properly executed, (conftest.out was not produced)" >&5
-echo "$as_me: error: erlang program was not properly executed, (conftest.out was not produced)" >&2;}
- { (exit 1); exit 1; }; }
- fi
-
- # First line
- ERLANG_EI_DIR=`cat conftest.out | head -n 1`
- # Second line
- ERLANG_EI_LIB=`cat conftest.out | head -n 2 | tail -n 1`
- # Third line
- ERLANG_DIR=`cat conftest.out | tail -n 1`
-
- ERLANG_CFLAGS="-I$ERLANG_EI_DIR/include -I$ERLANG_DIR/usr/include"
- ERLANG_LIBS="-L$ERLANG_EI_LIB -lerl_interface -lei"
-
-
-
-
-
-
-#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 <stdlib.h>
-#include <iconv.h>
-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 { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- am_cv_func_iconv=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f conftest.err conftest.$ac_objext \
- 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 <stdlib.h>
-#include <iconv.h>
-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 { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; 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 conftest.err conftest.$ac_objext \
- 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 <stdlib.h>
-#include <iconv.h>
-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 { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; 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 conftest.err conftest.$ac_objext \
- 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 <stdlib.h>
-#include <iconv.h>
-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 { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; 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 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'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
- if test "${ac_cv_prog_CPP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Double quotes because CPP needs to be expanded
- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- break
-fi
-
- done
- ac_cv_prog_CPP=$CPP
-
-fi
- CPP=$ac_cv_prog_CPP
-else
- ac_cv_prog_CPP=$CPP
-fi
-{ echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- :
-else
- { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
-echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Extract the first word of "grep ggrep" to use in msg output
-if test -z "$GREP"; then
-set dummy grep ggrep; ac_prog_name=$2
-if test "${ac_cv_path_GREP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_path_GREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in grep ggrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue
- # Check for GNU ac_path_GREP and select it if it is found.
- # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
- ac_count=0
- echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- echo 'GREP' >> "conftest.nl"
- "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- ac_count=`expr $ac_count + 1`
- if test $ac_count -gt ${ac_path_GREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_GREP="$ac_path_GREP"
- ac_path_GREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-
- $ac_path_GREP_found && break 3
- done
-done
-
-done
-IFS=$as_save_IFS
-
-
-fi
-
-GREP="$ac_cv_path_GREP"
-if test -z "$GREP"; then
- { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-else
- ac_cv_path_GREP=$GREP
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
-echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
- then ac_cv_path_EGREP="$GREP -E"
- else
- # Extract the first word of "egrep" to use in msg output
-if test -z "$EGREP"; then
-set dummy egrep; ac_prog_name=$2
-if test "${ac_cv_path_EGREP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_path_EGREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in egrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue
- # Check for GNU ac_path_EGREP and select it if it is found.
- # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
- ac_count=0
- echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- echo 'EGREP' >> "conftest.nl"
- "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- ac_count=`expr $ac_count + 1`
- if test $ac_count -gt ${ac_path_EGREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_EGREP="$ac_path_EGREP"
- ac_path_EGREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-
- $ac_path_EGREP_found && break 3
- done
-done
-
-done
-IFS=$as_save_IFS
-
-
-fi
-
-EGREP="$ac_cv_path_EGREP"
-if test -z "$EGREP"; then
- { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-else
- ac_cv_path_EGREP=$EGREP
-fi
-
-
- fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
-echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
-
-{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdc+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 <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_header_stdc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_header_stdc=no
-fi
-
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then
- :
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
-_ACEOF
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-
-
-
-
-
-
-
-
-
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
- inttypes.h stdint.h unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+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. */
-$ac_includes_default
-
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_Header=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- eval "$as_ac_Header=no"
-fi
-
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-
-# Check whether --with-expat was given.
-if test "${with_expat+set}" = set; then
- withval=$with_expat;
-fi
-
-
- EXPAT_CFLAGS=
- EXPAT_LIBS=
- if test x"$with_expat" != x; then
- EXPAT_CFLAGS="-I$with_expat/include"
- EXPAT_LIBS="-L$with_expat/lib"
- fi
-
- { echo "$as_me:$LINENO: checking for XML_ParserCreate in -lexpat" >&5
-echo $ECHO_N "checking for XML_ParserCreate in -lexpat... $ECHO_C" >&6; }
-if test "${ac_cv_lib_expat_XML_ParserCreate+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lexpat "$EXPAT_LIBS" $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char XML_ParserCreate ();
-int
-main ()
-{
-return XML_ParserCreate ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_expat_XML_ParserCreate=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_expat_XML_ParserCreate=no
-fi
-
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_expat_XML_ParserCreate" >&5
-echo "${ECHO_T}$ac_cv_lib_expat_XML_ParserCreate" >&6; }
-if test $ac_cv_lib_expat_XML_ParserCreate = yes; then
- EXPAT_LIBS="$EXPAT_LIBS -lexpat"
- expat_found=yes
-else
- expat_found=no
-fi
-
- if test $expat_found = no; then
- { { echo "$as_me:$LINENO: error: Could not find the Expat library" >&5
-echo "$as_me: error: Could not find the Expat library" >&2;}
- { (exit 1); exit 1; }; }
- fi
- expat_save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $EXPAT_CFLAGS"
-
-for ac_header in expat.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## --------------------------------- ##
-## Report this to BUG-REPORT-ADDRESS ##
-## --------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-else
- expat_found=no
-fi
-
-done
-
- if test $expat_found = no; then
- { { echo "$as_me:$LINENO: error: Could not find expat.h" >&5
-echo "$as_me: error: Could not find expat.h" >&2;}
- { (exit 1); exit 1; }; }
- fi
- CFLAGS="$expat_save_CFLAGS"
-
-
-
-
-#locating zlib
-
-# Check whether --with-zlib was given.
-if test "${with_zlib+set}" = set; then
- withval=$with_zlib;
-fi
-
-
- ZLIB_CFLAGS=
- ZLIB_LIBS=
- if test x"$with_zlib" != x; then
- ZLIB_CFLAGS="-I$with_zlib/include"
- ZLIB_LIBS="-L$with_zlib/lib"
- fi
-
- { echo "$as_me:$LINENO: checking for gzgets in -lz" >&5
-echo $ECHO_N "checking for gzgets in -lz... $ECHO_C" >&6; }
-if test "${ac_cv_lib_z_gzgets+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lz "$ZLIB_LIBS" $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char gzgets ();
-int
-main ()
-{
-return gzgets ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_z_gzgets=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_z_gzgets=no
-fi
-
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_z_gzgets" >&5
-echo "${ECHO_T}$ac_cv_lib_z_gzgets" >&6; }
-if test $ac_cv_lib_z_gzgets = yes; then
- ZLIB_LIBS="$ZLIB_LIBS -lz"
- zlib_found=yes
-else
- zlib_found=no
-fi
-
- if test $zlib_found = no; then
- { { echo "$as_me:$LINENO: error: Could not find the zlib library" >&5
-echo "$as_me: error: Could not find the zlib library" >&2;}
- { (exit 1); exit 1; }; }
- fi
- zlib_save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $ZLIB_CFLAGS"
-
-for ac_header in zlib.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## --------------------------------- ##
-## Report this to BUG-REPORT-ADDRESS ##
-## --------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-else
- zlib_found=no
-fi
-
-done
-
- if test $zlib_found = no; then
- { { echo "$as_me:$LINENO: error: Could not find zlib.h" >&5
-echo "$as_me: error: Could not find zlib.h" >&2;}
- { (exit 1); exit 1; }; }
- fi
- CFLAGS="$zlib_save_CFLAGS"
-
-
-
-
-
-# Checks for typedefs, structures, and compiler characteristics.
-{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
-echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; }
-if test "${ac_cv_c_const+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. */
-
-int
-main ()
-{
-/* FIXME: Include the comments suggested by Paul. */
-#ifndef __cplusplus
- /* Ultrix mips cc rejects this. */
- typedef int charset[2];
- const charset x;
- /* SunOS 4.1.1 cc rejects this. */
- char const *const *ccp;
- char **p;
- /* NEC SVR4.0.2 mips cc rejects this. */
- struct point {int x, y;};
- static struct point const zero = {0,0};
- /* AIX XL C 1.02.0.0 rejects this.
- It does not let you subtract one const X* pointer from another in
- an arm of an if-expression whose if-part is not a constant
- expression */
- const char *g = "string";
- ccp = &g + (g ? g-g : 0);
- /* HPUX 7.0 cc rejects these. */
- ++ccp;
- p = (char**) ccp;
- ccp = (char const *const *) p;
- { /* SCO 3.2v4 cc rejects this. */
- char *t;
- char const *s = 0 ? (char *) 0 : (char const *) 0;
-
- *t++ = 0;
- if (s) return 0;
- }
- { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
- int x[] = {25, 17};
- const int *foo = &x[0];
- ++foo;
- }
- { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
- typedef const int *iptr;
- iptr p = 0;
- ++p;
- }
- { /* AIX XL C 1.02.0.0 rejects this saying
- "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
- struct s { int j; const int *ap[3]; };
- struct s *b; b->j = 5;
- }
- { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
- const int foo = 10;
- if (!foo) return 0;
- }
- return !x[0] && !zero.x;
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_c_const=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_c_const=no
-fi
-
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
-echo "${ECHO_T}$ac_cv_c_const" >&6; }
-if test $ac_cv_c_const = no; then
-
-cat >>confdefs.h <<\_ACEOF
-#define const
-_ACEOF
-
-fi
-
-
-# Change default prefix
- /
-
-# Checks for library functions.
-
-for ac_header in stdlib.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## --------------------------------- ##
-## Report this to BUG-REPORT-ADDRESS ##
-## --------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-{ echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5
-echo $ECHO_N "checking for GNU libc compatible malloc... $ECHO_C" >&6; }
-if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_func_malloc_0_nonnull=no
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#if STDC_HEADERS || HAVE_STDLIB_H
-# include <stdlib.h>
-#else
-char *malloc ();
-#endif
-
-int
-main ()
-{
-return ! malloc (0);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_malloc_0_nonnull=yes
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_malloc_0_nonnull=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5
-echo "${ECHO_T}$ac_cv_func_malloc_0_nonnull" >&6; }
-if test $ac_cv_func_malloc_0_nonnull = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_MALLOC 1
-_ACEOF
-
-else
- cat >>confdefs.h <<\_ACEOF
-#define HAVE_MALLOC 0
-_ACEOF
-
- case " $LIBOBJS " in
- *" malloc.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS malloc.$ac_objext"
- ;;
-esac
-
-
-cat >>confdefs.h <<\_ACEOF
-#define malloc rpl_malloc
-_ACEOF
-
-fi
-
-
-
-{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdc+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 <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_header_stdc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_header_stdc=no
-fi
-
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then
- :
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
-_ACEOF
-
-fi
-
-
-
-mod_pubsub=
-make_mod_pubsub=
-{ echo "$as_me:$LINENO: checking whether build mod_pubsub" >&5
-echo $ECHO_N "checking whether build mod_pubsub... $ECHO_C" >&6; }
-# Check whether --enable-mod_pubsub was given.
-if test "${enable_mod_pubsub+set}" = set; then
- enableval=$enable_mod_pubsub; mr_enable_mod_pubsub="$enableval"
-else
- mr_enable_mod_pubsub=yes
-fi
-
-if test "$mr_enable_mod_pubsub" = "yes"; then
-mod_pubsub=mod_pubsub
-make_mod_pubsub=mod_pubsub/Makefile
-fi
-{ echo "$as_me:$LINENO: result: $mr_enable_mod_pubsub" >&5
-echo "${ECHO_T}$mr_enable_mod_pubsub" >&6; }
-
-
-
-
-
-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
-echo $ECHO_N "checking whether build mod_muc... $ECHO_C" >&6; }
-# Check whether --enable-mod_muc was given.
-if test "${enable_mod_muc+set}" = set; then
- enableval=$enable_mod_muc; mr_enable_mod_muc="$enableval"
-else
- mr_enable_mod_muc=yes
-fi
-
-if test "$mr_enable_mod_muc" = "yes"; then
-mod_muc=mod_muc
-make_mod_muc=mod_muc/Makefile
-fi
-{ echo "$as_me:$LINENO: result: $mr_enable_mod_muc" >&5
-echo "${ECHO_T}$mr_enable_mod_muc" >&6; }
-
-
-
-
-
-eldap=
-make_eldap=
-{ echo "$as_me:$LINENO: checking whether build eldap" >&5
-echo $ECHO_N "checking whether build eldap... $ECHO_C" >&6; }
-# Check whether --enable-eldap was given.
-if test "${enable_eldap+set}" = set; then
- enableval=$enable_eldap; mr_enable_eldap="$enableval"
-else
- mr_enable_eldap=yes
-fi
-
-if test "$mr_enable_eldap" = "yes"; then
-eldap=eldap
-make_eldap=eldap/Makefile
-fi
-{ echo "$as_me:$LINENO: result: $mr_enable_eldap" >&5
-echo "${ECHO_T}$mr_enable_eldap" >&6; }
-
-
-
-
-
-web=
-make_web=
-{ echo "$as_me:$LINENO: checking whether build web" >&5
-echo $ECHO_N "checking whether build web... $ECHO_C" >&6; }
-# Check whether --enable-web was given.
-if test "${enable_web+set}" = set; then
- enableval=$enable_web; mr_enable_web="$enableval"
-else
- mr_enable_web=yes
-fi
-
-if test "$mr_enable_web" = "yes"; then
-web=web
-make_web=web/Makefile
-fi
-{ echo "$as_me:$LINENO: result: $mr_enable_web" >&5
-echo "${ECHO_T}$mr_enable_web" >&6; }
-
-
-
-
-
-tls=
-make_tls=
-{ echo "$as_me:$LINENO: checking whether build tls" >&5
-echo $ECHO_N "checking whether build tls... $ECHO_C" >&6; }
-# Check whether --enable-tls was given.
-if test "${enable_tls+set}" = set; then
- enableval=$enable_tls; mr_enable_tls="$enableval"
-else
- mr_enable_tls=yes
-fi
-
-if test "$mr_enable_tls" = "yes"; then
-tls=tls
-make_tls=tls/Makefile
-fi
-{ echo "$as_me:$LINENO: result: $mr_enable_tls" >&5
-echo "${ECHO_T}$mr_enable_tls" >&6; }
-
-
-
-
-
-odbc=
-make_odbc=
-{ echo "$as_me:$LINENO: checking whether build odbc" >&5
-echo $ECHO_N "checking whether build odbc... $ECHO_C" >&6; }
-# Check whether --enable-odbc was given.
-if test "${enable_odbc+set}" = set; then
- enableval=$enable_odbc; mr_enable_odbc="$enableval"
-else
- mr_enable_odbc=no
-fi
-
-if test "$mr_enable_odbc" = "yes"; then
-odbc=odbc
-make_odbc=odbc/Makefile
-fi
-{ echo "$as_me:$LINENO: result: $mr_enable_odbc" >&5
-echo "${ECHO_T}$mr_enable_odbc" >&6; }
-
-
-
-
-
-ejabberd_zlib=
-make_ejabberd_zlib=
-{ echo "$as_me:$LINENO: checking whether build ejabberd_zlib" >&5
-echo $ECHO_N "checking whether build ejabberd_zlib... $ECHO_C" >&6; }
-# Check whether --enable-ejabberd_zlib was given.
-if test "${enable_ejabberd_zlib+set}" = set; then
- enableval=$enable_ejabberd_zlib; mr_enable_ejabberd_zlib="$enableval"
-else
- mr_enable_ejabberd_zlib=yes
-fi
-
-if test "$mr_enable_ejabberd_zlib" = "yes"; then
-ejabberd_zlib=ejabberd_zlib
-make_ejabberd_zlib=ejabberd_zlib/Makefile
-fi
-{ echo "$as_me:$LINENO: result: $mr_enable_ejabberd_zlib" >&5
-echo "${ECHO_T}$mr_enable_ejabberd_zlib" >&6; }
-
-
-
-
-
-# Check whether --enable-roster_gateway_workaround was given.
-if test "${enable_roster_gateway_workaround+set}" = set; then
- enableval=$enable_roster_gateway_workaround; case "${enableval}" in
- yes) roster_gateway_workaround=true ;;
- no) roster_gateway_workaround=false ;;
- *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-roster-gateway-workaround" >&5
-echo "$as_me: error: bad value ${enableval} for --enable-roster-gateway-workaround" >&2;}
- { (exit 1); exit 1; }; } ;;
-esac
-else
- roster_gateway_workaround=false
-fi
-
-
-
-# Check whether --enable-mssql was given.
-if test "${enable_mssql+set}" = set; then
- enableval=$enable_mssql; case "${enableval}" in
- yes) db_type=mssql ;;
- no) db_type=generic ;;
- *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-mssql" >&5
-echo "$as_me: error: bad value ${enableval} for --enable-mssql" >&2;}
- { (exit 1); exit 1; }; } ;;
-esac
-else
- db_type=generic
-fi
-
-
-
-ac_config_files="$ac_config_files Makefile $make_mod_irc $make_mod_muc $make_mod_pubsub $make_eldap $make_web stringprep/Makefile $make_tls $make_odbc $make_ejabberd_zlib"
-
-#openssl
-
-# Check whether --with-openssl was given.
-if test "${with_openssl+set}" = set; then
- withval=$with_openssl;
-fi
-
-unset SSL_LIBS;
-unset SSL_CFLAGS;
-have_openssl=no
-if test x"$tls" != x; then
- for ssl_prefix in $withval /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr; do
- printf "looking for openssl in $ssl_prefix...\n"
- SSL_CFLAGS="-I$ssl_prefix/include/openssl"
- SSL_LIBS="-L$ssl_prefix/lib -lcrypto"
- { echo "$as_me:$LINENO: checking for SSL_new in -lssl" >&5
-echo $ECHO_N "checking for SSL_new in -lssl... $ECHO_C" >&6; }
-if test "${ac_cv_lib_ssl_SSL_new+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lssl $SSL_LIBS $SSL_CFLAGS $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char SSL_new ();
-int
-main ()
-{
-return SSL_new ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_ssl_SSL_new=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_ssl_SSL_new=no
-fi
-
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SSL_new" >&5
-echo "${ECHO_T}$ac_cv_lib_ssl_SSL_new" >&6; }
-if test $ac_cv_lib_ssl_SSL_new = yes; then
- have_openssl=yes
-else
- have_openssl=no
-fi
-
- if test x"$have_openssl" = xyes; then
- save_CPPFLAGS=$CPPFLAGS
- CPPFLAGS="-I$ssl_prefix/lib $CPPFLAGS"
-
-for ac_header in openssl/ssl.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## --------------------------------- ##
-## Report this to BUG-REPORT-ADDRESS ##
-## --------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
- have_openssl_h=yes
-fi
-
-done
-
- CPPFLAGS=$save_CPPFLAGS
- if test x"$have_openssl_h" = xyes; then
- have_openssl=yes
- printf "openssl found in $ssl_prefix\n";
- SSL_LIBS="-L$ssl_prefix/lib -lssl -lcrypto"
- CPPFLAGS="-I$ssl_prefix/lib $CPPFLAGS"
- SSL_CFLAGS="-DHAVE_SSL"
- break
- fi
- fi
- done
-if test x${have_openssl} != xyes; then
- { { echo "$as_me:$LINENO: error: openssl library cannot be found. Install openssl or disable \`tls' module (--disable-tls)." >&5
-echo "$as_me: error: openssl library cannot be found. Install openssl or disable \`tls' module (--disable-tls)." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-
-fi
-
-# If ssl is kerberized it need krb5.h
-# On RedHat and OpenBSD, krb5.h is in an unsual place:
-KRB5_INCLUDE="`krb5-config --cflags 2>/dev/null`"
-if test -n "$KRB5_INCLUDE" ; then
- CPPFLAGS="$CPPFLAGS $KRB5_INCLUDE"
-else
- # For RedHat For BSD
- for D in /usr/kerberos/include /usr/include/kerberos /usr/include/kerberosV
- do
- if test -d $D ; then
- CPPFLAGS="$CPPFLAGS -I$D"
- fi
- done
-fi
-if test "${ac_cv_header_krb5_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for krb5.h" >&5
-echo $ECHO_N "checking for krb5.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_krb5_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_krb5_h" >&5
-echo "${ECHO_T}$ac_cv_header_krb5_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking krb5.h usability" >&5
-echo $ECHO_N "checking krb5.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <krb5.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking krb5.h presence" >&5
-echo $ECHO_N "checking krb5.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <krb5.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: krb5.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: krb5.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: krb5.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: krb5.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: krb5.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: krb5.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: krb5.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: krb5.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: krb5.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: krb5.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: krb5.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: krb5.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: krb5.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: krb5.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: krb5.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: krb5.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## --------------------------------- ##
-## Report this to BUG-REPORT-ADDRESS ##
-## --------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for krb5.h" >&5
-echo $ECHO_N "checking for krb5.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_krb5_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_krb5_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_krb5_h" >&5
-echo "${ECHO_T}$ac_cv_header_krb5_h" >&6; }
-
-fi
-
-
-
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems. If it contains results you don't
-# want to keep, you may remove or edit it.
-#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
-#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(
- for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- *) $as_unset $ac_var ;;
- esac ;;
- esac
- done
-
- (set) 2>&1 |
- case $as_nl`(ac_space=' '; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- # `set' does not quote correctly, so add quotes (double-quote
- # substitution turns \\\\ into \\, and sed turns \\ into \).
- sed -n \
- "s/'/'\\\\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
- ;; #(
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-) |
- sed '
- /^ac_cv_env_/b end
- t clear
- :clear
- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
- t end
- s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
- :end' >>confcache
-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
- if test -w "$cache_file"; then
- test "x$cache_file" != "x/dev/null" &&
- { echo "$as_me:$LINENO: updating cache $cache_file" >&5
-echo "$as_me: updating cache $cache_file" >&6;}
- cat confcache >$cache_file
- else
- { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
-echo "$as_me: not updating unwritable cache $cache_file" >&6;}
- fi
-fi
-rm -f confcache
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-# Transform confdefs.h into DEFS.
-# Protect against shell expansion while executing Makefile rules.
-# Protect against Makefile macro expansion.
-#
-# If the first sed substitution is executed (which looks for macros that
-# take arguments), then we branch to the quote section. Otherwise,
-# look for a macro that doesn't take arguments.
-cat >confdef2opt.sed <<\_ACEOF
-t clear
-:clear
-s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g
-t quote
-s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g
-t quote
-d
-:quote
-s/[ `~#$^&*(){}\\|;'"<>?]/\\&/g
-s/\[/\\&/g
-s/\]/\\&/g
-s/\$/$$/g
-p
-_ACEOF
-# We use echo to avoid assuming a particular line-breaking character.
-# The extra dot is to prevent the shell from consuming trailing
-# line-breaks from the sub-command output. A line-break within
-# single-quotes doesn't work because, if this script is created in a
-# platform that uses two characters for line-breaks (e.g., DOS), tr
-# would break.
-ac_LF_and_DOT=`echo; echo .`
-DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
-rm -f confdef2opt.sed
-
-
-ac_libobjs=
-ac_ltlibobjs=
-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
- # 1. Remove the extension, and $U if already installed.
- ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
- ac_i=`echo "$ac_i" | sed "$ac_script"`
- # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
- # will be set to the directory where LIBOBJS objects are built.
- ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
- ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
-done
-LIBOBJS=$ac_libobjs
-
-LTLIBOBJS=$ac_ltlibobjs
-
-
-
-: ${CONFIG_STATUS=./config.status}
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
-echo "$as_me: creating $CONFIG_STATUS" >&6;}
-cat >$CONFIG_STATUS <<_ACEOF
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate the current configuration.
-# Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
-
-debug=false
-ac_cs_recheck=false
-ac_cs_silent=false
-SHELL=\${CONFIG_SHELL-$SHELL}
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-## --------------------- ##
-## M4sh Initialization. ##
-## --------------------- ##
-
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
- as_unset=unset
-else
- as_unset=false
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-as_nl='
-'
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-case $0 in
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- { (exit 1); exit 1; }
-fi
-
-# Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-for as_var in \
- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
- LC_TELEPHONE LC_TIME
-do
- if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
- eval $as_var=C; export $as_var
- else
- ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
- fi
-done
-
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-
-# Name of the executable.
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# CDPATH.
-$as_unset CDPATH
-
-
-
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
-
- # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
- # uniformly replaced by the line number. The first 'sed' inserts a
- # line-number line after each line using $LINENO; the second 'sed'
- # does the real work. The second script uses 'N' to pair each
- # line-number line with the line containing $LINENO, and appends
- # trailing '-' during substitution so that $LINENO is not a special
- # case at line end.
- # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
- # scripts with optimization help from Paolo Bonzini. Blame Lee
- # E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
- { (exit 1); exit 1; }; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-
-if (dirname -- /) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
--n*)
- case `echo 'x\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- *) ECHO_C='\c';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir
-fi
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
-elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p=:
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-# Find out whether ``test -x'' works. Don't use a zero-byte file, as
-# systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
- as_executable_p="test -x"
-else
- as_executable_p=:
-fi
-rm -f conf$$.file
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-exec 6>&1
-
-# Save the log message, to keep $[0] and so on meaningful, and to
-# report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.
-ac_log="
-This file was extended by FULL-PACKAGE-NAME $as_me VERSION, which was
-generated by GNU Autoconf 2.59d. Invocation command line was
-
- CONFIG_FILES = $CONFIG_FILES
- CONFIG_HEADERS = $CONFIG_HEADERS
- CONFIG_LINKS = $CONFIG_LINKS
- CONFIG_COMMANDS = $CONFIG_COMMANDS
- $ $0 $@
-
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<_ACEOF
-# Files that config.status was made for.
-config_files="$ac_config_files"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-ac_cs_usage="\
-\`$as_me' instantiates files from templates according to the
-current configuration.
-
-Usage: $0 [OPTIONS] [FILE]...
-
- -h, --help print this help, then exit
- -V, --version print version number, then exit
- -q, --quiet do not print progress messages
- -d, --debug don't remove temporary files
- --recheck update $as_me by reconfiguring in the same conditions
- --file=FILE[:TEMPLATE]
- instantiate the configuration file FILE
-
-Configuration files:
-$config_files
-
-Report bugs to <bug-autoconf@gnu.org>."
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-ac_cs_version="\\
-FULL-PACKAGE-NAME config.status VERSION
-configured by $0, generated by GNU Autoconf 2.59d,
- with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
-
-Copyright (C) 2006 Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it."
-
-ac_pwd='$ac_pwd'
-srcdir='$srcdir'
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If no file are specified by the user, then we need to provide default
-# value. By we need to know if files were specified by the user.
-ac_need_defaults=:
-while test $# != 0
-do
- case $1 in
- --*=*)
- ac_option=`expr "X$1" : 'X\([^=]*\)='`
- ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
- ac_shift=:
- ;;
- *)
- ac_option=$1
- ac_optarg=$2
- ac_shift=shift
- ;;
- esac
-
- case $ac_option in
- # Handling of the options.
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- ac_cs_recheck=: ;;
- --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
- echo "$ac_cs_version"; exit ;;
- --debug | --debu | --deb | --de | --d | -d )
- debug=: ;;
- --file | --fil | --fi | --f )
- $ac_shift
- CONFIG_FILES="$CONFIG_FILES $ac_optarg"
- ac_need_defaults=false;;
- --he | --h | --help | --hel | -h )
- echo "$ac_cs_usage"; exit ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil | --si | --s)
- ac_cs_silent=: ;;
-
- # This is an error.
- -*) { echo "$as_me: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&2
- { (exit 1); exit 1; }; } ;;
-
- *) ac_config_targets="$ac_config_targets $1"
- ac_need_defaults=false ;;
-
- esac
- shift
-done
-
-ac_configure_extra_args=
-
-if $ac_cs_silent; then
- exec 6>/dev/null
- ac_configure_extra_args="$ac_configure_extra_args --silent"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-if \$ac_cs_recheck; then
- echo "running CONFIG_SHELL=$SHELL $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
- CONFIG_SHELL=$SHELL
- export CONFIG_SHELL
- exec $SHELL "$0" $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-exec 5>>config.log
-{
- echo
- sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
- echo "$ac_log"
-} >&5
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-
-# Handling of arguments.
-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_eldap") CONFIG_FILES="$CONFIG_FILES $make_eldap" ;;
- "$make_web") CONFIG_FILES="$CONFIG_FILES $make_web" ;;
- "stringprep/Makefile") CONFIG_FILES="$CONFIG_FILES stringprep/Makefile" ;;
- "$make_tls") CONFIG_FILES="$CONFIG_FILES $make_tls" ;;
- "$make_odbc") CONFIG_FILES="$CONFIG_FILES $make_odbc" ;;
- "$make_ejabberd_zlib") CONFIG_FILES="$CONFIG_FILES $make_ejabberd_zlib" ;;
-
- *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
-echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
- { (exit 1); exit 1; }; };;
- esac
-done
-
-
-# If the user did not use the arguments to specify the items to instantiate,
-# then the envvar interface is used. Set only those that are not.
-# We use the long form for the default assignment because of an extremely
-# bizarre bug on SunOS 4.1.3.
-if $ac_need_defaults; then
- test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
-fi
-
-# Have a temporary directory for convenience. Make it in the build tree
-# simply because there is no reason against having it here, and in addition,
-# creating and moving files from /tmp can sometimes cause problems.
-# Hook for its removal unless debugging.
-# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to `$tmp'.
-$debug ||
-{
- tmp=
- trap 'exit_status=$?
- { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
-' 0
- trap '{ (exit 1); exit 1; }' 1 2 13 15
-}
-# Create a (secure) tmp directory for tmp files.
-
-{
- tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
- test -n "$tmp" && test -d "$tmp"
-} ||
-{
- tmp=./conf$$-$RANDOM
- (umask 077 && mkdir "$tmp")
-} ||
-{
- echo "$me: cannot create a temporary directory in ." >&2
- { (exit 1); exit 1; }
-}
-
-#
-# Set up the sed scripts for CONFIG_FILES section.
-#
-
-# No need to generate the scripts if there are no CONFIG_FILES.
-# This happens for instance when ./config.status config.h
-if test -n "$CONFIG_FILES"; then
-
-_ACEOF
-
-
-
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
- cat >conf$$subs.sed <<_ACEOF
-SHELL!$SHELL$ac_delim
-PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
-PACKAGE_NAME!$PACKAGE_NAME$ac_delim
-PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
-PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
-PACKAGE_STRING!$PACKAGE_STRING$ac_delim
-PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
-exec_prefix!$exec_prefix$ac_delim
-prefix!$prefix$ac_delim
-program_transform_name!$program_transform_name$ac_delim
-bindir!$bindir$ac_delim
-sbindir!$sbindir$ac_delim
-libexecdir!$libexecdir$ac_delim
-datarootdir!$datarootdir$ac_delim
-datadir!$datadir$ac_delim
-sysconfdir!$sysconfdir$ac_delim
-sharedstatedir!$sharedstatedir$ac_delim
-localstatedir!$localstatedir$ac_delim
-includedir!$includedir$ac_delim
-oldincludedir!$oldincludedir$ac_delim
-docdir!$docdir$ac_delim
-infodir!$infodir$ac_delim
-htmldir!$htmldir$ac_delim
-dvidir!$dvidir$ac_delim
-pdfdir!$pdfdir$ac_delim
-psdir!$psdir$ac_delim
-libdir!$libdir$ac_delim
-localedir!$localedir$ac_delim
-mandir!$mandir$ac_delim
-DEFS!$DEFS$ac_delim
-ECHO_C!$ECHO_C$ac_delim
-ECHO_N!$ECHO_N$ac_delim
-ECHO_T!$ECHO_T$ac_delim
-LIBS!$LIBS$ac_delim
-build_alias!$build_alias$ac_delim
-host_alias!$host_alias$ac_delim
-target_alias!$target_alias$ac_delim
-CC!$CC$ac_delim
-CFLAGS!$CFLAGS$ac_delim
-LDFLAGS!$LDFLAGS$ac_delim
-CPPFLAGS!$CPPFLAGS$ac_delim
-ac_ct_CC!$ac_ct_CC$ac_delim
-EXEEXT!$EXEEXT$ac_delim
-OBJEXT!$OBJEXT$ac_delim
-SET_MAKE!$SET_MAKE$ac_delim
-ERLC!$ERLC$ac_delim
-ERL!$ERL$ac_delim
-ERLANG_CFLAGS!$ERLANG_CFLAGS$ac_delim
-ERLANG_LIBS!$ERLANG_LIBS$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
-ZLIB_CFLAGS!$ZLIB_CFLAGS$ac_delim
-ZLIB_LIBS!$ZLIB_LIBS$ac_delim
-LIBOBJS!$LIBOBJS$ac_delim
-mod_pubsub!$mod_pubsub$ac_delim
-make_mod_pubsub!$make_mod_pubsub$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
-eldap!$eldap$ac_delim
-make_eldap!$make_eldap$ac_delim
-web!$web$ac_delim
-make_web!$make_web$ac_delim
-tls!$tls$ac_delim
-make_tls!$make_tls$ac_delim
-odbc!$odbc$ac_delim
-make_odbc!$make_odbc$ac_delim
-ejabberd_zlib!$ejabberd_zlib$ac_delim
-make_ejabberd_zlib!$make_ejabberd_zlib$ac_delim
-roster_gateway_workaround!$roster_gateway_workaround$ac_delim
-db_type!$db_type$ac_delim
-SSL_LIBS!$SSL_LIBS$ac_delim
-SSL_CFLAGS!$SSL_CFLAGS$ac_delim
-LTLIBOBJS!$LTLIBOBJS$ac_delim
-_ACEOF
-
- if test `grep -c "$ac_delim\$" conf$$subs.sed` = 79; then
- break
- elif $ac_last_try; then
- { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
-echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
- { (exit 1); exit 1; }; }
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-
-ac_eof=
-if grep '^CEOF$' conf$$subs.sed >/dev/null; then
- ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF//p' conf$$subs.sed | sort -nru | sed 1q`
- ac_eof=`expr 0$ac_eof + 1`
-fi
-
-cat >>$CONFIG_STATUS <<_ACEOF
-cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
-_ACEOF
-sed '
-s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
-s/^/s,@/; s/!/@,|#_!!_#|/
-:n
-t n
-s/'"$ac_delim"'$/,g/; t
-s/$/\\/; p
-N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
-' >>$CONFIG_STATUS <conf$$subs.sed
-rm -f conf$$subs.sed
-cat >>$CONFIG_STATUS <<_ACEOF
-:end
-s/|#_!!_#|//g
-CEOF$ac_eof
-_ACEOF
-
-
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[ ]*\):*/\1/
-s/:*$//
-s/^[^=]*=[ ]*$//
-}'
-fi
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-fi # test -n "$CONFIG_FILES"
-
-
-for ac_tag in :F $CONFIG_FILES
-do
- case $ac_tag in
- :[FHLC]) ac_mode=$ac_tag; continue;;
- esac
- case $ac_mode$ac_tag in
- :[FHL]*:*);;
- :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
-echo "$as_me: error: Invalid tag $ac_tag." >&2;}
- { (exit 1); exit 1; }; };;
- :[FH]-) ac_tag=-:-;;
- :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
- esac
- ac_save_IFS=$IFS
- IFS=:
- set x $ac_tag
- IFS=$ac_save_IFS
- shift
- ac_file=$1
- shift
-
- case $ac_mode in
- :L) ac_source=$1;;
- :[FH])
- ac_file_inputs=
- for ac_f
- do
- case $ac_f in
- -) ac_f="$tmp/stdin";;
- *) # Look for the file first in the build tree, then in the source tree
- # (if the path is not absolute). The absolute path cannot be DOS-style,
- # because $ac_f cannot contain `:'.
- test -f "$ac_f" ||
- case $ac_f in
- [\\/$]*) false;;
- *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
- esac ||
- { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
-echo "$as_me: error: cannot find input file: $ac_f" >&2;}
- { (exit 1); exit 1; }; };;
- esac
- ac_file_inputs="$ac_file_inputs $ac_f"
- done
-
- # Let's still pretend it is `configure' which instantiates (i.e., don't
- # use $as_me), people would be surprised to read:
- # /* config.h. Generated by config.status. */
- configure_input="Generated from "`IFS=:
- echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
- if test x"$ac_file" != x-; then
- configure_input="$ac_file. $configure_input"
- { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
- fi
-
- case $ac_tag in
- *:-:* | *:-) cat >"$tmp/stdin";;
- esac
- ;;
- esac
-
- ac_dir=`$as_dirname -- "$ac_file" ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$ac_file" : 'X\(//\)[^/]' \| \
- X"$ac_file" : 'X\(//\)$' \| \
- X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$ac_file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- { as_dir="$ac_dir"
- case $as_dir in #(
- -*) as_dir=./$as_dir;;
- esac
- test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
- as_dirs=
- while :; do
- case $as_dir in #(
- *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
- *) as_qdir=$as_dir;;
- esac
- as_dirs="'$as_qdir' $as_dirs"
- as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- test -d "$as_dir" && break
- done
- test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
-echo "$as_me: error: cannot create directory $as_dir" >&2;}
- { (exit 1); exit 1; }; }; }
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-
- case $ac_mode in
- :F)
- #
- # CONFIG_FILE
- #
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If the template does not know about datarootdir, expand it.
-# FIXME: This hack should be removed a few years after 2.60.
-ac_datarootdir_hack=
-
-case `sed -n '/datarootdir/ {
- p
- q
-}
-/@datadir@/p
-/@docdir@/p
-/@infodir@/p
-/@localedir@/p
-/@mandir@/p
-' $ac_file_inputs` in
-*datarootdir*) ;;
-*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
- { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
- ac_datarootdir_hack='
- s&@datadir@&$datadir&g
- s&@docdir@&$docdir&g
- s&@infodir@&$infodir&g
- s&@localedir@&$localedir&g
- s&@mandir@&$mandir&g
- s&\\\${datarootdir}&$datarootdir&g' ;;
-esac
-_ACEOF
-
-# Neutralize VPATH when `$srcdir' = `.'.
-# Shell code in configure.ac might set extrasub.
-# FIXME: do we really want to maintain this feature?
-cat >>$CONFIG_STATUS <<_ACEOF
- sed "$ac_vpsub
-$extrasub
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-:t
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s&@configure_input@&$configure_input&;t t
-s&@top_builddir@&$ac_top_builddir_sub&;t t
-s&@srcdir@&$ac_srcdir&;t t
-s&@abs_srcdir@&$ac_abs_srcdir&;t t
-s&@top_srcdir@&$ac_top_srcdir&;t t
-s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
-s&@builddir@&$ac_builddir&;t t
-s&@abs_builddir@&$ac_abs_builddir&;t t
-s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
-$ac_datarootdir_hack
-" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
-
- rm -f "$tmp/stdin"
- case $ac_file in
- -) cat "$tmp/out"; rm -f "$tmp/out";;
- *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
- esac
- ;;
-
-
-
- esac
-
-done # for ac_tag
-
-
-{ (exit 0); exit 0; }
-_ACEOF
-chmod +x $CONFIG_STATUS
-ac_clean_files=$ac_clean_files_save
-
-
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
-# output is simply discarded. So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status. When coming back to configure, we
-# need to make the FD available again.
-if test "$no_create" != yes; then
- ac_cs_success=:
- ac_config_status_args=
- test "$silent" = yes &&
- ac_config_status_args="$ac_config_status_args --quiet"
- exec 5>/dev/null
- $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
- exec 5>>config.log
- # Use ||, not &&, to avoid exiting from the if with $? = 1, which
- # would make configure fail if this is the last instruction.
- $ac_cs_success || { (exit 1); exit 1; }
-fi
-
diff --git a/ejabberd-1.1.2/src/configure.ac b/ejabberd-1.1.2/src/configure.ac
deleted file mode 100644
index c77f79f08..000000000
--- a/ejabberd-1.1.2/src/configure.ac
+++ /dev/null
@@ -1,85 +0,0 @@
-# -*- Autoconf -*-
-# Process this file with autoconf to produce a configure script.
-
-AC_PREREQ(2.53)
-AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
-
-# Checks for programs.
-AC_PROG_CC
-AC_PROG_MAKE_SET
-
-#locating erlang
-AM_WITH_ERLANG
-#locating iconv
-AM_ICONV
-#locating libexpat
-AM_WITH_EXPAT
-#locating zlib
-AM_WITH_ZLIB
-
-# Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-
-# Change default prefix
-AC_PREFIX_DEFAULT /
-
-# Checks for library functions.
-AC_FUNC_MALLOC
-AC_HEADER_STDC
-
-AC_MOD_ENABLE(mod_pubsub, yes)
-AC_MOD_ENABLE(mod_irc, yes)
-AC_MOD_ENABLE(mod_muc, yes)
-AC_MOD_ENABLE(eldap, yes)
-AC_MOD_ENABLE(web, yes)
-AC_MOD_ENABLE(tls, yes)
-AC_MOD_ENABLE(odbc, no)
-AC_MOD_ENABLE(ejabberd_zlib, yes)
-
-AC_ARG_ENABLE(roster_gateway_workaround,
-[ --enable-roster-gateway-workaround Turn on workaround for processing gateway subscriptions (default: no)],
-[case "${enableval}" in
- yes) roster_gateway_workaround=true ;;
- no) roster_gateway_workaround=false ;;
- *) AC_MSG_ERROR(bad value ${enableval} for --enable-roster-gateway-workaround) ;;
-esac],[roster_gateway_workaround=false])
-AC_SUBST(roster_gateway_workaround)
-
-AC_ARG_ENABLE(mssql,
-[ --enable-mssql Use Microsoft SQL Server database (default: no, requires --enable-odbc)],
-[case "${enableval}" in
- yes) db_type=mssql ;;
- no) db_type=generic ;;
- *) AC_MSG_ERROR(bad value ${enableval} for --enable-mssql) ;;
-esac],[db_type=generic])
-AC_SUBST(db_type)
-
-AC_CONFIG_FILES([Makefile
- $make_mod_irc
- $make_mod_muc
- $make_mod_pubsub
- $make_eldap
- $make_web
- stringprep/Makefile
- $make_tls
- $make_odbc
- $make_ejabberd_zlib])
-#openssl
-AM_WITH_OPENSSL
-# If ssl is kerberized it need krb5.h
-# On RedHat and OpenBSD, krb5.h is in an unsual place:
-KRB5_INCLUDE="`krb5-config --cflags 2>/dev/null`"
-if test -n "$KRB5_INCLUDE" ; then
- CPPFLAGS="$CPPFLAGS $KRB5_INCLUDE"
-else
- # For RedHat For BSD
- for D in /usr/kerberos/include /usr/include/kerberos /usr/include/kerberosV
- do
- if test -d $D ; then
- CPPFLAGS="$CPPFLAGS -I$D"
- fi
- done
-fi
-AC_CHECK_HEADER(krb5.h,,)
-
-AC_OUTPUT
diff --git a/ejabberd-1.1.2/src/configure.bat b/ejabberd-1.1.2/src/configure.bat
deleted file mode 100644
index 46a93d8c9..000000000
--- a/ejabberd-1.1.2/src/configure.bat
+++ /dev/null
@@ -1,20 +0,0 @@
-
-@if "x%1"=="x--help" goto usage
-
-@set arg=dynamic
-@if "x%1"=="x--static" set arg=static
-
-@echo Configuring for %arg% build...
-
-erlc configure.erl
-erl -s configure -env arg %arg% -noshell
-
-@goto end
-
-:usage
-@echo Usage: configure.bat
-@echo or configure.bat --static
-@echo or configure.bat --help
-
-:end
-
diff --git a/ejabberd-1.1.2/src/configure.erl b/ejabberd-1.1.2/src/configure.erl
deleted file mode 100644
index 688f94fe5..000000000
--- a/ejabberd-1.1.2/src/configure.erl
+++ /dev/null
@@ -1,72 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : configure.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 27 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(configure).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([start/0]).
-
--include("ejabberd.hrl").
-
-start() ->
- Static = case os:getenv("arg") of
- false ->
- false;
- "static" ->
- true;
- _ ->
- false
- end,
- case Static of
- true ->
- ExpatLib = "EXPAT_LIB = $(EXPAT_DIR)\\StaticLibs\\libexpatMT.lib\n",
- ExpatFlag = "EXPAT_FLAG = -DXML_STATIC\n",
- IconvDir = "ICONV_DIR = c:\\progra~1\\libiconv-1.9.1-static\n",
- IconvLib = "ICONV_LIB = $(ICONV_DIR)\\lib\\iconv.lib\n",
- ZlibDir = "ZLIB_DIR = c:\\progra~1\\zlib-1.2.3\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:\\progra~1\\libiconv-1.9.1\n",
- IconvLib = "ICONV_LIB = $(ICONV_DIR)\\lib\\iconv.lib\n",
- ZlibDir = "ZLIB_DIR = c:\\progra~1\\zlib-1.2.3\n",
- ZlibLib = "ZLIB_LIB = $(ZLIB_DIR)\\lib\\zlib1.lib\n"
- end,
-
- EVersion = "ERLANG_VERSION = " ++ erlang:system_info(version) ++ "\n",
- EIDirS = "EI_DIR = " ++ code:lib_dir("erl_interface") ++ "\n",
- RootDirS = "ERLANG_DIR = " ++ code:root_dir() ++ "\n",
- Version = "EJABBERD_VERSION = " ++ ?VERSION ++ "\n",
- ExpatDir = "EXPAT_DIR = c:\\progra~1\\expat-1.95.7\n",
- OpenSSLDir = "OPENSSL_DIR = c:\\progra~1\\OpenSSL\n",
- DBType = "DBTYPE = generic\n", %% 'generic' or 'mssql'
-
- SSLDir = "SSLDIR = " ++ code:lib_dir("ssl") ++ "\n",
- StdLibDir = "STDLIBDIR = " ++ code:lib_dir("stdlib") ++ "\n",
-
- file:write_file("Makefile.inc",
- list_to_binary(EVersion ++
- EIDirS ++
- RootDirS ++
- Version ++
- SSLDir ++
- StdLibDir ++
- OpenSSLDir ++
- DBType ++
- ExpatDir ++
- ExpatLib ++
- ExpatFlag ++
- IconvDir ++
- IconvLib ++
- ZlibDir ++
- ZlibLib)),
- halt().
-
-
diff --git a/ejabberd-1.1.2/src/cyrsasl.erl b/ejabberd-1.1.2/src/cyrsasl.erl
deleted file mode 100644
index f8e548826..000000000
--- a/ejabberd-1.1.2/src/cyrsasl.erl
+++ /dev/null
@@ -1,149 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : cyrsasl.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Cyrus SASL-like library
-%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(cyrsasl).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([start/0,
- register_mechanism/3,
- listmech/1,
- server_new/6,
- server_start/3,
- server_step/2]).
-
--record(sasl_mechanism, {mechanism, module, require_plain_password}).
--record(sasl_state, {service, myname, realm,
- get_password, check_password,
- mech_mod, mech_state}).
-
--export([behaviour_info/1]).
-
-behaviour_info(callbacks) ->
- [{mech_new, 3}, {mech_step, 2}];
-behaviour_info(Other) ->
- undefined.
-
-start() ->
- ets:new(sasl_mechanism, [named_table,
- public,
- {keypos, #sasl_mechanism.mechanism}]),
- cyrsasl_plain:start([]),
- cyrsasl_digest:start([]),
- cyrsasl_anonymous:start([]),
- ok.
-
-register_mechanism(Mechanism, Module, RequirePlainPassword) ->
- ets:insert(sasl_mechanism,
- #sasl_mechanism{mechanism = Mechanism,
- module = Module,
- require_plain_password = RequirePlainPassword}).
-
-% TODO: use callbacks
--include("ejabberd.hrl").
--include("jlib.hrl").
-check_authzid(State, Props) ->
- AuthzId = xml:get_attr_s(authzid, Props),
- case jlib:string_to_jid(AuthzId) of
- error ->
- {error, "invalid-authzid"};
- JID ->
- LUser = jlib:nodeprep(xml:get_attr_s(username, Props)),
- {U, S, R} = jlib:jid_tolower(JID),
- case R of
- "" ->
- {error, "invalid-authzid"};
- _ ->
- case {LUser, ?MYNAME} of
- {U, S} ->
- ok;
- _ ->
- {error, "invalid-authzid"}
- end
- end
- end.
-
-check_credentials(State, Props) ->
- User = xml:get_attr_s(username, Props),
- case jlib:nodeprep(User) of
- error ->
- {error, "not-authorized"};
- "" ->
- {error, "not-authorized"};
- LUser ->
- ok
- end.
-
-listmech(Host) ->
- RequirePlainPassword = ejabberd_auth:plain_password_required(Host),
-
- Mechs = ets:select(sasl_mechanism,
- [{#sasl_mechanism{mechanism = '$1',
- require_plain_password = '$2',
- _ = '_'},
- if
- RequirePlainPassword ->
- [{'==', '$2', false}];
- true ->
- []
- end,
- ['$1']}]),
- filter_anonymous(Host, Mechs).
-
-server_new(Service, ServerFQDN, UserRealm, SecFlags,
- GetPassword, CheckPassword) ->
- #sasl_state{service = Service,
- myname = ServerFQDN,
- realm = UserRealm,
- get_password = GetPassword,
- check_password = CheckPassword}.
-
-server_start(State, Mech, ClientIn) ->
- case lists:member(Mech, listmech(State#sasl_state.myname)) of
- true ->
- case ets:lookup(sasl_mechanism, Mech) of
- [#sasl_mechanism{module = Module}] ->
- {ok, MechState} = Module:mech_new(
- State#sasl_state.myname,
- State#sasl_state.get_password,
- State#sasl_state.check_password),
- server_step(State#sasl_state{mech_mod = Module,
- mech_state = MechState},
- ClientIn);
- _ ->
- {error, "no-mechanism"}
- end;
- false ->
- {error, "no-mechanism"}
- end.
-
-server_step(State, ClientIn) ->
- Module = State#sasl_state.mech_mod,
- MechState = State#sasl_state.mech_state,
- case Module:mech_step(MechState, ClientIn) of
- {ok, Props} ->
- case check_credentials(State, Props) of
- ok ->
- {ok, Props};
- {error, Error} ->
- {error, Error}
- end;
- {continue, ServerOut, NewMechState} ->
- {continue, ServerOut,
- State#sasl_state{mech_state = NewMechState}};
- {error, Error} ->
- {error, Error}
- end.
-
-%% Remove the anonymous mechanism from the list if not enabled for the given
-%% host
-filter_anonymous(Host, Mechs) ->
- case ejabberd_auth_anonymous:is_sasl_anonymous_enabled(Host) of
- true -> Mechs;
- false -> Mechs -- ["ANONYMOUS"]
- end.
diff --git a/ejabberd-1.1.2/src/cyrsasl_anonymous.erl b/ejabberd-1.1.2/src/cyrsasl_anonymous.erl
deleted file mode 100644
index 6f05be9d1..000000000
--- a/ejabberd-1.1.2/src/cyrsasl_anonymous.erl
+++ /dev/null
@@ -1,39 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : cyrsasl_anonymous.erl
-%%% Author : Magnus Henoch <henoch@dtek.chalmers.se>
-%%% Purpose : ANONYMOUS SASL mechanism
-%%% Created : 23 Aug 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
-%% See http://www.ietf.org/internet-drafts/draft-ietf-sasl-anon-05.txt
-
--module(cyrsasl_anonymous).
--vsn('$Revision$').
-
--export([start/1, stop/0, mech_new/3, mech_step/2]).
-
--behaviour(cyrsasl).
-
--record(state, {server}).
-
-start(_Opts) ->
- cyrsasl:register_mechanism("ANONYMOUS", ?MODULE, false),
- ok.
-
-stop() ->
- ok.
-
-mech_new(Host, _GetPassword, _CheckPassword) ->
- {ok, #state{server = Host}}.
-
-mech_step(State, _ClientIn) ->
- %% We generate a random username:
- User = lists:concat([randoms:get_string() | tuple_to_list(now())]),
- Server = State#state.server,
-
- %% Checks that the username is available
- case ejabberd_auth:is_user_exists(User, Server) of
- true -> {error, "not-authorized"};
- false -> {ok, [{username, User}]}
- end.
diff --git a/ejabberd-1.1.2/src/cyrsasl_digest.erl b/ejabberd-1.1.2/src/cyrsasl_digest.erl
deleted file mode 100644
index cc44b1a95..000000000
--- a/ejabberd-1.1.2/src/cyrsasl_digest.erl
+++ /dev/null
@@ -1,163 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : cyrsasl_digest.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : DIGEST-MD5 SASL mechanism
-%%% Created : 11 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(cyrsasl_digest).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([start/1,
- stop/0,
- mech_new/3,
- mech_step/2]).
-
--behaviour(cyrsasl).
-
--record(state, {step, nonce, username, authzid, get_password}).
-
-start(_Opts) ->
- cyrsasl:register_mechanism("DIGEST-MD5", ?MODULE, true).
-
-stop() ->
- ok.
-
-mech_new(_Host, GetPassword, _CheckPassword) ->
- {ok, #state{step = 1,
- nonce = randoms:get_string(),
- get_password = GetPassword}}.
-
-mech_step(#state{step = 1, nonce = Nonce} = State, _) ->
- {continue,
- "nonce=\"" ++ Nonce ++
- "\",qop=\"auth\",charset=utf-8,algorithm=md5-sess",
- State#state{step = 3}};
-mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
- case parse(ClientIn) of
- bad ->
- {error, "bad-protocol"};
- KeyVals ->
- UserName = xml:get_attr_s("username", KeyVals),
- AuthzId = xml:get_attr_s("authzid", KeyVals),
- case (State#state.get_password)(UserName) of
- false ->
- {error, "not-authorized"};
- Passwd ->
- Response = response(KeyVals, UserName, Passwd,
- Nonce, AuthzId, "AUTHENTICATE"),
- case xml:get_attr_s("response", KeyVals) of
- Response ->
- RspAuth = response(KeyVals,
- UserName, Passwd,
- Nonce, AuthzId, ""),
- {continue,
- "rspauth=" ++ RspAuth,
- State#state{step = 5,
- username = UserName,
- authzid = AuthzId}};
- _ ->
- {error, "not-authorized"}
- end
- end
- end;
-mech_step(#state{step = 5,
- username = UserName,
- authzid = AuthzId}, "") ->
- {ok, [{username, UserName}, {authzid, AuthzId}]};
-mech_step(A, B) ->
- io:format("SASL DIGEST: A ~p B ~p", [A,B]),
- {error, "bad-protocol"}.
-
-
-parse(S) ->
- parse1(S, "", []).
-
-parse1([$= | Cs], S, Ts) ->
- parse2(Cs, lists:reverse(S), "", Ts);
-parse1([$, | Cs], [], Ts) ->
- parse1(Cs, [], Ts);
-parse1([$\s | Cs], [], Ts) ->
- parse1(Cs, [], Ts);
-parse1([C | Cs], S, Ts) ->
- parse1(Cs, [C | S], Ts);
-parse1([], [], T) ->
- lists:reverse(T);
-parse1([], _S, _T) ->
- bad.
-
-parse2([$" | Cs], Key, Val, Ts) ->
- parse3(Cs, Key, Val, Ts);
-parse2([C | Cs], Key, Val, Ts) ->
- parse4(Cs, Key, [C | Val], Ts);
-parse2([], _, _, _) ->
- bad.
-
-parse3([$" | Cs], Key, Val, Ts) ->
- parse4(Cs, Key, Val, Ts);
-parse3([C | Cs], Key, Val, Ts) ->
- parse3(Cs, Key, [C | Val], Ts);
-parse3([], _, _, _) ->
- bad.
-
-parse4([$, | Cs], Key, Val, Ts) ->
- parse1(Cs, "", [{Key, lists:reverse(Val)} | Ts]);
-parse4([$\s | Cs], Key, Val, Ts) ->
- parse4(Cs, Key, Val, Ts);
-parse4([C | Cs], Key, Val, Ts) ->
- parse4(Cs, Key, [C | Val], Ts);
-parse4([], Key, Val, Ts) ->
- parse1([], "", [{Key, lists:reverse(Val)} | Ts]).
-
-
-
-
-
-
-digit_to_xchar(D) when (D >= 0) and (D < 10) ->
- D + 48;
-digit_to_xchar(D) ->
- D + 87.
-
-hex(S) ->
- hex(S, []).
-
-hex([], Res) ->
- lists:reverse(Res);
-hex([N | Ns], Res) ->
- hex(Ns, [digit_to_xchar(N rem 16),
- digit_to_xchar(N div 16) | Res]).
-
-
-response(KeyVals, User, Passwd, Nonce, AuthzId, A2Prefix) ->
- Realm = xml:get_attr_s("realm", KeyVals),
- CNonce = xml:get_attr_s("cnonce", KeyVals),
- DigestURI = xml:get_attr_s("digest-uri", KeyVals),
- NC = xml:get_attr_s("nc", KeyVals),
- QOP = xml:get_attr_s("qop", KeyVals),
- A1 = case AuthzId of
- "" ->
- binary_to_list(
- crypto:md5(User ++ ":" ++ Realm ++ ":" ++ Passwd)) ++
- ":" ++ Nonce ++ ":" ++ CNonce;
- _ ->
- binary_to_list(
- crypto:md5(User ++ ":" ++ Realm ++ ":" ++ Passwd)) ++
- ":" ++ Nonce ++ ":" ++ CNonce ++ ":" ++ AuthzId
- end,
- A2 = case QOP of
- "auth" ->
- A2Prefix ++ ":" ++ DigestURI;
- _ ->
- A2Prefix ++ ":" ++ DigestURI ++
- ":00000000000000000000000000000000"
- end,
- T = hex(binary_to_list(crypto:md5(A1))) ++ ":" ++ Nonce ++ ":" ++
- NC ++ ":" ++ CNonce ++ ":" ++ QOP ++ ":" ++
- hex(binary_to_list(crypto:md5(A2))),
- hex(binary_to_list(crypto:md5(T))).
-
-
-
diff --git a/ejabberd-1.1.2/src/cyrsasl_plain.erl b/ejabberd-1.1.2/src/cyrsasl_plain.erl
deleted file mode 100644
index e58e1cc22..000000000
--- a/ejabberd-1.1.2/src/cyrsasl_plain.erl
+++ /dev/null
@@ -1,57 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : cyrsasl_plain.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : PLAIN SASL mechanism
-%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(cyrsasl_plain).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([start/1, stop/0, mech_new/3, mech_step/2, parse/1]).
-
--behaviour(cyrsasl).
-
--record(state, {check_password}).
-
-start(_Opts) ->
- cyrsasl:register_mechanism("PLAIN", ?MODULE, false),
- ok.
-
-stop() ->
- ok.
-
-mech_new(_Host, _GetPassword, CheckPassword) ->
- {ok, #state{check_password = CheckPassword}}.
-
-mech_step(State, ClientIn) ->
- case parse(ClientIn) of
- [AuthzId, User, Password] ->
- case (State#state.check_password)(User, Password) of
- true ->
- {ok, [{username, User}, {authzid, AuthzId}]};
- _ ->
- {error, "bad-auth"}
- end;
- _ ->
- {error, "bad-protocol"}
- end.
-
-
-parse(S) ->
- parse1(S, "", []).
-
-parse1([0 | Cs], S, T) ->
- parse1(Cs, "", [lists:reverse(S) | T]);
-parse1([C | Cs], S, T) ->
- parse1(Cs, [C | S], T);
-%parse1([], [], T) ->
-% lists:reverse(T);
-parse1([], S, T) ->
- lists:reverse([lists:reverse(S) | T]).
-
-
-
-
diff --git a/ejabberd-1.1.2/src/ejabberd.app b/ejabberd-1.1.2/src/ejabberd.app
deleted file mode 100644
index ea87c9215..000000000
--- a/ejabberd-1.1.2/src/ejabberd.app
+++ /dev/null
@@ -1,79 +0,0 @@
-% $Id$
-
-{application, ejabberd,
- [{description, "ejabberd"},
- {vsn, "1.1.2"},
- {modules, [acl,
- configure,
- cyrsasl,
- cyrsasl_digest,
- cyrsasl_plain,
- ejabberd,
- ejabberd_app,
- ejabberd_auth,
- ejabberd_c2s,
- ejabberd_config,
- ejabberd_listener,
- ejabberd_logger_h,
- ejabberd_local,
- ejabberd_router,
- ejabberd_s2s,
- ejabberd_s2s_in,
- ejabberd_s2s_out,
- ejabberd_service,
- ejabberd_sm,
- ejabberd_sup,
- ejabberd_tmp_sup,
- gen_iq_handler,
- gen_mod,
- jd2ejd,
- jlib,
- mod_configure,
- mod_disco,
- mod_echo,
- mod_last,
- mod_offline,
- mod_private,
- mod_register,
- mod_roster,
- mod_stats,
- mod_time,
- mod_vcard,
- mod_version,
- randoms,
- sha,
- shaper,
- translate,
- xml,
- xml_stream
- ]},
- {registered, [ejabberd,
- ejabberd_sup,
- ejabberd_auth,
- ejabberd_router,
- ejabberd_sm,
- ejabberd_s2s,
- ejabberd_local,
- ejabberd_listeners,
- ejabberd_iq_sup,
- ejabberd_service_sup,
- ejabberd_s2s_out_sup,
- ejabberd_s2s_in_sup,
- ejabberd_c2s_sup,
- ejabberd_mod_roster,
- ejabberd_mod_echo,
- ejabberd_mod_pubsub,
- ejabberd_mod_irc,
- ejabberd_mod_muc,
- ejabberd_offline,
- random_generator
- ]},
- {applications, [kernel, stdlib]},
- {env, []},
- {mod, {ejabberd_app, []}}]}.
-
-
-
-% Local Variables:
-% mode: erlang
-% End:
diff --git a/ejabberd-1.1.2/src/ejabberd.cfg.example b/ejabberd-1.1.2/src/ejabberd.cfg.example
deleted file mode 100644
index bcc103385..000000000
--- a/ejabberd-1.1.2/src/ejabberd.cfg.example
+++ /dev/null
@@ -1,187 +0,0 @@
-% $Id$
-
-%override_acls.
-
-
-% Users that have admin access. Add line like one of the following after you
-% will be successfully registered on server to get admin access:
-%{acl, admin, {user, "aleksey"}}.
-%{acl, admin, {user, "ermine"}}.
-
-% Blocked users:
-%{acl, blocked, {user, "test"}}.
-
-% Local users:
-{acl, local, {user_regexp, ""}}.
-
-% Another examples of ACLs:
-%{acl, jabberorg, {server, "jabber.org"}}.
-%{acl, aleksey, {user, "aleksey", "jabber.ru"}}.
-%{acl, test, {user_regexp, "^test"}}.
-%{acl, test, {user_glob, "test*"}}.
-
-% Everybody can create pubsub nodes
-{access, pubsub_createnode, [{allow, all}]}.
-
-% Only admins can use configuration interface:
-{access, configure, [{allow, admin}]}.
-
-% Every username can be registered via in-band registration:
-% You could replace {allow, all} with {deny, all} to prevent user from using
-% in-band registration
-{access, register, [{allow, all}]}.
-
-% After successful registration user will get message with following subject
-% and body:
-{welcome_message,
- {"Welcome!",
- "Welcome to Jabber Service. "
- "For information about Jabber visit http://jabber.org"}}.
-% Replace them with 'none' if you don't want to send such message:
-%{welcome_message, none}.
-
-% List of people who will get notifications about registered users
-%{registration_watchers, ["admin1@localhost",
-% "admin2@localhost"]}.
-
-% Only admins can send announcement messages:
-{access, announce, [{allow, admin}]}.
-
-
-% Only non-blocked users can use c2s connections:
-{access, c2s, [{deny, blocked},
- {allow, all}]}.
-
-% Set shaper with name "normal" to limit traffic speed to 1000B/s
-{shaper, normal, {maxrate, 1000}}.
-
-% Set shaper with name "fast" to limit traffic speed to 50000B/s
-{shaper, fast, {maxrate, 50000}}.
-
-% For all users except admins used "normal" shaper
-{access, c2s_shaper, [{none, admin},
- {normal, all}]}.
-
-% For all S2S connections used "fast" shaper
-{access, s2s_shaper, [{fast, all}]}.
-
-% Admins of this server are also admins of MUC service:
-{access, muc_admin, [{allow, admin}]}.
-
-% All users are allowed to use MUC service:
-{access, muc, [{allow, all}]}.
-
-% This rule allows access only for local users:
-{access, local, [{allow, local}]}.
-
-
-% Authentication method. If you want to use internal user base, then use
-% this line:
-{auth_method, internal}.
-
-% For LDAP authentication use these lines instead of above one:
-%{auth_method, ldap}.
-%{ldap_servers, ["localhost"]}. % List of LDAP servers
-%{ldap_uidattr, "uid"}. % LDAP attribute that holds user ID
-%{ldap_base, "dc=example,dc=com"}. % Search base of LDAP directory
-%{ldap_rootdn, "dc=example,dc=com"}. % LDAP manager
-%{ldap_password, "******"}. % Password to LDAP manager
-
-% For authentication via external script use the following:
-%{auth_method, external}.
-%{extauth_program, "/path/to/authentication/script"}.
-
-% For authentication via ODBC use the following:
-%{auth_method, odbc}.
-%{odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}.
-
-
-% Host name:
-{hosts, ["localhost"]}.
-
-%% Define the maximum number of time a single user is allowed to connect:
-{max_user_sessions, 10}.
-
-%% Anonymous login support:
-%% auth_method: anonymous
-%% anonymous_protocol: sasl_anon|login_anon|both
-%% allow_multiple_connections: true|false
-%%{host_config, "public.example.org", [{auth_method, anonymous},
-%% {allow_multiple_connections, false},
-%% {anonymous_protocol, sasl_anon}]}.
-%% To use both anonymous and internal authentication:
-%%{host_config, "public.example.org", [{auth_method, [anonymous, internal]}]}.
-
-% Default language for server messages
-{language, "en"}.
-
-% Listened ports:
-{listen,
- [{5222, ejabberd_c2s, [{access, c2s}, {shaper, c2s_shaper},
- {max_stanza_size, 65536},
- starttls, {certfile, "./ssl.pem"}]},
- {5223, ejabberd_c2s, [{access, c2s},
- {max_stanza_size, 65536},
- tls, {certfile, "./ssl.pem"}]},
- % Use these two lines instead if TLS support is not compiled
- %{5222, ejabberd_c2s, [{access, c2s}, {shaper, c2s_shaper}]},
- %{5223, ejabberd_c2s, [{access, c2s}, ssl, {certfile, "./ssl.pem"}]},
- {5269, ejabberd_s2s_in, [{shaper, s2s_shaper},
- {max_stanza_size, 131072}
- ]},
- {5280, ejabberd_http, [http_poll, web_admin]},
- {8888, ejabberd_service, [{access, all},
- {hosts, ["icq.localhost", "sms.localhost"],
- [{password, "secret"}]}]}
- ]}.
-
-
-% Use STARTTLS+Dialback for S2S connections
-{s2s_use_starttls, true}.
-{s2s_certfile, "./ssl.pem"}.
-%{domain_certfile, "example.org", "./example_org.pem"}.
-%{domain_certfile, "example.com", "./example_com.pem"}.
-
-% If SRV lookup fails, then port 5269 is used to communicate with remote server
-{outgoing_s2s_port, 5269}.
-
-
-% Used modules:
-{modules,
- [
- {mod_register, [{access, register}]},
- {mod_roster, []},
- {mod_privacy, []},
- {mod_adhoc, []},
- {mod_configure, []}, % Depends on mod_adhoc
- {mod_configure2, []},
- {mod_disco, []},
- {mod_stats, []},
- {mod_vcard, []},
- {mod_offline, []},
- {mod_announce, [{access, announce}]}, % Depends on mod_adhoc
- {mod_echo, [{host, "echo.localhost"}]},
- {mod_private, []},
- {mod_irc, []},
-% Default options for mod_muc:
-% host: "conference." ++ ?MYNAME
-% access: all
-% access_create: all
-% access_admin: none (only room creator has owner privileges)
- {mod_muc, [{access, muc},
- {access_create, muc},
- {access_admin, muc_admin}]},
-% {mod_muc_log, []},
-% {mod_shared_roster, []},
- {mod_pubsub, [{access_createnode, pubsub_createnode}]},
- {mod_time, []},
- {mod_last, []},
- {mod_version, []}
- ]}.
-
-
-
-
-% Local Variables:
-% mode: erlang
-% End:
diff --git a/ejabberd-1.1.2/src/ejabberd.erl b/ejabberd-1.1.2/src/ejabberd.erl
deleted file mode 100644
index fd6e48e08..000000000
--- a/ejabberd-1.1.2/src/ejabberd.erl
+++ /dev/null
@@ -1,34 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([start/0, stop/0,
- get_so_path/0]).
-
-start() ->
- application:start(ejabberd).
-
-stop() ->
- application:stop(ejabberd).
-
-
-get_so_path() ->
- case os:getenv("EJABBERD_SO_PATH") of
- false ->
- case code:priv_dir(ejabberd) of
- {error, _} ->
- ".";
- Path ->
- filename:join([Path, "lib"])
- end;
- Path ->
- Path
- end.
diff --git a/ejabberd-1.1.2/src/ejabberd.hrl b/ejabberd-1.1.2/src/ejabberd.hrl
deleted file mode 100644
index 47de8a2c9..000000000
--- a/ejabberd-1.1.2/src/ejabberd.hrl
+++ /dev/null
@@ -1,41 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd.hrl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 17 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--define(VERSION, "1.1.2").
-
-%-define(ejabberd_debug, true).
-%-define(DBGFSM, true).
-
--ifdef(ejabberd_debug).
--define(DEBUG(Format, Args), io:format("D(~p:~p:~p) : "++Format++"~n",
- [self(),?MODULE,?LINE]++Args)).
--else.
--define(DEBUG(F,A),[]).
--endif.
-
--define(ERROR_MSG(Format, Args),
- error_logger:error_msg("E(~p:~p:~p): "++Format++"~n",
- [self(),?MODULE,?LINE]++Args)).
-
--define(INFO_MSG(Format, Args),
- error_logger:info_msg("I(~p:~p:~p): "++Format++"~n",
- [self(),?MODULE,?LINE]++Args)).
-
-
--define(MYHOSTS, ejabberd_config:get_global_option(hosts)).
--define(MYNAME, hd(ejabberd_config:get_global_option(hosts))).
--define(S2STIMEOUT, 600000).
--define(MYLANG, ejabberd_config:get_global_option(language)).
-
--define(MSGS_DIR, "msgs").
--define(CONFIG_PATH, "ejabberd.cfg").
--define(LOG_PATH, "ejabberd.log").
-
-
--define(PRIVACY_SUPPORT, true).
-
diff --git a/ejabberd-1.1.2/src/ejabberd_admin.erl b/ejabberd-1.1.2/src/ejabberd_admin.erl
deleted file mode 100644
index 379e347b1..000000000
--- a/ejabberd-1.1.2/src/ejabberd_admin.erl
+++ /dev/null
@@ -1,59 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File : ejabberd_admin.erl
-%%% Author : Mickael Remond <mremond@process-one.net>
-%%% Description : This module gathers admin functions used by different
-%%% access method:
-%%% - ejabberdctl command-line tool
-%%% - web admin interface
-%%% - adhoc mode
-%%%
-%%% Created : 7 May 2006 by Mickael Remond <mremond@process-one.net>
-%%% Id : $Id: $
-%%%----------------------------------------------------------------------
-%%% Copyright (c) 2006 Process One
-%%%-------------------------------------------------------------------
-
--module(ejabberd_admin).
--author('mickael.remond@process-one.net').
--vsn('$Revision: $ ').
-
--export([restore/1]).
-
--include("ejabberd.hrl").
-
-%% Mnesia database restore
-%% This function is called from ejabberd_ctl, ejabberd_web_admin and
-%% mod_configure/adhoc
-restore(Path) ->
- mnesia:restore(Path, [{keep_tables,keep_tables()},
- {default_op, skip_tables}]).
-
-%% This function return a list of tables that should be kept from a previous
-%% version backup.
-%% Obsolete tables or tables created by module who are no longer used are not
-%% restored and are ignored.
-keep_tables() ->
- lists:flatten([acl, passwd, config, local_config, disco_publish,
- keep_modules_tables()]).
-
-%% Returns the list of modules tables in use, according to the list of actually
-%% loaded modules
-keep_modules_tables() ->
- lists:map(fun(Module) -> module_tables(Module) end,
- gen_mod:loaded_modules(?MYNAME)).
-
-%% TODO: This mapping should probably be moved to a callback function in each
-%% module.
-%% Mapping between modules and their tables
-module_tables(mod_announce) -> [motd, motd_users];
-module_tables(mod_irc) -> [irc_custom];
-module_tables(mod_last) -> [last_activity];
-module_tables(mod_muc) -> [muc_room, muc_registered];
-module_tables(mod_offline) -> [offline_msg];
-module_tables(mod_privacy) -> [privacy];
-module_tables(mod_private) -> [private_storage];
-module_tables(mod_pubsub) -> [pubsub_node];
-module_tables(mod_roster) -> [roster];
-module_tables(mod_shared_roster) -> [sr_group, sr_user];
-module_tables(mod_vcard) -> [vcard, vcard_search];
-module_tables(_Other) -> [].
diff --git a/ejabberd-1.1.2/src/ejabberd_app.erl b/ejabberd-1.1.2/src/ejabberd_app.erl
deleted file mode 100644
index c1ea274a2..000000000
--- a/ejabberd-1.1.2/src/ejabberd_app.erl
+++ /dev/null
@@ -1,104 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_app.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_app).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(application).
-
--export([start/2, stop/1, init/0]).
-
--include("ejabberd.hrl").
-
-start(normal, _Args) ->
- application:start(sasl),
- randoms:start(),
- db_init(),
- sha:start(),
- catch ssl:start(),
- translate:start(),
- acl:start(),
- ejabberd_ctl:init(),
- gen_mod:start(),
- ejabberd_config:start(),
- Sup = ejabberd_sup:start_link(),
- ejabberd_auth:start(),
- cyrsasl:start(),
- % Profiling
- %eprof:start(),
- %eprof:profile([self()]),
- %fprof:trace(start, "/tmp/fprof"),
- start(),
- load_modules(),
- Sup;
-start(_, _) ->
- {error, badarg}.
-
-stop(_StartArgs) ->
- ok.
-
-start() ->
- spawn_link(?MODULE, init, []).
-
-init() ->
- register(ejabberd, self()),
- %erlang:system_flag(fullsweep_after, 0),
- %error_logger:logfile({open, ?LOG_PATH}),
- LogPath =
- case application:get_env(log_path) of
- {ok, Path} ->
- Path;
- undefined ->
- case os:getenv("EJABBERD_LOG_PATH") of
- false ->
- ?LOG_PATH;
- Path ->
- Path
- end
- end,
- error_logger:add_report_handler(ejabberd_logger_h, LogPath),
- erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv),
- case erl_ddll:load_driver(ejabberd:get_so_path(), expat_erl) of
- ok -> ok;
- {error, already_loaded} -> ok
- end,
- Port = open_port({spawn, expat_erl}, [binary]),
- loop(Port).
-
-
-loop(Port) ->
- receive
- _ ->
- loop(Port)
- end.
-
-db_init() ->
- case mnesia:system_info(extra_db_nodes) of
- [] ->
- mnesia:create_schema([node()]);
- _ ->
- ok
- end,
- mnesia:start(),
- mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
-
-load_modules() ->
- lists:foreach(
- fun(Host) ->
- case ejabberd_config:get_local_option({modules, Host}) of
- undefined ->
- ok;
- Modules ->
- lists:foreach(
- fun({Module, Args}) ->
- gen_mod:start_module(Host, Module, Args)
- end, Modules)
- end
- end, ?MYHOSTS).
-
diff --git a/ejabberd-1.1.2/src/ejabberd_auth.erl b/ejabberd-1.1.2/src/ejabberd_auth.erl
deleted file mode 100644
index 4c34ae76a..000000000
--- a/ejabberd-1.1.2/src/ejabberd_auth.erl
+++ /dev/null
@@ -1,176 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_auth.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Authentification
-%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Updated : 23 Feb 2006 by Mickael Remond <mremond@process-one.net>
-%%% for anonymous login support
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
-%% TODO: Use the functions in ejabberd auth to add and remove users.
-
--module(ejabberd_auth).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
-%% External exports
--export([start/0,
- set_password/3,
- check_password/3,
- check_password/5,
- try_register/3,
- dirty_get_registered_users/0,
- get_vh_registered_users/1,
- get_password/2,
- get_password_s/2,
- is_user_exists/2,
- is_user_exists_in_other_modules/3,
- remove_user/2,
- remove_user/3,
- plain_password_required/1,
- ctl_process_get_registered/3
- ]).
-
--export([auth_modules/1]).
-
--include("ejabberd.hrl").
--include("ejabberd_ctl.hrl").
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-start() ->
- lists:foreach(
- fun(Host) ->
- lists:foreach(
- fun(M) ->
- M:start(Host)
- end, auth_modules(Host))
- end, ?MYHOSTS).
-
-plain_password_required(Server) ->
- lists:any(
- fun(M) ->
- M:plain_password_required()
- end, auth_modules(Server)).
-
-check_password(User, Server, Password) ->
- lists:any(
- fun(M) ->
- M:check_password(User, Server, Password)
- end, auth_modules(Server)).
-
-check_password(User, Server, Password, StreamID, Digest) ->
- lists:any(
- fun(M) ->
- M:check_password(User, Server, Password, StreamID, Digest)
- end, auth_modules(Server)).
-
-set_password(User, Server, Password) ->
- lists:foldl(
- fun(M, {error, _}) ->
- M:set_password(User, Server, Password);
- (_M, Res) ->
- Res
- end, {error, not_allowed}, auth_modules(Server)).
-
-try_register(User, Server, Password) ->
- case is_user_exists(User,Server) of
- true ->
- {atomic, exists};
- false ->
- case lists:member(jlib:nameprep(Server), ?MYHOSTS) of
- true ->
- lists:foldl(
- fun(_M, {atomic, ok} = Res) ->
- Res;
- (M, _) ->
- M:try_register(User, Server, Password)
- end, {error, not_allowed}, auth_modules(Server));
- false ->
- {error, not_allowed}
- end
- end.
-
-%% Registered users list do not include anonymous users logged
-dirty_get_registered_users() ->
- lists:flatmap(
- fun(M) ->
- M:dirty_get_registered_users()
- end, auth_modules(?MYNAME)).
-
-%% Registered users list do not include anonymous users logged
-get_vh_registered_users(Server) ->
- lists:flatmap(
- fun(M) ->
- M:get_vh_registered_users(Server)
- end, auth_modules(Server)).
-
-get_password(User, Server) ->
- lists:foldl(
- fun(M, false) ->
- M:get_password(User, Server);
- (_M, Password) ->
- Password
- end, false, auth_modules(Server)).
-
-get_password_s(User, Server) ->
- case get_password(User, Server) of
- false ->
- "";
- Password ->
- Password
- end.
-
-%% Returns true if the user exists in the DB or if an anonymous user is logged
-%% under the given name
-is_user_exists(User, Server) ->
- lists:any(
- fun(M) ->
- M:is_user_exists(User, Server)
- end, auth_modules(Server)).
-
-%% Check if the user exists in all authentications module except the module
-%% passed as parameter
-is_user_exists_in_other_modules(Module, User, Server) ->
- lists:any(
- fun(M) ->
- M:is_user_exists(User, Server)
- end, auth_modules(Server)--[Module]).
-
-remove_user(User, Server) ->
- lists:foreach(
- fun(M) ->
- M:remove_user(User, Server)
- end, auth_modules(Server)).
-
-remove_user(User, Server, Password) ->
- lists:foreach(
- fun(M) ->
- M:remove_user(User, Server, Password)
- end, auth_modules(Server)).
-
-
-ctl_process_get_registered(_Val, Host, ["registered-users"]) ->
- Users = ejabberd_auth:get_vh_registered_users(Host),
- NewLine = io_lib:format("~n", []),
- SUsers = lists:sort(Users),
- FUsers = lists:map(fun({U, _S}) -> [U, NewLine] end, SUsers),
- io:format("~s", [FUsers]),
- {stop, ?STATUS_SUCCESS};
-ctl_process_get_registered(Val, _Host, _Args) ->
- Val.
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-auth_modules(Server) ->
- LServer = jlib:nameprep(Server),
- Method = ejabberd_config:get_local_option({auth_method, LServer}),
- Methods = if
- Method == undefined -> [];
- is_list(Method) -> Method;
- is_atom(Method) -> [Method]
- end,
- [list_to_atom("ejabberd_auth_" ++ atom_to_list(M)) || M <- Methods].
diff --git a/ejabberd-1.1.2/src/ejabberd_auth_anonymous.erl b/ejabberd-1.1.2/src/ejabberd_auth_anonymous.erl
deleted file mode 100644
index 5090a353c..000000000
--- a/ejabberd-1.1.2/src/ejabberd_auth_anonymous.erl
+++ /dev/null
@@ -1,221 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_auth_anonymous.erl
-%%% Author : Mickael Remond <mickael.remond@process-one.net>
-%%% Purpose : Anonymous feature support in ejabberd
-%%% Created : 17 Feb 2006 by Mickael Remond <mremond@process-one.net>
-%%%
-%%% Anonymous support is based on the work of Magnus Henoch
-%%% <henoch@dtek.chalmers.se> and heavily extended by Process-one.
-%%%
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_auth_anonymous).
--author('mickael.remond@process-one.net').
--vsn('$Revision$ ').
-
--export([start/1,
- allow_anonymous/1,
- is_sasl_anonymous_enabled/1,
- is_login_anonymous_enabled/1,
- anonymous_user_exist/2,
- allow_multiple_connections/1,
- register_connection/2,
- unregister_connection/2
- ]).
-
-
-%% Function used by ejabberd_auth:
--export([login/2,
- set_password/3,
- check_password/3,
- check_password/5,
- try_register/3,
- dirty_get_registered_users/0,
- get_vh_registered_users/1,
- get_password/2,
- get_password/3,
- is_user_exists/2,
- remove_user/2,
- remove_user/3,
- plain_password_required/0]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--record(anonymous, {us, sid}).
-
-%% Create the anonymous table if at least one virtual host has anonymous features enabled
-%% Register to login / logout events
-start(Host) ->
- %% TODO: Check cluster mode
- mnesia:create_table(anonymous, [{ram_copies, [node()]},
- {type, bag},
- {attributes, record_info(fields, anonymous)}]),
- %% The hooks are needed to add / remove users from the anonymous tables
- ejabberd_hooks:add(sm_register_connection_hook, Host,
- ?MODULE, register_connection, 100),
- ejabberd_hooks:add(sm_remove_connection_hook, Host,
- ?MODULE, unregister_connection, 100),
- ok.
-
-%% Return true if anonymous is allowed for host or false otherwise
-allow_anonymous(Host) ->
- lists:member(?MODULE, ejabberd_auth:auth_modules(Host)).
-
-%% Return true if anonymous mode is enabled and if anonymous protocol is SASL
-%% anonymous protocol can be: sasl_anon|login_anon|both
-is_sasl_anonymous_enabled(Host) ->
- case allow_anonymous(Host) of
- false -> false;
- true ->
- case anonymous_protocol(Host) of
- sasl_anon -> true;
- both -> true;
- _Other -> false
- end
- end.
-
-%% Return true if anonymous login is enabled on the server
-%% anonymous login can be use using standard authentication method (i.e. with
-%% clients that do not support anonymous login)
-is_login_anonymous_enabled(Host) ->
- case allow_anonymous(Host) of
- false -> false;
- true ->
- case anonymous_protocol(Host) of
- login_anon -> true;
- both -> true;
- _Other -> false
- end
- end.
-
-%% Return the anonymous protocol to use: sasl_anon|login_anon|both
-%% defaults to login_anon
-anonymous_protocol(Host) ->
- case ejabberd_config:get_local_option({anonymous_protocol, Host}) of
- sasl_anon -> sasl_anon;
- login_anon -> login_anon;
- both -> both;
- _Other -> sasl_anon
- end.
-
-%% Return true if multiple connections have been allowed in the config file
-%% defaults to false
-allow_multiple_connections(Host) ->
- case ejabberd_config:get_local_option({allow_multiple_connections, Host}) of
- true -> true;
- _Other -> false
- end.
-
-%% Check if user exist in the anonymus database
-anonymous_user_exist(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- case catch mnesia:dirty_read({anonymous, US}) of
- [] ->
- false;
- [_H|_T] ->
- true
- end.
-
-%% Remove connection from Mnesia tables
-remove_connection(SID, LUser, LServer) ->
- US = {LUser, LServer},
- F = fun() ->
- mnesia:delete_object({anonymous, US, SID})
- end,
- mnesia:transaction(F).
-
-%% Register connection
-register_connection(SID, #jid{luser = LUser, lserver = LServer}) ->
- US = {LUser, LServer},
- mnesia:sync_dirty(
- fun() -> mnesia:write(#anonymous{us = US, sid=SID})
- end).
-
-%% Remove an anonymous user from the anonymous users table
-unregister_connection(SID, #jid{luser = LUser, lserver = LServer}) ->
- remove_connection(SID, LUser, LServer).
-
-%% ---------------------------------
-%% Specific anonymous auth functions
-%% ---------------------------------
-
-%% When anonymous login is enabled, check the password for permenant users
-%% before allowing access
-check_password(User, Server, Password) ->
- check_password(User, Server, Password, undefined, undefined).
-check_password(User, Server, _Password, _StreamID, _Digest) ->
- %% We refuse login for registered accounts (They cannot logged but
- %% they however are "reserved")
- case ejabberd_auth:is_user_exists_in_other_modules(?MODULE,
- User, Server) of
- true -> false;
- false -> login(User, Server)
- end.
-
-login(User, Server) ->
- case is_login_anonymous_enabled(Server) of
- false -> false;
- true ->
- case anonymous_user_exist(User, Server) of
- %% Reject the login if an anonymous user with the same login
- %% is already logged and if multiple login has not been enable
- %% in the config file.
- true -> allow_multiple_connections(Server);
- %% Accept login and add user to the anonymous table
- false -> true
- end
- end.
-
-%% When anonymous login is enabled, check that the user is permanent before
-%% changing its password
-set_password(User, Server, _Password) ->
- case anonymous_user_exist(User, Server) of
- true ->
- ok;
- false ->
- {error, not_allowed}
- end.
-
-%% When anonymous login is enabled, check if permanent users are allowed on
-%% the server:
-try_register(_User, _Server, _Password) ->
- {error, not_allowed}.
-
-dirty_get_registered_users() ->
- [].
-
-get_vh_registered_users(_Server) ->
- [].
-
-
-%% Return password of permanent user or false for anonymous users
-get_password(User, Server) ->
- get_password(User, Server, "").
-
-get_password(User, Server, DefaultValue) ->
- case anonymous_user_exist(User, Server) of
- %% We return the default value if the user is anonymous
- true ->
- DefaultValue;
- %% We return the permanent user password otherwise
- false ->
- false
- end.
-
-%% Returns true if the user exists in the DB or if an anonymous user is logged
-%% under the given name
-is_user_exists(User, Server) ->
- anonymous_user_exist(User, Server).
-
-remove_user(_User, _Server) ->
- {error, not_allowed}.
-
-remove_user(_User, _Server, _Password) ->
- not_allowed.
-
-plain_password_required() ->
- false.
-
diff --git a/ejabberd-1.1.2/src/ejabberd_auth_external.erl b/ejabberd-1.1.2/src/ejabberd_auth_external.erl
deleted file mode 100644
index 971edae98..000000000
--- a/ejabberd-1.1.2/src/ejabberd_auth_external.erl
+++ /dev/null
@@ -1,72 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_auth_external.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Authentification via LDAP external script
-%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_auth_external).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
-%% External exports
--export([start/1,
- set_password/3,
- check_password/3,
- check_password/5,
- try_register/3,
- dirty_get_registered_users/0,
- get_vh_registered_users/1,
- get_password/2,
- get_password_s/2,
- is_user_exists/2,
- remove_user/2,
- remove_user/3,
- plain_password_required/0
- ]).
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-start(Host) ->
- extauth:start(
- Host, ejabberd_config:get_local_option({extauth_program, Host})),
- ok.
-
-plain_password_required() ->
- true.
-
-check_password(User, Server, Password) ->
- extauth:check_password(User, Server, Password).
-
-check_password(User, Server, Password, _StreamID, _Digest) ->
- check_password(User, Server, Password).
-
-set_password(User, Server, Password) ->
- extauth:set_password(User, Server, Password).
-
-try_register(_User, _Server, _Password) ->
- {error, not_allowed}.
-
-dirty_get_registered_users() ->
- [].
-
-get_vh_registered_users(_Server) ->
- [].
-
-get_password(_User, _Server) ->
- false.
-
-get_password_s(_User, _Server) ->
- "".
-
-is_user_exists(User, Server) ->
- extauth:is_user_exists(User, Server).
-
-remove_user(_User, _Server) ->
- {error, not_allowed}.
-
-remove_user(_User, _Server, _Password) ->
- not_allowed.
-
diff --git a/ejabberd-1.1.2/src/ejabberd_auth_internal.erl b/ejabberd-1.1.2/src/ejabberd_auth_internal.erl
deleted file mode 100644
index 62e765421..000000000
--- a/ejabberd-1.1.2/src/ejabberd_auth_internal.erl
+++ /dev/null
@@ -1,243 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_auth_internal.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Authentification via mnesia
-%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_auth_internal).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
-%% External exports
--export([start/1,
- set_password/3,
- check_password/3,
- check_password/5,
- try_register/3,
- dirty_get_registered_users/0,
- get_vh_registered_users/1,
- get_password/2,
- get_password_s/2,
- is_user_exists/2,
- remove_user/2,
- remove_user/3,
- plain_password_required/0
- ]).
-
--include("ejabberd.hrl").
-
--record(passwd, {us, password}).
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-start(Host) ->
- mnesia:create_table(passwd, [{disc_copies, [node()]},
- {attributes, record_info(fields, passwd)}]),
- update_table(),
- ejabberd_ctl:register_commands(
- Host,
- [{"registered-users", "list all registered users"}],
- ejabberd_auth, ctl_process_get_registered),
- ok.
-
-plain_password_required() ->
- false.
-
-check_password(User, Server, Password) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- case catch mnesia:dirty_read({passwd, US}) of
- [#passwd{password = Password}] ->
- true;
- _ ->
- false
- end.
-
-check_password(User, Server, Password, StreamID, Digest) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- case catch mnesia:dirty_read({passwd, US}) of
- [#passwd{password = Passwd}] ->
- DigRes = if
- Digest /= "" ->
- Digest == sha:sha(StreamID ++ Passwd);
- true ->
- false
- end,
- if DigRes ->
- true;
- true ->
- (Passwd == Password) and (Password /= "")
- end;
- _ ->
- false
- end.
-
-set_password(User, Server, Password) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- if
- (LUser == error) or (LServer == error) ->
- {error, invalid_jid};
- true ->
- F = fun() ->
- mnesia:write(#passwd{us = US,
- password = Password})
- end,
- mnesia:transaction(F)
- end.
-
-
-try_register(User, Server, Password) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- if
- (LUser == error) or (LServer == error) ->
- {error, invalid_jid};
- true ->
- F = fun() ->
- case mnesia:read({passwd, US}) of
- [] ->
- mnesia:write(#passwd{us = US,
- password = Password}),
- ok;
- [_E] ->
- exists
- end
- end,
- mnesia:transaction(F)
- end.
-
-dirty_get_registered_users() ->
- mnesia:dirty_all_keys(passwd).
-
-get_vh_registered_users(Server) ->
- LServer = jlib:nameprep(Server),
- mnesia:dirty_select(
- passwd,
- [{#passwd{us = '$1', _ = '_'},
- [{'==', {element, 2, '$1'}, LServer}],
- ['$1']}]).
-
-get_password(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- case catch mnesia:dirty_read(passwd, US) of
- [#passwd{password = Password}] ->
- Password;
- _ ->
- false
- end.
-
-get_password_s(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- case catch mnesia:dirty_read(passwd, US) of
- [#passwd{password = Password}] ->
- Password;
- _ ->
- []
- end.
-
-is_user_exists(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- case catch mnesia:dirty_read({passwd, US}) of
- [] ->
- false;
- [_] ->
- true;
- _ ->
- false
- end.
-
-remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- F = fun() ->
- mnesia:delete({passwd, US})
- end,
- mnesia:transaction(F),
- ejabberd_hooks:run(remove_user, LServer, [User, Server]).
-
-remove_user(User, Server, Password) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- F = fun() ->
- case mnesia:read({passwd, US}) of
- [#passwd{password = Password}] ->
- mnesia:delete({passwd, US}),
- ok;
- [_] ->
- not_allowed;
- _ ->
- not_exists
- end
- end,
- case mnesia:transaction(F) of
- {atomic, ok} ->
- ejabberd_hooks:run(remove_user, LServer, [User, Server]),
- ok;
- {atomic, Res} ->
- Res;
- _ ->
- bad_request
- end.
-
-
-update_table() ->
- Fields = record_info(fields, passwd),
- case mnesia:table_info(passwd, attributes) of
- Fields ->
- ok;
- [user, password] ->
- ?INFO_MSG("Converting passwd table from "
- "{user, password} format", []),
- Host = ?MYNAME,
- {atomic, ok} = mnesia:create_table(
- ejabberd_auth_internal_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, passwd},
- {attributes, record_info(fields, passwd)}]),
- mnesia:transform_table(passwd, ignore, Fields),
- F1 = fun() ->
- mnesia:write_lock_table(ejabberd_auth_internal_tmp_table),
- mnesia:foldl(
- fun(#passwd{us = U} = R, _) ->
- mnesia:dirty_write(
- ejabberd_auth_internal_tmp_table,
- R#passwd{us = {U, Host}})
- end, ok, passwd)
- end,
- mnesia:transaction(F1),
- mnesia:clear_table(passwd),
- F2 = fun() ->
- mnesia:write_lock_table(passwd),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, ejabberd_auth_internal_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(ejabberd_auth_internal_tmp_table);
- _ ->
- ?INFO_MSG("Recreating passwd table", []),
- mnesia:transform_table(passwd, ignore, Fields)
- end.
-
-
-
diff --git a/ejabberd-1.1.2/src/ejabberd_auth_ldap.erl b/ejabberd-1.1.2/src/ejabberd_auth_ldap.erl
deleted file mode 100644
index d152d0895..000000000
--- a/ejabberd-1.1.2/src/ejabberd_auth_ldap.erl
+++ /dev/null
@@ -1,385 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_auth_ldap.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Authentification via LDAP
-%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_auth_ldap).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
-
-%% gen_server callbacks
--export([init/1,
- handle_info/2,
- handle_call/3,
- handle_cast/2,
- terminate/2,
- code_change/3
- ]).
-
-%% External exports
--export([start/1,
- stop/1,
- start_link/1,
- set_password/3,
- check_password/3,
- check_password/5,
- try_register/3,
- dirty_get_registered_users/0,
- get_vh_registered_users/1,
- get_password/2,
- get_password_s/2,
- is_user_exists/2,
- remove_user/2,
- remove_user/3,
- plain_password_required/0
- ]).
-
--include("ejabberd.hrl").
--include("eldap/eldap.hrl").
-
--record(state, {host,
- eldap_id,
- bind_eldap_id,
- servers,
- port,
- dn,
- password,
- base,
- uidattr,
- uidattr_format,
- ufilter,
- sfilter,
- dn_filter,
- dn_filter_attrs
- }).
-
-%% Unused callbacks.
-handle_cast(_Request, State) ->
- {noreply, State}.
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-handle_info(_Info, State) ->
- {noreply, State}.
-%% -----
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-
-start(Host) ->
- Proc = gen_mod:get_module_proc(Host, ?MODULE),
- ChildSpec = {
- Proc, {?MODULE, start_link, [Host]},
- permanent, 1000, worker, [?MODULE]
- },
- supervisor:start_child(ejabberd_sup, ChildSpec).
-
-stop(Host) ->
- Proc = gen_mod:get_module_proc(Host, ?MODULE),
- gen_server:call(Proc, stop),
- supervisor:terminate_child(ejabberd_sup, Proc),
- supervisor:delete_child(ejabberd_sup, Proc).
-
-start_link(Host) ->
- Proc = gen_mod:get_module_proc(Host, ?MODULE),
- gen_server:start_link({local, Proc}, ?MODULE, Host, []).
-
-terminate(_Reason, State) ->
- ejabberd_ctl:unregister_commands(
- State#state.host,
- [{"registered-users", "list all registered users"}],
- ejabberd_auth, ctl_process_get_registered).
-
-init(Host) ->
- State = parse_options(Host),
- eldap:start_link(State#state.eldap_id,
- State#state.servers,
- State#state.port,
- State#state.dn,
- State#state.password),
- eldap:start_link(State#state.bind_eldap_id,
- State#state.servers,
- State#state.port,
- State#state.dn,
- State#state.password),
- ejabberd_ctl:register_commands(
- Host,
- [{"registered-users", "list all registered users"}],
- ejabberd_auth, ctl_process_get_registered),
- {ok, State}.
-
--define(REPLY_TIMEOUT, 10000).
-
-plain_password_required() ->
- true.
-
-check_password(User, Server, Password) ->
- Proc = gen_mod:get_module_proc(Server, ?MODULE),
- case catch gen_server:call(Proc,
- {check_pass, User, Password}, ?REPLY_TIMEOUT) of
- {'EXIT', _} ->
- false;
- Result ->
- Result
- end.
-
-check_password(User, Server, Password, _StreamID, _Digest) ->
- check_password(User, Server, Password).
-
-set_password(_User, _Server, _Password) ->
- {error, not_allowed}.
-
-try_register(_User, _Server, _Password) ->
- {error, not_allowed}.
-
-dirty_get_registered_users() ->
- get_vh_registered_users(?MYNAME).
-
-get_vh_registered_users(Server) ->
- Proc = gen_mod:get_module_proc(Server, ?MODULE),
- case catch gen_server:call(Proc,
- get_vh_registered_users, ?REPLY_TIMEOUT) of
- {'EXIT', _} ->
- [];
- Result ->
- Result
- end.
-
-get_password(_User, _Server) ->
- false.
-
-get_password_s(_User, _Server) ->
- "".
-
-is_user_exists(User, Server) ->
- Proc = gen_mod:get_module_proc(Server, ?MODULE),
- case catch gen_server:call(Proc,
- {is_user_exists, User}, ?REPLY_TIMEOUT) of
- {'EXIT', _} ->
- false;
- Result ->
- Result
- end.
-
-remove_user(_User, _Server) ->
- {error, not_allowed}.
-
-remove_user(_User, _Server, _Password) ->
- not_allowed.
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-handle_call({check_pass, User, Password}, _From, State) ->
- Reply = case find_user_dn(User, State) of
- false ->
- false;
- DN ->
- case eldap:bind(State#state.bind_eldap_id, DN, Password) of
- ok -> true;
- _ -> false
- end
- end,
- {reply, Reply, State};
-
-handle_call(get_vh_registered_users, _From, State) ->
- UA = State#state.uidattr,
- UAF = State#state.uidattr_format,
- Eldap_ID = State#state.eldap_id,
- Server = State#state.host,
- SortedDNAttrs = usort_attrs(State#state.dn_filter_attrs),
- Reply = case eldap_filter:parse(State#state.sfilter) of
- {ok, EldapFilter} ->
- case eldap:search(Eldap_ID, [{base, State#state.base},
- {filter, EldapFilter},
- {attributes, SortedDNAttrs}]) of
- #eldap_search_result{entries = Entries} ->
- lists:flatmap(
- fun(#eldap_entry{attributes = Attrs,
- object_name = DN}) ->
- case is_valid_dn(DN, Attrs, State) of
- false -> [];
- _ ->
- case get_ldap_attr(UA, Attrs) of
- "" -> [];
- User ->
- case get_user_part(User, UAF) of
- {ok, U} ->
- case jlib:nodeprep(U) of
- error -> [];
- LU -> [{LU, jlib:nameprep(Server)}]
- end;
- _ -> []
- end
- end
- end
- end, Entries);
- _ ->
- []
- end;
- _ ->
- []
- end,
- {reply, Reply, State};
-
-handle_call({is_user_exists, User}, _From, State) ->
- Reply = case find_user_dn(User, State) of
- false -> false;
- _DN -> true
- end,
- {reply, Reply, State};
-
-handle_call(stop, _From, State) ->
- {stop, normal, ok, State};
-
-handle_call(_Request, _From, State) ->
- {reply, bad_request, State}.
-
-find_user_dn(User, State) ->
- DNAttrs = usort_attrs(State#state.dn_filter_attrs),
- case eldap_filter:parse(State#state.ufilter, [{"%u", User}]) of
- {ok, Filter} ->
- case eldap:search(State#state.eldap_id, [{base, State#state.base},
- {filter, Filter},
- {attributes, DNAttrs}]) of
- #eldap_search_result{entries = [#eldap_entry{attributes = Attrs,
- object_name = DN} | _]} ->
- is_valid_dn(DN, Attrs, State);
- _ ->
- false
- end;
- _ ->
- false
- end.
-
-is_valid_dn(DN, _, #state{dn_filter = undefined}) ->
- DN;
-
-is_valid_dn(DN, Attrs, State) ->
- DNAttrs = State#state.dn_filter_attrs,
- UA = State#state.uidattr,
- UAF = State#state.uidattr_format,
- Values = [{"%s", get_ldap_attr(Attr, Attrs), 1} || Attr <- DNAttrs],
- SubstValues = case get_ldap_attr(UA, Attrs) of
- "" -> Values;
- S ->
- case get_user_part(S, UAF) of
- {ok, U} -> [{"%u", U} | Values];
- _ -> Values
- end
- end ++ [{"%d", State#state.host}, {"%D", DN}],
- case eldap_filter:parse(State#state.dn_filter, SubstValues) of
- {ok, EldapFilter} ->
- case eldap:search(State#state.eldap_id, [
- {base, State#state.base},
- {filter, EldapFilter},
- {attributes, ["dn"]}]) of
- #eldap_search_result{entries = [_|_]} ->
- DN;
- _ ->
- false
- end;
- _ ->
- false
- end.
-
-%%%----------------------------------------------------------------------
-%%% Auxiliary functions
-%%%----------------------------------------------------------------------
-get_user_part(String, Pattern) ->
- F = fun(S, P) ->
- First = string:str(P, "%u"),
- TailLength = length(P) - (First+1),
- string:sub_string(S, First, length(S) - TailLength)
- end,
- case catch F(String, Pattern) of
- {'EXIT', _} ->
- {error, badmatch};
- Result ->
- case regexp:sub(Pattern, "%u", Result) of
- {ok, String, _} -> {ok, Result};
- _ -> {error, badmatch}
- end
- end.
-
-case_insensitive_match(X, Y) ->
- X1 = stringprep:tolower(X),
- Y1 = stringprep:tolower(Y),
- if
- X1 == Y1 -> true;
- true -> false
- end.
-
-get_ldap_attr(LDAPAttr, Attributes) ->
- Res = lists:filter(
- fun({Name, _}) ->
- case_insensitive_match(Name, LDAPAttr)
- end, Attributes),
- case Res of
- [{_, [Value|_]}] -> Value;
- _ -> ""
- end.
-
-usort_attrs(Attrs) when is_list(Attrs) ->
- lists:usort(Attrs);
-
-usort_attrs(_) ->
- [].
-
-parse_options(Host) ->
- Eldap_ID = atom_to_list(gen_mod:get_module_proc(Host, ?MODULE)),
- Bind_Eldap_ID = atom_to_list(gen_mod:get_module_proc(Host, bind_ejabberd_auth_ldap)),
- LDAPServers = ejabberd_config:get_local_option({ldap_servers, Host}),
- LDAPPort = case ejabberd_config:get_local_option({ldap_port, Host}) of
- undefined -> 389;
- P -> P
- end,
- RootDN = case ejabberd_config:get_local_option({ldap_rootdn, Host}) of
- undefined -> "";
- RDN -> RDN
- end,
- Password = case ejabberd_config:get_local_option({ldap_password, Host}) of
- undefined -> "";
- Pass -> Pass
- end,
- UIDAttr = case ejabberd_config:get_local_option({ldap_uidattr, Host}) of
- undefined -> "uid";
- UA -> UA
- end,
- UIDAttrFormat = case ejabberd_config:get_local_option({ldap_uidattr_format, Host}) of
- undefined -> "%u";
- UAF -> UAF
- end,
- SubFilter = "(" ++ UIDAttr ++ "=" ++ UIDAttrFormat ++ ")",
- UserFilter = case ejabberd_config:get_local_option({ldap_filter, Host}) of
- undefined -> SubFilter;
- "" -> SubFilter;
- F -> "(&" ++ SubFilter ++ F ++ ")"
- end,
- SearchFilter = eldap_filter:do_sub(UserFilter, [{"%u", "*"}]),
- LDAPBase = ejabberd_config:get_local_option({ldap_base, Host}),
- {DNFilter, DNFilterAttrs} =
- case ejabberd_config:get_local_option({ldap_dn_filter, Host}) of
- undefined -> {undefined, undefined};
- {DNF, DNFA} -> {DNF, DNFA}
- end,
- #state{host = Host,
- eldap_id = Eldap_ID,
- bind_eldap_id = Bind_Eldap_ID,
- servers = LDAPServers,
- port = LDAPPort,
- dn = RootDN,
- password = Password,
- base = LDAPBase,
- uidattr = UIDAttr,
- uidattr_format = UIDAttrFormat,
- ufilter = UserFilter,
- sfilter = SearchFilter,
- dn_filter = DNFilter,
- dn_filter_attrs = DNFilterAttrs
- }.
diff --git a/ejabberd-1.1.2/src/ejabberd_auth_odbc.erl b/ejabberd-1.1.2/src/ejabberd_auth_odbc.erl
deleted file mode 100644
index d946bfd48..000000000
--- a/ejabberd-1.1.2/src/ejabberd_auth_odbc.erl
+++ /dev/null
@@ -1,215 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_auth_odbc.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Authentification via ODBC
-%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_auth_odbc).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
-%% External exports
--export([start/1,
- set_password/3,
- check_password/3,
- check_password/5,
- try_register/3,
- dirty_get_registered_users/0,
- get_vh_registered_users/1,
- get_password/2,
- get_password_s/2,
- is_user_exists/2,
- remove_user/2,
- remove_user/3,
- plain_password_required/0
- ]).
-
--include("ejabberd.hrl").
-
--record(passwd, {user, password}).
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-start(Host) ->
- ChildSpec =
- {gen_mod:get_module_proc(Host, ejabberd_odbc_sup),
- {ejabberd_odbc_sup, start_link, [Host]},
- temporary,
- infinity,
- supervisor,
- [ejabberd_odbc_sup]},
- supervisor:start_child(ejabberd_sup, ChildSpec),
- ejabberd_ctl:register_commands(
- Host,
- [{"registered-users", "list all registered users"}],
- ejabberd_auth, ctl_process_get_registered),
- ok.
-
-plain_password_required() ->
- false.
-
-check_password(User, Server, Password) ->
- case jlib:nodeprep(User) of
- error ->
- false;
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- LServer = jlib:nameprep(Server),
- case catch odbc_queries:get_password(LServer, Username) of
- {selected, ["password"], [{Password}]} ->
- true;
- _ ->
- false
- end
- end.
-
-check_password(User, Server, Password, StreamID, Digest) ->
- case jlib:nodeprep(User) of
- error ->
- false;
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- LServer = jlib:nameprep(Server),
- case catch odbc_queries:get_password(LServer, Username) of
- {selected, ["password"], [{Passwd}]} ->
- DigRes = if
- Digest /= "" ->
- Digest == sha:sha(StreamID ++ Passwd);
- true ->
- false
- end,
- if DigRes ->
- true;
- true ->
- (Passwd == Password) and (Password /= "")
- end;
- _ ->
- false
- end
- end.
-
-set_password(User, Server, Password) ->
- case jlib:nodeprep(User) of
- error ->
- {error, invalid_jid};
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- Pass = ejabberd_odbc:escape(Password),
- LServer = jlib:nameprep(Server),
- catch odbc_queries:set_password_t(LServer, Username, Pass)
- end.
-
-
-try_register(User, Server, Password) ->
- case jlib:nodeprep(User) of
- error ->
- {error, invalid_jid};
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- Pass = ejabberd_odbc:escape(Password),
- LServer = jlib:nameprep(Server),
- case catch odbc_queries:add_user(LServer, Username, Pass) of
- {updated, 1} ->
- {atomic, ok};
- _ ->
- {atomic, exists}
- end
- end.
-
-dirty_get_registered_users() ->
- get_vh_registered_users(?MYNAME).
-
-get_vh_registered_users(Server) ->
- LServer = jlib:nameprep(Server),
- case catch odbc_queries:list_users(LServer) of
- {selected, ["username"], Res} ->
- [{U, LServer} || {U} <- Res];
- _ ->
- []
- end.
-
-get_password(User, Server) ->
- case jlib:nodeprep(User) of
- error ->
- false;
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- LServer = jlib:nameprep(Server),
- case catch odbc_queries:get_password(LServer, Username) of
- {selected, ["password"], [{Password}]} ->
- Password;
- _ ->
- false
- end
- end.
-
-get_password_s(User, Server) ->
- case jlib:nodeprep(User) of
- error ->
- "";
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- LServer = jlib:nameprep(Server),
- case catch odbc_queries:get_password(LServer, Username) of
- {selected, ["password"], [{Password}]} ->
- Password;
- _ ->
- ""
- end
- end.
-
-is_user_exists(User, Server) ->
- case jlib:nodeprep(User) of
- error ->
- false;
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- LServer = jlib:nameprep(Server),
- case catch odbc_queries:get_password(LServer, Username) of
- {selected, ["password"], [{_Password}]} ->
- true;
- _ ->
- false
- end
- end.
-
-remove_user(User, Server) ->
- case jlib:nodeprep(User) of
- error ->
- error;
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- LServer = jlib:nameprep(Server),
- catch odbc_queries:del_user(LServer, Username),
- ejabberd_hooks:run(remove_user, jlib:nameprep(Server),
- [User, Server])
- end.
-
-remove_user(User, Server, Password) ->
- case jlib:nodeprep(User) of
- error ->
- error;
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- Pass = ejabberd_odbc:escape(Password),
- LServer = jlib:nameprep(Server),
- F = fun() ->
- Result = odbc_queries:del_user_return_password(
- LServer, Username, Pass),
- case Result of
- {selected, ["password"], [{Password}]} ->
- ejabberd_hooks:run(remove_user, jlib:nameprep(Server),
- [User, Server]),
- ok;
- {selected, ["password"], []} ->
- not_exists;
- _ ->
- not_allowed
- end
- end,
- {atomic, Result} = odbc_queries:transaction(LServer, F),
- Result
- end.
diff --git a/ejabberd-1.1.2/src/ejabberd_c2s.erl b/ejabberd-1.1.2/src/ejabberd_c2s.erl
deleted file mode 100644
index 84c855c30..000000000
--- a/ejabberd-1.1.2/src/ejabberd_c2s.erl
+++ /dev/null
@@ -1,1785 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_c2s.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Serve C2S connection
-%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_c2s).
--author('alexey@sevcom.net').
--update_info({update, 0}).
-
--behaviour(gen_fsm).
-
-%% External exports
--export([start/2,
- start_link/2,
- send_text/2,
- send_element/2,
- become_controller/1,
- get_presence/1]).
-
-%% gen_fsm callbacks
--export([init/1,
- wait_for_stream/2,
- wait_for_auth/2,
- wait_for_feature_request/2,
- wait_for_bind/2,
- wait_for_session/2,
- wait_for_sasl_response/2,
- session_established/2,
- handle_event/3,
- handle_sync_event/4,
- code_change/4,
- handle_info/3,
- terminate/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--define(SETS, gb_sets).
-
--record(state, {socket, receiver,
- sockmod,
- streamid,
- sasl_state,
- access,
- shaper,
- zlib = false,
- tls = false,
- tls_required = false,
- tls_enabled = false,
- tls_options = [],
- authenticated = false,
- jid,
- user = "", server = ?MYNAME, resource = "",
- sid,
- pres_t = ?SETS:new(),
- pres_f = ?SETS:new(),
- pres_a = ?SETS:new(),
- pres_i = ?SETS:new(),
- pres_last, pres_pri,
- pres_timestamp,
- pres_invis = false,
- privacy_list = none,
- lang}).
-
-%-define(DBGFSM, true).
-
--ifdef(DBGFSM).
--define(FSMOPTS, [{debug, [trace]}]).
--else.
--define(FSMOPTS, []).
--endif.
-
--define(STREAM_HEADER,
- "<?xml version='1.0'?>"
- "<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "id='~s' from='~s'~s~s>"
- ).
-
--define(STREAM_TRAILER, "</stream:stream>").
-
--define(INVALID_NS_ERR,
- xml:element_to_string(?SERR_INVALID_NAMESPACE)).
--define(INVALID_XML_ERR,
- xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
--define(HOST_UNKNOWN_ERR,
- xml:element_to_string(?SERR_HOST_UNKNOWN)).
--define(POLICY_VIOLATION_ERR(Lang, Text),
- xml:element_to_string(?SERRT_POLICY_VIOLATION(Lang, Text))).
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-start(SockData, Opts) ->
- supervisor:start_child(ejabberd_c2s_sup, [SockData, Opts]).
-
-start_link(SockData, Opts) ->
- gen_fsm:start_link(ejabberd_c2s, [SockData, Opts], ?FSMOPTS).
-
-become_controller(Pid) ->
- gen_fsm:send_all_state_event(Pid, become_controller).
-
-%% Return Username, Resource and presence information
-get_presence(FsmRef) ->
- gen_fsm:sync_send_all_state_event(FsmRef, {get_presence}, 1000).
-
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_fsm
-%%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, StateName, StateData} |
-%% {ok, StateName, StateData, Timeout} |
-%% ignore |
-%% {stop, StopReason}
-%%----------------------------------------------------------------------
-init([{SockMod, Socket}, Opts]) ->
- Access = case lists:keysearch(access, 1, Opts) of
- {value, {_, A}} -> A;
- _ -> all
- end,
- Shaper = case lists:keysearch(shaper, 1, Opts) of
- {value, {_, S}} -> S;
- _ -> none
- end,
- MaxStanzaSize =
- case lists:keysearch(max_stanza_size, 1, Opts) of
- {value, {_, Size}} -> Size;
- _ -> infinity
- end,
- Zlib = lists:member(zlib, Opts),
- StartTLS = lists:member(starttls, Opts),
- StartTLSRequired = lists:member(starttls_required, Opts),
- TLSEnabled = lists:member(tls, Opts),
- TLS = StartTLS orelse StartTLSRequired orelse TLSEnabled,
- TLSOpts = lists:filter(fun({certfile, _}) -> true;
- (_) -> false
- end, Opts),
- {SockMod1, Socket1, ReceiverPid} =
- if
- TLSEnabled ->
- {ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
- RecPid = ejabberd_receiver:start(
- TLSSocket, tls, none, MaxStanzaSize),
- {tls, TLSSocket, RecPid};
- true ->
- RecPid = ejabberd_receiver:start(
- Socket, SockMod, none, MaxStanzaSize),
- {SockMod, Socket, RecPid}
- end,
- {ok, wait_for_stream, #state{socket = Socket1,
- sockmod = SockMod1,
- receiver = ReceiverPid,
- zlib = Zlib,
- tls = TLS,
- tls_required = StartTLSRequired,
- tls_enabled = TLSEnabled,
- tls_options = TLSOpts,
- streamid = new_id(),
- access = Access,
- shaper = Shaper}}.
-
-
-%%----------------------------------------------------------------------
-%% Func: StateName/2
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-
-wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
- DefaultLang = case ?MYLANG of
- undefined ->
- " xml:lang='en'";
- DL ->
- " xml:lang='" ++ DL ++ "'"
- end,
- case xml:get_attr_s("xmlns:stream", Attrs) of
- ?NS_STREAM ->
- Server = jlib:nameprep(xml:get_attr_s("to", Attrs)),
- case lists:member(Server, ?MYHOSTS) of
- true ->
- Lang = xml:get_attr_s("xml:lang", Attrs),
- case xml:get_attr_s("version", Attrs) of
- "1.0" ->
- Header = io_lib:format(?STREAM_HEADER,
- [StateData#state.streamid,
- Server,
- " version='1.0'",
- DefaultLang]),
- send_text(StateData, Header),
- case StateData#state.authenticated of
- false ->
- SASLState =
- cyrsasl:server_new(
- "jabber", Server, "", [],
- fun(U) ->
- ejabberd_auth:get_password(
- U, Server)
- end,
- fun(U, P) ->
- ejabberd_auth:check_password(
- U, Server, P)
- end),
- Mechs = lists:map(
- fun(S) ->
- {xmlelement, "mechanism", [],
- [{xmlcdata, S}]}
- end, cyrsasl:listmech(Server)),
- SockMod = StateData#state.sockmod,
- Zlib = StateData#state.zlib,
- CompressFeature =
- case Zlib andalso
- (SockMod == gen_tcp) of
- true ->
- [{xmlelement, "compression",
- [{"xmlns", ?NS_FEATURE_COMPRESS}],
- [{xmlelement, "method",
- [], [{xmlcdata, "zlib"}]}]}];
- _ ->
- []
- end,
- TLS = StateData#state.tls,
- TLSEnabled = StateData#state.tls_enabled,
- TLSRequired = StateData#state.tls_required,
- TLSFeature =
- case (TLS == true) andalso
- (TLSEnabled == false) andalso
- (SockMod == gen_tcp) of
- true ->
- case TLSRequired of
- true ->
- [{xmlelement, "starttls",
- [{"xmlns", ?NS_TLS}],
- [{xmlelement, "required",
- [], []}]}];
- _ ->
- [{xmlelement, "starttls",
- [{"xmlns", ?NS_TLS}], []}]
- end;
- false ->
- []
- end,
- send_element(StateData,
- {xmlelement, "stream:features", [],
- TLSFeature ++ CompressFeature ++
- [{xmlelement, "mechanisms",
- [{"xmlns", ?NS_SASL}],
- Mechs}] ++
- ejabberd_hooks:run_fold(
- c2s_stream_features,
- Server,
- [], [])}),
- {next_state, wait_for_feature_request,
- StateData#state{server = Server,
- sasl_state = SASLState,
- lang = Lang}};
- _ ->
- case StateData#state.resource of
- "" ->
- send_element(
- StateData,
- {xmlelement, "stream:features", [],
- [{xmlelement, "bind",
- [{"xmlns", ?NS_BIND}], []},
- {xmlelement, "session",
- [{"xmlns", ?NS_SESSION}], []}]}),
- {next_state, wait_for_bind,
- StateData#state{server = Server,
- lang = Lang}};
- _ ->
- send_element(
- StateData,
- {xmlelement, "stream:features", [], []}),
- {next_state, wait_for_session,
- StateData#state{server = Server,
- lang = Lang}}
- end
- end;
- _ ->
- Header = io_lib:format(
- ?STREAM_HEADER,
- [StateData#state.streamid, Server, "",
- DefaultLang]),
- if
- (not StateData#state.tls_enabled) and
- StateData#state.tls_required ->
- send_text(StateData,
- Header ++
- ?POLICY_VIOLATION_ERR(
- Lang,
- "Use of STARTTLS required") ++
- ?STREAM_TRAILER),
- {stop, normal, StateData};
- true ->
- send_text(StateData, Header),
- {next_state, wait_for_auth,
- StateData#state{server = Server,
- lang = Lang}}
- end
- end;
- _ ->
- Header = io_lib:format(
- ?STREAM_HEADER,
- [StateData#state.streamid, ?MYNAME, "",
- DefaultLang]),
- send_text(StateData,
- Header ++ ?HOST_UNKNOWN_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData}
- end;
- _ ->
- Header = io_lib:format(
- ?STREAM_HEADER,
- [StateData#state.streamid, ?MYNAME, "", DefaultLang]),
- send_text(StateData,
- Header ++ ?INVALID_NS_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData}
- end;
-
-wait_for_stream({xmlstreamerror, _}, StateData) ->
- Header = io_lib:format(?STREAM_HEADER,
- ["none", ?MYNAME, " version='1.0'", ""]),
- send_text(StateData,
- Header ++ ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_stream(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-wait_for_auth({xmlstreamelement, El}, StateData) ->
- case is_auth_packet(El) of
- {auth, _ID, get, {U, _, _, _}} ->
- {xmlelement, Name, Attrs, _Els} = jlib:make_result_iq_reply(El),
- case U of
- "" ->
- UCdata = [];
- _ ->
- UCdata = [{xmlcdata, U}]
- end,
- Res = case ejabberd_auth:plain_password_required(
- StateData#state.server) of
- false ->
- {xmlelement, Name, Attrs,
- [{xmlelement, "query", [{"xmlns", ?NS_AUTH}],
- [{xmlelement, "username", [], UCdata},
- {xmlelement, "password", [], []},
- {xmlelement, "digest", [], []},
- {xmlelement, "resource", [], []}
- ]}]};
- true ->
- {xmlelement, Name, Attrs,
- [{xmlelement, "query", [{"xmlns", ?NS_AUTH}],
- [{xmlelement, "username", [], UCdata},
- {xmlelement, "password", [], []},
- {xmlelement, "resource", [], []}
- ]}]}
- end,
- send_element(StateData, Res),
- {next_state, wait_for_auth, StateData};
- {auth, _ID, set, {_U, _P, _D, ""}} ->
- Err = jlib:make_error_reply(
- El,
- ?ERR_AUTH_NO_RESOURCE_PROVIDED(StateData#state.lang)),
- send_element(StateData, Err),
- {next_state, wait_for_auth, StateData};
- {auth, _ID, set, {U, P, D, R}} ->
- JID = jlib:make_jid(U, StateData#state.server, R),
- case (JID /= error) andalso
- (acl:match_rule(StateData#state.server,
- StateData#state.access, JID) == allow) of
- true ->
- case ejabberd_auth:check_password(
- U, StateData#state.server, P,
- StateData#state.streamid, D) of
- true ->
- ?INFO_MSG(
- "(~w) Accepted legacy authentication for ~s",
- [StateData#state.socket,
- jlib:jid_to_string(JID)]),
- SID = {now(), self()},
- ejabberd_sm:open_session(
- SID, U, StateData#state.server, R),
- Res1 = jlib:make_result_iq_reply(El),
- Res = setelement(4, Res1, []),
- send_element(StateData, Res),
- change_shaper(StateData, JID),
- {Fs, Ts} = ejabberd_hooks:run_fold(
- roster_get_subscription_lists,
- StateData#state.server,
- {[], []},
- [U, StateData#state.server]),
- LJID = jlib:jid_tolower(
- jlib:jid_remove_resource(JID)),
- Fs1 = [LJID | Fs],
- Ts1 = [LJID | Ts],
- PrivList =
- case catch mod_privacy:get_user_list(
- U, StateData#state.server) of
- {'EXIT', _} -> none;
- PL -> PL
- end,
- {next_state, session_established,
- StateData#state{user = U,
- resource = R,
- jid = JID,
- sid = SID,
- pres_f = ?SETS:from_list(Fs1),
- pres_t = ?SETS:from_list(Ts1),
- privacy_list = PrivList}};
- _ ->
- ?INFO_MSG(
- "(~w) Failed legacy authentication for ~s",
- [StateData#state.socket,
- jlib:jid_to_string(JID)]),
- Err = jlib:make_error_reply(
- El, ?ERR_NOT_AUTHORIZED),
- send_element(StateData, Err),
- {next_state, wait_for_auth, StateData}
- end;
- _ ->
- if
- JID == error ->
- ?INFO_MSG(
- "(~w) Forbidden legacy authentication for "
- "username '~s' with resource '~s'",
- [StateData#state.socket, U, R]),
- Err = jlib:make_error_reply(El, ?ERR_JID_MALFORMED),
- send_element(StateData, Err),
- {next_state, wait_for_auth, StateData};
- true ->
- ?INFO_MSG(
- "(~w) Forbidden legacy authentication for ~s",
- [StateData#state.socket,
- jlib:jid_to_string(JID)]),
- Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
- send_element(StateData, Err),
- {next_state, wait_for_auth, StateData}
- end
- end;
- _ ->
- process_unauthenticated_stanza(StateData, El),
- {next_state, wait_for_auth, StateData}
- end;
-
-wait_for_auth({xmlstreamend, _Name}, StateData) ->
- send_text(StateData, ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_auth({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_auth(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-wait_for_feature_request({xmlstreamelement, El}, StateData) ->
- {xmlelement, Name, Attrs, Els} = El,
- Zlib = StateData#state.zlib,
- TLS = StateData#state.tls,
- TLSEnabled = StateData#state.tls_enabled,
- TLSRequired = StateData#state.tls_required,
- SockMod = StateData#state.sockmod,
- case {xml:get_attr_s("xmlns", Attrs), Name} of
- {?NS_SASL, "auth"} when not ((SockMod == gen_tcp) and TLSRequired) ->
- Mech = xml:get_attr_s("mechanism", Attrs),
- ClientIn = jlib:decode_base64(xml:get_cdata(Els)),
- case cyrsasl:server_start(StateData#state.sasl_state,
- Mech,
- ClientIn) of
- {ok, Props} ->
- ejabberd_receiver:reset_stream(StateData#state.receiver),
- send_element(StateData,
- {xmlelement, "success",
- [{"xmlns", ?NS_SASL}], []}),
- U = xml:get_attr_s(username, Props),
- ?INFO_MSG("(~w) Accepted authentication for ~s",
- [StateData#state.socket, U]),
- {next_state, wait_for_stream,
- StateData#state{streamid = new_id(),
- authenticated = true,
- user = U
- }};
- {continue, ServerOut, NewSASLState} ->
- send_element(StateData,
- {xmlelement, "challenge",
- [{"xmlns", ?NS_SASL}],
- [{xmlcdata,
- jlib:encode_base64(ServerOut)}]}),
- {next_state, wait_for_sasl_response,
- StateData#state{sasl_state = NewSASLState}};
- {error, Error} ->
- send_element(StateData,
- {xmlelement, "failure",
- [{"xmlns", ?NS_SASL}],
- [{xmlelement, Error, [], []}]}),
- {next_state, wait_for_feature_request, StateData}
- end;
- {?NS_TLS, "starttls"} when TLS == true,
- TLSEnabled == false,
- SockMod == gen_tcp ->
- Socket = StateData#state.socket,
- TLSOpts = case ejabberd_config:get_local_option(
- {domain_certfile, StateData#state.server}) of
- undefined ->
- StateData#state.tls_options;
- CertFile ->
- [{certfile, CertFile} |
- lists:keydelete(
- certfile, 1, StateData#state.tls_options)]
- end,
- {ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
- ejabberd_receiver:starttls(StateData#state.receiver, TLSSocket),
- send_element(StateData,
- {xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []}),
- {next_state, wait_for_stream,
- StateData#state{sockmod = tls,
- socket = TLSSocket,
- streamid = new_id(),
- tls_enabled = true
- }};
- {?NS_COMPRESS, "compress"} when Zlib == true,
- SockMod == gen_tcp ->
- case xml:get_subtag(El, "method") of
- false ->
- send_element(StateData,
- {xmlelement, "failure",
- [{"xmlns", ?NS_COMPRESS}],
- [{xmlelement, "setup-failed", [], []}]}),
- {next_state, wait_for_feature_request, StateData};
- Method ->
- case xml:get_tag_cdata(Method) of
- "zlib" ->
- Socket = StateData#state.socket,
- {ok, ZlibSocket} = ejabberd_zlib:enable_zlib(SockMod,
- Socket),
- ejabberd_receiver:compress(StateData#state.receiver,
- ZlibSocket),
- send_element(StateData,
- {xmlelement, "compressed",
- [{"xmlns", ?NS_COMPRESS}], []}),
- {next_state, wait_for_stream,
- StateData#state{sockmod = ejabberd_zlib,
- socket = ZlibSocket,
- streamid = new_id()
- }};
- _ ->
- send_element(StateData,
- {xmlelement, "failure",
- [{"xmlns", ?NS_COMPRESS}],
- [{xmlelement, "unsupported-method",
- [], []}]}),
- {next_state, wait_for_feature_request, StateData}
- end
- end;
- _ ->
- if
- (SockMod == gen_tcp) and TLSRequired ->
- Lang = StateData#state.lang,
- send_text(StateData, ?POLICY_VIOLATION_ERR(
- Lang,
- "Use of STARTTLS required") ++
- ?STREAM_TRAILER),
- {stop, normal, StateData};
- true ->
- process_unauthenticated_stanza(StateData, El),
- {next_state, wait_for_feature_request, StateData}
- end
- end;
-
-wait_for_feature_request({xmlstreamend, _Name}, StateData) ->
- send_text(StateData, ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_feature_request({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_feature_request(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
- {xmlelement, Name, Attrs, Els} = El,
- case {xml:get_attr_s("xmlns", Attrs), Name} of
- {?NS_SASL, "response"} ->
- ClientIn = jlib:decode_base64(xml:get_cdata(Els)),
- case cyrsasl:server_step(StateData#state.sasl_state,
- ClientIn) of
- {ok, Props} ->
- ejabberd_receiver:reset_stream(StateData#state.receiver),
- send_element(StateData,
- {xmlelement, "success",
- [{"xmlns", ?NS_SASL}], []}),
- U = xml:get_attr_s(username, Props),
- ?INFO_MSG("(~w) Accepted authentication for ~s",
- [StateData#state.socket, U]),
- {next_state, wait_for_stream,
- StateData#state{streamid = new_id(),
- authenticated = true,
- user = U
- }};
- {continue, ServerOut, NewSASLState} ->
- send_element(StateData,
- {xmlelement, "challenge",
- [{"xmlns", ?NS_SASL}],
- [{xmlcdata,
- jlib:encode_base64(ServerOut)}]}),
- {next_state, wait_for_sasl_response,
- StateData#state{sasl_state = NewSASLState}};
- {error, Error} ->
- send_element(StateData,
- {xmlelement, "failure",
- [{"xmlns", ?NS_SASL}],
- [{xmlelement, Error, [], []}]}),
- {next_state, wait_for_feature_request, StateData}
- end;
- _ ->
- process_unauthenticated_stanza(StateData, El),
- {next_state, wait_for_feature_request, StateData}
- end;
-
-wait_for_sasl_response({xmlstreamend, _Name}, StateData) ->
- send_text(StateData, ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_sasl_response({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_sasl_response(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-
-wait_for_bind({xmlstreamelement, El}, StateData) ->
- case jlib:iq_query_info(El) of
- #iq{type = set, xmlns = ?NS_BIND, sub_el = SubEl} = IQ ->
- U = StateData#state.user,
- R1 = xml:get_path_s(SubEl, [{elem, "resource"}, cdata]),
- R = case jlib:resourceprep(R1) of
- error -> error;
- "" ->
- lists:concat(
- [randoms:get_string() | tuple_to_list(now())]);
- Resource -> Resource
- end,
- case R of
- error ->
- Err = jlib:make_error_reply(El, ?ERR_BAD_REQUEST),
- send_element(StateData, Err),
- {next_state, wait_for_bind, StateData};
- _ ->
- JID = jlib:make_jid(U, StateData#state.server, R),
- Res = IQ#iq{type = result,
- sub_el = [{xmlelement, "bind",
- [{"xmlns", ?NS_BIND}],
- [{xmlelement, "jid", [],
- [{xmlcdata,
- jlib:jid_to_string(JID)}]}]}]},
- send_element(StateData, jlib:iq_to_xml(Res)),
- {next_state, wait_for_session,
- StateData#state{resource = R, jid = JID}}
- end;
- _ ->
- {next_state, wait_for_bind, StateData}
- end;
-
-wait_for_bind({xmlstreamend, _Name}, StateData) ->
- send_text(StateData, ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_bind({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_bind(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-
-wait_for_session({xmlstreamelement, El}, StateData) ->
- case jlib:iq_query_info(El) of
- #iq{type = set, xmlns = ?NS_SESSION} ->
- U = StateData#state.user,
- R = StateData#state.resource,
- JID = StateData#state.jid,
- case acl:match_rule(StateData#state.server,
- StateData#state.access, JID) of
- allow ->
- ?INFO_MSG("(~w) Opened session for ~s",
- [StateData#state.socket,
- jlib:jid_to_string(JID)]),
- SID = {now(), self()},
- ejabberd_sm:open_session(
- SID, U, StateData#state.server, R),
- Res = jlib:make_result_iq_reply(El),
- send_element(StateData, Res),
- change_shaper(StateData, JID),
- {Fs, Ts} = ejabberd_hooks:run_fold(
- roster_get_subscription_lists,
- StateData#state.server,
- {[], []},
- [U, StateData#state.server]),
- LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
- Fs1 = [LJID | Fs],
- Ts1 = [LJID | Ts],
- PrivList =
- case catch mod_privacy:get_user_list(
- U, StateData#state.server) of
- {'EXIT', _} -> none;
- PL -> PL
- end,
- {next_state, session_established,
- StateData#state{sid = SID,
- pres_f = ?SETS:from_list(Fs1),
- pres_t = ?SETS:from_list(Ts1),
- privacy_list = PrivList}};
- _ ->
- ?INFO_MSG("(~w) Forbidden session for ~s",
- [StateData#state.socket,
- jlib:jid_to_string(JID)]),
- Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
- send_element(StateData, Err),
- {next_state, wait_for_session, StateData}
- end;
- _ ->
- {next_state, wait_for_session, StateData}
- end;
-
-wait_for_session({xmlstreamend, _Name}, StateData) ->
- send_text(StateData, ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_session({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_session(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-
-
-session_established({xmlstreamelement, El}, StateData) ->
- {xmlelement, Name, Attrs, _Els} = El,
- User = StateData#state.user,
- Server = StateData#state.server,
- % TODO: check 'from' attribute in stanza
- FromJID = StateData#state.jid,
- To = xml:get_attr_s("to", Attrs),
- ToJID = case To of
- "" ->
- jlib:make_jid(User, Server, "");
- _ ->
- jlib:string_to_jid(To)
- end,
- NewEl1 = jlib:remove_attr("xmlns", El),
- NewEl = case xml:get_attr_s("xml:lang", Attrs) of
- "" ->
- case StateData#state.lang of
- "" -> NewEl1;
- Lang ->
- xml:replace_tag_attr("xml:lang", Lang, NewEl1)
- end;
- _ ->
- NewEl1
- end,
- NewState =
- case ToJID of
- error ->
- case xml:get_attr_s("type", Attrs) of
- "error" -> StateData;
- "result" -> StateData;
- _ ->
- Err = jlib:make_error_reply(NewEl, ?ERR_JID_MALFORMED),
- send_element(StateData, Err),
- StateData
- end;
- _ ->
- case Name of
- "presence" ->
- case ToJID of
- #jid{user = User,
- server = Server,
- resource = ""} ->
- ?DEBUG("presence_update(~p,~n\t~p,~n\t~p)",
- [FromJID, NewEl, StateData]),
- presence_update(FromJID, NewEl, StateData);
- _ ->
- presence_track(FromJID, ToJID, NewEl, StateData)
- end;
- "iq" ->
- case StateData#state.privacy_list of
- none ->
- ejabberd_router:route(FromJID, ToJID, NewEl),
- StateData;
- _PrivList ->
- case jlib:iq_query_info(NewEl) of
- #iq{xmlns = ?NS_PRIVACY} = IQ ->
- process_privacy_iq(
- FromJID, ToJID, IQ, StateData);
- _ ->
- ejabberd_hooks:run(
- user_send_packet,
- Server,
- [FromJID, ToJID, NewEl]),
- ejabberd_router:route(
- FromJID, ToJID, NewEl),
- StateData
- end
- end;
- "message" ->
- ejabberd_hooks:run(user_send_packet,
- Server,
- [FromJID, ToJID, NewEl]),
- ejabberd_router:route(FromJID, ToJID, NewEl),
- StateData;
- _ ->
- StateData
- end
- end,
- {next_state, session_established, NewState};
-
-session_established({xmlstreamend, _Name}, StateData) ->
- send_text(StateData, ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-session_established({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-session_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(become_controller, StateName, StateData) ->
- ok = (StateData#state.sockmod):controlling_process(
- StateData#state.socket,
- StateData#state.receiver),
- ejabberd_receiver:become_controller(StateData#state.receiver),
- {next_state, StateName, StateData};
-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({get_presence}, _From, StateName, StateData) ->
- User = StateData#state.user,
- PresLast = StateData#state.pres_last,
-
- Show = get_showtag(PresLast),
- Status = get_statustag(PresLast),
- Resource = StateData#state.resource,
-
- Reply = {User, Resource, Show, Status},
- {reply, Reply, StateName, StateData};
-
-handle_sync_event(_Event, _From, StateName, StateData) ->
- Reply = ok,
- {reply, Reply, StateName, StateData}.
-
-
-code_change(_OldVsn, StateName, StateData, _Extra) ->
- {ok, StateName, StateData}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/3
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-handle_info({send_text, Text}, StateName, StateData) ->
- send_text(StateData, Text),
- {next_state, StateName, StateData};
-handle_info(replaced, _StateName, StateData) ->
- Lang = StateData#state.lang,
- send_text(StateData,
- xml:element_to_string(
- ?SERRT_CONFLICT(Lang, "Replaced by new connection"))
- ++ ?STREAM_TRAILER),
- {stop, normal, StateData#state{authenticated = replaced}};
-handle_info({route, From, To, Packet}, StateName, StateData) ->
- {xmlelement, Name, Attrs, Els} = Packet,
- {Pass, NewAttrs, NewState} =
- case Name of
- "presence" ->
- case xml:get_attr_s("type", Attrs) of
- "probe" ->
- LFrom = jlib:jid_tolower(From),
- LBFrom = jlib:jid_remove_resource(LFrom),
- NewStateData =
- case ?SETS:is_element(
- LFrom, StateData#state.pres_a) orelse
- ?SETS:is_element(
- LBFrom, StateData#state.pres_a) of
- true ->
- StateData;
- false ->
- case ?SETS:is_element(
- LFrom, StateData#state.pres_f) of
- true ->
- A = ?SETS:add_element(
- LFrom,
- StateData#state.pres_a),
- StateData#state{pres_a = A};
- false ->
- case ?SETS:is_element(
- LBFrom, StateData#state.pres_f) of
- true ->
- A = ?SETS:add_element(
- LBFrom,
- StateData#state.pres_a),
- StateData#state{pres_a = A};
- false ->
- StateData
- end
- end
- end,
- process_presence_probe(From, To, NewStateData),
- {false, Attrs, NewStateData};
- "error" ->
- NewA = remove_element(jlib:jid_tolower(From),
- StateData#state.pres_a),
- {true, Attrs, StateData#state{pres_a = NewA}};
- "invisible" ->
- Attrs1 = lists:keydelete("type", 1, Attrs),
- {true, [{"type", "unavailable"} | Attrs1], StateData};
- "subscribe" ->
- {true, Attrs, StateData};
- "subscribed" ->
- {true, Attrs, StateData};
- "unsubscribe" ->
- {true, Attrs, StateData};
- "unsubscribed" ->
- {true, Attrs, StateData};
- _ ->
-%-ifdef(PRIVACY_SUPPORT).
- case catch mod_privacy:check_packet(
- StateData#state.user,
- StateData#state.server,
- StateData#state.privacy_list,
- {From, To, Packet},
- in) of
- {'EXIT', _Reason} ->
- {true, Attrs, StateData};
- allow ->
- LFrom = jlib:jid_tolower(From),
- LBFrom = jlib:jid_remove_resource(LFrom),
- case ?SETS:is_element(
- LFrom, StateData#state.pres_a) orelse
- ?SETS:is_element(
- LBFrom, StateData#state.pres_a) of
- true ->
- {true, Attrs, StateData};
- false ->
- case ?SETS:is_element(
- LFrom, StateData#state.pres_f) of
- true ->
- A = ?SETS:add_element(
- LFrom,
- StateData#state.pres_a),
- {true, Attrs,
- StateData#state{pres_a = A}};
- false ->
- case ?SETS:is_element(
- LBFrom, StateData#state.pres_f) of
- true ->
- A = ?SETS:add_element(
- LBFrom,
- StateData#state.pres_a),
- {true, Attrs,
- StateData#state{pres_a = A}};
- false ->
- {true, Attrs, StateData}
- end
- end
- end;
- deny ->
- {false, Attrs, StateData}
- end
-%-elseif.
-% {true, Attrs, StateData}
-%-endif.
- end;
- "broadcast" ->
- ?DEBUG("broadcast~n~p~n", [Els]),
- case Els of
- [{item, IJID, ISubscription}] ->
- {false, Attrs,
- roster_change(IJID, ISubscription,
- StateData)};
- [{exit, Reason}] ->
- {exit, Attrs, Reason};
- [{privacy_list, PrivList, PrivListName}] ->
- case catch mod_privacy:updated_list(
- StateData#state.privacy_list,
- PrivList) of
- {'EXIT', _} ->
- {false, Attrs, StateData};
- NewPL ->
- PrivPushIQ =
- #iq{type = set, xmlns = ?NS_PRIVACY,
- id = "push",
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_PRIVACY}],
- [{xmlelement, "list",
- [{"name", PrivListName}],
- []}]}]},
- PrivPushEl =
- jlib:replace_from_to(
- jlib:jid_remove_resource(
- StateData#state.jid),
- StateData#state.jid,
- jlib:iq_to_xml(PrivPushIQ)),
- send_element(StateData, PrivPushEl),
- {false, Attrs, StateData#state{privacy_list = NewPL}}
- end;
- _ ->
- {false, Attrs, StateData}
- end;
- "iq" ->
- IQ = jlib:iq_query_info(Packet),
- case IQ of
- #iq{xmlns = ?NS_VCARD} ->
- Host = StateData#state.server,
- case ets:lookup(sm_iqtable, {?NS_VCARD, Host}) of
- [{_, Module, Function, Opts}] ->
- gen_iq_handler:handle(Host, Module, Function, Opts,
- From, To, IQ);
- [] ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
- ejabberd_router:route(To, From, Err)
- end,
- {false, Attrs, StateData};
-%-ifdef(PRIVACY_SUPPORT).
- #iq{} ->
- case catch mod_privacy:check_packet(
- StateData#state.user,
- StateData#state.server,
- StateData#state.privacy_list,
- {From, To, Packet},
- in) of
- {'EXIT', _Reason} ->
- {true, Attrs, StateData};
- allow ->
- {true, Attrs, StateData};
- deny ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
- ejabberd_router:route(To, From, Err),
- {false, Attrs, StateData}
- end;
-%-endif.
- _ ->
- {true, Attrs, StateData}
- end;
-%-ifdef(PRIVACY_SUPPORT).
- "message" ->
- case catch mod_privacy:check_packet(
- StateData#state.user,
- StateData#state.server,
- StateData#state.privacy_list,
- {From, To, Packet},
- in) of
- {'EXIT', _Reason} ->
- {true, Attrs, StateData};
- allow ->
- {true, Attrs, StateData};
- deny ->
- {false, Attrs, StateData}
- end;
-%-endif.
- _ ->
- {true, Attrs, StateData}
- end,
- if
- Pass == exit ->
- catch send_text(StateData, ?STREAM_TRAILER),
- {stop, normal, StateData};
- Pass ->
- Attrs2 = jlib:replace_from_to_attrs(jlib:jid_to_string(From),
- jlib:jid_to_string(To),
- NewAttrs),
- FixedPacket = {xmlelement, Name, Attrs2, Els},
- Text = xml:element_to_string(FixedPacket),
- send_text(StateData, Text),
- ejabberd_hooks:run(user_receive_packet,
- StateData#state.server,
- [StateData#state.jid, From, To, FixedPacket]),
- {next_state, StateName, NewState};
- true ->
- {next_state, StateName, NewState}
- end;
-handle_info(Info, StateName, StateData) ->
- ?ERROR_MSG("Unexpected info: ~p", [Info]),
- {next_state, StateName, StateData}.
-
-%%----------------------------------------------------------------------
-%% Func: terminate/3
-%% Purpose: Shutdown the fsm
-%% Returns: any
-%%----------------------------------------------------------------------
-terminate(_Reason, StateName, StateData) ->
- case StateName of
- session_established ->
- case StateData#state.authenticated of
- replaced ->
- ?INFO_MSG("(~w) Replaced session for ~s",
- [StateData#state.socket,
- jlib:jid_to_string(StateData#state.jid)]),
- From = StateData#state.jid,
- Packet = {xmlelement, "presence",
- [{"type", "unavailable"}],
- [{xmlelement, "status", [],
- [{xmlcdata, "Replaced by new connection"}]}]},
- ejabberd_sm:close_session_unset_presence(
- StateData#state.sid,
- StateData#state.user,
- StateData#state.server,
- StateData#state.resource,
- "Replaced by new connection"),
- presence_broadcast(
- StateData, From, StateData#state.pres_a, Packet),
- presence_broadcast(
- StateData, From, StateData#state.pres_i, Packet);
- _ ->
- ?INFO_MSG("(~w) Close session for ~s",
- [StateData#state.socket,
- jlib:jid_to_string(StateData#state.jid)]),
-
- EmptySet = ?SETS:new(),
- case StateData of
- #state{pres_last = undefined,
- pres_a = EmptySet,
- pres_i = EmptySet,
- pres_invis = false} ->
- ejabberd_sm:close_session(StateData#state.sid,
- StateData#state.user,
- StateData#state.server,
- StateData#state.resource);
- _ ->
- From = StateData#state.jid,
- Packet = {xmlelement, "presence",
- [{"type", "unavailable"}], []},
- ejabberd_sm:close_session_unset_presence(
- StateData#state.sid,
- StateData#state.user,
- StateData#state.server,
- StateData#state.resource,
- ""),
- presence_broadcast(
- StateData, From, StateData#state.pres_a, Packet),
- presence_broadcast(
- StateData, From, StateData#state.pres_i, Packet)
- end
- end;
- _ ->
- ok
- end,
- ejabberd_receiver:close(StateData#state.receiver),
- ok.
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-
-change_shaper(StateData, JID) ->
- Shaper = acl:match_rule(StateData#state.server,
- StateData#state.shaper, JID),
- ejabberd_receiver:change_shaper(StateData#state.receiver, Shaper).
-
-send_text(StateData, Text) ->
- ?DEBUG("Send XML on stream = ~p", [lists:flatten(Text)]),
- catch (StateData#state.sockmod):send(StateData#state.socket, Text).
-
-send_element(StateData, El) ->
- send_text(StateData, xml:element_to_string(El)).
-
-
-new_id() ->
- randoms:get_string().
-
-
-is_auth_packet(El) ->
- case jlib:iq_query_info(El) of
- #iq{id = ID, type = Type, xmlns = ?NS_AUTH, sub_el = SubEl} ->
- {xmlelement, _, _, Els} = SubEl,
- {auth, ID, Type,
- get_auth_tags(Els, "", "", "", "")};
- _ ->
- false
- end.
-
-
-get_auth_tags([{xmlelement, Name, _Attrs, Els}| L], U, P, D, R) ->
- CData = xml:get_cdata(Els),
- case Name of
- "username" ->
- get_auth_tags(L, CData, P, D, R);
- "password" ->
- get_auth_tags(L, U, CData, D, R);
- "digest" ->
- get_auth_tags(L, U, P, CData, R);
- "resource" ->
- get_auth_tags(L, U, P, D, CData);
- _ ->
- get_auth_tags(L, U, P, D, R)
- end;
-get_auth_tags([_ | L], U, P, D, R) ->
- get_auth_tags(L, U, P, D, R);
-get_auth_tags([], U, P, D, R) ->
- {U, P, D, R}.
-
-
-process_presence_probe(From, To, StateData) ->
- LFrom = jlib:jid_tolower(From),
- LBFrom = setelement(3, LFrom, ""),
- case StateData#state.pres_last of
- undefined ->
- ok;
- _ ->
- Cond1 = (not StateData#state.pres_invis)
- andalso (?SETS:is_element(LFrom, StateData#state.pres_f)
- orelse
- ((LFrom /= LBFrom) andalso
- ?SETS:is_element(LBFrom, StateData#state.pres_f)))
- andalso (not
- (?SETS:is_element(LFrom, StateData#state.pres_i)
- orelse
- ((LFrom /= LBFrom) andalso
- ?SETS:is_element(LBFrom, StateData#state.pres_i)))),
- Cond2 = StateData#state.pres_invis
- andalso ?SETS:is_element(LFrom, StateData#state.pres_f)
- andalso ?SETS:is_element(LFrom, StateData#state.pres_a),
- if
- Cond1 ->
- Packet = StateData#state.pres_last,
-%-ifdef(PRIVACY_SUPPORT).
- case catch mod_privacy:check_packet(
- StateData#state.user,
- StateData#state.server,
- StateData#state.privacy_list,
- {To, From, Packet},
- out) of
- deny ->
- ok;
- _ ->
-%-endif.
- ejabberd_router:route(To, From, Packet)
-%-ifdef(PRIVACY_SUPPORT).
- end;
-%-endif.
- Cond2 ->
- ejabberd_router:route(To, From,
- {xmlelement, "presence",
- [],
- []});
- true ->
- ok
- end
- end.
-
-presence_update(From, Packet, StateData) ->
- {xmlelement, _Name, Attrs, _Els} = Packet,
- case xml:get_attr_s("type", Attrs) of
- "unavailable" ->
- Status = case xml:get_subtag(Packet, "status") of
- false ->
- "";
- StatusTag ->
- xml:get_tag_cdata(StatusTag)
- end,
- ejabberd_sm:unset_presence(StateData#state.sid,
- StateData#state.user,
- StateData#state.server,
- StateData#state.resource,
- Status),
- presence_broadcast(StateData, From, StateData#state.pres_a, Packet),
- presence_broadcast(StateData, From, StateData#state.pres_i, Packet),
- StateData#state{pres_last = undefined,
- pres_a = ?SETS:new(),
- pres_i = ?SETS:new(),
- pres_invis = false};
- "invisible" ->
- NewState =
- if
- not StateData#state.pres_invis ->
- presence_broadcast(StateData, From,
- StateData#state.pres_a,
- Packet),
- presence_broadcast(StateData, From,
- StateData#state.pres_i,
- Packet),
- S1 = StateData#state{pres_last = undefined,
- pres_a = ?SETS:new(),
- pres_i = ?SETS:new(),
- pres_invis = true},
- presence_broadcast_first(From, S1, Packet);
- true ->
- StateData
- end,
- NewState;
- "error" ->
- StateData;
- "probe" ->
- StateData;
- "subscribe" ->
- StateData;
- "subscribed" ->
- StateData;
- "unsubscribe" ->
- StateData;
- "unsubscribed" ->
- StateData;
- _ ->
- OldPriority = case StateData#state.pres_last of
- undefined ->
- 0;
- OldPresence ->
- get_priority_from_presence(OldPresence)
- end,
- NewPriority = get_priority_from_presence(Packet),
- update_priority(NewPriority, StateData),
- FromUnavail = (StateData#state.pres_last == undefined) or
- StateData#state.pres_invis,
- ?DEBUG("from unavail = ~p~n", [FromUnavail]),
- NewState =
- if
- FromUnavail ->
- ejabberd_hooks:run(user_available_hook,
- StateData#state.server,
- [StateData#state.jid]),
- resend_offline_messages(StateData),
- resend_subscription_requests(StateData),
- presence_broadcast_first(
- From, StateData#state{pres_last = Packet,
- pres_invis = false
- }, Packet);
- true ->
- presence_broadcast_to_trusted(StateData,
- From,
- StateData#state.pres_f,
- StateData#state.pres_a,
- Packet),
- if OldPriority < 0, NewPriority >= 0 ->
- resend_offline_messages(StateData);
- true ->
- ok
- end,
- StateData#state{pres_last = Packet,
- pres_invis = false
- }
- end,
- NewState
- end.
-
-presence_track(From, To, Packet, StateData) ->
- {xmlelement, _Name, Attrs, _Els} = Packet,
- LTo = jlib:jid_tolower(To),
- User = StateData#state.user,
- Server = StateData#state.server,
- case xml:get_attr_s("type", Attrs) of
- "unavailable" ->
- ejabberd_router:route(From, To, Packet),
- I = remove_element(LTo, StateData#state.pres_i),
- A = remove_element(LTo, StateData#state.pres_a),
- StateData#state{pres_i = I,
- pres_a = A};
- "invisible" ->
- ejabberd_router:route(From, To, Packet),
- I = ?SETS:add_element(LTo, StateData#state.pres_i),
- A = remove_element(LTo, StateData#state.pres_a),
- StateData#state{pres_i = I,
- pres_a = A};
- "subscribe" ->
- ejabberd_hooks:run(roster_out_subscription,
- Server,
- [User, Server, To, subscribe]),
- ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
- StateData;
- "subscribed" ->
- ejabberd_hooks:run(roster_out_subscription,
- Server,
- [User, Server, To, subscribed]),
- ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
- StateData;
- "unsubscribe" ->
- ejabberd_hooks:run(roster_out_subscription,
- Server,
- [User, Server, To, unsubscribe]),
- ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
- StateData;
- "unsubscribed" ->
- ejabberd_hooks:run(roster_out_subscription,
- Server,
- [User, Server, To, unsubscribed]),
- ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
- StateData;
- "error" ->
- ejabberd_router:route(From, To, Packet),
- StateData;
- "probe" ->
- ejabberd_router:route(From, To, Packet),
- StateData;
- _ ->
-%-ifdef(PRIVACY_SUPPORT).
- case catch mod_privacy:check_packet(
- StateData#state.user,
- StateData#state.server,
- StateData#state.privacy_list,
- {From, To, Packet},
- out) of
- deny ->
- ok;
- _ ->
-%-endif.
- ejabberd_router:route(From, To, Packet)
-%-ifdef(PRIVACY_SUPPORT).
- end,
-%-endif.
- I = remove_element(LTo, StateData#state.pres_i),
- A = ?SETS:add_element(LTo, StateData#state.pres_a),
- StateData#state{pres_i = I,
- pres_a = A}
- end.
-
-presence_broadcast(StateData, From, JIDSet, Packet) ->
- lists:foreach(fun(JID) ->
- FJID = jlib:make_jid(JID),
-%-ifdef(PRIVACY_SUPPORT).
- case catch mod_privacy:check_packet(
- StateData#state.user,
- StateData#state.server,
- StateData#state.privacy_list,
- {From, FJID, Packet},
- out) of
- deny ->
- ok;
- _ ->
-%-endif.
- ejabberd_router:route(From, FJID, Packet)
-%-ifdef(PRIVACY_SUPPORT).
- end
-%-endif.
- end, ?SETS:to_list(JIDSet)).
-
-presence_broadcast_to_trusted(StateData, From, T, A, Packet) ->
- lists:foreach(
- fun(JID) ->
- case ?SETS:is_element(JID, T) of
- true ->
- FJID = jlib:make_jid(JID),
-%-ifdef(PRIVACY_SUPPORT).
- case catch mod_privacy:check_packet(
- StateData#state.user,
- StateData#state.server,
- StateData#state.privacy_list,
- {From, FJID, Packet},
- out) of
- deny ->
- ok;
- _ ->
-%-endif.
- ejabberd_router:route(From, FJID, Packet)
-%-ifdef(PRIVACY_SUPPORT).
- end;
-%-endif.
- _ ->
- ok
- end
- end, ?SETS:to_list(A)).
-
-
-presence_broadcast_first(From, StateData, Packet) ->
- ?SETS:fold(fun(JID, X) ->
- ejabberd_router:route(
- From,
- jlib:make_jid(JID),
- {xmlelement, "presence",
- [{"type", "probe"}],
- []}),
- X
- end,
- [],
- StateData#state.pres_t),
- if
- StateData#state.pres_invis ->
- StateData;
- true ->
- As = ?SETS:fold(
- fun(JID, A) ->
- FJID = jlib:make_jid(JID),
-%-ifdef(PRIVACY_SUPPORT).
- case catch mod_privacy:check_packet(
- StateData#state.user,
- StateData#state.server,
- StateData#state.privacy_list,
- {From, FJID, Packet},
- out) of
- deny ->
- ok;
- _ ->
-%-endif.
- ejabberd_router:route(From, FJID, Packet)
-%-ifdef(PRIVACY_SUPPORT).
- end,
-%-endif.
- ?SETS:add_element(JID, A)
- end,
- StateData#state.pres_a,
- StateData#state.pres_f),
- StateData#state{pres_a = As}
- end.
-
-
-remove_element(E, Set) ->
- case ?SETS:is_element(E, Set) of
- true ->
- ?SETS:del_element(E, Set);
- _ ->
- Set
- end.
-
-
-roster_change(IJID, ISubscription, StateData) ->
- LIJID = jlib:jid_tolower(IJID),
- IsFrom = (ISubscription == both) or (ISubscription == from),
- IsTo = (ISubscription == both) or (ISubscription == to),
- OldIsFrom = ?SETS:is_element(LIJID, StateData#state.pres_f),
- FSet = if
- IsFrom ->
- ?SETS:add_element(LIJID, StateData#state.pres_f);
- true ->
- remove_element(LIJID, StateData#state.pres_f)
- end,
- TSet = if
- IsTo ->
- ?SETS:add_element(LIJID, StateData#state.pres_t);
- true ->
- remove_element(LIJID, StateData#state.pres_t)
- end,
- case StateData#state.pres_last of
- undefined ->
- StateData#state{pres_f = FSet, pres_t = TSet};
- P ->
- ?DEBUG("roster changed for ~p~n", [StateData#state.user]),
- From = StateData#state.jid,
- To = jlib:make_jid(IJID),
- Cond1 = (not StateData#state.pres_invis) and IsFrom
- and (not OldIsFrom),
- Cond2 = (not IsFrom) and OldIsFrom
- and (?SETS:is_element(LIJID, StateData#state.pres_a) or
- ?SETS:is_element(LIJID, StateData#state.pres_i)),
- if
- Cond1 ->
- ?DEBUG("C1: ~p~n", [LIJID]),
- case catch mod_privacy:check_packet(
- StateData#state.user,
- StateData#state.server,
- StateData#state.privacy_list,
- {From, To, P},
- out) of
- deny ->
- ok;
- _ ->
- ejabberd_router:route(From, To, P)
- end,
- A = ?SETS:add_element(LIJID,
- StateData#state.pres_a),
- StateData#state{pres_a = A,
- pres_f = FSet,
- pres_t = TSet};
- Cond2 ->
- ?DEBUG("C2: ~p~n", [LIJID]),
- PU = {xmlelement, "presence",
- [{"type", "unavailable"}], []},
- case catch mod_privacy:check_packet(
- StateData#state.user,
- StateData#state.server,
- StateData#state.privacy_list,
- {From, To, PU},
- out) of
- deny ->
- ok;
- _ ->
- ejabberd_router:route(From, To, PU)
- end,
- I = remove_element(LIJID,
- StateData#state.pres_i),
- A = remove_element(LIJID,
- StateData#state.pres_a),
- StateData#state{pres_i = I,
- pres_a = A,
- pres_f = FSet,
- pres_t = TSet};
- true ->
- StateData#state{pres_f = FSet, pres_t = TSet}
- end
- end.
-
-
-update_priority(Pri, StateData) ->
- ejabberd_sm:set_presence(StateData#state.sid,
- StateData#state.user,
- StateData#state.server,
- StateData#state.resource,
- Pri).
-
-get_priority_from_presence(PresencePacket) ->
- case xml:get_subtag(PresencePacket, "priority") of
- false ->
- 0;
- SubEl ->
- case catch list_to_integer(xml:get_tag_cdata(SubEl)) of
- P when is_integer(P) ->
- P;
- _ ->
- 0
- end
- end.
-
-process_privacy_iq(From, To,
- #iq{type = Type, sub_el = SubEl} = IQ,
- StateData) ->
- {Res, NewStateData} =
- case Type of
- get ->
- case catch
- mod_privacy:process_iq_get(
- From, To, IQ,
- StateData#state.privacy_list) of
- {'EXIT', _} ->
- {{error, ?ERR_FEATURE_NOT_IMPLEMENTED}, StateData};
- R -> {R, StateData}
- end;
- set ->
- case catch
- mod_privacy:process_iq_set(
- From, To, IQ) of
- {'EXIT', _} ->
- {{error, ?ERR_FEATURE_NOT_IMPLEMENTED}, StateData};
- {result, R, NewPrivList} ->
- {{result, R},
- StateData#state{privacy_list = NewPrivList}};
- R -> {R, StateData}
- end
- end,
- IQRes =
- case Res of
- {result, Result} ->
- IQ#iq{type = result, sub_el = Result};
- {error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]}
- end,
- ejabberd_router:route(
- To, From, jlib:iq_to_xml(IQRes)),
- NewStateData.
-
-
-resend_offline_messages(#state{user = User,
- server = Server,
- privacy_list = PrivList} = StateData) ->
- case ejabberd_hooks:run_fold(resend_offline_messages_hook,
- Server,
- [],
- [User, Server]) of
- Rs when list(Rs) ->
- lists:foreach(
- fun({route,
- From, To, {xmlelement, Name, Attrs, Els} = Packet}) ->
- Pass = case catch mod_privacy:check_packet(
- User,
- Server,
- PrivList,
- {From, To, Packet},
- in) of
- {'EXIT', _Reason} ->
- true;
- allow ->
- true;
- deny ->
- false
- end,
- if
- Pass ->
- Attrs2 = jlib:replace_from_to_attrs(
- jlib:jid_to_string(From),
- jlib:jid_to_string(To),
- Attrs),
- send_element(StateData,
- {xmlelement, Name, Attrs2, Els});
- true ->
- ok
- end
- end, Rs)
- end.
-
-resend_subscription_requests(#state{user = User,
- server = Server} = StateData) ->
- PendingSubscriptions = ejabberd_hooks:run_fold(
- resend_subscription_requests_hook,
- Server,
- [],
- [User, Server]),
- lists:foreach(fun(XMLPacket) ->
- send_element(StateData,
- XMLPacket)
- end,
- PendingSubscriptions).
-
-get_showtag(undefined) ->
- "unavailable";
-get_showtag(Presence) ->
- case xml:get_path_s(Presence, [{elem, "show"}, cdata]) of
- "" -> "available";
- ShowTag -> ShowTag
- end.
-
-get_statustag(undefined) ->
- "";
-get_statustag(Presence) ->
- case xml:get_path_s(Presence, [{elem, "status"}, cdata]) of
- ShowTag -> ShowTag
- end.
-
-process_unauthenticated_stanza(StateData, El) ->
- case jlib:iq_query_info(El) of
- #iq{} = IQ ->
- Res = ejabberd_hooks:run_fold(c2s_unauthenticated_iq,
- StateData#state.server,
- empty,
- [StateData#state.server, IQ]),
- case Res of
- empty ->
- % The only reasonable IQ's here are auth and register IQ's
- % They contain secrets, so don't include subelements to response
- ResIQ = IQ#iq{type = error,
- sub_el = [?ERR_SERVICE_UNAVAILABLE]},
- Res1 = jlib:replace_from_to(
- jlib:make_jid("", StateData#state.server, ""),
- jlib:make_jid("", "", ""),
- jlib:iq_to_xml(ResIQ)),
- send_element(StateData, jlib:remove_attr("to", Res1));
- _ ->
- send_element(StateData, Res)
- end;
- _ ->
- % Drop any stanza, which isn't IQ stanza
- ok
- end.
-
diff --git a/ejabberd-1.1.2/src/ejabberd_config.erl b/ejabberd-1.1.2/src/ejabberd_config.erl
deleted file mode 100644
index 93aee3e19..000000000
--- a/ejabberd-1.1.2/src/ejabberd_config.erl
+++ /dev/null
@@ -1,228 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_config.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Load config file
-%%% Created : 14 Dec 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_config).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([start/0, load_file/1,
- add_global_option/2, add_local_option/2,
- get_global_option/1, get_local_option/1]).
-
--include("ejabberd.hrl").
-
--record(config, {key, value}).
--record(local_config, {key, value}).
--record(state, {opts = [],
- hosts = [],
- override_local = false,
- override_global = false,
- override_acls = false}).
-
-start() ->
- mnesia:create_table(config,
- [{disc_copies, [node()]},
- {attributes, record_info(fields, config)}]),
- mnesia:add_table_copy(config, node(), ram_copies),
- mnesia:create_table(local_config,
- [{disc_copies, [node()]},
- {local_content, true},
- {attributes, record_info(fields, local_config)}]),
- mnesia:add_table_copy(local_config, node(), ram_copies),
- Config = case application:get_env(config) of
- {ok, Path} -> Path;
- undefined ->
- case os:getenv("EJABBERD_CONFIG_PATH") of
- false ->
- ?CONFIG_PATH;
- Path ->
- Path
- end
- end,
- load_file(Config).
-
-
-load_file(File) ->
- case file:consult(File) of
- {ok, Terms} ->
- State = lists:foldl(fun search_hosts/2, #state{}, Terms),
- Res = lists:foldl(fun process_term/2, State, Terms),
- set_opts(Res);
- {error, Reason} ->
- ?ERROR_MSG("Can't load config file ~p: ~p", [File, Reason]),
- exit(file:format_error(Reason))
- end.
-
-search_hosts(Term, State) ->
- case Term of
- {host, Host} ->
- if
- State#state.hosts == [] ->
- add_option(hosts, [Host], State#state{hosts = [Host]});
- true ->
- ?ERROR_MSG("Can't load config file: "
- "too many hosts definitions", []),
- exit("too many hosts definitions")
- end;
- {hosts, Hosts} ->
- if
- State#state.hosts == [] ->
- add_option(hosts, Hosts, State#state{hosts = Hosts});
- true ->
- ?ERROR_MSG("Can't load config file: "
- "too many hosts definitions", []),
- exit("too many hosts definitions")
- end;
- _ ->
- State
- end.
-
-process_term(Term, State) ->
- case Term of
- override_global ->
- State#state{override_global = true};
- override_local ->
- State#state{override_local = true};
- override_acls ->
- State#state{override_acls = true};
- {acl, ACLName, ACLData} ->
- process_host_term(Term, global, State);
- {access, RuleName, Rules} ->
- process_host_term(Term, global, State);
- {shaper, Name, Data} ->
- lists:foldl(fun(Host, S) -> process_host_term(Term, Host, S) end,
- State, State#state.hosts);
- {host, Host} ->
- State;
- {hosts, Hosts} ->
- State;
- {host_config, Host, Terms} ->
- lists:foldl(fun(T, S) -> process_host_term(T, Host, S) end,
- State, Terms);
- {listen, Val} ->
- add_option(listen, Val, State);
- {outgoing_s2s_port, Port} ->
- add_option(outgoing_s2s_port, Port, State);
- {s2s_use_starttls, Port} ->
- add_option(s2s_use_starttls, Port, State);
- {s2s_certfile, CertFile} ->
- add_option(s2s_certfile, CertFile, State);
- {domain_certfile, Domain, CertFile} ->
- add_option({domain_certfile, Domain}, CertFile, State);
- {Opt, Val} ->
- lists:foldl(fun(Host, S) -> process_host_term(Term, Host, S) end,
- State, State#state.hosts)
- end.
-
-process_host_term(Term, Host, State) ->
- case Term of
- {acl, ACLName, ACLData} ->
- State#state{opts =
- [acl:to_record(Host, ACLName, ACLData) | State#state.opts]};
- {access, RuleName, Rules} ->
- State#state{opts = [#config{key = {access, RuleName, Host},
- value = Rules} |
- State#state.opts]};
- {shaper, Name, Data} ->
- State#state{opts = [#config{key = {shaper, Name, Host},
- value = Data} |
- State#state.opts]};
- {host, Host} ->
- State;
- {hosts, Hosts} ->
- State;
- {Opt, Val} ->
- add_option({Opt, Host}, Val, State)
- end.
-
-add_option(Opt, Val, State) ->
- Table = case Opt of
- hosts ->
- config;
- language ->
- config;
- _ ->
- local_config
- end,
- case Table of
- config ->
- State#state{opts = [#config{key = Opt, value = Val} |
- State#state.opts]};
- local_config ->
- State#state{opts = [#local_config{key = Opt, value = Val} |
- State#state.opts]}
- end.
-
-
-set_opts(State) ->
- Opts = lists:reverse(State#state.opts),
- F = fun() ->
- if
- State#state.override_global ->
- Ksg = mnesia:all_keys(config),
- lists:foreach(fun(K) ->
- mnesia:delete({config, K})
- end, Ksg);
- true ->
- ok
- end,
- if
- State#state.override_local ->
- Ksl = mnesia:all_keys(local_config),
- lists:foreach(fun(K) ->
- mnesia:delete({local_config, K})
- end, Ksl);
- true ->
- ok
- end,
- if
- State#state.override_acls ->
- Ksa = mnesia:all_keys(acl),
- lists:foreach(fun(K) ->
- mnesia:delete({acl, K})
- end, Ksa);
- true ->
- ok
- end,
- lists:foreach(fun(R) ->
- mnesia:write(R)
- end, Opts)
- end,
- {atomic, _} = mnesia:transaction(F).
-
-
-add_global_option(Opt, Val) ->
- mnesia:transaction(fun() ->
- mnesia:write(#config{key = Opt,
- value = Val})
- end).
-
-add_local_option(Opt, Val) ->
- mnesia:transaction(fun() ->
- mnesia:write(#local_config{key = Opt,
- value = Val})
- end).
-
-
-get_global_option(Opt) ->
- case ets:lookup(config, Opt) of
- [#config{value = Val}] ->
- Val;
- _ ->
- undefined
- end.
-
-get_local_option(Opt) ->
- case ets:lookup(local_config, Opt) of
- [#local_config{value = Val}] ->
- Val;
- _ ->
- undefined
- end.
-
-
diff --git a/ejabberd-1.1.2/src/ejabberd_ctl.erl b/ejabberd-1.1.2/src/ejabberd_ctl.erl
deleted file mode 100644
index 1d929c002..000000000
--- a/ejabberd-1.1.2/src/ejabberd_ctl.erl
+++ /dev/null
@@ -1,351 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_ctl.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Ejabberd admin tool
-%%% Created : 11 Jan 2004 by Alexey Shchepin <alex@alex.sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_ctl).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([start/0,
- init/0,
- process/1,
- register_commands/3,
- register_commands/4,
- unregister_commands/3,
- unregister_commands/4]).
-
--include("ejabberd_ctl.hrl").
--include("ejabberd.hrl").
-
-start() ->
- case init:get_plain_arguments() of
- [SNode | Args] ->
- Node = list_to_atom(SNode),
- Status = case rpc:call(Node, ?MODULE, process, [Args]) of
- {badrpc, Reason} ->
- io:format("RPC failed on the node ~p: ~p~n",
- [Node, Reason]),
- ?STATUS_BADRPC;
- S ->
- S
- end,
- halt(Status);
- _ ->
- print_usage(),
- halt(?STATUS_USAGE)
- end.
-
-init() ->
- ets:new(ejabberd_ctl_cmds, [named_table, set, public]),
- ets:new(ejabberd_ctl_host_cmds, [named_table, set, public]).
-
-
-process(["status"]) ->
- {InternalStatus, ProvidedStatus} = init:get_status(),
- io:format("Node ~p is ~p. Status: ~p~n",
- [node(), InternalStatus, ProvidedStatus]),
- case lists:keysearch(ejabberd, 1, application:which_applications()) of
- false ->
- io:format("ejabberd is not running~n", []),
- ?STATUS_ERROR;
- {value,_Version} ->
- io:format("ejabberd is running~n", []),
- ?STATUS_SUCCESS
- end;
-
-process(["stop"]) ->
- init:stop(),
- ?STATUS_SUCCESS;
-
-process(["restart"]) ->
- init:restart(),
- ?STATUS_SUCCESS;
-
-process(["reopen-log"]) ->
- ejabberd_logger_h:reopen_log(),
- ?STATUS_SUCCESS;
-
-process(["register", User, Server, Password]) ->
- case ejabberd_auth:try_register(User, Server, Password) of
- {atomic, ok} ->
- ?STATUS_SUCCESS;
- {atomic, exists} ->
- io:format("User ~p already registered at node ~p~n",
- [User ++ "@" ++ Server, node()]),
- ?STATUS_ERROR;
- {error, Reason} ->
- io:format("Can't register user ~p at node ~p: ~p~n",
- [User ++ "@" ++ Server, node(), Reason]),
- ?STATUS_ERROR
- end;
-
-process(["unregister", User, Server]) ->
- case ejabberd_auth:remove_user(User, Server) of
- {error, Reason} ->
- io:format("Can't unregister user ~p at node ~p: ~p~n",
- [User ++ "@" ++ Server, node(), Reason]),
- ?STATUS_ERROR;
- _ ->
- ?STATUS_SUCCESS
- end;
-
-process(["backup", Path]) ->
- case mnesia:backup(Path) of
- ok ->
- ?STATUS_SUCCESS;
- {error, Reason} ->
- io:format("Can't store backup in ~p at node ~p: ~p~n",
- [filename:absname(Path), node(), Reason]),
- ?STATUS_ERROR
- end;
-
-process(["dump", Path]) ->
- case dump_to_textfile(Path) of
- ok ->
- ?STATUS_SUCCESS;
- {error, Reason} ->
- io:format("Can't store dump in ~p at node ~p: ~p~n",
- [filename:absname(Path), node(), Reason]),
- ?STATUS_ERROR
- end;
-
-process(["load", Path]) ->
- case mnesia:load_textfile(Path) of
- {atomic, ok} ->
- ?STATUS_SUCCESS;
- {error, Reason} ->
- io:format("Can't load dump in ~p at node ~p: ~p~n",
- [filename:absname(Path), node(), Reason]),
- ?STATUS_ERROR
- end;
-
-process(["restore", Path]) ->
- case ejabberd_admin:restore(Path) of
- {atomic, _} ->
- ?STATUS_SUCCESS;
- {error, Reason} ->
- io:format("Can't restore backup from ~p at node ~p: ~p~n",
- [filename:absname(Path), node(), Reason]),
- ?STATUS_ERROR;
- {aborted,{no_exists,Table}} ->
- io:format("Can't restore backup from ~p at node ~p: Table ~p does not exist.~n",
- [filename:absname(Path), node(), Table]),
- ?STATUS_ERROR;
- {aborted,enoent} ->
- io:format("Can't restore backup from ~p at node ~p: File not found.~n",
- [filename:absname(Path), node()]),
- ?STATUS_ERROR
- end;
-
-process(["install-fallback", Path]) ->
- case mnesia:install_fallback(Path) of
- ok ->
- ?STATUS_SUCCESS;
- {error, Reason} ->
- io:format("Can't install fallback from ~p at node ~p: ~p~n",
- [filename:absname(Path), node(), Reason]),
- ?STATUS_ERROR
- end;
-
-process(["import-file", Path]) ->
- case jd2ejd:import_file(Path) of
- ok ->
- ?STATUS_SUCCESS;
- {error, Reason} ->
- io:format("Can't import jabberd 1.4 spool file ~p at node ~p: ~p~n",
- [filename:absname(Path), node(), Reason]),
- ?STATUS_ERROR
- end;
-
-process(["import-dir", Path]) ->
- case jd2ejd:import_dir(Path) of
- ok ->
- ?STATUS_SUCCESS;
- {error, Reason} ->
- io:format("Can't import jabberd 1.4 spool dir ~p at node ~p: ~p~n",
- [filename:absname(Path), node(), Reason]),
- ?STATUS_ERROR
- end;
-
-process(["delete-expired-messages"]) ->
- mod_offline:remove_expired_messages(),
- ?STATUS_SUCCESS;
-
-process(["delete-old-messages", Days]) ->
- case catch list_to_integer(Days) of
- {'EXIT',{Reason, _Stack}} ->
- io:format("Can't delete old messages (~p). Please pass an integer as parameter.~n",
- [Reason]),
- ?STATUS_ERROR;
- Integer when Integer >= 0 ->
- {atomic, _} = mod_offline:remove_old_messages(Integer),
- io:format("Removed messages older than ~s days~n", [Days]),
- ?STATUS_SUCCESS;
- Integer ->
- io:format("Can't delete old messages. Please pass a positive integer as parameter.~n", []),
- ?STATUS_ERROR
- end;
-
-process(["vhost", H | Args]) ->
- case jlib:nameprep(H) of
- false ->
- io:format("Bad hostname: ~p~n", [H]),
- ?STATUS_ERROR;
- Host ->
- case ejabberd_hooks:run_fold(
- ejabberd_ctl_process, Host, false, [Host, Args]) of
- false ->
- print_vhost_usage(Host),
- ?STATUS_USAGE;
- Status ->
- Status
- end
- end;
-
-process(Args) ->
- case ejabberd_hooks:run_fold(ejabberd_ctl_process, false, [Args]) of
- false ->
- print_usage(),
- ?STATUS_USAGE;
- Status ->
- Status
- end.
-
-
-print_usage() ->
- CmdDescs =
- [{"status", "get ejabberd status"},
- {"stop", "stop ejabberd"},
- {"restart", "restart ejabberd"},
- {"reopen-log", "reopen log file"},
- {"register user server password", "register a user"},
- {"unregister user server", "unregister a user"},
- {"backup file", "store a database backup to file"},
- {"restore file", "restore a database backup from file"},
- {"install-fallback file", "install a database fallback from file"},
- {"dump file", "dump a database to a text file"},
- {"load file", "restore a database from a text file"},
- {"import-file file", "import user data from jabberd 1.4 spool file"},
- {"import-dir dir", "import user data from jabberd 1.4 spool directory"},
- {"delete-expired-messages", "delete expired offline messages from database"},
- {"delete-old-messages n", "delete offline messages older than n days from database"},
- {"vhost host ...", "execute host-specific commands"}] ++
- ets:tab2list(ejabberd_ctl_cmds),
- MaxCmdLen =
- lists:max(lists:map(
- fun({Cmd, _Desc}) ->
- length(Cmd)
- end, CmdDescs)),
- NewLine = io_lib:format("~n", []),
- FmtCmdDescs =
- lists:map(
- fun({Cmd, Desc}) ->
- [" ", Cmd, string:chars($\s, MaxCmdLen - length(Cmd) + 2),
- Desc, NewLine]
- end, CmdDescs),
- io:format(
- "Usage: ejabberdctl node command~n"
- "~n"
- "Available commands:~n"
- ++ FmtCmdDescs ++
- "~n"
- "Example:~n"
- " ejabberdctl ejabberd@host restart~n"
- ).
-
-print_vhost_usage(Host) ->
- CmdDescs =
- ets:select(ejabberd_ctl_host_cmds,
- [{{Host, '$1', '$2'}, [], [{{'$1', '$2'}}]}]),
- MaxCmdLen =
- if
- CmdDescs == [] ->
- 0;
- true ->
- lists:max(lists:map(
- fun({Cmd, _Desc}) ->
- length(Cmd)
- end, CmdDescs))
- end,
- NewLine = io_lib:format("~n", []),
- FmtCmdDescs =
- lists:map(
- fun({Cmd, Desc}) ->
- [" ", Cmd, string:chars($\s, MaxCmdLen - length(Cmd) + 2),
- Desc, NewLine]
- end, CmdDescs),
- io:format(
- "Usage: ejabberdctl node vhost host command~n"
- "~n"
- "Available commands:~n"
- ++ FmtCmdDescs ++
- "~n"
- ).
-
-register_commands(CmdDescs, Module, Function) ->
- ets:insert(ejabberd_ctl_cmds, CmdDescs),
- ejabberd_hooks:add(ejabberd_ctl_process,
- Module, Function, 50),
- ok.
-
-register_commands(Host, CmdDescs, Module, Function) ->
- ets:insert(ejabberd_ctl_host_cmds,
- [{Host, Cmd, Desc} || {Cmd, Desc} <- CmdDescs]),
- ejabberd_hooks:add(ejabberd_ctl_process, Host,
- Module, Function, 50),
- ok.
-
-unregister_commands(CmdDescs, Module, Function) ->
- lists:foreach(fun(CmdDesc) ->
- ets:delete_object(ejabberd_ctl_cmds, CmdDesc)
- end, CmdDescs),
- ejabberd_hooks:delete(ejabberd_ctl_process,
- Module, Function, 50),
- ok.
-
-unregister_commands(Host, CmdDescs, Module, Function) ->
- lists:foreach(fun({Cmd, Desc}) ->
- ets:delete_object(ejabberd_ctl_host_cmds,
- {Host, Cmd, Desc})
- end, CmdDescs),
- ejabberd_hooks:delete(ejabberd_ctl_process,
- Module, Function, 50),
- ok.
-
-dump_to_textfile(File) ->
- dump_to_textfile(mnesia:system_info(is_running), file:open(File, write)).
-dump_to_textfile(yes, {ok, F}) ->
- Tabs1 = lists:delete(schema, mnesia:system_info(local_tables)),
- Tabs = lists:filter(
- fun(T) ->
- case mnesia:table_info(T, storage_type) of
- disc_copies -> true;
- disc_only_copies -> true;
- _ -> false
- end
- end, Tabs1),
- Defs = lists:map(
- fun(T) -> {T, [{record_name, mnesia:table_info(T, record_name)},
- {attributes, mnesia:table_info(T, attributes)}]}
- end,
- Tabs),
- io:format(F, "~p.~n", [{tables, Defs}]),
- lists:foreach(fun(T) -> dump_tab(F, T) end, Tabs),
- file:close(F);
-dump_to_textfile(_, {ok, F}) ->
- file:close(F),
- {error, mnesia_not_running};
-dump_to_textfile(_, {error, Reason}) ->
- {error, Reason}.
-
-
-dump_tab(F, T) ->
- W = mnesia:table_info(T, wild_pattern),
- {atomic,All} = mnesia:transaction(
- fun() -> mnesia:match_object(T, W, read) end),
- lists:foreach(
- fun(Term) -> io:format(F,"~p.~n", [setelement(1, Term, T)]) end, All).
diff --git a/ejabberd-1.1.2/src/ejabberd_ctl.hrl b/ejabberd-1.1.2/src/ejabberd_ctl.hrl
deleted file mode 100644
index cfac37c63..000000000
--- a/ejabberd-1.1.2/src/ejabberd_ctl.hrl
+++ /dev/null
@@ -1,12 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_ctl.hrl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 13 Feb 2006 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--define(STATUS_SUCCESS, 0).
--define(STATUS_ERROR, 1).
--define(STATUS_USAGE, 2).
--define(STATUS_BADRPC, 3).
diff --git a/ejabberd-1.1.2/src/ejabberd_hooks.erl b/ejabberd-1.1.2/src/ejabberd_hooks.erl
deleted file mode 100644
index 1888dabd3..000000000
--- a/ejabberd-1.1.2/src/ejabberd_hooks.erl
+++ /dev/null
@@ -1,199 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_hooks.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Manage hooks
-%%% Created : 8 Aug 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_hooks).
--author('alexey@sevcom.net').
-
--behaviour(gen_server).
-
-%% External exports
--export([start_link/0,
- add/4,
- delete/4,
- run/2,
- run_fold/3,
- add/5,
- delete/5,
- run/3,
- run_fold/4]).
-
-%% gen_server callbacks
--export([init/1,
- handle_call/3,
- handle_cast/2,
- code_change/3,
- handle_info/2,
- terminate/2]).
-
--include("ejabberd.hrl").
-
--record(state, {}).
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-start_link() ->
- gen_server:start_link({local, ejabberd_hooks}, ejabberd_hooks, [], []).
-
-add(Hook, Module, Function, Seq) ->
- add(Hook, global, Module, Function, Seq).
-
-add(Hook, Host, Module, Function, Seq) ->
- gen_server:call(ejabberd_hooks, {add, Hook, Host, Module, Function, Seq}).
-
-delete(Hook, Module, Function, Seq) ->
- delete(Hook, global, Module, Function, Seq).
-
-delete(Hook, Host, Module, Function, Seq) ->
- gen_server:call(ejabberd_hooks, {delete, Hook, Host, Module, Function, Seq}).
-
-run(Hook, Args) ->
- run(Hook, global, Args).
-
-run(Hook, Host, Args) ->
- case ets:lookup(hooks, {Hook, Host}) of
- [{_, Ls}] ->
- run1(Ls, Hook, Args);
- [] ->
- ok
- end.
-
-run_fold(Hook, Val, Args) ->
- run_fold(Hook, global, Val, Args).
-
-run_fold(Hook, Host, Val, Args) ->
- case ets:lookup(hooks, {Hook, Host}) of
- [{_, Ls}] ->
- run_fold1(Ls, Hook, Val, Args);
- [] ->
- Val
- end.
-
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_server
-%%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%%----------------------------------------------------------------------
-init([]) ->
- ets:new(hooks, [named_table]),
- {ok, #state{}}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_call/3
-%% Returns: {reply, Reply, State} |
-%% {reply, Reply, State, Timeout} |
-%% {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, Reply, State} | (terminate/2 is called)
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-handle_call({add, Hook, Host, Module, Function, Seq}, From, State) ->
- Reply = case ets:lookup(hooks, {Hook, Host}) of
- [{_, Ls}] ->
- El = {Seq, Module, Function},
- case lists:member(El, Ls) of
- true ->
- ok;
- false ->
- NewLs = lists:merge(Ls, [El]),
- ets:insert(hooks, {{Hook, Host}, NewLs}),
- ok
- end;
- [] ->
- NewLs = [{Seq, Module, Function}],
- ets:insert(hooks, {{Hook, Host}, NewLs}),
- ok
- end,
- {reply, Reply, State};
-handle_call({delete, Hook, Host, Module, Function, Seq}, From, State) ->
- Reply = case ets:lookup(hooks, {Hook, Host}) of
- [{_, Ls}] ->
- NewLs = lists:delete({Seq, Module, Function}, Ls),
- ets:insert(hooks, {{Hook, Host}, NewLs}),
- ok;
- [] ->
- ok
- end,
- {reply, Reply, State};
-handle_call(Request, From, State) ->
- Reply = ok,
- {reply, Reply, State}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_cast/2
-%% Returns: {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-handle_cast(Msg, State) ->
- {noreply, State}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/2
-%% Returns: {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-handle_info(Info, State) ->
- {noreply, State}.
-
-%%----------------------------------------------------------------------
-%% Func: terminate/2
-%% Purpose: Shutdown the server
-%% Returns: any (ignored by gen_server)
-%%----------------------------------------------------------------------
-terminate(Reason, State) ->
- ok.
-
-
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-
-run1([], Hook, Args) ->
- ok;
-run1([{_Seq, Module, Function} | Ls], Hook, Args) ->
- case catch apply(Module, Function, Args) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~nrunning hook: ~p",
- [Reason, {Hook, Args}]),
- run1(Ls, Hook, Args);
- stop ->
- ok;
- _ ->
- run1(Ls, Hook, Args)
- end.
-
-
-run_fold1([], Hook, Val, Args) ->
- Val;
-run_fold1([{_Seq, Module, Function} | Ls], Hook, Val, Args) ->
- case catch apply(Module, Function, [Val | Args]) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~nrunning hook: ~p",
- [Reason, {Hook, Args}]),
- run_fold1(Ls, Hook, Val, Args);
- stop ->
- stopped;
- {stop, NewVal} ->
- NewVal;
- NewVal ->
- run_fold1(Ls, Hook, NewVal, Args)
- end.
-
-
-
diff --git a/ejabberd-1.1.2/src/ejabberd_listener.erl b/ejabberd-1.1.2/src/ejabberd_listener.erl
deleted file mode 100644
index d387de7d4..000000000
--- a/ejabberd-1.1.2/src/ejabberd_listener.erl
+++ /dev/null
@@ -1,196 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_listener.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_listener).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([start_link/0, init/1, start/3,
- init/3,
- init_ssl/4,
- start_listener/3,
- stop_listener/1,
- add_listener/3,
- delete_listener/1
- ]).
-
--include("ejabberd.hrl").
-
-start_link() ->
- supervisor:start_link({local, ejabberd_listeners}, ?MODULE, []).
-
-
-init(_) ->
- case ejabberd_config:get_local_option(listen) of
- undefined ->
- ignore;
- Ls ->
- {ok, {{one_for_one, 10, 1},
- lists:map(
- fun({Port, Module, Opts}) ->
- {Port,
- {?MODULE, start, [Port, Module, Opts]},
- transient,
- brutal_kill,
- worker,
- [?MODULE]}
- end, Ls)}}
- end.
-
-
-start(Port, Module, Opts) ->
- case lists:keysearch(ssl, 1, Opts) of
- {value, {ssl, SSLOpts}} ->
- {ok, proc_lib:spawn_link(?MODULE, init_ssl,
- [Port, Module, Opts, SSLOpts])};
- _ ->
- case lists:member(ssl, Opts) of
- true ->
- {ok, proc_lib:spawn_link(?MODULE, init_ssl,
- [Port, Module, Opts, []])};
- false ->
- {ok, proc_lib:spawn_link(?MODULE, init,
- [Port, Module, Opts])}
- end
- end.
-
-init(Port, Module, Opts) ->
- SockOpts = lists:filter(fun({ip, _}) -> true;
- (inet6) -> true;
- (inet) -> true;
- (_) -> false
- end, Opts),
-
- Res = gen_tcp:listen(Port, [binary,
- {packet, 0},
- {active, false},
- {reuseaddr, true},
- {nodelay, true},
- {keepalive, true} |
- SockOpts]),
- case Res of
- {ok, ListenSocket} ->
- accept(ListenSocket, Module, Opts);
- {error, Reason} ->
- ?ERROR_MSG("Failed to open socket for ~p: ~p",
- [{Port, Module, Opts}, Reason]),
- error
- end.
-
-accept(ListenSocket, Module, Opts) ->
- case gen_tcp:accept(ListenSocket) of
- {ok, Socket} ->
- case {inet:sockname(Socket), inet:peername(Socket)} of
- {{ok, Addr}, {ok, PAddr}} ->
- ?INFO_MSG("(~w) Accepted connection ~w -> ~w",
- [Socket, PAddr, Addr]);
- _ ->
- ok
- end,
- {ok, Pid} = Module:start({gen_tcp, Socket}, Opts),
- case gen_tcp:controlling_process(Socket, Pid) of
- ok ->
- ok;
- {error, _Reason} ->
- gen_tcp:close(Socket)
- end,
- Module:become_controller(Pid),
- accept(ListenSocket, Module, Opts);
- {error, Reason} ->
- ?INFO_MSG("(~w) Failed TCP accept: ~w",
- [ListenSocket, Reason]),
- accept(ListenSocket, Module, Opts)
- end.
-
-
-init_ssl(Port, Module, Opts, SSLOpts) ->
- SockOpts = lists:filter(fun({ip, _}) -> true;
- (inet6) -> true;
- (inet) -> true;
- ({verify, _}) -> true;
- ({depth, _}) -> true;
- ({certfile, _}) -> true;
- ({keyfile, _}) -> true;
- ({password, _}) -> true;
- ({cacertfile, _}) -> true;
- ({ciphers, _}) -> true;
- (_) -> false
- end, Opts),
- Res = ssl:listen(Port, [binary,
- {packet, 0},
- {active, false},
- {nodelay, true} |
- SockOpts ++ SSLOpts]),
- case Res of
- {ok, ListenSocket} ->
- accept_ssl(ListenSocket, Module, Opts);
- {error, Reason} ->
- ?ERROR_MSG("Failed to open socket for ~p: ~p",
- [{Port, Module, Opts}, Reason]),
- error
- end.
-
-accept_ssl(ListenSocket, Module, Opts) ->
- case ssl:accept(ListenSocket, 200) of
- {ok, Socket} ->
- case {ssl:sockname(Socket), ssl:peername(Socket)} of
- {{ok, Addr}, {ok, PAddr}} ->
- ?INFO_MSG("(~w) Accepted SSL connection ~w -> ~w",
- [Socket, PAddr, Addr]);
- _ ->
- ok
- end,
- {ok, Pid} = Module:start({ssl, Socket}, Opts),
- catch ssl:controlling_process(Socket, Pid),
- Module:become_controller(Pid),
- accept_ssl(ListenSocket, Module, Opts);
- {error, timeout} ->
- accept_ssl(ListenSocket, Module, Opts);
- {error, Reason} ->
- ?INFO_MSG("(~w) Failed SSL handshake: ~w",
- [ListenSocket, Reason]),
- accept_ssl(ListenSocket, Module, Opts)
- end.
-
-
-start_listener(Port, Module, Opts) ->
- ChildSpec = {Port,
- {?MODULE, start, [Port, Module, Opts]},
- transient,
- brutal_kill,
- worker,
- [?MODULE]},
- supervisor:start_child(ejabberd_listeners, ChildSpec).
-
-stop_listener(Port) ->
- supervisor:terminate_child(ejabberd_listeners, Port),
- supervisor:delete_child(ejabberd_listeners, Port).
-
-add_listener(Port, Module, Opts) ->
- Ports = case ejabberd_config:get_local_option(listen) of
- undefined ->
- [];
- Ls ->
- Ls
- end,
- Ports1 = lists:keydelete(Port, 1, Ports),
- Ports2 = [{Port, Module, Opts} | Ports1],
- ejabberd_config:add_local_option(listen, Ports2),
- start_listener(Port, Module, Opts).
-
-delete_listener(Port) ->
- Ports = case ejabberd_config:get_local_option(listen) of
- undefined ->
- [];
- Ls ->
- Ls
- end,
- Ports1 = lists:keydelete(Port, 1, Ports),
- ejabberd_config:add_local_option(listen, Ports1),
- stop_listener(Port).
-
diff --git a/ejabberd-1.1.2/src/ejabberd_local.erl b/ejabberd-1.1.2/src/ejabberd_local.erl
deleted file mode 100644
index afb5332a7..000000000
--- a/ejabberd-1.1.2/src/ejabberd_local.erl
+++ /dev/null
@@ -1,245 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_local.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Route local packets
-%%% Created : 30 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_local).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
-
-%% API
--export([start_link/0]).
-
--export([route/3,
- register_iq_handler/4,
- register_iq_handler/5,
- unregister_iq_handler/2,
- refresh_iq_handlers/0,
- bounce_resource_packet/3
- ]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--record(state, {}).
-
--define(IQTABLE, local_iqtable).
-
-%%====================================================================
-%% API
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the server
-%%--------------------------------------------------------------------
-start_link() ->
- gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-
-process_iq(From, To, Packet) ->
- IQ = jlib:iq_query_info(Packet),
- case IQ of
- #iq{xmlns = XMLNS} ->
- Host = To#jid.lserver,
- case ets:lookup(?IQTABLE, {XMLNS, Host}) of
- [{_, Module, Function}] ->
- ResIQ = Module:Function(From, To, IQ),
- if
- ResIQ /= ignore ->
- ejabberd_router:route(
- To, From, jlib:iq_to_xml(ResIQ));
- true ->
- ok
- end;
- [{_, Module, Function, Opts}] ->
- gen_iq_handler:handle(Host, Module, Function, Opts,
- From, To, IQ);
- [] ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
- ejabberd_router:route(To, From, Err)
- end;
- reply ->
- ok;
- _ ->
- Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
- ejabberd_router:route(To, From, Err),
- ok
- end.
-
-route(From, To, Packet) ->
- case catch do_route(From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~nwhen processing: ~p",
- [Reason, {From, To, Packet}]);
- _ ->
- ok
- end.
-
-register_iq_handler(Host, XMLNS, Module, Fun) ->
- ejabberd_local ! {register_iq_handler, Host, XMLNS, Module, Fun}.
-
-register_iq_handler(Host, XMLNS, Module, Fun, Opts) ->
- ejabberd_local ! {register_iq_handler, Host, XMLNS, Module, Fun, Opts}.
-
-unregister_iq_handler(Host, XMLNS) ->
- ejabberd_local ! {unregister_iq_handler, Host, XMLNS}.
-
-refresh_iq_handlers() ->
- ejabberd_local ! refresh_iq_handlers.
-
-bounce_resource_packet(From, To, Packet) ->
- Err = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND),
- ejabberd_router:route(To, From, Err),
- stop.
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% Description: Initiates the server
-%%--------------------------------------------------------------------
-init([]) ->
- lists:foreach(
- fun(Host) ->
- ejabberd_router:register_route(Host, {apply, ?MODULE, route}),
- ejabberd_hooks:add(local_send_to_resource_hook, Host,
- ?MODULE, bounce_resource_packet, 100)
- end, ?MYHOSTS),
- catch ets:new(?IQTABLE, [named_table, public]),
- {ok, #state{}}.
-
-%%--------------------------------------------------------------------
-%% 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(_Request, _From, State) ->
- Reply = ok,
- {reply, Reply, 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) ->
- case catch do_route(From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~nwhen processing: ~p",
- [Reason, {From, To, Packet}]);
- _ ->
- ok
- end,
- {noreply, State};
-handle_info({register_iq_handler, Host, XMLNS, Module, Function}, State) ->
- ets:insert(?IQTABLE, {{XMLNS, Host}, Module, Function}),
- catch mod_disco:register_feature(Host, XMLNS),
- {noreply, State};
-handle_info({register_iq_handler, Host, XMLNS, Module, Function, Opts}, State) ->
- ets:insert(?IQTABLE, {{XMLNS, Host}, Module, Function, Opts}),
- catch mod_disco:register_feature(Host, XMLNS),
- {noreply, State};
-handle_info({unregister_iq_handler, Host, XMLNS}, State) ->
- case ets:lookup(?IQTABLE, {XMLNS, Host}) of
- [{_, Module, Function, Opts}] ->
- gen_iq_handler:stop_iq_handler(Module, Function, Opts);
- _ ->
- ok
- end,
- ets:delete(?IQTABLE, {XMLNS, Host}),
- catch mod_disco:unregister_feature(Host, XMLNS),
- {noreply, State};
-handle_info(refresh_iq_handlers, State) ->
- lists:foreach(
- fun(T) ->
- case T of
- {{XMLNS, Host}, _Module, _Function, _Opts} ->
- catch mod_disco:register_feature(Host, XMLNS);
- {{XMLNS, Host}, _Module, _Function} ->
- catch mod_disco:register_feature(Host, XMLNS);
- _ ->
- ok
- end
- end, ets:tab2list(?IQTABLE)),
- {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) ->
- 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
-%%--------------------------------------------------------------------
-do_route(From, To, Packet) ->
- ?DEBUG("local route~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
- [From, To, Packet, 8]),
- if
- To#jid.luser /= "" ->
- ejabberd_sm:route(From, To, Packet);
- To#jid.lresource == "" ->
- {xmlelement, Name, _Attrs, _Els} = Packet,
- case Name of
- "iq" ->
- process_iq(From, To, Packet);
- "message" ->
- ok;
- "presence" ->
- ok;
- _ ->
- ok
- end;
- true ->
- {xmlelement, _Name, Attrs, _Els} = Packet,
- case xml:get_attr_s("type", Attrs) of
- "error" -> ok;
- "result" -> ok;
- _ ->
- ejabberd_hooks:run(local_send_to_resource_hook,
- To#jid.lserver,
- [From, To, Packet])
- end
- end.
-
diff --git a/ejabberd-1.1.2/src/ejabberd_logger_h.erl b/ejabberd-1.1.2/src/ejabberd_logger_h.erl
deleted file mode 100644
index 975a9b25f..000000000
--- a/ejabberd-1.1.2/src/ejabberd_logger_h.erl
+++ /dev/null
@@ -1,206 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_logger_h.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 23 Oct 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%%----------------------------------------------------------------------
-
--module(ejabberd_logger_h).
--author('alexey@sevcom.net').
-
-%%-compile(export_all).
-%%-export([Function/Arity, ...]).
-
--behaviour(gen_event).
-
-%% gen_event callbacks
--export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2,
- code_change/3, reopen_log/0]).
-
--record(state, {fd, file}).
-
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_event
-%%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, State} |
-%% Other
-%%----------------------------------------------------------------------
-init(File) ->
- case file:open(File, [append, raw]) of
- {ok, Fd} ->
- {ok, #state{fd = Fd, file = File}};
- Error ->
- Error
- end.
-
-%%----------------------------------------------------------------------
-%% Func: handle_event/2
-%% Returns: {ok, State} |
-%% {swap_handler, Args1, State1, Mod2, Args2} |
-%% remove_handler
-%%----------------------------------------------------------------------
-handle_event(Event, State) ->
- write_event(State#state.fd, {erlang:localtime(), Event}),
- {ok, State}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_call/2
-%% Returns: {ok, Reply, State} |
-%% {swap_handler, Reply, Args1, State1, Mod2, Args2} |
-%% {remove_handler, Reply}
-%%----------------------------------------------------------------------
-handle_call(_Request, State) ->
- Reply = ok,
- {ok, Reply, State}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/2
-%% Returns: {ok, State} |
-%% {swap_handler, Args1, State1, Mod2, Args2} |
-%% remove_handler
-%%----------------------------------------------------------------------
-handle_info({'EXIT', _Fd, _Reason}, _State) ->
- remove_handler;
-handle_info({emulator, _GL, reopen}, State) ->
- file:close(State#state.fd),
- rotate_log(State#state.file),
- case file:open(State#state.file, [append, raw]) of
- {ok, Fd} ->
- {ok, State#state{fd = Fd}};
- Error ->
- Error
- end;
-handle_info({emulator, GL, Chars}, State) ->
- write_event(State#state.fd, {erlang:localtime(), {emulator, GL, Chars}}),
- {ok, State};
-handle_info(_Info, State) ->
- {ok, State}.
-
-%%----------------------------------------------------------------------
-%% Func: terminate/2
-%% Purpose: Shutdown the server
-%% Returns: any
-%%----------------------------------------------------------------------
-terminate(_Reason, _State) ->
- ok.
-
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-
-reopen_log() ->
- error_logger ! {emulator, noproc, reopen}.
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-
-% Copied from erlang_logger_file_h.erl
-write_event(Fd, {Time, {error, _GL, {Pid, Format, Args}}}) ->
- T = write_time(Time),
- case catch io_lib:format(add_node(Format,Pid), Args) of
- S when list(S) ->
- file:write(Fd, io_lib:format(T ++ S, []));
- _ ->
- F = add_node("ERROR: ~p - ~p~n", Pid),
- file:write(Fd, io_lib:format(T ++ F, [Format,Args]))
- end;
-write_event(Fd, {Time, {emulator, _GL, Chars}}) ->
- T = write_time(Time),
- case catch io_lib:format(Chars, []) of
- S when list(S) ->
- file:write(Fd, io_lib:format(T ++ S, []));
- _ ->
- file:write(Fd, io_lib:format(T ++ "ERROR: ~p ~n", [Chars]))
- end;
-write_event(Fd, {Time, {info, _GL, {Pid, Info, _}}}) ->
- T = write_time(Time),
- file:write(Fd, io_lib:format(T ++ add_node("~p~n",Pid), [Info]));
-write_event(Fd, {Time, {error_report, _GL, {Pid, std_error, Rep}}}) ->
- T = write_time(Time),
- S = format_report(Rep),
- file:write(Fd, io_lib:format(T ++ S ++ add_node("", Pid), []));
-write_event(Fd, {Time, {info_report, _GL, {Pid, std_info, Rep}}}) ->
- T = write_time(Time, "INFO REPORT"),
- S = format_report(Rep),
- file:write(Fd, io_lib:format(T ++ S ++ add_node("", Pid), []));
-write_event(Fd, {Time, {info_msg, _GL, {Pid, Format, Args}}}) ->
- T = write_time(Time, "INFO REPORT"),
- case catch io_lib:format(add_node(Format,Pid), Args) of
- S when list(S) ->
- file:write(Fd, io_lib:format(T ++ S, []));
- _ ->
- F = add_node("ERROR: ~p - ~p~n", Pid),
- file:write(Fd, io_lib:format(T ++ F, [Format,Args]))
- end;
-write_event(_, _) ->
- ok.
-
-format_report(Rep) when list(Rep) ->
- case string_p(Rep) of
- true ->
- io_lib:format("~s~n",[Rep]);
- _ ->
- format_rep(Rep)
- end;
-format_report(Rep) ->
- io_lib:format("~p~n",[Rep]).
-
-format_rep([{Tag,Data}|Rep]) ->
- io_lib:format(" ~p: ~p~n",[Tag,Data]) ++ format_rep(Rep);
-format_rep([Other|Rep]) ->
- io_lib:format(" ~p~n",[Other]) ++ format_rep(Rep);
-format_rep(_) ->
- [].
-
-add_node(X, Pid) when atom(X) ->
- add_node(atom_to_list(X), Pid);
-add_node(X, Pid) when node(Pid) /= node() ->
- lists:concat([X,"** at node ",node(Pid)," **~n"]);
-add_node(X, _) ->
- X.
-
-string_p([]) ->
- false;
-string_p(Term) ->
- string_p1(Term).
-
-string_p1([H|T]) when integer(H), H >= $\s, H < 255 ->
- string_p1(T);
-string_p1([$\n|T]) -> string_p1(T);
-string_p1([$\r|T]) -> string_p1(T);
-string_p1([$\t|T]) -> string_p1(T);
-string_p1([$\v|T]) -> string_p1(T);
-string_p1([$\b|T]) -> string_p1(T);
-string_p1([$\f|T]) -> string_p1(T);
-string_p1([$\e|T]) -> string_p1(T);
-string_p1([H|T]) when list(H) ->
- case string_p1(H) of
- true -> string_p1(T);
- _ -> false
- end;
-string_p1([]) -> true;
-string_p1(_) -> false.
-
-write_time(Time) -> write_time(Time, "ERROR REPORT").
-
-write_time({{Y,Mo,D},{H,Mi,S}}, Type) ->
- io_lib:format("~n=~s==== ~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w ===~n",
- [Type, Y, Mo, D, H, Mi, S]).
-
-%% Rename the log file if it the filename exists
-%% This is needed in systems when the file must be closed before rotation (Windows).
-%% On most Unix-like system, the file can be renamed from the command line and
-%%the log can directly be reopened.
-rotate_log(Filename) ->
- case file:read_file_info(Filename) of
- {ok, _FileInfo} ->
- RotationName = filename:rootname(Filename),
- file:rename(Filename, [RotationName, "-old.log"]),
- ok;
- {error, _Reason} ->
- ok
- end.
-
diff --git a/ejabberd-1.1.2/src/ejabberd_receiver.erl b/ejabberd-1.1.2/src/ejabberd_receiver.erl
deleted file mode 100644
index 9591bd9c0..000000000
--- a/ejabberd-1.1.2/src/ejabberd_receiver.erl
+++ /dev/null
@@ -1,272 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_receiver.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Socket receiver for C2S and S2S connections
-%%% Created : 10 Nov 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_receiver).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
-
-%% API
--export([start_link/5,
- start/3,
- start/4,
- change_shaper/2,
- reset_stream/1,
- starttls/2,
- compress/2,
- become_controller/1,
- close/1]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--include("ejabberd.hrl").
-
--record(state, {socket,
- sock_mod,
- shaper_state,
- c2s_pid,
- max_stanza_size,
- xml_stream_state,
- timeout}).
-
-%%====================================================================
-%% API
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the server
-%%--------------------------------------------------------------------
-start_link(Socket, SockMod, Shaper, MaxStanzaSize, C2SPid) ->
- gen_server:start_link(
- ?MODULE, [Socket, SockMod, Shaper, MaxStanzaSize, C2SPid], []).
-
-%%--------------------------------------------------------------------
-%% Function: start() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the server
-%%--------------------------------------------------------------------
-start(Socket, SockMod, Shaper) ->
- start(Socket, SockMod, Shaper, infinity).
-
-start(Socket, SockMod, Shaper, MaxStanzaSize) ->
- {ok, Pid} = supervisor:start_child(
- ejabberd_receiver_sup,
- [Socket, SockMod, Shaper, MaxStanzaSize, self()]),
- Pid.
-
-change_shaper(Pid, Shaper) ->
- gen_server:cast(Pid, {change_shaper, Shaper}).
-
-reset_stream(Pid) ->
- gen_server:call(Pid, reset_stream).
-
-starttls(Pid, TLSSocket) ->
- gen_server:call(Pid, {starttls, TLSSocket}).
-
-compress(Pid, ZlibSocket) ->
- gen_server:call(Pid, {compress, ZlibSocket}).
-
-become_controller(Pid) ->
- gen_server:call(Pid, become_controller).
-
-close(Pid) ->
- gen_server:cast(Pid, close).
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% Description: Initiates the server
-%%--------------------------------------------------------------------
-init([Socket, SockMod, Shaper, MaxStanzaSize, C2SPid]) ->
- XMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
- ShaperState = shaper:new(Shaper),
- Timeout = case SockMod of
- ssl ->
- 20;
- _ ->
- infinity
- end,
- {ok, #state{socket = Socket,
- sock_mod = SockMod,
- shaper_state = ShaperState,
- c2s_pid = C2SPid,
- max_stanza_size = MaxStanzaSize,
- xml_stream_state = XMLStreamState,
- timeout = Timeout}}.
-
-%%--------------------------------------------------------------------
-%% 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({starttls, TLSSocket}, _From,
- #state{xml_stream_state = XMLStreamState,
- c2s_pid = C2SPid,
- max_stanza_size = MaxStanzaSize} = State) ->
- xml_stream:close(XMLStreamState),
- NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
- NewState = State#state{socket = TLSSocket,
- sock_mod = tls,
- xml_stream_state = NewXMLStreamState},
- case tls:recv_data(TLSSocket, "") of
- {ok, TLSData} ->
- {reply, ok, process_data(TLSData, NewState)};
- {error, _Reason} ->
- {stop, normal, ok, NewState}
- end;
-handle_call({compress, ZlibSocket}, _From,
- #state{xml_stream_state = XMLStreamState,
- c2s_pid = C2SPid,
- max_stanza_size = MaxStanzaSize} = State) ->
- xml_stream:close(XMLStreamState),
- NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
- NewState = State#state{socket = ZlibSocket,
- sock_mod = ejabberd_zlib,
- xml_stream_state = NewXMLStreamState},
- case ejabberd_zlib:recv_data(ZlibSocket, "") of
- {ok, ZlibData} ->
- {reply, ok, process_data(ZlibData, NewState)};
- {error, _Reason} ->
- {stop, normal, ok, NewState}
- end;
-handle_call(reset_stream, _From,
- #state{xml_stream_state = XMLStreamState,
- c2s_pid = C2SPid,
- max_stanza_size = MaxStanzaSize} = State) ->
- xml_stream:close(XMLStreamState),
- NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
- Reply = ok,
- {reply, Reply, State#state{xml_stream_state = NewXMLStreamState}};
-handle_call(become_controller, _From, State) ->
- activate_socket(State),
- Reply = ok,
- {reply, Reply, State};
-handle_call(_Request, _From, State) ->
- Reply = ok,
- {reply, Reply, State}.
-
-%%--------------------------------------------------------------------
-%% Function: handle_cast(Msg, State) -> {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State}
-%% Description: Handling cast messages
-%%--------------------------------------------------------------------
-handle_cast({change_shaper, Shaper}, State) ->
- NewShaperState = shaper:new(Shaper),
- {noreply, State#state{shaper_state = NewShaperState}};
-handle_cast(close, State) ->
- {stop, normal, State};
-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({Tag, _TCPSocket, Data},
- #state{socket = Socket,
- sock_mod = SockMod} = State)
- when (Tag == tcp) or (Tag == ssl) ->
- case SockMod of
- tls ->
- case tls:recv_data(Socket, Data) of
- {ok, TLSData} ->
- {noreply, process_data(TLSData, State)};
- {error, _Reason} ->
- {stop, normal, State}
- end;
- ejabberd_zlib ->
- case ejabberd_zlib:recv_data(Socket, Data) of
- {ok, ZlibData} ->
- {noreply, process_data(ZlibData, State)};
- {error, _Reason} ->
- {stop, normal, State}
- end;
- _ ->
- {noreply, process_data(Data, State)}
- end;
-handle_info({Tag, _TCPSocket}, State)
- when (Tag == tcp_closed) or (Tag == ssl_closed) ->
- {stop, normal, State};
-handle_info({Tag, _TCPSocket, Reason}, State)
- when (Tag == tcp_error) or (Tag == ssl_error) ->
- case Reason of
- timeout ->
- {noreply, State};
- _ ->
- {stop, normal, State}
- end;
-handle_info({timeout, _Ref, activate}, State) ->
- activate_socket(State),
- {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{xml_stream_state = XMLStreamState,
- c2s_pid = C2SPid} = State) ->
- xml_stream:close(XMLStreamState),
- gen_fsm:send_event(C2SPid, closed),
- catch (State#state.sock_mod):close(State#state.socket),
- 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
-%%--------------------------------------------------------------------
-
-activate_socket(#state{socket = Socket,
- sock_mod = SockMod}) ->
- case SockMod of
- gen_tcp ->
- inet:setopts(Socket, [{active, once}]);
- _ ->
- SockMod:setopts(Socket, [{active, once}])
- end.
-
-process_data(Data,
- #state{xml_stream_state = XMLStreamState,
- shaper_state = ShaperState} = State) ->
- ?DEBUG("Received XML on stream = ~p", [binary_to_list(Data)]),
- XMLStreamState1 = xml_stream:parse(XMLStreamState, Data),
- {NewShaperState, Pause} = shaper:update(ShaperState, size(Data)),
- if
- Pause > 0 ->
- erlang:start_timer(Pause, self(), activate);
- true ->
- activate_socket(State)
- end,
- State#state{xml_stream_state = XMLStreamState1,
- shaper_state = NewShaperState}.
-
diff --git a/ejabberd-1.1.2/src/ejabberd_router.erl b/ejabberd-1.1.2/src/ejabberd_router.erl
deleted file mode 100644
index 5e3127f9f..000000000
--- a/ejabberd-1.1.2/src/ejabberd_router.erl
+++ /dev/null
@@ -1,285 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_router.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Main router
-%%% Created : 27 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_router).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
-
-%% API
--export([route/3,
- register_route/1,
- register_route/2,
- register_routes/1,
- unregister_route/1,
- unregister_routes/1,
- dirty_get_all_routes/0,
- dirty_get_all_domains/0
- ]).
-
--export([start_link/0]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--record(route, {domain, pid, local_hint}).
--record(state, {}).
-
-%%====================================================================
-%% API
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the server
-%%--------------------------------------------------------------------
-start_link() ->
- gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-
-
-route(From, To, Packet) ->
- case catch do_route(From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~nwhen processing: ~p",
- [Reason, {From, To, Packet}]);
- _ ->
- ok
- end.
-
-register_route(Domain) ->
- case jlib:nameprep(Domain) of
- error ->
- [] = {invalid_domain, Domain};
- LDomain ->
- Pid = self(),
- F = fun() ->
- mnesia:write(#route{domain = LDomain,
- pid = Pid})
- end,
- mnesia:transaction(F)
- end.
-
-register_route(Domain, LocalHint) ->
- case jlib:nameprep(Domain) of
- error ->
- [] = {invalid_domain, Domain};
- LDomain ->
- Pid = self(),
- F = fun() ->
- mnesia:write(#route{domain = LDomain,
- pid = Pid,
- local_hint = LocalHint})
- end,
- mnesia:transaction(F)
- end.
-
-register_routes(Domains) ->
- lists:foreach(fun(Domain) ->
- register_route(Domain)
- end, Domains).
-
-unregister_route(Domain) ->
- case jlib:nameprep(Domain) of
- error ->
- [] = {invalid_domain, Domain};
- LDomain ->
- Pid = self(),
- F = fun() ->
- mnesia:delete_object(#route{domain = LDomain,
- pid = Pid})
- end,
- mnesia:transaction(F)
- end.
-
-unregister_routes(Domains) ->
- lists:foreach(fun(Domain) ->
- unregister_route(Domain)
- end, Domains).
-
-
-dirty_get_all_routes() ->
- lists:usort(mnesia:dirty_all_keys(route)) -- ?MYHOSTS.
-
-dirty_get_all_domains() ->
- lists:usort(mnesia:dirty_all_keys(route)).
-
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% Description: Initiates the server
-%%--------------------------------------------------------------------
-init([]) ->
- update_tables(),
- mnesia:create_table(route,
- [{ram_copies, [node()]},
- {type, bag},
- {attributes,
- record_info(fields, route)}]),
- mnesia:add_table_copy(route, node(), ram_copies),
- mnesia:subscribe({table, route, simple}),
- lists:foreach(
- fun(Pid) ->
- erlang:monitor(process, Pid)
- end,
- mnesia:dirty_select(route, [{{route, '_', '$1', '_'}, [], ['$1']}])),
- {ok, #state{}}.
-
-%%--------------------------------------------------------------------
-%% 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(_Request, _From, State) ->
- Reply = ok,
- {reply, Reply, 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) ->
- case catch do_route(From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~nwhen processing: ~p",
- [Reason, {From, To, Packet}]);
- _ ->
- ok
- end,
- {noreply, State};
-handle_info({mnesia_table_event, {write, #route{pid = Pid}, _ActivityId}},
- State) ->
- erlang:monitor(process, Pid),
- {noreply, State};
-handle_info({'DOWN', _Ref, _Type, Pid, _Info}, State) ->
- F = fun() ->
- Es = mnesia:select(
- route,
- [{#route{pid = Pid, _ = '_'},
- [],
- ['$_']}]),
- lists:foreach(fun(E) ->
- mnesia:delete_object(E)
- end, Es)
- end,
- mnesia:transaction(F),
- {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) ->
- 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
-%%--------------------------------------------------------------------
-do_route(OrigFrom, OrigTo, OrigPacket) ->
- ?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n",
- [OrigFrom, OrigTo, OrigPacket]),
- LOrigDstDomain = OrigTo#jid.lserver,
- case ejabberd_hooks:run_fold(filter_packet,
- {OrigFrom, OrigTo, OrigPacket}, []) of
- {From, To, Packet} ->
- LDstDomain = To#jid.lserver,
- case mnesia:dirty_read(route, LDstDomain) of
- [] ->
- ejabberd_s2s:route(From, To, Packet);
- [R] ->
- Pid = R#route.pid,
- if
- node(Pid) == node() ->
- case R#route.local_hint of
- {apply, Module, Function} ->
- Module:Function(From, To, Packet);
- _ ->
- Pid ! {route, From, To, Packet}
- end;
- true ->
- Pid ! {route, From, To, Packet}
- end;
- Rs ->
- case [R || R <- Rs, node(R#route.pid) == node()] of
- [] ->
- R = lists:nth(erlang:phash(now(), length(Rs)), Rs),
- Pid = R#route.pid,
- Pid ! {route, From, To, Packet};
- LRs ->
- LRs,
- R = lists:nth(erlang:phash(now(), length(LRs)), LRs),
- Pid = R#route.pid,
- case R#route.local_hint of
- {apply, Module, Function} ->
- Module:Function(From, To, Packet);
- _ ->
- Pid ! {route, From, To, Packet}
- end
- end
- end;
- drop ->
- ok
- end.
-
-
-
-update_tables() ->
- case catch mnesia:table_info(route, attributes) of
- [domain, node, pid] ->
- mnesia:delete_table(route);
- [domain, pid] ->
- mnesia:delete_table(route);
- [domain, pid, local_hint] ->
- ok;
- {'EXIT', _} ->
- ok
- end,
- case lists:member(local_route, mnesia:system_info(tables)) of
- true ->
- mnesia:delete_table(local_route);
- false ->
- ok
- end.
-
diff --git a/ejabberd-1.1.2/src/ejabberd_s2s.erl b/ejabberd-1.1.2/src/ejabberd_s2s.erl
deleted file mode 100644
index 9b1177292..000000000
--- a/ejabberd-1.1.2/src/ejabberd_s2s.erl
+++ /dev/null
@@ -1,277 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_s2s.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : S2S connections manager
-%%% Created : 7 Dec 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_s2s).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
-
-%% API
--export([start_link/0,
- route/3,
- have_connection/1,
- get_key/1,
- try_register/1,
- remove_connection/1,
- dirty_get_connections/0,
- ctl_process/2
- ]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include("ejabberd_ctl.hrl").
-
--record(s2s, {fromto, pid, key}).
--record(state, {}).
-
-%%====================================================================
-%% API
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the server
-%%--------------------------------------------------------------------
-start_link() ->
- gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-
-route(From, To, Packet) ->
- case catch do_route(From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~nwhen processing: ~p",
- [Reason, {From, To, Packet}]);
- _ ->
- ok
- end.
-
-remove_connection(FromTo) ->
- F = fun() ->
- mnesia:delete({s2s, FromTo})
- end,
- mnesia:transaction(F).
-
-have_connection(FromTo) ->
- case catch mnesia:dirty_read(s2s, FromTo) of
- [_] ->
- true;
- _ ->
- false
- end.
-
-get_key(FromTo) ->
- case catch mnesia:dirty_read(s2s, FromTo) of
- [E] ->
- E#s2s.key;
- _ ->
- error
- end.
-
-try_register(FromTo) ->
- Key = randoms:get_string(),
- F = fun() ->
- case mnesia:read({s2s, FromTo}) of
- [] ->
- mnesia:write(#s2s{fromto = FromTo,
- pid = self(),
- key = Key}),
- {key, Key};
- _ ->
- false
- end
- end,
- case mnesia:transaction(F) of
- {atomic, Res} ->
- Res;
- _ ->
- false
- end.
-
-dirty_get_connections() ->
- mnesia:dirty_all_keys(s2s).
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% Description: Initiates the server
-%%--------------------------------------------------------------------
-init([]) ->
- update_tables(),
- mnesia:create_table(s2s, [{ram_copies, [node()]},
- {attributes, record_info(fields, s2s)}]),
- mnesia:add_table_copy(s2s, node(), ram_copies),
- mnesia:subscribe(system),
- ejabberd_ctl:register_commands(
- [{"incoming-s2s-number", "print number of incoming s2s connections on the node"},
- {"outgoing-s2s-number", "print number of outgoing s2s connections on the node"}],
- ?MODULE, ctl_process),
- {ok, #state{}}.
-
-%%--------------------------------------------------------------------
-%% 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(_Request, _From, State) ->
- Reply = ok,
- {reply, Reply, 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({mnesia_system_event, {mnesia_down, Node}}, State) ->
- clean_table_from_bad_node(Node),
- {noreply, State};
-handle_info({route, From, To, Packet}, State) ->
- case catch do_route(From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~nwhen processing: ~p",
- [Reason, {From, To, Packet}]);
- _ ->
- 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) ->
- 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
-%%--------------------------------------------------------------------
-clean_table_from_bad_node(Node) ->
- F = fun() ->
- Es = mnesia:select(
- s2s,
- [{#s2s{pid = '$1', _ = '_'},
- [{'==', {node, '$1'}, Node}],
- ['$_']}]),
- lists:foreach(fun(E) ->
- mnesia:delete_object(E)
- end, Es)
- end,
- mnesia:transaction(F).
-
-do_route(From, To, Packet) ->
- ?DEBUG("s2s manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
- [From, To, Packet, 8]),
- case find_connection(From, To) of
- {atomic, Pid} when pid(Pid) ->
- ?DEBUG("sending to process ~p~n", [Pid]),
- % TODO
- {xmlelement, Name, Attrs, Els} = Packet,
- NewAttrs = jlib:replace_from_to_attrs(jlib:jid_to_string(From),
- jlib:jid_to_string(To),
- Attrs),
- send_element(Pid, {xmlelement, Name, NewAttrs, Els}),
- ok;
- {aborted, Reason} ->
- ?DEBUG("delivery failed: ~p~n", [Reason]),
- false
- end.
-
-find_connection(From, To) ->
- #jid{lserver = MyServer} = From,
- #jid{lserver = Server} = To,
- FromTo = {MyServer, Server},
- case catch mnesia:dirty_read(s2s, FromTo) of
- {'EXIT', Reason} ->
- {aborted, Reason};
- [] ->
- ?DEBUG("starting new s2s connection~n", []),
- Key = randoms:get_string(),
- {ok, Pid} = ejabberd_s2s_out:start(MyServer, Server, {new, Key}),
- F = fun() ->
- case mnesia:read({s2s, FromTo}) of
- [El] ->
- El#s2s.pid;
- [] ->
- mnesia:write(#s2s{fromto = FromTo,
- pid = Pid,
- key = Key}),
- Pid
- end
- end,
- TRes = mnesia:transaction(F),
- ejabberd_s2s_out:start_connection(Pid),
- TRes;
- [El] ->
- {atomic, El#s2s.pid}
- end.
-
-send_element(Pid, El) ->
- Pid ! {send_element, El}.
-
-ctl_process(_Val, ["incoming-s2s-number"]) ->
- N = length(supervisor:which_children(ejabberd_s2s_in_sup)),
- io:format("~p~n", [N]),
- {stop, ?STATUS_SUCCESS};
-ctl_process(_Val, ["outgoing-s2s-number"]) ->
- N = length(supervisor:which_children(ejabberd_s2s_out_sup)),
- io:format("~p~n", [N]),
- {stop, ?STATUS_SUCCESS};
-ctl_process(Val, _Args) ->
- Val.
-
-update_tables() ->
- case catch mnesia:table_info(s2s, attributes) of
- [fromto, node, key] ->
- mnesia:transform_table(s2s, ignore, [fromto, pid, key]),
- mnesia:clear_table(s2s);
- [fromto, pid, key] ->
- ok;
- {'EXIT', _} ->
- ok
- end,
- case lists:member(local_s2s, mnesia:system_info(tables)) of
- true ->
- mnesia:delete_table(local_s2s);
- false ->
- ok
- end.
-
diff --git a/ejabberd-1.1.2/src/ejabberd_s2s_in.erl b/ejabberd-1.1.2/src/ejabberd_s2s_in.erl
deleted file mode 100644
index 725421d1d..000000000
--- a/ejabberd-1.1.2/src/ejabberd_s2s_in.erl
+++ /dev/null
@@ -1,686 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_s2s_in.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Serve incoming s2s connection
-%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_s2s_in).
--author('alexey@sevcom.net').
-
--behaviour(gen_fsm).
-
-%% External exports
--export([start/2,
- start_link/2,
- become_controller/1,
- match_domain/2]).
-
-%% gen_fsm callbacks
--export([init/1,
- wait_for_stream/2,
- wait_for_feature_request/2,
- stream_established/2,
- handle_event/3,
- handle_sync_event/4,
- code_change/4,
- handle_info/3,
- terminate/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include_lib("ssl/include/PKIX1Explicit88.hrl").
--include_lib("ssl/include/PKIX1Implicit88.hrl").
--include("XmppAddr.hrl").
-
--define(DICT, dict).
-
--record(state, {socket,
- sockmod,
- receiver,
- streamid,
- shaper,
- tls = false,
- tls_enabled = false,
- tls_options = [],
- authenticated = false,
- auth_domain,
- connections = ?DICT:new(),
- timer}).
-
-
-%-define(DBGFSM, true).
-
--ifdef(DBGFSM).
--define(FSMOPTS, [{debug, [trace]}]).
--else.
--define(FSMOPTS, []).
--endif.
-
--define(STREAM_HEADER(Version),
- ("<?xml version='1.0'?>"
- "<stream:stream "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "xmlns='jabber:server' "
- "xmlns:db='jabber:server:dialback' "
- "id='" ++ StateData#state.streamid ++ "'" ++ Version ++ ">")
- ).
-
--define(STREAM_TRAILER, "</stream:stream>").
-
--define(INVALID_NAMESPACE_ERR,
- xml:element_to_string(?SERR_INVALID_NAMESPACE)).
-
--define(HOST_UNKNOWN_ERR,
- xml:element_to_string(?SERR_HOST_UNKNOWN)).
-
--define(INVALID_XML_ERR,
- xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-start(SockData, Opts) ->
- supervisor:start_child(ejabberd_s2s_in_sup, [SockData, Opts]).
-
-start_link(SockData, Opts) ->
- gen_fsm:start_link(ejabberd_s2s_in, [SockData, Opts], ?FSMOPTS).
-
-become_controller(Pid) ->
- gen_fsm:send_all_state_event(Pid, become_controller).
-
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_fsm
-%%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, StateName, StateData} |
-%% {ok, StateName, StateData, Timeout} |
-%% ignore |
-%% {stop, StopReason}
-%%----------------------------------------------------------------------
-init([{SockMod, Socket}, Opts]) ->
- ?INFO_MSG("started: ~p", [{SockMod, Socket}]),
- Shaper = case lists:keysearch(shaper, 1, Opts) of
- {value, {_, S}} -> S;
- _ -> none
- end,
- MaxStanzaSize =
- case lists:keysearch(max_stanza_size, 1, Opts) of
- {value, {_, Size}} -> Size;
- _ -> infinity
- end,
- ReceiverPid = ejabberd_receiver:start(
- Socket, SockMod, none, MaxStanzaSize),
- StartTLS = case ejabberd_config:get_local_option(s2s_use_starttls) of
- undefined ->
- false;
- UseStartTLS ->
- UseStartTLS
- end,
- TLSOpts = case ejabberd_config:get_local_option(s2s_certfile) of
- undefined ->
- [];
- CertFile ->
- [{certfile, CertFile}]
- end,
- Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
- {ok, wait_for_stream,
- #state{socket = Socket,
- sockmod = SockMod,
- receiver = ReceiverPid,
- streamid = new_id(),
- shaper = Shaper,
- tls = StartTLS,
- tls_enabled = false,
- tls_options = TLSOpts,
- timer = Timer}}.
-
-%%----------------------------------------------------------------------
-%% Func: StateName/2
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-
-wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
- case {xml:get_attr_s("xmlns", Attrs),
- xml:get_attr_s("xmlns:db", Attrs),
- xml:get_attr_s("version", Attrs) == "1.0"} of
- {"jabber:server", _, true} when
- StateData#state.tls and (not StateData#state.authenticated) ->
- send_text(StateData, ?STREAM_HEADER(" version='1.0'")),
- SASL =
- if
- StateData#state.tls_enabled ->
- case tls:get_peer_certificate(StateData#state.socket) of
- {ok, _Cert} ->
- case tls:get_verify_result(
- StateData#state.socket) of
- 0 ->
- [{xmlelement, "mechanisms",
- [{"xmlns", ?NS_SASL}],
- [{xmlelement, "mechanism", [],
- [{xmlcdata, "EXTERNAL"}]}]}];
- _ ->
- []
- end;
- error ->
- []
- end;
- true ->
- []
- end,
- StartTLS = if
- StateData#state.tls_enabled ->
- [];
- true ->
- [{xmlelement, "starttls",
- [{"xmlns", ?NS_TLS}], []}]
- end,
- send_element(StateData,
- {xmlelement, "stream:features", [],
- SASL ++ StartTLS}),
- {next_state, wait_for_feature_request, StateData};
- {"jabber:server", _, true} when
- StateData#state.authenticated ->
- send_text(StateData, ?STREAM_HEADER(" version='1.0'")),
- send_element(StateData,
- {xmlelement, "stream:features", [], []}),
- {next_state, stream_established, StateData};
- {"jabber:server", "jabber:server:dialback", _} ->
- send_text(StateData, ?STREAM_HEADER("")),
- {next_state, stream_established, StateData};
- _ ->
- send_text(StateData, ?INVALID_NAMESPACE_ERR),
- {stop, normal, StateData}
- end;
-
-wait_for_stream({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?STREAM_HEADER("") ++ ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_stream(timeout, StateData) ->
- {stop, normal, StateData};
-
-wait_for_stream(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-wait_for_feature_request({xmlstreamelement, El}, StateData) ->
- {xmlelement, Name, Attrs, Els} = El,
- TLS = StateData#state.tls,
- TLSEnabled = StateData#state.tls_enabled,
- SockMod = StateData#state.sockmod,
- case {xml:get_attr_s("xmlns", Attrs), Name} of
- {?NS_TLS, "starttls"} when TLS == true,
- TLSEnabled == false,
- SockMod == gen_tcp ->
- ?INFO_MSG("starttls", []),
- Socket = StateData#state.socket,
- TLSOpts = StateData#state.tls_options,
- {ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
- ejabberd_receiver:starttls(StateData#state.receiver, TLSSocket),
- send_element(StateData,
- {xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []}),
- {next_state, wait_for_stream,
- StateData#state{sockmod = tls,
- socket = TLSSocket,
- streamid = new_id(),
- tls_enabled = true
- }};
- {?NS_SASL, "auth"} when TLSEnabled ->
- Mech = xml:get_attr_s("mechanism", Attrs),
- case Mech of
- "EXTERNAL" ->
- Auth = jlib:decode_base64(xml:get_cdata(Els)),
- AuthDomain = jlib:nameprep(Auth),
- AuthRes =
- case tls:get_peer_certificate(StateData#state.socket) of
- {ok, Cert} ->
- case tls:get_verify_result(
- StateData#state.socket) of
- 0 ->
- case AuthDomain of
- error ->
- false;
- _ ->
- case idna:domain_utf8_to_ascii(AuthDomain) of
- false ->
- false;
- PCAuthDomain ->
- lists:any(
- fun(D) ->
- match_domain(
- PCAuthDomain, D)
- end, get_cert_domains(Cert))
- end
- end;
- _ ->
- false
- end;
- error ->
- false
- end,
- if
- AuthRes ->
- ejabberd_receiver:reset_stream(
- StateData#state.receiver),
- send_element(StateData,
- {xmlelement, "success",
- [{"xmlns", ?NS_SASL}], []}),
- ?INFO_MSG("(~w) Accepted s2s authentication for ~s",
- [StateData#state.socket, AuthDomain]),
- {next_state, wait_for_stream,
- StateData#state{streamid = new_id(),
- authenticated = true,
- auth_domain = AuthDomain
- }};
- true ->
- send_element(StateData,
- {xmlelement, "failure",
- [{"xmlns", ?NS_SASL}], []}),
- send_text(StateData, ?STREAM_TRAILER),
- {stop, normal, StateData}
- end;
- _ ->
- send_element(StateData,
- {xmlelement, "failure",
- [{"xmlns", ?NS_SASL}],
- [{xmlelement, "invalid-mechanism", [], []}]}),
- {stop, normal, StateData}
- end;
- _ ->
- stream_established({xmlstreamelement, El}, StateData)
- end;
-
-wait_for_feature_request({xmlstreamend, _Name}, StateData) ->
- send_text(StateData, ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_feature_request({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_feature_request(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-stream_established({xmlstreamelement, El}, StateData) ->
- cancel_timer(StateData#state.timer),
- Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
- case is_key_packet(El) of
- {key, To, From, Id, Key} ->
- ?INFO_MSG("GET KEY: ~p", [{To, From, Id, Key}]),
- LTo = jlib:nameprep(To),
- LFrom = jlib:nameprep(From),
- case lists:member(LTo, ejabberd_router:dirty_get_all_domains()) of
- true ->
- ejabberd_s2s_out:start(To, From,
- {verify, self(),
- Key, StateData#state.streamid}),
- Conns = ?DICT:store({LFrom, LTo}, wait_for_verification,
- StateData#state.connections),
- change_shaper(StateData, LTo, jlib:make_jid("", LFrom, "")),
- {next_state,
- stream_established,
- StateData#state{connections = Conns,
- timer = Timer}};
- _ ->
- send_text(StateData, ?HOST_UNKNOWN_ERR),
- {stop, normal, StateData}
- end;
- {verify, To, From, Id, Key} ->
- ?INFO_MSG("VERIFY KEY: ~p", [{To, From, Id, Key}]),
- LTo = jlib:nameprep(To),
- LFrom = jlib:nameprep(From),
- Key1 = ejabberd_s2s:get_key({LTo, LFrom}),
- Type = if Key == Key1 -> "valid";
- true -> "invalid"
- end,
- send_element(StateData,
- {xmlelement,
- "db:verify",
- [{"from", To},
- {"to", From},
- {"id", Id},
- {"type", Type}],
- []}),
- {next_state, stream_established, StateData#state{timer = Timer}};
- _ ->
- NewEl = jlib:remove_attr("xmlns", El),
- {xmlelement, Name, Attrs, _Els} = NewEl,
- From_s = xml:get_attr_s("from", Attrs),
- From = jlib:string_to_jid(From_s),
- To_s = xml:get_attr_s("to", Attrs),
- To = jlib:string_to_jid(To_s),
- if
- (To /= error) and (From /= error) ->
- LFrom = From#jid.lserver,
- LTo = To#jid.lserver,
- if
- StateData#state.authenticated ->
- case (LFrom == StateData#state.auth_domain)
- andalso
- lists:member(
- LTo,
- ejabberd_router:dirty_get_all_domains()) of
- true ->
- if ((Name == "iq") or
- (Name == "message") or
- (Name == "presence")) ->
- ejabberd_router:route(
- From, To, NewEl);
- true ->
- error
- end;
- false ->
- error
- end;
- true ->
- case ?DICT:find({LFrom, LTo},
- StateData#state.connections) of
- {ok, established} ->
- if ((Name == "iq") or
- (Name == "message") or
- (Name == "presence")) ->
- ejabberd_router:route(
- From, To, NewEl);
- true ->
- error
- end;
- _ ->
- error
- end
- end;
- true ->
- error
- end,
- {next_state, stream_established, StateData#state{timer = Timer}}
- end;
-
-stream_established({valid, From, To}, StateData) ->
- send_element(StateData,
- {xmlelement,
- "db:result",
- [{"from", To},
- {"to", From},
- {"type", "valid"}],
- []}),
- LFrom = jlib:nameprep(From),
- LTo = jlib:nameprep(To),
- NSD = StateData#state{
- connections = ?DICT:store({LFrom, LTo}, established,
- StateData#state.connections)},
- {next_state, stream_established, NSD};
-
-stream_established({invalid, From, To}, StateData) ->
- send_element(StateData,
- {xmlelement,
- "db:result",
- [{"from", To},
- {"to", From},
- {"type", "invalid"}],
- []}),
- LFrom = jlib:nameprep(From),
- LTo = jlib:nameprep(To),
- NSD = StateData#state{
- connections = ?DICT:erase({LFrom, LTo},
- StateData#state.connections)},
- {next_state, stream_established, NSD};
-
-stream_established({xmlstreamend, _Name}, StateData) ->
- {stop, normal, StateData};
-
-stream_established({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {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(become_controller, StateName, StateData) ->
- ok = (StateData#state.sockmod):controlling_process(
- StateData#state.socket,
- StateData#state.receiver),
- ejabberd_receiver:become_controller(StateData#state.receiver),
- {next_state, StateName, StateData};
-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}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/3
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-handle_info({send_text, Text}, StateName, StateData) ->
- send_text(StateData, Text),
- {next_state, StateName, StateData};
-
-handle_info({timeout, Timer, _}, _StateName,
- #state{timer = Timer} = StateData) ->
- {stop, normal, StateData};
-
-handle_info(_, StateName, StateData) ->
- {next_state, StateName, StateData}.
-
-
-%%----------------------------------------------------------------------
-%% Func: terminate/3
-%% Purpose: Shutdown the fsm
-%% Returns: any
-%%----------------------------------------------------------------------
-terminate(Reason, _StateName, StateData) ->
- ?INFO_MSG("terminated: ~p", [Reason]),
- ejabberd_receiver:close(StateData#state.receiver),
- ok.
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-
-send_text(StateData, Text) ->
- (StateData#state.sockmod):send(StateData#state.socket, Text).
-
-send_element(StateData, El) ->
- send_text(StateData, xml:element_to_string(El)).
-
-
-change_shaper(StateData, Host, JID) ->
- Shaper = acl:match_rule(Host, StateData#state.shaper, JID),
- ejabberd_receiver:change_shaper(StateData#state.receiver, Shaper).
-
-
-new_id() ->
- randoms:get_string().
-
-cancel_timer(Timer) ->
- erlang:cancel_timer(Timer),
- receive
- {timeout, Timer, _} ->
- ok
- after 0 ->
- ok
- end.
-
-
-is_key_packet({xmlelement, Name, Attrs, Els}) when Name == "db:result" ->
- {key,
- xml:get_attr_s("to", Attrs),
- xml:get_attr_s("from", Attrs),
- xml:get_attr_s("id", Attrs),
- xml:get_cdata(Els)};
-is_key_packet({xmlelement, Name, Attrs, Els}) when Name == "db:verify" ->
- {verify,
- xml:get_attr_s("to", Attrs),
- xml:get_attr_s("from", Attrs),
- xml:get_attr_s("id", Attrs),
- xml:get_cdata(Els)};
-is_key_packet(_) ->
- false.
-
-
-get_cert_domains(Cert) ->
- {rdnSequence, Subject} =
- (Cert#'Certificate'.tbsCertificate)#'TBSCertificate'.subject,
- Extensions =
- (Cert#'Certificate'.tbsCertificate)#'TBSCertificate'.extensions,
- lists:flatmap(
- fun(#'AttributeTypeAndValue'{type = ?'id-at-commonName',
- value = Val}) ->
- case 'PKIX1Explicit88':decode('X520CommonName', Val) of
- {ok, {_, D1}} ->
- D = if
- is_list(D1) -> D1;
- is_binary(D1) -> binary_to_list(D1);
- true -> error
- end,
- if
- D /= error ->
- case jlib:string_to_jid(D) of
- #jid{luser = "",
- lserver = LD,
- lresource = ""} ->
- [LD];
- _ ->
- []
- end;
- true ->
- []
- end;
- _ ->
- []
- end;
- (_) ->
- []
- end, lists:flatten(Subject)) ++
- lists:flatmap(
- fun(#'Extension'{extnID = ?'id-ce-subjectAltName',
- extnValue = Val}) ->
- BVal = if
- is_list(Val) -> list_to_binary(Val);
- is_binary(Val) -> Val;
- true -> Val
- end,
- case 'PKIX1Implicit88':decode('SubjectAltName', BVal) of
- {ok, SANs} ->
- lists:flatmap(
- fun({otherName,
- #'AnotherName'{'type-id' = ?'id-on-xmppAddr',
- value = XmppAddr
- }}) ->
- case 'XmppAddr':decode(
- 'XmppAddr', XmppAddr) of
- {ok, D} when is_binary(D) ->
- case jlib:string_to_jid(
- binary_to_list(D)) of
- #jid{luser = "",
- lserver = LD,
- lresource = ""} ->
- case idna:domain_utf8_to_ascii(LD) of
- false ->
- [];
- PCLD ->
- [PCLD]
- end;
- _ ->
- []
- end;
- _ ->
- []
- end;
- ({dNSName, D}) when is_list(D) ->
- case jlib:string_to_jid(D) of
- #jid{luser = "",
- lserver = LD,
- lresource = ""} ->
- [LD];
- _ ->
- []
- end;
- (_) ->
- []
- end, SANs);
- _ ->
- []
- end;
- (_) ->
- []
- end, Extensions).
-
-match_domain(Domain, Domain) ->
- true;
-match_domain(Domain, Pattern) ->
- DLabels = string:tokens(Domain, "."),
- PLabels = string:tokens(Pattern, "."),
- match_labels(DLabels, PLabels).
-
-match_labels([], []) ->
- true;
-match_labels([], [_ | _]) ->
- false;
-match_labels([_ | _], []) ->
- false;
-match_labels([DL | DLabels], [PL | PLabels]) ->
- case lists:all(fun(C) -> (($a =< C) andalso (C =< $z))
- orelse (($0 =< C) andalso (C =< $9))
- orelse (C == $-) orelse (C == $*)
- end, PL) of
- true ->
- Regexp = regexp:sh_to_awk(PL),
- case regexp:match(DL, Regexp) of
- {match, _, _} ->
- match_labels(DLabels, PLabels);
- _ ->
- false
- end;
- false ->
- false
- end.
-
-
diff --git a/ejabberd-1.1.2/src/ejabberd_s2s_out.erl b/ejabberd-1.1.2/src/ejabberd_s2s_out.erl
deleted file mode 100644
index 358abf5a3..000000000
--- a/ejabberd-1.1.2/src/ejabberd_s2s_out.erl
+++ /dev/null
@@ -1,857 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_s2s_out.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_s2s_out).
--author('alexey@sevcom.net').
-
--behaviour(gen_fsm).
-
-%% External exports
--export([start/3,
- start_link/3,
- start_connection/1]).
-
-%% gen_fsm callbacks
--export([init/1,
- open_socket/2,
- wait_for_stream/2,
- wait_for_validation/2,
- wait_for_features/2,
- wait_for_auth_result/2,
- wait_for_starttls_proceed/2,
- reopen_socket/2,
- stream_established/2,
- handle_event/3,
- handle_sync_event/4,
- handle_info/3,
- terminate/3,
- code_change/4,
- test_get_addr_port/1]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--record(state, {socket, receiver,
- sockmod,
- streamid,
- use_v10,
- tls = false,
- tls_required = false,
- tls_enabled = false,
- tls_options = [],
- authenticated = false,
- db_enabled = true,
- try_auth = true,
- myname, server, queue,
- new = false, verify = false,
- timer}).
-
-%-define(DBGFSM, true).
-
--ifdef(DBGFSM).
--define(FSMOPTS, [{debug, [trace]}]).
--else.
--define(FSMOPTS, []).
--endif.
-
--define(STREAM_HEADER,
- "<?xml version='1.0'?>"
- "<stream:stream "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "xmlns='jabber:server' "
- "xmlns:db='jabber:server:dialback' "
- "to='~s'~s>"
- ).
-
--define(STREAM_TRAILER, "</stream:stream>").
-
--define(INVALID_NAMESPACE_ERR,
- xml:element_to_string(?SERR_INVALID_NAMESPACE)).
-
--define(HOST_UNKNOWN_ERR,
- xml:element_to_string(?SERR_HOST_UNKNOWN)).
-
--define(INVALID_XML_ERR,
- xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-start(From, Host, Type) ->
- supervisor:start_child(ejabberd_s2s_out_sup, [From, Host, Type]).
-
-start_link(From, Host, Type) ->
- gen_fsm:start_link(ejabberd_s2s_out, [From, Host, Type], ?FSMOPTS).
-
-start_connection(Pid) ->
- gen_fsm:send_event(Pid, init).
-
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_fsm
-%%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, StateName, StateData} |
-%% {ok, StateName, StateData, Timeout} |
-%% ignore |
-%% {stop, StopReason}
-%%----------------------------------------------------------------------
-init([From, Server, Type]) ->
- ?INFO_MSG("started: ~p", [{From, Server, Type}]),
- TLS = case ejabberd_config:get_local_option(s2s_use_starttls) of
- undefined ->
- false;
- UseStartTLS ->
- UseStartTLS
- end,
- UseV10 = TLS,
- TLSOpts = case ejabberd_config:get_local_option(s2s_certfile) of
- undefined ->
- [];
- CertFile ->
- [{certfile, CertFile}, connect]
- end,
- {New, Verify} = case Type of
- {new, Key} ->
- {Key, false};
- {verify, Pid, Key, SID} ->
- start_connection(self()),
- {false, {Pid, Key, SID}}
- end,
- Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
- {ok, open_socket, #state{use_v10 = UseV10,
- tls = TLS,
- tls_options = TLSOpts,
- queue = queue:new(),
- myname = From,
- server = Server,
- new = New,
- verify = Verify,
- timer = Timer}}.
-
-%%----------------------------------------------------------------------
-%% Func: StateName/2
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-open_socket(init, StateData) ->
- AddrList = get_addr_port(StateData#state.server),
- case lists:foldl(fun({Addr, Port}, Acc) ->
- case Acc of
- {ok, Socket} ->
- {ok, Socket};
- _ ->
- open_socket1(Addr, Port)
- end
- end, {error, badarg}, AddrList) of
- {ok, Socket} ->
- ReceiverPid = ejabberd_receiver:start(Socket, gen_tcp, none),
- ok = gen_tcp:controlling_process(Socket, ReceiverPid),
- ejabberd_receiver:become_controller(ReceiverPid),
- Version = if
- StateData#state.use_v10 ->
- " version='1.0'";
- true ->
- ""
- end,
- NewStateData = StateData#state{socket = Socket,
- sockmod = gen_tcp,
- tls_enabled = false,
- receiver = ReceiverPid,
- streamid = new_id()},
- send_text(NewStateData, io_lib:format(?STREAM_HEADER,
- [StateData#state.server,
- Version])),
- {next_state, wait_for_stream, NewStateData};
- {error, _Reason} ->
- Error = ?ERR_REMOTE_SERVER_NOT_FOUND,
- bounce_messages(Error),
- {stop, normal, StateData}
- end;
-open_socket(_, StateData) ->
- {next_state, open_socket, StateData}.
-
-%%----------------------------------------------------------------------
-open_socket1(Addr, Port) ->
- Res = case idna:domain_utf8_to_ascii(Addr) of
- false -> {error, badarg};
- ASCIIAddr ->
- ?DEBUG("s2s_out: connecting to ~s:~p~n", [ASCIIAddr, Port]),
- case catch gen_tcp:connect(ASCIIAddr, Port,
- [binary, {packet, 0},
- {active, false}]) of
- {ok, _Socket} = R -> R;
- {error, Reason1} ->
- ?DEBUG("s2s_out: connect return ~p~n", [Reason1]),
- catch gen_tcp:connect(Addr, Port,
- [binary, {packet, 0},
- {active, false}, inet6]);
- {'EXIT', Reason1} ->
- ?DEBUG("s2s_out: connect crashed ~p~n", [Reason1]),
- catch gen_tcp:connect(Addr, Port,
- [binary, {packet, 0},
- {active, false}, inet6])
- end
- end,
- case Res of
- {ok, Socket} ->
- {ok, Socket};
- {error, Reason} ->
- ?DEBUG("s2s_out: inet6 connect return ~p~n", [Reason]),
- {error, Reason};
- {'EXIT', Reason} ->
- ?DEBUG("s2s_out: inet6 connect crashed ~p~n", [Reason]),
- {error, Reason}
- end.
-
-%%----------------------------------------------------------------------
-
-
-wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
- case {xml:get_attr_s("xmlns", Attrs),
- xml:get_attr_s("xmlns:db", Attrs),
- xml:get_attr_s("version", Attrs) == "1.0"} of
- {"jabber:server", "jabber:server:dialback", false} ->
- send_db_request(StateData);
- {"jabber:server", "jabber:server:dialback", true} when
- StateData#state.use_v10 ->
- {next_state, wait_for_features, StateData};
- {"jabber:server", "", true} when StateData#state.use_v10 ->
- {next_state, wait_for_features, StateData#state{db_enabled = false}};
- _ ->
- send_text(StateData, ?INVALID_NAMESPACE_ERR),
- {stop, normal, StateData}
- end;
-
-wait_for_stream({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_stream(timeout, StateData) ->
- {stop, normal, StateData};
-
-wait_for_stream(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-
-wait_for_validation({xmlstreamelement, El}, StateData) ->
- case is_verify_res(El) of
- {result, To, From, Id, Type} ->
- ?INFO_MSG("recv result: ~p", [{From, To, Id, Type}]),
- case Type of
- "valid" ->
- send_queue(StateData, StateData#state.queue),
- {next_state, stream_established,
- StateData#state{queue = queue:new()}};
- _ ->
- % TODO: bounce packets
- {stop, normal, StateData}
- end;
- {verify, To, From, Id, Type} ->
- ?INFO_MSG("recv verify: ~p", [{From, To, Id, Type}]),
- case StateData#state.verify of
- false ->
- {next_state, wait_for_validation, StateData};
- {Pid, _Key, _SID} ->
- case Type of
- "valid" ->
- gen_fsm:send_event(
- Pid, {valid,
- StateData#state.server,
- StateData#state.myname});
- _ ->
- gen_fsm:send_event(
- Pid, {invalid,
- StateData#state.server,
- StateData#state.myname})
- end,
- if
- StateData#state.verify == false ->
- {stop, normal, StateData};
- true ->
- {next_state, wait_for_validation, StateData}
- end
- end;
- _ ->
- {next_state, wait_for_validation, StateData}
- end;
-
-wait_for_validation({xmlstreamend, Name}, StateData) ->
- {stop, normal, StateData};
-
-wait_for_validation({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_validation(timeout, StateData) ->
- {stop, normal, StateData};
-
-wait_for_validation(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-wait_for_features({xmlstreamelement, El}, StateData) ->
- case El of
- {xmlelement, "stream:features", _Attrs, Els} ->
- {SASLEXT, StartTLS, StartTLSRequired} =
- lists:foldl(
- fun({xmlelement, "mechanisms", Attrs1, Els1} = El1,
- {SEXT, STLS, STLSReq} = Acc) ->
- case xml:get_attr_s("xmlns", Attrs1) of
- ?NS_SASL ->
- NewSEXT =
- lists:any(
- fun({xmlelement, "mechanism", _, Els2}) ->
- case xml:get_cdata(Els2) of
- "EXTERNAL" -> true;
- _ -> false
- end;
- (_) -> false
- end, Els1),
- {NewSEXT, STLS, STLSReq};
- _ ->
- Acc
- end;
- ({xmlelement, "starttls", Attrs1, Els1} = El1,
- {SEXT, STLS, STLSReq} = Acc) ->
- case xml:get_attr_s("xmlns", Attrs1) of
- ?NS_TLS ->
- Req = case xml:get_subtag(El1, "required") of
- {xmlelement, _, _, _} -> true;
- false -> false
- end,
- {SEXT, true, Req};
- _ ->
- Acc
- end;
- (_, Acc) ->
- Acc
- end, {false, false, false}, Els),
- if
- (not SASLEXT) and (not StartTLS) and
- StateData#state.authenticated ->
- send_queue(StateData, StateData#state.queue),
- {next_state, stream_established,
- StateData#state{queue = queue:new()}};
- SASLEXT and StateData#state.try_auth and
- (StateData#state.new /= false) ->
- send_element(StateData,
- {xmlelement, "auth",
- [{"xmlns", ?NS_SASL},
- {"mechanism", "EXTERNAL"}],
- [{xmlcdata,
- jlib:encode_base64(
- StateData#state.myname)}]}),
- {next_state, wait_for_auth_result,
- StateData#state{try_auth = false}};
- StartTLS and StateData#state.tls and
- (not StateData#state.tls_enabled) ->
- send_element(StateData,
- {xmlelement, "starttls",
- [{"xmlns", ?NS_TLS}], []}),
- {next_state, wait_for_starttls_proceed, StateData};
- StartTLSRequired and (not StateData#state.tls) ->
- ?INFO_MSG("restarted: ~p", [{StateData#state.myname,
- StateData#state.server}]),
- ejabberd_receiver:close(StateData#state.receiver),
- {next_state, reopen_socket,
- StateData#state{socket = undefined,
- use_v10 = false}};
- StateData#state.db_enabled ->
- send_db_request(StateData);
- true ->
- ?INFO_MSG("restarted: ~p", [{StateData#state.myname,
- StateData#state.server}]),
- % TODO: clear message queue
- ejabberd_receiver:close(StateData#state.receiver),
- {next_state, reopen_socket, StateData#state{socket = undefined,
- use_v10 = false}}
- end;
- _ ->
- send_text(StateData,
- xml:element_to_string(?SERR_BAD_FORMAT) ++
- ?STREAM_TRAILER),
- {stop, normal, StateData}
- end;
-
-wait_for_features({xmlstreamend, Name}, StateData) ->
- {stop, normal, StateData};
-
-wait_for_features({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_features(timeout, StateData) ->
- {stop, normal, StateData};
-
-wait_for_features(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-wait_for_auth_result({xmlstreamelement, El}, StateData) ->
- case El of
- {xmlelement, "success", Attrs, _Els} ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_SASL ->
- ?INFO_MSG("auth: ~p", [{StateData#state.myname,
- StateData#state.server}]),
- ejabberd_receiver:reset_stream(
- StateData#state.receiver),
- send_text(StateData,
- io_lib:format(?STREAM_HEADER,
- [StateData#state.server,
- " version='1.0'"])),
- {next_state, wait_for_stream,
- StateData#state{streamid = new_id(),
- authenticated = true
- }};
- _ ->
- send_text(StateData,
- xml:element_to_string(?SERR_BAD_FORMAT) ++
- ?STREAM_TRAILER),
- {stop, normal, StateData}
- end;
- {xmlelement, "failure", Attrs, _Els} ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_SASL ->
- ?INFO_MSG("restarted: ~p", [{StateData#state.myname,
- StateData#state.server}]),
- ejabberd_receiver:close(StateData#state.receiver),
- {next_state, reopen_socket,
- StateData#state{socket = undefined}};
- _ ->
- send_text(StateData,
- xml:element_to_string(?SERR_BAD_FORMAT) ++
- ?STREAM_TRAILER),
- {stop, normal, StateData}
- end;
- _ ->
- send_text(StateData,
- xml:element_to_string(?SERR_BAD_FORMAT) ++
- ?STREAM_TRAILER),
- {stop, normal, StateData}
- end;
-
-wait_for_auth_result({xmlstreamend, Name}, StateData) ->
- {stop, normal, StateData};
-
-wait_for_auth_result({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_auth_result(timeout, StateData) ->
- {stop, normal, StateData};
-
-wait_for_auth_result(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-wait_for_starttls_proceed({xmlstreamelement, El}, StateData) ->
- case El of
- {xmlelement, "proceed", Attrs, _Els} ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_TLS ->
- ?INFO_MSG("starttls: ~p", [{StateData#state.myname,
- StateData#state.server}]),
- Socket = StateData#state.socket,
- TLSOpts = case ejabberd_config:get_local_option(
- {domain_certfile,
- StateData#state.server}) of
- undefined ->
- StateData#state.tls_options;
- CertFile ->
- [{certfile, CertFile} |
- lists:keydelete(
- certfile, 1,
- StateData#state.tls_options)]
- end,
- {ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
- ejabberd_receiver:starttls(
- StateData#state.receiver, TLSSocket),
- NewStateData = StateData#state{sockmod = tls,
- socket = TLSSocket,
- streamid = new_id(),
- tls_enabled = true
- },
- send_text(NewStateData,
- io_lib:format(?STREAM_HEADER,
- [StateData#state.server,
- " version='1.0'"])),
- {next_state, wait_for_stream, NewStateData};
- _ ->
- send_text(StateData,
- xml:element_to_string(?SERR_BAD_FORMAT) ++
- ?STREAM_TRAILER),
- {stop, normal, StateData}
- end;
- _ ->
- {stop, normal, StateData}
- end;
-
-wait_for_starttls_proceed({xmlstreamend, Name}, StateData) ->
- {stop, normal, StateData};
-
-wait_for_starttls_proceed({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_starttls_proceed(timeout, StateData) ->
- {stop, normal, StateData};
-
-wait_for_starttls_proceed(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-reopen_socket({xmlstreamelement, El}, StateData) ->
- {next_state, reopen_socket, StateData};
-reopen_socket({xmlstreamend, Name}, StateData) ->
- {next_state, reopen_socket, StateData};
-reopen_socket({xmlstreamerror, _}, StateData) ->
- {next_state, reopen_socket, StateData};
-reopen_socket(timeout, StateData) ->
- {stop, normal, StateData};
-reopen_socket(closed, StateData) ->
- gen_fsm:send_event(self(), init),
- {next_state, open_socket, StateData}.
-
-
-stream_established({xmlstreamelement, El}, StateData) ->
- ?INFO_MSG("stream established", []),
- case is_verify_res(El) of
- {verify, VTo, VFrom, VId, VType} ->
- ?INFO_MSG("recv verify: ~p", [{VFrom, VTo, VId, VType}]),
- case StateData#state.verify of
- {VPid, _VKey, _SID} ->
- case VType of
- "valid" ->
- gen_fsm:send_event(
- VPid, {valid,
- StateData#state.server,
- StateData#state.myname});
- _ ->
- gen_fsm:send_event(
- VPid, {invalid,
- StateData#state.server,
- StateData#state.myname})
- end;
- _ ->
- ok
- end;
- _ ->
- ok
- end,
- {next_state, stream_established, StateData};
-
-stream_established({xmlstreamend, Name}, StateData) ->
- {stop, normal, StateData};
-
-stream_established({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {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}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/3
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-handle_info({send_text, Text}, StateName, StateData) ->
- send_text(StateData, Text),
- cancel_timer(StateData#state.timer),
- Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
- {next_state, StateName, StateData#state{timer = Timer}};
-
-handle_info({send_element, El}, StateName, StateData) ->
- cancel_timer(StateData#state.timer),
- Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
- case StateName of
- stream_established ->
- send_element(StateData, El),
- {next_state, StateName, StateData#state{timer = Timer}};
- _ ->
- Q = queue:in(El, StateData#state.queue),
- {next_state, StateName, StateData#state{queue = Q,
- timer = Timer}}
- end;
-
-%handle_info({tcp, Socket, Data}, StateName, StateData) ->
-% xml_stream:send_text(StateData#state.xmlpid, Data),
-% {next_state, StateName, StateData};
-%
-%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};
-
-handle_info({timeout, Timer, _}, StateName,
- #state{timer = Timer} = StateData) ->
- {stop, normal, StateData};
-
-handle_info(_, StateName, StateData) ->
- {next_state, StateName, StateData}.
-
-%%----------------------------------------------------------------------
-%% Func: terminate/3
-%% Purpose: Shutdown the fsm
-%% Returns: any
-%%----------------------------------------------------------------------
-terminate(Reason, StateName, StateData) ->
- ?INFO_MSG("terminated: ~p", [Reason]),
- bounce_queue(StateData#state.queue, ?ERR_REMOTE_SERVER_NOT_FOUND),
- case StateData#state.new of
- false ->
- ok;
- Key ->
- ejabberd_s2s:remove_connection({StateData#state.myname,
- StateData#state.server})
- end,
- case StateData#state.socket of
- undefined ->
- ok;
- _Socket ->
- ejabberd_receiver:close(StateData#state.receiver)
- end,
- ok.
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-
-send_text(StateData, Text) ->
- (StateData#state.sockmod):send(StateData#state.socket, Text).
-
-send_element(StateData, El) ->
- send_text(StateData, xml:element_to_string(El)).
-
-send_queue(StateData, Q) ->
- case queue:out(Q) of
- {{value, El}, Q1} ->
- send_element(StateData, El),
- send_queue(StateData, Q1);
- {empty, Q1} ->
- ok
- end.
-
-bounce_queue(Q, Error) ->
- case queue:out(Q) of
- {{value, El}, Q1} ->
- Err = jlib:make_error_reply(El, Error),
- From = jlib:string_to_jid(xml:get_tag_attr_s("from", El)),
- To = jlib:string_to_jid(xml:get_tag_attr_s("to", El)),
- ejabberd_router:route(To, From, Err),
- bounce_queue(Q1, Error);
- {empty, Q1} ->
- ok
- end.
-
-new_id() ->
- randoms:get_string().
-
-cancel_timer(Timer) ->
- erlang:cancel_timer(Timer),
- receive
- {timeout, Timer, _} ->
- ok
- after 0 ->
- ok
- end.
-
-bounce_messages(Error) ->
- receive
- {send_element, El} ->
- {xmlelement, _Name, Attrs, _SubTags} = El,
- case xml:get_attr_s("type", Attrs) of
- "error" ->
- ok;
- _ ->
- Err = jlib:make_error_reply(El, Error),
- From = jlib:string_to_jid(xml:get_attr_s("from", Attrs)),
- To = jlib:string_to_jid(xml:get_attr_s("to", Attrs)),
- ejabberd_router:route(To, From, Err)
- end,
- bounce_messages(Error)
- after 0 ->
- ok
- end.
-
-
-send_db_request(StateData) ->
- Server = StateData#state.server,
- New = case StateData#state.new of
- false ->
- case ejabberd_s2s:try_register(
- {StateData#state.myname, Server}) of
- {key, Key} ->
- Key;
- false ->
- false
- end;
- Key ->
- Key
- end,
- case New of
- false ->
- ok;
- Key1 ->
- send_element(StateData,
- {xmlelement,
- "db:result",
- [{"from", StateData#state.myname},
- {"to", Server}],
- [{xmlcdata, Key1}]})
- end,
- case StateData#state.verify of
- false ->
- ok;
- {Pid, Key2, SID} ->
- send_element(StateData,
- {xmlelement,
- "db:verify",
- [{"from", StateData#state.myname},
- {"to", StateData#state.server},
- {"id", SID}],
- [{xmlcdata, Key2}]})
- end,
- {next_state, wait_for_validation, StateData#state{new = New}}.
-
-
-is_verify_res({xmlelement, Name, Attrs, Els}) when Name == "db:result" ->
- {result,
- xml:get_attr_s("to", Attrs),
- xml:get_attr_s("from", Attrs),
- xml:get_attr_s("id", Attrs),
- xml:get_attr_s("type", Attrs)};
-is_verify_res({xmlelement, Name, Attrs, Els}) when Name == "db:verify" ->
- {verify,
- xml:get_attr_s("to", Attrs),
- xml:get_attr_s("from", Attrs),
- xml:get_attr_s("id", Attrs),
- xml:get_attr_s("type", Attrs)};
-is_verify_res(_) ->
- false.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% SRV support
-
--include_lib("kernel/include/inet.hrl").
-
-get_addr_port(Server) ->
- Res = case inet_res:getbyname("_xmpp-server._tcp." ++ Server, srv) of
- {error, _Reason} ->
- inet_res:getbyname("_jabber._tcp." ++ Server, srv);
- {ok, _HEnt} = R -> R
- end,
- case Res of
- {error, Reason} ->
- ?DEBUG("srv lookup of '~s' failed: ~p~n", [Server, Reason]),
- [{Server, ejabberd_config:get_local_option(outgoing_s2s_port)}];
- {ok, HEnt} ->
- ?DEBUG("srv lookup of '~s': ~p~n",
- [Server, HEnt#hostent.h_addr_list]),
- case HEnt#hostent.h_addr_list of
- [] ->
- [{Server,
- ejabberd_config:get_local_option(outgoing_s2s_port)}];
- AddrList ->
- % Probabilities are not exactly proportional to weights
- % for simplicity (higher weigths are overvalued)
- {A1, A2, A3} = now(),
- random:seed(A1, A2, A3),
- case (catch lists:map(
- fun({Priority, Weight, Port, Host}) ->
- N = case Weight of
- 0 -> 0;
- _ -> (Weight + 1) * random:uniform()
- end,
- {Priority * 65536 - N, Host, Port}
- end, AddrList)) of
- {'EXIT', _Reasn} ->
- [{Server,
- ejabberd_config:get_local_option(outgoing_s2s_port)}];
- SortedList ->
- List = lists:map(
- fun({_, Host, Port}) ->
- {Host, Port}
- end, lists:keysort(1, SortedList)),
- ?DEBUG("srv lookup of '~s': ~p~n", [Server, List]),
- List
- end
- end
- end.
-
-test_get_addr_port(Server) ->
- lists:foldl(
- fun(_, Acc) ->
- [HostPort | _] = get_addr_port(Server),
- case lists:keysearch(HostPort, 1, Acc) of
- false ->
- [{HostPort, 1} | Acc];
- {value, {_, Num}} ->
- lists:keyreplace(HostPort, 1, Acc, {HostPort, Num + 1})
- end
- end, [], lists:seq(1, 100000)).
-
diff --git a/ejabberd-1.1.2/src/ejabberd_service.erl b/ejabberd-1.1.2/src/ejabberd_service.erl
deleted file mode 100644
index 551ff436e..000000000
--- a/ejabberd-1.1.2/src/ejabberd_service.erl
+++ /dev/null
@@ -1,347 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_service.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_service).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_fsm).
-
-%% External exports
--export([start/2,
- start_link/2,
- send_text/2,
- send_element/2,
- become_controller/1]).
-
-%% gen_fsm callbacks
--export([init/1,
- wait_for_stream/2,
- wait_for_handshake/2,
- stream_established/2,
- handle_event/3,
- handle_sync_event/4,
- code_change/4,
- handle_info/3,
- terminate/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--record(state, {socket, receiver, streamid, sockmod,
- hosts, password, access}).
-
-%-define(DBGFSM, true).
-
--ifdef(DBGFSM).
--define(FSMOPTS, [{debug, [trace]}]).
--else.
--define(FSMOPTS, []).
--endif.
-
--define(STREAM_HEADER,
- "<?xml version='1.0'?>"
- "<stream:stream "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "xmlns='jabber:component:accept' "
- "id='~s' from='~s'>"
- ).
-
--define(STREAM_TRAILER, "</stream:stream>").
-
--define(INVALID_HEADER_ERR,
- "<stream:stream>"
- "<stream:error>Invalid Stream Header</stream:error>"
- "</stream:stream>"
- ).
-
--define(INVALID_HANDSHAKE_ERR,
- "<stream:error>Invalid Handshake</stream:error>"
- "</stream:stream>"
- ).
-
--define(INVALID_XML_ERR,
- xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
--define(INVALID_NS_ERR,
- xml:element_to_string(?SERR_INVALID_NAMESPACE)).
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-start(SockData, Opts) ->
- supervisor:start_child(ejabberd_service_sup, [SockData, Opts]).
-
-start_link(SockData, Opts) ->
- gen_fsm:start_link(ejabberd_service, [SockData, Opts], ?FSMOPTS).
-
-become_controller(Pid) ->
- gen_fsm:send_all_state_event(Pid, become_controller).
-
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_fsm
-%%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, StateName, StateData} |
-%% {ok, StateName, StateData, Timeout} |
-%% ignore |
-%% {stop, StopReason}
-%%----------------------------------------------------------------------
-init([{SockMod, Socket}, Opts]) ->
- Access = case lists:keysearch(access, 1, Opts) of
- {value, {_, A}} -> A;
- _ -> all
- end,
- {Hosts, Password} =
- case lists:keysearch(hosts, 1, Opts) of
- {value, {_, Hs, HOpts}} ->
- case lists:keysearch(password, 1, HOpts) of
- {value, {_, P}} ->
- {Hs, P};
- _ ->
- % TODO: generate error
- false
- end;
- _ ->
- case lists:keysearch(host, 1, Opts) of
- {value, {_, H, HOpts}} ->
- case lists:keysearch(password, 1, HOpts) of
- {value, {_, P}} ->
- {[H], P};
- _ ->
- % TODO: generate error
- false
- end;
- _ ->
- % TODO: generate error
- false
- end
- end,
- ReceiverPid = ejabberd_receiver:start(Socket, SockMod, none),
- {ok, wait_for_stream, #state{socket = Socket,
- receiver = ReceiverPid,
- streamid = new_id(),
- sockmod = SockMod,
- hosts = Hosts,
- password = Password,
- access = Access
- }}.
-
-%%----------------------------------------------------------------------
-%% Func: StateName/2
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-
-wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
- % TODO
- case xml:get_attr_s("xmlns", Attrs) of
- "jabber:component:accept" ->
- Header = io_lib:format(?STREAM_HEADER,
- [StateData#state.streamid, ?MYNAME]),
- send_text(StateData, Header),
- {next_state, wait_for_handshake, StateData};
- _ ->
- send_text(StateData, ?INVALID_HEADER_ERR),
- {stop, normal, StateData}
- end;
-
-wait_for_stream({xmlstreamerror, _}, StateData) ->
- Header = io_lib:format(?STREAM_HEADER,
- ["none", ?MYNAME]),
- send_text(StateData,
- Header ++ ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_stream(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-wait_for_handshake({xmlstreamelement, El}, StateData) ->
- {xmlelement, Name, _Attrs, Els} = El,
- case {Name, xml:get_cdata(Els)} of
- {"handshake", Digest} ->
- case sha:sha(StateData#state.streamid ++
- StateData#state.password) of
- Digest ->
- send_text(StateData, "<handshake/>"),
- lists:foreach(
- fun(H) ->
- ejabberd_router:register_route(H)
- end, StateData#state.hosts),
- {next_state, stream_established, StateData};
- _ ->
- send_text(StateData, ?INVALID_HANDSHAKE_ERR),
- {stop, normal, StateData}
- end;
- _ ->
- {next_state, wait_for_handshake, StateData}
- end;
-
-wait_for_handshake({xmlstreamend, _Name}, StateData) ->
- {stop, normal, StateData};
-
-wait_for_handshake({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-wait_for_handshake(closed, StateData) ->
- {stop, normal, StateData}.
-
-
-stream_established({xmlstreamelement, El}, StateData) ->
- NewEl = jlib:remove_attr("xmlns", El),
- {xmlelement, Name, Attrs, _Els} = NewEl,
- From = xml:get_attr_s("from", Attrs),
- FromJID1 = jlib:string_to_jid(From),
- FromJID = case FromJID1 of
- #jid{lserver = Server} ->
- case lists:member(Server, StateData#state.hosts) of
- true -> FromJID1;
- false -> error
- end;
- _ -> error
- end,
- To = xml:get_attr_s("to", Attrs),
- ToJID = case To of
- "" -> error;
- _ -> jlib:string_to_jid(To)
- end,
- if ((Name == "iq") or
- (Name == "message") or
- (Name == "presence")) and
- (ToJID /= error) and (FromJID /= error) ->
- ejabberd_router:route(FromJID, ToJID, NewEl);
- true ->
- Err = jlib:make_error_reply(NewEl, ?ERR_BAD_REQUEST),
- send_element(StateData, Err),
- error
- end,
- {next_state, stream_established, StateData};
-
-stream_established({xmlstreamend, _Name}, StateData) ->
- % TODO
- {stop, normal, StateData};
-
-stream_established({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
- {stop, normal, StateData};
-
-stream_established(closed, StateData) ->
- % TODO
- {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(become_controller, StateName, StateData) ->
- ok = (StateData#state.sockmod):controlling_process(
- StateData#state.socket,
- StateData#state.receiver),
- ejabberd_receiver:become_controller(StateData#state.receiver),
- {next_state, StateName, StateData};
-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}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/3
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-handle_info({send_text, Text}, StateName, StateData) ->
- send_text(StateData, Text),
- {next_state, StateName, StateData};
-handle_info({send_element, El}, StateName, StateData) ->
- send_element(StateData, El),
- {next_state, StateName, StateData};
-handle_info({route, From, To, Packet}, StateName, StateData) ->
- case acl:match_rule(global, StateData#state.access, From) of
- allow ->
- {xmlelement, Name, Attrs, Els} = Packet,
- Attrs2 = jlib:replace_from_to_attrs(jlib:jid_to_string(From),
- jlib:jid_to_string(To),
- Attrs),
- Text = xml:element_to_string({xmlelement, Name, Attrs2, Els}),
- send_text(StateData, Text);
- deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
- ejabberd_router:route(To, From, Err)
- end,
- {next_state, StateName, StateData}.
-
-
-%%----------------------------------------------------------------------
-%% Func: terminate/3
-%% Purpose: Shutdown the fsm
-%% Returns: any
-%%----------------------------------------------------------------------
-terminate(Reason, StateName, StateData) ->
- ?INFO_MSG("terminated: ~p", [Reason]),
- case StateName of
- stream_established ->
- lists:foreach(
- fun(H) ->
- ejabberd_router:unregister_route(H)
- end, StateData#state.hosts);
- _ ->
- ok
- end,
- ejabberd_receiver:close(StateData#state.receiver),
- ok.
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-
-send_text(StateData, Text) ->
- (StateData#state.sockmod):send(StateData#state.socket,Text).
-
-send_element(StateData, El) ->
- send_text(StateData, xml:element_to_string(El)).
-
-
-new_id() ->
- randoms:get_string().
-
diff --git a/ejabberd-1.1.2/src/ejabberd_sm.erl b/ejabberd-1.1.2/src/ejabberd_sm.erl
deleted file mode 100644
index 7f4d6b87a..000000000
--- a/ejabberd-1.1.2/src/ejabberd_sm.erl
+++ /dev/null
@@ -1,617 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_sm.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Session manager
-%%% Created : 24 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_sm).
--author('alexey@sevcom.net').
-
--behaviour(gen_server).
-
-%% API
--export([start_link/0,
- route/3,
- open_session/4, close_session/4,
- bounce_offline_message/3,
- disconnect_removed_user/2,
- get_user_resources/2,
- set_presence/5,
- unset_presence/5,
- close_session_unset_presence/5,
- dirty_get_sessions_list/0,
- dirty_get_my_sessions_list/0,
- get_vh_session_list/1,
- register_iq_handler/4,
- register_iq_handler/5,
- unregister_iq_handler/2,
- ctl_process/2
- ]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include("ejabberd_ctl.hrl").
-
--record(session, {sid, usr, us, priority}).
--record(state, {}).
-
-%% default value for the maximum number of user connections
--define(MAX_USER_SESSIONS, infinity).
-
-%%====================================================================
-%% API
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the server
-%%--------------------------------------------------------------------
-start_link() ->
- gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-
-route(From, To, Packet) ->
- case catch do_route(From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~nwhen processing: ~p",
- [Reason, {From, To, Packet}]);
- _ ->
- ok
- end.
-
-open_session(SID, User, Server, Resource) ->
- set_session(SID, User, Server, Resource, undefined),
- check_for_sessions_to_replace(User, Server, Resource),
- JID = jlib:make_jid(User, Server, Resource),
- ejabberd_hooks:run(sm_register_connection_hook, JID#jid.lserver,
- [SID, JID]).
-
-close_session(SID, User, Server, Resource) ->
- F = fun() ->
- mnesia:delete({session, SID})
- end,
- mnesia:sync_dirty(F),
- JID = jlib:make_jid(User, Server, Resource),
- ejabberd_hooks:run(sm_remove_connection_hook, JID#jid.lserver,
- [SID, JID]).
-
-bounce_offline_message(From, To, Packet) ->
- Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router:route(To, From, Err),
- stop.
-
-disconnect_removed_user(User, Server) ->
- ejabberd_sm:route(jlib:make_jid("", "", ""),
- jlib:make_jid(User, Server, ""),
- {xmlelement, "broadcast", [],
- [{exit, "User removed"}]}).
-
-get_user_resources(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- case catch mnesia:dirty_index_read(session, US, #session.us) of
- {'EXIT', _Reason} ->
- [];
- Ss ->
- [element(3, S#session.usr) || S <- clean_session_list(Ss)]
- end.
-
-set_presence(SID, User, Server, Resource, Priority) ->
- set_session(SID, User, Server, Resource, Priority).
-
-unset_presence(SID, User, Server, Resource, Status) ->
- set_session(SID, User, Server, Resource, undefined),
- ejabberd_hooks:run(unset_presence_hook, jlib:nameprep(Server),
- [User, Server, Resource, Status]).
-
-close_session_unset_presence(SID, User, Server, Resource, Status) ->
- close_session(SID, User, Server, Resource),
- ejabberd_hooks:run(unset_presence_hook, jlib:nameprep(Server),
- [User, Server, Resource, Status]).
-
-
-dirty_get_sessions_list() ->
- mnesia:dirty_select(
- session,
- [{#session{usr = '$1', _ = '_'},
- [],
- ['$1']}]).
-
-dirty_get_my_sessions_list() ->
- mnesia:dirty_select(
- session,
- [{#session{sid = {'_', '$1'}, _ = '_'},
- [{'==', {node, '$1'}, node()}],
- ['$_']}]).
-
-get_vh_session_list(Server) ->
- LServer = jlib:nameprep(Server),
- mnesia:dirty_select(
- session,
- [{#session{usr = '$1', _ = '_'},
- [{'==', {element, 2, '$1'}, LServer}],
- ['$1']}]).
-
-register_iq_handler(Host, XMLNS, Module, Fun) ->
- ejabberd_sm ! {register_iq_handler, Host, XMLNS, Module, Fun}.
-
-register_iq_handler(Host, XMLNS, Module, Fun, Opts) ->
- ejabberd_sm ! {register_iq_handler, Host, XMLNS, Module, Fun, Opts}.
-
-unregister_iq_handler(Host, XMLNS) ->
- ejabberd_sm ! {unregister_iq_handler, Host, XMLNS}.
-
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% Description: Initiates the server
-%%--------------------------------------------------------------------
-init([]) ->
- update_tables(),
- mnesia:create_table(session,
- [{ram_copies, [node()]},
- {attributes, record_info(fields, session)}]),
- mnesia:add_table_index(session, usr),
- mnesia:add_table_index(session, us),
- mnesia:add_table_copy(session, node(), ram_copies),
- mnesia:subscribe(system),
- ets:new(sm_iqtable, [named_table]),
- lists:foreach(
- fun(Host) ->
- ejabberd_hooks:add(offline_message_hook, Host,
- ejabberd_sm, bounce_offline_message, 100),
- ejabberd_hooks:add(remove_user, Host,
- ejabberd_sm, disconnect_removed_user, 100)
- end, ?MYHOSTS),
- ejabberd_ctl:register_commands(
- [{"connected-users", "list all established sessions"},
- {"connected-users-number", "print a number of established sessions"},
- {"user-resources user server", "print user's connected resources"}],
- ?MODULE, ctl_process),
-
- {ok, #state{}}.
-
-%%--------------------------------------------------------------------
-%% 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(_Request, _From, State) ->
- Reply = ok,
- {reply, Reply, 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) ->
- case catch do_route(From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~nwhen processing: ~p",
- [Reason, {From, To, Packet}]);
- _ ->
- ok
- end,
- {noreply, State};
-handle_info({mnesia_system_event, {mnesia_down, Node}}, State) ->
- clean_table_from_bad_node(Node),
- {noreply, State};
-handle_info({register_iq_handler, Host, XMLNS, Module, Function}, State) ->
- ets:insert(sm_iqtable, {{XMLNS, Host}, Module, Function}),
- {noreply, State};
-handle_info({register_iq_handler, Host, XMLNS, Module, Function, Opts}, State) ->
- ets:insert(sm_iqtable, {{XMLNS, Host}, Module, Function, Opts}),
- {noreply, State};
-handle_info({unregister_iq_handler, Host, XMLNS}, State) ->
- case ets:lookup(sm_iqtable, {XMLNS, Host}) of
- [{_, Module, Function, Opts}] ->
- gen_iq_handler:stop_iq_handler(Module, Function, Opts);
- _ ->
- ok
- end,
- ets:delete(sm_iqtable, {XMLNS, Host}),
- {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) ->
- 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
-%%--------------------------------------------------------------------
-
-set_session(SID, User, Server, Resource, Priority) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- LResource = jlib:resourceprep(Resource),
- US = {LUser, LServer},
- USR = {LUser, LServer, LResource},
- F = fun() ->
- mnesia:write(#session{sid = SID,
- usr = USR,
- us = US,
- priority = Priority})
- end,
- mnesia:sync_dirty(F).
-
-clean_table_from_bad_node(Node) ->
- F = fun() ->
- Es = mnesia:select(
- session,
- [{#session{sid = {'_', '$1'}, _ = '_'},
- [{'==', {node, '$1'}, Node}],
- ['$_']}]),
- lists:foreach(fun(E) ->
- mnesia:delete({session, E#session.sid})
- end, Es)
- end,
- mnesia:sync_dirty(F).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-do_route(From, To, Packet) ->
- ?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
- [From, To, Packet, 8]),
- #jid{user = User, server = Server,
- luser = LUser, lserver = LServer, lresource = LResource} = To,
- {xmlelement, Name, Attrs, _Els} = Packet,
- case LResource of
- "" ->
- case Name of
- "presence" ->
- {Pass, Subsc} =
- case xml:get_attr_s("type", Attrs) of
- "subscribe" ->
- Reason = xml:get_path_s(
- Packet,
- [{elem, "status"}, cdata]),
- {ejabberd_hooks:run_fold(
- roster_in_subscription,
- LServer,
- false,
- [User, Server, From, subscribe, Reason]),
- true};
- "subscribed" ->
- {ejabberd_hooks:run_fold(
- roster_in_subscription,
- LServer,
- false,
- [User, Server, From, subscribed, ""]),
- true};
- "unsubscribe" ->
- {ejabberd_hooks:run_fold(
- roster_in_subscription,
- LServer,
- false,
- [User, Server, From, unsubscribe, ""]),
- true};
- "unsubscribed" ->
- {ejabberd_hooks:run_fold(
- roster_in_subscription,
- LServer,
- false,
- [User, Server, From, unsubscribed, ""]),
- true};
- _ ->
- {true, false}
- end,
- if Pass ->
- LFrom = jlib:jid_tolower(From),
- PResources = get_user_present_resources(
- LUser, LServer),
- lists:foreach(
- fun({_, R}) ->
- if LFrom /=
- {LUser, LServer, R} ->
- do_route(
- From,
- jlib:jid_replace_resource(To, R),
- Packet);
- true ->
- ok
- end
- end, PResources);
- true ->
- ok
- end;
- "message" ->
- route_message(From, To, Packet);
- "iq" ->
- process_iq(From, To, Packet);
- "broadcast" ->
- lists:foreach(
- fun(R) ->
- do_route(From,
- jlib:jid_replace_resource(To, R),
- Packet)
- end, get_user_resources(User, Server));
- _ ->
- ok
- end;
- _ ->
- USR = {LUser, LServer, LResource},
- case mnesia:dirty_index_read(session, USR, #session.usr) of
- [] ->
- case Name of
- "message" ->
- route_message(From, To, Packet);
- "iq" ->
- case xml:get_attr_s("type", Attrs) of
- "error" -> ok;
- "result" -> ok;
- _ ->
- Err =
- jlib:make_error_reply(
- Packet, ?ERR_RECIPIENT_UNAVAILABLE),
- ejabberd_router:route(To, From, Err)
- end;
- _ ->
- ?DEBUG("packet droped~n", [])
- end;
- Ss ->
- Session = lists:max(Ss),
- Pid = element(2, Session#session.sid),
- ?DEBUG("sending to process ~p~n", [Pid]),
- Pid ! {route, From, To, Packet}
- end
- end.
-
-route_message(From, To, Packet) ->
- LUser = To#jid.luser,
- LServer = To#jid.lserver,
- PrioRes = get_user_present_resources(LUser, LServer),
- case catch lists:max(PrioRes) of
- {Priority, _R} when is_integer(Priority), Priority >= 0 ->
- lists:foreach(
- %% Route messages to all priority that equals the max, if
- %% positive
- fun({P, R}) when P == Priority ->
- LResource = jlib:resourceprep(R),
- USR = {LUser, LServer, LResource},
- case mnesia:dirty_index_read(session, USR, #session.usr) of
- [] ->
- ok; % Race condition
- Ss ->
- Session = lists:max(Ss),
- Pid = element(2, Session#session.sid),
- ?DEBUG("sending to process ~p~n", [Pid]),
- Pid ! {route, From, To, Packet}
- end;
- %% Ignore other priority:
- ({_Prio, _Res}) ->
- ok
- end,
- PrioRes);
- _ ->
- case xml:get_tag_attr_s("type", Packet) of
- "error" ->
- ok;
- _ ->
- case ejabberd_auth:is_user_exists(LUser, LServer) of
- true ->
- ejabberd_hooks:run(offline_message_hook,
- LServer,
- [From, To, Packet]);
- _ ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router:route(To, From, Err)
- end
- end
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-clean_session_list(Ss) ->
- clean_session_list(lists:keysort(#session.usr, Ss), []).
-
-clean_session_list([], Res) ->
- Res;
-clean_session_list([S], Res) ->
- [S | Res];
-clean_session_list([S1, S2 | Rest], Res) ->
- if
- S1#session.usr == S2#session.usr ->
- if
- S1#session.sid > S2#session.sid ->
- clean_session_list([S1 | Rest], Res);
- true ->
- clean_session_list([S2 | Rest], Res)
- end;
- true ->
- clean_session_list([S2 | Rest], [S1 | Res])
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-get_user_present_resources(LUser, LServer) ->
- US = {LUser, LServer},
- case catch mnesia:dirty_index_read(session, US, #session.us) of
- {'EXIT', _Reason} ->
- [];
- Ss ->
- [{S#session.priority, element(3, S#session.usr)} ||
- S <- clean_session_list(Ss), is_integer(S#session.priority)]
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% On new session, check if some existing connections need to be replace
-check_for_sessions_to_replace(User, Server, Resource) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- LResource = jlib:resourceprep(Resource),
-
- %% TODO: Depending on how this is executed, there could be an unneeded
- %% replacement for max_sessions. We need to check this at some point.
- check_existing_resources(LUser, LServer, LResource),
- check_max_sessions(LUser, LServer).
-
-check_existing_resources(LUser, LServer, LResource) ->
- USR = {LUser, LServer, LResource},
- %% A connection exist with the same resource. We replace it:
- SIDs = mnesia:dirty_select(
- session,
- [{#session{sid = '$1', usr = USR, _ = '_'}, [], ['$1']}]),
- if
- SIDs == [] -> ok;
- true ->
- MaxSID = lists:max(SIDs),
- lists:foreach(
- fun({_, Pid} = S) when S /= MaxSID ->
- Pid ! replaced;
- (_) -> ok
- end, SIDs)
- end.
-
-check_max_sessions(LUser, LServer) ->
- %% If the max number of sessions for a given is reached, we replace the
- %% first one
- SIDs = mnesia:dirty_select(
- session,
- [{#session{sid = '$1', usr = {LUser, LServer, '_'}, _ = '_'}, [], ['$1']}]),
- MaxSessions = get_max_user_sessions(LServer),
- if length(SIDs) =< MaxSessions -> ok;
- true -> {_, Pid} = lists:min(SIDs),
- Pid ! replaced
- end.
-
-
-%% Get the user_max_session setting
-%% This option defines the max number of time a given users are allowed to
-%% log in
-%% Defaults to infinity
-get_max_user_sessions(Host) ->
- case ejabberd_config:get_local_option({max_user_sessions, Host}) of
- undefined -> ?MAX_USER_SESSIONS;
- Max -> Max
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-process_iq(From, To, Packet) ->
- IQ = jlib:iq_query_info(Packet),
- case IQ of
- #iq{xmlns = XMLNS} ->
- Host = To#jid.lserver,
- case ets:lookup(sm_iqtable, {XMLNS, Host}) of
- [{_, Module, Function}] ->
- ResIQ = Module:Function(From, To, IQ),
- if
- ResIQ /= ignore ->
- ejabberd_router:route(To, From,
- jlib:iq_to_xml(ResIQ));
- true ->
- ok
- end;
- [{_, Module, Function, Opts}] ->
- gen_iq_handler:handle(Host, Module, Function, Opts,
- From, To, IQ);
- [] ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router:route(To, From, Err)
- end;
- reply ->
- ok;
- _ ->
- Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
- ejabberd_router:route(To, From, Err),
- ok
- end.
-
-
-ctl_process(_Val, ["connected-users"]) ->
- USRs = dirty_get_sessions_list(),
- NewLine = io_lib:format("~n", []),
- SUSRs = lists:sort(USRs),
- FUSRs = lists:map(fun({U, S, R}) -> [U, $@, S, $/, R, NewLine] end, SUSRs),
- io:format("~s", [FUSRs]),
- {stop, ?STATUS_SUCCESS};
-ctl_process(_Val, ["connected-users-number"]) ->
- N = length(dirty_get_sessions_list()),
- io:format("~p~n", [N]),
- {stop, ?STATUS_SUCCESS};
-ctl_process(_Val, ["user-resources", User, Server]) ->
- Resources = get_user_resources(User, Server),
- NewLine = io_lib:format("~n", []),
- SResources = lists:sort(Resources),
- FResources = lists:map(fun(R) -> [R, NewLine] end, SResources),
- io:format("~s", [FResources]),
- {stop, ?STATUS_SUCCESS};
-ctl_process(Val, _Args) ->
- Val.
-
-
-update_tables() ->
- case catch mnesia:table_info(session, attributes) of
- [ur, user, node] ->
- mnesia:delete_table(session);
- [ur, user, pid] ->
- mnesia:delete_table(session);
- [usr, us, pid] ->
- mnesia:delete_table(session);
- [sid, usr, us, priority] ->
- ok;
- {'EXIT', _} ->
- ok
- end,
- case lists:member(presence, mnesia:system_info(tables)) of
- true ->
- mnesia:delete_table(presence);
- false ->
- ok
- end,
- case lists:member(local_session, mnesia:system_info(tables)) of
- true ->
- mnesia:delete_table(local_session);
- false ->
- ok
- end.
-
diff --git a/ejabberd-1.1.2/src/ejabberd_sup.erl b/ejabberd-1.1.2/src/ejabberd_sup.erl
deleted file mode 100644
index 1e6851dc2..000000000
--- a/ejabberd-1.1.2/src/ejabberd_sup.erl
+++ /dev/null
@@ -1,151 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_sup.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_sup).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(supervisor).
-
--export([start_link/0, init/1]).
-
-start_link() ->
- supervisor:start_link({local, ?MODULE}, ?MODULE, []).
-
-
-init([]) ->
- Hooks =
- {ejabberd_hooks,
- {ejabberd_hooks, start_link, []},
- permanent,
- brutal_kill,
- worker,
- [ejabberd_hooks]},
- StringPrep =
- {stringprep,
- {stringprep, start_link, []},
- permanent,
- brutal_kill,
- worker,
- [stringprep]},
- Router =
- {ejabberd_router,
- {ejabberd_router, start_link, []},
- permanent,
- brutal_kill,
- worker,
- [ejabberd_router]},
- SM =
- {ejabberd_sm,
- {ejabberd_sm, start_link, []},
- permanent,
- brutal_kill,
- worker,
- [ejabberd_sm]},
- S2S =
- {ejabberd_s2s,
- {ejabberd_s2s, start_link, []},
- permanent,
- brutal_kill,
- worker,
- [ejabberd_s2s]},
- Local =
- {ejabberd_local,
- {ejabberd_local, start_link, []},
- permanent,
- brutal_kill,
- worker,
- [ejabberd_local]},
- Listener =
- {ejabberd_listener,
- {ejabberd_listener, start_link, []},
- permanent,
- infinity,
- supervisor,
- [ejabberd_listener]},
- ReceiverSupervisor =
- {ejabberd_receiver_sup,
- {ejabberd_tmp_sup, start_link,
- [ejabberd_receiver_sup, ejabberd_receiver]},
- permanent,
- infinity,
- supervisor,
- [ejabberd_tmp_sup]},
- C2SSupervisor =
- {ejabberd_c2s_sup,
- {ejabberd_tmp_sup, start_link, [ejabberd_c2s_sup, ejabberd_c2s]},
- permanent,
- infinity,
- supervisor,
- [ejabberd_tmp_sup]},
- S2SInSupervisor =
- {ejabberd_s2s_in_sup,
- {ejabberd_tmp_sup, start_link,
- [ejabberd_s2s_in_sup, ejabberd_s2s_in]},
- permanent,
- infinity,
- supervisor,
- [ejabberd_tmp_sup]},
- S2SOutSupervisor =
- {ejabberd_s2s_out_sup,
- {ejabberd_tmp_sup, start_link,
- [ejabberd_s2s_out_sup, ejabberd_s2s_out]},
- permanent,
- infinity,
- supervisor,
- [ejabberd_tmp_sup]},
- ServiceSupervisor =
- {ejabberd_service_sup,
- {ejabberd_tmp_sup, start_link,
- [ejabberd_service_sup, ejabberd_service]},
- permanent,
- infinity,
- supervisor,
- [ejabberd_tmp_sup]},
- HTTPSupervisor =
- {ejabberd_http_sup,
- {ejabberd_tmp_sup, start_link,
- [ejabberd_http_sup, ejabberd_http]},
- permanent,
- infinity,
- supervisor,
- [ejabberd_tmp_sup]},
- HTTPPollSupervisor =
- {ejabberd_http_poll_sup,
- {ejabberd_tmp_sup, start_link,
- [ejabberd_http_poll_sup, ejabberd_http_poll]},
- permanent,
- infinity,
- supervisor,
- [ejabberd_tmp_sup]},
- IQSupervisor =
- {ejabberd_iq_sup,
- {ejabberd_tmp_sup, start_link,
- [ejabberd_iq_sup, gen_iq_handler]},
- permanent,
- infinity,
- supervisor,
- [ejabberd_tmp_sup]},
- {ok, {{one_for_one, 10, 1},
- [Hooks,
- StringPrep,
- Router,
- SM,
- S2S,
- Local,
- ReceiverSupervisor,
- C2SSupervisor,
- S2SInSupervisor,
- S2SOutSupervisor,
- ServiceSupervisor,
- HTTPSupervisor,
- HTTPPollSupervisor,
- IQSupervisor,
- Listener]}}.
-
-
diff --git a/ejabberd-1.1.2/src/ejabberd_tmp_sup.erl b/ejabberd-1.1.2/src/ejabberd_tmp_sup.erl
deleted file mode 100644
index 357bdd67a..000000000
--- a/ejabberd-1.1.2/src/ejabberd_tmp_sup.erl
+++ /dev/null
@@ -1,22 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_tmp_sup.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Supervisor for temporary processess
-%%% Created : 18 Jul 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_tmp_sup).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([start_link/2, init/1]).
-
-start_link(Name, Module) ->
- supervisor:start_link({local, Name}, ?MODULE, Module).
-
-
-init(Module) ->
- {ok, {{simple_one_for_one, 10, 1},
- [{undefined, {Module, start_link, []},
- temporary, brutal_kill, worker, [Module]}]}}.
diff --git a/ejabberd-1.1.2/src/ejabberd_update.erl b/ejabberd-1.1.2/src/ejabberd_update.erl
deleted file mode 100644
index d4a513a2c..000000000
--- a/ejabberd-1.1.2/src/ejabberd_update.erl
+++ /dev/null
@@ -1,128 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File : ejabberd_update.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Update ejabberd
-%%% Created : 27 Jan 2006 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id: ejabberd_c2s.erl 492 2006-01-25 00:35:12Z alexey $
-%%%-------------------------------------------------------------------
-
--module(ejabberd_update).
--author('alexey@sevcom.net').
-
-%% API
--export([update/0, update_info/0]).
-
-%%====================================================================
-%% API
-%%====================================================================
-update() ->
- case update_info() of
- {ok, Dir, _UpdatedBeams, _Script, LowLevelScript, _Check} ->
- Eval =
- release_handler_1:eval_script(
- LowLevelScript, [],
- [{ejabberd, "", filename:join(Dir, "..")}]),
- io:format("eval: ~p~n", [Eval]),
- Eval;
- {error, Reason} ->
- {error, Reason}
- end.
-
-update_info() ->
- Dir = filename:dirname(code:which(ejabberd)),
- case file:list_dir(Dir) of
- {ok, Files} ->
- Beams = [list_to_atom(filename:rootname(FN)) ||
- FN <- Files, lists:suffix(".beam", FN)],
- UpdatedBeams =
- lists:filter(
- fun(Module) ->
- {ok, {Module, [NewVsn]}} =
- beam_lib:version(code:which(Module)),
- case code:is_loaded(Module) of
- {file, _} ->
- Attrs = Module:module_info(attributes),
- {value, {vsn, [CurVsn]}} =
- lists:keysearch(vsn, 1, Attrs),
- NewVsn /= CurVsn;
- false ->
- false
- end
- end, Beams),
- io:format("beam files: ~p~n", [UpdatedBeams]),
- Script = make_script(UpdatedBeams),
- io:format("script: ~p~n", [Script]),
- LowLevelScript = make_low_level_script(UpdatedBeams, Script),
- io:format("low level script: ~p~n", [LowLevelScript]),
- Check =
- release_handler_1:check_script(
- LowLevelScript,
- [{ejabberd, "", filename:join(Dir, "..")}]),
- io:format("check: ~p~n", [Check]),
- {ok, Dir, UpdatedBeams, Script, LowLevelScript, Check};
- {error, Reason} ->
- {error, Reason}
- end.
-
-
-%%--------------------------------------------------------------------
-%%% Internal functions
-%%--------------------------------------------------------------------
-
-%% From systools.hrl
--record(application,
- {name, %% Name of the application, atom().
- type = permanent, %% Application start type, atom().
- vsn = "", %% Version of the application, string().
- id = "", %% Id of the application, string().
- description = "", %% Description of application, string().
- modules = [], %% [Module | {Module,Vsn}] of modules
- %% incorporated in the application,
- %% Module = atom(), Vsn = string().
- uses = [], %% [Application] list of applications required
- %% by the application, Application = atom().
- includes = [], %% [Application] list of applications included
- %% by the application, Application = atom().
- regs = [], %% [RegNames] a list of registered process
- %% names used by the application, RegNames =
- %% atom().
- env = [], %% [{Key,Value}] environment variable of
- %% application, Key = Value = term().
- maxT = infinity, %% Max time an application may exist,
- %% integer() | infinity.
- maxP = infinity, %% Max number of processes in an application,
- %% integer() | infinity.
- mod = [], %% [] | {Mod, StartArgs}, Mod= atom(),
- %% StartArgs = list().
- start_phases = [], %% [] | {Phase, PhaseArgs}, Phase = atom(),
- %% PhaseArgs = list().
- dir = "" %% The directory where the .app file was
- %% found (internal use).
- }).
-
-
-make_script(UpdatedBeams) ->
- lists:map(
- fun(Module) ->
- {ok, {Module, [{attributes, NewAttrs}]}} =
- beam_lib:chunks(code:which(Module), [attributes]),
- CurAttrs = Module:module_info(attributes),
- case lists:keysearch(update_info, 1, NewAttrs) of
- {value, {_, [{update, _}]}} ->
- case lists:keysearch(update_info, 1, CurAttrs) of
- {value, {_, [{update, Extra}]}} ->
- {update, Module, {advanced, Extra}};
- false ->
- {update, Module, {advanced, 0}}
- end;
- false ->
- {load_module, Module}
- end
- end, UpdatedBeams).
-
-make_low_level_script(UpdatedBeams, Script) ->
- EJDApp = #application{name = ejabberd,
- modules = UpdatedBeams},
- {ok, LowLevelScript} =
- systools_rc:translate_scripts([Script], [EJDApp], [EJDApp]),
- LowLevelScript.
diff --git a/ejabberd-1.1.2/src/ejabberd_zlib/Makefile.in b/ejabberd-1.1.2/src/ejabberd_zlib/Makefile.in
deleted file mode 100644
index 2a44860c5..000000000
--- a/ejabberd-1.1.2/src/ejabberd_zlib/Makefile.in
+++ /dev/null
@@ -1,45 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@ @ZLIB_CFLAGS@ @ERLANG_CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@ @ZLIB_LIBS@ @ERLANG_LIBS@
-
-ifeq ($(shell uname),Darwin)
-DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
-else
-# Assume Linux-style dynamic library flags
-DYNAMIC_LIB_CFLAGS = -fpic -shared
-endif
-
-SUBDIRS =
-
-ERLSHLIBS = ../ejabberd_zlib_drv.so
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-OBJS = \
- $(OUTDIR)/ejabberd_zlib.beam
-
-all: $(OBJS) $(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) -Wall $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \
- $(subst ../,,$(subst .so,.c,$@)) $(LIBS) \
- -o $@ $(DYNAMIC_LIB_CFLAGS)
-
-clean:
- rm -f $(OBJS) $(ERLSHLIBS)
-
-distclean: clean
- rm -f Makefile
-
-TAGS:
- etags *.erl
diff --git a/ejabberd-1.1.2/src/ejabberd_zlib/Makefile.win32 b/ejabberd-1.1.2/src/ejabberd_zlib/Makefile.win32
deleted file mode 100644
index e2d05f519..000000000
--- a/ejabberd-1.1.2/src/ejabberd_zlib/Makefile.win32
+++ /dev/null
@@ -1,37 +0,0 @@
-
-include ..\Makefile.inc
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-
-OBJS = \
- $(OUTDIR)\ejabberd_zlib.beam
-
-SOURCE = ejabberd_zlib_drv.c
-OBJECT = ejabberd_zlib_drv.o
-DLL = $(OUTDIR)\ejabberd_zlib_drv.dll
-
-ALL : $(DLL) $(OBJS)
-
-CLEAN :
- -@erase $(DLL)
- -@erase $(OUTDIR)\ejabberd_zlib_drv.exp
- -@erase $(OUTDIR)\ejabberd_zlib_drv.lib
- -@erase $(OBJECT)
- -@erase $(OBJS)
-
-$(OUTDIR)\ejabberd_zlib.beam : ejabberd_zlib.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_zlib.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"$(ZLIB_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" "$(ZLIB_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/ejabberd-1.1.2/src/ejabberd_zlib/ejabberd_zlib.erl b/ejabberd-1.1.2/src/ejabberd_zlib/ejabberd_zlib.erl
deleted file mode 100644
index 2f74108df..000000000
--- a/ejabberd-1.1.2/src/ejabberd_zlib/ejabberd_zlib.erl
+++ /dev/null
@@ -1,134 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_zlib.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Interface to zlib
-%%% Created : 19 Jan 2006 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_zlib).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
-
--export([start/0, start_link/0,
- enable_zlib/2, disable_zlib/1,
- send/2,
- recv/2, recv/3, recv_data/2,
- setopts/2,
- controlling_process/2,
- close/1]).
-
-%% Internal exports, call-back functions.
--export([init/1,
- handle_call/3,
- handle_cast/2,
- handle_info/2,
- code_change/3,
- terminate/2]).
-
--define(DEFLATE, 1).
--define(INFLATE, 2).
-
--record(zlibsock, {sockmod, socket, zlibport}).
-
-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(), ejabberd_zlib_drv) of
- ok -> ok;
- {error, already_loaded} -> ok
- end,
- Port = open_port({spawn, ejabberd_zlib_drv}, [binary]),
- {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.
-
-
-enable_zlib(SockMod, Socket) ->
- case erl_ddll:load_driver(ejabberd:get_so_path(), ejabberd_zlib_drv) of
- ok -> ok;
- {error, already_loaded} -> ok
- end,
- Port = open_port({spawn, ejabberd_zlib_drv}, [binary]),
- {ok, #zlibsock{sockmod = SockMod, socket = Socket, zlibport = Port}}.
-
-disable_zlib(#zlibsock{sockmod = SockMod, socket = Socket, zlibport = Port}) ->
- port_close(Port),
- {SockMod, Socket}.
-
-recv(Socket, Length) ->
- recv(Socket, Length, infinity).
-recv(#zlibsock{sockmod = SockMod, socket = Socket} = ZlibSock,
- Length, Timeout) ->
- case SockMod:recv(Socket, Length, Timeout) of
- {ok, Packet} ->
- recv_data(ZlibSock, Packet);
- {error, _Reason} = Error ->
- Error
- end.
-
-recv_data(#zlibsock{zlibport = Port} = _ZlibSock, Packet) ->
- case port_control(Port, ?INFLATE, Packet) of
- <<0, In/binary>> ->
- {ok, In};
- <<1, Error/binary>> ->
- {error, binary_to_list(Error)}
- end.
-
-send(#zlibsock{sockmod = SockMod, socket = Socket, zlibport = Port},
- Packet) ->
- case port_control(Port, ?DEFLATE, Packet) of
- <<0, Out/binary>> ->
- SockMod:send(Socket, Out);
- <<1, Error/binary>> ->
- {error, binary_to_list(Error)}
- end.
-
-
-setopts(#zlibsock{sockmod = SockMod, socket = Socket}, Opts) ->
- case SockMod of
- gen_tcp ->
- inet:setopts(Socket, Opts);
- _ ->
- SockMod:setopts(Socket, Opts)
- end.
-
-controlling_process(#zlibsock{sockmod = SockMod, socket = Socket}, Pid) ->
- SockMod:controlling_process(Socket, Pid).
-
-close(#zlibsock{sockmod = SockMod, socket = Socket, zlibport = Port}) ->
- SockMod:close(Socket),
- port_close(Port).
-
-
diff --git a/ejabberd-1.1.2/src/ejabberd_zlib/ejabberd_zlib_drv.c b/ejabberd-1.1.2/src/ejabberd_zlib/ejabberd_zlib_drv.c
deleted file mode 100644
index 075e31176..000000000
--- a/ejabberd-1.1.2/src/ejabberd_zlib/ejabberd_zlib_drv.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/* $Id$ */
-
-#include <stdio.h>
-#include <string.h>
-#include <erl_driver.h>
-#include <zlib.h>
-
-
-#define BUF_SIZE 1024
-
-typedef struct {
- ErlDrvPort port;
- z_stream *d_stream;
- z_stream *i_stream;
-} ejabberd_zlib_data;
-
-
-static ErlDrvData ejabberd_zlib_drv_start(ErlDrvPort port, char *buff)
-{
- ejabberd_zlib_data *d =
- (ejabberd_zlib_data *)driver_alloc(sizeof(ejabberd_zlib_data));
- d->port = port;
-
- d->d_stream = (z_stream *)malloc(sizeof(z_stream));
-
- d->d_stream->zalloc = (alloc_func)0;
- d->d_stream->zfree = (free_func)0;
- d->d_stream->opaque = (voidpf)0;
-
- deflateInit(d->d_stream, Z_DEFAULT_COMPRESSION);
-
- d->i_stream = (z_stream *)malloc(sizeof(z_stream));
-
- d->i_stream->zalloc = (alloc_func)0;
- d->i_stream->zfree = (free_func)0;
- d->i_stream->opaque = (voidpf)0;
-
- inflateInit(d->i_stream);
-
- set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
-
- return (ErlDrvData)d;
-}
-
-static void ejabberd_zlib_drv_stop(ErlDrvData handle)
-{
- ejabberd_zlib_data *d = (ejabberd_zlib_data *)handle;
-
- deflateEnd(d->d_stream);
- free(d->d_stream);
-
- inflateEnd(d->i_stream);
- free(d->i_stream);
-
- driver_free((char *)handle);
-}
-
-
-#define DEFLATE 1
-#define INFLATE 2
-
-#define die_unless(cond, errstr) \
- if (!(cond)) \
- { \
- rlen = strlen(errstr) + 1; \
- b = driver_realloc_binary(b, rlen); \
- b->orig_bytes[0] = 1; \
- strncpy(b->orig_bytes + 1, errstr, rlen - 1); \
- *rbuf = (char *)b; \
- return rlen; \
- }
-
-
-static int ejabberd_zlib_drv_control(ErlDrvData handle,
- unsigned int command,
- char *buf, int len,
- char **rbuf, int rlen)
-{
- ejabberd_zlib_data *d = (ejabberd_zlib_data *)handle;
- int err;
- int size;
- ErlDrvBinary *b;
-
- switch (command)
- {
- case DEFLATE:
- size = BUF_SIZE + 1;
- rlen = 1;
- b = driver_alloc_binary(size);
- b->orig_bytes[0] = 0;
-
- d->d_stream->next_in = buf;
- d->d_stream->avail_in = len;
- d->d_stream->avail_out = 0;
- err = Z_OK;
-
- while (err == Z_OK && d->d_stream->avail_out == 0)
- {
- d->d_stream->next_out = b->orig_bytes + rlen;
- d->d_stream->avail_out = BUF_SIZE;
-
- err = deflate(d->d_stream, Z_SYNC_FLUSH);
- die_unless((err == Z_OK) || (err == Z_STREAM_END),
- "Deflate error");
-
- rlen += (BUF_SIZE - d->d_stream->avail_out);
- size += (BUF_SIZE - d->d_stream->avail_out);
- b = driver_realloc_binary(b, size);
- }
- b = driver_realloc_binary(b, rlen);
- *rbuf = (char *)b;
- return rlen;
- case INFLATE:
- size = BUF_SIZE + 1;
- rlen = 1;
- b = driver_alloc_binary(size);
- b->orig_bytes[0] = 0;
-
- if (len > 0) {
- d->i_stream->next_in = buf;
- d->i_stream->avail_in = len;
- d->i_stream->avail_out = 0;
- err = Z_OK;
-
- while (err == Z_OK && d->i_stream->avail_out == 0)
- {
- d->i_stream->next_out = b->orig_bytes + rlen;
- d->i_stream->avail_out = BUF_SIZE;
-
- err = inflate(d->i_stream, Z_SYNC_FLUSH);
- die_unless((err == Z_OK) || (err == Z_STREAM_END),
- "Inflate error");
-
- rlen += (BUF_SIZE - d->i_stream->avail_out);
- size += (BUF_SIZE - d->i_stream->avail_out);
- b = driver_realloc_binary(b, size);
- }
- }
- b = driver_realloc_binary(b, rlen);
- *rbuf = (char *)b;
- return rlen;
- }
-
- b = driver_alloc_binary(1);
- b->orig_bytes[0] = 0;
- *rbuf = (char *)b;
- return 1;
-}
-
-
-ErlDrvEntry ejabberd_zlib_driver_entry = {
- NULL, /* F_PTR init, N/A */
- ejabberd_zlib_drv_start, /* L_PTR start, called when port is opened */
- ejabberd_zlib_drv_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 */
- "ejabberd_zlib_drv", /* char *driver_name, the argument to open_port */
- NULL, /* F_PTR finish, called when unloaded */
- NULL, /* handle */
- ejabberd_zlib_drv_control, /* F_PTR control, port_command callback */
- NULL, /* F_PTR timeout, reserved */
- NULL /* F_PTR outputv, reserved */
-};
-
-DRIVER_INIT(ejabberd_zlib_drv) /* must match name in driver_entry */
-{
- return &ejabberd_zlib_driver_entry;
-}
-
-
diff --git a/ejabberd-1.1.2/src/ejd2odbc.erl b/ejabberd-1.1.2/src/ejd2odbc.erl
deleted file mode 100644
index 8a7f6ada0..000000000
--- a/ejabberd-1.1.2/src/ejd2odbc.erl
+++ /dev/null
@@ -1,310 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejd2odbc.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Export some mnesia tables to SQL DB
-%%% Created : 22 Aug 2005 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejd2odbc).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
-%% External exports
--export([export_passwd/2,
- export_roster/2,
- export_offline/2,
- export_last/2,
- export_vcard/2,
- export_vcard_search/2]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include("mod_roster.hrl").
-
--record(offline_msg, {us, timestamp, expire, from, to, packet}).
--record(last_activity, {us, timestamp, status}).
--record(vcard, {us, vcard}).
--record(vcard_search, {us,
- user, luser,
- fn, lfn,
- family, lfamily,
- given, lgiven,
- middle, lmiddle,
- nickname, lnickname,
- bday, lbday,
- ctry, lctry,
- locality, llocality,
- email, lemail,
- orgname, lorgname,
- orgunit, lorgunit
- }).
-
--define(MAX_RECORDS_PER_TRANSACTION, 1000).
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-
-export_passwd(Server, Output) ->
- export_common(
- Server, passwd, Output,
- fun(Host, {passwd, {LUser, LServer}, Password} = R)
- when LServer == Host ->
- Username = ejabberd_odbc:escape(LUser),
- Pass = ejabberd_odbc:escape(Password),
- ["delete from users where username='", Username ,"';"
- "insert into users(username, password) "
- "values ('", Username, "', '", Pass, "');"];
- (_Host, _R) ->
- []
- end).
-
-export_roster(Server, Output) ->
- export_common(
- Server, roster, Output,
- fun(Host, #roster{usj = {LUser, LServer, LJID}} = R)
- when LServer == Host ->
- Username = ejabberd_odbc:escape(LUser),
- SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)),
- ItemVals = record_to_string(R),
- ItemGroups = groups_to_string(R),
- ["delete from rosterusers "
- " where username='", Username, "' "
- " and jid='", SJID, "';"
- "insert into rosterusers("
- " username, jid, nick, "
- " subscription, ask, askmessage, "
- " server, subscribe, type) "
- " values ", ItemVals, ";"
- "delete from rostergroups "
- " where username='", Username, "' "
- " and jid='", SJID, "';",
- [["insert into rostergroups("
- " username, jid, grp) "
- " values ", ItemGroup, ";"] ||
- ItemGroup <- ItemGroups]];
- (_Host, _R) ->
- []
- end).
-
-export_offline(Server, Output) ->
- export_common(
- Server, offline_msg, Output,
- fun(Host, #offline_msg{us = {LUser, LServer},
- timestamp = TimeStamp,
- from = From,
- to = To,
- packet = Packet})
- when LServer == Host ->
- Username = ejabberd_odbc:escape(LUser),
- {xmlelement, Name, Attrs, Els} = Packet,
- Attrs2 = jlib:replace_from_to_attrs(
- jlib:jid_to_string(From),
- jlib:jid_to_string(To),
- Attrs),
- NewPacket = {xmlelement, Name, Attrs2,
- Els ++
- [jlib:timestamp_to_xml(
- calendar:now_to_universal_time(TimeStamp))]},
- XML =
- ejabberd_odbc:escape(
- lists:flatten(
- xml:element_to_string(NewPacket))),
- ["insert into spool(username, xml) "
- "values ('", Username, "', '",
- XML,
- "');"];
- (_Host, _R) ->
- []
- end).
-
-export_last(Server, Output) ->
- export_common(
- Server, last_activity, Output,
- fun(Host, #last_activity{us = {LUser, LServer},
- timestamp = TimeStamp,
- status = Status})
- when LServer == Host ->
- Username = ejabberd_odbc:escape(LUser),
- Seconds = ejabberd_odbc:escape(integer_to_list(TimeStamp)),
- State = ejabberd_odbc:escape(Status),
- ["delete from last where username='", Username, "';"
- "insert into last(username, seconds, state) "
- "values ('", Username, "', '", Seconds, "', '", State, "');"];
- (_Host, _R) ->
- []
- end).
-
-export_vcard(Server, Output) ->
- export_common(
- Server, vcard, Output,
- fun(Host, #vcard{us = {LUser, LServer},
- vcard = VCARD})
- when LServer == Host ->
- Username = ejabberd_odbc:escape(LUser),
- SVCARD = ejabberd_odbc:escape(
- lists:flatten(xml:element_to_string(VCARD))),
- ["delete from vcard where username='", Username, "';"
- "insert into vcard(username, vcard) "
- "values ('", Username, "', '", SVCARD, "');"];
- (_Host, _R) ->
- []
- end).
-
-export_vcard_search(Server, Output) ->
- export_common(
- Server, vcard_search, Output,
- fun(Host, #vcard_search{user = {User, LServer},
- luser = LUser,
- fn = FN, lfn = LFN,
- family = Family, lfamily = LFamily,
- given = Given, lgiven = LGiven,
- middle = Middle, lmiddle = LMiddle,
- nickname = Nickname, lnickname = LNickname,
- bday = BDay, lbday = LBDay,
- ctry = CTRY, lctry = LCTRY,
- locality = Locality, llocality = LLocality,
- email = EMail, lemail = LEMail,
- orgname = OrgName, lorgname = LOrgName,
- orgunit = OrgUnit, lorgunit = LOrgUnit
- })
- when LServer == Host ->
- Username = ejabberd_odbc:escape(User),
- LUsername = ejabberd_odbc:escape(LUser),
-
- SFN = ejabberd_odbc:escape(FN),
- SLFN = ejabberd_odbc:escape(LFN),
- SFamily = ejabberd_odbc:escape(Family),
- SLFamily = ejabberd_odbc:escape(LFamily),
- SGiven = ejabberd_odbc:escape(Given),
- SLGiven = ejabberd_odbc:escape(LGiven),
- SMiddle = ejabberd_odbc:escape(Middle),
- SLMiddle = ejabberd_odbc:escape(LMiddle),
- SNickname = ejabberd_odbc:escape(Nickname),
- SLNickname = ejabberd_odbc:escape(LNickname),
- SBDay = ejabberd_odbc:escape(BDay),
- SLBDay = ejabberd_odbc:escape(LBDay),
- SCTRY = ejabberd_odbc:escape(CTRY),
- SLCTRY = ejabberd_odbc:escape(LCTRY),
- SLocality = ejabberd_odbc:escape(Locality),
- SLLocality = ejabberd_odbc:escape(LLocality),
- SEMail = ejabberd_odbc:escape(EMail),
- SLEMail = ejabberd_odbc:escape(LEMail),
- SOrgName = ejabberd_odbc:escape(OrgName),
- SLOrgName = ejabberd_odbc:escape(LOrgName),
- SOrgUnit = ejabberd_odbc:escape(OrgUnit),
- SLOrgUnit = ejabberd_odbc:escape(LOrgUnit),
-
- ["delete from vcard_search where lusername='", LUsername, "';"
- "insert into vcard_search("
- " username, lusername, fn, lfn, family, lfamily,"
- " given, lgiven, middle, lmiddle, nickname, lnickname,"
- " bday, lbday, ctry, lctry, locality, llocality,"
- " email, lemail, orgname, lorgname, orgunit, lorgunit)"
- "values (",
- " '", Username, "', '", LUsername, "',"
- " '", SFN, "', '", SLFN, "',"
- " '", SFamily, "', '", SLFamily, "',"
- " '", SGiven, "', '", SLGiven, "',"
- " '", SMiddle, "', '", SLMiddle, "',"
- " '", SNickname, "', '", SLNickname, "',"
- " '", SBDay, "', '", SLBDay, "',"
- " '", SCTRY, "', '", SLCTRY, "',"
- " '", SLocality, "', '", SLLocality, "',"
- " '", SEMail, "', '", SLEMail, "',"
- " '", SOrgName, "', '", SLOrgName, "',"
- " '", SOrgUnit, "', '", SLOrgUnit, "');"];
- (_Host, _R) ->
- []
- end).
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-
-export_common(Server, Table, Output, ConvertFun) ->
- IO = case Output of
- odbc ->
- odbc;
- _ ->
- {ok, IODevice} = file:open(Output, [write, raw]),
- IODevice
- end,
- mnesia:transaction(
- fun() ->
- mnesia:read_lock_table(Table),
- LServer = jlib:nameprep(Server),
- {_N, SQLs} =
- mnesia:foldl(
- fun(R, {N, SQLs} = Acc) ->
- case ConvertFun(LServer, R) of
- [] ->
- Acc;
- SQL ->
- if
- N < ?MAX_RECORDS_PER_TRANSACTION - 1 ->
- {N + 1, [SQL | SQLs]};
- true ->
- output(LServer, IO,
- ["begin;",
- lists:reverse([SQL | SQLs]),
- "commit"]),
- {0, []}
- end
- end
- end, {0, []}, Table),
- output(LServer, IO,
- ["begin;",
- lists:reverse(SQLs),
- "commit"])
- end).
-
-output(LServer, IO, SQL) ->
- case IO of
- odbc ->
- catch ejabberd_odbc:sql_query(LServer, SQL);
- _ ->
- file:write(IO, [SQL, $;, $\n])
- end.
-
-record_to_string(#roster{usj = {User, Server, JID},
- name = Name,
- subscription = Subscription,
- ask = Ask,
- askmessage = AskMessage}) ->
- Username = ejabberd_odbc:escape(User),
- SJID = ejabberd_odbc:escape(jlib:jid_to_string(JID)),
- Nick = ejabberd_odbc:escape(Name),
- SSubscription = case Subscription of
- both -> "B";
- to -> "T";
- from -> "F";
- none -> "N"
- end,
- SAsk = case Ask of
- subscribe -> "S";
- unsubscribe -> "U";
- both -> "B";
- out -> "O";
- in -> "I";
- none -> "N"
- end,
- ["("
- "'", Username, "',"
- "'", SJID, "',"
- "'", Nick, "',"
- "'", SSubscription, "',"
- "'", SAsk, "',"
- "'", AskMessage, "',"
- "'N', '', 'item')"].
-
-groups_to_string(#roster{usj = {User, Server, JID},
- groups = Groups}) ->
- Username = ejabberd_odbc:escape(User),
- SJID = ejabberd_odbc:escape(jlib:jid_to_string(JID)),
- [["("
- "'", Username, "',"
- "'", SJID, "',"
- "'", ejabberd_odbc:escape(Group), "')"] || Group <- Groups].
-
diff --git a/ejabberd-1.1.2/src/eldap/ELDAPv3.asn b/ejabberd-1.1.2/src/eldap/ELDAPv3.asn
deleted file mode 100644
index 0cfac48c3..000000000
--- a/ejabberd-1.1.2/src/eldap/ELDAPv3.asn
+++ /dev/null
@@ -1,291 +0,0 @@
--- LDAPv3 ASN.1 specification, taken from RFC 2251
-
--- Lightweight-Directory-Access-Protocol-V3 DEFINITIONS
-ELDAPv3 DEFINITIONS
-IMPLICIT TAGS ::=
-
-BEGIN
-
-LDAPMessage ::= SEQUENCE {
- messageID MessageID,
- protocolOp CHOICE {
- bindRequest BindRequest,
- bindResponse BindResponse,
- unbindRequest UnbindRequest,
- searchRequest SearchRequest,
- searchResEntry SearchResultEntry,
- searchResDone SearchResultDone,
- searchResRef SearchResultReference,
- modifyRequest ModifyRequest,
- modifyResponse ModifyResponse,
- addRequest AddRequest,
- addResponse AddResponse,
- delRequest DelRequest,
- delResponse DelResponse,
- modDNRequest ModifyDNRequest,
- modDNResponse ModifyDNResponse,
- compareRequest CompareRequest,
- compareResponse CompareResponse,
- abandonRequest AbandonRequest,
- extendedReq ExtendedRequest,
- extendedResp ExtendedResponse },
- controls [0] Controls OPTIONAL }
-
-MessageID ::= INTEGER (0 .. maxInt)
-
-maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) --
-
-LDAPString ::= OCTET STRING
-
-LDAPOID ::= OCTET STRING
-
-LDAPDN ::= LDAPString
-
-RelativeLDAPDN ::= LDAPString
-
-AttributeType ::= LDAPString
-
-AttributeDescription ::= LDAPString
-
-
-
-
--- Wahl, et. al. Standards Track [Page 44]
---
--- RFC 2251 LDAPv3 December 1997
-
-
-AttributeDescriptionList ::= SEQUENCE OF
- AttributeDescription
-
-AttributeValue ::= OCTET STRING
-
-AttributeValueAssertion ::= SEQUENCE {
- attributeDesc AttributeDescription,
- assertionValue AssertionValue }
-
-AssertionValue ::= OCTET STRING
-
-Attribute ::= SEQUENCE {
- type AttributeDescription,
- vals SET OF AttributeValue }
-
-MatchingRuleId ::= LDAPString
-
-LDAPResult ::= SEQUENCE {
- resultCode ENUMERATED {
- success (0),
- operationsError (1),
- protocolError (2),
- timeLimitExceeded (3),
- sizeLimitExceeded (4),
- compareFalse (5),
- compareTrue (6),
- authMethodNotSupported (7),
- strongAuthRequired (8),
- -- 9 reserved --
- referral (10), -- new
- adminLimitExceeded (11), -- new
- unavailableCriticalExtension (12), -- new
- confidentialityRequired (13), -- new
- saslBindInProgress (14), -- new
- noSuchAttribute (16),
- undefinedAttributeType (17),
- inappropriateMatching (18),
- constraintViolation (19),
- attributeOrValueExists (20),
- invalidAttributeSyntax (21),
- -- 22-31 unused --
- noSuchObject (32),
- aliasProblem (33),
- invalidDNSyntax (34),
- -- 35 reserved for undefined isLeaf --
- aliasDereferencingProblem (36),
- -- 37-47 unused --
- inappropriateAuthentication (48),
-
--- Wahl, et. al. Standards Track [Page 45]
---
--- RFC 2251 LDAPv3 December 1997
-
-
- invalidCredentials (49),
- insufficientAccessRights (50),
- busy (51),
- unavailable (52),
- unwillingToPerform (53),
- loopDetect (54),
- -- 55-63 unused --
- namingViolation (64),
- objectClassViolation (65),
- notAllowedOnNonLeaf (66),
- notAllowedOnRDN (67),
- entryAlreadyExists (68),
- objectClassModsProhibited (69),
- -- 70 reserved for CLDAP --
- affectsMultipleDSAs (71), -- new
- -- 72-79 unused --
- other (80) },
- -- 81-90 reserved for APIs --
- matchedDN LDAPDN,
- errorMessage LDAPString,
- referral [3] Referral OPTIONAL }
-
-Referral ::= SEQUENCE OF LDAPURL
-
-LDAPURL ::= LDAPString -- limited to characters permitted in URLs
-
-Controls ::= SEQUENCE OF Control
-
-Control ::= SEQUENCE {
- controlType LDAPOID,
- criticality BOOLEAN DEFAULT FALSE,
- controlValue OCTET STRING OPTIONAL }
-
-BindRequest ::= [APPLICATION 0] SEQUENCE {
- version INTEGER (1 .. 127),
- name LDAPDN,
- authentication AuthenticationChoice }
-
-AuthenticationChoice ::= CHOICE {
- simple [0] OCTET STRING,
- -- 1 and 2 reserved
- sasl [3] SaslCredentials }
-
-SaslCredentials ::= SEQUENCE {
- mechanism LDAPString,
- credentials OCTET STRING OPTIONAL }
-
-BindResponse ::= [APPLICATION 1] SEQUENCE {
-
--- Wahl, et. al. Standards Track [Page 46]
---
--- RFC 2251 LDAPv3 December 1997
-
-
- COMPONENTS OF LDAPResult,
- serverSaslCreds [7] OCTET STRING OPTIONAL }
-
-UnbindRequest ::= [APPLICATION 2] NULL
-
-SearchRequest ::= [APPLICATION 3] SEQUENCE {
- baseObject LDAPDN,
- scope ENUMERATED {
- baseObject (0),
- singleLevel (1),
- wholeSubtree (2) },
- derefAliases ENUMERATED {
- neverDerefAliases (0),
- derefInSearching (1),
- derefFindingBaseObj (2),
- derefAlways (3) },
- sizeLimit INTEGER (0 .. maxInt),
- timeLimit INTEGER (0 .. maxInt),
- typesOnly BOOLEAN,
- filter Filter,
- attributes AttributeDescriptionList }
-
-Filter ::= CHOICE {
- and [0] SET OF Filter,
- or [1] SET OF Filter,
- not [2] Filter,
- equalityMatch [3] AttributeValueAssertion,
- substrings [4] SubstringFilter,
- greaterOrEqual [5] AttributeValueAssertion,
- lessOrEqual [6] AttributeValueAssertion,
- present [7] AttributeDescription,
- approxMatch [8] AttributeValueAssertion,
- extensibleMatch [9] MatchingRuleAssertion }
-
-SubstringFilter ::= SEQUENCE {
- type AttributeDescription,
- -- at least one must be present
- substrings SEQUENCE OF CHOICE {
- initial [0] LDAPString,
- any [1] LDAPString,
- final [2] LDAPString } }
-
-MatchingRuleAssertion ::= SEQUENCE {
- matchingRule [1] MatchingRuleId OPTIONAL,
- type [2] AttributeDescription OPTIONAL,
- matchValue [3] AssertionValue,
- dnAttributes [4] BOOLEAN DEFAULT FALSE }
-
--- Wahl, et. al. Standards Track [Page 47]
---
--- RFC 2251 LDAPv3 December 1997
-
-SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
- objectName LDAPDN,
- attributes PartialAttributeList }
-
-PartialAttributeList ::= SEQUENCE OF SEQUENCE {
- type AttributeDescription,
- vals SET OF AttributeValue }
-
-SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
-
-SearchResultDone ::= [APPLICATION 5] LDAPResult
-
-ModifyRequest ::= [APPLICATION 6] SEQUENCE {
- object LDAPDN,
- modification SEQUENCE OF SEQUENCE {
- operation ENUMERATED {
- add (0),
- delete (1),
- replace (2) },
- modification AttributeTypeAndValues } }
-
-AttributeTypeAndValues ::= SEQUENCE {
- type AttributeDescription,
- vals SET OF AttributeValue }
-
-ModifyResponse ::= [APPLICATION 7] LDAPResult
-
-AddRequest ::= [APPLICATION 8] SEQUENCE {
- entry LDAPDN,
- attributes AttributeList }
-
-AttributeList ::= SEQUENCE OF SEQUENCE {
- type AttributeDescription,
- vals SET OF AttributeValue }
-
-AddResponse ::= [APPLICATION 9] LDAPResult
-
-DelRequest ::= [APPLICATION 10] LDAPDN
-
-DelResponse ::= [APPLICATION 11] LDAPResult
-
-ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
- entry LDAPDN,
- newrdn RelativeLDAPDN,
- deleteoldrdn BOOLEAN,
- newSuperior [0] LDAPDN OPTIONAL }
-
-ModifyDNResponse ::= [APPLICATION 13] LDAPResult
-
--- Wahl, et. al. Standards Track [Page 48]
---
--- RFC 2251 LDAPv3 December 1997
-
-
-CompareRequest ::= [APPLICATION 14] SEQUENCE {
- entry LDAPDN,
- ava AttributeValueAssertion }
-
-CompareResponse ::= [APPLICATION 15] LDAPResult
-
-AbandonRequest ::= [APPLICATION 16] MessageID
-
-ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
- requestName [0] LDAPOID,
- requestValue [1] OCTET STRING OPTIONAL }
-
-ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
- COMPONENTS OF LDAPResult,
- responseName [10] LDAPOID OPTIONAL,
- response [11] OCTET STRING OPTIONAL }
-
-END
-
-
diff --git a/ejabberd-1.1.2/src/eldap/Makefile.in b/ejabberd-1.1.2/src/eldap/Makefile.in
deleted file mode 100644
index 72e7b4632..000000000
--- a/ejabberd-1.1.2/src/eldap/Makefile.in
+++ /dev/null
@@ -1,39 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@ @ERLANG_CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@ @ERLANG_LIBS@
-
-SUBDIRS =
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-OBJS = \
- $(OUTDIR)/eldap.beam \
- $(OUTDIR)/ELDAPv3.beam \
- $(OUTDIR)/eldap_filter.beam
-
-all: $(OBJS)
-
-ELDAPv3.erl: ELDAPv3.asn
- @ERLC@ -bber_bin -W $(EFLAGS) $<
-
-$(OUTDIR)/%.beam: %.erl ELDAPv3.erl
- @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-
-clean:
- rm -f ELDAPv3.asn1db
- rm -f ELDAPv3.erl
- rm -f ELDAPv3.hrl
- rm -f ELDAPv3.beam
- rm -f $(OBJS)
-
-distclean: clean
- rm -f Makefile
-
-TAGS:
- etags *.erl
-
diff --git a/ejabberd-1.1.2/src/eldap/Makefile.win32 b/ejabberd-1.1.2/src/eldap/Makefile.win32
deleted file mode 100644
index 5d737d05a..000000000
--- a/ejabberd-1.1.2/src/eldap/Makefile.win32
+++ /dev/null
@@ -1,28 +0,0 @@
-
-include ..\Makefile.inc
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-
-OBJS = \
- $(OUTDIR)\eldap.beam \
- $(OUTDIR)\ELDAPv3.beam \
- $(OUTDIR)\eldap_filter.beam
-
-ALL : $(OBJS)
-
-CLEAN :
- -@erase ELDAPv3.asn1db
- -@erase ELDAPv3.erl
- -@erase ELDAPv3.hrl
- -@erase ELDAPv3.beam
- -@erase $(OBJS)
-
-ELDAPv3.erl : ELDAPv3.asn
- erlc -bber_bin -W $(EFLAGS) ELDAPv3.asn
-
-$(OUTDIR)\eldap.beam : eldap.erl ELDAPv3.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) eldap.erl
-
-$(OUTDIR)\ELDAPv3.beam : ELDAPv3.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) ELDAPv3.erl
diff --git a/ejabberd-1.1.2/src/eldap/eldap.erl b/ejabberd-1.1.2/src/eldap/eldap.erl
deleted file mode 100644
index 894982e82..000000000
--- a/ejabberd-1.1.2/src/eldap/eldap.erl
+++ /dev/null
@@ -1,995 +0,0 @@
--module(eldap).
-%%% --------------------------------------------------------------------
-%%% Created: 12 Oct 2000 by Tobbe <tnt@home.se>
-%%% Function: Erlang client LDAP implementation according RFC 2251.
-%%% The interface is based on RFC 1823, and
-%%% draft-ietf-asid-ldap-c-api-00.txt
-%%%
-%%% Copyright (C) 2000 Torbjrn Trnkvist, tnt@home.se
-%%%
-%%% 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
-
-
-%%% Modified by Sean Hinde <shinde@iee.org> 7th Dec 2000
-%%% Turned into gen_fsm, made non-blocking, added timers etc to support this.
-%%% Now has the concept of a name (string() or atom()) per instance which allows
-%%% multiple users to call by name if so desired.
-%%%
-%%% Can be configured with start_link parameters or use a config file to get
-%%% host to connect to, dn, password, log function etc.
-
-
-%%% Modified by Alexey Shchepin <alexey@sevcom.net>
-%%% --------------------------------------------------------------------
--vc('$Id$ ').
-
-
-%%%----------------------------------------------------------------------
-%%% LDAP Client state machine.
-%%% Possible states are:
-%%% connecting - actually disconnected, but retrying periodically
-%%% wait_bind_response - connected and sent bind request
-%%% active - bound to LDAP Server and ready to handle commands
-%%%----------------------------------------------------------------------
-
-%%-compile(export_all).
-%%-export([Function/Arity, ...]).
-
--behaviour(gen_fsm).
-
-%% External exports
--export([start_link/1, start_link/5, start_link/6]).
-
--export([baseObject/0,singleLevel/0,wholeSubtree/0,close/1,
- equalityMatch/2,greaterOrEqual/2,lessOrEqual/2,
- approxMatch/2,search/2,substrings/2,present/1,
- 'and'/1,'or'/1,'not'/1,modify/3, mod_add/2, mod_delete/2,
- mod_replace/2, add/3, delete/2, modify_dn/5, bind/3]).
--export([debug_level/2, get_status/1]).
-
-%% gen_fsm callbacks
--export([init/1, connecting/2,
- connecting/3, wait_bind_response/3, active/3, handle_event/3,
- handle_sync_event/4, handle_info/3, terminate/3, code_change/4]).
-
-
--import(lists,[concat/1]).
-
--include("ELDAPv3.hrl").
--include("eldap.hrl").
-
--define(LDAP_VERSION, 3).
--define(RETRY_TIMEOUT, 5000).
--define(BIND_TIMEOUT, 10000).
--define(CMD_TIMEOUT, 5000).
--define(MAX_TRANSACTION_ID, 65535).
--define(MIN_TRANSACTION_ID, 0).
-
--record(eldap, {version = ?LDAP_VERSION,
- hosts, % Possible hosts running LDAP servers
- host = null, % Connected Host LDAP server
- port = 389 , % The LDAP server port
- fd = null, % Socket filedescriptor.
- rootdn = "", % Name of the entry to bind as
- passwd, % Password for (above) entry
- id = 0, % LDAP Request ID
- log, % User provided log function
- bind_timer, % Ref to bind timeout
- dict, % dict holding operation params and results
- debug_level % Integer debug/logging level
- }).
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-start_link(Name) ->
- Reg_name = list_to_atom("eldap_" ++ Name),
- gen_fsm:start_link({local, Reg_name}, ?MODULE, [], []).
-
-start_link(Name, Hosts, Port, Rootdn, Passwd) ->
- Log = fun(N, Fmt, Args) -> io:format("---- " ++ Fmt, [Args]) end,
- Reg_name = list_to_atom("eldap_" ++ Name),
- gen_fsm:start_link({local, Reg_name}, ?MODULE, {Hosts, Port, Rootdn, Passwd, Log}, []).
-
-start_link(Name, Hosts, Port, Rootdn, Passwd, Log) ->
- Reg_name = list_to_atom("eldap_" ++ Name),
- gen_fsm:start_link({local, Reg_name}, ?MODULE, {Hosts, Port, Rootdn, Passwd, Log}, []).
-
-%%% --------------------------------------------------------------------
-%%% Set Debug Level. 0 - none, 1 - errors, 2 - ldap events
-%%% --------------------------------------------------------------------
-debug_level(Handle, N) when integer(N) ->
- Handle1 = get_handle(Handle),
- gen_fsm:sync_send_all_state_event(Handle1, {debug_level,N}).
-
-%%% --------------------------------------------------------------------
-%%% Get status of connection.
-%%% --------------------------------------------------------------------
-get_status(Handle) ->
- Handle1 = get_handle(Handle),
- gen_fsm:sync_send_all_state_event(Handle1, get_status).
-
-%%% --------------------------------------------------------------------
-%%% Shutdown connection (and process) asynchronous.
-%%% --------------------------------------------------------------------
-close(Handle) ->
- Handle1 = get_handle(Handle),
- gen_fsm:send_all_state_event(Handle1, close).
-
-%%% --------------------------------------------------------------------
-%%% Add an entry. The entry field MUST NOT exist for the AddRequest
-%%% to succeed. The parent of the entry MUST exist.
-%%% Example:
-%%%
-%%% add(Handle,
-%%% "cn=Bill Valentine, ou=people, o=Bluetail AB, dc=bluetail, dc=com",
-%%% [{"objectclass", ["person"]},
-%%% {"cn", ["Bill Valentine"]},
-%%% {"sn", ["Valentine"]},
-%%% {"telephoneNumber", ["545 555 00"]}]
-%%% )
-%%% --------------------------------------------------------------------
-add(Handle, Entry, Attributes) when list(Entry),list(Attributes) ->
- Handle1 = get_handle(Handle),
- gen_fsm:sync_send_event(Handle1, {add, Entry, add_attrs(Attributes)}).
-
-%%% Do sanity check !
-add_attrs(Attrs) ->
- F = fun({Type,Vals}) when list(Type),list(Vals) ->
- %% Confused ? Me too... :-/
- {'AddRequest_attributes',Type, Vals}
- end,
- case catch lists:map(F, Attrs) of
- {'EXIT', _} -> throw({error, attribute_values});
- Else -> Else
- end.
-
-
-%%% --------------------------------------------------------------------
-%%% Delete an entry. The entry consists of the DN of
-%%% the entry to be deleted.
-%%% Example:
-%%%
-%%% delete(Handle,
-%%% "cn=Bill Valentine, ou=people, o=Bluetail AB, dc=bluetail, dc=com"
-%%% )
-%%% --------------------------------------------------------------------
-delete(Handle, Entry) when list(Entry) ->
- Handle1 = get_handle(Handle),
- gen_fsm:sync_send_event(Handle1, {delete, Entry}).
-
-%%% --------------------------------------------------------------------
-%%% Modify an entry. Given an entry a number of modification
-%%% operations can be performed as one atomic operation.
-%%% Example:
-%%%
-%%% modify(Handle,
-%%% "cn=Torbjorn Tornkvist, ou=people, o=Bluetail AB, dc=bluetail, dc=com",
-%%% [replace("telephoneNumber", ["555 555 00"]),
-%%% add("description", ["LDAP hacker"])]
-%%% )
-%%% --------------------------------------------------------------------
-modify(Handle, Object, Mods) when list(Object), list(Mods) ->
- Handle1 = get_handle(Handle),
- gen_fsm:sync_send_event(Handle1, {modify, Object, Mods}).
-
-%%%
-%%% Modification operations.
-%%% Example:
-%%% replace("telephoneNumber", ["555 555 00"])
-%%%
-mod_add(Type, Values) when list(Type), list(Values) -> m(add, Type, Values).
-mod_delete(Type, Values) when list(Type), list(Values) -> m(delete, Type, Values).
-mod_replace(Type, Values) when list(Type), list(Values) -> m(replace, Type, Values).
-
-m(Operation, Type, Values) ->
- #'ModifyRequest_modification_SEQOF'{
- operation = Operation,
- modification = #'AttributeTypeAndValues'{
- type = Type,
- vals = Values}}.
-
-%%% --------------------------------------------------------------------
-%%% Modify an entry. Given an entry a number of modification
-%%% operations can be performed as one atomic operation.
-%%% Example:
-%%%
-%%% modify_dn(Handle,
-%%% "cn=Bill Valentine, ou=people, o=Bluetail AB, dc=bluetail, dc=com",
-%%% "cn=Ben Emerson",
-%%% true,
-%%% ""
-%%% )
-%%% --------------------------------------------------------------------
-modify_dn(Handle, Entry, NewRDN, DelOldRDN, NewSup)
- when list(Entry),list(NewRDN),atom(DelOldRDN),list(NewSup) ->
- Handle1 = get_handle(Handle),
- gen_fsm:sync_send_event(Handle1, {modify_dn, Entry, NewRDN, bool_p(DelOldRDN), optional(NewSup)}).
-
-
-%%% --------------------------------------------------------------------
-%%% Bind.
-%%% Example:
-%%%
-%%% bind(Handle,
-%%% "cn=Bill Valentine, ou=people, o=Bluetail AB, dc=bluetail, dc=com",
-%%% "secret")
-%%% --------------------------------------------------------------------
-bind(Handle, RootDN, Passwd)
- when list(RootDN),list(Passwd) ->
- Handle1 = get_handle(Handle),
- gen_fsm:sync_send_event(Handle1, {bind, RootDN, Passwd}).
-
-%%% Sanity checks !
-
-bool_p(Bool) when Bool==true;Bool==false -> Bool.
-
-optional([]) -> asn1_NOVALUE;
-optional(Value) -> Value.
-
-%%% --------------------------------------------------------------------
-%%% Synchronous search of the Directory returning a
-%%% requested set of attributes.
-%%%
-%%% Example:
-%%%
-%%% Filter = eldap:substrings("sn", [{any,"o"}]),
-%%% eldap:search(S, [{base, "dc=bluetail, dc=com"},
-%%% {filter, Filter},
-%%% {attributes,["cn"]}])),
-%%%
-%%% Returned result: {ok, #eldap_search_result{}}
-%%%
-%%% Example:
-%%%
-%%% {ok,{eldap_search_result,
-%%% [{eldap_entry,
-%%% "cn=Magnus Froberg, dc=bluetail, dc=com",
-%%% [{"cn",["Magnus Froberg"]}]},
-%%% {eldap_entry,
-%%% "cn=Torbjorn Tornkvist, dc=bluetail, dc=com",
-%%% [{"cn",["Torbjorn Tornkvist"]}]}],
-%%% []}}
-%%%
-%%% --------------------------------------------------------------------
-search(Handle, A) when record(A, eldap_search) ->
- call_search(Handle, A);
-search(Handle, L) when list(Handle), list(L) ->
- case catch parse_search_args(L) of
- {error, Emsg} -> {error, Emsg};
- {'EXIT', Emsg} -> {error, Emsg};
- A when record(A, eldap_search) -> call_search(Handle, A)
- end.
-
-call_search(Handle, A) ->
- Handle1 = get_handle(Handle),
- gen_fsm:sync_send_event(Handle1, {search, A}).
-
-parse_search_args(Args) ->
- parse_search_args(Args, #eldap_search{scope = wholeSubtree}).
-
-parse_search_args([{base, Base}|T],A) ->
- parse_search_args(T,A#eldap_search{base = Base});
-parse_search_args([{filter, Filter}|T],A) ->
- parse_search_args(T,A#eldap_search{filter = Filter});
-parse_search_args([{scope, Scope}|T],A) ->
- parse_search_args(T,A#eldap_search{scope = Scope});
-parse_search_args([{attributes, Attrs}|T],A) ->
- parse_search_args(T,A#eldap_search{attributes = Attrs});
-parse_search_args([{types_only, TypesOnly}|T],A) ->
- parse_search_args(T,A#eldap_search{types_only = TypesOnly});
-parse_search_args([{timeout, Timeout}|T],A) when integer(Timeout) ->
- parse_search_args(T,A#eldap_search{timeout = Timeout});
-parse_search_args([H|T],A) ->
- throw({error,{unknown_arg, H}});
-parse_search_args([],A) ->
- A.
-
-%%%
-%%% The Scope parameter
-%%%
-baseObject() -> baseObject.
-singleLevel() -> singleLevel.
-wholeSubtree() -> wholeSubtree.
-
-%%%
-%%% Boolean filter operations
-%%%
-'and'(ListOfFilters) when list(ListOfFilters) -> {'and',ListOfFilters}.
-'or'(ListOfFilters) when list(ListOfFilters) -> {'or', ListOfFilters}.
-'not'(Filter) when tuple(Filter) -> {'not',Filter}.
-
-%%%
-%%% The following Filter parameters consist of an attribute
-%%% and an attribute value. Example: F("uid","tobbe")
-%%%
-equalityMatch(Desc, Value) -> {equalityMatch, av_assert(Desc, Value)}.
-greaterOrEqual(Desc, Value) -> {greaterOrEqual, av_assert(Desc, Value)}.
-lessOrEqual(Desc, Value) -> {lessOrEqual, av_assert(Desc, Value)}.
-approxMatch(Desc, Value) -> {approxMatch, av_assert(Desc, Value)}.
-
-av_assert(Desc, Value) ->
- #'AttributeValueAssertion'{attributeDesc = Desc,
- assertionValue = Value}.
-
-%%%
-%%% Filter to check for the presence of an attribute
-%%%
-present(Attribute) when list(Attribute) ->
- {present, Attribute}.
-
-
-%%%
-%%% A substring filter seem to be based on a pattern:
-%%%
-%%% InitValue*AnyValue*FinalValue
-%%%
-%%% where all three parts seem to be optional (at least when
-%%% talking with an OpenLDAP server). Thus, the arguments
-%%% to substrings/2 looks like this:
-%%%
-%%% Type ::= string( <attribute> )
-%%% SubStr ::= listof( {initial,Value} | {any,Value}, {final,Value})
-%%%
-%%% Example: substrings("sn",[{initial,"To"},{any,"kv"},{final,"st"}])
-%%% will match entries containing: 'sn: Tornkvist'
-%%%
-substrings(Type, SubStr) when list(Type), list(SubStr) ->
- Ss = {'SubstringFilter_substrings',v_substr(SubStr)},
- {substrings,#'SubstringFilter'{type = Type,
- substrings = Ss}}.
-
-
-get_handle(Pid) when pid(Pid) -> Pid;
-get_handle(Atom) when atom(Atom) -> Atom;
-get_handle(Name) when list(Name) -> list_to_atom("eldap_" ++ Name).
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_fsm
-%%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, StateName, StateData} |
-%% {ok, StateName, StateData, Timeout} |
-%% ignore |
-%% {stop, StopReason}
-%% I use the trick of setting a timeout of 0 to pass control into the
-%% process.
-%%----------------------------------------------------------------------
-init([]) ->
- case get_config() of
- {ok, Hosts, Rootdn, Passwd, Log} ->
- init({Hosts, Rootdn, Passwd, Log});
- {error, Reason} ->
- {stop, Reason}
- end;
-init({Hosts, Port, Rootdn, Passwd, Log}) ->
- {ok, connecting, #eldap{hosts = Hosts,
- port = Port,
- rootdn = Rootdn,
- passwd = Passwd,
- id = 0,
- log = Log,
- dict = dict:new(),
- debug_level = 0}, 0}.
-
-%%----------------------------------------------------------------------
-%% Func: StateName/2
-%% Called when gen_fsm:send_event/2,3 is invoked (async)
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-connecting(timeout, S) ->
- {ok, NextState, NewS} = connect_bind(S),
- {next_state, NextState, NewS}.
-
-%%----------------------------------------------------------------------
-%% Func: StateName/3
-%% Called when gen_fsm:sync_send_event/2,3 is invoked.
-%% 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}
-%%----------------------------------------------------------------------
-connecting(Event, From, S) ->
- Reply = {error, connecting},
- {reply, Reply, connecting, S}.
-
-wait_bind_response(Event, From, S) ->
- Reply = {error, wait_bind_response},
- {reply, Reply, wait_bind_response, S}.
-
-active(Event, From, S) ->
- case catch send_command(Event, From, S) of
- {ok, NewS} ->
- {next_state, active, NewS};
- {error, Reason} ->
- {reply, {error, Reason}, active, S};
- {'EXIT', Reason} ->
- {reply, {error, Reason}, active, S}
- end.
-
-%%----------------------------------------------------------------------
-%% Func: handle_event/3
-%% Called when gen_fsm:send_all_state_event/2 is invoked.
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-handle_event(close, StateName, S) ->
- gen_tcp:close(S#eldap.fd),
- {stop, closed, S};
-
-handle_event(Event, StateName, S) ->
- {next_state, StateName, S}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_sync_event/4
-%% Called when gen_fsm:sync_send_all_state_event/2,3 is invoked
-%% 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({debug_level, N}, From, StateName, S) ->
- {reply, ok, StateName, S#eldap{debug_level = N}};
-
-handle_sync_event(Event, From, StateName, S) ->
- {reply, {StateName, S}, StateName, S};
-
-handle_sync_event(Event, From, StateName, S) ->
- Reply = ok,
- {reply, Reply, StateName, S}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/3
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-
-%%
-%% Packets arriving in various states
-%%
-handle_info({tcp, Socket, Data}, connecting, S) ->
- log1("eldap. tcp packet received when disconnected!~n~p~n", [Data], S),
- {next_state, connecting, S};
-
-handle_info({tcp, Socket, Data}, wait_bind_response, S) ->
- cancel_timer(S#eldap.bind_timer),
- case catch recvd_wait_bind_response(Data, S) of
- bound -> {next_state, active, S};
- {fail_bind, Reason} -> close_and_retry(S),
- {next_state, connecting, S#eldap{fd = null}};
- {'EXIT', Reason} -> close_and_retry(S),
- {next_state, connecting, S#eldap{fd = null}};
- {error, Reason} -> close_and_retry(S),
- {next_state, connecting, S#eldap{fd = null}}
- end;
-
-handle_info({tcp, Socket, Data}, active, S) ->
- case catch recvd_packet(Data, S) of
- {reply, Reply, To, NewS} -> gen_fsm:reply(To, Reply),
- {next_state, active, NewS};
- {ok, NewS} -> {next_state, active, NewS};
- {'EXIT', Reason} -> {next_state, active, S};
- {error, Reason} -> {next_state, active, S}
- end;
-
-handle_info({tcp_closed, Socket}, All_fsm_states, S) ->
- F = fun(Id, [{Timer, From, Name}|Res]) ->
- gen_fsm:reply(From, {error, tcp_closed}),
- cancel_timer(Timer)
- end,
- dict:map(F, S#eldap.dict),
- retry_connect(),
- {next_state, connecting, S#eldap{fd = null,
- dict = dict:new()}};
-
-handle_info({tcp_error, Socket, Reason}, Fsm_state, S) ->
- log1("eldap received tcp_error: ~p~nIn State: ~p~n", [Reason, Fsm_state], S),
- {next_state, Fsm_state, S};
-%%
-%% Timers
-%%
-handle_info({timeout, Timer, {cmd_timeout, Id}}, active, S) ->
- case cmd_timeout(Timer, Id, S) of
- {reply, To, Reason, NewS} -> gen_fsm:reply(To, Reason),
- {next_state, active, NewS};
- {error, Reason} -> {next_state, active, S}
- end;
-
-handle_info({timeout, retry_connect}, connecting, S) ->
- {ok, NextState, NewS} = connect_bind(S),
- {next_state, NextState, NewS};
-
-handle_info({timeout, Timer, bind_timeout}, wait_bind_response, S) ->
- close_and_retry(S),
- {next_state, connecting, S#eldap{fd = null}};
-
-%%
-%% Make sure we don't fill the message queue with rubbish
-%%
-handle_info(Info, StateName, S) ->
- log1("eldap. Unexpected Info: ~p~nIn state: ~p~n when StateData is: ~p~n",
- [Info, StateName, S], S),
- {next_state, StateName, S}.
-
-%%----------------------------------------------------------------------
-%% Func: terminate/3
-%% Purpose: Shutdown the fsm
-%% Returns: any
-%%----------------------------------------------------------------------
-terminate(Reason, StateName, StatData) ->
- ok.
-
-%%----------------------------------------------------------------------
-%% Func: code_change/4
-%% Purpose: Convert process state when code is changed
-%% Returns: {ok, NewState, NewStateData}
-%%----------------------------------------------------------------------
-code_change(OldVsn, StateName, S, Extra) ->
- {ok, StateName, S}.
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-send_command(Command, From, S) ->
- Id = bump_id(S),
- {Name, Request} = gen_req(Command),
- Message = #'LDAPMessage'{messageID = Id,
- protocolOp = {Name, Request}},
- log2("~p~n",[{Name, Request}], S),
- {ok, Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage', Message),
- ok = gen_tcp:send(S#eldap.fd, Bytes),
- Timer = erlang:start_timer(?CMD_TIMEOUT, self(), {cmd_timeout, Id}),
- New_dict = dict:store(Id, [{Timer, From, Name}], S#eldap.dict),
- {ok, S#eldap{id = Id,
- dict = New_dict}}.
-
-gen_req({search, A}) ->
- {searchRequest,
- #'SearchRequest'{baseObject = A#eldap_search.base,
- scope = v_scope(A#eldap_search.scope),
- derefAliases = neverDerefAliases,
- sizeLimit = 0, % no size limit
- timeLimit = v_timeout(A#eldap_search.timeout),
- typesOnly = v_bool(A#eldap_search.types_only),
- filter = v_filter(A#eldap_search.filter),
- attributes = v_attributes(A#eldap_search.attributes)
- }};
-gen_req({add, Entry, Attrs}) ->
- {addRequest,
- #'AddRequest'{entry = Entry,
- attributes = Attrs}};
-gen_req({delete, Entry}) ->
- {delRequest, Entry};
-gen_req({modify, Obj, Mod}) ->
- v_modifications(Mod),
- {modifyRequest,
- #'ModifyRequest'{object = Obj,
- modification = Mod}};
-gen_req({modify_dn, Entry, NewRDN, DelOldRDN, NewSup}) ->
- {modDNRequest,
- #'ModifyDNRequest'{entry = Entry,
- newrdn = NewRDN,
- deleteoldrdn = DelOldRDN,
- newSuperior = NewSup}};
-
-gen_req({bind, RootDN, Passwd}) ->
- {bindRequest,
- #'BindRequest'{version = ?LDAP_VERSION,
- name = RootDN,
- authentication = {simple, Passwd}}}.
-
-%%-----------------------------------------------------------------------
-%% recvd_packet
-%% Deals with incoming packets in the active state
-%% Will return one of:
-%% {ok, NewS} - Don't reply to client yet as this is part of a search
-%% result and we haven't got all the answers yet.
-%% {reply, Result, From, NewS} - Reply with result to client From
-%% {error, Reason}
-%% {'EXIT', Reason} - Broke
-%%-----------------------------------------------------------------------
-recvd_packet(Pkt, S) ->
- check_tag(Pkt),
- case asn1rt:decode('ELDAPv3', 'LDAPMessage', Pkt) of
- {ok,Msg} ->
- Op = Msg#'LDAPMessage'.protocolOp,
- log2("~p~n",[Op], S),
- Dict = S#eldap.dict,
- Id = Msg#'LDAPMessage'.messageID,
- {Timer, From, Name, Result_so_far} = get_op_rec(Id, Dict),
- case {Name, Op} of
- {searchRequest, {searchResEntry, R}} when
- record(R,'SearchResultEntry') ->
- New_dict = dict:append(Id, R, Dict),
- {ok, S#eldap{dict = New_dict}};
- {searchRequest, {searchResDone, Result}} ->
- case Result#'LDAPResult'.resultCode of
- success ->
- {Res, Ref} = polish(Result_so_far),
- New_dict = dict:erase(Id, Dict),
- cancel_timer(Timer),
- {reply, #eldap_search_result{entries = Res,
- referrals = Ref}, From,
- S#eldap{dict = New_dict}};
- Reason ->
- New_dict = dict:erase(Id, Dict),
- cancel_timer(Timer),
- {reply, {error, Reason}, From, S#eldap{dict = New_dict}}
- end;
- {searchRequest, {searchResRef, R}} ->
- New_dict = dict:append(Id, R, Dict),
- {ok, S#eldap{dict = New_dict}};
- {addRequest, {addResponse, Result}} ->
- New_dict = dict:erase(Id, Dict),
- cancel_timer(Timer),
- Reply = check_reply(Result, From),
- {reply, Reply, From, S#eldap{dict = New_dict}};
- {delRequest, {delResponse, Result}} ->
- New_dict = dict:erase(Id, Dict),
- cancel_timer(Timer),
- Reply = check_reply(Result, From),
- {reply, Reply, From, S#eldap{dict = New_dict}};
- {modifyRequest, {modifyResponse, Result}} ->
- New_dict = dict:erase(Id, Dict),
- cancel_timer(Timer),
- Reply = check_reply(Result, From),
- {reply, Reply, From, S#eldap{dict = New_dict}};
- {modDNRequest, {modDNResponse, Result}} ->
- New_dict = dict:erase(Id, Dict),
- cancel_timer(Timer),
- Reply = check_reply(Result, From),
- {reply, Reply, From, S#eldap{dict = New_dict}};
- {bindRequest, {bindResponse, Result}} ->
- New_dict = dict:erase(Id, Dict),
- cancel_timer(Timer),
- Reply = check_bind_reply(Result, From),
- {reply, Reply, From, S#eldap{dict = New_dict}};
- {OtherName, OtherResult} ->
- New_dict = dict:erase(Id, Dict),
- cancel_timer(Timer),
- {reply, {error, {invalid_result, OtherName, OtherResult}},
- From, S#eldap{dict = New_dict}}
- end;
- Error -> Error
- end.
-
-check_reply(#'LDAPResult'{resultCode = success}, From) ->
- ok;
-check_reply(#'LDAPResult'{resultCode = Reason}, From) ->
- {error, Reason};
-check_reply(Other, From) ->
- {error, Other}.
-
-check_bind_reply(#'BindResponse'{resultCode = success}, From) ->
- ok;
-check_bind_reply(#'BindResponse'{resultCode = Reason}, From) ->
- {error, Reason};
-check_bind_reply(Other, From) ->
- {error, Other}.
-
-get_op_rec(Id, Dict) ->
- case dict:find(Id, Dict) of
- {ok, [{Timer, From, Name}|Res]} ->
- {Timer, From, Name, Res};
- error ->
- throw({error, unkown_id})
- end.
-
-%%-----------------------------------------------------------------------
-%% recvd_wait_bind_response packet
-%% Deals with incoming packets in the wait_bind_response state
-%% Will return one of:
-%% bound - Success - move to active state
-%% {fail_bind, Reason} - Failed
-%% {error, Reason}
-%% {'EXIT', Reason} - Broken packet
-%%-----------------------------------------------------------------------
-recvd_wait_bind_response(Pkt, S) ->
- check_tag(Pkt),
- case asn1rt:decode('ELDAPv3', 'LDAPMessage', Pkt) of
- {ok,Msg} ->
- log2("~p", [Msg], S),
- check_id(S#eldap.id, Msg#'LDAPMessage'.messageID),
- case Msg#'LDAPMessage'.protocolOp of
- {bindResponse, Result} ->
- case Result#'LDAPResult'.resultCode of
- success -> bound;
- Error -> {fail_bind, Error}
- end
- end;
- Else ->
- {fail_bind, Else}
- end.
-
-check_id(Id, Id) -> ok;
-check_id(_, _) -> throw({error, wrong_bind_id}).
-
-%%-----------------------------------------------------------------------
-%% General Helpers
-%%-----------------------------------------------------------------------
-
-cancel_timer(Timer) ->
- erlang:cancel_timer(Timer),
- receive
- {timeout, Timer, _} ->
- ok
- after 0 ->
- ok
- end.
-
-
-%%% Sanity check of received packet
-check_tag(Data) ->
- case asn1rt_ber_bin:decode_tag(Data) of
- {Tag, Data1, Rb} ->
- case asn1rt_ber_bin:decode_length(Data1) of
- {{Len,Data2}, Rb2} -> ok;
- _ -> throw({error,decoded_tag_length})
- end;
- _ -> throw({error,decoded_tag})
- end.
-
-close_and_retry(S) ->
- gen_tcp:close(S#eldap.fd),
- retry_connect().
-
-retry_connect() ->
- erlang:send_after(?RETRY_TIMEOUT, self(),
- {timeout, retry_connect}).
-
-
-%%-----------------------------------------------------------------------
-%% Sort out timed out commands
-%%-----------------------------------------------------------------------
-cmd_timeout(Timer, Id, S) ->
- Dict = S#eldap.dict,
- case dict:find(Id, Dict) of
- {ok, [{Timer, From, Name}|Res]} ->
- case Name of
- searchRequest ->
- {Res1, Ref1} = polish(Res),
- New_dict = dict:erase(Id, Dict),
- {reply, From, {timeout,
- #eldap_search_result{entries = Res1,
- referrals = Ref1}},
- S#eldap{dict = New_dict}};
- Others ->
- New_dict = dict:erase(Id, Dict),
- {reply, From, {error, timeout}, S#eldap{dict = New_dict}}
- end;
- error ->
- {error, timed_out_cmd_not_in_dict}
- end.
-
-%%-----------------------------------------------------------------------
-%% Common stuff for results
-%%-----------------------------------------------------------------------
-%%%
-%%% Polish the returned search result
-%%%
-
-polish(Entries) ->
- polish(Entries, [], []).
-
-polish([H|T], Res, Ref) when record(H, 'SearchResultEntry') ->
- ObjectName = H#'SearchResultEntry'.objectName,
- F = fun({_,A,V}) -> {A,V} end,
- Attrs = lists:map(F, H#'SearchResultEntry'.attributes),
- polish(T, [#eldap_entry{object_name = ObjectName,
- attributes = Attrs}|Res], Ref);
-polish([H|T], Res, Ref) -> % No special treatment of referrals at the moment.
- polish(T, Res, [H|Ref]);
-polish([], Res, Ref) ->
- {Res, Ref}.
-
-%%-----------------------------------------------------------------------
-%% Connect to next server in list and attempt to bind to it.
-%%-----------------------------------------------------------------------
-connect_bind(S) ->
- Host = next_host(S#eldap.host, S#eldap.hosts),
- TcpOpts = [{packet, asn1}, {active, true}, {keepalive, true}, binary],
- case gen_tcp:connect(Host, S#eldap.port, TcpOpts) of
- {ok, Socket} ->
- case bind_request(Socket, S) of
- {ok, NewS} ->
- Timer = erlang:start_timer(?BIND_TIMEOUT, self(),
- {timeout, bind_timeout}),
- {ok, wait_bind_response, NewS#eldap{fd = Socket,
- host = Host,
- bind_timer = Timer}};
- {error, Reason} ->
- gen_tcp:close(Socket),
- erlang:send_after(?RETRY_TIMEOUT, self(),
- {timeout, retry_connect}),
- {ok, connecting, S#eldap{host = Host}}
- end;
- {error, Reason} ->
- erlang:send_after(?RETRY_TIMEOUT, self(),
- {timeout, retry_connect}),
- {ok, connecting, S#eldap{host = Host}}
- end.
-
-bind_request(Socket, S) ->
- Id = bump_id(S),
- Req = #'BindRequest'{version = S#eldap.version,
- name = S#eldap.rootdn,
- authentication = {simple, S#eldap.passwd}},
- Message = #'LDAPMessage'{messageID = Id,
- protocolOp = {bindRequest, Req}},
- log2("Message:~p~n",[Message], S),
- {ok, Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage', Message),
- ok = gen_tcp:send(Socket, Bytes),
- {ok, S#eldap{id = Id}}.
-
-%% Given last tried Server, find next one to try
-next_host(null, [H|_]) -> H; % First time, take first
-next_host(Host, Hosts) -> % Find next in turn
- next_host(Host, Hosts, Hosts).
-
-next_host(Host, [Host], Hosts) -> hd(Hosts); % Wrap back to first
-next_host(Host, [Host|Tail], Hosts) -> hd(Tail); % Take next
-next_host(Host, [], Hosts) -> hd(Hosts); % Never connected before? (shouldn't happen)
-next_host(Host, [H|T], Hosts) -> next_host(Host, T, Hosts).
-
-
-%%% --------------------------------------------------------------------
-%%% Verify the input data
-%%% --------------------------------------------------------------------
-
-v_filter({'and',L}) -> {'and',L};
-v_filter({'or', L}) -> {'or',L};
-v_filter({'not',L}) -> {'not',L};
-v_filter({equalityMatch,AV}) -> {equalityMatch,AV};
-v_filter({greaterOrEqual,AV}) -> {greaterOrEqual,AV};
-v_filter({lessOrEqual,AV}) -> {lessOrEqual,AV};
-v_filter({approxMatch,AV}) -> {approxMatch,AV};
-v_filter({present,A}) -> {present,A};
-v_filter({substrings,S}) when record(S,'SubstringFilter') -> {substrings,S};
-v_filter(_Filter) -> throw({error,concat(["unknown filter: ",_Filter])}).
-
-v_modifications(Mods) ->
- F = fun({_,Op,_}) ->
- case lists:member(Op,[add,delete,replace]) of
- true -> true;
- _ -> throw({error,{mod_operation,Op}})
- end
- end,
- lists:foreach(F, Mods).
-
-v_substr([{Key,Str}|T]) when list(Str),Key==initial;Key==any;Key==final ->
- [{Key,Str}|v_substr(T)];
-v_substr([H|T]) ->
- throw({error,{substring_arg,H}});
-v_substr([]) ->
- [].
-v_scope(baseObject) -> baseObject;
-v_scope(singleLevel) -> singleLevel;
-v_scope(wholeSubtree) -> wholeSubtree;
-v_scope(_Scope) -> throw({error,concat(["unknown scope: ",_Scope])}).
-
-v_bool(true) -> true;
-v_bool(false) -> false;
-v_bool(_Bool) -> throw({error,concat(["not Boolean: ",_Bool])}).
-
-v_timeout(I) when integer(I), I>=0 -> I;
-v_timeout(_I) -> throw({error,concat(["timeout not positive integer: ",_I])}).
-
-v_attributes(Attrs) ->
- F = fun(A) when list(A) -> A;
- (A) -> throw({error,concat(["attribute not String: ",A])})
- end,
- lists:map(F,Attrs).
-
-
-%%% --------------------------------------------------------------------
-%%% Get and Validate the initial configuration
-%%% --------------------------------------------------------------------
-get_config() ->
- Priv_dir = code:priv_dir(eldap),
- File = filename:join(Priv_dir, "eldap.conf"),
- case file:consult(File) of
- {ok, Entries} ->
- case catch parse(Entries) of
- {ok, Hosts, Port, Rootdn, Passwd, Log} ->
- {ok, Hosts, Port, Rootdn, Passwd, Log};
- {error, Reason} ->
- {error, Reason};
- {'EXIT', Reason} ->
- {error, Reason}
- end;
- {error, Reason} ->
- {error, Reason}
- end.
-
-parse(Entries) ->
- {ok,
- get_hosts(host, Entries),
- get_integer(port, Entries),
- get_list(rootdn, Entries),
- get_list(passwd, Entries),
- get_log(log, Entries)}.
-
-get_integer(Key, List) ->
- case lists:keysearch(Key, 1, List) of
- {value, {Key, Value}} when integer(Value) ->
- Value;
- {value, {Key, Value}} ->
- throw({error, "Bad Value in Config for " ++ atom_to_list(Key)});
- false ->
- throw({error, "No Entry in Config for " ++ atom_to_list(Key)})
- end.
-
-get_list(Key, List) ->
- case lists:keysearch(Key, 1, List) of
- {value, {Key, Value}} when list(Value) ->
- Value;
- {value, {Key, Value}} ->
- throw({error, "Bad Value in Config for " ++ atom_to_list(Key)});
- false ->
- throw({error, "No Entry in Config for " ++ atom_to_list(Key)})
- end.
-
-get_log(Key, List) ->
- case lists:keysearch(Key, 1, List) of
- {value, {Key, Value}} when function(Value) ->
- Value;
- {value, {Key, Else}} ->
- false;
- false ->
- fun(Level, Format, Args) -> io:format("--- " ++ Format, Args) end
- end.
-
-get_hosts(Key, List) ->
- lists:map(fun({Key1, {A,B,C,D}}) when integer(A),
- integer(B),
- integer(C),
- integer(D),
- Key == Key1->
- {A,B,C,D};
- ({Key1, Value}) when list(Value),
- Key == Key1->
- Value;
- ({Else, Value}) ->
- throw({error, "Bad Hostname in config"})
- end, List).
-
-%%% --------------------------------------------------------------------
-%%% Other Stuff
-%%% --------------------------------------------------------------------
-bump_id(#eldap{id = Id}) when Id > ?MAX_TRANSACTION_ID ->
- ?MIN_TRANSACTION_ID;
-bump_id(#eldap{id = Id}) ->
- Id + 1.
-
-%%% --------------------------------------------------------------------
-%%% Log routines. Call a user provided log routine Fun.
-%%% --------------------------------------------------------------------
-
-log1(Str, Args, #eldap{log = Fun, debug_level = N}) -> log(Fun, Str, Args, 1, N).
-log2(Str, Args, #eldap{log = Fun, debug_level = N}) -> log(Fun, Str, Args, 2, N).
-
-log(Fun, Str, Args, This_level, Status) when function(Fun), This_level =< Status ->
- catch Fun(This_level, Str, Args);
-log(_, _, _, _, _) ->
- ok.
diff --git a/ejabberd-1.1.2/src/eldap/eldap.hrl b/ejabberd-1.1.2/src/eldap/eldap.hrl
deleted file mode 100644
index e31a34991..000000000
--- a/ejabberd-1.1.2/src/eldap/eldap.hrl
+++ /dev/null
@@ -1,13 +0,0 @@
--record(eldap_search, {scope = wholeSubtree,
- base = [],
- filter,
- attributes = [],
- types_only = false,
- timeout = 0}).
-
-
--record(eldap_search_result, {entries,
- referrals}).
-
--record(eldap_entry, {object_name,
- attributes}).
diff --git a/ejabberd-1.1.2/src/eldap/eldap_filter.erl b/ejabberd-1.1.2/src/eldap/eldap_filter.erl
deleted file mode 100644
index a93205295..000000000
--- a/ejabberd-1.1.2/src/eldap/eldap_filter.erl
+++ /dev/null
@@ -1,285 +0,0 @@
-%%%====================================================
-%%% File: eldap_filter.erl
-%%% Purpose: Converts String Representation of
-%%% LDAP Search Filter (RFC 2254)
-%%% to eldap's representation of filter
-%%% Author: Evgeniy Khramtsov <xramtsov@gmail.com>
-%%% License: GPL
-%%%====================================================
-
--module(eldap_filter).
--author('xram@jabber.ru').
-
-%%%======================
-%%% Export functions
-%%%======================
-
--export([parse/1,
- parse/2,
- do_sub/2
- ]).
-
-%%%-------------------------------------------------------------------------
-%%% Arity: parse/1
-%%% Function: parse(RFC2254_Filter) -> {ok, EldapFilter} |
-%%% {error, bad_filter}
-%%%
-%%% RFC2254_Filter = string().
-%%%
-%%% Description: Converts String Representation of LDAP Search Filter (RFC 2254)
-%%% to eldap's representation of filter.
-%%%
-%%% Example:
-%%% > eldap_filter:parse("(&(!(uid<=100))(mail=*))").
-%%%
-%%% {ok,{'and',[{'not',{lessOrEqual,{'AttributeValueAssertion',"uid","100"}}},
-%%% {present,"mail"}]}}
-%%%-------------------------------------------------------------------------
-parse(RFC2254_Filter) ->
- parse(RFC2254_Filter, []).
-
-%%%-------------------------------------------------------------------------
-%%% Arity: parse/2
-%%% Function: parse(RFC2254_Filter, [SubstValue |...]) ->
-%%% {ok, EldapFilter} |
-%%% {error, bad_filter} |
-%%% {error, bad_regexp} |
-%%% {error, max_substitute_recursion}
-%%%
-%%% SubstValue = {RegExp, Value} | {RegExp, Value, N},
-%%% RFC2254_Filter = RegExp = Value = string(),
-%%% N = integer().
-%%%
-%%% Description: The same as parse/1, but substitutes N or all occurences
-%%% of RegExp with Value *after* parsing.
-%%%
-%%% Example:
-%%% > eldap_filter:parse(
-%%% "(|(mail=%u@%d)(jid=%u@%d))",
-%%% [{"%u", "xramtsov"},{"%d","gmail.com"}]).
-%%%
-%%% {ok,{'or',[{equalityMatch,{'AttributeValueAssertion',
-%%% "mail",
-%%% "xramtsov@gmail.com"}},
-%%% {equalityMatch,{'AttributeValueAssertion',
-%%% "jid",
-%%% "xramtsov@gmail.com"}}]}}
-%%%--------------------------------------------------------------------------
-parse(RFC2254_Filter, ListOfSubValues) ->
- case catch convert_filter(parse_filter(RFC2254_Filter), ListOfSubValues) of
- [EldapFilter] when is_tuple(EldapFilter) ->
- {ok, EldapFilter};
- {regexp, Error} ->
- {error, Error};
- _ ->
- {error, bad_filter}
- end.
-
-%%%==========================
-%%% Internal functions
-%%%==========================
-
-%%%----------------------
-%%% split/1,4
-%%%----------------------
-split(Filter) ->
- split(Filter, 0, [], []).
-
-split([], _, _, Result) ->
- Result;
-
-split([H|T], Num, Rest, Result) ->
- NewNum = case H of
- $( -> Num + 1;
- $) -> Num - 1;
- _ -> Num
- end,
- if
- NewNum == 0 ->
- X = Rest++[H],
- LenX = length(X),
- if
- LenX > 2 ->
- split(T, 0, [], Result ++ [lists:sublist(X, 2, LenX-2)]);
- true ->
- split(T, 0, Rest, Result)
- end;
- true ->
- split(T, NewNum, Rest++[H], Result)
- end.
-
-%%%-----------------------
-%%% parse_filter/1
-%%%-----------------------
-parse_filter(Filter) ->
- case Filter of
- [$! | T] ->
- {'not', parse_filter(T)};
- [$| | T] ->
- {'or', parse_filter(T)};
- [$& | T] ->
- {'and', parse_filter(T)};
- [$( | _] ->
- parse_filter(split(Filter));
- [List | _] when is_list(List) ->
- [parse_filter(X) || X <- Filter];
- _ ->
- Filter
- end.
-
-%%%--------------------
-%%% convert_filter/2
-%%%--------------------
-convert_filter({'not', [Val | _]}, Replace) ->
- eldap:'not'(convert_filter(Val, Replace));
-
-convert_filter({'or', Vals}, Replace) ->
- eldap:'or'([convert_filter(X, Replace) || X <- Vals]);
-
-convert_filter({'and', Vals}, Replace) ->
- eldap:'and'([convert_filter(X, Replace) || X <- Vals]);
-
-convert_filter([H|_] = Filter, Replace) when is_integer(H) ->
- parse_attr(Filter, Replace);
-
-convert_filter(Filter, Replace) when is_list(Filter) ->
- [convert_filter(X, Replace) || X <- Filter].
-
-%%%-----------------
-%%% parse_attr/2,3
-%%%-----------------
-parse_attr(Attr, ListOfSubValues) ->
- {Action, [_|_] = Name, [_|_] = Value} = split_attribute(Attr),
- parse_attr(Action, {Name, Value}, ListOfSubValues).
-
-parse_attr(approx, {Name, Value}, ListOfSubValues) ->
- NewValue = do_sub(Value, ListOfSubValues),
- eldap:approxMatch(Name, NewValue);
-
-parse_attr(greater, {Name, Value}, ListOfSubValues) ->
- NewValue = do_sub(Value, ListOfSubValues),
- eldap:greaterOrEqual(Name, NewValue);
-
-parse_attr(less, {Name, Value}, ListOfSubValues) ->
- NewValue = do_sub(Value, ListOfSubValues),
- eldap:lessOrEqual(Name, NewValue);
-
-parse_attr(equal, {Name, Value}, ListOfSubValues) ->
- {ok, RegSList} = regexp:split(remove_extra_asterisks(Value), "[*]"),
- Pattern = case [do_sub(X, ListOfSubValues) || X <- RegSList] of
- [Head | Tail] when Tail /= [] ->
- {Head, lists:sublist(Tail, length(Tail)-1), lists:last(Tail)};
- R ->
- R
- end,
- case Pattern of
- [V] ->
- eldap:equalityMatch(Name, V);
- {[], [], []} ->
- eldap:present(Name);
- {"", Any, ""} ->
- eldap:substrings(Name, [{any, X} || X<-Any]);
- {H, Any, ""} ->
- eldap:substrings(Name, [{initial, H}]++[{any, X} || X<-Any]);
- {"", Any, T} ->
- eldap:substrings(Name, [{any, X} || X<-Any]++[{final, T}]);
- {H, Any, T} ->
- eldap:substrings(Name, [{initial, H}]++[{any, X} || X<-Any]++[{final, T}])
- end;
-
-parse_attr(_, _, _) ->
- false.
-
-%%%--------------------
-%%% do_sub/2,3
-%%%--------------------
-
--define(MAX_RECURSION, 100).
-
-do_sub(S, []) ->
- S;
-
-do_sub([], _) ->
- [];
-
-do_sub(S, [{RegExp, New} | T]) ->
- Result = do_sub(S, {RegExp, replace_amps(New)}, 1),
- do_sub(Result, T);
-
-do_sub(S, [{RegExp, New, Times} | T]) ->
- Result = do_sub(S, {RegExp, replace_amps(New), Times}, 1),
- do_sub(Result, T).
-
-do_sub(S, {RegExp, New}, Iter) ->
- case regexp:sub(S, RegExp, New) of
- {ok, NewS, 0} ->
- NewS;
- {ok, NewS, _} when Iter =< ?MAX_RECURSION ->
- do_sub(NewS, {RegExp, New}, Iter+1);
- {ok, _, _} when Iter > ?MAX_RECURSION ->
- throw({regexp, max_substitute_recursion});
- _ ->
- throw({regexp, bad_regexp})
- end;
-
-do_sub(S, {_, _, N}, _) when N<1 ->
- S;
-
-do_sub(S, {RegExp, New, Times}, Iter) ->
- case regexp:sub(S, RegExp, New) of
- {ok, NewS, 0} ->
- NewS;
- {ok, NewS, _} when Iter < Times ->
- do_sub(NewS, {RegExp, New, Times}, Iter+1);
- {ok, NewS, _} ->
- NewS;
- _ ->
- throw({regexp, bad_regexp})
- end.
-
-remove_extra_asterisks(String) ->
- {Res, _} = lists:foldl(
- fun(X, {Acc, Last}) ->
- case X of
- $* when Last==$* ->
- {Acc, X};
- _ ->
- {Acc ++ [X], X}
- end
- end,
- {"", ""}, String),
- Res.
-
-replace_amps(String) ->
- lists:foldl(
- fun(X, Acc) ->
- if
- X == $& ->
- Acc ++ "\\&";
- true ->
- Acc ++ [X]
- end
- end,
- "", String).
-
-split_attribute(String) ->
- split_attribute(String, "", $0).
-
-split_attribute([], _, _) ->
- {error, "", ""};
-
-split_attribute([H|Tail], Acc, Last) ->
- case H of
- $= when Last==$> ->
- {greater, lists:sublist(Acc, 1, length(Acc)-1), Tail};
- $= when Last==$< ->
- {less, lists:sublist(Acc, 1, length(Acc)-1), Tail};
- $= when Last==$~ ->
- {approx, lists:sublist(Acc, 1, length(Acc)-1), Tail};
- $= when Last==$: ->
- {equal, lists:sublist(Acc, 1, length(Acc)-1), Tail};
- $= ->
- {equal, Acc, Tail};
- _ ->
- split_attribute(Tail, Acc++[H], H)
- end.
diff --git a/ejabberd-1.1.2/src/expat_erl.c b/ejabberd-1.1.2/src/expat_erl.c
deleted file mode 100644
index e4c3fd10b..000000000
--- a/ejabberd-1.1.2/src/expat_erl.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/* $Id$ */
-
-#include <stdio.h>
-#include <string.h>
-#include <erl_driver.h>
-#include <ei.h>
-#include <expat.h>
-
-#define EI_ENCODE_STRING_BUG
-
-#ifdef EI_ENCODE_STRING_BUG
-
-/*
- * Workaround for EI encode_string bug
- */
-
-#define put8(s,n) do { \
- (s)[0] = (char)((n) & 0xff); \
- (s) += 1; \
-} while (0)
-
-#define put16be(s,n) do { \
- (s)[0] = ((n) >> 8) & 0xff; \
- (s)[1] = (n) & 0xff; \
- (s) += 2; \
-} while (0)
-
-#define put32be(s,n) do { \
- (s)[0] = ((n) >> 24) & 0xff; \
- (s)[1] = ((n) >> 16) & 0xff; \
- (s)[2] = ((n) >> 8) & 0xff; \
- (s)[3] = (n) & 0xff; \
- (s) += 4; \
-} while (0)
-
-int ei_encode_string_len_fixed(char *buf, int *index, const char *p, int len)
-{
- char *s = buf + *index;
- char *s0 = s;
- int i;
-
- if (len <= 0xffff) {
- if (!buf) s += 3;
- else {
- put8(s,ERL_STRING_EXT);
- put16be(s,len);
- memmove(s,p,len); /* unterminated string */
- }
- s += len;
- }
- else {
- if (!buf) s += 6 + (2*len);
- else {
- /* strings longer than 65535 are encoded as lists */
- put8(s,ERL_LIST_EXT);
- put32be(s,len);
-
- for (i=0; i<len; i++) {
- put8(s,ERL_SMALL_INTEGER_EXT);
- put8(s,p[i]);
- }
-
- put8(s,ERL_NIL_EXT);
- }
- }
-
- *index += s-s0;
-
- return 0;
-}
-
-int ei_encode_string_fixed(char *buf, int *index, const char *p)
-{
- return ei_encode_string_len_fixed(buf, index, p, strlen(p));
-}
-
-int ei_x_encode_string_len_fixed(ei_x_buff* x, const char* s, int len)
-{
- int i = x->index;
- ei_encode_string_len_fixed(NULL, &i, s, len);
- if (!x_fix_buff(x, i))
- return -1;
- return ei_encode_string_len_fixed(x->buff, &x->index, s, len);
-}
-
-int ei_x_encode_string_fixed(ei_x_buff* x, const char* s)
-{
- return ei_x_encode_string_len_fixed(x, s, strlen(s));
-}
-
-#else
-
-#define ei_encode_string_len_fixed(buf, index, p, len) \
- ei_encode_string_len(buf, index, p, len)
-#define ei_encode_string_fixed(buf, index, p) \
- ei_encode_string(buf, index, p)
-#define ei_x_encode_string_len_fixed(x, s, len) \
- ei_x_encode_string_len(x, s, len)
-#define ei_x_encode_string_fixed(x, s) \
- ei_x_encode_string(x, s)
-
-#endif
-
-#define XML_START 0
-#define XML_END 1
-#define XML_CDATA 2
-#define XML_ERROR 3
-
-#define PARSE_COMMAND 0
-#define PARSE_FINAL_COMMAND 1
-
-ei_x_buff event_buf;
-
-typedef struct {
- ErlDrvPort port;
- XML_Parser parser;
-} expat_data;
-
-void *erlXML_StartElementHandler(expat_data *d,
- const XML_Char *name,
- const XML_Char **atts)
-{
- int i;
-
- ei_x_encode_list_header(&event_buf, 1);
- ei_x_encode_tuple_header(&event_buf, 2);
- ei_x_encode_long(&event_buf, XML_START);
- ei_x_encode_tuple_header(&event_buf, 2);
- ei_x_encode_string_fixed(&event_buf, name);
-
- for (i = 0; atts[i]; i += 2) {}
-
- if (i > 0)
- {
- ei_x_encode_list_header(&event_buf, i/2);
-
- for (i = 0; atts[i]; i += 2)
- {
- ei_x_encode_tuple_header(&event_buf, 2);
- ei_x_encode_string_fixed(&event_buf, atts[i]);
- ei_x_encode_string_fixed(&event_buf, atts[i+1]);
- }
- }
-
- ei_x_encode_empty_list(&event_buf);
-
- return NULL;
-}
-
-void *erlXML_EndElementHandler(expat_data *d,
- const XML_Char *name)
-{
- ei_x_encode_list_header(&event_buf, 1);
- ei_x_encode_tuple_header(&event_buf, 2);
- ei_x_encode_long(&event_buf, XML_END);
- ei_x_encode_string_fixed(&event_buf, name);
- return NULL;
-}
-
-void *erlXML_CharacterDataHandler(expat_data *d,
- const XML_Char *s,
- int len)
-{
- ei_x_encode_list_header(&event_buf, 1);
- ei_x_encode_tuple_header(&event_buf, 2);
- ei_x_encode_long(&event_buf, XML_CDATA);
- ei_x_encode_binary(&event_buf, s, len);
- return NULL;
-}
-
-
-static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff)
-{
- expat_data* d = (expat_data*)driver_alloc(sizeof(expat_data));
- d->port = port;
- d->parser = XML_ParserCreate("UTF-8");
- XML_SetUserData(d->parser, d);
-
- set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
-
- XML_SetStartElementHandler(
- d->parser, (XML_StartElementHandler)erlXML_StartElementHandler);
- XML_SetEndElementHandler(
- d->parser, (XML_EndElementHandler)erlXML_EndElementHandler);
- XML_SetCharacterDataHandler(
- d->parser, (XML_CharacterDataHandler)erlXML_CharacterDataHandler);
-
-
- return (ErlDrvData)d;
-}
-
-static void expat_erl_stop(ErlDrvData handle)
-{
- XML_ParserFree(((expat_data *)handle)->parser);
- driver_free((char*)handle);
-}
-
-static int expat_erl_control(ErlDrvData drv_data,
- unsigned int command,
- char *buf, int len,
- char **rbuf, int rlen)
-{
- expat_data* d = (expat_data*)drv_data;
- int res, errcode;
- char *errstring;
- ErlDrvBinary *b;
- size_t size;
-
- switch (command)
- {
- case PARSE_COMMAND:
- case PARSE_FINAL_COMMAND:
- ei_x_new_with_version(&event_buf);
- res = XML_Parse(d->parser, buf, len, command == PARSE_FINAL_COMMAND);
-
- if(!res)
- {
- errcode = XML_GetErrorCode(d->parser);
- errstring = (char *)XML_ErrorString(errcode);
-
- ei_x_encode_list_header(&event_buf, 1);
- ei_x_encode_tuple_header(&event_buf, 2);
- ei_x_encode_long(&event_buf, XML_ERROR);
- ei_x_encode_tuple_header(&event_buf, 2);
- ei_x_encode_long(&event_buf, errcode);
- ei_x_encode_string_fixed(&event_buf, errstring);
- }
-
- ei_x_encode_empty_list(&event_buf);
-
- size = event_buf.index;
-
- b = driver_alloc_binary(size);
- memcpy(b->orig_bytes, event_buf.buff, size);
-
- ei_x_free(&event_buf);
-
- *rbuf = (char *)b;
- return size;
- default:
- return 0;
- }
-}
-
-ErlDrvEntry expat_driver_entry = {
- NULL, /* F_PTR init, N/A */
- expat_erl_start, /* L_PTR start, called when port is opened */
- expat_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 */
- "expat_erl", /* char *driver_name, the argument to open_port */
- NULL, /* F_PTR finish, called when unloaded */
- NULL, /* handle */
- expat_erl_control, /* F_PTR control, port_command callback */
- NULL, /* F_PTR timeout, reserved */
- NULL /* F_PTR outputv, reserved */
-};
-
-DRIVER_INIT(expat_erl) /* must match name in driver_entry */
-{
- return &expat_driver_entry;
-}
-
-
diff --git a/ejabberd-1.1.2/src/extauth.erl b/ejabberd-1.1.2/src/extauth.erl
deleted file mode 100644
index 80f55c596..000000000
--- a/ejabberd-1.1.2/src/extauth.erl
+++ /dev/null
@@ -1,77 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : extauth.erl
-%%% Author : Leif Johansson <leifj@it.su.se>
-%%% Purpose : External authentication using a simple port-driver
-%%% Created : 30 Jul 2004 by Leif Johansson <leifj@it.su.se>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(extauth).
--author('leifj@it.su.se').
-
--export([start/2, stop/1, init/2,
- check_password/3, set_password/3, is_user_exists/2]).
-
-
-start(Host, ExtPrg) ->
- spawn(?MODULE, init, [Host, ExtPrg]).
-
-init(Host, ExtPrg) ->
- register(gen_mod:get_module_proc(Host, eauth), self()),
- process_flag(trap_exit,true),
- Port = open_port({spawn, ExtPrg}, [{packet,2}]),
- loop(Port).
-
-stop(Host) ->
- gen_mod:get_module_proc(Host, eauth) ! stop.
-
-check_password(User, Server, Password) ->
- call_port(Server, ["auth", User, Server, Password]).
-
-is_user_exists(User, Server) ->
- call_port(Server, ["isuser", User, Server]).
-
-set_password(User, Server, Password) ->
- call_port(Server, ["setpass", User, Server, Password]).
-
-call_port(Server, Msg) ->
- LServer = jlib:nameprep(Server),
- gen_mod:get_module_proc(LServer, eauth) ! {call, self(), Msg},
- receive
- {eauth,Result} ->
- Result
- end.
-
-loop(Port) ->
- receive
- {call, Caller, Msg} ->
- Port ! {self(), {command, encode(Msg)}},
- receive
- {Port, {data, Data}} ->
- Caller ! {eauth, decode(Data)}
- end,
- loop(Port);
- stop ->
- Port ! {self(), close},
- receive
- {Port, closed} ->
- exit(normal)
- end;
- {'EXIT', Port, Reason} ->
- io:format("~p ~n", [Reason]),
- exit(port_terminated)
- end.
-
-join(List, Sep) ->
- lists:foldl(fun(A, "") -> A;
- (A, Acc) -> Acc ++ Sep ++ A
- end, "", List).
-
-encode(L) ->
- join(L,":").
-
-decode([0,0]) ->
- false;
-decode([0,1]) ->
- true.
-
diff --git a/ejabberd-1.1.2/src/gen_iq_handler.erl b/ejabberd-1.1.2/src/gen_iq_handler.erl
deleted file mode 100644
index 63f4e357c..000000000
--- a/ejabberd-1.1.2/src/gen_iq_handler.erl
+++ /dev/null
@@ -1,184 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : gen_iq_handler.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : IQ handler support
-%%% Created : 22 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(gen_iq_handler).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
-
-%% API
--export([start_link/3,
- add_iq_handler/6,
- remove_iq_handler/3,
- stop_iq_handler/3,
- handle/7,
- process_iq/6]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--include("ejabberd.hrl").
-
--record(state, {host,
- module,
- function}).
-
-%%====================================================================
-%% API
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the server
-%%--------------------------------------------------------------------
-start_link(Host, Module, Function) ->
- gen_server:start_link(?MODULE, [Host, Module, Function], []).
-
-add_iq_handler(Component, Host, NS, Module, Function, Type) ->
- case Type of
- no_queue ->
- Component:register_iq_handler(Host, NS, Module, Function, no_queue);
- one_queue ->
- {ok, Pid} = supervisor:start_child(ejabberd_iq_sup,
- [Host, Module, Function]),
- Component:register_iq_handler(Host, NS, Module, Function,
- {one_queue, Pid});
- {queues, N} ->
- Pids =
- lists:map(
- fun(_) ->
- {ok, Pid} = supervisor:start_child(
- ejabberd_iq_sup,
- [Host, Module, Function]),
- Pid
- end, lists:seq(1, N)),
- Component:register_iq_handler(Host, NS, Module, Function,
- {queues, Pids});
- parallel ->
- Component:register_iq_handler(Host, NS, Module, Function, parallel)
- end.
-
-remove_iq_handler(Component, Host, NS) ->
- Component:unregister_iq_handler(Host, NS).
-
-stop_iq_handler(_Module, _Function, Opts) ->
- case Opts of
- {one_queue, Pid} ->
- gen_server:call(Pid, stop);
- {queues, Pids} ->
- lists:foreach(fun(Pid) ->
- catch gen_server:call(Pid, stop)
- end, Pids);
- _ ->
- ok
- end.
-
-handle(Host, Module, Function, Opts, From, To, IQ) ->
- case Opts of
- no_queue ->
- process_iq(Host, Module, Function, From, To, IQ);
- {one_queue, Pid} ->
- Pid ! {process_iq, From, To, IQ};
- {queues, Pids} ->
- Pid = lists:nth(erlang:phash(now(), length(Pids)), Pids),
- Pid ! {process_iq, From, To, IQ};
- parallel ->
- spawn(?MODULE, process_iq, [Host, Module, Function, From, To, IQ]);
- _ ->
- todo
- end.
-
-
-process_iq(_Host, Module, Function, From, To, IQ) ->
- case catch Module:Function(From, To, IQ) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]);
- ResIQ ->
- if
- ResIQ /= ignore ->
- ejabberd_router:route(To, From,
- jlib:iq_to_xml(ResIQ));
- true ->
- ok
- end
- end.
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% Description: Initiates the server
-%%--------------------------------------------------------------------
-init([Host, Module, Function]) ->
- {ok, #state{host = Host,
- module = Module,
- function = Function}}.
-
-%%--------------------------------------------------------------------
-%% 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) ->
- Reply = ok,
- {stop, normal, Reply, 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({process_iq, From, To, IQ},
- #state{host = Host,
- module = Module,
- function = Function} = State) ->
- process_iq(Host, Module, Function, From, To, IQ),
- {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) ->
- 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
-%%--------------------------------------------------------------------
diff --git a/ejabberd-1.1.2/src/gen_mod.erl b/ejabberd-1.1.2/src/gen_mod.erl
deleted file mode 100644
index 5f96a2fc6..000000000
--- a/ejabberd-1.1.2/src/gen_mod.erl
+++ /dev/null
@@ -1,150 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : gen_mod.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 24 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(gen_mod).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([start/0,
- start_module/3,
- stop_module/2,
- get_opt/2,
- get_opt/3,
- get_module_opt/4,
- loaded_modules/1,
- loaded_modules_with_opts/1,
- get_hosts/2,
- get_module_proc/2,
- is_loaded/2]).
-
--export([behaviour_info/1]).
-
--include("ejabberd.hrl").
-
--record(ejabberd_module, {module_host, opts}).
-
-behaviour_info(callbacks) ->
- [{start, 2},
- {stop, 1}];
-behaviour_info(_Other) ->
- undefined.
-
-start() ->
- ets:new(ejabberd_modules, [named_table,
- public,
- {keypos, #ejabberd_module.module_host}]),
- ok.
-
-
-start_module(Host, Module, Opts) ->
- case catch Module:start(Host, Opts) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]);
- _ ->
- ets:insert(ejabberd_modules,
- #ejabberd_module{module_host = {Module, Host},
- opts = Opts}),
- ok
- end.
-
-stop_module(Host, Module) ->
- case catch Module:stop(Host) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]);
- {wait, ProcList} when is_list(ProcList) ->
- lists:foreach(fun wait_for_process/1, ProcList),
- ets:delete(ejabberd_modules, {Module, Host}),
- ok;
- {wait, Process} ->
- wait_for_process(Process),
- ets:delete(ejabberd_modules, {Module, Host}),
- ok;
- _ ->
- ets:delete(ejabberd_modules, {Module, Host}),
- ok
- end.
-
-wait_for_process(Process) ->
- MonitorReference = erlang:monitor(process, Process),
- wait_for_stop(Process, MonitorReference).
-
-wait_for_stop(Process, MonitorReference) ->
- receive
- {'DOWN', MonitorReference, _Type, _Object, _Info} ->
- ok
- after 5000 ->
- catch exit(whereis(Process), kill),
- wait_for_stop1(MonitorReference)
- end.
-
-wait_for_stop1(MonitorReference) ->
- receive
- {'DOWN', MonitorReference, _Type, _Object, _Info} ->
- ok
- after 5000 ->
- ok
- end.
-
-get_opt(Opt, Opts) ->
- case lists:keysearch(Opt, 1, Opts) of
- false ->
- % TODO: replace with more appropriate function
- [] = {undefined_option, Opt};
- {value, {_, Val}} ->
- Val
- end.
-
-get_opt(Opt, Opts, Default) ->
- case lists:keysearch(Opt, 1, Opts) of
- false ->
- Default;
- {value, {_, Val}} ->
- Val
- end.
-
-get_module_opt(Host, Module, Opt, Default) ->
- OptsList = ets:lookup(ejabberd_modules, {Module, Host}),
- case OptsList of
- [] ->
- Default;
- [#ejabberd_module{opts = Opts} | _] ->
- get_opt(Opt, Opts, Default)
- end.
-
-loaded_modules(Host) ->
- ets:select(ejabberd_modules,
- [{#ejabberd_module{_ = '_', module_host = {'$1', Host}},
- [],
- ['$1']}]).
-
-loaded_modules_with_opts(Host) ->
- ets:select(ejabberd_modules,
- [{#ejabberd_module{_ = '_', module_host = {'$1', Host},
- opts = '$2'},
- [],
- [{{'$1', '$2'}}]}]).
-
-get_hosts(Opts, Prefix) ->
- case catch gen_mod:get_opt(hosts, Opts) of
- {'EXIT', _Error1} ->
- case catch gen_mod:get_opt(host, Opts) of
- {'EXIT', _Error2} ->
- [Prefix ++ Host || Host <- ?MYHOSTS];
- Host ->
- [Host]
- end;
- Hosts ->
- Hosts
- end.
-
-get_module_proc(Host, Base) ->
- list_to_atom(atom_to_list(Base) ++ "_" ++ Host).
-
-is_loaded(Host, Module) ->
- ets:member(ejabberd_modules, {Module, Host}).
-
diff --git a/ejabberd-1.1.2/src/idna.erl b/ejabberd-1.1.2/src/idna.erl
deleted file mode 100644
index cba1dbc93..000000000
--- a/ejabberd-1.1.2/src/idna.erl
+++ /dev/null
@@ -1,179 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : idna.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Support for IDNA (RFC3490)
-%%% Created : 10 Apr 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(idna).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
-%-compile(export_all).
--export([domain_utf8_to_ascii/1,
- domain_ucs2_to_ascii/1]).
-
-
-domain_utf8_to_ascii(Domain) ->
- domain_ucs2_to_ascii(utf8_to_ucs2(Domain)).
-
-utf8_to_ucs2(S) ->
- utf8_to_ucs2(S, "").
-
-utf8_to_ucs2([], R) ->
- lists:reverse(R);
-utf8_to_ucs2([C | S], R) when C < 16#80 ->
- utf8_to_ucs2(S, [C | R]);
-utf8_to_ucs2([C1, C2 | S], R) when C1 < 16#E0 ->
- utf8_to_ucs2(S, [((C1 band 16#1F) bsl 6) bor
- (C2 band 16#3F) | R]);
-utf8_to_ucs2([C1, C2, C3 | S], R) when C1 < 16#F0 ->
- utf8_to_ucs2(S, [((C1 band 16#0F) bsl 12) bor
- ((C2 band 16#3F) bsl 6) bor
- (C3 band 16#3F) | R]).
-
-
-domain_ucs2_to_ascii(Domain) ->
- case catch domain_ucs2_to_ascii1(Domain) of
- {'EXIT', _Reason} ->
- false;
- Res ->
- Res
- end.
-
-domain_ucs2_to_ascii1(Domain) ->
- Parts = string:tokens(Domain, [16#002E, 16#3002, 16#FF0E, 16#FF61]),
- ASCIIParts = lists:map(fun(P) ->
- to_ascii(P)
- end, Parts),
- string:strip(lists:flatmap(fun(P) -> [$. | P] end, ASCIIParts),
- left, $.).
-
-% Domain names are already nameprep'ed in ejabberd, so we skiping this step
-to_ascii(Name) ->
- false = lists:any(
- fun(C) when
- ( 0 =< C) and (C =< 16#2C) or
- (16#2E =< C) and (C =< 16#2F) or
- (16#3A =< C) and (C =< 16#40) or
- (16#5B =< C) and (C =< 16#60) or
- (16#7B =< C) and (C =< 16#7F) ->
- true;
- (_) ->
- false
- end, Name),
- case Name of
- [H | _] when H /= $- ->
- true = lists:last(Name) /= $-
- end,
- ASCIIName = case lists:any(fun(C) -> C > 16#7F end, Name) of
- true ->
- true = case Name of
- "xn--" ++ _ -> false;
- _ -> true
- end,
- "xn--" ++ punycode_encode(Name);
- false ->
- Name
- end,
- L = length(ASCIIName),
- true = (1 =< L) and (L =< 63),
- ASCIIName.
-
-
-%%% PUNYCODE (RFC3492)
-
--define(BASE, 36).
--define(TMIN, 1).
--define(TMAX, 26).
--define(SKEW, 38).
--define(DAMP, 700).
--define(INITIAL_BIAS, 72).
--define(INITIAL_N, 128).
-
-punycode_encode(Input) ->
- N = ?INITIAL_N,
- Delta = 0,
- Bias = ?INITIAL_BIAS,
- Basic = lists:filter(fun(C) -> C =< 16#7f end, Input),
- NonBasic = lists:filter(fun(C) -> C > 16#7f end, Input),
- L = length(Input),
- B = length(Basic),
- SNonBasic = lists:usort(NonBasic),
- Output1 = if
- B > 0 -> Basic ++ "-";
- true -> ""
- end,
- Output2 = punycode_encode1(Input, SNonBasic, B, B, L, N, Delta, Bias, ""),
- Output1 ++ Output2.
-
-
-punycode_encode1(Input, [M | SNonBasic], B, H, L, N, Delta, Bias, Out)
- when H < L ->
- Delta1 = Delta + (M - N) * (H + 1),
- % let n = m
- {NewDelta, NewBias, NewH, NewOut} =
- lists:foldl(
- fun(C, {ADelta, ABias, AH, AOut}) ->
- if
- C < M ->
- {ADelta + 1, ABias, AH, AOut};
- C == M ->
- NewOut = punycode_encode_delta(ADelta, ABias, AOut),
- NewBias = adapt(ADelta, H + 1, H == B),
- {0, NewBias, AH + 1, NewOut};
- true ->
- {ADelta, ABias, AH, AOut}
- end
- end, {Delta1, Bias, H, Out}, Input),
- punycode_encode1(
- Input, SNonBasic, B, NewH, L, M + 1, NewDelta + 1, NewBias, NewOut);
-
-punycode_encode1(Input, SNonBasic, B, H, L, N, Delta, Bias, Out) ->
- lists:reverse(Out).
-
-
-punycode_encode_delta(Delta, Bias, Out) ->
- punycode_encode_delta(Delta, Bias, Out, ?BASE).
-
-punycode_encode_delta(Delta, Bias, Out, K) ->
- T = if
- K =< Bias -> ?TMIN;
- K >= Bias + ?TMAX -> ?TMAX;
- true -> K - Bias
- end,
- if
- Delta < T ->
- [codepoint(Delta) | Out];
- true ->
- C = T + ((Delta - T) rem (?BASE - T)),
- punycode_encode_delta((Delta - T) div (?BASE - T), Bias,
- [codepoint(C) | Out], K + ?BASE)
- end.
-
-
-adapt(Delta, NumPoints, FirstTime) ->
- Delta1 = if
- FirstTime -> Delta div ?DAMP;
- true -> Delta div 2
- end,
- Delta2 = Delta1 + (Delta1 div NumPoints),
- adapt1(Delta2, 0).
-
-adapt1(Delta, K) ->
- if
- Delta > ((?BASE - ?TMIN) * ?TMAX) div 2 ->
- adapt1(Delta div (?BASE - ?TMIN), K + ?BASE);
- true ->
- K + (((?BASE - ?TMIN + 1) * Delta) div (Delta + ?SKEW))
- end.
-
-
-codepoint(C) ->
- if
- (0 =< C) and (C =< 25) ->
- C + 97;
- (26 =< C) and (C =< 35) ->
- C + 22
- end.
diff --git a/ejabberd-1.1.2/src/jd2ejd.erl b/ejabberd-1.1.2/src/jd2ejd.erl
deleted file mode 100644
index 9fa6048ea..000000000
--- a/ejabberd-1.1.2/src/jd2ejd.erl
+++ /dev/null
@@ -1,191 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : jd2ejd.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Import of jabberd1.4 user spool file
-%%% Created : 2 Feb 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(jd2ejd).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
-%% External exports
--export([import_file/1,
- import_dir/1]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
-
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-
-import_file(File) ->
- User = filename:rootname(filename:basename(File)),
- Server = filename:basename(filename:dirname(File)),
- case (jlib:nodeprep(User) /= error) andalso
- (jlib:nameprep(Server) /= error) of
- true ->
- case file:read_file(File) of
- {ok, Text} ->
- case xml_stream:parse_element(Text) of
- El when element(1, El) == xmlelement ->
- case catch process_xdb(User, Server, El) of
- {'EXIT', Reason} ->
- ?ERROR_MSG(
- "Error while processing file \"~s\": ~p~n",
- [File, Reason]),
- {error, Reason};
- _ ->
- ok
- end;
- {error, Reason} ->
- ?ERROR_MSG("Can't parse file \"~s\": ~p~n",
- [File, Reason]),
- {error, Reason}
- end;
- {error, Reason} ->
- ?ERROR_MSG("Can't read file \"~s\": ~p~n", [File, Reason]),
- {error, Reason}
- end;
- false ->
- ?ERROR_MSG("Illegal user/server name in file \"~s\"~n", [File]),
- {error, "illegal user/server"}
- end.
-
-
-import_dir(Dir) ->
- {ok, Files} = file:list_dir(Dir),
- MsgFiles = lists:filter(
- fun(FN) ->
- case string:len(FN) > 4 of
- true ->
- string:substr(FN,
- string:len(FN) - 3) == ".xml";
- _ ->
- false
- end
- end, Files),
- lists:foldl(
- fun(FN, A) ->
- Res = import_file(filename:join([Dir, FN])),
- case {A, Res} of
- {ok, ok} -> ok;
- {ok, _} -> {error, "see ejabberd log for details"};
- _ -> A
- end
- end, ok, MsgFiles).
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-
-process_xdb(User, Server, {xmlelement, Name, _Attrs, Els}) ->
- case Name of
- "xdb" ->
- lists:foreach(
- fun(El) ->
- xdb_data(User, Server, El)
- end, Els);
- _ ->
- ok
- end.
-
-
-xdb_data(User, Server, {xmlcdata, _CData}) ->
- ok;
-xdb_data(User, Server, {xmlelement, _Name, Attrs, _Els} = El) ->
- From = jlib:make_jid(User, Server, ""),
- LServer = jlib:nameprep(Server),
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_AUTH ->
- Password = xml:get_tag_cdata(El),
- ejabberd_auth:set_password(User, Server, Password),
- ok;
- ?NS_ROSTER ->
- case lists:member(mod_roster_odbc,
- gen_mod:loaded_modules(LServer)) of
- true ->
- catch mod_roster_odbc:set_items(User, Server, El);
- false ->
- catch mod_roster:set_items(User, Server, El)
- end,
- ok;
- ?NS_LAST ->
- TimeStamp = xml:get_attr_s("last", Attrs),
- Status = xml:get_tag_cdata(El),
- case lists:member(mod_last_odbc,
- gen_mod:loaded_modules(LServer)) of
- true ->
- catch mod_last_odbc:store_last_info(
- User,
- Server,
- list_to_integer(TimeStamp),
- Status);
- false ->
- catch mod_last:store_last_info(
- User,
- Server,
- list_to_integer(TimeStamp),
- Status)
- end,
- ok;
- ?NS_VCARD ->
- case lists:member(mod_vcard_odbc,
- gen_mod:loaded_modules(LServer)) of
- true ->
- catch mod_vcard_odbc:process_sm_iq(
- From,
- jlib:make_jid("", Server, ""),
- #iq{type = set, xmlns = ?NS_VCARD, sub_el = El});
- false ->
- catch mod_vcard:process_sm_iq(
- From,
- jlib:make_jid("", Server, ""),
- #iq{type = set, xmlns = ?NS_VCARD, sub_el = El})
- end,
- ok;
- "jabber:x:offline" ->
- process_offline(Server, From, El),
- ok;
- XMLNS ->
- case xml:get_attr_s("j_private_flag", Attrs) of
- "1" ->
- catch mod_private:process_sm_iq(
- From,
- jlib:make_jid("", Server, ""),
- #iq{type = set, xmlns = ?NS_PRIVATE,
- sub_el = {xmlelement, "query", [],
- [jlib:remove_attr(
- "j_private_flag",
- jlib:remove_attr("xdbns", El))]}});
- _ ->
- ?DEBUG("jd2ejd: Unknown namespace \"~s\"~n", [XMLNS])
- end,
- ok
- end.
-
-
-process_offline(Server, To, {xmlelement, _, _, Els}) ->
- LServer = jlib:nameprep(Server),
- lists:foreach(fun({xmlelement, _, Attrs, _} = El) ->
- FromS = xml:get_attr_s("from", Attrs),
- From = case FromS of
- "" ->
- jlib:make_jid("", Server, "");
- _ ->
- jlib:string_to_jid(FromS)
- end,
- case From of
- error ->
- ok;
- _ ->
- ejabberd_hooks:run(offline_message_hook,
- LServer,
- [From, To, El])
- end
- end, Els).
-
diff --git a/ejabberd-1.1.2/src/jlib.erl b/ejabberd-1.1.2/src/jlib.erl
deleted file mode 100644
index 74369cf22..000000000
--- a/ejabberd-1.1.2/src/jlib.erl
+++ /dev/null
@@ -1,633 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : jlib.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(jlib).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([make_result_iq_reply/1,
- make_error_reply/3,
- make_error_reply/2,
- make_error_element/2,
- make_correct_from_to_attrs/3,
- replace_from_to_attrs/3,
- replace_from_to/3,
- remove_attr/2,
- make_jid/3,
- make_jid/1,
- string_to_jid/1,
- jid_to_string/1,
- is_nodename/1,
- tolower/1,
- nodeprep/1,
- nameprep/1,
- resourceprep/1,
- jid_tolower/1,
- jid_remove_resource/1,
- jid_replace_resource/2,
- get_iq_namespace/1,
- iq_query_info/1,
- is_iq_request_type/1,
- iq_to_xml/1,
- parse_xdata_submit/1,
- timestamp_to_iso/1,
- timestamp_to_xml/1,
- now_to_utc_string/1,
- now_to_local_string/1,
- datetime_string_to_timestamp/1,
- decode_base64/1,
- encode_base64/1]).
-
--include("jlib.hrl").
-
-%send_iq(From, To, ID, SubTags) ->
-% ok.
-
-make_result_iq_reply({xmlelement, Name, Attrs, SubTags}) ->
- NewAttrs = make_result_iq_reply_attrs(Attrs),
- {xmlelement, Name, NewAttrs, SubTags}.
-
-make_result_iq_reply_attrs(Attrs) ->
- To = xml:get_attr("to", Attrs),
- From = xml:get_attr("from", Attrs),
- Attrs1 = lists:keydelete("to", 1, Attrs),
- Attrs2 = lists:keydelete("from", 1, Attrs1),
- Attrs3 = case To of
- {value, ToVal} ->
- [{"from", ToVal} | Attrs2];
- _ ->
- Attrs2
- end,
- Attrs4 = case From of
- {value, FromVal} ->
- [{"to", FromVal} | Attrs3];
- _ ->
- Attrs3
- end,
- Attrs5 = lists:keydelete("type", 1, Attrs4),
- Attrs6 = [{"type", "result"} | Attrs5],
- Attrs6.
-
-make_error_reply({xmlelement, Name, Attrs, SubTags}, Code, Desc) ->
- NewAttrs = make_error_reply_attrs(Attrs),
- {xmlelement, Name, NewAttrs, SubTags ++ [{xmlelement, "error",
- [{"code", Code}],
- [{xmlcdata, Desc}]}]}.
-
-make_error_reply({xmlelement, Name, Attrs, SubTags}, Error) ->
- NewAttrs = make_error_reply_attrs(Attrs),
- {xmlelement, Name, NewAttrs, SubTags ++ [Error]}.
-
-make_error_reply_attrs(Attrs) ->
- To = xml:get_attr("to", Attrs),
- From = xml:get_attr("from", Attrs),
- Attrs1 = lists:keydelete("to", 1, Attrs),
- Attrs2 = lists:keydelete("from", 1, Attrs1),
- Attrs3 = case To of
- {value, ToVal} ->
- [{"from", ToVal} | Attrs2];
- _ ->
- Attrs2
- end,
- Attrs4 = case From of
- {value, FromVal} ->
- [{"to", FromVal} | Attrs3];
- _ ->
- Attrs3
- end,
- Attrs5 = lists:keydelete("type", 1, Attrs4),
- Attrs6 = [{"type", "error"} | Attrs5],
- Attrs6.
-
-make_error_element(Code, Desc) ->
- {xmlelement, "error",
- [{"code", Code}],
- [{xmlcdata, Desc}]}.
-
-make_correct_from_to_attrs(From, To, Attrs) ->
- Attrs1 = lists:keydelete("from", 1, Attrs),
- Attrs2 = case xml:get_attr("to", Attrs) of
- {value, _} ->
- Attrs1;
- _ ->
- [{"to", To} | Attrs1]
- end,
- Attrs3 = [{"from", From} | Attrs2],
- Attrs3.
-
-
-replace_from_to_attrs(From, To, Attrs) ->
- Attrs1 = lists:keydelete("to", 1, Attrs),
- Attrs2 = lists:keydelete("from", 1, Attrs1),
- Attrs3 = [{"to", To} | Attrs2],
- Attrs4 = [{"from", From} | Attrs3],
- Attrs4.
-
-replace_from_to(From, To, {xmlelement, Name, Attrs, Els}) ->
- NewAttrs = replace_from_to_attrs(jlib:jid_to_string(From),
- jlib:jid_to_string(To),
- Attrs),
- {xmlelement, Name, NewAttrs, Els}.
-
-
-remove_attr(Attr, {xmlelement, Name, Attrs, Els}) ->
- NewAttrs = lists:keydelete(Attr, 1, Attrs),
- {xmlelement, Name, NewAttrs, Els}.
-
-
-make_jid(User, Server, Resource) ->
- case nodeprep(User) of
- error -> error;
- LUser ->
- case nameprep(Server) of
- error -> error;
- LServer ->
- case resourceprep(Resource) of
- error -> error;
- LResource ->
- #jid{user = User,
- server = Server,
- resource = Resource,
- luser = LUser,
- lserver = LServer,
- lresource = LResource}
- end
- end
- end.
-
-make_jid({User, Server, Resource}) ->
- make_jid(User, Server, Resource).
-
-string_to_jid(J) ->
- string_to_jid1(J, "").
-
-string_to_jid1([$@ | _J], "") ->
- error;
-string_to_jid1([$@ | J], N) ->
- string_to_jid2(J, lists:reverse(N), "");
-string_to_jid1([$/ | _J], "") ->
- error;
-string_to_jid1([$/ | J], N) ->
- string_to_jid3(J, "", lists:reverse(N), "");
-string_to_jid1([C | J], N) ->
- string_to_jid1(J, [C | N]);
-string_to_jid1([], "") ->
- error;
-string_to_jid1([], N) ->
- make_jid("", lists:reverse(N), "").
-
-%% Only one "@" is admitted per JID
-string_to_jid2([$@ | _J], _N, _S) ->
- error;
-string_to_jid2([$/ | _J], _N, "") ->
- error;
-string_to_jid2([$/ | J], N, S) ->
- string_to_jid3(J, N, lists:reverse(S), "");
-string_to_jid2([C | J], N, S) ->
- string_to_jid2(J, N, [C | S]);
-string_to_jid2([], _N, "") ->
- error;
-string_to_jid2([], N, S) ->
- make_jid(N, lists:reverse(S), "").
-
-string_to_jid3([C | J], N, S, R) ->
- string_to_jid3(J, N, S, [C | R]);
-string_to_jid3([], N, S, R) ->
- make_jid(N, S, lists:reverse(R)).
-
-jid_to_string(#jid{user = User, server = Server, resource = Resource}) ->
- jid_to_string({User, Server, Resource});
-jid_to_string({Node, Server, Resource}) ->
- S1 = case Node of
- "" ->
- "";
- _ ->
- Node ++ "@"
- end,
- S2 = S1 ++ Server,
- S3 = case Resource of
- "" ->
- S2;
- _ ->
- S2 ++ "/" ++ Resource
- end,
- S3.
-
-
-is_nodename([]) ->
- false;
-is_nodename(J) ->
- nodeprep(J) /= error.
-
-
-%tolower_c(C) when C >= $A, C =< $Z ->
-% C + 32;
-%tolower_c(C) ->
-% C.
-
--define(LOWER(Char),
- if
- Char >= $A, Char =< $Z ->
- Char + 32;
- true ->
- Char
- end).
-
-%tolower(S) ->
-% lists:map(fun tolower_c/1, S).
-
-%tolower(S) ->
-% [?LOWER(Char) || Char <- S].
-
-% Not tail-recursive but it seems works faster than variants above
-tolower([C | Cs]) ->
- if
- C >= $A, C =< $Z ->
- [C + 32 | tolower(Cs)];
- true ->
- [C | tolower(Cs)]
- end;
-tolower([]) ->
- [].
-
-%tolower([C | Cs]) when C >= $A, C =< $Z ->
-% [C + 32 | tolower(Cs)];
-%tolower([C | Cs]) ->
-% [C | tolower(Cs)];
-%tolower([]) ->
-% [].
-
-
-nodeprep(S) when length(S) < 1024 ->
- R = stringprep:nodeprep(S),
- if
- length(R) < 1024 -> R;
- true -> error
- end;
-nodeprep(_) ->
- error.
-
-nameprep(S) when length(S) < 1024 ->
- R = stringprep:nameprep(S),
- if
- length(R) < 1024 -> R;
- true -> error
- end;
-nameprep(_) ->
- error.
-
-resourceprep(S) when length(S) < 1024 ->
- R = stringprep:resourceprep(S),
- if
- length(R) < 1024 -> R;
- true -> error
- end;
-resourceprep(_) ->
- error.
-
-
-jid_tolower(#jid{luser = U, lserver = S, lresource = R}) ->
- {U, S, R};
-jid_tolower({U, S, R}) ->
- case nodeprep(U) of
- error -> error;
- LUser ->
- case nameprep(S) of
- error -> error;
- LServer ->
- case resourceprep(R) of
- error -> error;
- LResource ->
- {LUser, LServer, LResource}
- end
- end
- end.
-
-jid_remove_resource(#jid{} = JID) ->
- JID#jid{resource = "", lresource = ""};
-jid_remove_resource({U, S, _R}) ->
- {U, S, ""}.
-
-jid_replace_resource(JID, Resource) ->
- case resourceprep(Resource) of
- error -> error;
- LResource ->
- JID#jid{resource = Resource, lresource = LResource}
- end.
-
-
-get_iq_namespace({xmlelement, Name, _Attrs, Els}) when Name == "iq" ->
- case xml:remove_cdata(Els) of
- [{xmlelement, _Name2, Attrs2, _Els2}] ->
- xml:get_attr_s("xmlns", Attrs2);
- _ ->
- ""
- end;
-get_iq_namespace(_) ->
- "".
-
-iq_query_info({xmlelement, Name, Attrs, Els}) when Name == "iq" ->
- ID = xml:get_attr_s("id", Attrs),
- Type = xml:get_attr_s("type", Attrs),
- Lang = xml:get_attr_s("xml:lang", Attrs),
- Type1 = case Type of
- "set" -> set;
- "get" -> get;
- "result" -> reply;
- "error" -> reply;
- _ -> invalid
- end,
- if
- (Type1 /= invalid) and (Type1 /= reply) ->
- case xml:remove_cdata(Els) of
- [{xmlelement, Name2, Attrs2, Els2}] ->
- XMLNS = xml:get_attr_s("xmlns", Attrs2),
- if
- XMLNS /= "" ->
- #iq{id = ID,
- type = Type1,
- xmlns = XMLNS,
- lang = Lang,
- sub_el = {xmlelement, Name2, Attrs2, Els2}};
- true ->
- invalid
- end;
- _ ->
- invalid
- end;
- true ->
- Type1
- end;
-iq_query_info(_) ->
- not_iq.
-
-is_iq_request_type(set) -> true;
-is_iq_request_type(get) -> true;
-is_iq_request_type(_) -> false.
-
-iq_type_to_string(set) -> "set";
-iq_type_to_string(get) -> "get";
-iq_type_to_string(result) -> "result";
-iq_type_to_string(error) -> "error";
-iq_type_to_string(_) -> invalid.
-
-
-iq_to_xml(#iq{id = ID, type = Type, sub_el = SubEl}) ->
- if
- ID /= "" ->
- {xmlelement, "iq",
- [{"id", ID}, {"type", iq_type_to_string(Type)}], SubEl};
- true ->
- {xmlelement, "iq",
- [{"type", iq_type_to_string(Type)}], SubEl}
- end.
-
-
-parse_xdata_submit(El) ->
- {xmlelement, _Name, Attrs, Els} = El,
- case xml:get_attr_s("type", Attrs) of
- "submit" ->
- lists:reverse(parse_xdata_fields(Els, []));
- _ ->
- invalid
- end.
-
-parse_xdata_fields([], Res) ->
- Res;
-parse_xdata_fields([{xmlelement, Name, Attrs, SubEls} | Els], Res) ->
- case Name of
- "field" ->
- case xml:get_attr_s("var", Attrs) of
- "" ->
- parse_xdata_fields(Els, Res);
- Var ->
- Field =
- {Var, lists:reverse(parse_xdata_values(SubEls, []))},
- parse_xdata_fields(Els, [Field | Res])
- end;
- _ ->
- parse_xdata_fields(Els, Res)
- end;
-parse_xdata_fields([_ | Els], Res) ->
- parse_xdata_fields(Els, Res).
-
-parse_xdata_values([], Res) ->
- Res;
-parse_xdata_values([{xmlelement, Name, _Attrs, SubEls} | Els], Res) ->
- case Name of
- "value" ->
- Val = xml:get_cdata(SubEls),
- parse_xdata_values(Els, [Val | Res]);
- _ ->
- parse_xdata_values(Els, Res)
- end;
-parse_xdata_values([_ | Els], Res) ->
- parse_xdata_values(Els, Res).
-
-
-timestamp_to_iso({{Year, Month, Day}, {Hour, Minute, Second}}) ->
- lists:flatten(
- io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w",
- [Year, Month, Day, Hour, Minute, Second])).
-
-timestamp_to_xml({{Year, Month, Day}, {Hour, Minute, Second}}) ->
- {xmlelement, "x",
- [{"xmlns", ?NS_DELAY},
- {"stamp", lists:flatten(
- io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w",
- [Year, Month, Day, Hour, Minute, Second]))}],
- []}.
-
-now_to_utc_string({MegaSecs, Secs, MicroSecs}) ->
- {{Year, Month, Day}, {Hour, Minute, Second}} =
- calendar:now_to_universal_time({MegaSecs, Secs, MicroSecs}),
- lists:flatten(
- io_lib:format("~4..0w-~2..0w-~2..0wT~2..0w:~2..0w:~2..0w.~6..0wZ",
- [Year, Month, Day, Hour, Minute, Second, MicroSecs])).
-
-now_to_local_string({MegaSecs, Secs, MicroSecs}) ->
- LocalTime = calendar:now_to_local_time({MegaSecs, Secs, MicroSecs}),
- UTCTime = calendar:now_to_universal_time({MegaSecs, Secs, MicroSecs}),
- Seconds = calendar:datetime_to_gregorian_seconds(LocalTime) -
- calendar:datetime_to_gregorian_seconds(UTCTime),
- {{H, M, _}, Sign} = if
- Seconds < 0 ->
- {calendar:seconds_to_time(-Seconds), "-"};
- true ->
- {calendar:seconds_to_time(Seconds), "+"}
- end,
- {{Year, Month, Day}, {Hour, Minute, Second}} = LocalTime,
- lists:flatten(
- io_lib:format("~4..0w-~2..0w-~2..0wT~2..0w:~2..0w:~2..0w.~6..0w~s~2..0w:~2..0w",
- [Year, Month, Day, Hour, Minute, Second, MicroSecs, Sign, H, M])).
-
-
-% yyyy-mm-ddThh:mm:ss[.sss]{Z|{+|-}hh:mm} -> {MegaSecs, Secs, MicroSecs}
-datetime_string_to_timestamp(TimeStr) ->
- case catch parse_datetime(TimeStr) of
- {'EXIT', _Err} ->
- undefined;
- TimeStamp ->
- TimeStamp
- end.
-
-parse_datetime(TimeStr) ->
- [Date, Time] = string:tokens(TimeStr, "T"),
- D = parse_date(Date),
- {T, MS, TZH, TZM} = parse_time(Time),
- S = calendar:datetime_to_gregorian_seconds({D, T}),
- S1 = calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}}),
- Seconds = (S - S1) - TZH * 60 * 60 - TZM * 60,
- {Seconds div 1000000, Seconds rem 1000000, MS}.
-
-% yyyy-mm-dd
-parse_date(Date) ->
- [Y, M, D] = string:tokens(Date, "-"),
- Date1 = {list_to_integer(Y), list_to_integer(M), list_to_integer(D)},
- case calendar:valid_date(Date1) of
- true ->
- Date1;
- _ ->
- false
- end.
-
-% hh:mm:ss[.sss]TZD
-parse_time(Time) ->
- case string:str(Time, "Z") of
- 0 ->
- parse_time_with_timezone(Time);
- _ ->
- [T | _] = string:tokens(Time, "Z"),
- {TT, MS} = parse_time1(T),
- {TT, MS, 0, 0}
- end.
-
-parse_time_with_timezone(Time) ->
- case string:str(Time, "+") of
- 0 ->
- case string:str(Time, "-") of
- 0 ->
- false;
- _ ->
- parse_time_with_timezone(Time, "-")
- end;
- _ ->
- parse_time_with_timezone(Time, "+")
- end.
-
-parse_time_with_timezone(Time, Delim) ->
- [T, TZ] = string:tokens(Time, Delim),
- {TZH, TZM} = parse_timezone(TZ),
- {TT, MS} = parse_time1(T),
- case Delim of
- "-" ->
- {TT, MS, -TZH, -TZM};
- "+" ->
- {TT, MS, TZH, TZM}
- end.
-
-parse_timezone(TZ) ->
- [H, M] = string:tokens(TZ, ":"),
- {[H1, M1], true} = check_list([{H, 12}, {M, 60}]),
- {H1, M1}.
-
-parse_time1(Time) ->
- [HMS | T] = string:tokens(Time, "."),
- MS = case T of
- [] ->
- 0;
- [Val] ->
- list_to_integer(string:left(Val, 6, $0))
- end,
- [H, M, S] = string:tokens(HMS, ":"),
- {[H1, M1, S1], true} = check_list([{H, 24}, {M, 60}, {S, 60}]),
- {{H1, M1, S1}, MS}.
-
-check_list(List) ->
- lists:mapfoldl(
- fun({L, N}, B)->
- V = list_to_integer(L),
- if
- (V >= 0) and (V =< N) ->
- {V, B};
- true ->
- {false, false}
- end
- end, true, List).
-
-
-%
-% Base64 stuff (based on httpd_util.erl)
-%
-
-decode_base64(S) ->
- decode1_base64([C || C <- S,
- C /= $ ,
- C /= $\t,
- C /= $\n,
- C /= $\r]).
-
-decode1_base64([]) ->
- [];
-decode1_base64([Sextet1,Sextet2,$=,$=|Rest]) ->
- Bits2x6=
- (d(Sextet1) bsl 18) bor
- (d(Sextet2) bsl 12),
- Octet1=Bits2x6 bsr 16,
- [Octet1|decode_base64(Rest)];
-decode1_base64([Sextet1,Sextet2,Sextet3,$=|Rest]) ->
- Bits3x6=
- (d(Sextet1) bsl 18) bor
- (d(Sextet2) bsl 12) bor
- (d(Sextet3) bsl 6),
- Octet1=Bits3x6 bsr 16,
- Octet2=(Bits3x6 bsr 8) band 16#ff,
- [Octet1,Octet2|decode_base64(Rest)];
-decode1_base64([Sextet1,Sextet2,Sextet3,Sextet4|Rest]) ->
- Bits4x6=
- (d(Sextet1) bsl 18) bor
- (d(Sextet2) bsl 12) bor
- (d(Sextet3) bsl 6) bor
- d(Sextet4),
- Octet1=Bits4x6 bsr 16,
- Octet2=(Bits4x6 bsr 8) band 16#ff,
- Octet3=Bits4x6 band 16#ff,
- [Octet1,Octet2,Octet3|decode_base64(Rest)];
-decode1_base64(_CatchAll) ->
- "".
-
-d(X) when X >= $A, X =<$Z ->
- X-65;
-d(X) when X >= $a, X =<$z ->
- X-71;
-d(X) when X >= $0, X =<$9 ->
- X+4;
-d($+) -> 62;
-d($/) -> 63;
-d(_) -> 63.
-
-
-encode_base64([]) ->
- [];
-encode_base64([A]) ->
- [e(A bsr 2), e((A band 3) bsl 4), $=, $=];
-encode_base64([A,B]) ->
- [e(A bsr 2), e(((A band 3) bsl 4) bor (B bsr 4)), e((B band 15) bsl 2), $=];
-encode_base64([A,B,C|Ls]) ->
- encode_base64_do(A,B,C, Ls).
-encode_base64_do(A,B,C, Rest) ->
- BB = (A bsl 16) bor (B bsl 8) bor C,
- [e(BB bsr 18), e((BB bsr 12) band 63),
- e((BB bsr 6) band 63), e(BB band 63)|encode_base64(Rest)].
-
-e(X) when X >= 0, X < 26 -> X+65;
-e(X) when X>25, X<52 -> X+71;
-e(X) when X>51, X<62 -> X-4;
-e(62) -> $+;
-e(63) -> $/;
-e(X) -> exit({bad_encode_base64_token, X}).
diff --git a/ejabberd-1.1.2/src/jlib.hrl b/ejabberd-1.1.2/src/jlib.hrl
deleted file mode 100644
index ca261320f..000000000
--- a/ejabberd-1.1.2/src/jlib.hrl
+++ /dev/null
@@ -1,287 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : jlib.hrl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 5 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%%----------------------------------------------------------------------
-
--define(NS_DISCO_ITEMS, "http://jabber.org/protocol/disco#items").
--define(NS_DISCO_INFO, "http://jabber.org/protocol/disco#info").
--define(NS_VCARD, "vcard-temp").
--define(NS_AUTH, "jabber:iq:auth").
--define(NS_AUTH_ERROR, "jabber:iq:auth:error").
--define(NS_REGISTER, "jabber:iq:register").
--define(NS_SEARCH, "jabber:iq:search").
--define(NS_ROSTER, "jabber:iq:roster").
--define(NS_PRIVACY, "jabber:iq:privacy").
--define(NS_PRIVATE, "jabber:iq:private").
--define(NS_VERSION, "jabber:iq:version").
--define(NS_TIME, "jabber:iq:time").
--define(NS_LAST, "jabber:iq:last").
--define(NS_XDATA, "jabber:x:data").
--define(NS_IQDATA, "jabber:iq:data").
--define(NS_DELAY, "jabber:x:delay").
--define(NS_EXPIRE, "jabber:x:expire").
--define(NS_EVENT, "jabber:x:event").
--define(NS_XCONFERENCE, "jabber:x:conference").
--define(NS_STATS, "http://jabber.org/protocol/stats").
--define(NS_MUC, "http://jabber.org/protocol/muc").
--define(NS_MUC_USER, "http://jabber.org/protocol/muc#user").
--define(NS_MUC_ADMIN, "http://jabber.org/protocol/muc#admin").
--define(NS_MUC_OWNER, "http://jabber.org/protocol/muc#owner").
--define(NS_PUBSUB, "http://jabber.org/protocol/pubsub").
--define(NS_PUBSUB_EVENT, "http://jabber.org/protocol/pubsub#event").
--define(NS_PUBSUB_OWNER, "http://jabber.org/protocol/pubsub#owner").
--define(NS_PUBSUB_NMI, "http://jabber.org/protocol/pubsub#node-meta-info").
--define(NS_COMMANDS, "http://jabber.org/protocol/commands").
-
--define(NS_EJABBERD_CONFIG, "ejabberd:config").
-
--define(NS_STREAM, "http://etherx.jabber.org/streams").
-
--define(NS_STANZAS, "urn:ietf:params:xml:ns:xmpp-stanzas").
--define(NS_STREAMS, "urn:ietf:params:xml:ns:xmpp-streams").
-
--define(NS_TLS, "urn:ietf:params:xml:ns:xmpp-tls").
--define(NS_SASL, "urn:ietf:params:xml:ns:xmpp-sasl").
--define(NS_SESSION, "urn:ietf:params:xml:ns:xmpp-session").
--define(NS_BIND, "urn:ietf:params:xml:ns:xmpp-bind").
-
--define(NS_FEATURE_IQAUTH, "http://jabber.org/features/iq-auth").
--define(NS_FEATURE_IQREGISTER, "http://jabber.org/features/iq-register").
--define(NS_FEATURE_COMPRESS, "http://jabber.org/features/compress").
-
--define(NS_COMPRESS, "http://jabber.org/protocol/compress").
-
-% TODO: remove "code" attribute (currently it used for backward-compatibility)
--define(STANZA_ERROR(Code, Type, Condition),
- {xmlelement, "error",
- [{"code", Code}, {"type", Type}],
- [{xmlelement, Condition, [{"xmlns", ?NS_STANZAS}], []}]}).
-
--define(ERR_BAD_REQUEST,
- ?STANZA_ERROR("400", "modify", "bad-request")).
--define(ERR_CONFLICT,
- ?STANZA_ERROR("409", "cancel", "conflict")).
--define(ERR_FEATURE_NOT_IMPLEMENTED,
- ?STANZA_ERROR("501", "cancel", "feature-not-implemented")).
--define(ERR_FORBIDDEN,
- ?STANZA_ERROR("403", "auth", "forbidden")).
--define(ERR_GONE,
- ?STANZA_ERROR("302", "modify", "gone")).
--define(ERR_INTERNAL_SERVER_ERROR,
- ?STANZA_ERROR("500", "wait", "internal-server-error")).
--define(ERR_ITEM_NOT_FOUND,
- ?STANZA_ERROR("404", "cancel", "item-not-found")).
--define(ERR_JID_MALFORMED,
- ?STANZA_ERROR("400", "modify", "jid-malformed")).
--define(ERR_NOT_ACCEPTABLE,
- ?STANZA_ERROR("406", "modify", "not-acceptable")).
--define(ERR_NOT_ALLOWED,
- ?STANZA_ERROR("405", "cancel", "not-allowed")).
--define(ERR_NOT_AUTHORIZED,
- ?STANZA_ERROR("401", "auth", "not-authorized")).
--define(ERR_PAYMENT_REQUIRED,
- ?STANZA_ERROR("402", "auth", "payment-required")).
--define(ERR_RECIPIENT_UNAVAILABLE,
- ?STANZA_ERROR("404", "wait", "recipient-unavailable")).
--define(ERR_REDIRECT,
- ?STANZA_ERROR("302", "modify", "redirect")).
--define(ERR_REGISTRATION_REQUIRED,
- ?STANZA_ERROR("407", "auth", "registration-required")).
--define(ERR_REMOTE_SERVER_NOT_FOUND,
- ?STANZA_ERROR("404", "cancel", "remote-server-not-found")).
--define(ERR_REMOTE_SERVER_TIMEOUT,
- ?STANZA_ERROR("504", "wait", "remote-server-timeout")).
--define(ERR_RESOURCE_CONSTRAINT,
- ?STANZA_ERROR("500", "wait", "resource-constraint")).
--define(ERR_SERVICE_UNAVAILABLE,
- ?STANZA_ERROR("503", "cancel", "service-unavailable")).
--define(ERR_SUBSCRIPTION_REQUIRED,
- ?STANZA_ERROR("407", "auth", "subscription-required")).
--define(ERR_UNEXPECTED_REQUEST,
- ?STANZA_ERROR("400", "wait", "unexpected-request")).
-%-define(ERR_,
-% ?STANZA_ERROR("", "", "")).
-
--define(STANZA_ERRORT(Code, Type, Condition, Lang, Text),
- {xmlelement, "error",
- [{"code", Code}, {"type", Type}],
- [{xmlelement, Condition, [{"xmlns", ?NS_STANZAS}], []},
- {xmlelement, "text", [{"xmlns", ?NS_STANZAS}],
- [{xmlcdata, translate:translate(Lang, Text)}]}]}).
-
--define(ERRT_BAD_REQUEST(Lang, Text),
- ?STANZA_ERRORT("400", "modify", "bad-request", Lang, Text)).
--define(ERRT_CONFLICT(Lang, Text),
- ?STANZA_ERRORT("409", "cancel", "conflict", Lang, Text)).
--define(ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Text),
- ?STANZA_ERRORT("501", "cancel", "feature-not-implemented", Lang, Text)).
--define(ERRT_FORBIDDEN(Lang, Text),
- ?STANZA_ERRORT("403", "auth", "forbidden", Lang, Text)).
--define(ERRT_GONE(Lang, Text),
- ?STANZA_ERRORT("302", "modify", "gone", Lang, Text)).
--define(ERRT_INTERNAL_SERVER_ERROR(Lang, Text),
- ?STANZA_ERRORT("500", "wait", "internal-server-error", Lang, Text)).
--define(ERRT_ITEM_NOT_FOUND(Lang, Text),
- ?STANZA_ERRORT("404", "cancel", "item-not-found", Lang, Text)).
--define(ERRT_JID_MALFORMED(Lang, Text),
- ?STANZA_ERRORT("400", "modify", "jid-malformed", Lang, Text)).
--define(ERRT_NOT_ACCEPTABLE(Lang, Text),
- ?STANZA_ERRORT("406", "modify", "not-acceptable", Lang, Text)).
--define(ERRT_NOT_ALLOWED(Lang, Text),
- ?STANZA_ERRORT("405", "cancel", "not-allowed", Lang, Text)).
--define(ERRT_NOT_AUTHORIZED(Lang, Text),
- ?STANZA_ERRORT("401", "auth", "not-authorized", Lang, Text)).
--define(ERRT_PAYMENT_REQUIRED(Lang, Text),
- ?STANZA_ERRORT("402", "auth", "payment-required", Lang, Text)).
--define(ERRT_RECIPIENT_UNAVAILABLE(Lang, Text),
- ?STANZA_ERRORT("404", "wait", "recipient-unavailable", Lang, Text)).
--define(ERRT_REDIRECT(Lang, Text),
- ?STANZA_ERRORT("302", "modify", "redirect", Lang, Text)).
--define(ERRT_REGISTRATION_REQUIRED(Lang, Text),
- ?STANZA_ERRORT("407", "auth", "registration-required", Lang, Text)).
--define(ERRT_REMOTE_SERVER_NOT_FOUND(Lang, Text),
- ?STANZA_ERRORT("404", "cancel", "remote-server-not-found", Lang, Text)).
--define(ERRT_REMOTE_SERVER_TIMEOUT(Lang, Text),
- ?STANZA_ERRORT("504", "wait", "remote-server-timeout", Lang, Text)).
--define(ERRT_RESOURCE_CONSTRAINT(Lang, Text),
- ?STANZA_ERRORT("500", "wait", "resource-constraint", Lang, Text)).
--define(ERRT_SERVICE_UNAVAILABLE(Lang, Text),
- ?STANZA_ERRORT("503", "cancel", "service-unavailable", Lang, Text)).
--define(ERRT_SUBSCRIPTION_REQUIRED(Lang, Text),
- ?STANZA_ERRORT("407", "auth", "subscription-required", Lang, Text)).
--define(ERRT_UNEXPECTED_REQUEST(Lang, Text),
- ?STANZA_ERRORT("400", "wait", "unexpected-request", Lang, Text)).
-
-% Auth stanza errors
--define(ERR_AUTH_NO_RESOURCE_PROVIDED(Lang),
- ?ERRT_NOT_ACCEPTABLE(Lang, "No resource provided")).
--define(ERR_AUTH_BAD_RESOURCE_FORMAT(Lang),
- ?ERRT_NOT_ACCEPTABLE(Lang, "Illegal resource format")).
--define(ERR_AUTH_RESOURCE_CONFLICT(Lang),
- ?ERRT_CONFLICT(Lang, "Resource conflict")).
-
-
--define(STREAM_ERROR(Condition),
- {xmlelement, "stream:error",
- [],
- [{xmlelement, Condition, [{"xmlns", ?NS_STREAMS}], []}]}).
-
--define(SERR_BAD_FORMAT,
- ?STREAM_ERROR("bad-format")).
--define(SERR_BAD_NAMESPACE_PREFIX,
- ?STREAM_ERROR("bad-namespace-prefix")).
--define(SERR_CONFLICT,
- ?STREAM_ERROR("conflict")).
--define(SERR_CONNECTION_TIMEOUT,
- ?STREAM_ERROR("connection-timeout")).
--define(SERR_HOST_GONE,
- ?STREAM_ERROR("host-gone")).
--define(SERR_HOST_UNKNOWN,
- ?STREAM_ERROR("host-unknown")).
--define(SERR_IMPROPER_ADDRESSING,
- ?STREAM_ERROR("improper-addressing")).
--define(SERR_INTERNAL_SERVER_ERROR,
- ?STREAM_ERROR("internal-server-error")).
--define(SERR_INVALID_FROM,
- ?STREAM_ERROR("invalid-from")).
--define(SERR_INVALID_ID,
- ?STREAM_ERROR("invalid-id")).
--define(SERR_INVALID_NAMESPACE,
- ?STREAM_ERROR("invalid-namespace")).
--define(SERR_INVALID_XML,
- ?STREAM_ERROR("invalid-xml")).
--define(SERR_NOT_AUTHORIZED,
- ?STREAM_ERROR("not-authorized")).
--define(SERR_POLICY_VIOLATION,
- ?STREAM_ERROR("policy-violation")).
--define(SERR_REMOTE_CONNECTION_FAILED,
- ?STREAM_ERROR("remote-connection-failed")).
--define(SERR_RESOURSE_CONSTRAINT,
- ?STREAM_ERROR("resource-constraint")).
--define(SERR_RESTRICTED_XML,
- ?STREAM_ERROR("restricted-xml")).
-% TODO: include hostname or IP
--define(SERR_SEE_OTHER_HOST,
- ?STREAM_ERROR("see-other-host")).
--define(SERR_SYSTEM_SHUTDOWN,
- ?STREAM_ERROR("system-shutdown")).
--define(SERR_UNSUPPORTED_ENCODING,
- ?STREAM_ERROR("unsupported-encoding")).
--define(SERR_UNSUPPORTED_STANZA_TYPE,
- ?STREAM_ERROR("unsupported-stanza-type")).
--define(SERR_UNSUPPORTED_VERSION,
- ?STREAM_ERROR("unsupported-version")).
--define(SERR_XML_NOT_WELL_FORMED,
- ?STREAM_ERROR("xml-not-well-formed")).
-%-define(SERR_,
-% ?STREAM_ERROR("")).
-
--define(STREAM_ERRORT(Condition, Lang, Text),
- {xmlelement, "stream:error",
- [],
- [{xmlelement, Condition, [{"xmlns", ?NS_STREAMS}], []},
- {xmlelement, "text", [{"xml:lang", Lang}, {"xmlns", ?NS_STREAMS}],
- [{xmlcdata, translate:translate(Lang, Text)}]}]}).
-
--define(SERRT_BAD_FORMAT(Lang, Text),
- ?STREAM_ERRORT("bad-format", Lang, Text)).
--define(SERRT_BAD_NAMESPACE_PREFIX(Lang, Text),
- ?STREAM_ERRORT("bad-namespace-prefix", Lang, Text)).
--define(SERRT_CONFLICT(Lang, Text),
- ?STREAM_ERRORT("conflict", Lang, Text)).
--define(SERRT_CONNECTION_TIMEOUT(Lang, Text),
- ?STREAM_ERRORT("connection-timeout", Lang, Text)).
--define(SERRT_HOST_GONE(Lang, Text),
- ?STREAM_ERRORT("host-gone", Lang, Text)).
--define(SERRT_HOST_UNKNOWN(Lang, Text),
- ?STREAM_ERRORT("host-unknown", Lang, Text)).
--define(SERRT_IMPROPER_ADDRESSING(Lang, Text),
- ?STREAM_ERRORT("improper-addressing", Lang, Text)).
--define(SERRT_INTERNAL_SERVER_ERROR(Lang, Text),
- ?STREAM_ERRORT("internal-server-error", Lang, Text)).
--define(SERRT_INVALID_FROM(Lang, Text),
- ?STREAM_ERRORT("invalid-from", Lang, Text)).
--define(SERRT_INVALID_ID(Lang, Text),
- ?STREAM_ERRORT("invalid-id", Lang, Text)).
--define(SERRT_INVALID_NAMESPACE(Lang, Text),
- ?STREAM_ERRORT("invalid-namespace", Lang, Text)).
--define(SERRT_INVALID_XML(Lang, Text),
- ?STREAM_ERRORT("invalid-xml", Lang, Text)).
--define(SERRT_NOT_AUTHORIZED(Lang, Text),
- ?STREAM_ERRORT("not-authorized", Lang, Text)).
--define(SERRT_POLICY_VIOLATION(Lang, Text),
- ?STREAM_ERRORT("policy-violation", Lang, Text)).
--define(SERRT_REMOTE_CONNECTION_FAILED(Lang, Text),
- ?STREAM_ERRORT("remote-connection-failed", Lang, Text)).
--define(SERRT_RESOURSE_CONSTRAINT(Lang, Text),
- ?STREAM_ERRORT("resource-constraint", Lang, Text)).
--define(SERRT_RESTRICTED_XML(Lang, Text),
- ?STREAM_ERRORT("restricted-xml", Lang, Text)).
-% TODO: include hostname or IP
--define(SERRT_SEE_OTHER_HOST(Lang, Text),
- ?STREAM_ERRORT("see-other-host", Lang, Text)).
--define(SERRT_SYSTEM_SHUTDOWN(Lang, Text),
- ?STREAM_ERRORT("system-shutdown", Lang, Text)).
--define(SERRT_UNSUPPORTED_ENCODING(Lang, Text),
- ?STREAM_ERRORT("unsupported-encoding", Lang, Text)).
--define(SERRT_UNSUPPORTED_STANZA_TYPE(Lang, Text),
- ?STREAM_ERRORT("unsupported-stanza-type", Lang, Text)).
--define(SERRT_UNSUPPORTED_VERSION(Lang, Text),
- ?STREAM_ERRORT("unsupported-version", Lang, Text)).
--define(SERRT_XML_NOT_WELL_FORMED(Lang, Text),
- ?STREAM_ERRORT("xml-not-well-formed", Lang, Text)).
-%-define(SERRT_(Lang, Text),
-% ?STREAM_ERRORT("", Lang, Text)).
-
-
--record(jid, {user, server, resource,
- luser, lserver, lresource}).
-
--record(iq, {id = "",
- type,
- xmlns = "",
- lang = "",
- sub_el}).
-
diff --git a/ejabberd-1.1.2/src/mod_adhoc.erl b/ejabberd-1.1.2/src/mod_adhoc.erl
deleted file mode 100644
index 4288524ab..000000000
--- a/ejabberd-1.1.2/src/mod_adhoc.erl
+++ /dev/null
@@ -1,250 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_adhoc.erl
-%%% Author : Magnus Henoch <henoch@dtek.chalmers.se>
-%%% Purpose : Handle incoming ad-doc requests (JEP-0050)
-%%% Created : 15 Nov 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_adhoc).
--author('henoch@dtek.chalmers.se').
--vsn('$Revision$ ').
-
--behaviour(gen_mod).
-
--export([start/2,
- stop/1,
- process_local_iq/3,
- process_sm_iq/3,
- get_local_commands/5,
- get_local_identity/5,
- get_local_features/5,
- get_sm_commands/5,
- get_sm_identity/5,
- get_sm_features/5,
- ping_item/4,
- ping_command/4]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include("adhoc.hrl").
-
-start(Host, Opts) ->
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
-
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS,
- ?MODULE, process_local_iq, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_COMMANDS,
- ?MODULE, process_sm_iq, IQDisc),
-
- ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 99),
- ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 99),
- ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_commands, 99),
- ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 99),
- ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 99),
- ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_commands, 99),
- ejabberd_hooks:add(adhoc_local_items, Host, ?MODULE, ping_item, 100),
- ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, ping_command, 100).
-
-stop(Host) ->
- ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, ping_command, 100),
- ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, ping_item, 100),
- ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_commands, 99),
- ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 99),
- ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, get_sm_identity, 99),
- ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_commands, 99),
- ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 99),
- ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 99),
-
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_COMMANDS),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_COMMANDS).
-
-%-------------------------------------------------------------------------
-
-get_local_commands(Acc, _From, #jid{server = Server, lserver = LServer} = _To, "", Lang) ->
- Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, false),
- case Display of
- false ->
- Acc;
- _ ->
- Items = case Acc of
- {result, I} -> I;
- _ -> []
- end,
- Nodes = [{xmlelement,
- "item",
- [{"jid", Server},
- {"node", ?NS_COMMANDS},
- {"name", translate:translate(Lang, "Commands")}],
- []}],
- {result, Items ++ Nodes}
- end;
-
-get_local_commands(_Acc, From, #jid{lserver = LServer} = To, ?NS_COMMANDS, Lang) ->
- ejabberd_hooks:run_fold(adhoc_local_items, LServer, {result, []}, [From, To, Lang]);
-
-get_local_commands(_Acc, _From, _To, "ping", _Lang) ->
- {result, []};
-
-get_local_commands(Acc, _From, _To, _Node, _Lang) ->
- Acc.
-
-%-------------------------------------------------------------------------
-
-get_sm_commands(Acc, _From, #jid{lserver = LServer} = To, "", Lang) ->
- Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, false),
- case Display of
- false ->
- Acc;
- _ ->
- Items = case Acc of
- {result, I} -> I;
- _ -> []
- end,
- Nodes = [{xmlelement,
- "item",
- [{"jid", jlib:jid_to_string(To)},
- {"node", ?NS_COMMANDS},
- {"name", translate:translate(Lang, "Commands")}],
- []}],
- {result, Items ++ Nodes}
- end;
-
-get_sm_commands(_Acc, From, #jid{lserver = LServer} = To, ?NS_COMMANDS, Lang) ->
- ejabberd_hooks:run_fold(adhoc_sm_items, LServer, {result, []}, [From, To, Lang]);
-
-get_sm_commands(Acc, _From, _To, _Node, _Lang) ->
- Acc.
-
-%-------------------------------------------------------------------------
-
-%% On disco info request to the ad-hoc node, return automation/command-list.
-get_local_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) ->
- [{xmlelement, "identity",
- [{"category", "automation"},
- {"type", "command-list"},
- {"name", translate:translate(Lang, "Commands")}], []} | Acc];
-
-get_local_identity(Acc, _From, _To, "ping", Lang) ->
- [{xmlelement, "identity",
- [{"category", "automation"},
- {"type", "command-node"},
- {"name", translate:translate(Lang, "Ping")}], []} | Acc];
-
-get_local_identity(Acc, _From, _To, _Node, _Lang) ->
- Acc.
-
-%-------------------------------------------------------------------------
-
-%% On disco info request to the ad-hoc node, return automation/command-list.
-get_sm_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) ->
- [{xmlelement, "identity",
- [{"category", "automation"},
- {"type", "command-list"},
- {"name", translate:translate(Lang, "Commands")}], []} | Acc];
-
-get_sm_identity(Acc, _From, _To, _Node, _Lang) ->
- Acc.
-
-%-------------------------------------------------------------------------
-
-get_local_features(Acc, _From, _To, "", _Lang) ->
- Feats = case Acc of
- {result, I} -> I;
- _ -> []
- end,
- {result, Feats ++ [?NS_COMMANDS]};
-
-get_local_features(_Acc, _From, _To, ?NS_COMMANDS, _Lang) ->
- %% override all lesser features...
- {result, []};
-
-get_local_features(_Acc, _From, _To, "ping", _Lang) ->
- %% override all lesser features...
- {result, [?NS_COMMANDS]};
-
-get_local_features(Acc, _From, _To, _Node, _Lang) ->
- Acc.
-
-%-------------------------------------------------------------------------
-
-get_sm_features(Acc, _From, _To, "", _Lang) ->
- Feats = case Acc of
- {result, I} -> I;
- _ -> []
- end,
- {result, Feats ++ [?NS_COMMANDS]};
-
-get_sm_features(_Acc, _From, _To, ?NS_COMMANDS, _Lang) ->
- %% override all lesser features...
- {result, []};
-
-get_sm_features(Acc, _From, _To, _Node, _Lang) ->
- Acc.
-
-%-------------------------------------------------------------------------
-
-process_local_iq(From, To, IQ) ->
- process_adhoc_request(From, To, IQ, adhoc_local_commands).
-
-
-process_sm_iq(From, To, IQ) ->
- process_adhoc_request(From, To, IQ, adhoc_sm_commands).
-
-
-process_adhoc_request(From, To, #iq{sub_el = SubEl} = IQ, Hook) ->
- ?DEBUG("About to parse ~p...", [IQ]),
- case adhoc:parse_request(IQ) of
- {error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]};
- #adhoc_request{} = AdhocRequest ->
- Host = To#jid.lserver,
- case ejabberd_hooks:run_fold(Hook, Host, empty,
- [From, To, AdhocRequest]) of
- ignore ->
- ignore;
- empty ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]};
- {error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]};
- Command ->
- IQ#iq{type = result, sub_el = [Command]}
- end
- end.
-
-
-ping_item(Acc, _From, #jid{server = Server} = _To, Lang) ->
- Items = case Acc of
- {result, I} ->
- I;
- _ ->
- []
- end,
- Nodes = [{xmlelement, "item",
- [{"jid", Server},
- {"node", "ping"},
- {"name", translate:translate(Lang, "Ping")}],
- []}],
- {result, Items ++ Nodes}.
-
-
-ping_command(_Acc, _From, _To,
- #adhoc_request{lang = Lang,
- node = "ping",
- sessionid = _Sessionid,
- action = Action} = Request) ->
- if
- Action == ""; Action == "execute" ->
- adhoc:produce_response(
- Request,
- #adhoc_response{status = completed,
- notes = [{"info", translate:translate(
- Lang,
- "Pong")}]});
- true ->
- {error, ?ERR_BAD_REQUEST}
- end;
-
-ping_command(Acc, _From, _To, _Request) ->
- Acc.
-
diff --git a/ejabberd-1.1.2/src/mod_announce.erl b/ejabberd-1.1.2/src/mod_announce.erl
deleted file mode 100644
index 8cabf748a..000000000
--- a/ejabberd-1.1.2/src/mod_announce.erl
+++ /dev/null
@@ -1,757 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_announce.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Manage announce messages
-%%% Created : 11 Aug 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_announce).
--author('alexey@sevcom.net').
-
--behaviour(gen_mod).
-
--export([start/2,
- init/0,
- stop/1,
- announce/3,
- send_motd/1,
- disco_identity/5,
- disco_features/5,
- disco_items/5,
- announce_commands/4,
- announce_items/4]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include("adhoc.hrl").
-
--record(motd, {server, packet}).
--record(motd_users, {us, dummy = []}).
-
--define(PROCNAME, ejabberd_announce).
-
-start(Host, _Opts) ->
- mnesia:create_table(motd, [{disc_copies, [node()]},
- {attributes, record_info(fields, motd)}]),
- mnesia:create_table(motd_users, [{disc_copies, [node()]},
- {attributes, record_info(fields, motd_users)}]),
- update_tables(),
- ejabberd_hooks:add(local_send_to_resource_hook, Host,
- ?MODULE, announce, 50),
- ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, disco_identity, 50),
- ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50),
- ejabberd_hooks:add(disco_local_items, Host, ?MODULE, disco_items, 50),
- ejabberd_hooks:add(adhoc_local_items, Host, ?MODULE, announce_items, 50),
- ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, announce_commands, 50),
- ejabberd_hooks:add(user_available_hook, Host,
- ?MODULE, send_motd, 50),
- register(gen_mod:get_module_proc(Host, ?PROCNAME),
- proc_lib:spawn(?MODULE, init, [])).
-
-init() ->
- loop().
-
-loop() ->
- receive
- {announce_all, From, To, Packet} ->
- announce_all(From, To, Packet),
- loop();
- {announce_online, From, To, Packet} ->
- announce_online(From, To, Packet),
- loop();
- {announce_all_hosts_online, From, To, Packet} ->
- announce_all_hosts_online(From, To, Packet),
- loop();
- {announce_motd, From, To, Packet} ->
- announce_motd(From, To, Packet),
- loop();
- {announce_motd_update, From, To, Packet} ->
- announce_motd_update(From, To, Packet),
- loop();
- {announce_motd_delete, From, To, Packet} ->
- announce_motd_delete(From, To, Packet),
- loop();
- _ ->
- loop()
- end.
-
-stop(Host) ->
- ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, announce_commands, 50),
- ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, announce_items, 50),
- ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 50),
- ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 50),
- ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, disco_items, 50),
- ejabberd_hooks:delete(local_send_to_resource_hook, Host,
- ?MODULE, announce, 50),
- ejabberd_hooks:delete(sm_register_connection_hook, Host,
- ?MODULE, send_motd, 50),
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- exit(whereis(Proc), stop),
- {wait, Proc}.
-
-% Announcing via messages to a custom resource
-announce(From, To, Packet) ->
- case To of
- #jid{luser = "", lresource = Res} ->
- {xmlelement, Name, _Attrs, _Els} = Packet,
- Proc = gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME),
- case {Res, Name} of
- {"announce/all", "message"} ->
- Proc ! {announce_all, From, To, Packet},
- stop;
- {"announce/online", "message"} ->
- Proc ! {announce_online, From, To, Packet},
- stop;
- {"announce/all-hosts/online", "message"} ->
- Proc ! {announce_all_hosts_online, From, To, Packet},
- stop;
- {"announce/motd", "message"} ->
- Proc ! {announce_motd, From, To, Packet},
- stop;
- {"announce/motd/update", "message"} ->
- Proc ! {announce_motd_update, From, To, Packet},
- stop;
- {"announce/motd/delete", "message"} ->
- Proc ! {announce_motd_delete, From, To, Packet},
- stop;
- _ ->
- ok
- end;
- _ ->
- ok
- end.
-
-%-------------------------------------------------------------------------
-% Announcing via ad-hoc commands
--define(INFO_COMMAND(Lang, Node),
- [{xmlelement, "identity",
- [{"category", "automation"},
- {"type", "command-node"},
- {"name", get_title(Lang, Node)}], []}]).
-
-disco_identity(Acc, _From, _To, Node, Lang) ->
- case Node of
- "announce/all" ->
- ?INFO_COMMAND(Lang, Node);
- "announce/all-hosts/online" ->
- ?INFO_COMMAND(Lang, Node);
- "announce/online" ->
- ?INFO_COMMAND(Lang, Node);
- "announce/motd" ->
- ?INFO_COMMAND(Lang, Node);
- "announce/motd/delete" ->
- ?INFO_COMMAND(Lang, Node);
- "announce/motd/update" ->
- ?INFO_COMMAND(Lang, Node);
- _ ->
- Acc
- end.
-
-%-------------------------------------------------------------------------
-
--define(INFO_RESULT(Allow, Feats),
- case Allow of
- deny ->
- {error, ?ERR_FORBIDDEN};
- allow ->
- {result, Feats}
- end).
-
-disco_features(Acc, From, #jid{lserver = LServer} = _To,
- "announce", _Lang) ->
- case gen_mod:is_loaded(LServer, mod_adhoc) of
- false ->
- Acc;
- _ ->
- Access1 = gen_mod:get_module_opt(LServer, ?MODULE, access, none),
- Access2 = gen_mod:get_module_opt(global, ?MODULE, access, none),
- case {acl:match_rule(LServer, Access1, From),
- acl:match_rule(global, Access2, From)} of
- {deny, deny} ->
- {error, ?ERR_FORBIDDEN};
- _ ->
- {result, []}
- end
- end;
-
-disco_features(Acc, From, #jid{lserver = LServer} = _To,
- "announce/all-hosts/online", _Lang) ->
- case gen_mod:is_loaded(LServer, mod_adhoc) of
- false ->
- Acc;
- _ ->
- Access = gen_mod:get_module_opt(global, ?MODULE, access, none),
- Allow = acl:match_rule(global, Access, From),
- ?INFO_RESULT(Allow, [?NS_COMMANDS])
- end;
-
-disco_features(Acc, From, #jid{lserver = LServer} = _To,
- Node, _Lang) ->
- case gen_mod:is_loaded(LServer, mod_adhoc) of
- false ->
- Acc;
- _ ->
- Access = gen_mod:get_module_opt(LServer, ?MODULE, access, none),
- Allow = acl:match_rule(LServer, Access, From),
- case Node of
- "announce/all" ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- "announce/online" ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- "announce/motd" ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- "announce/motd/delete" ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- "announce/motd/update" ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- _ ->
- Acc
- end
- end.
-
-%-------------------------------------------------------------------------
-
--define(NODE_TO_ITEM(Lang, Server, Node),
- {xmlelement, "item",
- [{"jid", Server},
- {"node", Node},
- {"name", get_title(Lang, Node)}],
- []}).
-
--define(ITEMS_RESULT(Allow, Items),
- case Allow of
- deny ->
- {error, ?ERR_FORBIDDEN};
- allow ->
- {result, Items}
- end).
-
-disco_items(Acc, From, #jid{lserver = LServer, server = Server} = _To,
- "", Lang) ->
- case gen_mod:is_loaded(LServer, mod_adhoc) of
- false ->
- Acc;
- _ ->
- Access1 = gen_mod:get_module_opt(LServer, ?MODULE, access, none),
- Access2 = gen_mod:get_module_opt(global, ?MODULE, access, none),
- case {acl:match_rule(LServer, Access1, From),
- acl:match_rule(global, Access2, From)} of
- {deny, deny} ->
- Acc;
- _ ->
- Items = case Acc of
- {result, I} -> I;
- _ -> []
- end,
- Nodes = [?NODE_TO_ITEM(Lang, Server, "announce")],
- {result, Items ++ Nodes}
- end
- end;
-
-disco_items(Acc, From, #jid{lserver = LServer} = To, "announce", Lang) ->
- case gen_mod:is_loaded(LServer, mod_adhoc) of
- false ->
- Acc;
- _ ->
- announce_items(Acc, From, To, Lang)
- end;
-
-disco_items(Acc, From, #jid{lserver = LServer} = _To,
- "announce/all-hosts/online", _Lang) ->
- case gen_mod:is_loaded(LServer, mod_adhoc) of
- false ->
- Acc;
- _ ->
- Access = gen_mod:get_module_opt(global, ?MODULE, access, none),
- Allow = acl:match_rule(global, Access, From),
- ?ITEMS_RESULT(Allow, [])
- end;
-
-disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
- case gen_mod:is_loaded(LServer, mod_adhoc) of
- false ->
- Acc;
- _ ->
- Access = gen_mod:get_module_opt(LServer, ?MODULE, access, none),
- Allow = acl:match_rule(LServer, Access, From),
- case Node of
- "announce/all" ->
- ?ITEMS_RESULT(Allow, []);
- "announce/online" ->
- ?ITEMS_RESULT(Allow, []);
- "announce/motd" ->
- ?ITEMS_RESULT(Allow, []);
- "announce/motd/delete" ->
- ?ITEMS_RESULT(Allow, []);
- "announce/motd/update" ->
- ?ITEMS_RESULT(Allow, []);
- _ ->
- Acc
- end
- end.
-
-%-------------------------------------------------------------------------
-
-announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang) ->
- Access1 = gen_mod:get_module_opt(LServer, ?MODULE, access, none),
- Nodes1 = case acl:match_rule(LServer, Access1, From) of
- allow ->
- [?NODE_TO_ITEM(Lang, Server, "announce/all"),
- ?NODE_TO_ITEM(Lang, Server, "announce/online"),
- ?NODE_TO_ITEM(Lang, Server, "announce/motd"),
- ?NODE_TO_ITEM(Lang, Server, "announce/motd/delete"),
- ?NODE_TO_ITEM(Lang, Server, "announce/motd/update")];
- deny ->
- []
- end,
- Access2 = gen_mod:get_module_opt(global, ?MODULE, access, none),
- Nodes2 = case acl:match_rule(global, Access2, From) of
- allow ->
- [?NODE_TO_ITEM(Lang, Server, "announce/all-hosts/online")];
- deny ->
- []
- end,
- case {Nodes1, Nodes2} of
- {[], []} ->
- Acc;
- _ ->
- Items = case Acc of
- {result, I} -> I;
- _ -> []
- end,
- {result, Items ++ Nodes1 ++ Nodes2}
- end.
-
-%-------------------------------------------------------------------------
-
--define(COMMANDS_RESULT(Allow, From, To, Request),
- case Allow of
- deny ->
- {error, ?ERR_FORBIDDEN};
- allow ->
- announce_commands(From, To, Request)
- end).
-
-announce_commands(_Acc, From, To,
- #adhoc_request{
- node = "announce/all-hosts/online"} = Request) ->
- Access = gen_mod:get_module_opt(global, ?MODULE, access, none),
- Allow = acl:match_rule(global, Access, From),
- ?COMMANDS_RESULT(Allow, From, To, Request);
-
-announce_commands(Acc, From, #jid{lserver = LServer} = To,
- #adhoc_request{node = Node} = Request) ->
- Access = gen_mod:get_module_opt(LServer, ?MODULE, access, none),
- Allow = acl:match_rule(LServer, Access, From),
- case Node of
- "announce/all" ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- "announce/online" ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- "announce/motd" ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- "announce/motd/delete" ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- "announce/motd/update" ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- _ ->
- Acc
- end.
-
-%-------------------------------------------------------------------------
-
-announce_commands(From, To,
- #adhoc_request{lang = Lang,
- node = Node,
- action = Action,
- xdata = XData} = Request) ->
- %% If the "action" attribute is not present, it is
- %% understood as "execute". If there was no <actions/>
- %% element in the first response (which there isn't in our
- %% case), "execute" and "complete" are equivalent.
- ActionIsExecute = lists:member(Action,
- ["", "execute", "complete"]),
- if Action == "cancel" ->
- %% User cancels request
- adhoc:produce_response(Request,
- #adhoc_response{status = canceled});
- XData == false, ActionIsExecute ->
- %% User requests form
- adhoc:produce_response(
- Request,
- #adhoc_response{status = executing,
- elements = [generate_adhoc_form(Lang, Node)]});
- XData /= false, ActionIsExecute ->
- %% User returns form.
- case jlib:parse_xdata_submit(XData) of
- invalid ->
- {error, ?ERR_BAD_REQUEST};
- Fields ->
- handle_adhoc_form(From, To, Request, Fields)
- end;
- true ->
- {error, ?ERR_BAD_REQUEST}
- end.
-
-generate_adhoc_form(Lang, Node) ->
- {xmlelement, "x",
- [{"xmlns", ?NS_XDATA},
- {"type", "form"}],
- [{xmlelement, "title", [], [{xmlcdata, get_title(Lang, Node)}]}]
- ++
- if Node == "announce/motd/delete" ->
- [{xmlelement, "field",
- [{"var", "confirm"},
- {"type", "boolean"},
- {"label", translate:translate(Lang, "Really delete message of the day?")}],
- [{xmlelement, "value",
- [],
- [{xmlcdata, "true"}]}]}];
- true ->
- [{xmlelement, "field",
- [{"var", "subject"},
- {"type", "text-single"},
- {"label", translate:translate(Lang, "Subject")}],
- []},
- {xmlelement, "field",
- [{"var", "body"},
- {"type", "text-multi"},
- {"label", translate:translate(Lang, "Message body")}],
- []}]
- end}.
-
-join_lines([]) ->
- [];
-join_lines(Lines) ->
- join_lines(Lines, []).
-join_lines([Line|Lines], Acc) ->
- join_lines(Lines, ["\n",Line|Acc]);
-join_lines([], Acc) ->
- %% Remove last newline
- lists:flatten(lists:reverse(tl(Acc))).
-
-handle_adhoc_form(From, #jid{lserver = LServer} = To,
- #adhoc_request{lang = Lang,
- node = Node,
- sessionid = SessionID},
- Fields) ->
- Confirm = case lists:keysearch("confirm", 1, Fields) of
- {value, {"confirm", ["true"]}} ->
- true;
- {value, {"confirm", ["1"]}} ->
- true;
- _ ->
- false
- end,
- Subject = case lists:keysearch("subject", 1, Fields) of
- {value, {"subject", SubjectLines}} ->
- %% There really shouldn't be more than one
- %% subject line, but can we stop them?
- join_lines(SubjectLines);
- _ ->
- []
- end,
- Body = case lists:keysearch("body", 1, Fields) of
- {value, {"body", BodyLines}} ->
- join_lines(BodyLines);
- _ ->
- []
- end,
- Response = #adhoc_response{lang = Lang,
- node = Node,
- sessionid = SessionID,
- status = completed},
- Packet = {xmlelement, "message", [{"type", "normal"}],
- if Subject /= [] ->
- [{xmlelement, "subject", [],
- [{xmlcdata, Subject}]}];
- true ->
- []
- end ++
- if Body /= [] ->
- [{xmlelement, "body", [],
- [{xmlcdata, Body}]}];
- true ->
- []
- end},
-
- Proc = gen_mod:get_module_proc(LServer, ?PROCNAME),
- case {Node, Body} of
- {"announce/motd/delete", _} ->
- if Confirm ->
- Proc ! {announce_motd_delete, From, To, Packet},
- adhoc:produce_response(Response);
- true ->
- adhoc:produce_response(Response)
- end;
- {_, []} ->
- %% An announce message with no body is definitely an operator error.
- %% Throw an error and give him/her a chance to send message again.
- {error, ?ERRT_NOT_ACCEPTABLE(
- Lang,
- "No body provided for announce message")};
- %% Now send the packet to ?PROCNAME.
- %% We don't use direct announce_* functions because it
- %% leads to large delay in response and <iq/> queries processing
- {"announce/all", _} ->
- Proc ! {announce_all, From, To, Packet},
- adhoc:produce_response(Response);
- {"announce/online", _} ->
- Proc ! {announce_online, From, To, Packet},
- adhoc:produce_response(Response);
- {"announce/all-hosts/online", _} ->
- Proc ! {announce_all_hosts_online, From, To, Packet},
- adhoc:produce_response(Response);
- {"announce/motd", _} ->
- Proc ! {announce_motd, From, To, Packet},
- adhoc:produce_response(Response);
- {"announce/motd/update", _} ->
- Proc ! {announce_motd_update, From, To, Packet},
- adhoc:produce_response(Response);
- _ ->
- %% This can't happen, as we haven't registered any other
- %% command nodes.
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end.
-
-get_title(Lang, "announce") ->
- translate:translate(Lang, "Announcements");
-get_title(Lang, "announce/all") ->
- translate:translate(Lang, "Send announcement to all users");
-get_title(Lang, "announce/online") ->
- translate:translate(Lang, "Send announcement to all online users");
-get_title(Lang, "announce/all-hosts/online") ->
- translate:translate(Lang, "Send announcement to all online users on all hosts");
-get_title(Lang, "announce/motd") ->
- translate:translate(Lang, "Set message of the day and send to online users");
-get_title(Lang, "announce/motd/update") ->
- translate:translate(Lang, "Update message of the day (don't send)");
-get_title(Lang, "announce/motd/delete") ->
- translate:translate(Lang, "Delete message of the day").
-
-%-------------------------------------------------------------------------
-
-announce_all(From, To, Packet) ->
- Host = To#jid.lserver,
- Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
- case acl:match_rule(Host, Access, From) of
- deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
- ejabberd_router:route(To, From, Err);
- allow ->
- Local = jlib:make_jid("", To#jid.server, ""),
- lists:foreach(
- fun({User, Server}) ->
- Dest = jlib:make_jid(User, Server, ""),
- ejabberd_router:route(Local, Dest, Packet)
- end, ejabberd_auth:get_vh_registered_users(Host))
- end.
-
-announce_online(From, To, Packet) ->
- Host = To#jid.lserver,
- Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
- case acl:match_rule(Host, Access, From) of
- deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
- ejabberd_router:route(To, From, Err);
- allow ->
- announce_online1(ejabberd_sm:get_vh_session_list(Host),
- To#jid.server,
- Packet)
- end.
-
-announce_all_hosts_online(From, To, Packet) ->
- Access = gen_mod:get_module_opt(global, ?MODULE, access, none),
- case acl:match_rule(global, Access, From) of
- deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
- ejabberd_router:route(To, From, Err);
- allow ->
- announce_online1(ejabberd_sm:dirty_get_sessions_list(),
- To#jid.server,
- Packet)
- end.
-
-announce_online1(Sessions, Server, Packet) ->
- Local = jlib:make_jid("", Server, ""),
- lists:foreach(
- fun({U, S, R}) ->
- Dest = jlib:make_jid(U, S, R),
- ejabberd_router:route(Local, Dest, Packet)
- end, Sessions).
-
-announce_motd(From, To, Packet) ->
- Host = To#jid.lserver,
- Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
- case acl:match_rule(Host, Access, From) of
- deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
- ejabberd_router:route(To, From, Err);
- allow ->
- announce_motd_update(To#jid.lserver, Packet),
- Sessions = ejabberd_sm:get_vh_session_list(Host),
- announce_online1(Sessions, To#jid.server, Packet),
- F = fun() ->
- lists:foreach(
- fun({U, S, _R}) ->
- mnesia:write(#motd_users{us = {U, S}})
- end, Sessions)
- end,
- mnesia:transaction(F)
- end.
-
-announce_motd_update(From, To, Packet) ->
- Host = To#jid.lserver,
- Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
- case acl:match_rule(Host, Access, From) of
- deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
- ejabberd_router:route(To, From, Err);
- allow ->
- announce_motd_update(Host, Packet)
- end.
-
-announce_motd_update(LServer, Packet) ->
- announce_motd_delete(LServer),
- F = fun() ->
- mnesia:write(#motd{server = LServer, packet = Packet})
- end,
- mnesia:transaction(F).
-
-announce_motd_delete(From, To, Packet) ->
- Host = To#jid.lserver,
- Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
- case acl:match_rule(Host, Access, From) of
- deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
- ejabberd_router:route(To, From, Err);
- allow ->
- announce_motd_delete(Host)
- end.
-
-announce_motd_delete(LServer) ->
- F = fun() ->
- mnesia:delete({motd, LServer}),
- mnesia:write_lock_table(motd_users),
- Users = mnesia:select(
- motd_users,
- [{#motd_users{us = '$1', _ = '_'},
- [{'==', {element, 2, '$1'}, LServer}],
- ['$1']}]),
- lists:foreach(fun(US) ->
- mnesia:delete({motd_users, US})
- end, Users)
- end,
- mnesia:transaction(F).
-
-send_motd(#jid{luser = LUser, lserver = LServer} = JID) ->
- case catch mnesia:dirty_read({motd, LServer}) of
- [#motd{packet = Packet}] ->
- US = {LUser, LServer},
- case catch mnesia:dirty_read({motd_users, US}) of
- [#motd_users{}] ->
- ok;
- _ ->
- Local = jlib:make_jid("", LServer, ""),
- ejabberd_router:route(Local, JID, Packet),
- F = fun() ->
- mnesia:write(#motd_users{us = US})
- end,
- mnesia:transaction(F)
- end;
- _ ->
- ok
- end.
-
-%-------------------------------------------------------------------------
-
-update_tables() ->
- update_motd_table(),
- update_motd_users_table().
-
-update_motd_table() ->
- Fields = record_info(fields, motd),
- case mnesia:table_info(motd, attributes) of
- Fields ->
- ok;
- [id, packet] ->
- ?INFO_MSG("Converting motd table from "
- "{id, packet} format", []),
- Host = ?MYNAME,
- {atomic, ok} = mnesia:create_table(
- mod_announce_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, motd},
- {attributes, record_info(fields, motd)}]),
- mnesia:transform_table(motd, ignore, Fields),
- F1 = fun() ->
- mnesia:write_lock_table(mod_announce_tmp_table),
- mnesia:foldl(
- fun(#motd{server = _} = R, _) ->
- mnesia:dirty_write(
- mod_announce_tmp_table,
- R#motd{server = Host})
- end, ok, motd)
- end,
- mnesia:transaction(F1),
- mnesia:clear_table(motd),
- F2 = fun() ->
- mnesia:write_lock_table(motd),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_announce_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_announce_tmp_table);
- _ ->
- ?INFO_MSG("Recreating motd table", []),
- mnesia:transform_table(motd, ignore, Fields)
- end.
-
-
-update_motd_users_table() ->
- Fields = record_info(fields, motd_users),
- case mnesia:table_info(motd_users, attributes) of
- Fields ->
- ok;
- [luser, dummy] ->
- ?INFO_MSG("Converting motd_users table from "
- "{luser, dummy} format", []),
- Host = ?MYNAME,
- {atomic, ok} = mnesia:create_table(
- mod_announce_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, motd_users},
- {attributes, record_info(fields, motd_users)}]),
- mnesia:transform_table(motd_users, ignore, Fields),
- F1 = fun() ->
- mnesia:write_lock_table(mod_announce_tmp_table),
- mnesia:foldl(
- fun(#motd_users{us = U} = R, _) ->
- mnesia:dirty_write(
- mod_announce_tmp_table,
- R#motd_users{us = {U, Host}})
- end, ok, motd_users)
- end,
- mnesia:transaction(F1),
- mnesia:clear_table(motd_users),
- F2 = fun() ->
- mnesia:write_lock_table(motd_users),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_announce_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_announce_tmp_table);
- _ ->
- ?INFO_MSG("Recreating motd_users table", []),
- mnesia:transform_table(motd_users, ignore, Fields)
- end.
-
diff --git a/ejabberd-1.1.2/src/mod_configure.erl b/ejabberd-1.1.2/src/mod_configure.erl
deleted file mode 100644
index 541b50318..000000000
--- a/ejabberd-1.1.2/src/mod_configure.erl
+++ /dev/null
@@ -1,1417 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_configure.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Support for online configuration of ejabberd
-%%% Created : 19 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_configure).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_mod).
-
--export([start/2,
- stop/1,
- get_local_identity/5,
- get_local_features/5,
- get_local_items/5,
- adhoc_local_items/4,
- adhoc_local_commands/4,
- get_sm_identity/5,
- get_sm_features/5,
- get_sm_items/5,
- adhoc_sm_items/4,
- adhoc_sm_commands/4]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include("adhoc.hrl").
-
-
-start(Host, _Opts) ->
- ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_items, 50),
- ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 50),
- ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 50),
- ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_items, 50),
- ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
- ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 50),
- ejabberd_hooks:add(adhoc_local_items, Host, ?MODULE, adhoc_local_items, 50),
- ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, adhoc_local_commands, 50),
- ejabberd_hooks:add(adhoc_sm_items, Host, ?MODULE, adhoc_sm_items, 50),
- ejabberd_hooks:add(adhoc_sm_commands, Host, ?MODULE, adhoc_sm_commands, 50),
- ok.
-
-stop(Host) ->
- ejabberd_hooks:delete(adhoc_sm_commands, Host, ?MODULE, adhoc_sm_commands, 50),
- ejabberd_hooks:delete(adhoc_sm_items, Host, ?MODULE, adhoc_sm_items, 50),
- ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, adhoc_local_commands, 50),
- ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, adhoc_local_items, 50),
- ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, get_sm_identity, 50),
- ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
- ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_items, 50),
- ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 50),
- ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 50),
- ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_items, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_COMMANDS),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_COMMANDS).
-
-%%%-----------------------------------------------------------------------
-
--define(INFO_IDENTITY(Category, Type, Name, Lang),
- [{xmlelement, "identity",
- [{"category", Category},
- {"type", Type},
- {"name", translate:translate(Lang, Name)}], []}]).
-
--define(INFO_COMMAND(Name, Lang),
- ?INFO_IDENTITY("automation", "command-node", Name, Lang)).
-
-get_sm_identity(Acc, _From, _To, Node, Lang) ->
- case Node of
- "config" ->
- ?INFO_COMMAND("Configuration", Lang);
- _ ->
- Acc
- end.
-
-get_local_identity(Acc, _From, _To, Node, Lang) ->
- LNode = string:tokens(Node, "/"),
- case LNode of
- ["running nodes", ENode] ->
- ?INFO_IDENTITY("ejabberd", "node", ENode, Lang);
- ["running nodes", _ENode, "DB"] ->
- ?INFO_COMMAND("Database", Lang);
- ["running nodes", _ENode, "modules", "start"] ->
- ?INFO_COMMAND("Start Modules", Lang);
- ["running nodes", _ENode, "modules", "stop"] ->
- ?INFO_COMMAND("Stop Modules", Lang);
- ["running nodes", _ENode, "backup", "backup"] ->
- ?INFO_COMMAND("Backup", Lang);
- ["running nodes", _ENode, "backup", "restore"] ->
- ?INFO_COMMAND("Restore", Lang);
- ["running nodes", _ENode, "backup", "textfile"] ->
- ?INFO_COMMAND("Dump to Text File", Lang);
- ["running nodes", _ENode, "import", "file"] ->
- ?INFO_COMMAND("Import File", Lang);
- ["running nodes", _ENode, "import", "dir"] ->
- ?INFO_COMMAND("Import Directory", Lang);
- ["config", "hostname"] ->
- ?INFO_COMMAND("Host Name", Lang);
- ["config", "acls"] ->
- ?INFO_COMMAND("Access Control Lists", Lang);
- ["config", "access"] ->
- ?INFO_COMMAND("Access Rules", Lang);
- _ ->
- Acc
- end.
-
-%%%-----------------------------------------------------------------------
-
--define(INFO_RESULT(Allow, Feats),
- case Allow of
- deny ->
- {error, ?ERR_FORBIDDEN};
- allow ->
- {result, Feats}
- end).
-
-get_sm_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
- case gen_mod:is_loaded(LServer, mod_adhoc) of
- false ->
- Acc;
- _ ->
- Allow = acl:match_rule(LServer, configure, From),
- case Node of
- "config" ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- _ ->
- Acc
- end
- end.
-
-get_local_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
- case gen_mod:is_loaded(LServer, mod_adhoc) of
- false ->
- Acc;
- _ ->
- LNode = string:tokens(Node, "/"),
- Allow = acl:match_rule(LServer, configure, From),
- case LNode of
- ["config"] ->
- ?INFO_RESULT(Allow, []);
- ["online users"] ->
- ?INFO_RESULT(Allow, []);
- ["all users"] ->
- ?INFO_RESULT(Allow, []);
- ["all users", [$@ | _]] ->
- ?INFO_RESULT(Allow, []);
- ["outgoing s2s" | _] ->
- ?INFO_RESULT(Allow, []);
- ["running nodes"] ->
- ?INFO_RESULT(Allow, []);
- ["stopped nodes"] ->
- ?INFO_RESULT(Allow, []);
- ["running nodes", _ENode] ->
- ?INFO_RESULT(Allow, [?NS_STATS]);
- ["running nodes", _ENode, "DB"] ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- ["running nodes", _ENode, "modules"] ->
- ?INFO_RESULT(Allow, []);
- ["running nodes", _ENode, "modules", _] ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- ["running nodes", _ENode, "backup"] ->
- ?INFO_RESULT(Allow, []);
- ["running nodes", _ENode, "backup", _] ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- ["running nodes", _ENode, "import"] ->
- ?INFO_RESULT(Allow, []);
- ["running nodes", _ENode, "import", _] ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- ["config", _] ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- _ ->
- Acc
- end
- end.
-
-%%%-----------------------------------------------------------------------
-
-adhoc_sm_items(Acc, From, #jid{lserver = LServer} = To, Lang) ->
- case acl:match_rule(LServer, configure, From) of
- allow ->
- Items = case Acc of
- {result, Its} -> Its;
- empty -> []
- end,
- Nodes = [{xmlelement, "item",
- [{"jid", jlib:jid_to_string(To)},
- {"name", translate:translate(Lang, "Configuration")},
- {"node", "config"}], []}],
- {result, Items ++ Nodes};
- _ ->
- Acc
- end.
-
-%%%-----------------------------------------------------------------------
-
-get_sm_items(Acc, From,
- #jid{user = User, server = Server, lserver = LServer} = To,
- Node, Lang) ->
- case gen_mod:is_loaded(LServer, mod_adhoc) of
- false ->
- Acc;
- _ ->
- Items = case Acc of
- {result, Its} -> Its;
- empty -> []
- end,
- case {acl:match_rule(LServer, configure, From), Node} of
- {allow, ""} ->
- Nodes = [{xmlelement, "item",
- [{"jid", jlib:jid_to_string(To)},
- {"name", translate:translate(Lang, "Configuration")},
- {"node", "config"}], []}],
- {result, Items ++ Nodes ++ get_user_resources(User, Server)};
- {allow, "config"} ->
- {result, []};
- {_, "config"} ->
- {error, ?ERR_FORBIDDEN};
- _ ->
- Acc
- end
- end.
-
-get_user_resources(User, Server) ->
- Rs = ejabberd_sm:get_user_resources(User, Server),
- lists:map(fun(R) ->
- {xmlelement, "item",
- [{"jid", User ++ "@" ++ Server ++ "/" ++ R},
- {"name", User}], []}
- end, lists:sort(Rs)).
-
-%%%-----------------------------------------------------------------------
-
-adhoc_local_items(Acc, From, #jid{lserver = LServer, server = Server} = To,
- Lang) ->
- case acl:match_rule(LServer, configure, From) of
- allow ->
- Items = case Acc of
- {result, Its} -> Its;
- empty -> []
- end,
- %% Recursively get all configure commands
- Nodes = recursively_get_local_items(LServer, "", Server, Lang),
- Nodes1 = lists:filter(
- fun(N) ->
- Nd = xml:get_tag_attr_s("node", N),
- F = get_local_features([], From, To, Nd, Lang),
- case F of
- {result, [?NS_COMMANDS]} ->
- true;
- _ ->
- false
- end
- end, Nodes),
- {result, Items ++ Nodes1};
- _ ->
- Acc
- end.
-
-recursively_get_local_items(_LServer, "online users", _Server, _Lang) ->
- [];
-
-recursively_get_local_items(_LServer, "all users", _Server, _Lang) ->
- [];
-
-recursively_get_local_items(LServer, Node, Server, Lang) ->
- LNode = string:tokens(Node, "/"),
- Items = case get_local_items(LServer, LNode, Server, Lang) of
- {result, Res} ->
- Res;
- {error, _Error} ->
- []
- end,
- Nodes = lists:flatten(
- lists:map(
- fun(N) ->
- S = xml:get_tag_attr_s("jid", N),
- Nd = xml:get_tag_attr_s("node", N),
- if (S /= Server) or (Nd == "") ->
- [];
- true ->
- [N, recursively_get_local_items(
- LServer, Nd, Server, Lang)]
- end
- end, Items)),
- Nodes.
-
-%%%-----------------------------------------------------------------------
-
--define(ITEMS_RESULT(Allow, LNode, Fallback),
- case Allow of
- deny ->
- Fallback;
- allow ->
- case get_local_items(LServer, LNode,
- jlib:jid_to_string(To), Lang) of
- {result, Res} ->
- {result, Res};
- {error, Error} ->
- {error, Error}
- end
- end).
-
-get_local_items(Acc, From, #jid{lserver = LServer} = To, "", Lang) ->
- case gen_mod:is_loaded(LServer, mod_adhoc) of
- false ->
- Acc;
- _ ->
- Items = case Acc of
- {result, Its} -> Its;
- empty -> []
- end,
- Allow = acl:match_rule(LServer, configure, From),
- case Allow of
- deny ->
- {result, Items};
- allow ->
- case get_local_items(LServer, [],
- jlib:jid_to_string(To), Lang) of
- {result, Res} ->
- {result, Items ++ Res};
- {error, _Error} ->
- {result, Items}
- end
- end
- end;
-
-get_local_items(Acc, From, #jid{lserver = LServer} = To, Node, Lang) ->
- case gen_mod:is_loaded(LServer, mod_adhoc) of
- false ->
- Acc;
- _ ->
- LNode = string:tokens(Node, "/"),
- Allow = acl:match_rule(LServer, configure, From),
- case LNode of
- ["config"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["online users"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["all users"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["all users", [$@ | _]] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["outgoing s2s" | _] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["running nodes"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["stopped nodes"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["running nodes", _ENode] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["running nodes", _ENode, "DB"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["running nodes", _ENode, "modules"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["running nodes", _ENode, "modules", _] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["running nodes", _ENode, "backup"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["running nodes", _ENode, "backup", _] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["running nodes", _ENode, "import"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["running nodes", _ENode, "import", _] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- ["config", _] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
- _ ->
- Acc
- end
- end.
-
-%%%-----------------------------------------------------------------------
-
--define(NODE(Name, Node),
- {xmlelement, "item",
- [{"jid", Server},
- {"name", translate:translate(Lang, Name)},
- {"node", Node}], []}).
-
-get_local_items(_Host, [], Server, Lang) ->
- {result,
- [?NODE("Configuration", "config"),
- ?NODE("Online Users", "online users"),
- ?NODE("All Users", "all users"),
- ?NODE("Outgoing s2s Connections", "outgoing s2s"),
- ?NODE("Running Nodes", "running nodes"),
- ?NODE("Stopped Nodes", "stopped nodes")
- ]};
-
-get_local_items(_Host, ["config"], Server, Lang) ->
- {result,
- [?NODE("Host Name", "config/hostname"),
- ?NODE("Access Control Lists", "config/acls"),
- ?NODE("Access Rules", "config/access")
- % Too expensive on big hosts
- %?NODE("Remove Users", "config/remusers")
- ]};
-
-get_local_items(_Host, ["config", _], _Server, _Lang) ->
- {result, []};
-
-get_local_items(Host, ["online users"], _Server, _Lang) ->
- {result, get_online_vh_users(Host)};
-
-get_local_items(Host, ["all users"], _Server, _Lang) ->
- {result, get_all_vh_users(Host)};
-
-get_local_items(_Host, ["all users", [$@ | Diap]], _Server, _Lang) ->
- case catch ejabberd_auth:dirty_get_registered_users() of
- {'EXIT', _Reason} ->
- ?ERR_INTERNAL_SERVER_ERROR;
- Users ->
- SUsers = lists:sort([{S, U} || {U, S} <- Users]),
- case catch begin
- {ok, [S1, S2]} = regexp:split(Diap, "-"),
- N1 = list_to_integer(S1),
- N2 = list_to_integer(S2),
- Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
- lists:map(fun({S, U}) ->
- {xmlelement, "item",
- [{"jid", U ++ "@" ++ S},
- {"name", U ++ "@" ++ S}], []}
- end, Sub)
- end of
- {'EXIT', _Reason} ->
- ?ERR_NOT_ACCEPTABLE;
- Res ->
- {result, Res}
- end
- end;
-
-get_local_items(Host, ["outgoing s2s"], _Server, Lang) ->
- {result, get_outgoing_s2s(Host, Lang)};
-
-get_local_items(Host, ["outgoing s2s", To], _Server, Lang) ->
- {result, get_outgoing_s2s(Host, Lang, To)};
-
-get_local_items(_Host, ["running nodes"], _Server, Lang) ->
- {result, get_running_nodes(Lang)};
-
-get_local_items(_Host, ["stopped nodes"], _Server, Lang) ->
- {result, get_stopped_nodes(Lang)};
-
-get_local_items(_Host, ["running nodes", ENode], Server, Lang) ->
- {result,
- [?NODE("Database", "running nodes/" ++ ENode ++ "/DB"),
- ?NODE("Modules", "running nodes/" ++ ENode ++ "/modules"),
- ?NODE("Backup Management", "running nodes/" ++ ENode ++ "/backup"),
- ?NODE("Import Users From jabberd 1.4 Spool Files",
- "running nodes/" ++ ENode ++ "/import")
- ]};
-
-get_local_items(_Host, ["running nodes", _ENode, "DB"], _Server, _Lang) ->
- {result, []};
-
-get_local_items(_Host, ["running nodes", ENode, "modules"], Server, Lang) ->
- {result,
- [?NODE("Start Modules", "running nodes/" ++ ENode ++ "/modules/start"),
- ?NODE("Stop Modules", "running nodes/" ++ ENode ++ "/modules/stop")
- ]};
-
-get_local_items(_Host, ["running nodes", _ENode, "modules", _], _Server, _Lang) ->
- {result, []};
-
-get_local_items(_Host, ["running nodes", ENode, "backup"], Server, Lang) ->
- {result,
- [?NODE("Backup", "running nodes/" ++ ENode ++ "/backup/backup"),
- ?NODE("Restore", "running nodes/" ++ ENode ++ "/backup/restore"),
- ?NODE("Dump to Text File",
- "running nodes/" ++ ENode ++ "/backup/textfile")
- ]};
-
-get_local_items(_Host, ["running nodes", _ENode, "backup", _], _Server, _Lang) ->
- {result, []};
-
-get_local_items(_Host, ["running nodes", ENode, "import"], Server, Lang) ->
- {result,
- [?NODE("Import File", "running nodes/" ++ ENode ++ "/import/file"),
- ?NODE("Import Directory", "running nodes/" ++ ENode ++ "/import/dir")
- ]};
-
-get_local_items(_Host, ["running nodes", _ENode, "import", _], _Server, _Lang) ->
- {result, []};
-
-get_local_items(_Host, _, _Server, _Lang) ->
- {error, ?ERR_ITEM_NOT_FOUND}.
-
-
-get_online_vh_users(Host) ->
- case catch ejabberd_sm:get_vh_session_list(Host) of
- {'EXIT', _Reason} ->
- [];
- USRs ->
- SURs = lists:sort([{S, U, R} || {U, S, R} <- USRs]),
- lists:map(fun({S, U, R}) ->
- {xmlelement, "item",
- [{"jid", U ++ "@" ++ S ++ "/" ++ R},
- {"name", U ++ "@" ++ S}], []}
- end, SURs)
- end.
-
-get_all_vh_users(Host) ->
- case catch ejabberd_auth:get_vh_registered_users(Host) of
- {'EXIT', _Reason} ->
- [];
- Users ->
- SUsers = lists:sort([{S, U} || {U, S} <- Users]),
- case length(SUsers) of
- N when N =< 100 ->
- lists:map(fun({S, U}) ->
- {xmlelement, "item",
- [{"jid", U ++ "@" ++ S},
- {"name", U ++ "@" ++ S}], []}
- end, SUsers);
- N ->
- NParts = trunc(math:sqrt(N * 0.618)) + 1,
- M = trunc(N / NParts) + 1,
- lists:map(fun(K) ->
- L = K + M - 1,
- Node =
- "@" ++ integer_to_list(K) ++
- "-" ++ integer_to_list(L),
- {FS, FU} = lists:nth(K, SUsers),
- {LS, LU} =
- if L < N -> lists:nth(L, SUsers);
- true -> lists:last(SUsers)
- end,
- Name =
- FU ++ "@" ++ FS ++
- " -- " ++
- LU ++ "@" ++ LS,
- {xmlelement, "item",
- [{"jid", Host},
- {"node", "all users/" ++ Node},
- {"name", Name}], []}
- end, lists:seq(1, N, M))
- end
- end.
-
-get_outgoing_s2s(Host, Lang) ->
- case catch ejabberd_s2s:dirty_get_connections() of
- {'EXIT', _Reason} ->
- [];
- Connections ->
- DotHost = "." ++ Host,
- TConns = [TH || {FH, TH} <- Connections,
- Host == FH orelse lists:suffix(DotHost, FH)],
- lists:map(
- fun(T) ->
- {xmlelement, "item",
- [{"jid", Host},
- {"node", "outgoing s2s/" ++ T},
- {"name",
- lists:flatten(
- io_lib:format(
- translate:translate(Lang, "To ~s"), [T]))}],
- []}
- end, lists:usort(TConns))
- end.
-
-get_outgoing_s2s(Host, Lang, To) ->
- case catch ejabberd_s2s:dirty_get_connections() of
- {'EXIT', _Reason} ->
- [];
- Connections ->
- lists:map(
- fun({F, _T}) ->
- {xmlelement, "item",
- [{"jid", Host},
- {"node", "outgoing s2s/" ++ To ++ "/" ++ F},
- {"name",
- lists:flatten(
- io_lib:format(
- translate:translate(Lang, "From ~s"), [F]))}],
- []}
- end, lists:keysort(1, lists:filter(fun(E) ->
- element(2, E) == To
- end, Connections)))
- end.
-
-
-get_running_nodes(_Lang) ->
- case catch mnesia:system_info(running_db_nodes) of
- {'EXIT', _Reason} ->
- [];
- DBNodes ->
- lists:map(
- fun(N) ->
- S = atom_to_list(N),
- {xmlelement, "item",
- [{"jid", ?MYNAME},
- {"node", "running nodes/" ++ S},
- {"name", S}],
- []}
- end, lists:sort(DBNodes))
- end.
-
-get_stopped_nodes(_Lang) ->
- case catch (lists:usort(mnesia:system_info(db_nodes) ++
- mnesia:system_info(extra_db_nodes)) --
- mnesia:system_info(running_db_nodes)) of
- {'EXIT', _Reason} ->
- [];
- DBNodes ->
- lists:map(
- fun(N) ->
- S = atom_to_list(N),
- {xmlelement, "item",
- [{"jid", ?MYNAME},
- {"node", "stopped nodes/" ++ S},
- {"name", S}],
- []}
- end, lists:sort(DBNodes))
- end.
-
-%-------------------------------------------------------------------------
-
--define(COMMANDS_RESULT(Allow, From, To, Request),
- case Allow of
- deny ->
- {error, ?ERR_FORBIDDEN};
- allow ->
- adhoc_local_commands(From, To, Request)
- end).
-
-adhoc_local_commands(Acc, From, #jid{lserver = LServer} = To,
- #adhoc_request{node = Node} = Request) ->
- LNode = string:tokens(Node, "/"),
- Allow = acl:match_rule(LServer, configure, From),
- case LNode of
- ["running nodes", _ENode, "DB"] ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- ["running nodes", _ENode, "modules", _] ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- ["running nodes", _ENode, "backup", _] ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- ["running nodes", _ENode, "import", _] ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- ["config", _] ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- _ ->
- Acc
- end.
-
-adhoc_local_commands(_From, #jid{lserver = LServer} = _To,
- #adhoc_request{lang = Lang,
- node = Node,
- sessionid = SessionID,
- action = Action,
- xdata = XData} = Request) ->
- LNode = string:tokens(Node, "/"),
- %% If the "action" attribute is not present, it is
- %% understood as "execute". If there was no <actions/>
- %% element in the first response (which there isn't in our
- %% case), "execute" and "complete" are equivalent.
- ActionIsExecute = lists:member(Action,
- ["", "execute", "complete"]),
- if Action == "cancel" ->
- %% User cancels request
- adhoc:produce_response(
- Request,
- #adhoc_response{status = canceled});
- XData == false, ActionIsExecute ->
- %% User requests form
- case get_form(LServer, LNode, Lang) of
- {result, Form} ->
- adhoc:produce_response(
- Request,
- #adhoc_response{status = executing,
- elements = Form});
- {error, Error} ->
- {error, Error}
- end;
- XData /= false, ActionIsExecute ->
- %% User returns form.
- case jlib:parse_xdata_submit(XData) of
- invalid ->
- {error, ?ERR_BAD_REQUEST};
- Fields ->
- case set_form(LServer, LNode, Lang, Fields) of
- {result, _Res} ->
- adhoc:produce_response(
- #adhoc_response{lang = Lang,
- node = Node,
- sessionid = SessionID,
- status = completed});
- {error, Error} ->
- {error, Error}
- end
- end;
- true ->
- {error, ?ERR_BAD_REQUEST}
- end.
-
-
--define(TLFIELD(Type, Label, Var),
- {xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
- {"var", Var}], []}).
-
--define(XFIELD(Type, Label, Var, Val),
- {xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
- {"var", Var}],
- [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
-
--define(TABLEFIELD(Table, Val),
- {xmlelement, "field", [{"type", "list-single"},
- {"label", atom_to_list(Table)},
- {"var", atom_to_list(Table)}],
- [{xmlelement, "value", [], [{xmlcdata, atom_to_list(Val)}]},
- {xmlelement, "option", [{"label",
- translate:translate(Lang, "RAM copy")}],
- [{xmlelement, "value", [], [{xmlcdata, "ram_copies"}]}]},
- {xmlelement, "option", [{"label",
- translate:translate(Lang,
- "RAM and disc copy")}],
- [{xmlelement, "value", [], [{xmlcdata, "disc_copies"}]}]},
- {xmlelement, "option", [{"label",
- translate:translate(Lang,
- "Disc only copy")}],
- [{xmlelement, "value", [], [{xmlcdata, "disc_only_copies"}]}]},
- {xmlelement, "option", [{"label",
- translate:translate(Lang, "Remote copy")}],
- [{xmlelement, "value", [], [{xmlcdata, "unknown"}]}]}
- ]}).
-
-
-
-get_form(_Host, ["running nodes", ENode, "DB"], Lang) ->
- case search_running_node(ENode) of
- false ->
- {error, ?ERR_ITEM_NOT_FOUND};
- Node ->
- case rpc:call(Node, mnesia, system_info, [tables]) of
- {badrpc, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- Tables ->
- STables = lists:sort(Tables),
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Database Tables Configuration at ") ++
- ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Choose storage type of tables")}]} |
- lists:map(
- fun(Table) ->
- case rpc:call(Node,
- mnesia,
- table_info,
- [Table, storage_type]) of
- {badrpc, _} ->
- ?TABLEFIELD(Table, unknown);
- Type ->
- ?TABLEFIELD(Table, Type)
- end
- end, STables)
- ]}]}
- end
- end;
-
-get_form(Host, ["running nodes", ENode, "modules", "stop"], Lang) ->
- case search_running_node(ENode) of
- false ->
- {error, ?ERR_ITEM_NOT_FOUND};
- Node ->
- case rpc:call(Node, gen_mod, loaded_modules, [Host]) of
- {badrpc, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- Modules ->
- SModules = lists:sort(Modules),
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Stop Modules at ") ++ ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Choose modules to stop")}]} |
- lists:map(fun(M) ->
- S = atom_to_list(M),
- ?XFIELD("boolean", S, S, "0")
- end, SModules)
- ]}]}
- end
- end;
-
-get_form(_Host, ["running nodes", ENode, "modules", "start"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Start Modules at ") ++ ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Enter list of {Module, [Options]}")}]},
- {xmlelement, "field", [{"type", "text-multi"},
- {"label",
- translate:translate(
- Lang, "List of modules to start")},
- {"var", "modules"}],
- [{xmlelement, "value", [], [{xmlcdata, "[]."}]}]
- }
- ]}]};
-
-get_form(_Host, ["running nodes", ENode, "backup", "backup"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Backup to File at ") ++ ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Enter path to backup file")}]},
- {xmlelement, "field", [{"type", "text-single"},
- {"label",
- translate:translate(
- Lang, "Path to File")},
- {"var", "path"}],
- [{xmlelement, "value", [], [{xmlcdata, ""}]}]
- }
- ]}]};
-
-get_form(_Host, ["running nodes", ENode, "backup", "restore"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Restore Backup from File at ") ++ ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Enter path to backup file")}]},
- {xmlelement, "field", [{"type", "text-single"},
- {"label",
- translate:translate(
- Lang, "Path to File")},
- {"var", "path"}],
- [{xmlelement, "value", [], [{xmlcdata, ""}]}]
- }
- ]}]};
-
-get_form(_Host, ["running nodes", ENode, "backup", "textfile"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Dump Backup to Text File at ") ++ ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Enter path to text file")}]},
- {xmlelement, "field", [{"type", "text-single"},
- {"label",
- translate:translate(
- Lang, "Path to File")},
- {"var", "path"}],
- [{xmlelement, "value", [], [{xmlcdata, ""}]}]
- }
- ]}]};
-
-get_form(_Host, ["running nodes", ENode, "import", "file"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Import User from File at ") ++ ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Enter path to jabberd1.4 spool file")}]},
- {xmlelement, "field", [{"type", "text-single"},
- {"label",
- translate:translate(
- Lang, "Path to File")},
- {"var", "path"}],
- [{xmlelement, "value", [], [{xmlcdata, ""}]}]
- }
- ]}]};
-
-get_form(_Host, ["running nodes", ENode, "import", "dir"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Import Users from Dir at ") ++ ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Enter path to jabberd1.4 spool dir")}]},
- {xmlelement, "field", [{"type", "text-single"},
- {"label",
- translate:translate(
- Lang, "Path to Dir")},
- {"var", "path"}],
- [{xmlelement, "value", [], [{xmlcdata, ""}]}]
- }
- ]}]};
-
-get_form(_Host, ["config", "hostname"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Hostname Configuration")}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Choose host name")}]},
- {xmlelement, "field", [{"type", "text-single"},
- {"label",
- translate:translate(Lang,
- "Host name")},
- {"var", "hostname"}],
- [{xmlelement, "value", [], [{xmlcdata, ?MYNAME}]}]}
- ]}]};
-
-get_form(_Host, ["config", "acls"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Access Control List Configuration")}]},
- %{xmlelement, "instructions", [],
- % [{xmlcdata,
- % translate:translate(
- % Lang, "")}]},
- {xmlelement, "field", [{"type", "text-multi"},
- {"label",
- translate:translate(
- Lang, "Access control lists")},
- {"var", "acls"}],
- lists:map(fun(S) ->
- {xmlelement, "value", [], [{xmlcdata, S}]}
- end,
- string:tokens(
- lists:flatten(io_lib:format("~p.",
- [ets:tab2list(acl)])),
- "\n"))
- }
- ]}]};
-
-get_form(_Host, ["config", "access"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Access Configuration")}]},
- %{xmlelement, "instructions", [],
- % [{xmlcdata,
- % translate:translate(
- % Lang, "")}]},
- {xmlelement, "field", [{"type", "text-multi"},
- {"label",
- translate:translate(
- Lang, "Access rules")},
- {"var", "access"}],
- lists:map(fun(S) ->
- {xmlelement, "value", [], [{xmlcdata, S}]}
- end,
- string:tokens(
- lists:flatten(
- io_lib:format(
- "~p.",
- [ets:select(config,
- [{{config, {access, '$1'}, '$2'},
- [],
- [{{access, '$1', '$2'}}]}])
- ])),
- "\n"))
- }
- ]}]};
-
-get_form(Host, ["config", "remusers"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Remove Users")}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Choose users to remove")}]}] ++
- case catch ejabberd_auth:get_vh_registered_users(Host) of
- {'EXIT', _Reason} ->
- [];
- Users ->
- lists:map(fun(U) ->
- ?XFIELD("boolean", U, U, "0")
- end, lists:sort(Users))
- end
- }]};
-
-get_form(_Host, _, _Lang) ->
- {error, ?ERR_SERVICE_UNAVAILABLE}.
-
-
-
-set_form(_Host, ["running nodes", ENode, "DB"], _Lang, XData) ->
- case search_running_node(ENode) of
- false ->
- {error, ?ERR_ITEM_NOT_FOUND};
- Node ->
- lists:foreach(
- fun({SVar, SVals}) ->
- % We believe that this is allowed only for good people
- Table = list_to_atom(SVar),
- Type = case SVals of
- ["unknown"] -> unknown;
- ["ram_copies"] -> ram_copies;
- ["disc_copies"] -> disc_copies;
- ["disc_only_copies"] -> disc_only_copies;
- _ -> false
- end,
- if
- Type == false ->
- ok;
- Type == unknown ->
- mnesia:del_table_copy(Table, Node);
- true ->
- case mnesia:add_table_copy(Table, Node, Type) of
- {aborted, _} ->
- mnesia:change_table_copy_type(
- Table, Node, Type);
- _ ->
- ok
- end
- end
- end, XData),
- {result, []}
- end;
-
-set_form(Host, ["running nodes", ENode, "modules", "stop"], _Lang, XData) ->
- case search_running_node(ENode) of
- false ->
- {error, ?ERR_ITEM_NOT_FOUND};
- Node ->
- lists:foreach(
- fun({Var, Vals}) ->
- case Vals of
- ["1"] ->
- Module = list_to_atom(Var),
- rpc:call(Node, gen_mod, stop_module, [Host, Module]);
- _ ->
- ok
- end
- end, XData),
- {result, []}
- end;
-
-set_form(Host, ["running nodes", ENode, "modules", "start"], _Lang, XData) ->
- case search_running_node(ENode) of
- false ->
- {error, ?ERR_ITEM_NOT_FOUND};
- Node ->
- case lists:keysearch("modules", 1, XData) of
- false ->
- {error, ?ERR_BAD_REQUEST};
- {value, {_, Strings}} ->
- String = lists:foldl(fun(S, Res) ->
- Res ++ S ++ "\n"
- end, "", Strings),
- case erl_scan:string(String) of
- {ok, Tokens, _} ->
- case erl_parse:parse_term(Tokens) of
- {ok, Modules} ->
- lists:foreach(
- fun({Module, Args}) ->
- rpc:call(Node,
- gen_mod,
- start_module,
- [Host, Module, Args])
- end, Modules),
- {result, []};
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end
- end;
-
-
-set_form(_Host, ["running nodes", ENode, "backup", "backup"], _Lang, XData) ->
- case search_running_node(ENode) of
- false ->
- {error, ?ERR_ITEM_NOT_FOUND};
- Node ->
- case lists:keysearch("path", 1, XData) of
- false ->
- {error, ?ERR_BAD_REQUEST};
- {value, {_, [String]}} ->
- case rpc:call(Node, mnesia, backup, [String]) of
- {badrpc, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- {error, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- _ ->
- {result, []}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end
- end;
-
-
-set_form(_Host, ["running nodes", ENode, "backup", "restore"], _Lang, XData) ->
- case search_running_node(ENode) of
- false ->
- {error, ?ERR_ITEM_NOT_FOUND};
- Node ->
- case lists:keysearch("path", 1, XData) of
- false ->
- {error, ?ERR_BAD_REQUEST};
- {value, {_, [String]}} ->
- case rpc:call(Node, ejabberd_admin, restore, [String]) of
- {badrpc, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- {error, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- _ ->
- {result, []}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end
- end;
-
-
-set_form(_Host, ["running nodes", ENode, "backup", "textfile"], _Lang, XData) ->
- case search_running_node(ENode) of
- false ->
- {error, ?ERR_ITEM_NOT_FOUND};
- Node ->
- case lists:keysearch("path", 1, XData) of
- false ->
- {error, ?ERR_BAD_REQUEST};
- {value, {_, [String]}} ->
- case rpc:call(Node, mnesia, dump_to_textfile, [String]) of
- {badrpc, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- {error, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- _ ->
- {result, []}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end
- end;
-
-
-set_form(_Host, ["running nodes", ENode, "import", "file"], _Lang, XData) ->
- case search_running_node(ENode) of
- false ->
- {error, ?ERR_ITEM_NOT_FOUND};
- Node ->
- case lists:keysearch("path", 1, XData) of
- false ->
- {error, ?ERR_BAD_REQUEST};
- {value, {_, [String]}} ->
- rpc:call(Node, jd2ejd, import_file, [String]),
- {result, []};
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end
- end;
-
-
-set_form(_Host, ["running nodes", ENode, "import", "dir"], _Lang, XData) ->
- case search_running_node(ENode) of
- false ->
- {error, ?ERR_ITEM_NOT_FOUND};
- Node ->
- case lists:keysearch("path", 1, XData) of
- false ->
- {error, ?ERR_BAD_REQUEST};
- {value, {_, [String]}} ->
- rpc:call(Node, jd2ejd, import_dir, [String]),
- {result, []};
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end
- end;
-
-
-set_form(_Host, ["config", "hostname"], _Lang, XData) ->
- case lists:keysearch("hostname", 1, XData) of
- false ->
- {error, ?ERR_BAD_REQUEST};
- {value, {_, [""]}} ->
- {error, ?ERR_BAD_REQUEST};
- {value, {_, [NewName]}} ->
- ejabberd_config:add_global_option(hostname, NewName),
- {result, []};
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
-
-set_form(_Host, ["config", "acls"], _Lang, XData) ->
- case lists:keysearch("acls", 1, XData) of
- {value, {_, Strings}} ->
- String = lists:foldl(fun(S, Res) ->
- Res ++ S ++ "\n"
- end, "", Strings),
- case erl_scan:string(String) of
- {ok, Tokens, _} ->
- case erl_parse:parse_term(Tokens) of
- {ok, ACLs} ->
- case acl:add_list(ACLs, true) of
- ok ->
- {result, []};
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
-
-set_form(_Host, ["config", "access"], _Lang, XData) ->
- SetAccess =
- fun(Rs) ->
- mnesia:transaction(
- fun() ->
- Os = mnesia:select(config,
- [{{config, {access, '$1'}, '$2'},
- [],
- ['$_']}]),
- lists:foreach(fun(O) ->
- mnesia:delete_object(O)
- end, Os),
- lists:foreach(
- fun({access, Name, Rules}) ->
- mnesia:write({config,
- {access, Name},
- Rules})
- end, Rs)
- end)
- end,
- case lists:keysearch("access", 1, XData) of
- {value, {_, Strings}} ->
- String = lists:foldl(fun(S, Res) ->
- Res ++ S ++ "\n"
- end, "", Strings),
- case erl_scan:string(String) of
- {ok, Tokens, _} ->
- case erl_parse:parse_term(Tokens) of
- {ok, Rs} ->
- case SetAccess(Rs) of
- {atomic, _} ->
- {result, []};
- E ->
- io:format("A: ~p~n", [E]),
- {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
-
-set_form(Host, ["config", "remusers"], _Lang, XData) ->
- lists:foreach(
- fun({Var, Vals}) ->
- case Vals of
- ["1"] ->
- catch ejabberd_auth:remove_user(Var, Host);
- _ ->
- ok
- end
- end, XData),
- {result, []};
-
-set_form(_Host, _, _Lang, _XData) ->
- {error, ?ERR_SERVICE_UNAVAILABLE}.
-
-
-
-search_running_node(SNode) ->
- search_running_node(SNode, mnesia:system_info(running_db_nodes)).
-
-search_running_node(_, []) ->
- false;
-search_running_node(SNode, [Node | Nodes]) ->
- case atom_to_list(Node) of
- SNode ->
- Node;
- _ ->
- search_running_node(SNode, Nodes)
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-adhoc_sm_commands(_Acc, From,
- #jid{user = User, server = Server, lserver = LServer} = _To,
- #adhoc_request{lang = Lang,
- node = "config",
- action = Action,
- xdata = XData} = Request) ->
- case acl:match_rule(LServer, configure, From) of
- deny ->
- {error, ?ERR_FORBIDDEN};
- allow ->
- %% If the "action" attribute is not present, it is
- %% understood as "execute". If there was no <actions/>
- %% element in the first response (which there isn't in our
- %% case), "execute" and "complete" are equivalent.
- ActionIsExecute = lists:member(Action,
- ["", "execute", "complete"]),
- if Action == "cancel" ->
- %% User cancels request
- adhoc:produce_response(
- Request,
- #adhoc_response{status = canceled});
- XData == false, ActionIsExecute ->
- %% User requests form
- case get_sm_form(User, Server, "config", Lang) of
- {result, Form} ->
- adhoc:produce_response(
- Request,
- #adhoc_response{status = executing,
- elements = Form});
- {error, Error} ->
- {error, Error}
- end;
- XData /= false, ActionIsExecute ->
- %% User returns form.
- case jlib:parse_xdata_submit(XData) of
- invalid ->
- {error, ?ERR_BAD_REQUEST};
- Fields ->
- set_sm_form(User, Server, "config", Request, Fields)
- end;
- true ->
- {error, ?ERR_BAD_REQUEST}
- end
- end;
-
-adhoc_sm_commands(Acc, _From, _To, _Request) ->
- Acc.
-
-get_sm_form(User, Server, "config", Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Administration of ") ++ User}]},
- {xmlelement, "field",
- [{"type", "list-single"},
- {"label", translate:translate(Lang, "Action on user")},
- {"var", "action"}],
- [{xmlelement, "value", [], [{xmlcdata, "edit"}]},
- {xmlelement, "option",
- [{"label", translate:translate(Lang, "Edit Properties")}],
- [{xmlelement, "value", [], [{xmlcdata, "edit"}]}]},
- {xmlelement, "option",
- [{"label", translate:translate(Lang, "Remove User")}],
- [{xmlelement, "value", [], [{xmlcdata, "remove"}]}]}
- ]},
- ?XFIELD("text-private", "Password", "password",
- ejabberd_auth:get_password_s(User, Server))
- ]}]};
-
-get_sm_form(_User, _Server, _Node, _Lang) ->
- {error, ?ERR_SERVICE_UNAVAILABLE}.
-
-
-set_sm_form(User, Server, "config",
- #adhoc_request{lang = Lang,
- node = Node,
- sessionid = SessionID}, XData) ->
- Response = #adhoc_response{lang = Lang,
- node = Node,
- sessionid = SessionID,
- status = completed},
- case lists:keysearch("action", 1, XData) of
- {value, {_, ["edit"]}} ->
- case lists:keysearch("password", 1, XData) of
- {value, {_, [Password]}} ->
- ejabberd_auth:set_password(User, Server, Password),
- adhoc:produce_response(Response);
- _ ->
- {error, ?ERR_NOT_ACCEPTABLE}
- end;
- {value, {_, ["remove"]}} ->
- catch ejabberd_auth:remove_user(User, Server),
- adhoc:produce_response(Response);
- _ ->
- {error, ?ERR_NOT_ACCEPTABLE}
- end;
-
-set_sm_form(_User, _Server, _Node, _Request, _Fields) ->
- {error, ?ERR_SERVICE_UNAVAILABLE}.
-
diff --git a/ejabberd-1.1.2/src/mod_configure2.erl b/ejabberd-1.1.2/src/mod_configure2.erl
deleted file mode 100644
index 0852546d4..000000000
--- a/ejabberd-1.1.2/src/mod_configure2.erl
+++ /dev/null
@@ -1,153 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_configure2.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Support for online configuration of ejabberd
-%%% Created : 26 Oct 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_configure2).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_mod).
-
--export([start/2,
- stop/1,
- process_local_iq/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--define(NS_ECONFIGURE, "http://ejabberd.jabberstudio.org/protocol/configure").
-
-start(Host, Opts) ->
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_ECONFIGURE,
- ?MODULE, process_local_iq, IQDisc),
- ok.
-
-stop(Host) ->
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ECONFIGURE).
-
-
-process_local_iq(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
- case acl:match_rule(To#jid.lserver, configure, From) of
- deny ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- allow ->
- case Type of
- set ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_FEATURE_NOT_IMPLEMENTED]};
- %case xml:get_tag_attr_s("type", SubEl) of
- % "cancel" ->
- % IQ#iq{type = result,
- % sub_el = [{xmlelement, "query",
- % [{"xmlns", XMLNS}], []}]};
- % "submit" ->
- % XData = jlib:parse_xdata_submit(SubEl),
- % case XData of
- % invalid ->
- % IQ#iq{type = error,
- % sub_el = [SubEl, ?ERR_BAD_REQUEST]};
- % _ ->
- % Node =
- % string:tokens(
- % xml:get_tag_attr_s("node", SubEl),
- % "/"),
- % case set_form(Node, Lang, XData) of
- % {result, Res} ->
- % IQ#iq{type = result,
- % sub_el = [{xmlelement, "query",
- % [{"xmlns", XMLNS}],
- % Res
- % }]};
- % {error, Error} ->
- % IQ#iq{type = error,
- % sub_el = [SubEl, Error]}
- % end
- % end;
- % _ ->
- % IQ#iq{type = error,
- % sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
- %end;
- get ->
- case process_get(SubEl) of
- {result, Res} ->
- IQ#iq{type = result, sub_el = [Res]};
- {error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]}
- end
- end
- end.
-
-
-process_get({xmlelement, "info", _Attrs, _SubEls}) ->
- S2SConns = ejabberd_s2s:dirty_get_connections(),
- TConns = lists:usort([element(2, C) || C <- S2SConns]),
- Attrs = [{"registered-users",
- integer_to_list(mnesia:table_info(passwd, size))},
- {"online-users",
- integer_to_list(mnesia:table_info(presence, size))},
- {"running-nodes",
- integer_to_list(length(mnesia:system_info(running_db_nodes)))},
- {"stopped-nodes",
- integer_to_list(
- length(lists:usort(mnesia:system_info(db_nodes) ++
- mnesia:system_info(extra_db_nodes)) --
- mnesia:system_info(running_db_nodes)))},
- {"outgoing-s2s-servers", integer_to_list(length(TConns))}],
- {result, {xmlelement, "info",
- [{"xmlns", ?NS_ECONFIGURE} | Attrs], []}};
-process_get({xmlelement, "welcome-message", Attrs, _SubEls}) ->
- {Subj, Body} = case ejabberd_config:get_local_option(welcome_message) of
- {_Subj, _Body} = SB -> SB;
- _ -> {"", ""}
- end,
- {result, {xmlelement, "welcome-message", Attrs,
- [{xmlelement, "subject", [], [{xmlcdata, Subj}]},
- {xmlelement, "body", [], [{xmlcdata, Body}]}]}};
-process_get({xmlelement, "registration-watchers", Attrs, _SubEls}) ->
- SubEls =
- case ejabberd_config:get_local_option(registration_watchers) of
- JIDs when is_list(JIDs) ->
- lists:map(fun(JID) ->
- {xmlelement, "jid", [], [{xmlcdata, JID}]}
- end, JIDs);
- _ ->
- []
- end,
- {result, {xmlelement, "registration_watchers", Attrs, SubEls}};
-process_get({xmlelement, "acls", Attrs, _SubEls}) ->
- Str = lists:flatten(io_lib:format("~p.", [ets:tab2list(acl)])),
- {result, {xmlelement, "acls", Attrs, [{xmlcdata, Str}]}};
-process_get({xmlelement, "access", Attrs, _SubEls}) ->
- Str =
- lists:flatten(
- io_lib:format(
- "~p.",
- [ets:select(config,
- [{{config, {access, '$1'}, '$2'},
- [],
- [{{access, '$1', '$2'}}]}])
- ])),
- {result, {xmlelement, "access", Attrs, [{xmlcdata, Str}]}};
-process_get({xmlelement, "last", Attrs, _SubEls}) ->
- case catch mnesia:dirty_select(
- last_activity, [{{last_activity, '_', '$1', '_'}, [], ['$1']}]) of
- {'EXIT', _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- Vals ->
- {MegaSecs, Secs, _MicroSecs} = now(),
- TimeStamp = MegaSecs * 1000000 + Secs,
- Str = lists:flatten(
- lists:append(
- [[integer_to_list(TimeStamp - V), " "] || V <- Vals])),
- {result, {xmlelement, "last", Attrs, [{xmlcdata, Str}]}}
- end;
-%process_get({xmlelement, Name, Attrs, SubEls}) ->
-% {result, };
-process_get(_) ->
- {error, ?ERR_BAD_REQUEST}.
-
diff --git a/ejabberd-1.1.2/src/mod_disco.erl b/ejabberd-1.1.2/src/mod_disco.erl
deleted file mode 100644
index 22f67da21..000000000
--- a/ejabberd-1.1.2/src/mod_disco.erl
+++ /dev/null
@@ -1,480 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_disco.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Service Discovery (JEP-0030) support
-%%% Created : 1 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_disco).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_mod).
-
--export([start/2,
- stop/1,
- process_local_iq_items/3,
- process_local_iq_info/3,
- get_local_identity/5,
- get_local_features/5,
- get_local_services/5,
- process_sm_iq_items/3,
- process_sm_iq_info/3,
- get_sm_identity/5,
- get_sm_features/5,
- get_sm_items/5,
- get_publish_items/5,
- register_feature/2,
- unregister_feature/2,
- register_extra_domain/2,
- unregister_extra_domain/2]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--record(disco_publish, {owner_node, jid, name, node}).
-
-start(Host, Opts) ->
- mnesia:create_table(disco_publish,
- [{disc_only_copies, [node()]},
- {attributes, record_info(fields, disco_publish)},
- {type, bag}]),
- mnesia:add_table_index(disco_publish, owner_node),
-
- ejabberd_local:refresh_iq_handlers(),
-
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS,
- ?MODULE, process_local_iq_items, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO,
- ?MODULE, process_local_iq_info, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS,
- ?MODULE, process_sm_iq_items, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO,
- ?MODULE, process_sm_iq_info, IQDisc),
-
- catch ets:new(disco_features, [named_table, ordered_set, public]),
- register_feature(Host, "iq"),
- register_feature(Host, "presence"),
- register_feature(Host, "presence-invisible"),
- register_feature(Host, "http://jabber.org/protocol/disco#publish"),
-
- catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
- ExtraDomains = gen_mod:get_opt(extra_domains, Opts, []),
- lists:foreach(fun(Domain) -> register_extra_domain(Host, Domain) end,
- ExtraDomains),
- catch ets:new(disco_sm_features, [named_table, ordered_set, public]),
- catch ets:new(disco_sm_nodes, [named_table, ordered_set, public]),
- ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_services, 100),
- ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 100),
- ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 100),
- ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_items, 100),
- ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 100),
- ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 100),
- ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_publish_items, 75),
- ok.
-
-stop(Host) ->
- ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_publish_items, 75),
- ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, get_sm_identity, 100),
- ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 100),
- ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_items, 100),
- ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 100),
- ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 100),
- ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_services, 100),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO),
- catch ets:match_delete(disco_features, {{'_', Host}}),
- catch ets:match_delete(disco_extra_domains, {{'_', Host}}),
- ok.
-
-
-register_feature(Host, Feature) ->
- catch ets:new(disco_features, [named_table, ordered_set, public]),
- ets:insert(disco_features, {{Feature, Host}}).
-
-unregister_feature(Host, Feature) ->
- catch ets:new(disco_features, [named_table, ordered_set, public]),
- ets:delete(disco_features, {Feature, Host}).
-
-register_extra_domain(Host, Domain) ->
- catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
- ets:insert(disco_extra_domains, {{Domain, Host}}).
-
-unregister_extra_domain(Host, Domain) ->
- catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
- ets:delete(disco_extra_domains, {Domain, Host}).
-
-process_local_iq_items(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- Node = xml:get_tag_attr_s("node", SubEl),
- Host = To#jid.lserver,
-
- case ejabberd_hooks:run_fold(disco_local_items,
- Host,
- empty,
- [From, To, Node, Lang]) of
- {result, Items} ->
- ANode = case Node of
- "" -> [];
- _ -> [{"node", Node}]
- end,
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_DISCO_ITEMS} | ANode],
- Items
- }]};
- {error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]}
- end
- end.
-
-
-process_local_iq_info(From, To, #iq{type = Type, lang = Lang,
- sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- Host = To#jid.lserver,
- Node = xml:get_tag_attr_s("node", SubEl),
- Identity = ejabberd_hooks:run_fold(disco_local_identity,
- Host,
- [],
- [From, To, Node, Lang]),
- case ejabberd_hooks:run_fold(disco_local_features,
- Host,
- empty,
- [From, To, Node, Lang]) of
- {result, Features} ->
- ANode = case Node of
- "" -> [];
- _ -> [{"node", Node}]
- end,
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_DISCO_INFO} | ANode],
- Identity ++
- lists:map(fun feature_to_xml/1, Features)
- }]};
- {error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]}
- end
- end.
-
-get_local_identity(_Acc, _From, _To, [], _Lang) ->
- [{xmlelement, "identity",
- [{"category", "server"},
- {"type", "im"},
- {"name", "ejabberd"}], []}];
-
-get_local_identity(Acc, _From, _To, _Node, _Lang) ->
- Acc.
-
-get_local_features({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
- Acc;
-
-get_local_features(Acc, _From, To, [], _Lang) ->
- Feats = case Acc of
- {result, Features} -> Features;
- empty -> []
- end,
- Host = To#jid.lserver,
- {result,
- ets:select(disco_features, [{{{'_', Host}}, [], ['$_']}]) ++ Feats};
-
-get_local_features(Acc, _From, _To, _Node, _Lang) ->
- case Acc of
- {result, _Features} ->
- Acc;
- empty ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end.
-
-
-feature_to_xml({{Feature, _Host}}) ->
- feature_to_xml(Feature);
-feature_to_xml(Feature) when is_list(Feature) ->
- {xmlelement, "feature", [{"var", Feature}], []}.
-
-domain_to_xml({Domain}) ->
- {xmlelement, "item", [{"jid", Domain}], []};
-domain_to_xml(Domain) ->
- {xmlelement, "item", [{"jid", Domain}], []}.
-
-get_local_services({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
- Acc;
-
-get_local_services(Acc, _From, To, [], _Lang) ->
- Items = case Acc of
- {result, Its} -> Its;
- empty -> []
- end,
- Host = To#jid.lserver,
- {result,
- lists:usort(
- lists:map(fun domain_to_xml/1,
- get_vh_services(Host) ++
- ets:select(disco_extra_domains,
- [{{{'$1', Host}}, [], ['$1']}]))
- ) ++ Items};
-
-get_local_services({result, _} = Acc, _From, _To, _Node, _Lang) ->
- Acc;
-
-get_local_services(empty, _From, _To, _Node, _Lang) ->
- {error, ?ERR_ITEM_NOT_FOUND}.
-
-get_vh_services(Host) ->
- Hosts = lists:sort(fun(H1, H2) -> length(H1) >= length(H2) end, ?MYHOSTS),
- lists:filter(fun(H) ->
- case lists:dropwhile(
- fun(VH) ->
- not lists:suffix("." ++ VH, H)
- end, Hosts) of
- [] ->
- false;
- [VH | _] ->
- VH == Host
- end
- end, ejabberd_router:dirty_get_all_routes()).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-process_sm_iq_items(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- #jid{luser = LTo, lserver = ToServer} = To,
- #jid{luser = LFrom, lserver = LServer} = From,
- Self = (LTo == LFrom) andalso (ToServer == LServer),
- Node = xml:get_tag_attr_s("node", SubEl),
- if
- Self, Node /= [] ->
- %% Here, we treat disco publish attempts to your own JID.
- {xmlelement, _, _, Items} = SubEl,
- case process_disco_publish({LFrom, LServer}, Node, Items) of
- ok ->
- IQ#iq{type = result, sub_el = []};
- {error, Err} ->
- IQ#iq{type = error, sub_el = [SubEl, Err]}
- end;
-
- true ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
- end;
- get ->
- Host = To#jid.lserver,
- Node = xml:get_tag_attr_s("node", SubEl),
- case ejabberd_hooks:run_fold(disco_sm_items,
- Host,
- empty,
- [From, To, Node, Lang]) of
- {result, Items} ->
- ANode = case Node of
- "" -> [];
- _ -> [{"node", Node}]
- end,
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_DISCO_ITEMS} | ANode],
- Items
- }]};
- {error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]}
- end
- end.
-
-get_sm_items({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
- Acc;
-
-get_sm_items(Acc,
- #jid{luser = LFrom, lserver = LSFrom},
- #jid{user = User, server = Server, luser = LTo, lserver = LSTo} = _To,
- [], _Lang) ->
- Items = case Acc of
- {result, Its} -> Its;
- empty -> []
- end,
- Items1 = case {LFrom, LSFrom} of
- {LTo, LSTo} -> get_user_resources(User, Server);
- _ -> []
- end,
- {result, Items ++ Items1};
-
-get_sm_items({result, _} = Acc, _From, _To, _Node, _Lang) ->
- Acc;
-
-get_sm_items(empty, From, To, _Node, _Lang) ->
- #jid{luser = LFrom, lserver = LSFrom} = From,
- #jid{luser = LTo, lserver = LSTo} = To,
- case {LFrom, LSFrom} of
- {LTo, LSTo} ->
- {error, ?ERR_ITEM_NOT_FOUND};
- _ ->
- {error, ?ERR_NOT_ALLOWED}
- end.
-
-process_sm_iq_info(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- Host = To#jid.lserver,
- Node = xml:get_tag_attr_s("node", SubEl),
- Identity = ejabberd_hooks:run_fold(disco_sm_identity,
- Host,
- [],
- [From, To, Node, Lang]),
- case ejabberd_hooks:run_fold(disco_sm_features,
- Host,
- empty,
- [From, To, Node, Lang]) of
- {result, Features} ->
- ANode = case Node of
- "" -> [];
- _ -> [{"node", Node}]
- end,
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_DISCO_INFO} | ANode],
- Identity ++
- lists:map(fun feature_to_xml/1, Features)
- }]};
- {error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]}
- end
- end.
-
-get_sm_identity(Acc, _From, _To, _Node, _Lang) ->
- Acc.
-
-get_sm_features(empty, From, To, _Node, _Lang) ->
- #jid{luser = LFrom, lserver = LSFrom} = From,
- #jid{luser = LTo, lserver = LSTo} = To,
- case {LFrom, LSFrom} of
- {LTo, LSTo} ->
- {error, ?ERR_ITEM_NOT_FOUND};
- _ ->
- {error, ?ERR_NOT_ALLOWED}
- end;
-
-get_sm_features(Acc, _From, _To, _Node, _Lang) ->
- Acc.
-
-
-
-get_user_resources(User, Server) ->
- Rs = ejabberd_sm:get_user_resources(User, Server),
- lists:map(fun(R) ->
- {xmlelement, "item",
- [{"jid", User ++ "@" ++ Server ++ "/" ++ R},
- {"name", User}], []}
- end, lists:sort(Rs)).
-
-
-get_publish_items(empty,
- #jid{luser = LFrom, lserver = LSFrom},
- #jid{luser = LTo, lserver = LSTo} = _To,
- Node, _Lang) ->
- if
- (LFrom == LTo) and (LSFrom == LSTo) ->
- retrieve_disco_publish({LTo, LSTo}, Node);
- true ->
- empty
- end;
-get_publish_items(Acc, _From, _To, _Node, _Lang) ->
- Acc.
-
-process_disco_publish(User, Node, Items) ->
- F = fun() ->
- lists:foreach(
- fun({xmlelement, _Name, _Attrs, _SubEls} = Item) ->
- Action = xml:get_tag_attr_s("action", Item),
- Jid = xml:get_tag_attr_s("jid", Item),
- PNode = xml:get_tag_attr_s("node", Item),
- Name = xml:get_tag_attr_s("name", Item),
- ?INFO_MSG("Disco publish: ~p ~p ~p ~p ~p ~p~n",
- [User, Action, Node, Jid, PNode, Name]),
-
- %% The disco_publish table isn't strictly a "bag" table, as
- %% entries with same jid and node combination are considered
- %% the same, even if they have different names. Therefore,
- %% we find a list of items to supersede.
- SupersededItems = mnesia:match_object(
- #disco_publish{owner_node = {User, Node},
- jid = Jid,
- node = PNode,
- _ = '_'}),
- case Action of
- "update" ->
- lists:map(
- fun(O) ->
- mnesia:delete_object(O)
- end, SupersededItems),
- mnesia:write(
- #disco_publish{owner_node = {User, Node},
- jid = Jid,
- name = Name,
- node = PNode});
- "remove" ->
- case SupersededItems of
- [] ->
- mnesia:abort({error, ?ERR_ITEM_NOT_FOUND});
- _ ->
- lists:map(
- fun(O) ->
- mnesia:delete_object(O)
- end, SupersededItems)
- end;
- _ ->
- %% invalid "action" attribute - return an error
- mnesia:abort({error, ?ERR_BAD_REQUEST})
- end;
- ({xmlcdata, _CDATA}) ->
- ok
- end, Items)
- end,
- case mnesia:transaction(F) of
- {aborted, {error, _} = Error} ->
- Error;
- {atomic, _} ->
- ok;
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end.
-
-retrieve_disco_publish(User, Node) ->
- case catch mnesia:dirty_read({disco_publish, {User, Node}}) of
- {'EXIT', _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- [] ->
- empty;
- Items ->
- {result,
- lists:map(
- fun(#disco_publish{jid = Jid,
- name = Name,
- node = PNode}) ->
- {xmlelement, "item",
- lists:append([[{"jid", Jid}],
- case Name of
- "" ->
- [];
- _ ->
- [{"name", Name}]
- end,
- case PNode of
- "" ->
- [];
- _ ->
- [{"node", PNode}]
- end]), []}
- end, Items)}
- end.
-
diff --git a/ejabberd-1.1.2/src/mod_echo.erl b/ejabberd-1.1.2/src/mod_echo.erl
deleted file mode 100644
index d37becb6a..000000000
--- a/ejabberd-1.1.2/src/mod_echo.erl
+++ /dev/null
@@ -1,126 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_echo.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 15 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_echo).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
--behaviour(gen_mod).
-
-%% API
--export([start_link/2, start/2, stop/1]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--record(state, {host}).
-
--define(PROCNAME, ejabberd_mod_echo).
-
-%%====================================================================
-%% 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) ->
- 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) ->
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- gen_server:call(Proc, stop),
- supervisor:stop_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]) ->
- MyHost = gen_mod:get_opt(host, Opts, "echo." ++ Host),
- ejabberd_router:register_route(MyHost),
- {ok, #state{host = MyHost}}.
-
-%%--------------------------------------------------------------------
-%% 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) ->
- ejabberd_router:route(To, From, Packet),
- {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
-%%--------------------------------------------------------------------
diff --git a/ejabberd-1.1.2/src/mod_irc/Makefile.in b/ejabberd-1.1.2/src/mod_irc/Makefile.in
deleted file mode 100644
index a206027d5..000000000
--- a/ejabberd-1.1.2/src/mod_irc/Makefile.in
+++ /dev/null
@@ -1,48 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@ @ERLANG_CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@ @ERLANG_LIBS@ @LIBICONV@
-
-ifeq ($(shell uname),Darwin)
-DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
-else
-# Assume Linux-style dynamic library flags
-DYNAMIC_LIB_CFLAGS = -fpic -shared
-endif
-
-SUBDIRS =
-
-ERLSHLIBS = ../iconv_erl.so
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-OBJS = \
- $(OUTDIR)/mod_irc.beam \
- $(OUTDIR)/mod_irc_connection.beam \
- $(OUTDIR)/iconv.beam
-
-all: $(OBJS) $(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) -Wall $(INCLUDES) $(CFLAGS) $(LDFLAGS) \
- $(subst ../,,$(subst .so,.c,$@)) $(LIBS) \
- -o $@ $(DYNAMIC_LIB_CFLAGS)
-
-clean:
- rm -f $(OBJS) $(ERLSHLIBS)
-
-distclean: clean
- rm -f Makefile
-
-TAGS:
- etags *.erl
-
diff --git a/ejabberd-1.1.2/src/mod_irc/Makefile.win32 b/ejabberd-1.1.2/src/mod_irc/Makefile.win32
deleted file mode 100644
index cba50e697..000000000
--- a/ejabberd-1.1.2/src/mod_irc/Makefile.win32
+++ /dev/null
@@ -1,45 +0,0 @@
-
-include ..\Makefile.inc
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-
-OBJS = \
- $(OUTDIR)\iconv.beam \
- $(OUTDIR)\mod_irc.beam \
- $(OUTDIR)\mod_irc_connection.beam
-
-SOURCE = iconv_erl.c
-OBJECT = iconv_erl.o
-DLL = $(OUTDIR)\iconv_erl.dll
-
-ALL : $(DLL) $(OBJS)
-
-CLEAN :
- -@erase $(DLL)
- -@erase $(OUTDIR)\iconv_erl.exp
- -@erase $(OUTDIR)\iconv_erl.lib
- -@erase $(OBJECT)
- -@erase $(OBJS)
-
-$(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/ejabberd-1.1.2/src/mod_irc/iconv.erl b/ejabberd-1.1.2/src/mod_irc/iconv.erl
deleted file mode 100644
index 1e4ef7a94..000000000
--- a/ejabberd-1.1.2/src/mod_irc/iconv.erl
+++ /dev/null
@@ -1,78 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : iconv.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Interface to libiconv
-%%% Created : 16 Feb 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(iconv).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--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', Pid, Reason}, Port) ->
- {noreply, Port};
-
-handle_info({'EXIT', Port, Reason}, Port) ->
- {stop, {port_died, Reason}, 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/ejabberd-1.1.2/src/mod_irc/iconv_erl.c b/ejabberd-1.1.2/src/mod_irc/iconv_erl.c
deleted file mode 100644
index 3698ee977..000000000
--- a/ejabberd-1.1.2/src/mod_irc/iconv_erl.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* $Id$ */
-
-#include <stdio.h>
-#include <string.h>
-#include <erl_driver.h>
-#include <ei.h>
-#include <iconv.h>
-
-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/ejabberd-1.1.2/src/mod_irc/mod_irc.erl b/ejabberd-1.1.2/src/mod_irc/mod_irc.erl
deleted file mode 100644
index 77c2f575d..000000000
--- a/ejabberd-1.1.2/src/mod_irc/mod_irc.erl
+++ /dev/null
@@ -1,590 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_irc.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : IRC transport
-%%% Created : 15 Feb 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_irc).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
--behaviour(gen_mod).
-
-%% API
--export([start_link/2,
- start/2,
- stop/1,
- closed_connection/3,
- get_user_and_encoding/3]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--define(DEFAULT_IRC_ENCODING, "koi8-r").
-
--record(irc_connection, {jid_server_host, pid}).
--record(irc_custom, {us_host, data}).
-
--record(state, {host, server_host, 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, Opts, "irc." ++ Host),
- update_table(MyHost),
- Access = gen_mod:get_opt(access, Opts, all),
- 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,
- 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,
- access = Access} = State) ->
- case catch do_route(Host, ServerHost, Access, From, To, Packet) 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) ->
- case acl:match_rule(Host, Access, From) of
- allow ->
- do_route1(Host, ServerHost, From, To, Packet);
- _ ->
- {xmlelement, _Name, Attrs, _Els} = Packet,
- Lang = xml:get_attr_s("xml:lang", Attrs),
- ErrText = "Access denied by service policy",
- Err = jlib:make_error_reply(Packet,
- ?ERRT_FORBIDDEN(Lang, ErrText)),
- ejabberd_router:route(To, From, Err)
- end.
-
-do_route1(Host, ServerHost, From, To, Packet) ->
- #jid{user = ChanServ, resource = Resource} = To,
- {xmlelement, _Name, Attrs, _Els} = Packet,
- case ChanServ of
- "" ->
- case Resource of
- "" ->
- case jlib:iq_query_info(Packet) of
- #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS,
- sub_el = SubEl} = IQ ->
- Res = IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", XMLNS}],
- iq_disco()}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(Res));
- #iq{type = get, xmlns = ?NS_DISCO_ITEMS = XMLNS} = IQ ->
- Res = IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", XMLNS}],
- []}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(Res));
- #iq{xmlns = ?NS_REGISTER} = IQ ->
- process_register(Host, From, To, IQ);
- #iq{type = get, xmlns = ?NS_VCARD = XMLNS,
- lang = Lang} = IQ ->
- Res = IQ#iq{type = result,
- sub_el =
- [{xmlelement, "vCard",
- [{"xmlns", XMLNS}],
- iq_get_vcard(Lang)}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(Res));
- #iq{} = IQ ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
- ejabberd_router:route(To, From, Err);
- _ ->
- ok
- end;
- _ ->
- Err = jlib:make_error_reply(Packet, ?ERR_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
- [] ->
- io:format("open new connection~n"),
- {Username, Encoding} = get_user_and_encoding(
- Host, From, Server),
- {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,
- io:format("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 = jlib:make_error_reply(
- Packet, ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router:route(To, From, Err);
- [R] ->
- Pid = R#irc_connection.pid,
- io:format("send to process ~p~n",
- [Pid]),
- mod_irc_connection:route_nick(
- Pid, Nick, Packet),
- ok
- end;
- _ ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_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() ->
- [{xmlelement, "identity",
- [{"category", "conference"},
- {"type", "irc"},
- {"name", "IRC Transport"}], []},
- {xmlelement, "feature",
- [{"var", ?NS_MUC}], []},
- {xmlelement, "feature",
- [{"var", ?NS_REGISTER}], []},
- {xmlelement, "feature",
- [{"var", ?NS_VCARD}], []}].
-
-iq_get_vcard(Lang) ->
- [{xmlelement, "FN", [],
- [{xmlcdata, "ejabberd/mod_irc"}]},
- {xmlelement, "URL", [],
- [{xmlcdata,
- "http://ejabberd.jabberstudio.org/"}]},
- {xmlelement, "DESC", [],
- [{xmlcdata, translate:translate(Lang, "ejabberd IRC module\n"
- "Copyright (c) 2003-2006 Alexey Shchepin")}]}].
-
-process_register(Host, From, To, #iq{} = IQ) ->
- case catch process_irc_register(Host, From, To, IQ) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]);
- ResIQ ->
- if
- ResIQ /= ignore ->
- ejabberd_router:route(To, From,
- jlib:iq_to_xml(ResIQ));
- true ->
- ok
- end
- end.
-
-find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) ->
- find_xdata_el1(SubEls).
-
-find_xdata_el1([]) ->
- false;
-
-find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_XDATA ->
- {xmlelement, Name, Attrs, SubEls};
- _ ->
- find_xdata_el1(Els)
- end;
-
-find_xdata_el1([_ | Els]) ->
- find_xdata_el1(Els).
-
-process_irc_register(Host, From, To,
- #iq{type = Type, xmlns = XMLNS,
- lang = Lang, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- XDataEl = find_xdata_el(SubEl),
- case XDataEl of
- false ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ACCEPTABLE]};
- {xmlelement, _Name, Attrs, SubEls} ->
- case xml:get_attr_s("type", Attrs) of
- "cancel" ->
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", XMLNS}], []}]};
- "submit" ->
- XData = jlib:parse_xdata_submit(XDataEl),
- case XData of
- invalid ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_BAD_REQUEST]};
- _ ->
- Node = string:tokens(
- xml:get_tag_attr_s("node", SubEl),
- "/"),
- case set_form(
- Host, From, Node, Lang, XData) of
- {result, Res} ->
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", XMLNS}],
- Res
- }]};
- {error, Error} ->
- IQ#iq{type = error,
- sub_el = [SubEl, Error]}
- end
- end;
- _ ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_BAD_REQUEST]}
- end
- end;
- get ->
- Node =
- string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
- case get_form(Host, From, Node, Lang) of
- {result, Res} ->
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", XMLNS}],
- Res
- }]};
- {error, Error} ->
- IQ#iq{type = error,
- sub_el = [SubEl, Error]}
- end
- end.
-
-
-
-get_form(Host, From, [], Lang) ->
- #jid{user = User, server = Server,
- luser = LUser, lserver = LServer} = From,
- US = {LUser, LServer},
- Customs =
- case catch mnesia:dirty_read({irc_custom, {US, Host}}) of
- {'EXIT', Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- [] ->
- {User, []};
- [#irc_custom{data = Data}] ->
- {xml:get_attr_s(username, Data),
- xml:get_attr_s(encodings, Data)}
- end,
- case Customs of
- {error, _Error} ->
- Customs;
- {Username, Encodings} ->
- {result,
- [{xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang,
- "You need an x:data capable client "
- "to configure mod_irc settings")}]},
- {xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang,
- "Registration in mod_irc for ") ++ User ++ "@" ++ Server}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang,
- "Enter username and encodings you wish to use for "
- "connecting to IRC servers")}]},
- {xmlelement, "field", [{"type", "text-single"},
- {"label",
- translate:translate(
- Lang, "IRC Username")},
- {"var", "username"}],
- [{xmlelement, "value", [], [{xmlcdata, Username}]}]},
- {xmlelement, "field", [{"type", "fixed"}],
- [{xmlelement, "value", [],
- [{xmlcdata,
- 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."),
- [?DEFAULT_IRC_ENCODING]))}]}]},
- {xmlelement, "field", [{"type", "fixed"}],
- [{xmlelement, "value", [],
- [{xmlcdata,
- translate:translate(
- Lang,
- "Example: [{\"irc.lucky.net\", \"koi8-r\"}, "
- "{\"vendetta.fef.net\", \"iso8859-1\"}]."
- )}]}]},
- {xmlelement, "field", [{"type", "text-multi"},
- {"label",
- translate:translate(Lang, "Encodings")},
- {"var", "encodings"}],
- lists:map(
- fun(S) ->
- {xmlelement, "value", [], [{xmlcdata, S}]}
- end,
- string:tokens(
- lists:flatten(
- io_lib:format("~p.", [Encodings])),
- "\n"))
- }
- ]}]}
- end;
-
-get_form(_Host, _, _, Lang) ->
- {error, ?ERR_SERVICE_UNAVAILABLE}.
-
-
-
-
-set_form(Host, From, [], Lang, XData) ->
- {LUser, LServer, _} = jlib:jid_tolower(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, ?ERR_NOT_ACCEPTABLE}
- end;
- _ ->
- {error, ?ERR_NOT_ACCEPTABLE}
- end;
- _ ->
- {error, ?ERR_NOT_ACCEPTABLE}
- end;
- _ ->
- {error, ?ERR_NOT_ACCEPTABLE}
- end;
-
-
-set_form(_Host, _, _, Lang, XData) ->
- {error, ?ERR_SERVICE_UNAVAILABLE}.
-
-
-get_user_and_encoding(Host, From, IRCServer) ->
- #jid{user = User, server = Server,
- luser = LUser, lserver = LServer} = From,
- US = {LUser, LServer},
- case catch mnesia:dirty_read({irc_custom, {US, Host}}) of
- {'EXIT', Reason} ->
- {User, ?DEFAULT_IRC_ENCODING};
- [] ->
- {User, ?DEFAULT_IRC_ENCODING};
- [#irc_custom{data = Data}] ->
- {xml:get_attr_s(username, Data),
- case xml:get_attr_s(IRCServer, xml:get_attr_s(encodings, Data)) of
- "" -> ?DEFAULT_IRC_ENCODING;
- 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/ejabberd-1.1.2/src/mod_irc/mod_irc_connection.erl b/ejabberd-1.1.2/src/mod_irc/mod_irc_connection.erl
deleted file mode 100644
index 53dc2c21c..000000000
--- a/ejabberd-1.1.2/src/mod_irc/mod_irc_connection.erl
+++ /dev/null
@@ -1,1192 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_irc_connection.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 15 Feb 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_irc_connection).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--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("ejabberd.hrl").
--include("jlib.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,
- {xmlelement, "presence", Attrs, Els}},
- StateName, StateData) ->
- NewStateData =
- case xml:get_attr_s("type", Attrs) 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
- "" ->
- 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,
- {xmlelement, "message", Attrs, Els} = El},
- StateName, StateData) ->
- NewStateData =
- case xml:get_attr_s("type", Attrs) of
- "groupchat" ->
- case xml:get_path_s(El, [{elem, "subject"}, cdata]) of
- "" ->
- ejabberd_router:route(
- jlib:make_jid(
- lists:concat(
- [Channel, "%", StateData#state.server]),
- StateData#state.host, StateData#state.nick),
- StateData#state.user, El),
- Body = xml:get_path_s(El, [{elem, "body"}, cdata]),
- 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 == ""; Type == "normal" ->
- Body = xml:get_path_s(El, [{elem, "body"}, cdata]),
- 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,
- {xmlelement, "iq", Attrs, Els} = El},
- StateName, StateData) ->
- From = StateData#state.user,
- To = jlib:make_jid(lists:concat([Channel, "%", StateData#state.server]),
- StateData#state.host, StateData#state.nick),
- case jlib:iq_query_info(El) of
- #iq{xmlns = ?NS_MUC_ADMIN} = IQ ->
- iq_admin(StateData, Channel, From, To, IQ);
- #iq{xmlns = ?NS_VERSION} ->
- Res = io_lib:format("PRIVMSG ~s :\001VERSION\001\r\n",
- [Resource]),
- ?SEND(Res),
- Err = jlib:make_error_reply(
- El, ?ERR_FEATURE_NOT_IMPLEMENTED),
- ejabberd_router:route(To, From, Err);
- #iq{xmlns = ?NS_TIME} ->
- Res = io_lib:format("PRIVMSG ~s :\001TIME\001\r\n",
- [Resource]),
- ?SEND(Res),
- Err = jlib:make_error_reply(
- El, ?ERR_FEATURE_NOT_IMPLEMENTED),
- ejabberd_router:route(To, From, Err);
- #iq{xmlns = ?NS_VCARD} ->
- Res = io_lib:format("WHOIS ~s \r\n",
- [Resource]),
- ?SEND(Res),
- Err = jlib:make_error_reply(
- El, ?ERR_FEATURE_NOT_IMPLEMENTED),
- ejabberd_router:route(To, From, Err);
- #iq{} ->
- Err = jlib:make_error_reply(
- El, ?ERR_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,
- {xmlelement, "message", Attrs, Els} = El},
- StateName, StateData) ->
- NewStateData =
- case xml:get_attr_s("type", Attrs) of
- "chat" ->
- Body = xml:get_path_s(El, [{elem, "body"}, cdata]),
- 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(
- jlib:make_jid(
- lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, StateData#state.nick),
- StateData#state.user,
- {xmlelement, "presence", [{"type", "error"}],
- [{xmlelement, "error", [{"code", "502"}],
- [{xmlcdata, "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} ->
- {xmlelement, Name, Attrs, SubTags} = El,
- case xml:get_attr_s("type", Attrs) of
- "error" ->
- ok;
- _ ->
- Err = jlib:make_error_reply(El,
- "502", Reason),
- From = jlib:string_to_jid(xml:get_attr_s("from", Attrs)),
- To = jlib:string_to_jid(xml:get_attr_s("to", Attrs)),
- 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(
- jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, User2),
- StateData#state.user,
- {xmlelement, "presence", [],
- [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "item",
- [{"affiliation", Affiliation},
- {"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(
- jlib:make_jid(
- lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- {xmlelement, "message", [{"type", "groupchat"}],
- [{xmlelement, "subject", [], [{xmlcdata, Msg1}]},
- {xmlelement, "body", [], [{xmlcdata, "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(
- jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- {xmlelement, "message", [{"type", "groupchat"}],
- [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}).
-
-
-
-process_endofwhois(StateData, String, Nick) ->
- ejabberd_router:route(
- jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- {xmlelement, "message", [{"type", "chat"}],
- [{xmlelement, "body", [], [{xmlcdata, "End of WHOIS"}]}]}).
-
-process_whois311(StateData, String, Nick, Ident, Irchost) ->
- {ok, Fullname, _} = regexp:sub(String, ".*311[^:]*:", ""),
- ejabberd_router:route(
- jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- {xmlelement, "message", [{"type", "chat"}],
- [{xmlelement, "body", [],
- [{xmlcdata, lists:concat(
- ["WHOIS: ", Nick, " is ",
- Ident, "@" , Irchost, " : " , Fullname])}]}]}).
-
-process_whois312(StateData, String, Nick, Ircserver) ->
- {ok, Ircserverdesc, _} = regexp:sub(String, ".*312[^:]*:", ""),
- ejabberd_router:route(
- jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- {xmlelement, "message", [{"type", "chat"}],
- [{xmlelement, "body", [],
- [{xmlcdata, lists:concat(["WHOIS: ", Nick, " use ",
- Ircserver, " : ", Ircserverdesc])}]}]}).
-
-process_whois319(StateData, String, Nick) ->
- {ok, Chanlist, _} = regexp:sub(String, ".*319[^:]*:", ""),
- ejabberd_router:route(
- jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- {xmlelement, "message", [{"type", "chat"}],
- [{xmlelement, "body", [],
- [{xmlcdata, 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(
- jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, FromUser),
- StateData#state.user,
- {xmlelement, "message", [{"type", "groupchat"}],
- [{xmlelement, "body", [], [{xmlcdata, 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(
- jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, FromUser),
- StateData#state.user,
- {xmlelement, "message", [{"type", "groupchat"}],
- [{xmlelement, "body", [], [{xmlcdata, 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(
- jlib:make_jid(lists:concat([FromUser, "!", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- {xmlelement, "message", [{"type", "chat"}],
- [{xmlelement, "body", [], [{xmlcdata, 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(
- jlib:make_jid(lists:concat([FromUser, "!", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- {xmlelement, "message", [{"type", "chat"}],
- [{xmlelement, "body", [], [{xmlcdata, 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 "
- "http://ejabberd.jabberstudio.org/"
- "\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,
- jlib:jid_to_string(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(
- jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, FromUser),
- StateData#state.user,
- {xmlelement, "message", [{"type", "groupchat"}],
- [{xmlelement, "subject", [], [{xmlcdata, Msg1}]},
- {xmlelement, "body", [],
- [{xmlcdata, "/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(
- jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, FromUser),
- StateData#state.user,
- {xmlelement, "presence", [{"type", "unavailable"}],
- [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "item",
- [{"affiliation", "member"},
- {"role", "none"}],
- []}]},
- {xmlelement, "status", [],
- [{xmlcdata, 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(
- jlib:make_jid(
- lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, FromUser),
- StateData#state.user,
- {xmlelement, "presence", [{"type", "unavailable"}],
- [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "item",
- [{"affiliation", "member"},
- {"role", "none"}],
- []}]},
- {xmlelement, "status", [],
- [{xmlcdata, 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(
- jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, FromUser),
- StateData#state.user,
- {xmlelement, "presence", [],
- [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "item",
- [{"affiliation", "member"},
- {"role", "participant"}],
- []}]},
- {xmlelement, "status", [],
- [{xmlcdata, 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(
- jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, Nick),
- StateData#state.user,
- {xmlelement, "presence", [],
- [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "item",
- [{"affiliation", Affiliation},
- {"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(
- jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, ""),
- StateData#state.user,
- {xmlelement, "message", [{"type", "groupchat"}],
- [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}),
- ejabberd_router:route(
- jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, Nick),
- StateData#state.user,
- {xmlelement, "presence", [{"type", "unavailable"}],
- [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "item",
- [{"affiliation", "none"},
- {"role", "none"}],
- []},
- {xmlelement, "status", [{"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(
- jlib:make_jid(
- lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, FromUser),
- StateData#state.user,
- {xmlelement, "presence", [{"type", "unavailable"}],
- [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "item",
- [{"affiliation", "member"},
- {"role", "participant"},
- {"nick", Nick}],
- []},
- {xmlelement, "status", [{"code", "303"}], []}
- ]}]}),
- ejabberd_router:route(
- jlib:make_jid(
- lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, Nick),
- StateData#state.user,
- {xmlelement, "presence", [],
- [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "item",
- [{"affiliation", "member"},
- {"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(
- jlib:make_jid(
- lists:concat([Chan, "%", StateData#state.server]),
- StateData#state.host, StateData#state.nick),
- StateData#state.user,
- {xmlelement, "presence", [{"type", "error"}],
- [{xmlelement, "error", [{"code", "502"}],
- [{xmlcdata, 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, xmlns = XMLNS, sub_el = SubEl} = IQ) ->
- 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} ->
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", XMLNS}],
- ResEls
- }]};
- {error, Error} ->
- IQ#iq{type = error,
- sub_el = [SubEl, Error]}
- end,
- ejabberd_router:route(To, From,
- jlib:iq_to_xml(ResIQ));
- true ->
- ok
- end
- end.
-
-
-process_iq_admin(StateData, Channel, set, SubEl) ->
- case xml:get_subtag(SubEl, "item") of
- false ->
- {error, ?ERR_BAD_REQUEST};
- ItemEl ->
- Nick = xml:get_tag_attr_s("nick", ItemEl),
- Affiliation = xml:get_tag_attr_s("affiliation", ItemEl),
- Role = xml:get_tag_attr_s("role", ItemEl),
- Reason = xml:get_path_s(ItemEl, [{elem, "reason"}, cdata]),
- process_admin(StateData, Channel, Nick, Affiliation, Role, Reason)
- end;
-process_iq_admin(StateData, Channel, get, SubEl) ->
- {error, ?ERR_FEATURE_NOT_IMPLEMENTED}.
-
-
-
-process_admin(StateData, Channel, "", Affiliation, Role, Reason) ->
- {error, ?ERR_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, ?ERR_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/ejabberd-1.1.2/src/mod_last.erl b/ejabberd-1.1.2/src/mod_last.erl
deleted file mode 100644
index 34ab81c6f..000000000
--- a/ejabberd-1.1.2/src/mod_last.erl
+++ /dev/null
@@ -1,196 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_last.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : jabber:iq:last support (JEP-0012)
-%%% Created : 24 Oct 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_last).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_mod).
-
--export([start/2,
- stop/1,
- process_local_iq/3,
- process_sm_iq/3,
- on_presence_update/4,
- store_last_info/4,
- remove_user/2]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--record(last_activity, {us, timestamp, status}).
-
-
-start(Host, Opts) ->
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- mnesia:create_table(last_activity,
- [{disc_copies, [node()]},
- {attributes, record_info(fields, last_activity)}]),
- update_table(),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST,
- ?MODULE, process_local_iq, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST,
- ?MODULE, process_sm_iq, IQDisc),
- ejabberd_hooks:add(remove_user, Host,
- ?MODULE, remove_user, 50),
- ejabberd_hooks:add(unset_presence_hook, Host,
- ?MODULE, on_presence_update, 50).
-
-stop(Host) ->
- ejabberd_hooks:delete(remove_user, Host,
- ?MODULE, remove_user, 50),
- ejabberd_hooks:delete(unset_presence_hook, Host,
- ?MODULE, on_presence_update, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST).
-
-process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- Sec = trunc(element(1, erlang:statistics(wall_clock))/1000),
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_LAST},
- {"seconds", integer_to_list(Sec)}],
- []}]}
- end.
-
-
-process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- User = To#jid.luser,
- Server = To#jid.lserver,
- {Subscription, _Groups} =
- ejabberd_hooks:run_fold(
- roster_get_jid_info, Server,
- {none, []}, [User, Server, From]),
- if
- (Subscription == both) or (Subscription == from) ->
- case catch mod_privacy:get_user_list(User, Server) of
- {'EXIT', _Reason} ->
- get_last(IQ, SubEl, User, Server);
- List ->
- case catch mod_privacy:check_packet(
- User, Server, List,
- {From, To,
- {xmlelement, "presence", [], []}},
- out) of
- {'EXIT', _Reason} ->
- get_last(IQ, SubEl, User, Server);
- allow ->
- get_last(IQ, SubEl, User, Server);
- deny ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
- end
- end;
- true ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
- end
- end.
-
-get_last(IQ, SubEl, LUser, LServer) ->
- case catch mnesia:dirty_read(last_activity, {LUser, LServer}) of
- {'EXIT', _Reason} ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
- [] ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
- [#last_activity{timestamp = TimeStamp, status = Status}] ->
- {MegaSecs, Secs, _MicroSecs} = now(),
- TimeStamp2 = MegaSecs * 1000000 + Secs,
- Sec = TimeStamp2 - TimeStamp,
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_LAST},
- {"seconds", integer_to_list(Sec)}],
- [{xmlcdata, Status}]}]}
- end.
-
-
-
-on_presence_update(User, Server, _Resource, Status) ->
- {MegaSecs, Secs, _MicroSecs} = now(),
- TimeStamp = MegaSecs * 1000000 + Secs,
- store_last_info(User, Server, TimeStamp, Status).
-
-store_last_info(User, Server, TimeStamp, Status) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- F = fun() ->
- mnesia:write(#last_activity{us = US,
- timestamp = TimeStamp,
- status = Status})
- end,
- mnesia:transaction(F).
-
-
-remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- F = fun() ->
- mnesia:delete({last_activity, US})
- end,
- mnesia:transaction(F).
-
-
-update_table() ->
- Fields = record_info(fields, last_activity),
- case mnesia:table_info(last_activity, attributes) of
- Fields ->
- ok;
- [user, timestamp, status] ->
- ?INFO_MSG("Converting last_activity table from {user, timestamp, status} format", []),
- Host = ?MYNAME,
- mnesia:transform_table(last_activity, ignore, Fields),
- F = fun() ->
- mnesia:write_lock_table(last_activity),
- mnesia:foldl(
- fun({_, U, T, S} = R, _) ->
- mnesia:delete_object(R),
- mnesia:write(
- #last_activity{us = {U, Host},
- timestamp = T,
- status = S})
- end, ok, last_activity)
- end,
- mnesia:transaction(F);
- [user, timestamp] ->
- ?INFO_MSG("Converting last_activity table from {user, timestamp} format", []),
- Host = ?MYNAME,
- mnesia:transform_table(
- last_activity,
- fun({_, U, T}) ->
- #last_activity{us = U,
- timestamp = T,
- status = ""}
- end, Fields),
- F = fun() ->
- mnesia:write_lock_table(last_activity),
- mnesia:foldl(
- fun({_, U, T, S} = R, _) ->
- mnesia:delete_object(R),
- mnesia:write(
- #last_activity{us = {U, Host},
- timestamp = T,
- status = S})
- end, ok, last_activity)
- end,
- mnesia:transaction(F);
- _ ->
- ?INFO_MSG("Recreating last_activity table", []),
- mnesia:transform_table(last_activity, ignore, Fields)
- end.
-
diff --git a/ejabberd-1.1.2/src/mod_last_odbc.erl b/ejabberd-1.1.2/src/mod_last_odbc.erl
deleted file mode 100644
index 8ec76823d..000000000
--- a/ejabberd-1.1.2/src/mod_last_odbc.erl
+++ /dev/null
@@ -1,138 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_last_odbc.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : jabber:iq:last support (JEP-0012)
-%%% Created : 24 Oct 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_last_odbc).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_mod).
-
--export([start/2,
- stop/1,
- process_local_iq/3,
- process_sm_iq/3,
- on_presence_update/4,
- store_last_info/4,
- remove_user/2]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
-
-start(Host, Opts) ->
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST,
- ?MODULE, process_local_iq, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST,
- ?MODULE, process_sm_iq, IQDisc),
- ejabberd_hooks:add(remove_user, Host,
- ?MODULE, remove_user, 50),
- ejabberd_hooks:add(unset_presence_hook, Host,
- ?MODULE, on_presence_update, 50).
-
-stop(Host) ->
- ejabberd_hooks:delete(remove_user, Host,
- ?MODULE, remove_user, 50),
- ejabberd_hooks:delete(unset_presence_hook, Host,
- ?MODULE, on_presence_update, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST).
-
-process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- Sec = trunc(element(1, erlang:statistics(wall_clock))/1000),
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_LAST},
- {"seconds", integer_to_list(Sec)}],
- []}]}
- end.
-
-process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- User = To#jid.luser,
- Server = To#jid.lserver,
- {Subscription, _Groups} =
- ejabberd_hooks:run_fold(
- roster_get_jid_info, Server,
- {none, []}, [User, Server, From]),
- if
- (Subscription == both) or (Subscription == from) ->
- case catch mod_privacy:get_user_list(User, Server) of
- {'EXIT', _Reason} ->
- get_last(IQ, SubEl, User, Server);
- List ->
- case catch mod_privacy:check_packet(
- User, Server, List,
- {From, To,
- {xmlelement, "presence", [], []}},
- out) of
- {'EXIT', _Reason} ->
- get_last(IQ, SubEl, User, Server);
- allow ->
- get_last(IQ, SubEl, User, Server);
- deny ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
- end
- end;
- true ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
- end
- end.
-
-get_last(IQ, SubEl, LUser, LServer) ->
- Username = ejabberd_odbc:escape(LUser),
- case catch odbc_queries:get_last(LServer, Username) of
- {'EXIT', _Reason} ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
- {selected, ["seconds","state"], []} ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
- {selected, ["seconds","state"], [{STimeStamp, Status}]} ->
- case catch list_to_integer(STimeStamp) of
- TimeStamp when is_integer(TimeStamp) ->
- {MegaSecs, Secs, _MicroSecs} = now(),
- TimeStamp2 = MegaSecs * 1000000 + Secs,
- Sec = TimeStamp2 - TimeStamp,
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_LAST},
- {"seconds", integer_to_list(Sec)}],
- [{xmlcdata, Status}]}]};
- _ ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
- end
- end.
-
-on_presence_update(User, Server, _Resource, Status) ->
- {MegaSecs, Secs, _MicroSecs} = now(),
- TimeStamp = MegaSecs * 1000000 + Secs,
- store_last_info(User, Server, TimeStamp, Status).
-
-store_last_info(User, Server, TimeStamp, Status) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- Username = ejabberd_odbc:escape(LUser),
- Seconds = ejabberd_odbc:escape(integer_to_list(TimeStamp)),
- State = ejabberd_odbc:escape(Status),
- odbc_queries:set_last_t(LServer, Username, Seconds, State).
-
-
-remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- Username = ejabberd_odbc:escape(LUser),
- odbc_queries:del_last(LServer, Username).
diff --git a/ejabberd-1.1.2/src/mod_muc/Makefile.in b/ejabberd-1.1.2/src/mod_muc/Makefile.in
deleted file mode 100644
index 6ab1d8a72..000000000
--- a/ejabberd-1.1.2/src/mod_muc/Makefile.in
+++ /dev/null
@@ -1,31 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@ @ERLANG_CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@ @ERLANG_LIBS@
-
-SUBDIRS =
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-OBJS = \
- $(OUTDIR)/mod_muc.beam \
- $(OUTDIR)/mod_muc_log.beam \
- $(OUTDIR)/mod_muc_room.beam
-
-all: $(OBJS)
-
-$(OUTDIR)/%.beam: %.erl
- @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-clean:
- rm -f $(OBJS)
-
-distclean: clean
- rm -f Makefile
-
-TAGS:
- etags *.erl
-
diff --git a/ejabberd-1.1.2/src/mod_muc/Makefile.win32 b/ejabberd-1.1.2/src/mod_muc/Makefile.win32
deleted file mode 100644
index 76f6bb7f4..000000000
--- a/ejabberd-1.1.2/src/mod_muc/Makefile.win32
+++ /dev/null
@@ -1,24 +0,0 @@
-
-include ..\Makefile.inc
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-
-OBJS = \
- $(OUTDIR)\mod_muc.beam \
- $(OUTDIR)\mod_muc_log.beam \
- $(OUTDIR)\mod_muc_room.beam
-
-ALL : $(OBJS)
-
-CLEAN :
- -@erase $(OBJS)
-
-$(OUTDIR)\mod_muc.beam : mod_muc.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) mod_muc.erl
-
-$(OUTDIR)\mod_muc_log.beam : mod_muc_log.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) mod_muc_log.erl
-
-$(OUTDIR)\mod_muc_room.beam : mod_muc_room.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) mod_muc_room.erl
diff --git a/ejabberd-1.1.2/src/mod_muc/mod_muc.erl b/ejabberd-1.1.2/src/mod_muc/mod_muc.erl
deleted file mode 100644
index d5ecb5b91..000000000
--- a/ejabberd-1.1.2/src/mod_muc/mod_muc.erl
+++ /dev/null
@@ -1,694 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_muc.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : MUC support (JEP-0045)
-%%% Created : 19 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_muc).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
--behaviour(gen_mod).
-
-%% API
--export([start_link/2,
- start/2,
- stop/1,
- room_destroyed/3,
- store_room/3,
- restore_room/2,
- forget_room/2,
- process_iq_disco_items/4,
- can_use_nick/3]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
-
--record(muc_room, {name_host, opts}).
--record(muc_online_room, {name_host, pid}).
--record(muc_registered, {us_host, nick}).
-
--record(state, {host, server_host, access, history_size}).
-
--define(PROCNAME, ejabberd_mod_muc).
-
-%%====================================================================
-%% 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).
-
-room_destroyed(Host, Room, ServerHost) ->
- gen_mod:get_module_proc(ServerHost, ?PROCNAME) !
- {room_destroyed, {Room, Host}},
- ok.
-
-store_room(Host, Name, Opts) ->
- F = fun() ->
- mnesia:write(#muc_room{name_host = {Name, Host},
- opts = Opts})
- end,
- mnesia:transaction(F).
-
-restore_room(Host, Name) ->
- case catch mnesia:dirty_read(muc_room, {Name, Host}) of
- [#muc_room{opts = Opts}] ->
- Opts;
- _ ->
- error
- end.
-
-forget_room(Host, Name) ->
- F = fun() ->
- mnesia:delete({muc_room, {Name, Host}})
- end,
- mnesia:transaction(F).
-
-process_iq_disco_items(Host, From, To, #iq{lang = Lang} = IQ) ->
- Res = IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_DISCO_ITEMS}],
- iq_disco_items(Host, From, Lang)}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(Res)).
-
-can_use_nick(_Host, _JID, "") ->
- false;
-can_use_nick(Host, JID, Nick) ->
- {LUser, LServer, _} = jlib:jid_tolower(JID),
- LUS = {LUser, LServer},
- case catch mnesia:dirty_select(
- muc_registered,
- [{#muc_registered{us_host = '$1',
- nick = Nick,
- _ = '_'},
- [{'==', {element, 2, '$1'}, Host}],
- ['$_']}]) of
- {'EXIT', _Reason} ->
- true;
- [] ->
- true;
- [#muc_registered{us_host = {U, _Host}}] ->
- U == LUS
- end.
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% Description: Initiates the server
-%%--------------------------------------------------------------------
-init([Host, Opts]) ->
- mnesia:create_table(muc_room,
- [{disc_copies, [node()]},
- {attributes, record_info(fields, muc_room)}]),
- mnesia:create_table(muc_registered,
- [{disc_copies, [node()]},
- {attributes, record_info(fields, muc_registered)}]),
- MyHost = gen_mod:get_opt(host, Opts, "conference." ++ Host),
- update_tables(MyHost),
- mnesia:add_table_index(muc_registered, nick),
- Access = gen_mod:get_opt(access, Opts, all),
- AccessCreate = gen_mod:get_opt(access_create, Opts, all),
- AccessAdmin = gen_mod:get_opt(access_admin, Opts, none),
- HistorySize = gen_mod:get_opt(history_size, Opts, 20),
- catch ets:new(muc_online_room, [named_table,
- public,
- {keypos, #muc_online_room.name_host}]),
- ejabberd_router:register_route(MyHost),
- load_permanent_rooms(MyHost, Host, {Access, AccessCreate, AccessAdmin},
- HistorySize),
- {ok, #state{host = MyHost,
- server_host = Host,
- access = {Access, AccessCreate, AccessAdmin},
- history_size = HistorySize}}.
-
-%%--------------------------------------------------------------------
-%% 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,
- access = Access,
- history_size = HistorySize} = State) ->
- case catch do_route(Host, ServerHost, Access, HistorySize, From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]);
- _ ->
- ok
- end,
- {noreply, State};
-handle_info({room_destroyed, RoomHost}, State) ->
- ets:delete(muc_online_room, RoomHost),
- {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_muc_sup),
- ChildSpec =
- {Proc,
- {ejabberd_tmp_sup, start_link,
- [Proc, mod_muc_room]},
- permanent,
- infinity,
- supervisor,
- [ejabberd_tmp_sup]},
- supervisor:start_child(ejabberd_sup, ChildSpec).
-
-stop_supervisor(Host) ->
- Proc = gen_mod:get_module_proc(Host, ejabberd_mod_muc_sup),
- supervisor:terminate_child(ejabberd_sup, Proc),
- supervisor:delete_child(ejabberd_sup, Proc).
-
-do_route(Host, ServerHost, Access, HistorySize, From, To, Packet) ->
- {AccessRoute, _AccessCreate, _AccessAdmin} = Access,
- case acl:match_rule(ServerHost, AccessRoute, From) of
- allow ->
- do_route1(Host, ServerHost, Access, HistorySize, From, To, Packet);
- _ ->
- {xmlelement, _Name, Attrs, _Els} = Packet,
- Lang = xml:get_attr_s("xml:lang", Attrs),
- ErrText = "Access denied by service policy",
- Err = jlib:make_error_reply(Packet,
- ?ERRT_FORBIDDEN(Lang, ErrText)),
- ejabberd_router:route(To, From, Err)
- end.
-
-
-do_route1(Host, ServerHost, Access, HistorySize, From, To, Packet) ->
- {_AccessRoute, AccessCreate, AccessAdmin} = Access,
- {Room, _, Nick} = jlib:jid_tolower(To),
- {xmlelement, Name, Attrs, _Els} = Packet,
- case Room of
- "" ->
- case Nick of
- "" ->
- case Name of
- "iq" ->
- case jlib:iq_query_info(Packet) of
- #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS,
- sub_el = _SubEl} = IQ ->
- Res = IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", XMLNS}],
- iq_disco_info()}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(Res));
- #iq{type = get,
- xmlns = ?NS_DISCO_ITEMS} = IQ ->
- spawn(?MODULE,
- process_iq_disco_items,
- [Host, From, To, IQ]);
- #iq{type = get,
- xmlns = ?NS_REGISTER = XMLNS,
- lang = Lang,
- sub_el = _SubEl} = IQ ->
- Res = IQ#iq{type = result,
- sub_el =
- [{xmlelement, "query",
- [{"xmlns", XMLNS}],
- iq_get_register_info(
- Host, From, Lang)}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(Res));
- #iq{type = set,
- xmlns = ?NS_REGISTER = XMLNS,
- lang = Lang,
- sub_el = SubEl} = IQ ->
- case process_iq_register_set(Host, From, SubEl, Lang) of
- {result, IQRes} ->
- Res = IQ#iq{type = result,
- sub_el =
- [{xmlelement, "query",
- [{"xmlns", XMLNS}],
- IQRes}]},
- ejabberd_router:route(
- To, From, jlib:iq_to_xml(Res));
- {error, Error} ->
- Err = jlib:make_error_reply(
- Packet, Error),
- ejabberd_router:route(
- To, From, Err)
- end;
- #iq{type = get,
- xmlns = ?NS_VCARD = XMLNS,
- lang = Lang,
- sub_el = _SubEl} = IQ ->
- Res = IQ#iq{type = result,
- sub_el =
- [{xmlelement, "vCard",
- [{"xmlns", XMLNS}],
- iq_get_vcard(Lang)}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(Res));
- #iq{} ->
- Err = jlib:make_error_reply(
- Packet,
- ?ERR_FEATURE_NOT_IMPLEMENTED),
- ejabberd_router:route(To, From, Err);
- _ ->
- ok
- end;
- "message" ->
- case xml:get_attr_s("type", Attrs) of
- "error" ->
- ok;
- _ ->
- case acl:match_rule(ServerHost, AccessAdmin, From) of
- allow ->
- Msg = xml:get_path_s(
- Packet,
- [{elem, "body"}, cdata]),
- broadcast_service_message(Host, Msg);
- _ ->
- Lang = xml:get_attr_s("xml:lang", Attrs),
- ErrText = "Only service administrators "
- "are allowed to send service messages",
- Err = jlib:make_error_reply(
- Packet,
- ?ERRT_FORBIDDEN(Lang, ErrText)),
- ejabberd_router:route(
- To, From, Err)
- end
- end;
- "presence" ->
- ok
- end;
- _ ->
- case xml:get_attr_s("type", Attrs) of
- "error" ->
- ok;
- "result" ->
- ok;
- _ ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_ITEM_NOT_FOUND),
- ejabberd_router:route(To, From, Err)
- end
- end;
- _ ->
- case ets:lookup(muc_online_room, {Room, Host}) of
- [] ->
- Type = xml:get_attr_s("type", Attrs),
- case {Name, Type} of
- {"presence", ""} ->
- case acl:match_rule(ServerHost, AccessCreate, From) of
- allow ->
- ?DEBUG("MUC: open new room '~s'~n", [Room]),
- {ok, Pid} = mod_muc_room:start(
- Host, ServerHost, Access,
- Room, HistorySize, From,
- Nick),
- ets:insert(
- muc_online_room,
- #muc_online_room{name_host = {Room, Host},
- pid = Pid}),
- mod_muc_room:route(Pid, From, Nick, Packet),
- ok;
- _ ->
- Lang = xml:get_attr_s("xml:lang", Attrs),
- ErrText = "Room creation is denied by service policy",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_FORBIDDEN(Lang, ErrText)),
- ejabberd_router:route(To, From, Err)
- end;
- _ ->
- Lang = xml:get_attr_s("xml:lang", Attrs),
- ErrText = "Conference room does not exist",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_ITEM_NOT_FOUND(Lang, ErrText)),
- ejabberd_router:route(To, From, Err)
- end;
- [R] ->
- Pid = R#muc_online_room.pid,
- ?DEBUG("MUC: send to process ~p~n", [Pid]),
- mod_muc_room:route(Pid, From, Nick, Packet),
- ok
- end
- end.
-
-
-
-
-load_permanent_rooms(Host, ServerHost, Access, HistorySize) ->
- case catch mnesia:dirty_select(
- muc_room, [{#muc_room{name_host = {'_', Host}, _ = '_'},
- [],
- ['$_']}]) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]),
- ok;
- Rs ->
- lists:foreach(fun(R) ->
- {Room, Host} = R#muc_room.name_host,
- {ok, Pid} = mod_muc_room:start(
- Host,
- ServerHost,
- Access,
- Room,
- HistorySize,
- R#muc_room.opts),
- ets:insert(
- muc_online_room,
- #muc_online_room{name_host = {Room, Host},
- pid = Pid})
- end, Rs)
- end.
-
-
-iq_disco_info() ->
- [{xmlelement, "identity",
- [{"category", "conference"},
- {"type", "text"},
- {"name", "Chatrooms"}], []},
- {xmlelement, "feature", [{"var", ?NS_MUC}], []},
- {xmlelement, "feature", [{"var", ?NS_REGISTER}], []},
- {xmlelement, "feature", [{"var", ?NS_VCARD}], []}].
-
-
-iq_disco_items(Host, From, Lang) ->
- lists:zf(fun(#muc_online_room{name_host = {Name, _Host}, pid = Pid}) ->
- case catch gen_fsm:sync_send_all_state_event(
- Pid, {get_disco_item, From, Lang}, 100) of
- {item, Desc} ->
- {true,
- {xmlelement, "item",
- [{"jid", jlib:jid_to_string({Name, Host, ""})},
- {"name", Desc}], []}};
- _ ->
- false
- end
- end, get_vh_rooms(Host)).
-
-
--define(XFIELD(Type, Label, Var, Val),
- {xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
- {"var", Var}],
- [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
-
-iq_get_register_info(Host, From, Lang) ->
- {LUser, LServer, _} = jlib:jid_tolower(From),
- LUS = {LUser, LServer},
- {Nick, Registered} =
- case catch mnesia:dirty_read(muc_registered, {LUS, Host}) of
- {'EXIT', _Reason} ->
- {"", []};
- [] ->
- {"", []};
- [#muc_registered{nick = N}] ->
- {N, [{xmlelement, "registered", [], []}]}
- end,
- Registered ++
- [{xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "You need an x:data capable client to register nickname")}]},
- {xmlelement, "x",
- [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Nickname Registration at ") ++ Host}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Enter nickname you want to register")}]},
- ?XFIELD("text-single", "Nickname", "nick", Nick)]}].
-
-iq_set_register_info(Host, From, Nick, Lang) ->
- {LUser, LServer, _} = jlib:jid_tolower(From),
- LUS = {LUser, LServer},
- F = fun() ->
- case Nick of
- "" ->
- mnesia:delete({muc_registered, {LUS, Host}}),
- ok;
- _ ->
- Allow =
- case mnesia:select(
- muc_registered,
- [{#muc_registered{us_host = '$1',
- nick = Nick,
- _ = '_'},
- [{'==', {element, 2, '$1'}, Host}],
- ['$_']}]) of
- [] ->
- true;
- [#muc_registered{us_host = {U, _Host}}] ->
- U == LUS
- end,
- if
- Allow ->
- mnesia:write(
- #muc_registered{us_host = {LUS, Host},
- nick = Nick}),
- ok;
- true ->
- false
- end
- end
- end,
- case mnesia:transaction(F) of
- {atomic, ok} ->
- {result, []};
- {atomic, false} ->
- ErrText = "Specified nickname is already registered",
- {error, ?ERRT_CONFLICT(Lang, ErrText)};
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end.
-
-process_iq_register_set(Host, From, SubEl, Lang) ->
- {xmlelement, _Name, _Attrs, Els} = SubEl,
- case xml:get_subtag(SubEl, "remove") of
- false ->
- case xml:remove_cdata(Els) of
- [{xmlelement, "x", _Attrs1, _Els1} = XEl] ->
- case {xml:get_tag_attr_s("xmlns", XEl),
- xml:get_tag_attr_s("type", XEl)} of
- {?NS_XDATA, "cancel"} ->
- {result, []};
- {?NS_XDATA, "submit"} ->
- XData = jlib:parse_xdata_submit(XEl),
- case XData of
- invalid ->
- {error, ?ERR_BAD_REQUEST};
- _ ->
- case lists:keysearch("nick", 1, XData) of
- false ->
- ErrText = "You must fill in field \"Nickname\" in the form",
- {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)};
- {value, {_, [Nick]}} ->
- iq_set_register_info(Host, From, Nick, Lang)
- end
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- iq_set_register_info(Host, From, "", Lang)
- end.
-
-iq_get_vcard(Lang) ->
- [{xmlelement, "FN", [],
- [{xmlcdata, "ejabberd/mod_muc"}]},
- {xmlelement, "URL", [],
- [{xmlcdata,
- "http://ejabberd.jabberstudio.org/"}]},
- {xmlelement, "DESC", [],
- [{xmlcdata, translate:translate(Lang, "ejabberd MUC module\n"
- "Copyright (c) 2003-2006 Alexey Shchepin")}]}].
-
-
-broadcast_service_message(Host, Msg) ->
- lists:foreach(
- fun(#muc_online_room{pid = Pid}) ->
- gen_fsm:send_all_state_event(
- Pid, {service_message, Msg})
- end, get_vh_rooms(Host)).
-
-get_vh_rooms(Host) ->
- ets:select(muc_online_room,
- [{#muc_online_room{name_host = '$1', _ = '_'},
- [{'==', {element, 2, '$1'}, Host}],
- ['$_']}]).
-
-
-
-update_tables(Host) ->
- update_muc_room_table(Host),
- update_muc_registered_table(Host).
-
-update_muc_room_table(Host) ->
- Fields = record_info(fields, muc_room),
- case mnesia:table_info(muc_room, attributes) of
- Fields ->
- ok;
- [name, opts] ->
- ?INFO_MSG("Converting muc_room table from "
- "{name, opts} format", []),
- {atomic, ok} = mnesia:create_table(
- mod_muc_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, muc_room},
- {attributes, record_info(fields, muc_room)}]),
- mnesia:transform_table(muc_room, ignore, Fields),
- F1 = fun() ->
- mnesia:write_lock_table(mod_muc_tmp_table),
- mnesia:foldl(
- fun(#muc_room{name_host = Name} = R, _) ->
- mnesia:dirty_write(
- mod_muc_tmp_table,
- R#muc_room{name_host = {Name, Host}})
- end, ok, muc_room)
- end,
- mnesia:transaction(F1),
- mnesia:clear_table(muc_room),
- F2 = fun() ->
- mnesia:write_lock_table(muc_room),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_muc_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_muc_tmp_table);
- _ ->
- ?INFO_MSG("Recreating muc_room table", []),
- mnesia:transform_table(muc_room, ignore, Fields)
- end.
-
-
-update_muc_registered_table(Host) ->
- Fields = record_info(fields, muc_registered),
- case mnesia:table_info(muc_registered, attributes) of
- Fields ->
- ok;
- [user, nick] ->
- ?INFO_MSG("Converting muc_registered table from "
- "{user, nick} format", []),
- {atomic, ok} = mnesia:create_table(
- mod_muc_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, muc_registered},
- {attributes, record_info(fields, muc_registered)}]),
- mnesia:del_table_index(muc_registered, nick),
- mnesia:transform_table(muc_registered, ignore, Fields),
- F1 = fun() ->
- mnesia:write_lock_table(mod_muc_tmp_table),
- mnesia:foldl(
- fun(#muc_registered{us_host = US} = R, _) ->
- mnesia:dirty_write(
- mod_muc_tmp_table,
- R#muc_registered{us_host = {US, Host}})
- end, ok, muc_registered)
- end,
- mnesia:transaction(F1),
- mnesia:clear_table(muc_registered),
- F2 = fun() ->
- mnesia:write_lock_table(muc_registered),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_muc_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_muc_tmp_table);
- _ ->
- ?INFO_MSG("Recreating muc_registered table", []),
- mnesia:transform_table(muc_registered, ignore, Fields)
- end.
diff --git a/ejabberd-1.1.2/src/mod_muc/mod_muc_log.erl b/ejabberd-1.1.2/src/mod_muc/mod_muc_log.erl
deleted file mode 100644
index 1ba731e7c..000000000
--- a/ejabberd-1.1.2/src/mod_muc/mod_muc_log.erl
+++ /dev/null
@@ -1,749 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_muc_log.erl
-%%% Author : Badlop
-%%% Purpose : MUC room logging
-%%% Created : 12 Mar 2006 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_muc_log).
--author('badlop').
-
--behaviour(gen_server).
--behaviour(gen_mod).
-
-%% API
--export([start_link/2,
- start/2,
- stop/1,
- check_access_log/2,
- add_to_log/5]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--define(T(Text), translate:translate(Lang, Text)).
--define(PROCNAME, ejabberd_mod_muc_log).
--record(room, {jid, title, subject, subject_author, config}).
-
-
--record(state, {host,
- out_dir,
- dir_type,
- css_file,
- access,
- lang,
- timezone,
- top_link}).
-
-%%====================================================================
-%% 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) ->
- 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) ->
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- gen_server:call(Proc, stop),
- supervisor:delete_child(ejabberd_sup, Proc).
-
-add_to_log(Host, Type, Data, Room, Opts) ->
- gen_server:cast(get_proc_name(Host),
- {add_to_log, Type, Data, Room, Opts}).
-
-check_access_log(Host, From) ->
- case catch gen_server:call(get_proc_name(Host),
- {check_access_log, Host, From}) of
- {'EXIT', _Error} ->
- false;
- Res ->
- Res
- end.
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% Description: Initiates the server
-%%--------------------------------------------------------------------
-init([Host, Opts]) ->
- OutDir = gen_mod:get_opt(outdir, Opts, "www/muc"),
- DirType = gen_mod:get_opt(dirtype, Opts, subdirs),
- CSSFile = gen_mod:get_opt(cssfile, Opts, false),
- AccessLog = gen_mod:get_opt(access_log, Opts, muc_admin),
- Timezone = gen_mod:get_opt(timezone, Opts, local),
- Top_link = gen_mod:get_opt(top_link, Opts, {"/", "Home"}),
- Lang = case ejabberd_config:get_local_option({language, Host}) of
- undefined ->
- "";
- L ->
- L
- end,
- {ok, #state{host = Host,
- out_dir = OutDir,
- dir_type = DirType,
- css_file = CSSFile,
- access = AccessLog,
- lang = Lang,
- timezone = Timezone,
- top_link = Top_link}}.
-
-%%--------------------------------------------------------------------
-%% 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({check_access_log, ServerHost, FromJID}, _From, State) ->
- Reply = acl:match_rule(ServerHost, State#state.access, FromJID),
- {reply, Reply, State};
-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({add_to_log, Type, Data, Room, Opts}, State) ->
- case catch add_to_log2(Type, Data, Room, Opts, State) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]);
- _ ->
- ok
- end,
- {noreply, State};
-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(_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) ->
- 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
-%%--------------------------------------------------------------------
-add_to_log2(text, {Nick, Packet}, Room, Opts, State) ->
- case {xml:get_subtag(Packet, "subject"), xml:get_subtag(Packet, "body")} of
- {false, false} ->
- ok;
- {false, SubEl} ->
- Message = {body, xml:get_tag_cdata(SubEl)},
- add_message_to_log(Nick, Message, Room, Opts, State);
- {SubEl, _} ->
- Message = {subject, xml:get_tag_cdata(SubEl)},
- add_message_to_log(Nick, Message, Room, Opts, State)
- end;
-
-add_to_log2(roomconfig_change, _, Room, Opts, State) ->
- add_message_to_log("", roomconfig_change, Room, Opts, State);
-
-add_to_log2(nickchange, {OldNick, NewNick}, Room, Opts, State) ->
- add_message_to_log(NewNick, {nickchange, OldNick}, Room, Opts, State);
-
-add_to_log2(join, Nick, Room, Opts, State) ->
- add_message_to_log(Nick, join, Room, Opts, State);
-
-add_to_log2(leave, {Nick, Reason}, Room, Opts, State) ->
- case Reason of
- "" -> add_message_to_log(Nick, leave, Room, Opts, State);
- _ -> add_message_to_log(Nick, {leave, Reason}, Room, Opts, State)
- end;
-
-add_to_log2(kickban, {Nick, Reason, Code}, Room, Opts, State) ->
- add_message_to_log(Nick, {kickban, Code, Reason}, Room, Opts, State).
-
-
-%%----------------------------------------------------------------------
-%% Core
-
-build_filename_string(TimeStamp, OutDir, RoomJID, DirType) ->
- {{Year, Month, Day}, _Time} = TimeStamp,
-
- % Directory and file names
- {Dir, Filename, Rel} =
- case DirType of
- subdirs ->
- SYear = lists:flatten(io_lib:format("~4..0w", [Year])),
- SMonth = lists:flatten(io_lib:format("~2..0w", [Month])),
- SDay = lists:flatten(io_lib:format("~2..0w", [Day])),
- {filename:join(SYear, SMonth), SDay, "../.."};
- plain ->
- Date = lists:flatten(
- io_lib:format("~4..0w-~2..0w-~2..0w",
- [Year, Month, Day])),
- {"", Date, "."}
- end,
- Fd = filename:join([OutDir, RoomJID, Dir]),
- Fn = filename:join([Fd, Filename ++ ".html"]),
- Fnrel = filename:join([Rel, Dir, Filename ++ ".html"]),
- {Fd, Fn, Fnrel}.
-
-% calculate day before
-get_timestamp_daydiff(TimeStamp, Daydiff) ->
- {Date1, HMS} = TimeStamp,
- Date2 = calendar:gregorian_days_to_date(
- calendar:date_to_gregorian_days(Date1) + Daydiff),
- {Date2, HMS}.
-
-% Try to close the previous day log, if it exists
-close_previous_log(Fn, Images_dir) ->
- case file:read_file_info(Fn) of
- {ok, _} ->
- {ok, F} = file:open(Fn, [append]),
- %fw(F, "<div class=\"legend\">ejabberd/mod_muc log<span class=\"w3c\">"),
- fw(F, "<div class=\"legend\">"),
- fw(F, " <a href=\"http://ejabberd.jabber.ru\"><img style=\"border:0\" src=\"~s/powered-by-ejabberd.png\" alt=\"Powered by ejabberd\"/></a>", [Images_dir]),
- fw(F, " <a href=\"http://www.erlang.org/\"><img style=\"border:0\" src=\"~s/powered-by-erlang.png\" alt=\"Powered by Erlang\"/></a>", [Images_dir]),
- fw(F, "<span class=\"w3c\">"),
- fw(F, " <a href=\"http://validator.w3.org/check?uri=referer\"><img style=\"border:0;width:88px;height:31px\" src=\"~s/valid-xhtml10.png\" alt=\"Valid XHTML 1.0 Transitional\" /></a>", [Images_dir]),
- fw(F, " <a href=\"http://jigsaw.w3.org/css-validator/\"><img style=\"border:0;width:88px;height:31px\" src=\"~s/vcss.png\" alt=\"Valid CSS!\"/></a>", [Images_dir]),
- fw(F, "</span></div></body></html>"),
- file:close(F);
- _ -> ok
- end.
-
-add_message_to_log(Nick1, Message, RoomJID, Opts, State) ->
- Nick = htmlize(Nick1),
- #state{out_dir = OutDir,
- dir_type = DirType,
- css_file = CSSFile,
- lang = Lang,
- timezone = Timezone,
- top_link = TopLink} = State,
- Room = get_room_info(RoomJID, Opts),
-
- TimeStamp = case Timezone of
- local -> calendar:now_to_local_time(now());
- universal -> calendar:now_to_universal_time(now())
- end,
- {Fd, Fn, _Dir} = build_filename_string(TimeStamp, OutDir, Room#room.jid, DirType),
- {Date, Time} = TimeStamp,
-
- % Open file, create if it does not exist, create parent dirs if needed
- case file:read_file_info(Fn) of
- {ok, _} ->
- {ok, F} = file:open(Fn, [append]);
- {error, enoent} ->
- make_dir_rec(Fd),
- {ok, F} = file:open(Fn, [append]),
- Datestring = get_dateweek(Date, Lang),
-
- TimeStampYesterday = get_timestamp_daydiff(TimeStamp, -1),
- {_FdYesterday, FnYesterday, DatePrev} =
- build_filename_string(
- TimeStampYesterday, OutDir, Room#room.jid, DirType),
-
- TimeStampTomorrow = get_timestamp_daydiff(TimeStamp, 1),
- {_FdTomorrow, _FnTomorrow, DateNext} =
- build_filename_string(
- TimeStampTomorrow, OutDir, Room#room.jid, DirType),
-
- HourOffset = calc_hour_offset(TimeStamp),
- put_header(F, Room, Datestring, CSSFile, Lang,
- HourOffset, DatePrev, DateNext, TopLink),
-
- Images_dir = filename:join([OutDir, "images"]),
- file:make_dir(Images_dir),
- create_image_files(Images_dir),
- Images_url = case DirType of
- subdirs -> "../../../images";
- plain -> "../images"
- end,
- close_previous_log(FnYesterday, Images_url)
- end,
-
- % Build message
- Text = case Message of
- roomconfig_change ->
- RoomConfig = roomconfig_to_string(Room#room.config, Lang),
- put_room_config(F, RoomConfig, Lang),
- io_lib:format("<font class=\"mrcm\">~s</font><br/>",
- [?T("Chatroom configuration modified")]);
- join ->
- io_lib:format("<font class=\"mj\">~s ~s</font><br/>",
- [Nick, ?T("joins the room")]);
- leave ->
- io_lib:format("<font class=\"ml\">~s ~s</font><br/>",
- [Nick, ?T("leaves the room")]);
- {leave, Reason} ->
- io_lib:format("<font class=\"ml\">~s ~s: ~s</font><br/>",
- [Nick, ?T("leaves the room"), htmlize(Reason)]);
- {kickban, "307", ""} ->
- io_lib:format("<font class=\"mk\">~s ~s</font><br/>",
- [Nick, ?T("has been kicked")]);
- {kickban, "307", Reason} ->
- io_lib:format("<font class=\"mk\">~s ~s: ~s</font><br/>",
- [Nick, ?T("has been kicked"), htmlize(Reason)]);
- {kickban, "301", ""} ->
- io_lib:format("<font class=\"mb\">~s ~s</font><br/>",
- [Nick, ?T("has been banned")]);
- {kickban, "301", Reason} ->
- io_lib:format("<font class=\"mb\">~s ~s: ~s</font><br/>",
- [Nick, ?T("has been banned"), htmlize(Reason)]);
- {nickchange, OldNick} ->
- io_lib:format("<font class=\"mnc\">~s ~s ~s</font><br/>",
- [OldNick, ?T("is now known as"), Nick]);
- {subject, T} ->
- io_lib:format("<font class=\"msc\">~s~s~s</font><br/>",
- [Nick, ?T(" has set the subject to: "), htmlize(T)]);
- {body, T} ->
- case regexp:first_match(T, "^/me\s") of
- {match, _, _} ->
- io_lib:format("<font class=\"mne\">~s ~s</font><br/>",
- [Nick, string:substr(htmlize(T), 5)]);
- nomatch ->
- io_lib:format("<font class=\"mn\">&lt;~s&gt;</font> ~s<br/>",
- [Nick, htmlize(T)])
- end
- end,
- {Hour, Minute, Second} = Time,
- STime = lists:flatten(
- io_lib:format("~2..0w:~2..0w:~2..0w", [Hour, Minute, Second])),
-
- % Write message
- file:write(F, io_lib:format("<a name=\"~s\" href=\"#~s\" class=\"ts\">[~s]</a> ~s~n",
- [STime, STime, STime, Text])),
-
- % Close file
- file:close(F),
- ok.
-
-
-%%----------------------------------------------------------------------
-%% Utilities
-
-get_dateweek(Date, Lang) ->
- Weekday = case calendar:day_of_the_week(Date) of
- 1 -> ?T("Monday");
- 2 -> ?T("Tuesday");
- 3 -> ?T("Wednesday");
- 4 -> ?T("Thursday");
- 5 -> ?T("Friday");
- 6 -> ?T("Saturday");
- 7 -> ?T("Sunday")
- end,
- {Y, M, D} = Date,
- Month = case M of
- 1 -> ?T("January");
- 2 -> ?T("February");
- 3 -> ?T("March");
- 4 -> ?T("April");
- 5 -> ?T("May");
- 6 -> ?T("June");
- 7 -> ?T("July");
- 8 -> ?T("August");
- 9 -> ?T("September");
- 10 -> ?T("October");
- 11 -> ?T("November");
- 12 -> ?T("December")
- end,
- case Lang of
- "en" -> io_lib:format("~s, ~s ~w, ~w", [Weekday, Month, D, Y]);
- "es" -> io_lib:format("~s ~w de ~s de ~w", [Weekday, D, Month, Y]);
- _ -> io_lib:format("~s, ~w ~s ~w", [Weekday, D, Month, Y])
- end.
-
-make_dir_rec(Dir) ->
- case file:read_file_info(Dir) of
- {ok, _} ->
- ok;
- {error, enoent} ->
- DirS = filename:split(Dir),
- DirR = lists:sublist(DirS, length(DirS)-1),
- make_dir_rec(filename:join(DirR)),
- file:make_dir(Dir)
- end.
-
-
-% {ok, F1}=file:open("valid-xhtml10.png", [read]).
-% {ok, F1b}=file:read(F1, 1000000).
-% c("../../ejabberd/src/jlib.erl").
-% jlib:encode_base64(F1b).
-
-image_base64("powered-by-erlang.png") ->
- "iVBORw0KGgoAAAANSUhEUgAAAGUAAAAfCAYAAAD+xQNoAAADN0lEQVRo3u1a"
- "P0waURz+rjGRRQ+nUyRCYmJyDPTapDARaSIbTUjt1gVSh8ZW69aBAR0cWLSx"
- "CXWp59LR1jbdqKnGxoQuRZZrSYyHEVM6iZMbHewROA7u3fHvkr5vOn737vcu"
- "33ffu9/vcQz+gef5Cij6CkmSGABgFEH29r5SVvqIsTEOHo8HkiQxDBXEOjg9"
- "PcHc3BxuUSqsI8jR0REAUFGsCCoKFYWCBAN6AxyO0Z7cyMXFb6oGqSgAsIrJ"
- "ut9hMQlvdNbUhKWshLd3HtTF4jihShgVpRaBxKKmIGX5HL920/hz/BM2+zAm"
- "pn2YioQaxnECj0BiEYcrG0Tzzc8/rfudSm02jaVSm9Vr1MdG8rSKKXlJ7lHr"
- "fjouCut2IrC82BDPbe/gc+xlXez7KxEz63H4lmIN473Rh8Si1BKhRY6aEJI8"
- "pLmbjSPN0xOnBBILmg5RC6Lg28preKOzsNmHG8R1Bf0o7GdMucUslDy1pJLG"
- "2sndVVG0lq3c9vum4zmBR1kuwiYMN5ybmCYXxQg57ThFOTYznzpPO+IQi+IK"
- "+jXjg/YhuIJ+cIIHg+wQJoJ+2N3jYN3Olvk4ge/IU98spne+FfGtlslm16nn"
- "a8fduntfDscoVjGJqUgIjz686ViFUdjP4N39x9Xq638viZVtlq2tLXKncLf5"
- "ticuZSWU5XOUshJKxxKtfdtdvs4OyNb/68urKvlluYizgwwu5SLK8jllu1t9"
- "ihYOlzdwdpBBKSvh+vKKzHkCj1JW3y1m+hSj13WjqOiJKK0qpXKhSFxJAYBv"
- "KYaZ9TjWRu4SiWi2LyDtb6wghGmn5HfTml16ILGA/G5al2DW7URYTFYrOU7g"
- "icQ020sYqYDM9CbdgqFd4vzHL03JfvLjk6ZgADAVCSEsJvHsdL+utNYrm2uf"
- "ZDVZSkzPKaQkW8kthpyS297BvRdRzR6DdTurJbPy9Ov1K6xr3HBPQuIMowR3"
- "asegUyDuU9SuUG+dmIGyZ0b7FBN9St3WunyC5yMsrVv7uXzRP58s/qKn6C4q"
- "lQoVxVIvd4YBwzBUFKs6ZaD27U9hEdcAN98Sx2IxykafIYrizbfESoB+dd9/"
- "KF/d/wX3cJvREzl1vAAAAABJRU5ErkJggg==";
-
-image_base64("valid-xhtml10.png") ->
- "iVBORw0KGgoAAAANSUhEUgAAAFgAAAAfCAMAAAEjEcpEAAACiFBMVEUAAADe"
- "5+fOezmtra3ejEKlhELvvWO9WlrehELOe3vepaWclHvetVLGc3PerVKcCAj3"
- "vVqUjHOUe1JjlL0xOUpjjL2UAAC91ueMrc7vrVKlvdbW3u+EpcbO3ufO1ucY"
- "WpSMKQi9SiF7e3taWkoQEAiMczkQSoxaUkpzc3O1lEoICACEazEhGAgIAACE"
- "YzFra2utjELWcznGnEr/7+9jY2POazHOYzGta2NShLVrlL05OUqctdacCADG"
- "a2ucAADGpVqUtc61ORg5OTmlUikYGAiUezl7YzEYEAiUczkxMTG9nEqtIRDe"
- "3t4AMXu9lEoQCACMazEAKXspKSmljFrW1ta1jELOzs7n7/fGxsa9pVqEOSkp"
- "Y5xznL29tZxahLXOpVr/99ZrY1L/79ZjUiljSikAOYTvxmMAMYScezmchFqU"
- "czGtlFp7c2utjFqUlJStxt73///39/9Ce61CSkq9xsZznMbW5+9Cc62MjIxC"
- "Qkrv9/fv7/fOzsbnlErWjIz/3mtCORhza1IpIRBzWjH/1mtCMRhzY1L/zmvn"
- "vVpSQiHOpVJrUinntVr3zmOEc1L3xmNaWlq1nFo5QkrGWim1lFoISpRSUlK1"
- "zt4hWpwASoz///////8xa6WUaykAQoxKe61KSkp7nMbWtWPe5+9jWlL39/f3"
- "9/fWrWNCQkLera3nvWPv7+85MRjntWPetVp7c1IxKRCUlHtKORh7a1IxIRCU"
- "jHtaSiHWrVIpIQhzWinvvVpaQiH/1mPWpVKMe1L/zmP/xmNrUiGErc4YGBj/"
- "73PG1ucQWpT/53O9nFoQUpS1SiEQEBC9zt69vb05c6UISoxSUko5a6UICAhS"
- "SkohUpS1tbXetWMAQoSUgD+kAAAA2HRSTlP/////////iP9sSf//dP//////"
- "//////////////////////////////////////////8M////////////ef//"
- "////////////////////////////////////////////////////////////"
- "//////////////////////9d////////////////////////////////////"
- "AP//////////////CP//RP//////////////////////////////////////"
- "//////////////////////9xPp1gAAAFvUlEQVR42pVWi18URRwfy7vsYUba"
- "iqBRBFmICUQGVKcZckQeaRJQUCLeycMSfKGH0uo5NELpIvGQGzokvTTA85VH"
- "KTpbRoeJnPno/p1+M7t3txj20e/Nzu7Ofve7v/k9Zg4Vc+wRQMW0eyLx1ZSA"
- "NeBDxVmxZZSwEUYkGAewm1eIBOMRvhv1UA+q8KXIVuxGdCelFYwxAnxOrxgb"
- "Y8Ti1t4VA0QHYz4x3FnVC8OVLXv9fkKGSWDoW/4lG6VbdtBblesOs+MjmEmz"
- "JKNIJWFEfEQTCWNPFKvcKEymjLO1b8bwYQd1hCiiDCl5KsrDCIlhj4fSuvcp"
- "fSpgJmyv6dzeZv+nMPx3dhbt94II07/JZliEtm1N2RIYPkTYshwYm245a/zk"
- "WjJwcyFh6ZIcYxxmqiaDSYxhOhFUsqngi3Fzcj3ljdYDNE9uzA1YD/5MhnzW"
- "1KRqF7mYG8jFYXLcfLpjOe2LA0fuGqQrQHl10sdK0sFcFSOSlzF0BgXQH9h3"
- "QZDBI0ccNEhftjXuippBDD2/eMRiETmwwNEYHyqhdDyo22w+3QHuNbdve5a7"
- "eOkHmDVJ0ixNmfbz1h0qo/Q6GuSB2wQJQbpOjOQAl7woWSRJ0m2ewhvAOUiY"
- "YtZtaZL0CZZmtmVOQttLfr/dbveLZodrfrL7W75wG/JjqkQxoNTtNsTKELQp"
- "QL6/D5loaSmyTT8TUhsmi8iFA0hZiyltf7OiNKdarRm5w2So2lTNdPLuIzR+"
- "AiLj8VTRJaj0LmX4VhJ27f/VJV/yycilWPOrk8NkXi7Qqmj5bHqVZlJKZIRk"
- "1wFzKrt0WUbnXMPJ1fk4TJ5oWBA61p1V76DeIs0MX+s3GxRlA1vtw83KhgNp"
- "hc1nyErLO5zcvbOsrq+scbZnpzc6QVFPenLwGxmC+BOfYI+DN55QYddh4Q/N"
- "E/yGYYj4TOGNngQavAZnzzTovEA+kcMJ+247uYexNA+4Fsvjmuv662jsWxPZ"
- "x2xg890bYMYnTgya7bjmCiEY0qgJ0vMF3c+NoFdPyzxz6V3Uxs3AOWCDchRv"
- "OsQtBrbFsrT2fhHEc7ByGzu/dA4IO0A3HdfeP9yMqAwP6NPEb6cbwn0PWVU1"
- "7/FDBQh/CPIrbfcg027IZrsAT/Bf3FNWyn9RSR4cvvwn3e4HFmYPDl/thYcR"
- "Vi8qPEoXVUWBl6FTBFTtnqmKKg5wnlF4wZ1yeLv7TiwXKektE+iDBNicWEyL"
- "pnFhfDkpJc3q2khSPyQBbE0dMJnOoDzTwGsI7cdyMkL5gWqUjCF6Txst/twx"
- "Cv1WzzHoy21ZDQ1xnuDzdPDWR4knr14v0tYn3IxaMFFdiMOlEOJHw1jOQ4sW"
- "t5rQopRkXZhMEi7pmeDCVWBlfUKwhMZ7rsF6elKsvbwiKxgxIdewa3ErsaYo"
- "mCVZFYJb0GUu3JqGUNoplBxYiYby8vLBFWef+Cri4/I1sbQ/1OtYTrNtdXS+"
- "rSe7kQ52eSObL99/iErCWUjCy5W4JLygmCouGfG9x9fmx17XhBuDCaOerbt5"
- "38erta7TFktLvdHghZcCbcPQO33zIJG9kxF5hoVXnzTzRz0r5js8oTj6uyPk"
- "GRf346HOLcasgFexueNUWFPtuFKzjoSFYYedhwVlhsRVYWWJpltv1XPQT1Rl"
- "0bjZIBlb1XujVDzY/Kj4k6Ku3+Z0jo1owjVzDpFTXe1juvBSWNFmNWGZy8Lv"
- "zUl5PN4JCwyNDzbQ0aAj4Zrjz0FatGJJYhvq4j7mGSpvytGFlZtHf2C4o/28"
- "Zu8z7wo7eYPfXysnF0i9NnPh1t1zR7VBb9GqaOXhtTmHQdgMFXE+Z608cnpO"
- "DdZdjL+TuDY44Q38kJXHhccWLoOd9uv1AwwvO+48uu+faCSJPJ1bmy6Thyvp"
- "ivBmYWgjxPDPAp7JTemY/yGKFEiRt/jG/2P79s8KCwoLCgoLC/khUBA5F0Sf"
- "QZ+RYfpNE/4Xosmq7jsZAJsAAAAASUVORK5CYII=";
-
-image_base64("vcss.png") ->
- "iVBORw0KGgoAAAANSUhEUgAAAFgAAAAfCAMAAABUFvrSAAABKVBMVEUAAAAj"
- "Ix8MR51ZVUqAdlmdnZ3ejEWLDAuNjY1kiMG0n2d9fX19Ghfrp1FtbW3y39+3"
- "Ph6lIRNdXV2qJBFcVUhcVUhPT0/dsmpUfLr57+/u7u4/PDWZAACZAADOp1Gd"
- "GxG+SyTgvnNdSySzk16+mkuxw+BOS0BOS0DOzs7MzMy4T09RRDwsJBG+vr73"
- "wV6fkG6eCQRFcLSurq6/X1+ht9nXfz5sepHuwV59ZTHetFjQ2+wMCQQ2ZK5t"
- "WCsmWajsz8+Sq9NMPh4hVaY8MRj///////////////////////9MTEyOp9Lu"
- "8vhXU1A8PDyjOSTBz+YLRJ2rLy8sLCwXTaKujEUcHByDn82dfz7/zGafDw+f"
- "Dw+zRSlzlMcMDAyNcji1tbXf5vIcFgvATJOjAAAAY3RSTlP/8///////////"
- "//////8A//////P/////ov//8//////////////z///T//////////+i////"
- "//////////8w/////6IA/xAgMP//////////8/////////8w0/////////+z"
- "ehebAAACkUlEQVR42u2VfVPTQBDG19VqC6LY+lKrRIxFQaFSBPuSvhBPF8SI"
- "UZK2J5Yav/+HcO8uZdLqTCsU/nKnyWwvk1/unnt2D9ZmH+8/cMAaTRFy+ng6"
- "9/yiwC/+gy8R3McGv5zHvGJEGAdR4eBgi1IbZwevIEZE24pFtBtzG1Q4AoD5"
- "zvw5pEDcJvIQV/TE3/l+H9GnNJwcdABS5wAbFQLMqI98/UReoAaOTlaJsp0z"
- "aHx7LwZvY0BUR2xpWTzqam0gzY8KGzG4MhBCNGucha4QbpETy+Yk/BP85nt7"
- "34AjpQLTsE4ZFpf/dnkUCglXVNYB+OfUZJHvAqAoa45OeuPgm4+Xjtv7xm4N"
- "7PMV4C61+Mrz3H2WImm3ATiWrAiwZRWcUA5Ej4dgIEMxDv6yxHHcNuAutnjv"
- "2HZ1NeuycoVPh0mwC834zZC9Ao5dkZZKwLVGwT+WdLw0YOZ1saEkUDoT+QGW"
- "KZ0E2xpcrPakVW2KXwyUtYEtlEAj3GXD/fYwrryAdeiyGqidQSw1eqtJcA8c"
- "Zq4zXqhPuCBYE1fKJjh/5X6MwRm9c2xf7WVdLf5oSdt64esVIwVAKC1HJ2ol"
- "i8vj3L0YzC4zjkMagt+arDAs6bApbL1RVlWIqrJbreqKZmh4y6VR7rAJeUYD"
- "VRj9VqRXkErpJ9lbEwtE83KlIfeG4p52t7zWIMO1XcaGz54uUyet+hBM7BXX"
- "DS8Xc5+8Gmmbu1xwSoGIokA3oTptQecQ4Iimm/Ew7jwbPfMi3TM91T9XVIGo"
- "+W9xC8oWpugVCXLuwXijjxJ3r/6PjX7nlFua8QmyM+TO/Gja2TTc2Z95C5ua"
- "ewGH6cJi6bJO6Z+TY276eH3tbgy+/3ly3Js+rj66osG/AV5htgaQ9SeRAAAA"
- "AElFTkSuQmCC";
-
-image_base64("powered-by-ejabberd.png") ->
- "iVBORw0KGgoAAAANSUhEUgAAAGUAAAAfCAMAAADJG/NaAAAAw1BMVEUAAAAj"
- "BgYtBAM5AwFCAAAYGAJNAABcAABIDQ5qAAAoJRV7AACFAAAoKSdJHByLAAAw"
- "Lwk1NQA1MzFJKyo4NxtDQQBEQT5KSCxSTgBSUBlgQ0JYSEpZWQJPUU5hYABb"
- "W0ZiYClcW1poaCVwbQRpaDhzYWNsakhuZ2VrbFZ8dwCEgAB3dnd4d2+OjACD"
- "hYKcmACJi4iQkpWspgCYmJm5swCmqazEwACwsbS4ub3X0QLExsPLyszW1Nnc"
- "3ODm5ugMBwAWAwPHm1IFAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJ"
- "cEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfVCRQOBA7VBkCMAAACcElEQVRI"
- "x72WjXKiMBSFQalIFbNiy1pdrJZaRVYR5deGwPs/VRNBSBB2OjvQO0oYjPfj"
- "5J6bCcdx8i2UldxKcDhk1HbIPwFBF/kHKJfjPSVAyIRHF9rRZ4sUX3EDdWOv"
- "1+u2tESaavpnYTbv9zvd0WwDy3/QcGQXlH5uTxB1l07MJlRpsUei0JF6Qi+O"
- "HyGK7ijXxPklHe/umIllim3iUBMJDIEULxxPP0TVWhhKJoN9fUpdmQLteV8a"
- "DgEAg9gIcTjL4F4L+r4WVKEF+rbJdwYYAoQHY+oQjnGootyKwxapoi73WkyF"
- "FySQBv988naEEp4+YMMec5VUCQDJTscEy7Kc0HsLmqNE7rovDjMpIHHGYeid"
- "Xn4TQcaxMYqP3RV3C8oCl2WvrlSPaNpGZadRnmPGCk8ylM2okAJ4i9TEe1Ke"
- "rsXxSl6jUt5uayiIodirtcKLOaWblj50wiyMv1F9lm9TUDArGAD0FmEpvCUs"
- "VoZy6dW81Fg0aDaHogQa36ekAPG5DDGsbdZrGsrzZUnzvBo1I2tLmuL69kSi"
- "tAweyHKN9b3leDfQMnu3nIIKWfmXnqGVKedJT6QpICbJvf2f8aOsvn68v+k7"
- "/cwUQdPoxaMoRTnKFHNlKsKQphCTOa84u64vpi8bH31CqsbF6lSONRTkTyQG"
- "Arq49/fEvjBwz4eDS2/JpaXRNOoXRD/VmOrDVTJJRIZCTLav3VrqbPvP3vdd"
- "uGEhQJzilncbpSA4F3vsihErO+dayv/sY5/yRE0GDEXCu2VoNiMlo5i+P2Kl"
- "gMEvTNk2eYa5XEyh12Ex17Z8vzQUR3KEPbYd6XG87eC4Ly75RneS5ZYHAAAA"
- "AElFTkSuQmCC".
-
-create_image_files(Images_dir) ->
- Filenames = [
- "powered-by-ejabberd.png",
- "powered-by-erlang.png",
- "valid-xhtml10.png",
- "vcss.png"
- ],
- lists:foreach(
- fun(Filename) ->
- Filename_full = filename:join([Images_dir, Filename]),
- {ok, F} = file:open(Filename_full, [write]),
- Image = jlib:decode_base64(image_base64(Filename)),
- io:format(F, "~s", [Image]),
- file:close(F)
- end,
- Filenames),
- ok.
-
-fw(F, S, O) -> io:format(F, S ++ "~n", O).
-fw(F, S) -> fw(F, S, []).
-
-put_header(F, Room, Date, CSSFile, Lang, Hour_offset, Date_prev, Date_next, Top_link) ->
- fw(F, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"),
- fw(F, "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"~s\" lang=\"~s\">", [Lang, Lang]),
- fw(F, "<head>"),
- fw(F, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"),
- fw(F, "<title>~s - ~s</title>", [htmlize(Room#room.title), Date]),
- put_header_css(F, CSSFile),
- put_header_script(F),
- fw(F, "</head>"),
- fw(F, "<body>"),
- {Top_url, Top_text} = Top_link,
- fw(F, "<div style=\"text-align: right;\"><a style=\"color: #AAAAAA; font-family: monospace; text-decoration: none; font-weight: bold;\" href=\"~s\">~s</a></div>", [Top_url, Top_text]),
- fw(F, "<div class=\"roomtitle\">~s</div>", [htmlize(Room#room.title)]),
- fw(F, "<a class=\"roomjid\" href=\"xmpp:~s?join\">~s</a>", [Room#room.jid, Room#room.jid]),
- fw(F, "<div class=\"logdate\">~s<span class=\"w3c\"><a class=\"nav\" href=\"~s\">&lt;</a> <a class=\"nav\" href=\".\/\">^</a> <a class=\"nav\" href=\"~s\">&gt;</a></span></div>", [Date, Date_prev, Date_next]),
- case {htmlize(Room#room.subject_author), htmlize(Room#room.subject)} of
- {"", ""} -> ok;
- {SuA, Su} -> fw(F, "<div class=\"roomsubject\">~s~s~s</div>", [SuA, ?T(" has set the subject to: "), Su])
- end,
- RoomConfig = roomconfig_to_string(Room#room.config, Lang),
- put_room_config(F, RoomConfig, Lang),
- Time_offset_str = case Hour_offset<0 of
- true -> io_lib:format("~p", [Hour_offset]);
- false -> io_lib:format("+~p", [Hour_offset])
- end,
- fw(F, "<br/><a class=\"ts\">GMT~s</a><br/>", [Time_offset_str]).
-
-put_header_css(F, false) ->
- fw(F, "<style type=\"text/css\">"),
- fw(F, "<!--"),
- fw(F, ".ts {color: #AAAAAA; text-decoration: none;}"),
- fw(F, ".mrcm {color: #009900; font-style: italic; font-weight: bold;}"),
- fw(F, ".msc {color: #009900; font-style: italic; font-weight: bold;}"),
- fw(F, ".mj {color: #009900; font-style: italic;}"),
- fw(F, ".ml {color: #009900; font-style: italic;}"),
- fw(F, ".mk {color: #009900; font-style: italic;}"),
- fw(F, ".mb {color: #009900; font-style: italic;}"),
- fw(F, ".mnc {color: #009900; font-style: italic;}"),
- fw(F, ".mn {color: #0000AA;}"),
- fw(F, ".mne {color: #AA0099;}"),
- fw(F, "a.nav {color: #AAAAAA; font-family: monospace; letter-spacing: 3px; text-decoration: none;}"),
- fw(F, "div.roomtitle {border-bottom: #224466 solid 3pt; margin-left: 20pt;}"),
- fw(F, "div.roomtitle {color: #336699; font-size: 24px; font-weight: bold; font-family: sans-serif; letter-spacing: 3px; text-decoration: none;}"),
- fw(F, "a.roomjid {color: #336699; font-size: 24px; font-weight: bold; font-family: sans-serif; letter-spacing: 3px; margin-left: 20pt; text-decoration: none;}"),
- fw(F, "div.logdate {color: #663399; font-size: 20px; font-weight: bold; font-family: sans-serif; letter-spacing: 2px; border-bottom: #224466 solid 1pt; margin-left:80pt; margin-top:20px;}"),
- fw(F, "div.roomsubject {color: #336699; font-size: 18px; font-family: sans-serif; margin-left: 80pt; margin-bottom: 10px;}"),
- fw(F, "div.rc {color: #336699; font-size: 12px; font-family: sans-serif; margin-left: 50%; text-align: right; background: #f3f6f9; border-bottom: 1px solid #336699; border-right: 4px solid #336699;}"),
- fw(F, "div.rct {font-weight: bold; background: #e3e6e9; padding-right: 10px;}"),
- fw(F, "div.rcos {padding-right: 10px;}"),
- fw(F, "div.rcoe {color: green;}"),
- fw(F, "div.rcod {color: red;}"),
- fw(F, "div.rcoe:after {content: \": v\";}"),
- fw(F, "div.rcod:after {content: \": x\";}"),
- fw(F, "div.rcot:after {}"),
- fw(F, ".legend {width: 100%; margin-top: 30px; border-top: #224466 solid 1pt; padding: 10px 0px 10px 0px; text-align: left; font-family: monospace; letter-spacing: 2px;}"),
- fw(F, ".w3c {position: absolute; right: 10px; width: 60%; text-align: right; font-family: monospace; letter-spacing: 1px;}"),
- fw(F, "//-->"),
- fw(F, "</style>");
-
-put_header_css(F, CSSFile) ->
- fw(F, "<link rel=\"stylesheet\" type=\"text/css\" href=\"~s\" media=\"all\">", [CSSFile]).
-
-put_header_script(F) ->
- fw(F, "<script type=\"text/javascript\">"),
- fw(F, "function sh(e) // Show/Hide an element"),
- fw(F, "{if(document.getElementById(e).style.display=='none')"),
- fw(F, "{document.getElementById(e).style.display='block';}"),
- fw(F, "else {document.getElementById(e).style.display='none';}}"),
- fw(F, "</script>").
-
-put_room_config(F, RoomConfig, Lang) ->
- {_, Now2, _} = now(),
- fw(F, "<div class=\"rc\">"),
- fw(F, "<div class=\"rct\" onclick=\"sh('a~p');return false;\">~s</div>", [Now2, ?T("Room Configuration")]),
- fw(F, "<div class=\"rcos\" id=\"a~p\" style=\"display: none;\" ><br/>~s</div>", [Now2, RoomConfig]),
- fw(F, "</div>").
-
-htmlize(S1) ->
- S2_list = string:tokens(S1, "\n"),
- lists:foldl(
- fun(Si, Res) ->
- Si2 = htmlize2(Si),
- case Res of
- "" -> Si2;
- _ -> Res ++ "<br/>" ++ Si2
- end
- end,
- "",
- S2_list).
-
-htmlize2(S1) ->
- S2 = element(2, regexp:gsub(S1, "\\&", "\\&amp;")),
- S3 = element(2, regexp:gsub(S2, "<", "\\&lt;")),
- S4 = element(2, regexp:gsub(S3, ">", "\\&gt;")),
- S5 = element(2, regexp:gsub(S4, "(http|ftp)://.[^ ]*", "<a href=\"&\">&</a>")),
- S5.
-
-get_room_info(RoomJID, Opts) ->
- Title =
- case lists:keysearch(title, 1, Opts) of
- {value, {_, T}} -> T;
- false -> ""
- end,
- Subject =
- case lists:keysearch(subject, 1, Opts) of
- {value, {_, S}} -> S;
- false -> ""
- end,
- SubjectAuthor =
- case lists:keysearch(subject_author, 1, Opts) of
- {value, {_, SA}} -> SA;
- false -> ""
- end,
- #room{jid = jlib:jid_to_string(RoomJID),
- title = Title,
- subject = Subject,
- subject_author = SubjectAuthor,
- config = Opts
- }.
-
-roomconfig_to_string(Options, Lang) ->
- % Get title, if available
- Title = case lists:keysearch(title, 1, Options) of
- {value, Tuple} -> [Tuple];
- false -> []
- end,
-
- % Remove title from list
- Os1 = lists:keydelete(title, 1, Options),
-
- % Order list
- Os2 = lists:sort(Os1),
-
- % Add title to ordered list
- Options2 = Title ++ Os2,
-
- lists:foldl(
- fun({Opt, Val}, R) ->
- case get_roomconfig_text(Opt) of
- undefined ->
- R;
- OptT ->
- OptText = ?T(OptT),
- R2 = case Val of
- false -> "<div class=\"rcod\">" ++ OptText ++ "</div>";
- true -> "<div class=\"rcoe\">" ++ OptText ++ "</div>";
- "" -> "<div class=\"rcod\">" ++ OptText ++ "</div>";
- T ->
- case Opt of
- password -> "<div class=\"rcoe\">" ++ OptText ++ "</div>";
- title -> "<div class=\"rcot\">" ++ ?T("Room title") ++ ": \"" ++ htmlize(T) ++ "\"</div>";
- _ -> "\"" ++ T ++ "\""
- end
- end,
- R ++ R2
- end
- end,
- "",
- Options2).
-
-get_roomconfig_text(title) -> "Room title";
-get_roomconfig_text(persistent) -> "Make room persistent";
-get_roomconfig_text(public) -> "Make room public searchable";
-get_roomconfig_text(public_list) -> "Make participants list public";
-get_roomconfig_text(password_protected) -> "Make room password protected";
-get_roomconfig_text(password) -> "Password";
-get_roomconfig_text(anonymous) -> "Make room semianonymous";
-get_roomconfig_text(members_only) -> "Make room members-only";
-get_roomconfig_text(moderated) -> "Make room moderated";
-get_roomconfig_text(members_by_default) -> "Default users as participants";
-get_roomconfig_text(allow_change_subj) -> "Allow users to change subject";
-get_roomconfig_text(allow_private_messages) -> "Allow users to send private messages";
-get_roomconfig_text(allow_query_users) -> "Allow users to query other users";
-get_roomconfig_text(allow_user_invites) -> "Allow users to send invites";
-get_roomconfig_text(logging) -> "Enable logging";
-get_roomconfig_text(_) -> undefined.
-
-get_proc_name(Host) -> gen_mod:get_module_proc(Host, ?PROCNAME).
-
-calc_hour_offset(TimeHere) ->
- TimeZero = calendar:now_to_universal_time(now()),
- TimeHereHour = calendar:datetime_to_gregorian_seconds(TimeHere) div 3600,
- TimeZeroHour = calendar:datetime_to_gregorian_seconds(TimeZero) div 3600,
- TimeHereHour - TimeZeroHour.
diff --git a/ejabberd-1.1.2/src/mod_muc/mod_muc_room.erl b/ejabberd-1.1.2/src/mod_muc/mod_muc_room.erl
deleted file mode 100644
index 6c4352d17..000000000
--- a/ejabberd-1.1.2/src/mod_muc/mod_muc_room.erl
+++ /dev/null
@@ -1,2572 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_muc_room.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : MUC room stuff
-%%% Created : 19 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_muc_room).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_fsm).
-
-
-%% External exports
--export([start_link/7,
- start_link/6,
- start/7,
- start/6,
- route/4]).
-
-%% gen_fsm callbacks
--export([init/1,
- normal_state/2,
- handle_event/3,
- handle_sync_event/4,
- handle_info/3,
- terminate/3,
- code_change/4]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--define(SETS, gb_sets).
--define(DICT, dict).
-
--record(lqueue, {queue, len, max}).
-
--record(config, {title = "",
- allow_change_subj = true,
- allow_query_users = true,
- allow_private_messages = true,
- public = true,
- public_list = true,
- persistent = false,
- moderated = false, % TODO
- members_by_default = true,
- members_only = false,
- allow_user_invites = false,
- password_protected = false,
- password = "",
- anonymous = true,
- logging = false
- }).
-
--record(user, {jid,
- nick,
- role,
- last_presence}).
-
--record(state, {room,
- host,
- server_host,
- access,
- jid,
- config = #config{},
- users = ?DICT:new(),
- affiliations = ?DICT:new(),
- history = lqueue_new(20),
- subject = "",
- subject_author = "",
- just_created = false}).
-
-
-%-define(DBGFSM, true).
-
--ifdef(DBGFSM).
--define(FSMOPTS, [{debug, [trace]}]).
--else.
--define(FSMOPTS, []).
--endif.
-
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-start(Host, ServerHost, Access, Room, HistorySize, Creator, Nick) ->
- Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_muc_sup),
- supervisor:start_child(
- Supervisor, [Host, ServerHost, Access, Room, HistorySize, Creator, Nick]).
-
-start(Host, ServerHost, Access, Room, HistorySize, Opts) ->
- Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_muc_sup),
- supervisor:start_child(
- Supervisor, [Host, ServerHost, Access, Room, HistorySize, Opts]).
-
-start_link(Host, ServerHost, Access, Room, HistorySize, Creator, Nick) ->
- gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, HistorySize, Creator, Nick],
- ?FSMOPTS).
-
-start_link(Host, ServerHost, Access, Room, HistorySize, Opts) ->
- gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, HistorySize, Opts],
- ?FSMOPTS).
-
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_fsm
-%%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, StateName, StateData} |
-%% {ok, StateName, StateData, Timeout} |
-%% ignore |
-%% {stop, StopReason}
-%%----------------------------------------------------------------------
-init([Host, ServerHost, Access, Room, HistorySize, Creator, _Nick]) ->
- State = set_affiliation(Creator, owner,
- #state{host = Host,
- server_host = ServerHost,
- access = Access,
- room = Room,
- history = lqueue_new(HistorySize),
- jid = jlib:make_jid(Room, Host, ""),
- just_created = true}),
- {ok, normal_state, State};
-init([Host, ServerHost, Access, Room, HistorySize, Opts]) ->
- State = set_opts(Opts, #state{host = Host,
- server_host = ServerHost,
- access = Access,
- room = Room,
- history = lqueue_new(HistorySize),
- jid = jlib:make_jid(Room, Host, "")}),
- {ok, normal_state, State}.
-
-%%----------------------------------------------------------------------
-%% Func: StateName/2
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-normal_state({route, From, "",
- {xmlelement, "message", Attrs, Els} = Packet},
- StateData) ->
- Lang = xml:get_attr_s("xml:lang", Attrs),
- case is_user_online(From, StateData) of
- true ->
- case xml:get_attr_s("type", Attrs) of
- "groupchat" ->
- {ok, #user{nick = FromNick, role = Role}} =
- ?DICT:find(jlib:jid_tolower(From),
- StateData#state.users),
- if
- (Role == moderator) or (Role == participant) ->
- {NewStateData1, IsAllowed} =
- case check_subject(Packet) of
- false ->
- {StateData, true};
- Subject ->
- case can_change_subject(Role,
- StateData) of
- true ->
- NSD =
- StateData#state{
- subject = Subject,
- subject_author =
- FromNick},
- case (NSD#state.config)#config.persistent of
- true ->
- mod_muc:store_room(
- NSD#state.host,
- NSD#state.room,
- make_opts(NSD));
- _ ->
- ok
- end,
- {NSD, true};
- _ ->
- {StateData, false}
- end
- end,
- case IsAllowed of
- true ->
- lists:foreach(
- fun({_LJID, Info}) ->
- ejabberd_router:route(
- jlib:jid_replace_resource(
- StateData#state.jid,
- FromNick),
- Info#user.jid,
- Packet)
- end,
- ?DICT:to_list(StateData#state.users)),
- NewStateData2 =
- add_message_to_history(FromNick,
- Packet,
- NewStateData1),
- {next_state, normal_state, NewStateData2};
- _ ->
- Err =
- case (StateData#state.config)#config.allow_change_subj of
- true ->
- ?ERRT_FORBIDDEN(
- Lang,
- "Only moderators and participants "
- "are allowed to change subject in this room");
- _ ->
- ?ERRT_FORBIDDEN(
- Lang,
- "Only moderators "
- "are allowed to change subject in this room")
- end,
- ejabberd_router:route(
- StateData#state.jid,
- From,
- jlib:make_error_reply(Packet, Err)),
- {next_state, normal_state, StateData}
- end;
- true ->
- ErrText = "Visitors are not allowed to send messages to all occupants",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_FORBIDDEN(Lang, ErrText)),
- ejabberd_router:route(
- StateData#state.jid,
- From, Err),
- {next_state, normal_state, StateData}
- end;
- "error" ->
- case is_user_online(From, StateData) of
- true ->
- NewState =
- add_user_presence_un(
- From,
- {xmlelement, "presence",
- [{"type", "unavailable"}], []},
- StateData),
- send_new_presence(From, NewState),
- {next_state, normal_state,
- remove_online_user(From, NewState)};
- _ ->
- {next_state, normal_state, StateData}
- end;
- "chat" ->
- ErrText = "It is not allowed to send private messages to the conference",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)),
- ejabberd_router:route(
- StateData#state.jid,
- From, Err),
- {next_state, normal_state, StateData};
- Type when (Type == "") or (Type == "normal") ->
- case check_invitation(From, Els, StateData) of
- error ->
- ErrText = "It is not allowed to send normal messages to the conference",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)),
- ejabberd_router:route(
- StateData#state.jid,
- From, Err),
- {next_state, normal_state, StateData};
- IJID ->
- Config = StateData#state.config,
- case Config#config.members_only of
- true ->
- case get_affiliation(IJID, StateData) of
- none ->
- NSD = set_affiliation(
- IJID,
- member,
- StateData),
- case (NSD#state.config)#config.persistent of
- true ->
- mod_muc:store_room(
- NSD#state.host,
- NSD#state.room,
- make_opts(NSD));
- _ ->
- ok
- end,
- {next_state, normal_state, NSD};
- _ ->
- {next_state, normal_state,
- StateData}
- end;
- false ->
- {next_state, normal_state, StateData}
- end
- end;
- _ ->
- ErrText = "Improper message type",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)),
- ejabberd_router:route(
- StateData#state.jid,
- From, Err),
- {next_state, normal_state, StateData}
- end;
- _ ->
- case xml:get_attr_s("type", Attrs) of
- "error" ->
- ok;
- _ ->
- ErrText = "Only occupants are allowed to send messages to the conference",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)),
- ejabberd_router:route(StateData#state.jid, From, Err)
- end,
- {next_state, normal_state, StateData}
- end;
-
-normal_state({route, From, "",
- {xmlelement, "iq", _Attrs, _Els} = Packet},
- StateData) ->
- case jlib:iq_query_info(Packet) of
- #iq{type = Type, xmlns = XMLNS, lang = Lang, sub_el = SubEl} = IQ when
- (XMLNS == ?NS_MUC_ADMIN) or
- (XMLNS == ?NS_MUC_OWNER) or
- (XMLNS == ?NS_DISCO_INFO) or
- (XMLNS == ?NS_DISCO_ITEMS) ->
- Res1 = case XMLNS of
- ?NS_MUC_ADMIN ->
- process_iq_admin(From, Type, Lang, SubEl, StateData);
- ?NS_MUC_OWNER ->
- process_iq_owner(From, Type, Lang, SubEl, StateData);
- ?NS_DISCO_INFO ->
- process_iq_disco_info(From, Type, Lang, StateData);
- ?NS_DISCO_ITEMS ->
- process_iq_disco_items(From, Type, Lang, StateData)
- end,
- {IQRes, NewStateData} =
- case Res1 of
- {result, Res, SD} ->
- {IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", XMLNS}],
- Res
- }]},
- SD};
- {error, Error} ->
- {IQ#iq{type = error,
- sub_el = [SubEl, Error]},
- StateData}
- end,
- ejabberd_router:route(StateData#state.jid,
- From,
- jlib:iq_to_xml(IQRes)),
- case NewStateData of
- stop ->
- {stop, normal, StateData};
- _ ->
- {next_state, normal_state, NewStateData}
- end;
- reply ->
- {next_state, normal_state, StateData};
- _ ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
- ejabberd_router:route(StateData#state.jid, From, Err),
- {next_state, normal_state, StateData}
- end;
-
-normal_state({route, From, Nick,
- {xmlelement, "presence", Attrs, _Els} = Packet},
- StateData) ->
- Type = xml:get_attr_s("type", Attrs),
- Lang = xml:get_attr_s("xml:lang", Attrs),
- StateData1 =
- case Type of
- "unavailable" ->
- case is_user_online(From, StateData) of
- true ->
- NewState =
- add_user_presence_un(From, Packet, StateData),
- send_new_presence(From, NewState),
- Reason = case xml:get_subtag(Packet, "status") of
- false -> "";
- Status_el -> xml:get_tag_cdata(Status_el)
- end,
- remove_online_user(From, NewState, Reason);
- _ ->
- StateData
- end;
- "error" ->
- case is_user_online(From, StateData) of
- true ->
- NewState =
- add_user_presence_un(
- From,
- {xmlelement, "presence",
- [{"type", "unavailable"}], []},
- StateData),
- send_new_presence(From, NewState),
- remove_online_user(From, NewState);
- _ ->
- StateData
- end;
- "" ->
- case is_user_online(From, StateData) of
- true ->
- case is_nick_change(From, Nick, StateData) of
- true ->
- case {is_nick_exists(Nick, StateData),
- mod_muc:can_use_nick(
- StateData#state.host, From, Nick)} of
- {true, _} ->
- Lang = xml:get_attr_s("xml:lang", Attrs),
- ErrText = "Nickname is already in use by another occupant",
- Err = jlib:make_error_reply(
- Packet,
- ?ERRT_CONFLICT(Lang, ErrText)),
- ejabberd_router:route(
- jlib:jid_replace_resource(
- StateData#state.jid,
- Nick), % TODO: s/Nick/""/
- From, Err),
- StateData;
- {_, false} ->
- ErrText = "Nickname is registered by another person",
- Err = jlib:make_error_reply(
- Packet,
- ?ERRT_CONFLICT(Lang, ErrText)),
- ejabberd_router:route(
- % TODO: s/Nick/""/
- jlib:jid_replace_resource(
- StateData#state.jid,
- Nick),
- From, Err),
- StateData;
- _ ->
- change_nick(From, Nick, StateData)
- end;
- _ ->
- NewState =
- add_user_presence(From, Packet, StateData),
- send_new_presence(From, NewState),
- NewState
- end;
- _ ->
- add_new_user(From, Nick, Packet, StateData)
- end;
- _ ->
- StateData
- end,
- %io:format("STATE1: ~p~n", [?DICT:to_list(StateData#state.users)]),
- %io:format("STATE2: ~p~n", [?DICT:to_list(StateData1#state.users)]),
- case (not (StateData1#state.config)#config.persistent) andalso
- (?DICT:to_list(StateData1#state.users) == []) of
- true ->
- {stop, normal, StateData1};
- _ ->
- {next_state, normal_state, StateData1}
- end;
-
-normal_state({route, From, ToNick,
- {xmlelement, "message", Attrs, _Els} = Packet},
- StateData) ->
- Type = xml:get_attr_s("type", Attrs),
- Lang = xml:get_attr_s("xml:lang", Attrs),
- case Type of
- "error" ->
- case is_user_online(From, StateData) of
- true ->
- NewState =
- add_user_presence_un(
- From,
- {xmlelement, "presence",
- [{"type", "unavailable"}], []},
- StateData),
- send_new_presence(From, NewState),
- {next_state, normal_state,
- remove_online_user(From, NewState)};
- _ ->
- {next_state, normal_state, StateData}
- end;
- _ ->
- case (StateData#state.config)#config.allow_private_messages
- andalso is_user_online(From, StateData) of
- true ->
- case Type of
- "groupchat" ->
- ErrText = "It is not allowed to send private "
- "messages of type \"groupchat\"",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_BAD_REQUEST(Lang, ErrText)),
- ejabberd_router:route(
- jlib:jid_replace_resource(
- StateData#state.jid,
- ToNick),
- From, Err);
- _ ->
- case find_jid_by_nick(ToNick, StateData) of
- false ->
- ErrText = "Recipient is not in the conference room",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_ITEM_NOT_FOUND(Lang, ErrText)),
- ejabberd_router:route(
- jlib:jid_replace_resource(
- StateData#state.jid,
- ToNick),
- From, Err);
- ToJID ->
- {ok, #user{nick = FromNick}} =
- ?DICT:find(jlib:jid_tolower(From),
- StateData#state.users),
- ejabberd_router:route(
- jlib:jid_replace_resource(
- StateData#state.jid,
- FromNick),
- ToJID, Packet)
- end
- end;
- _ ->
- ErrText = "Only occupants are allowed to send messages to the conference",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)),
- ejabberd_router:route(
- jlib:jid_replace_resource(
- StateData#state.jid,
- ToNick),
- From, Err)
- end,
- {next_state, normal_state, StateData}
- end;
-
-normal_state({route, From, ToNick,
- {xmlelement, "iq", Attrs, _Els} = Packet},
- StateData) ->
- Lang = xml:get_attr_s("xml:lang", Attrs),
- case {(StateData#state.config)#config.allow_query_users,
- is_user_online(From, StateData)} of
- {true, true} ->
- case find_jid_by_nick(ToNick, StateData) of
- false ->
- case jlib:iq_query_info(Packet) of
- reply ->
- ok;
- _ ->
- ErrText = "Recipient is not in the conference room",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_ITEM_NOT_FOUND(Lang, ErrText)),
- ejabberd_router:route(
- jlib:jid_replace_resource(
- StateData#state.jid, ToNick),
- From, Err)
- end;
- ToJID ->
- {ok, #user{nick = FromNick}} =
- ?DICT:find(jlib:jid_tolower(From),
- StateData#state.users),
- ejabberd_router:route(
- jlib:jid_replace_resource(StateData#state.jid, FromNick),
- ToJID, Packet)
- end;
- {_, false} ->
- case jlib:iq_query_info(Packet) of
- reply ->
- ok;
- _ ->
- ErrText = "Only occupants are allowed to send queries to the conference",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)),
- ejabberd_router:route(
- jlib:jid_replace_resource(StateData#state.jid, ToNick),
- From, Err)
- end;
- _ ->
- case jlib:iq_query_info(Packet) of
- reply ->
- ok;
- _ ->
- ErrText = "Queries to the conference members are not allowed in this room",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_NOT_ALLOWED(Lang, ErrText)),
- ejabberd_router:route(
- jlib:jid_replace_resource(StateData#state.jid, ToNick),
- From, Err)
- end
- end,
- {next_state, normal_state, StateData};
-
-normal_state(_Event, StateData) ->
- {next_state, normal_state, StateData}.
-
-
-
-%%----------------------------------------------------------------------
-%% Func: handle_event/3
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-handle_event({service_message, Msg}, _StateName, StateData) ->
- MessagePkt = {xmlelement, "message",
- [{"type", "groupchat"}],
- [{xmlelement, "body", [], [{xmlcdata, Msg}]}]},
- lists:foreach(
- fun({_LJID, Info}) ->
- ejabberd_router:route(
- StateData#state.jid,
- Info#user.jid,
- MessagePkt)
- end,
- ?DICT:to_list(StateData#state.users)),
- NSD = add_message_to_history("",
- MessagePkt,
- StateData),
- {next_state, normal_state, NSD};
-
-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({get_disco_item, JID, Lang}, _From, StateName, StateData) ->
- FAffiliation = get_affiliation(JID, StateData),
- FRole = get_role(JID, StateData),
- Tail =
- case ((StateData#state.config)#config.public_list == true) orelse
- (FRole /= none) orelse
- (FAffiliation == admin) orelse
- (FAffiliation == owner) of
- true ->
- Desc = case (StateData#state.config)#config.public of
- true ->
- "";
- _ ->
- translate:translate(Lang, "private, ")
- end,
- Len = length(?DICT:to_list(StateData#state.users)),
- " (" ++ Desc ++ integer_to_list(Len) ++ ")";
- _ ->
- ""
- end,
- Reply = case ((StateData#state.config)#config.public == true) orelse
- (FRole /= none) orelse
- (FAffiliation == admin) orelse
- (FAffiliation == owner) of
- true ->
- {item, get_title(StateData) ++ Tail};
- _ ->
- false
- end,
- {reply, Reply, StateName, StateData};
-handle_sync_event(_Event, _From, StateName, StateData) ->
- Reply = ok,
- {reply, Reply, StateName, StateData}.
-
-code_change(_OldVsn, StateName, StateData, _Extra) ->
- {ok, StateName, StateData}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/3
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-handle_info(_Info, StateName, StateData) ->
- {next_state, StateName, StateData}.
-
-%%----------------------------------------------------------------------
-%% Func: terminate/3
-%% Purpose: Shutdown the fsm
-%% Returns: any
-%%----------------------------------------------------------------------
-terminate(_Reason, _StateName, StateData) ->
- mod_muc:room_destroyed(StateData#state.host, StateData#state.room,
- StateData#state.server_host),
- ok.
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-
-route(Pid, From, ToNick, Packet) ->
- gen_fsm:send_event(Pid, {route, From, ToNick, Packet}).
-
-
-is_user_online(JID, StateData) ->
- LJID = jlib:jid_tolower(JID),
- ?DICT:is_key(LJID, StateData#state.users).
-
-role_to_list(Role) ->
- case Role of
- moderator -> "moderator";
- participant -> "participant";
- visitor -> "visitor";
- none -> "none"
- end.
-
-affiliation_to_list(Affiliation) ->
- case Affiliation of
- owner -> "owner";
- admin -> "admin";
- member -> "member";
- outcast -> "outcast";
- none -> "none"
- end.
-
-list_to_role(Role) ->
- case Role of
- "moderator" -> moderator;
- "participant" -> participant;
- "visitor" -> visitor;
- "none" -> none
- end.
-
-list_to_affiliation(Affiliation) ->
- case Affiliation of
- "owner" -> owner;
- "admin" -> admin;
- "member" -> member;
- "outcast" -> outcast;
- "none" -> none
- end.
-
-
-
-set_affiliation(JID, Affiliation, StateData) ->
- LJID = jlib:jid_remove_resource(jlib:jid_tolower(JID)),
- Affiliations = case Affiliation of
- none ->
- ?DICT:erase(LJID,
- StateData#state.affiliations);
- _ ->
- ?DICT:store(LJID,
- Affiliation,
- StateData#state.affiliations)
- end,
- StateData#state{affiliations = Affiliations}.
-
-set_affiliation_and_reason(JID, Affiliation, Reason, StateData) ->
- LJID = jlib:jid_remove_resource(jlib:jid_tolower(JID)),
- Affiliations = case Affiliation of
- none ->
- ?DICT:erase(LJID,
- StateData#state.affiliations);
- _ ->
- ?DICT:store(LJID,
- {Affiliation, Reason},
- StateData#state.affiliations)
- end,
- StateData#state{affiliations = Affiliations}.
-
-get_affiliation(JID, StateData) ->
- {_AccessRoute, _AccessCreate, AccessAdmin} = StateData#state.access,
- Res =
- case acl:match_rule(StateData#state.server_host, AccessAdmin, JID) of
- allow ->
- owner;
- _ ->
- LJID = jlib:jid_tolower(JID),
- case ?DICT:find(LJID, StateData#state.affiliations) of
- {ok, Affiliation} ->
- Affiliation;
- _ ->
- LJID1 = jlib:jid_remove_resource(LJID),
- case ?DICT:find(LJID1, StateData#state.affiliations) of
- {ok, Affiliation} ->
- Affiliation;
- _ ->
- LJID2 = setelement(1, LJID, ""),
- case ?DICT:find(LJID2, StateData#state.affiliations) of
- {ok, Affiliation} ->
- Affiliation;
- _ ->
- LJID3 = jlib:jid_remove_resource(LJID2),
- case ?DICT:find(LJID3, StateData#state.affiliations) of
- {ok, Affiliation} ->
- Affiliation;
- _ ->
- none
- end
- end
- end
- end
- end,
- case Res of
- {A, _Reason} ->
- A;
- _ ->
- Res
- end.
-
-set_role(JID, Role, StateData) ->
- LJID = jlib:jid_tolower(JID),
- LJIDs = case LJID of
- {U, S, ""} ->
- ?DICT:fold(
- fun(J, _, Js) ->
- case J of
- {U, S, _} ->
- [J | Js];
- _ ->
- Js
- end
- end, [], StateData#state.users);
- _ ->
- case ?DICT:is_key(LJID, StateData#state.users) of
- true ->
- [LJID];
- _ ->
- []
- end
- end,
- Users = case Role of
- none ->
- lists:foldl(fun(J, Us) ->
- ?DICT:erase(J,
- Us)
- end, StateData#state.users, LJIDs);
- _ ->
- lists:foldl(fun(J, Us) ->
- {ok, User} = ?DICT:find(J, Us),
- ?DICT:store(J,
- User#user{role = Role},
- Us)
- end, StateData#state.users, LJIDs)
- end,
- StateData#state{users = Users}.
-
-get_role(JID, StateData) ->
- LJID = jlib:jid_tolower(JID),
- case ?DICT:find(LJID, StateData#state.users) of
- {ok, #user{role = Role}} ->
- Role;
- _ ->
- none
- end.
-
-get_default_role(Affiliation, StateData) ->
- case Affiliation of
- owner -> moderator;
- admin -> moderator;
- member -> participant;
- outcast -> none;
- none ->
- case (StateData#state.config)#config.members_only of
- true ->
- none;
- _ ->
- case (StateData#state.config)#config.members_by_default of
- true ->
- participant;
- _ ->
- visitor
- end
- end
- end.
-
-
-add_online_user(JID, Nick, Role, StateData) ->
- LJID = jlib:jid_tolower(JID),
- Users = ?DICT:store(LJID,
- #user{jid = JID,
- nick = Nick,
- role = Role},
- StateData#state.users),
- add_to_log(join, Nick, StateData),
- StateData#state{users = Users}.
-
-remove_online_user(JID, StateData) ->
- remove_online_user(JID, StateData, "").
-
-remove_online_user(JID, StateData, Reason) ->
- LJID = jlib:jid_tolower(JID),
- {ok, #user{nick = Nick}} =
- ?DICT:find(LJID, StateData#state.users),
- add_to_log(leave, {Nick, Reason}, StateData),
- Users = ?DICT:erase(LJID, StateData#state.users),
- StateData#state{users = Users}.
-
-
-filter_presence({xmlelement, "presence", Attrs, Els}) ->
- FEls = lists:filter(
- fun(El) ->
- case El of
- {xmlcdata, _} ->
- false;
- {xmlelement, _Name1, Attrs1, _Els1} ->
- XMLNS = xml:get_attr_s("xmlns", Attrs1),
- case XMLNS of
- ?NS_MUC ++ _ ->
- false;
- _ ->
- true
- end
- end
- end, Els),
- {xmlelement, "presence", Attrs, FEls}.
-
-
-add_user_presence(JID, Presence, StateData) ->
- LJID = jlib:jid_tolower(JID),
- FPresence = filter_presence(Presence),
- Users =
- ?DICT:update(
- LJID,
- fun(#user{} = User) ->
- User#user{last_presence = FPresence}
- end, StateData#state.users),
- StateData#state{users = Users}.
-
-add_user_presence_un(JID, Presence, StateData) ->
- LJID = jlib:jid_tolower(JID),
- FPresence = filter_presence(Presence),
- Users =
- ?DICT:update(
- LJID,
- fun(#user{} = User) ->
- User#user{last_presence = FPresence,
- role = none}
- end, StateData#state.users),
- StateData#state{users = Users}.
-
-
-is_nick_exists(Nick, StateData) ->
- ?DICT:fold(fun(_, #user{nick = N}, B) ->
- B orelse (N == Nick)
- end, false, StateData#state.users).
-
-find_jid_by_nick(Nick, StateData) ->
- ?DICT:fold(fun(_, #user{jid = JID, nick = N}, R) ->
- case Nick of
- N -> JID;
- _ -> R
- end
- end, false, StateData#state.users).
-
-is_nick_change(JID, Nick, StateData) ->
- LJID = jlib:jid_tolower(JID),
- case Nick of
- "" ->
- false;
- _ ->
- {ok, #user{nick = OldNick}} =
- ?DICT:find(LJID, StateData#state.users),
- Nick /= OldNick
- end.
-
-add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
- Lang = xml:get_attr_s("xml:lang", Attrs),
- case {is_nick_exists(Nick, StateData),
- mod_muc:can_use_nick(StateData#state.host, From, Nick)} of
- {true, _} ->
- ErrText = "Nickname is already in use by another occupant",
- Err = jlib:make_error_reply(Packet, ?ERRT_CONFLICT(Lang, ErrText)),
- ejabberd_router:route(
- % TODO: s/Nick/""/
- jlib:jid_replace_resource(StateData#state.jid, Nick),
- From, Err),
- StateData;
- {_, false} ->
- ErrText = "Nickname is registered by another person",
- Err = jlib:make_error_reply(Packet, ?ERRT_CONFLICT(Lang, ErrText)),
- ejabberd_router:route(
- % TODO: s/Nick/""/
- jlib:jid_replace_resource(StateData#state.jid, Nick),
- From, Err),
- StateData;
- _ ->
- Affiliation = get_affiliation(From, StateData),
- Role = get_default_role(Affiliation, StateData),
- case Role of
- none ->
- Err = jlib:make_error_reply(
- Packet,
- case Affiliation of
- outcast ->
- ErrText = "You have been banned from this room",
- ?ERRT_FORBIDDEN(Lang, ErrText);
- _ ->
- ErrText = "Membership required to enter this room",
- ?ERRT_REGISTRATION_REQUIRED(Lang, ErrText)
- end),
- ejabberd_router:route( % TODO: s/Nick/""/
- jlib:jid_replace_resource(StateData#state.jid, Nick),
- From, Err),
- StateData;
- _ ->
- case check_password(Affiliation, Els, StateData) of
- true ->
- NewState =
- add_user_presence(
- From, Packet,
- add_online_user(From, Nick, Role, StateData)),
- if not (NewState#state.config)#config.anonymous ->
- WPacket = {xmlelement, "message", [{"type", "groupchat"}],
- [{xmlelement, "body", [],
- [{xmlcdata, translate:translate(
- Lang,
- "This room is not anonymous")}]},
- {xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "status", [{"code", "100"}], []}]}]},
- ejabberd_router:route(
- StateData#state.jid,
- From, WPacket);
- true ->
- ok
- end,
- send_existing_presences(From, NewState),
- send_new_presence(From, NewState),
- Shift = count_stanza_shift(Nick, Els, NewState),
- case send_history(From, Shift, NewState) of
- true ->
- ok;
- _ ->
- send_subject(From, Lang, StateData)
- end,
- case NewState#state.just_created of
- true ->
- NewState#state{just_created = false};
- false ->
- NewState
- end;
- nopass ->
- ErrText = "Password required to enter this room",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_NOT_AUTHORIZED(Lang, ErrText)),
- ejabberd_router:route( % TODO: s/Nick/""/
- jlib:jid_replace_resource(
- StateData#state.jid, Nick),
- From, Err),
- StateData;
- _ ->
- ErrText = "Incorrect password",
- Err = jlib:make_error_reply(
- Packet, ?ERRT_NOT_AUTHORIZED(Lang, ErrText)),
- ejabberd_router:route( % TODO: s/Nick/""/
- jlib:jid_replace_resource(
- StateData#state.jid, Nick),
- From, Err),
- StateData
- end
- end
- end.
-
-check_password(owner, _Els, _StateData) ->
- true;
-check_password(_Affiliation, Els, StateData) ->
- case (StateData#state.config)#config.password_protected of
- false ->
- true;
- true ->
- Pass = extract_password(Els),
- case Pass of
- false ->
- nopass;
- _ ->
- case (StateData#state.config)#config.password of
- Pass ->
- true;
- _ ->
- false
- end
- end
- end.
-
-extract_password([]) ->
- false;
-extract_password([{xmlelement, _Name, Attrs, _SubEls} = El | Els]) ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_MUC ->
- case xml:get_subtag(El, "password") of
- false ->
- false;
- SubEl ->
- xml:get_tag_cdata(SubEl)
- end;
- _ ->
- extract_password(Els)
- end;
-extract_password([_ | Els]) ->
- extract_password(Els).
-
-count_stanza_shift(Nick, Els, StateData) ->
- HL = lqueue_to_list(StateData#state.history),
- Since = extract_history(Els, "since"),
- Shift0 = case Since of
- false ->
- 0;
- _ ->
- Sin = calendar:datetime_to_gregorian_seconds(Since),
- count_seconds_shift(Sin, HL)
- end,
- Seconds = extract_history(Els, "seconds"),
- Shift1 = case Seconds of
- false ->
- 0;
- _ ->
- Sec = calendar:datetime_to_gregorian_seconds(
- calendar:now_to_universal_time(now())) - Seconds,
- count_seconds_shift(Sec, HL)
- end,
- MaxStanzas = extract_history(Els, "maxstanzas"),
- Shift2 = case MaxStanzas of
- false ->
- 0;
- _ ->
- count_maxstanzas_shift(MaxStanzas, HL)
- end,
- MaxChars = extract_history(Els, "maxchars"),
- Shift3 = case MaxChars of
- false ->
- 0;
- _ ->
- count_maxchars_shift(Nick, MaxChars, HL)
- end,
- lists:max([Shift0, Shift1, Shift2, Shift3]).
-
-count_seconds_shift(Seconds, HistoryList) ->
- lists:sum(
- lists:map(
- fun({_Nick, _Packet, _HaveSubject, TimeStamp, _Size}) ->
- T = calendar:datetime_to_gregorian_seconds(TimeStamp),
- if
- T < Seconds ->
- 1;
- true ->
- 0
- end
- end, HistoryList)).
-
-count_maxstanzas_shift(MaxStanzas, HistoryList) ->
- S = length(HistoryList) - MaxStanzas,
- if
- S =< 0 ->
- 0;
- true ->
- S
- end.
-
-count_maxchars_shift(Nick, MaxSize, HistoryList) ->
- NLen = string:len(Nick) + 1,
- Sizes = lists:map(
- fun({_Nick, _Packet, _HaveSubject, _TimeStamp, Size}) ->
- Size + NLen
- end, HistoryList),
- calc_shift(MaxSize, Sizes).
-
-calc_shift(MaxSize, Sizes) ->
- Total = lists:sum(Sizes),
- calc_shift(MaxSize, Total, 0, Sizes).
-
-calc_shift(_MaxSize, _Size, Shift, []) ->
- Shift;
-calc_shift(MaxSize, Size, Shift, [S | TSizes]) ->
- if
- MaxSize >= Size ->
- Shift;
- true ->
- calc_shift(MaxSize, Size - S, Shift + 1, TSizes)
- end.
-
-extract_history([], _Type) ->
- false;
-extract_history([{xmlelement, _Name, Attrs, _SubEls} = El | Els], Type) ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_MUC ->
- AttrVal = xml:get_path_s(El,
- [{elem, "history"}, {attr, Type}]),
- case Type of
- "since" ->
- case jlib:datetime_string_to_timestamp(AttrVal) of
- undefined ->
- false;
- TS ->
- calendar:now_to_universal_time(TS)
- end;
- _ ->
- case catch list_to_integer(AttrVal) of
- IntVal when is_integer(IntVal) and (IntVal >= 0) ->
- IntVal;
- _ ->
- false
- end
- end;
- _ ->
- extract_history(Els, Type)
- end;
-extract_history([_ | Els], Type) ->
- extract_history(Els, Type).
-
-
-send_update_presence(JID, StateData) ->
- LJID = jlib:jid_tolower(JID),
- LJIDs = case LJID of
- {U, S, ""} ->
- ?DICT:fold(
- fun(J, _, Js) ->
- case J of
- {U, S, _} ->
- [J | Js];
- _ ->
- Js
- end
- end, [], StateData#state.users);
- _ ->
- case ?DICT:is_key(LJID, StateData#state.users) of
- true ->
- [LJID];
- _ ->
- []
- end
- end,
- lists:foreach(fun(J) ->
- send_new_presence(J, StateData)
- end, LJIDs).
-
-send_new_presence(NJID, StateData) ->
- {ok, #user{jid = RealJID,
- nick = Nick,
- role = Role,
- last_presence = Presence}} =
- ?DICT:find(jlib:jid_tolower(NJID), StateData#state.users),
- Affiliation = get_affiliation(NJID, StateData),
- SAffiliation = affiliation_to_list(Affiliation),
- SRole = role_to_list(Role),
- lists:foreach(
- fun({_LJID, Info}) ->
- ItemAttrs =
- case (Info#user.role == moderator) orelse
- ((StateData#state.config)#config.anonymous == false) of
- true ->
- [{"jid", jlib:jid_to_string(RealJID)},
- {"affiliation", SAffiliation},
- {"role", SRole}];
- _ ->
- [{"affiliation", SAffiliation},
- {"role", SRole}]
- end,
- Status = case StateData#state.just_created of
- true ->
- [{xmlelement, "status", [{"code", "201"}], []}];
- false ->
- []
- end,
- Packet = append_subtags(
- Presence,
- [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "item", ItemAttrs, []} | Status]}]),
- ejabberd_router:route(
- jlib:jid_replace_resource(StateData#state.jid, Nick),
- Info#user.jid,
- Packet)
- end, ?DICT:to_list(StateData#state.users)).
-
-
-send_existing_presences(ToJID, StateData) ->
- LToJID = jlib:jid_tolower(ToJID),
- {ok, #user{jid = RealToJID,
- role = Role}} =
- ?DICT:find(LToJID, StateData#state.users),
- lists:foreach(
- fun({LJID, #user{jid = FromJID,
- nick = FromNick,
- role = FromRole,
- last_presence = Presence
- }}) ->
- case RealToJID of
- FromJID ->
- ok;
- _ ->
- FromAffiliation = get_affiliation(LJID, StateData),
- ItemAttrs =
- case (Role == moderator) orelse
- ((StateData#state.config)#config.anonymous ==
- false) of
- true ->
- [{"jid", jlib:jid_to_string(FromJID)},
- {"affiliation",
- affiliation_to_list(FromAffiliation)},
- {"role", role_to_list(FromRole)}];
- _ ->
- [{"affiliation",
- affiliation_to_list(FromAffiliation)},
- {"role", role_to_list(FromRole)}]
- end,
- Packet = append_subtags(
- Presence,
- [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "item", ItemAttrs, []}]}]),
- ejabberd_router:route(
- jlib:jid_replace_resource(
- StateData#state.jid, FromNick),
- RealToJID,
- Packet)
- end
- end, ?DICT:to_list(StateData#state.users)).
-
-
-append_subtags({xmlelement, Name, Attrs, SubTags1}, SubTags2) ->
- {xmlelement, Name, Attrs, SubTags1 ++ SubTags2}.
-
-
-change_nick(JID, Nick, StateData) ->
- LJID = jlib:jid_tolower(JID),
- {ok, #user{nick = OldNick}} =
- ?DICT:find(LJID, StateData#state.users),
- Users =
- ?DICT:update(
- LJID,
- fun(#user{} = User) ->
- User#user{nick = Nick}
- end, StateData#state.users),
- NewStateData = StateData#state{users = Users},
- send_nick_changing(JID, OldNick, NewStateData),
- add_to_log(nickchange, {OldNick, Nick}, StateData),
- NewStateData.
-
-send_nick_changing(JID, OldNick, StateData) ->
- {ok, #user{jid = RealJID,
- nick = Nick,
- role = Role,
- last_presence = Presence}} =
- ?DICT:find(jlib:jid_tolower(JID), StateData#state.users),
- Affiliation = get_affiliation(JID, StateData),
- SAffiliation = affiliation_to_list(Affiliation),
- SRole = role_to_list(Role),
- lists:foreach(
- fun({_LJID, Info}) ->
- ItemAttrs1 =
- case (Info#user.role == moderator) orelse
- ((StateData#state.config)#config.anonymous == false) of
- true ->
- [{"jid", jlib:jid_to_string(RealJID)},
- {"affiliation", SAffiliation},
- {"role", SRole},
- {"nick", Nick}];
- _ ->
- [{"affiliation", SAffiliation},
- {"role", SRole},
- {"nick", Nick}]
- end,
- ItemAttrs2 =
- case (Info#user.role == moderator) orelse
- ((StateData#state.config)#config.anonymous == false) of
- true ->
- [{"jid", jlib:jid_to_string(RealJID)},
- {"affiliation", SAffiliation},
- {"role", SRole}];
- _ ->
- [{"affiliation", SAffiliation},
- {"role", SRole}]
- end,
- Packet1 =
- {xmlelement, "presence", [{"type", "unavailable"}],
- [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "item", ItemAttrs1, []},
- {xmlelement, "status", [{"code", "303"}], []}]}]},
- Packet2 = append_subtags(
- Presence,
- [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "item", ItemAttrs2, []}]}]),
- ejabberd_router:route(
- jlib:jid_replace_resource(StateData#state.jid, OldNick),
- Info#user.jid,
- Packet1),
- ejabberd_router:route(
- jlib:jid_replace_resource(StateData#state.jid, Nick),
- Info#user.jid,
- Packet2)
- end, ?DICT:to_list(StateData#state.users)).
-
-
-lqueue_new(Max) ->
- #lqueue{queue = queue:new(),
- len = 0,
- max = Max}.
-
-%% If the message queue limit is set to 0, do not store messages.
-lqueue_in(_Item, LQ = #lqueue{max = 0}) ->
- LQ;
-%% Otherwise, rotate messages in the queue store.
-lqueue_in(Item, #lqueue{queue = Q1, len = Len, max = Max}) ->
- Q2 = queue:in(Item, Q1),
- if
- Len >= Max ->
- Q3 = lqueue_cut(Q2, Len - Max + 1),
- #lqueue{queue = Q3, len = Max, max = Max};
- true ->
- #lqueue{queue = Q2, len = Len + 1, max = Max}
- end.
-
-lqueue_cut(Q, 0) ->
- Q;
-lqueue_cut(Q, N) ->
- {_, Q1} = queue:out(Q),
- lqueue_cut(Q1, N - 1).
-
-lqueue_to_list(#lqueue{queue = Q1}) ->
- queue:to_list(Q1).
-
-
-add_message_to_history(FromNick, Packet, StateData) ->
- HaveSubject = case xml:get_subtag(Packet, "subject") of
- false ->
- false;
- _ ->
- true
- end,
- TimeStamp = calendar:now_to_universal_time(now()),
- TSPacket = append_subtags(Packet,
- [jlib:timestamp_to_xml(TimeStamp)]),
- SPacket = jlib:replace_from_to(
- jlib:jid_replace_resource(StateData#state.jid, FromNick),
- StateData#state.jid,
- TSPacket),
- Size = lists:flatlength(xml:element_to_string(SPacket)),
- Q1 = lqueue_in({FromNick, TSPacket, HaveSubject, TimeStamp, Size},
- StateData#state.history),
- add_to_log(text, {FromNick, Packet}, StateData),
- StateData#state{history = Q1}.
-
-send_history(JID, Shift, StateData) ->
- lists:foldl(
- fun({Nick, Packet, HaveSubject, _TimeStamp, _Size}, B) ->
- ejabberd_router:route(
- jlib:jid_replace_resource(StateData#state.jid, Nick),
- JID,
- Packet),
- B or HaveSubject
- end, false, lists:nthtail(Shift, lqueue_to_list(StateData#state.history))).
-
-
-send_subject(JID, Lang, StateData) ->
- case StateData#state.subject_author of
- "" ->
- ok;
- Nick ->
- Subject = StateData#state.subject,
- Packet = {xmlelement, "message", [{"type", "groupchat"}],
- [{xmlelement, "subject", [], [{xmlcdata, Subject}]},
- {xmlelement, "body", [],
- [{xmlcdata,
- Nick ++
- translate:translate(Lang,
- " has set the subject to: ") ++
- Subject}]}]},
- ejabberd_router:route(
- StateData#state.jid,
- JID,
- Packet)
- end.
-
-check_subject(Packet) ->
- case xml:get_subtag(Packet, "subject") of
- false ->
- false;
- SubjEl ->
- xml:get_tag_cdata(SubjEl)
- end.
-
-can_change_subject(Role, StateData) ->
- case (StateData#state.config)#config.allow_change_subj of
- true ->
- (Role == moderator) orelse (Role == participant);
- _ ->
- Role == moderator
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Admin stuff
-
-process_iq_admin(From, set, Lang, SubEl, StateData) ->
- {xmlelement, _, _, Items} = SubEl,
- process_admin_items_set(From, Items, Lang, StateData);
-
-process_iq_admin(From, get, Lang, SubEl, StateData) ->
- case xml:get_subtag(SubEl, "item") of
- false ->
- {error, ?ERR_BAD_REQUEST};
- Item ->
- FAffiliation = get_affiliation(From, StateData),
- FRole = get_role(From, StateData),
- case xml:get_tag_attr("role", Item) of
- false ->
- case xml:get_tag_attr("affiliation", Item) of
- false ->
- {error, ?ERR_BAD_REQUEST};
- {value, StrAffiliation} ->
- case catch list_to_affiliation(StrAffiliation) of
- {'EXIT', _} ->
- {error, ?ERR_BAD_REQUEST};
- SAffiliation ->
- if
- (FAffiliation == owner) or
- (FAffiliation == admin) ->
- Items = items_with_affiliation(
- SAffiliation, StateData),
- {result, Items, StateData};
- true ->
- ErrText = "Administrator privileges required",
- {error, ?ERRT_FORBIDDEN(Lang, ErrText)}
- end
- end
- end;
- {value, StrRole} ->
- case catch list_to_role(StrRole) of
- {'EXIT', _} ->
- {error, ?ERR_BAD_REQUEST};
- SRole ->
- if
- FRole == moderator ->
- Items = items_with_role(SRole, StateData),
- {result, Items, StateData};
- true ->
- ErrText = "Moderator privileges required",
- {error, ?ERRT_FORBIDDEN(Lang, ErrText)}
- end
- end
- end
- end.
-
-
-items_with_role(SRole, StateData) ->
- lists:map(
- fun({_, U}) ->
- user_to_item(U, StateData)
- end, search_role(SRole, StateData)).
-
-items_with_affiliation(SAffiliation, StateData) ->
- lists:map(
- fun({JID, {Affiliation, Reason}}) ->
- {xmlelement, "item",
- [{"affiliation", affiliation_to_list(Affiliation)},
- {"jid", jlib:jid_to_string(JID)}],
- [{xmlelement, "reason", [], [{xmlcdata, Reason}]}]};
- ({JID, Affiliation}) ->
- {xmlelement, "item",
- [{"affiliation", affiliation_to_list(Affiliation)},
- {"jid", jlib:jid_to_string(JID)}],
- []}
- end, search_affiliation(SAffiliation, StateData)).
-
-user_to_item(#user{role = Role,
- nick = Nick,
- jid = JID
- }, StateData) ->
- Affiliation = get_affiliation(JID, StateData),
- {xmlelement, "item",
- [{"role", role_to_list(Role)},
- {"affiliation", affiliation_to_list(Affiliation)},
- {"nick", Nick},
- {"jid", jlib:jid_to_string(JID)}],
- []}.
-
-search_role(Role, StateData) ->
- lists:filter(
- fun({_, #user{role = R}}) ->
- Role == R
- end, ?DICT:to_list(StateData#state.users)).
-
-search_affiliation(Affiliation, StateData) ->
- lists:filter(
- fun({_, A}) ->
- case A of
- {A1, _Reason} ->
- Affiliation == A1;
- _ ->
- Affiliation == A
- end
- end, ?DICT:to_list(StateData#state.affiliations)).
-
-
-process_admin_items_set(UJID, Items, Lang, StateData) ->
- UAffiliation = get_affiliation(UJID, StateData),
- URole = get_role(UJID, StateData),
- case find_changed_items(UJID, UAffiliation, URole, Items, Lang, StateData, []) of
- {result, Res} ->
- NSD =
- lists:foldl(
- fun(E, SD) ->
- case catch (
- case E of
- {JID, role, none, Reason} ->
- catch send_kickban_presence(
- JID, Reason, "307", SD),
- set_role(JID, none, SD);
- {JID, affiliation, none, Reason} ->
- case (SD#state.config)#config.members_only of
- true ->
- catch send_kickban_presence(
- JID, Reason, "321", SD),
- SD1 = set_affiliation(JID, none, SD),
- set_role(JID, none, SD1);
- _ ->
- SD1 = set_affiliation(JID, none, SD),
- send_update_presence(JID, SD1),
- SD1
- end;
- {JID, affiliation, outcast, Reason} ->
- catch send_kickban_presence(
- JID, Reason, "301", SD),
- set_affiliation_and_reason(
- JID, outcast, Reason,
- set_role(JID, none, SD));
- {JID, affiliation, A, _Reason} when
- (A == admin) or (A == owner) ->
- SD1 = set_affiliation(JID, A, SD),
- SD2 = set_role(JID, moderator, SD1),
- send_update_presence(JID, SD2),
- SD2;
- {JID, affiliation, member, _Reason} ->
- SD1 = set_affiliation(
- JID, member, SD),
- SD2 = set_role(JID, participant, SD1),
- send_update_presence(JID, SD2),
- SD2;
- {JID, role, R, _Reason} ->
- SD1 = set_role(JID, R, SD),
- catch send_new_presence(JID, SD1),
- SD1;
- {JID, affiliation, A, _Reason} ->
- SD1 = set_affiliation(JID, A, SD),
- send_update_presence(JID, SD1),
- SD1
- end
- ) of
- {'EXIT', ErrReason} ->
- ?ERROR_MSG("MUC ITEMS SET ERR: ~p~n",
- [ErrReason]),
- SD;
- NSD ->
- NSD
- end
- end, StateData, Res),
- case (NSD#state.config)#config.persistent of
- true ->
- mod_muc:store_room(NSD#state.host, NSD#state.room,
- make_opts(NSD));
- _ ->
- ok
- end,
- {result, [], NSD};
- Err ->
- Err
- end.
-
-
-find_changed_items(_UJID, _UAffiliation, _URole, [], _Lang, _StateData, Res) ->
- {result, Res};
-find_changed_items(UJID, UAffiliation, URole, [{xmlcdata, _} | Items],
- Lang, StateData, Res) ->
- find_changed_items(UJID, UAffiliation, URole, Items, Lang, StateData, Res);
-find_changed_items(UJID, UAffiliation, URole,
- [{xmlelement, "item", Attrs, _Els} = Item | Items],
- Lang, StateData, Res) ->
- TJID = case xml:get_attr("jid", Attrs) of
- {value, S} ->
- case jlib:string_to_jid(S) of
- error ->
- ErrText = io_lib:format(
- translate:translate(
- Lang,
- "JID ~s is invalid"), [S]),
- {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)};
- J ->
- {value, J}
- end;
- _ ->
- case xml:get_attr("nick", Attrs) of
- {value, N} ->
- case find_jid_by_nick(N, StateData) of
- false ->
- ErrText =
- io_lib:format(
- translate:translate(
- Lang,
- "Nickname ~s does not exist in the room"),
- [N]),
- {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)};
- J ->
- {value, J}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end
- end,
- case TJID of
- {value, JID} ->
- TAffiliation = get_affiliation(JID, StateData),
- TRole = get_role(JID, StateData),
- case xml:get_attr("role", Attrs) of
- false ->
- case xml:get_attr("affiliation", Attrs) of
- false ->
- {error, ?ERR_BAD_REQUEST};
- {value, StrAffiliation} ->
- case catch list_to_affiliation(StrAffiliation) of
- {'EXIT', _} ->
- ErrText1 =
- io_lib:format(
- translate:translate(
- Lang,
- "Invalid affiliation: ~s"),
- [StrAffiliation]),
- {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText1)};
- SAffiliation ->
- CanChangeRA =
- case can_change_ra(
- UAffiliation, URole,
- TAffiliation, TRole,
- affiliation, SAffiliation) of
- nothing ->
- nothing;
- true ->
- true;
- check_owner ->
- case search_affiliation(
- owner, StateData) of
- [{OJID, _}] ->
- jlib:jid_remove_resource(OJID) /=
- jlib:jid_tolower(jlib:jid_remove_resource(UJID));
- _ ->
- true
- end;
- _ ->
- false
- end,
- case CanChangeRA of
- nothing ->
- find_changed_items(
- UJID,
- UAffiliation, URole,
- Items, Lang, StateData,
- Res);
- true ->
- find_changed_items(
- UJID,
- UAffiliation, URole,
- Items, Lang, StateData,
- [{jlib:jid_remove_resource(JID),
- affiliation,
- SAffiliation,
- xml:get_path_s(
- Item, [{elem, "reason"},
- cdata])} | Res]);
- false ->
- {error, ?ERR_NOT_ALLOWED}
- end
- end
- end;
- {value, StrRole} ->
- case catch list_to_role(StrRole) of
- {'EXIT', _} ->
- ErrText1 =
- io_lib:format(
- translate:translate(
- Lang,
- "Invalid role: ~s"),
- [StrRole]),
- {error, ?ERRT_BAD_REQUEST(Lang, ErrText1)};
- SRole ->
- CanChangeRA =
- case can_change_ra(
- UAffiliation, URole,
- TAffiliation, TRole,
- role, SRole) of
- nothing ->
- nothing;
- true ->
- true;
- check_owner ->
- case search_affiliation(
- owner, StateData) of
- [{OJID, _}] ->
- jlib:jid_remove_resource(OJID) /=
- jlib:jid_tolower(jlib:jid_remove_resource(UJID));
- _ ->
- true
- end;
- _ ->
- false
- end,
- case CanChangeRA of
- nothing ->
- find_changed_items(
- UJID,
- UAffiliation, URole,
- Items, Lang, StateData,
- Res);
- true ->
- find_changed_items(
- UJID,
- UAffiliation, URole,
- Items, Lang, StateData,
- [{JID, role, SRole,
- xml:get_path_s(
- Item, [{elem, "reason"},
- cdata])} | Res]);
- _ ->
- {error, ?ERR_NOT_ALLOWED}
- end
- end
- end;
- Err ->
- Err
- end;
-find_changed_items(_UJID, _UAffiliation, _URole, _Items,
- _Lang, _StateData, _Res) ->
- {error, ?ERR_BAD_REQUEST}.
-
-
-can_change_ra(_FAffiliation, _FRole,
- TAffiliation, _TRole,
- affiliation, Value)
- when (TAffiliation == Value) ->
- nothing;
-can_change_ra(_FAffiliation, _FRole,
- _TAffiliation, TRole,
- role, Value)
- when (TRole == Value) ->
- nothing;
-can_change_ra(FAffiliation, _FRole,
- outcast, _TRole,
- affiliation, none)
- when (FAffiliation == owner) or (FAffiliation == admin) ->
- true;
-can_change_ra(FAffiliation, _FRole,
- outcast, _TRole,
- affiliation, member)
- when (FAffiliation == owner) or (FAffiliation == admin) ->
- true;
-can_change_ra(owner, _FRole,
- outcast, _TRole,
- affiliation, admin) ->
- true;
-can_change_ra(owner, _FRole,
- outcast, _TRole,
- affiliation, owner) ->
- true;
-can_change_ra(FAffiliation, _FRole,
- none, _TRole,
- affiliation, outcast)
- when (FAffiliation == owner) or (FAffiliation == admin) ->
- true;
-can_change_ra(FAffiliation, _FRole,
- none, _TRole,
- affiliation, member)
- when (FAffiliation == owner) or (FAffiliation == admin) ->
- true;
-can_change_ra(owner, _FRole,
- none, _TRole,
- affiliation, admin) ->
- true;
-can_change_ra(owner, _FRole,
- none, _TRole,
- affiliation, owner) ->
- true;
-can_change_ra(FAffiliation, _FRole,
- member, _TRole,
- affiliation, outcast)
- when (FAffiliation == owner) or (FAffiliation == admin) ->
- true;
-can_change_ra(FAffiliation, _FRole,
- member, _TRole,
- affiliation, none)
- when (FAffiliation == owner) or (FAffiliation == admin) ->
- true;
-can_change_ra(owner, _FRole,
- member, _TRole,
- affiliation, admin) ->
- true;
-can_change_ra(owner, _FRole,
- member, _TRole,
- affiliation, owner) ->
- true;
-can_change_ra(owner, _FRole,
- admin, _TRole,
- affiliation, _Affiliation) ->
- true;
-can_change_ra(owner, _FRole,
- owner, _TRole,
- affiliation, _Affiliation) ->
- check_owner;
-can_change_ra(_FAffiliation, _FRole,
- _TAffiliation, _TRole,
- affiliation, _Value) ->
- false;
-can_change_ra(_FAffiliation, moderator,
- _TAffiliation, visitor,
- role, none) ->
- true;
-can_change_ra(_FAffiliation, moderator,
- _TAffiliation, visitor,
- role, participant) ->
- true;
-can_change_ra(FAffiliation, _FRole,
- _TAffiliation, visitor,
- role, moderator)
- when (FAffiliation == owner) or (FAffiliation == admin) ->
- true;
-can_change_ra(_FAffiliation, moderator,
- _TAffiliation, participant,
- role, none) ->
- true;
-can_change_ra(_FAffiliation, moderator,
- _TAffiliation, participant,
- role, visitor) ->
- true;
-can_change_ra(FAffiliation, _FRole,
- _TAffiliation, participant,
- role, moderator)
- when (FAffiliation == owner) or (FAffiliation == admin) ->
- true;
-can_change_ra(_FAffiliation, _FRole,
- owner, moderator,
- role, visitor) ->
- false;
-can_change_ra(owner, _FRole,
- _TAffiliation, moderator,
- role, visitor) ->
- true;
-can_change_ra(_FAffiliation, _FRole,
- admin, moderator,
- role, visitor) ->
- false;
-can_change_ra(admin, _FRole,
- _TAffiliation, moderator,
- role, visitor) ->
- true;
-can_change_ra(_FAffiliation, _FRole,
- owner, moderator,
- role, participant) ->
- false;
-can_change_ra(owner, _FRole,
- _TAffiliation, moderator,
- role, participant) ->
- true;
-can_change_ra(_FAffiliation, _FRole,
- admin, moderator,
- role, participant) ->
- false;
-can_change_ra(admin, _FRole,
- _TAffiliation, moderator,
- role, participant) ->
- true;
-can_change_ra(_FAffiliation, _FRole,
- _TAffiliation, _TRole,
- role, _Value) ->
- false.
-
-
-send_kickban_presence(JID, Reason, Code, StateData) ->
- LJID = jlib:jid_tolower(JID),
- LJIDs = case LJID of
- {U, S, ""} ->
- ?DICT:fold(
- fun(J, _, Js) ->
- case J of
- {U, S, _} ->
- [J | Js];
- _ ->
- Js
- end
- end, [], StateData#state.users);
- _ ->
- case ?DICT:is_key(LJID, StateData#state.users) of
- true ->
- [LJID];
- _ ->
- []
- end
- end,
- lists:foreach(fun(J) ->
- {ok, #user{nick = Nick}} =
- ?DICT:find(J, StateData#state.users),
- add_to_log(kickban, {Nick, Reason, Code}, StateData),
- send_kickban_presence1(J, Reason, Code, StateData)
- end, LJIDs).
-
-send_kickban_presence1(UJID, Reason, Code, StateData) ->
- {ok, #user{jid = _RealJID,
- nick = Nick}} =
- ?DICT:find(jlib:jid_tolower(UJID), StateData#state.users),
- Affiliation = get_affiliation(UJID, StateData),
- SAffiliation = affiliation_to_list(Affiliation),
- lists:foreach(
- fun({_LJID, Info}) ->
- ItemAttrs = [{"affiliation", SAffiliation},
- {"role", "none"}],
- ItemEls = case Reason of
- "" ->
- [];
- _ ->
- [{xmlelement, "reason", [],
- [{xmlcdata, Reason}]}]
- end,
- Packet = {xmlelement, "presence", [{"type", "unavailable"}],
- [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "item", ItemAttrs, ItemEls},
- {xmlelement, "status", [{"code", Code}], []}]}]},
- ejabberd_router:route(
- jlib:jid_replace_resource(StateData#state.jid, Nick),
- Info#user.jid,
- Packet)
- end, ?DICT:to_list(StateData#state.users)).
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Owner stuff
-
-process_iq_owner(From, set, Lang, SubEl, StateData) ->
- FAffiliation = get_affiliation(From, StateData),
- case FAffiliation of
- owner ->
- {xmlelement, _Name, _Attrs, Els} = SubEl,
- case xml:remove_cdata(Els) of
- [{xmlelement, "x", _Attrs1, _Els1} = XEl] ->
- case {xml:get_tag_attr_s("xmlns", XEl),
- xml:get_tag_attr_s("type", XEl)} of
- {?NS_XDATA, "cancel"} ->
- {result, [], StateData};
- {?NS_XDATA, "submit"} ->
- case check_allowed_log_change(XEl, StateData, From) of
- allow -> set_config(XEl, StateData);
- deny -> {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- [{xmlelement, "destroy", _Attrs1, _Els1} = SubEl1] ->
- destroy_room(SubEl1, StateData);
- Items ->
- process_admin_items_set(From, Items, Lang, StateData)
- end;
- _ ->
- ErrText = "Owner privileges required",
- {error, ?ERRT_FORBIDDEN(Lang, ErrText)}
- end;
-
-process_iq_owner(From, get, Lang, SubEl, StateData) ->
- FAffiliation = get_affiliation(From, StateData),
- case FAffiliation of
- owner ->
- {xmlelement, _Name, _Attrs, Els} = SubEl,
- case xml:remove_cdata(Els) of
- [] ->
- get_config(Lang, StateData, From);
- [Item] ->
- case xml:get_tag_attr("affiliation", Item) of
- false ->
- {error, ?ERR_BAD_REQUEST};
- {value, StrAffiliation} ->
- case catch list_to_affiliation(StrAffiliation) of
- {'EXIT', _} ->
- ErrText =
- io_lib:format(
- translate:translate(
- Lang,
- "Invalid affiliation: ~s"),
- [StrAffiliation]),
- {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)};
- SAffiliation ->
- Items = items_with_affiliation(
- SAffiliation, StateData),
- {result, Items, StateData}
- end
- end;
- _ ->
- {error, ?ERR_FEATURE_NOT_IMPLEMENTED}
- end;
- _ ->
- ErrText = "Owner privileges required",
- {error, ?ERRT_FORBIDDEN(Lang, ErrText)}
- end.
-
-check_allowed_log_change(XEl, StateData, From) ->
- case lists:keymember("muc#roomconfig_enablelogging", 1,
- jlib:parse_xdata_submit(XEl)) of
- false ->
- allow;
- true ->
- mod_muc_log:check_access_log(
- StateData#state.server_host, From)
- end.
-
-
--define(XFIELD(Type, Label, Var, Val),
- {xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
- {"var", Var}],
- [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
-
--define(BOOLXFIELD(Label, Var, Val),
- ?XFIELD("boolean", Label, Var,
- case Val of
- true -> "1";
- _ -> "0"
- end)).
-
--define(STRINGXFIELD(Label, Var, Val),
- ?XFIELD("text-single", Label, Var, Val)).
-
--define(PRIVATEXFIELD(Label, Var, Val),
- ?XFIELD("text-private", Label, Var, Val)).
-
-
-get_config(Lang, StateData, From) ->
- Config = StateData#state.config,
- Res =
- [{xmlelement, "title", [],
- [{xmlcdata, translate:translate(Lang, "Configuration for ") ++
- jlib:jid_to_string(StateData#state.jid)}]},
- {xmlelement, "field", [{"type", "hidden"},
- {"var", "FORM_TYPE"}],
- [{xmlelement, "value", [],
- [{xmlcdata, "http://jabber.org/protocol/muc#roomconfig"}]}]},
- ?STRINGXFIELD("Room title",
- "muc#roomconfig_roomname",
- Config#config.title),
- ?BOOLXFIELD("Make room persistent",
- "muc#roomconfig_persistentroom",
- Config#config.persistent),
- ?BOOLXFIELD("Make room public searchable",
- "muc#roomconfig_publicroom",
- Config#config.public),
- ?BOOLXFIELD("Make participants list public",
- "public_list",
- Config#config.public_list),
- ?BOOLXFIELD("Make room password protected",
- "muc#roomconfig_passwordprotectedroom",
- Config#config.password_protected),
- ?PRIVATEXFIELD("Password",
- "muc#roomconfig_roomsecret",
- case Config#config.password_protected of
- true -> Config#config.password;
- false -> ""
- end),
- {xmlelement, "field",
- [{"type", "list-single"},
- {"label", translate:translate(Lang, "Present real JIDs to")},
- {"var", "muc#roomconfig_whois"}],
- [{xmlelement, "value", [], [{xmlcdata,
- if Config#config.anonymous ->
- "moderators";
- true ->
- "anyone"
- end}]},
- {xmlelement, "option", [{"label", translate:translate(Lang, "moderators only")}],
- [{xmlelement, "value", [], [{xmlcdata, "moderators"}]}]},
- {xmlelement, "option", [{"label", translate:translate(Lang, "anyone")}],
- [{xmlelement, "value", [], [{xmlcdata, "anyone"}]}]}]},
- ?BOOLXFIELD("Make room members-only",
- "muc#roomconfig_membersonly",
- Config#config.members_only),
- ?BOOLXFIELD("Make room moderated",
- "muc#roomconfig_moderatedroom",
- Config#config.moderated),
- ?BOOLXFIELD("Default users as participants",
- "members_by_default",
- Config#config.members_by_default),
- ?BOOLXFIELD("Allow users to change subject",
- "muc#roomconfig_changesubject",
- Config#config.allow_change_subj),
- ?BOOLXFIELD("Allow users to send private messages",
- "allow_private_messages",
- Config#config.allow_private_messages),
- ?BOOLXFIELD("Allow users to query other users",
- "allow_query_users",
- Config#config.allow_query_users),
- ?BOOLXFIELD("Allow users to send invites",
- "muc#roomconfig_allowinvites",
- Config#config.allow_user_invites)
- ] ++
- case mod_muc_log:check_access_log(
- StateData#state.server_host, From) of
- allow ->
- [?BOOLXFIELD(
- "Enable logging",
- "muc#roomconfig_enablelogging",
- Config#config.logging)];
- _ -> []
- end,
- {result, [{xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "You need an x:data capable client to configure room")}]},
- {xmlelement, "x", [{"xmlns", ?NS_XDATA},
- {"type", "form"}],
- Res}],
- StateData}.
-
-
-
-set_config(XEl, StateData) ->
- XData = jlib:parse_xdata_submit(XEl),
- case XData of
- invalid ->
- {error, ?ERR_BAD_REQUEST};
- _ ->
- case set_xoption(XData, StateData#state.config) of
- #config{} = Config ->
- Res = change_config(Config, StateData),
- {result, _, NSD} = Res,
- add_to_log(roomconfig_change, [], NSD),
- Res;
- Err ->
- Err
- end
- end.
-
--define(SET_BOOL_XOPT(Opt, Val),
- case Val of
- "0" -> set_xoption(Opts, Config#config{Opt = false});
- "false" -> set_xoption(Opts, Config#config{Opt = false});
- "1" -> set_xoption(Opts, Config#config{Opt = true});
- "true" -> set_xoption(Opts, Config#config{Opt = true});
- _ -> {error, ?ERR_BAD_REQUEST}
- end).
-
--define(SET_STRING_XOPT(Opt, Val),
- set_xoption(Opts, Config#config{Opt = Val})).
-
-
-set_xoption([], Config) ->
- Config;
-set_xoption([{"muc#roomconfig_roomname", [Val]} | Opts], Config) ->
- ?SET_STRING_XOPT(title, Val);
-set_xoption([{"muc#roomconfig_changesubject", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(allow_change_subj, Val);
-set_xoption([{"allow_query_users", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(allow_query_users, Val);
-set_xoption([{"allow_private_messages", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(allow_private_messages, Val);
-set_xoption([{"muc#roomconfig_publicroom", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(public, Val);
-set_xoption([{"public_list", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(public_list, Val);
-set_xoption([{"muc#roomconfig_persistentroom", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(persistent, Val);
-set_xoption([{"muc#roomconfig_moderatedroom", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(moderated, Val);
-set_xoption([{"members_by_default", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(members_by_default, Val);
-set_xoption([{"muc#roomconfig_membersonly", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(members_only, Val);
-set_xoption([{"muc#roomconfig_allowinvites", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(allow_user_invites, Val);
-set_xoption([{"muc#roomconfig_passwordprotectedroom", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(password_protected, Val);
-set_xoption([{"muc#roomconfig_roomsecret", [Val]} | Opts], Config) ->
- ?SET_STRING_XOPT(password, Val);
-set_xoption([{"anonymous", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(anonymous, Val);
-set_xoption([{"muc#roomconfig_whois", [Val]} | Opts], Config) ->
- case Val of
- "moderators" ->
- ?SET_BOOL_XOPT(anonymous, "1");
- "anyone" ->
- ?SET_BOOL_XOPT(anonymous, "0");
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
-set_xoption([{"muc#roomconfig_enablelogging", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(logging, Val);
-set_xoption([{"FORM_TYPE", _} | Opts], Config) ->
- %% Ignore our FORM_TYPE
- set_xoption(Opts, Config);
-set_xoption([_ | _Opts], _Config) ->
- {error, ?ERR_BAD_REQUEST}.
-
-
-change_config(Config, StateData) ->
- NSD = StateData#state{config = Config},
- case {(StateData#state.config)#config.persistent,
- Config#config.persistent} of
- {_, true} ->
- mod_muc:store_room(NSD#state.host, NSD#state.room, make_opts(NSD));
- {true, false} ->
- mod_muc:forget_room(NSD#state.host, NSD#state.room);
- {false, false} ->
- ok
- end,
- case {(StateData#state.config)#config.members_only,
- Config#config.members_only} of
- {false, true} ->
- NSD1 = remove_nonmembers(NSD),
- {result, [], NSD1};
- _ ->
- {result, [], NSD}
- end.
-
-remove_nonmembers(StateData) ->
- lists:foldl(
- fun({_LJID, #user{jid = JID}}, SD) ->
- Affiliation = get_affiliation(JID, SD),
- case Affiliation of
- none ->
- catch send_kickban_presence(
- JID, "", "322", SD),
- set_role(JID, none, SD);
- _ ->
- SD
- end
- end, StateData, ?DICT:to_list(StateData#state.users)).
-
-
--define(CASE_CONFIG_OPT(Opt),
- Opt -> StateData#state{
- config = (StateData#state.config)#config{Opt = Val}}).
-
-set_opts([], StateData) ->
- StateData;
-set_opts([{Opt, Val} | Opts], StateData) ->
- NSD = case Opt of
- ?CASE_CONFIG_OPT(title);
- ?CASE_CONFIG_OPT(allow_change_subj);
- ?CASE_CONFIG_OPT(allow_query_users);
- ?CASE_CONFIG_OPT(allow_private_messages);
- ?CASE_CONFIG_OPT(public);
- ?CASE_CONFIG_OPT(public_list);
- ?CASE_CONFIG_OPT(persistent);
- ?CASE_CONFIG_OPT(moderated);
- ?CASE_CONFIG_OPT(members_by_default);
- ?CASE_CONFIG_OPT(members_only);
- ?CASE_CONFIG_OPT(allow_user_invites);
- ?CASE_CONFIG_OPT(password_protected);
- ?CASE_CONFIG_OPT(password);
- ?CASE_CONFIG_OPT(anonymous);
- ?CASE_CONFIG_OPT(logging);
- affiliations ->
- StateData#state{affiliations = ?DICT:from_list(Val)};
- subject ->
- StateData#state{subject = Val};
- subject_author ->
- StateData#state{subject_author = Val};
- _ -> StateData
- end,
- set_opts(Opts, NSD).
-
--define(MAKE_CONFIG_OPT(Opt), {Opt, Config#config.Opt}).
-
-make_opts(StateData) ->
- Config = StateData#state.config,
- [
- ?MAKE_CONFIG_OPT(title),
- ?MAKE_CONFIG_OPT(allow_change_subj),
- ?MAKE_CONFIG_OPT(allow_query_users),
- ?MAKE_CONFIG_OPT(allow_private_messages),
- ?MAKE_CONFIG_OPT(public),
- ?MAKE_CONFIG_OPT(public_list),
- ?MAKE_CONFIG_OPT(persistent),
- ?MAKE_CONFIG_OPT(moderated),
- ?MAKE_CONFIG_OPT(members_by_default),
- ?MAKE_CONFIG_OPT(members_only),
- ?MAKE_CONFIG_OPT(allow_user_invites),
- ?MAKE_CONFIG_OPT(password_protected),
- ?MAKE_CONFIG_OPT(password),
- ?MAKE_CONFIG_OPT(anonymous),
- ?MAKE_CONFIG_OPT(logging),
- {affiliations, ?DICT:to_list(StateData#state.affiliations)},
- {subject, StateData#state.subject},
- {subject_author, StateData#state.subject_author}
- ].
-
-
-
-destroy_room(DEl, StateData) ->
- lists:foreach(
- fun({_LJID, Info}) ->
- Nick = Info#user.nick,
- ItemAttrs = [{"affiliation", "none"},
- {"role", "none"}],
- Packet = {xmlelement, "presence", [{"type", "unavailable"}],
- [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
- [{xmlelement, "item", ItemAttrs, []}, DEl]}]},
- ejabberd_router:route(
- jlib:jid_replace_resource(StateData#state.jid, Nick),
- Info#user.jid,
- Packet)
- end, ?DICT:to_list(StateData#state.users)),
- case (StateData#state.config)#config.persistent of
- true ->
- mod_muc:forget_room(StateData#state.host, StateData#state.room);
- false ->
- ok
- end,
- {result, [], stop}.
-
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Disco
-
--define(FEATURE(Var), {xmlelement, "feature", [{"var", Var}], []}).
-
--define(CONFIG_OPT_TO_FEATURE(Opt, Fiftrue, Fiffalse),
- case Opt of
- true ->
- ?FEATURE(Fiftrue);
- false ->
- ?FEATURE(Fiffalse)
- end).
-
-process_iq_disco_info(_From, set, _Lang, _StateData) ->
- {error, ?ERR_NOT_ALLOWED};
-
-process_iq_disco_info(_From, get, Lang, StateData) ->
- Config = StateData#state.config,
- {result, [{xmlelement, "identity",
- [{"category", "conference"},
- {"type", "text"},
- {"name", get_title(StateData)}], []},
- {xmlelement, "feature",
- [{"var", ?NS_MUC}], []},
- ?CONFIG_OPT_TO_FEATURE(Config#config.public,
- "muc_public", "muc_hidden"),
- ?CONFIG_OPT_TO_FEATURE(Config#config.persistent,
- "muc_persistent", "muc_temporary"),
- ?CONFIG_OPT_TO_FEATURE(Config#config.members_only,
- "muc_membersonly", "muc_open"),
- ?CONFIG_OPT_TO_FEATURE(Config#config.anonymous,
- "muc_semianonymous", "muc_nonanonymous"),
- ?CONFIG_OPT_TO_FEATURE(Config#config.moderated,
- "muc_moderated", "muc_unmoderated"),
- ?CONFIG_OPT_TO_FEATURE(Config#config.password_protected,
- "muc_passwordprotected", "muc_unsecured")
- ] ++ iq_disco_info_extras(Lang, StateData), StateData}.
-
--define(RFIELDT(Type, Var, Val),
- {xmlelement, "field", [{"type", Type}, {"var", Var}],
- [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
-
--define(RFIELD(Label, Var, Val),
- {xmlelement, "field", [{"label", translate:translate(Lang, Label)},
- {"var", Var}],
- [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
-
-iq_disco_info_extras(Lang, StateData) ->
- Len = length(?DICT:to_list(StateData#state.users)),
- [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}],
- [?RFIELDT("hidden", "FORM_TYPE",
- "http://jabber.org/protocol/muc#roominfo"),
- ?RFIELD("Description", "muc#roominfo_description",
- (StateData#state.config)#config.title),
- %?RFIELD("Subject", "muc#roominfo_subject", StateData#state.subject),
- ?RFIELD("Number of occupants", "muc#roominfo_occupants",
- integer_to_list(Len))
- ]}].
-
-process_iq_disco_items(_From, set, _Lang, _StateData) ->
- {error, ?ERR_NOT_ALLOWED};
-
-process_iq_disco_items(From, get, _Lang, StateData) ->
- FAffiliation = get_affiliation(From, StateData),
- FRole = get_role(From, StateData),
- case ((StateData#state.config)#config.public_list == true) orelse
- (FRole /= none) orelse
- (FAffiliation == admin) orelse
- (FAffiliation == owner) of
- true ->
- UList =
- lists:map(
- fun({_LJID, Info}) ->
- Nick = Info#user.nick,
- {xmlelement, "item",
- [{"jid", jlib:jid_to_string(
- {StateData#state.room,
- StateData#state.host,
- Nick})},
- {"name", Nick}], []}
- end,
- ?DICT:to_list(StateData#state.users)),
- {result, UList, StateData};
- _ ->
- {error, ?ERR_FORBIDDEN}
- end.
-
-get_title(StateData) ->
- case (StateData#state.config)#config.title of
- "" ->
- StateData#state.room;
- Name ->
- Name
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Invitation support
-
-check_invitation(From, Els, StateData) ->
- FAffiliation = get_affiliation(From, StateData),
- CanInvite = (StateData#state.config)#config.allow_user_invites
- orelse (FAffiliation == admin) orelse (FAffiliation == owner),
- case xml:remove_cdata(Els) of
- [{xmlelement, "x", _Attrs1, Els1} = XEl] ->
- case xml:get_tag_attr_s("xmlns", XEl) of
- ?NS_MUC_USER ->
- case xml:remove_cdata(Els1) of
- [{xmlelement, "invite", Attrs2, _Els2} = InviteEl] ->
- case jlib:string_to_jid(
- xml:get_attr_s("to", Attrs2)) of
- error ->
- error;
- JID ->
- case CanInvite of
- true ->
- Reason =
- xml:get_path_s(
- InviteEl,
- [{elem, "reason"}, cdata]),
- IEl =
- [{xmlelement, "invite",
- [{"from",
- jlib:jid_to_string(From)}],
- [{xmlelement, "reason", [],
- [{xmlcdata, Reason}]}]}],
- PasswdEl =
- case (StateData#state.config)#config.password_protected of
- true ->
- [{xmlelement, "password", [],
- [{xmlcdata, (StateData#state.config)#config.password}]}];
- _ ->
- []
- end,
- Msg =
- {xmlelement, "message",
- [{"type", "normal"}],
- [{xmlelement, "x",
- [{"xmlns", ?NS_MUC_USER}],
- IEl ++ PasswdEl},
- {xmlelement, "x",
- [{"xmlns",
- ?NS_XCONFERENCE},
- {"jid",
- jlib:jid_to_string(
- {StateData#state.room,
- StateData#state.host,
- ""})}],
- [{xmlcdata, Reason}]}]},
- ejabberd_router:route(
- StateData#state.jid,
- JID,
- Msg),
- JID;
- _ ->
- error
- end
- end;
- _ ->
- error
- end;
- _ ->
- error
- end;
- _ ->
- error
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Logging
-
-add_to_log(Type, Data, StateData) ->
- case (StateData#state.config)#config.logging of
- true ->
- mod_muc_log:add_to_log(
- StateData#state.server_host, Type, Data,
- StateData#state.jid, make_opts(StateData));
- false ->
- ok
- end.
diff --git a/ejabberd-1.1.2/src/mod_offline.erl b/ejabberd-1.1.2/src/mod_offline.erl
deleted file mode 100644
index 425406c9d..000000000
--- a/ejabberd-1.1.2/src/mod_offline.erl
+++ /dev/null
@@ -1,390 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_offline.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 5 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_offline).
--author('alexey@sevcom.net').
-
--behaviour(gen_mod).
-
--export([start/2,
- init/0,
- stop/1,
- store_packet/3,
- resend_offline_messages/2,
- pop_offline_messages/3,
- remove_expired_messages/0,
- remove_old_messages/1,
- remove_user/2]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--record(offline_msg, {us, timestamp, expire, from, to, packet}).
-
--define(PROCNAME, ejabberd_offline).
--define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000).
-
-start(Host, _Opts) ->
- mnesia:create_table(offline_msg,
- [{disc_only_copies, [node()]},
- {type, bag},
- {attributes, record_info(fields, offline_msg)}]),
- update_table(),
- ejabberd_hooks:add(offline_message_hook, Host,
- ?MODULE, store_packet, 50),
- ejabberd_hooks:add(resend_offline_messages_hook, Host,
- ?MODULE, pop_offline_messages, 50),
- ejabberd_hooks:add(remove_user, Host,
- ?MODULE, remove_user, 50),
- register(gen_mod:get_module_proc(Host, ?PROCNAME),
- spawn(?MODULE, init, [])).
-
-init() ->
- loop().
-
-loop() ->
- receive
- #offline_msg{} = Msg ->
- Msgs = receive_all([Msg]),
- Len = length(Msgs),
- F = fun() ->
- if
- Len >= ?OFFLINE_TABLE_LOCK_THRESHOLD ->
- mnesia:write_lock_table(offline_msg);
- true ->
- ok
- end,
- lists:foreach(fun(M) ->
- mnesia:write(M)
- end, Msgs)
- end,
- mnesia:transaction(F),
- loop();
- _ ->
- loop()
- end.
-
-receive_all(Msgs) ->
- receive
- #offline_msg{} = Msg ->
- receive_all([Msg | Msgs])
- after 0 ->
- Msgs
- end.
-
-
-stop(Host) ->
- ejabberd_hooks:delete(offline_message_hook, Host,
- ?MODULE, store_packet, 50),
- ejabberd_hooks:delete(resend_offline_messages_hook, Host,
- ?MODULE, pop_offline_messages, 50),
- ejabberd_hooks:delete(remove_user, Host,
- ?MODULE, remove_user, 50),
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- exit(whereis(Proc), stop),
- {wait, Proc}.
-
-store_packet(From, To, Packet) ->
- Type = xml:get_tag_attr_s("type", Packet),
- if
- (Type /= "error") and (Type /= "groupchat") and
- (Type /= "headline") ->
- case check_event(From, To, Packet) of
- true ->
- #jid{luser = LUser, lserver = LServer} = To,
- TimeStamp = now(),
- {xmlelement, _Name, _Attrs, Els} = Packet,
- Expire = find_x_expire(TimeStamp, Els),
- gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) !
- #offline_msg{us = {LUser, LServer},
- timestamp = TimeStamp,
- expire = Expire,
- from = From,
- to = To,
- packet = Packet},
- stop;
- _ ->
- ok
- end;
- true ->
- ok
- end.
-
-check_event(From, To, Packet) ->
- {xmlelement, Name, Attrs, Els} = Packet,
- case find_x_event(Els) of
- false ->
- true;
- El ->
- case xml:get_subtag(El, "id") of
- false ->
- case xml:get_subtag(El, "offline") of
- false ->
- true;
- _ ->
- ID = case xml:get_tag_attr_s("id", Packet) of
- "" ->
- {xmlelement, "id", [], []};
- S ->
- {xmlelement, "id", [],
- [{xmlcdata, S}]}
- end,
- ejabberd_router:route(
- To, From, {xmlelement, Name, Attrs,
- [{xmlelement, "x",
- [{"xmlns", ?NS_EVENT}],
- [ID,
- {xmlelement, "offline", [], []}]}]
- }),
- true
- end;
- _ ->
- false
- end
- end.
-
-find_x_event([]) ->
- false;
-find_x_event([{xmlcdata, _} | Els]) ->
- find_x_event(Els);
-find_x_event([El | Els]) ->
- case xml:get_tag_attr_s("xmlns", El) of
- ?NS_EVENT ->
- El;
- _ ->
- find_x_event(Els)
- end.
-
-find_x_expire(_, []) ->
- never;
-find_x_expire(TimeStamp, [{xmlcdata, _} | Els]) ->
- find_x_expire(TimeStamp, Els);
-find_x_expire(TimeStamp, [El | Els]) ->
- case xml:get_tag_attr_s("xmlns", El) of
- ?NS_EXPIRE ->
- case xml:get_tag_attr_s("seconds", El) of
- Val ->
- case catch list_to_integer(Val) of
- {'EXIT', _} ->
- never;
- Int when Int > 0 ->
- {MegaSecs, Secs, MicroSecs} = TimeStamp,
- S = MegaSecs * 1000000 + Secs + Int,
- MegaSecs1 = S div 1000000,
- Secs1 = S rem 1000000,
- {MegaSecs1, Secs1, MicroSecs};
- _ ->
- never
- end;
- _ ->
- never
- end;
- _ ->
- find_x_expire(TimeStamp, Els)
- end.
-
-
-resend_offline_messages(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- F = fun() ->
- Rs = mnesia:wread({offline_msg, US}),
- mnesia:delete({offline_msg, US}),
- Rs
- end,
- case mnesia:transaction(F) of
- {atomic, Rs} ->
- lists:foreach(
- fun(R) ->
- {xmlelement, Name, Attrs, Els} = R#offline_msg.packet,
- ejabberd_sm !
- {route,
- R#offline_msg.from,
- R#offline_msg.to,
- {xmlelement, Name, Attrs,
- Els ++
- [jlib:timestamp_to_xml(
- calendar:now_to_universal_time(
- R#offline_msg.timestamp))]}}
- end,
- lists:keysort(#offline_msg.timestamp, Rs));
- _ ->
- ok
- end.
-
-pop_offline_messages(Ls, User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- F = fun() ->
- Rs = mnesia:wread({offline_msg, US}),
- mnesia:delete({offline_msg, US}),
- Rs
- end,
- case mnesia:transaction(F) of
- {atomic, Rs} ->
- TS = now(),
- Ls ++ lists:map(
- fun(R) ->
- {xmlelement, Name, Attrs, Els} = R#offline_msg.packet,
- {route,
- R#offline_msg.from,
- R#offline_msg.to,
- {xmlelement, Name, Attrs,
- Els ++
- [jlib:timestamp_to_xml(
- calendar:now_to_universal_time(
- R#offline_msg.timestamp))]}}
- end,
- lists:filter(
- fun(R) ->
- case R#offline_msg.expire of
- never ->
- true;
- TimeStamp ->
- TS < TimeStamp
- end
- end,
- lists:keysort(#offline_msg.timestamp, Rs)));
- _ ->
- Ls
- end.
-
-remove_expired_messages() ->
- TimeStamp = now(),
- F = fun() ->
- mnesia:write_lock_table(offline_msg),
- mnesia:foldl(
- fun(Rec, _Acc) ->
- case Rec#offline_msg.expire of
- never ->
- ok;
- TS ->
- if
- TS < TimeStamp ->
- mnesia:delete_object(Rec);
- true ->
- ok
- end
- end
- end, ok, offline_msg)
- end,
- mnesia:transaction(F).
-
-remove_old_messages(Days) ->
- {MegaSecs, Secs, _MicroSecs} = now(),
- S = MegaSecs * 1000000 + Secs - 60 * 60 * 24 * Days,
- MegaSecs1 = S div 1000000,
- Secs1 = S rem 1000000,
- TimeStamp = {MegaSecs1, Secs1, 0},
- F = fun() ->
- mnesia:write_lock_table(offline_msg),
- mnesia:foldl(
- fun(#offline_msg{timestamp = TS} = Rec, _Acc)
- when TS < TimeStamp ->
- mnesia:delete_object(Rec);
- (_Rec, _Acc) -> ok
- end, ok, offline_msg)
- end,
- mnesia:transaction(F).
-
-remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- F = fun() ->
- mnesia:delete({offline_msg, US})
- end,
- mnesia:transaction(F).
-
-update_table() ->
- Fields = record_info(fields, offline_msg),
- case mnesia:table_info(offline_msg, attributes) of
- Fields ->
- ok;
- [user, timestamp, expire, from, to, packet] ->
- ?INFO_MSG("Converting offline_msg table from "
- "{user, timestamp, expire, from, to, packet} format", []),
- Host = ?MYNAME,
- {atomic, ok} = mnesia:create_table(
- mod_offline_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, offline_msg},
- {attributes, record_info(fields, offline_msg)}]),
- mnesia:transform_table(offline_msg, ignore, Fields),
- F1 = fun() ->
- mnesia:write_lock_table(mod_offline_tmp_table),
- mnesia:foldl(
- fun(#offline_msg{us = U} = R, _) ->
- mnesia:dirty_write(
- mod_offline_tmp_table,
- R#offline_msg{us = {U, Host}})
- end, ok, offline_msg)
- end,
- mnesia:transaction(F1),
- mnesia:clear_table(offline_msg),
- F2 = fun() ->
- mnesia:write_lock_table(offline_msg),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_offline_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_offline_tmp_table);
- [user, timestamp, from, to, packet] ->
- ?INFO_MSG("Converting offline_msg table from "
- "{user, timestamp, from, to, packet} format", []),
- Host = ?MYNAME,
- {atomic, ok} = mnesia:create_table(
- mod_offline_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, offline_msg},
- {attributes, record_info(fields, offline_msg)}]),
- mnesia:transform_table(
- offline_msg,
- fun({_, U, TS, F, T, P}) ->
- {xmlelement, _Name, _Attrs, Els} = P,
- Expire = find_x_expire(TS, Els),
- #offline_msg{us = U,
- timestamp = TS,
- expire = Expire,
- from = F,
- to = T,
- packet = P}
- end, Fields),
- F1 = fun() ->
- mnesia:write_lock_table(mod_offline_tmp_table),
- mnesia:foldl(
- fun(#offline_msg{us = U} = R, _) ->
- mnesia:dirty_write(
- mod_offline_tmp_table,
- R#offline_msg{us = {U, Host}})
- end, ok, offline_msg)
- end,
- mnesia:transaction(F1),
- mnesia:clear_table(offline_msg),
- F2 = fun() ->
- mnesia:write_lock_table(offline_msg),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_offline_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_offline_tmp_table);
- _ ->
- ?INFO_MSG("Recreating offline_msg table", []),
- mnesia:transform_table(offline_msg, ignore, Fields)
- end.
-
diff --git a/ejabberd-1.1.2/src/mod_offline_odbc.erl b/ejabberd-1.1.2/src/mod_offline_odbc.erl
deleted file mode 100644
index e3ac67104..000000000
--- a/ejabberd-1.1.2/src/mod_offline_odbc.erl
+++ /dev/null
@@ -1,236 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_offline_odbc.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 5 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
--module(mod_offline_odbc).
--author('alexey@sevcom.net').
-
--behaviour(gen_mod).
-
--export([start/2,
- init/1,
- stop/1,
- store_packet/3,
- pop_offline_messages/3,
- remove_user/2]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--record(offline_msg, {user, timestamp, expire, from, to, packet}).
-
--define(PROCNAME, ejabberd_offline).
--define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000).
-
-start(Host, _Opts) ->
- ejabberd_hooks:add(offline_message_hook, Host,
- ?MODULE, store_packet, 50),
- ejabberd_hooks:add(resend_offline_messages_hook, Host,
- ?MODULE, pop_offline_messages, 50),
- ejabberd_hooks:add(remove_user, Host,
- ?MODULE, remove_user, 50),
- register(gen_mod:get_module_proc(Host, ?PROCNAME),
- spawn(?MODULE, init, [Host])).
-
-init(Host) ->
- loop(Host).
-
-loop(Host) ->
- receive
- #offline_msg{} = Msg ->
- Msgs = receive_all([Msg]),
- % TODO
- Query = lists:map(
- fun(M) ->
- Username =
- ejabberd_odbc:escape(
- (M#offline_msg.to)#jid.luser),
- From = M#offline_msg.from,
- To = M#offline_msg.to,
- {xmlelement, Name, Attrs, Els} =
- M#offline_msg.packet,
- Attrs2 = jlib:replace_from_to_attrs(
- jlib:jid_to_string(From),
- jlib:jid_to_string(To),
- Attrs),
- Packet = {xmlelement, Name, Attrs2,
- Els ++
- [jlib:timestamp_to_xml(
- calendar:now_to_universal_time(
- M#offline_msg.timestamp))]},
- XML =
- ejabberd_odbc:escape(
- lists:flatten(
- xml:element_to_string(Packet))),
- odbc_queries:add_spool_sql(Username, XML)
- end, Msgs),
- case catch odbc_queries:add_spool(Host, Query) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~n", [Reason]);
- _ ->
- ok
- end,
- loop(Host);
- _ ->
- loop(Host)
- end.
-
-receive_all(Msgs) ->
- receive
- #offline_msg{} = Msg ->
- receive_all([Msg | Msgs])
- after 0 ->
- lists:reverse(Msgs)
- end.
-
-
-stop(Host) ->
- ejabberd_hooks:delete(offline_message_hook, Host,
- ?MODULE, store_packet, 50),
- ejabberd_hooks:delete(resend_offline_messages_hook, Host,
- ?MODULE, pop_offline_messages, 50),
- ejabberd_hooks:delete(remove_user, Host,
- ?MODULE, remove_user, 50),
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- exit(whereis(Proc), stop),
- ok.
-
-store_packet(From, To, Packet) ->
- Type = xml:get_tag_attr_s("type", Packet),
- if
- (Type /= "error") and (Type /= "groupchat") and
- (Type /= "headline") ->
- case check_event(From, To, Packet) of
- true ->
- #jid{luser = LUser} = To,
- TimeStamp = now(),
- {xmlelement, _Name, _Attrs, Els} = Packet,
- Expire = find_x_expire(TimeStamp, Els),
- gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) !
- #offline_msg{user = LUser,
- timestamp = TimeStamp,
- expire = Expire,
- from = From,
- to = To,
- packet = Packet},
- stop;
- _ ->
- ok
- end;
- true ->
- ok
- end.
-
-check_event(From, To, Packet) ->
- {xmlelement, Name, Attrs, Els} = Packet,
- case find_x_event(Els) of
- false ->
- true;
- El ->
- case xml:get_subtag(El, "id") of
- false ->
- case xml:get_subtag(El, "offline") of
- false ->
- true;
- _ ->
- ID = case xml:get_tag_attr_s("id", Packet) of
- "" ->
- {xmlelement, "id", [], []};
- S ->
- {xmlelement, "id", [],
- [{xmlcdata, S}]}
- end,
- ejabberd_router:route(
- To, From, {xmlelement, Name, Attrs,
- [{xmlelement, "x",
- [{"xmlns", ?NS_EVENT}],
- [ID,
- {xmlelement, "offline", [], []}]}]
- }),
- true
- end;
- _ ->
- false
- end
- end.
-
-find_x_event([]) ->
- false;
-find_x_event([{xmlcdata, _} | Els]) ->
- find_x_event(Els);
-find_x_event([El | Els]) ->
- case xml:get_tag_attr_s("xmlns", El) of
- ?NS_EVENT ->
- El;
- _ ->
- find_x_event(Els)
- end.
-
-find_x_expire(_, []) ->
- never;
-find_x_expire(TimeStamp, [{xmlcdata, _} | Els]) ->
- find_x_expire(TimeStamp, Els);
-find_x_expire(TimeStamp, [El | Els]) ->
- case xml:get_tag_attr_s("xmlns", El) of
- ?NS_EXPIRE ->
- case xml:get_tag_attr_s("seconds", El) of
- Val ->
- case catch list_to_integer(Val) of
- {'EXIT', _} ->
- never;
- Int when Int > 0 ->
- {MegaSecs, Secs, MicroSecs} = TimeStamp,
- S = MegaSecs * 1000000 + Secs + Int,
- MegaSecs1 = S div 1000000,
- Secs1 = S rem 1000000,
- {MegaSecs1, Secs1, MicroSecs};
- _ ->
- never
- end;
- _ ->
- never
- end;
- _ ->
- find_x_expire(TimeStamp, Els)
- end.
-
-
-pop_offline_messages(Ls, User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- EUser = ejabberd_odbc:escape(LUser),
- case odbc_queries:get_and_del_spool_msg_t(LServer, EUser) of
- {atomic, {selected, ["username","xml"], Rs}} ->
- Ls ++ lists:flatmap(
- fun({_, XML}) ->
- case xml_stream:parse_element(XML) of
- {error, _Reason} ->
- [];
- El ->
- To = jlib:string_to_jid(
- xml:get_tag_attr_s("to", El)),
- From = jlib:string_to_jid(
- xml:get_tag_attr_s("from", El)),
- if
- (To /= error) and
- (From /= error) ->
- [{route, From, To, El}];
- true ->
- []
- end
- end
- end, Rs);
- _ ->
- Ls
- end.
-
-
-remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- Username = ejabberd_odbc:escape(LUser),
- odbc_queries:del_spool_msg(LServer, Username).
-
diff --git a/ejabberd-1.1.2/src/mod_privacy.erl b/ejabberd-1.1.2/src/mod_privacy.erl
deleted file mode 100644
index db2a78693..000000000
--- a/ejabberd-1.1.2/src/mod_privacy.erl
+++ /dev/null
@@ -1,718 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_privacy.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : jabber:iq:privacy support
-%%% Created : 21 Jul 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_privacy).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_mod).
-
--export([start/2, stop/1,
- process_iq/3,
- process_iq_set/3,
- process_iq_get/4,
- get_user_list/2,
- check_packet/5,
- updated_list/2]).
-
-%-include_lib("mnemosyne/include/mnemosyne.hrl").
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--record(privacy, {us,
- default = none,
- lists = []}).
-
--record(listitem, {type = none,
- value = none,
- action,
- order,
- match_all = false,
- match_iq = false,
- match_message = false,
- match_presence_in = false,
- match_presence_out = false
- }).
-
--record(userlist, {name = none, list = []}).
-
-
-start(Host, Opts) ->
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- mnesia:create_table(privacy, [{disc_copies, [node()]},
- {attributes, record_info(fields, privacy)}]),
- update_table(),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY,
- ?MODULE, process_iq, IQDisc).
-
-stop(Host) ->
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY).
-
-process_iq(From, _To, IQ) ->
- #iq{type = Type, sub_el = SubEl} = IQ,
- #jid{lserver = Server} = From,
- Res =
- case ?MYNAME of
- Server ->
- case Type of
- set ->
- %process_iq_set(From, To, IQ);
- {error, ?ERR_NOT_ALLOWED};
- get ->
- {error, ?ERR_NOT_ALLOWED}
- end;
- _ ->
- {error, ?ERR_NOT_ALLOWED}
- end,
- case Res of
- {result, IQRes} ->
- IQ#iq{type = result, sub_el = IQRes};
- {error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]}
- end.
-
-
-process_iq_get(From, _To, #iq{sub_el = SubEl},
- #userlist{name = Active}) ->
- #jid{luser = LUser, lserver = LServer} = From,
- {xmlelement, _, _, Els} = SubEl,
- case xml:remove_cdata(Els) of
- [] ->
- process_lists_get(LUser, LServer, Active);
- [{xmlelement, Name, Attrs, _SubEls}] ->
- case Name of
- "list" ->
- ListName = xml:get_attr("name", Attrs),
- process_list_get(LUser, LServer, ListName);
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end.
-
-
-process_lists_get(LUser, LServer, Active) ->
- case catch mnesia:dirty_read(privacy, {LUser, LServer}) of
- {'EXIT', _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- [] ->
- {result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]};
- [#privacy{default = Default, lists = Lists}] ->
- case Lists of
- [] ->
- {result, [{xmlelement, "query",
- [{"xmlns", ?NS_PRIVACY}], []}]};
- _ ->
- LItems = lists:map(
- fun({N, _}) ->
- {xmlelement, "list",
- [{"name", N}], []}
- end, Lists),
- DItems =
- case Default of
- none ->
- LItems;
- _ ->
- [{xmlelement, "default",
- [{"name", Default}], []} | LItems]
- end,
- ADItems =
- case Active of
- none ->
- DItems;
- _ ->
- [{xmlelement, "active",
- [{"name", Active}], []} | DItems]
- end,
- {result,
- [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}],
- ADItems}]}
- end
- end.
-
-process_list_get(LUser, LServer, {value, Name}) ->
- case catch mnesia:dirty_read(privacy, {LUser, LServer}) of
- {'EXIT', _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- [] ->
- {error, ?ERR_ITEM_NOT_FOUND};
- %{result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]};
- [#privacy{lists = Lists}] ->
- case lists:keysearch(Name, 1, Lists) of
- {value, {_, List}} ->
- LItems = lists:map(fun item_to_xml/1, List),
- {result,
- [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}],
- [{xmlelement, "list",
- [{"name", Name}], LItems}]}]};
- _ ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end
- end;
-
-process_list_get(_LUser, _LServer, false) ->
- {error, ?ERR_BAD_REQUEST}.
-
-item_to_xml(Item) ->
- Attrs1 = [{"action", action_to_list(Item#listitem.action)},
- {"order", order_to_list(Item#listitem.order)}],
- Attrs2 = case Item#listitem.type of
- none ->
- Attrs1;
- Type ->
- [{"type", type_to_list(Item#listitem.type)},
- {"value", value_to_list(Type, Item#listitem.value)} |
- Attrs1]
- end,
- SubEls = case Item#listitem.match_all of
- true ->
- [];
- false ->
- SE1 = case Item#listitem.match_iq of
- true ->
- [{xmlelement, "iq", [], []}];
- false ->
- []
- end,
- SE2 = case Item#listitem.match_message of
- true ->
- [{xmlelement, "message", [], []} | SE1];
- false ->
- SE1
- end,
- SE3 = case Item#listitem.match_presence_in of
- true ->
- [{xmlelement, "presence-in", [], []} | SE2];
- false ->
- SE2
- end,
- SE4 = case Item#listitem.match_presence_out of
- true ->
- [{xmlelement, "presence-out", [], []} | SE3];
- false ->
- SE3
- end,
- SE4
- end,
- {xmlelement, "item", Attrs2, SubEls}.
-
-
-action_to_list(Action) ->
- case Action of
- allow -> "allow";
- deny -> "deny"
- end.
-
-order_to_list(Order) ->
- integer_to_list(Order).
-
-type_to_list(Type) ->
- case Type of
- jid -> "jid";
- group -> "group";
- subscription -> "subscription"
- end.
-
-value_to_list(Type, Val) ->
- case Type of
- jid -> jlib:jid_to_string(Val);
- group -> Val;
- subscription ->
- case Val of
- both -> "both";
- to -> "to";
- from -> "from";
- none -> "none"
- end
- end.
-
-
-
-list_to_action(S) ->
- case S of
- "allow" -> allow;
- "deny" -> deny
- end.
-
-
-
-process_iq_set(From, _To, #iq{sub_el = SubEl}) ->
- #jid{luser = LUser, lserver = LServer} = From,
- {xmlelement, _, _, Els} = SubEl,
- case xml:remove_cdata(Els) of
- [{xmlelement, Name, Attrs, SubEls}] ->
- ListName = xml:get_attr("name", Attrs),
- case Name of
- "list" ->
- process_list_set(LUser, LServer, ListName,
- xml:remove_cdata(SubEls));
- "active" ->
- process_active_set(LUser, LServer, ListName);
- "default" ->
- process_default_set(LUser, LServer, ListName);
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end.
-
-
-process_default_set(LUser, LServer, {value, Name}) ->
- F = fun() ->
- case mnesia:read({privacy, {LUser, LServer}}) of
- [] ->
- {error, ?ERR_ITEM_NOT_FOUND};
- [#privacy{lists = Lists} = P] ->
- case lists:keymember(Name, 1, Lists) of
- true ->
- mnesia:write(P#privacy{default = Name,
- lists = Lists}),
- {result, []};
- false ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end
- end
- end,
- case mnesia:transaction(F) of
- {atomic, {error, _} = Error} ->
- Error;
- {atomic, {result, _} = Res} ->
- Res;
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end;
-
-process_default_set(LUser, LServer, false) ->
- F = fun() ->
- case mnesia:read({privacy, {LUser, LServer}}) of
- [] ->
- {result, []};
- [R] ->
- mnesia:write(R#privacy{default = none}),
- {result, []}
- end
- end,
- case mnesia:transaction(F) of
- {atomic, {error, _} = Error} ->
- Error;
- {atomic, {result, _} = Res} ->
- Res;
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end.
-
-
-process_active_set(LUser, LServer, {value, Name}) ->
- case catch mnesia:dirty_read(privacy, {LUser, LServer}) of
- [] ->
- {error, ?ERR_ITEM_NOT_FOUND};
- [#privacy{lists = Lists}] ->
- case lists:keysearch(Name, 1, Lists) of
- {value, {_, List}} ->
- {result, [], #userlist{name = Name, list = List}};
- false ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end
- end;
-
-process_active_set(_LUser, _LServer, false) ->
- {result, [], #userlist{}}.
-
-
-
-
-
-
-process_list_set(LUser, LServer, {value, Name}, Els) ->
- case parse_items(Els) of
- false ->
- {error, ?ERR_BAD_REQUEST};
- remove ->
- F =
- fun() ->
- case mnesia:read({privacy, {LUser, LServer}}) of
- [] ->
- {result, []};
- [#privacy{default = Default, lists = Lists} = P] ->
- % TODO: check active
- if
- Name == Default ->
- {error, ?ERR_CONFLICT};
- true ->
- NewLists =
- lists:keydelete(Name, 1, Lists),
- mnesia:write(
- P#privacy{lists = NewLists}),
- {result, []}
- end
- end
- end,
- case mnesia:transaction(F) of
- {atomic, {error, _} = Error} ->
- Error;
- {atomic, {result, _} = Res} ->
- ejabberd_router:route(
- jlib:make_jid(LUser, ?MYNAME, ""),
- jlib:make_jid(LUser, ?MYNAME, ""),
- {xmlelement, "broadcast", [],
- [{privacy_list,
- #userlist{name = Name, list = []},
- Name}]}),
- Res;
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end;
- List ->
- F =
- fun() ->
- case mnesia:wread({privacy, {LUser, LServer}}) of
- [] ->
- NewLists = [{Name, List}],
- mnesia:write(#privacy{us = {LUser, LServer},
- lists = NewLists}),
- {result, []};
- [#privacy{lists = Lists} = P] ->
- NewLists1 = lists:keydelete(Name, 1, Lists),
- NewLists = [{Name, List} | NewLists1],
- mnesia:write(P#privacy{lists = NewLists}),
- {result, []}
- end
- end,
- case mnesia:transaction(F) of
- {atomic, {error, _} = Error} ->
- Error;
- {atomic, {result, _} = Res} ->
- ejabberd_router:route(
- jlib:make_jid(LUser, ?MYNAME, ""),
- jlib:make_jid(LUser, ?MYNAME, ""),
- {xmlelement, "broadcast", [],
- [{privacy_list,
- #userlist{name = Name, list = List},
- Name}]}),
- Res;
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end
- end;
-
-process_list_set(_LUser, _LServer, false, _Els) ->
- {error, ?ERR_BAD_REQUEST}.
-
-
-parse_items([]) ->
- remove;
-parse_items(Els) ->
- parse_items(Els, []).
-
-parse_items([], Res) ->
- lists:reverse(Res);
-parse_items([{xmlelement, "item", Attrs, SubEls} | Els], Res) ->
- Type = xml:get_attr("type", Attrs),
- Value = xml:get_attr("value", Attrs),
- SAction = xml:get_attr("action", Attrs),
- SOrder = xml:get_attr("order", Attrs),
- Action = case catch list_to_action(element(2, SAction)) of
- {'EXIT', _} -> false;
- Val -> Val
- end,
- Order = case catch list_to_integer(element(2, SOrder)) of
- {'EXIT', _} ->
- false;
- IntVal ->
- if
- IntVal >= 0 ->
- IntVal;
- true ->
- false
- end
- end,
- if
- (Action /= false) and (Order /= false) ->
- I1 = #listitem{action = Action, order = Order},
- I2 = case {Type, Value} of
- {{value, T}, {value, V}} ->
- case T of
- "jid" ->
- case jlib:string_to_jid(V) of
- error ->
- false;
- JID ->
- I1#listitem{
- type = jid,
- value = jlib:jid_tolower(JID)}
- end;
- "group" ->
- I1#listitem{type = group,
- value = V};
- "subscription" ->
- case V of
- "none" ->
- I1#listitem{type = subscription,
- value = none};
- "both" ->
- I1#listitem{type = subscription,
- value = both};
- "from" ->
- I1#listitem{type = subscription,
- value = from};
- "to" ->
- I1#listitem{type = subscription,
- value = to};
- _ ->
- false
- end
- end;
- {{value, _}, false} ->
- false;
- _ ->
- I1
- end,
- case I2 of
- false ->
- false;
- _ ->
- case parse_matches(I2, xml:remove_cdata(SubEls)) of
- false ->
- false;
- I3 ->
- parse_items(Els, [I3 | Res])
- end
- end;
- true ->
- false
- end;
-
-parse_items(_, _Res) ->
- false.
-
-
-parse_matches(Item, []) ->
- Item#listitem{match_all = true};
-parse_matches(Item, Els) ->
- parse_matches1(Item, Els).
-
-parse_matches1(Item, []) ->
- Item;
-parse_matches1(Item, [{xmlelement, "message", _, _} | Els]) ->
- parse_matches1(Item#listitem{match_message = true}, Els);
-parse_matches1(Item, [{xmlelement, "iq", _, _} | Els]) ->
- parse_matches1(Item#listitem{match_iq = true}, Els);
-parse_matches1(Item, [{xmlelement, "presence-in", _, _} | Els]) ->
- parse_matches1(Item#listitem{match_presence_in = true}, Els);
-parse_matches1(Item, [{xmlelement, "presence-out", _, _} | Els]) ->
- parse_matches1(Item#listitem{match_presence_out = true}, Els);
-parse_matches1(_Item, [{xmlelement, _, _, _} | _Els]) ->
- false.
-
-
-
-
-
-
-
-get_user_list(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- case catch mnesia:dirty_read(privacy, {LUser, LServer}) of
- [] ->
- #userlist{};
- [#privacy{default = Default, lists = Lists}] ->
- case Default of
- none ->
- #userlist{};
- _ ->
- case lists:keysearch(Default, 1, Lists) of
- {value, {_, List}} ->
- SortedList = lists:keysort(#listitem.order, List),
- #userlist{name = Default, list = SortedList};
- _ ->
- #userlist{}
- end
- end;
- _ ->
- #userlist{}
- end.
-
-
-check_packet(User, Server,
- #userlist{list = List},
- {From, To, {xmlelement, PName, _, _}},
- Dir) ->
- case List of
- [] ->
- allow;
- _ ->
- PType = case PName of
- "message" -> message;
- "iq" -> iq;
- "presence" -> presence
- end,
- case {PType, Dir} of
- {message, in} ->
- LJID = jlib:jid_tolower(From),
- {Subscription, Groups} =
- ejabberd_hooks:run_fold(
- roster_get_jid_info, jlib:nameprep(Server),
- {none, []}, [User, Server, LJID]),
- check_packet_aux(List, message,
- LJID, Subscription, Groups);
- {iq, in} ->
- LJID = jlib:jid_tolower(From),
- {Subscription, Groups} =
- ejabberd_hooks:run_fold(
- roster_get_jid_info, jlib:nameprep(Server),
- {none, []}, [User, Server, LJID]),
- check_packet_aux(List, iq,
- LJID, Subscription, Groups);
- {presence, in} ->
- LJID = jlib:jid_tolower(From),
- {Subscription, Groups} =
- ejabberd_hooks:run_fold(
- roster_get_jid_info, jlib:nameprep(Server),
- {none, []}, [User, Server, LJID]),
- check_packet_aux(List, presence_in,
- LJID, Subscription, Groups);
- {presence, out} ->
- LJID = jlib:jid_tolower(To),
- {Subscription, Groups} =
- ejabberd_hooks:run_fold(
- roster_get_jid_info, jlib:nameprep(Server),
- {none, []}, [User, Server, LJID]),
- check_packet_aux(List, presence_out,
- LJID, Subscription, Groups);
- _ ->
- allow
- end
- end.
-
-check_packet_aux([], _PType, _JID, _Subscription, _Groups) ->
- allow;
-check_packet_aux([Item | List], PType, JID, Subscription, Groups) ->
- #listitem{type = Type, value = Value, action = Action} = Item,
- case is_ptype_match(Item, PType) of
- true ->
- case Type of
- none ->
- Action;
- _ ->
- case is_type_match(Type, Value,
- JID, Subscription, Groups) of
- true ->
- Action;
- false ->
- check_packet_aux(List, PType,
- JID, Subscription, Groups)
- end
- end;
- false ->
- check_packet_aux(List, PType, JID, Subscription, Groups)
- end.
-
-
-is_ptype_match(Item, PType) ->
- case Item#listitem.match_all of
- true ->
- true;
- false ->
- case PType of
- message ->
- Item#listitem.match_message;
- iq ->
- Item#listitem.match_iq;
- presence_in ->
- Item#listitem.match_presence_in;
- presence_out ->
- Item#listitem.match_presence_out
- end
- end.
-
-
-is_type_match(Type, Value, JID, Subscription, Groups) ->
- case Type of
- jid ->
- case Value of
- {"", Server, ""} ->
- case JID of
- {_, Server, _} ->
- true;
- _ ->
- false
- end;
- {User, Server, ""} ->
- case JID of
- {User, Server, _} ->
- true;
- _ ->
- false
- end;
- _ ->
- Value == JID
- end;
- subscription ->
- Value == Subscription;
- group ->
- lists:member(Value, Groups)
- end.
-
-
-updated_list(#userlist{name = OldName} = Old,
- #userlist{name = NewName} = New) ->
- if
- OldName == NewName ->
- New;
- true ->
- Old
- end.
-
-
-
-update_table() ->
- Fields = record_info(fields, privacy),
- case mnesia:table_info(privacy, attributes) of
- Fields ->
- ok;
- [user, default, lists] ->
- ?INFO_MSG("Converting privacy table from "
- "{user, default, lists} format", []),
- Host = ?MYNAME,
- {atomic, ok} = mnesia:create_table(
- mod_privacy_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, privacy},
- {attributes, record_info(fields, privacy)}]),
- mnesia:transform_table(privacy, ignore, Fields),
- F1 = fun() ->
- mnesia:write_lock_table(mod_privacy_tmp_table),
- mnesia:foldl(
- fun(#privacy{us = U} = R, _) ->
- mnesia:dirty_write(
- mod_privacy_tmp_table,
- R#privacy{us = {U, Host}})
- end, ok, privacy)
- end,
- mnesia:transaction(F1),
- mnesia:clear_table(privacy),
- F2 = fun() ->
- mnesia:write_lock_table(privacy),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_privacy_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_privacy_tmp_table);
- _ ->
- ?INFO_MSG("Recreating privacy table", []),
- mnesia:transform_table(privacy, ignore, Fields)
- end.
-
-
diff --git a/ejabberd-1.1.2/src/mod_private.erl b/ejabberd-1.1.2/src/mod_private.erl
deleted file mode 100644
index 6b8925dda..000000000
--- a/ejabberd-1.1.2/src/mod_private.erl
+++ /dev/null
@@ -1,171 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_private.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 16 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_private).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_mod).
-
--export([start/2,
- stop/1,
- process_sm_iq/3,
- remove_user/2]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--record(private_storage, {usns, xml}).
-
-start(Host, Opts) ->
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- mnesia:create_table(private_storage,
- [{disc_only_copies, [node()]},
- {attributes, record_info(fields, private_storage)}]),
- update_table(),
- ejabberd_hooks:add(remove_user, Host,
- ?MODULE, remove_user, 50),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE,
- ?MODULE, process_sm_iq, IQDisc).
-
-stop(Host) ->
- ejabberd_hooks:delete(remove_user, Host,
- ?MODULE, remove_user, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE).
-
-
-process_sm_iq(From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
- #jid{luser = LUser, lserver = LServer} = From,
- case lists:member(LServer, ?MYHOSTS) of
- true ->
- {xmlelement, Name, Attrs, Els} = SubEl,
- case Type of
- set ->
- F = fun() ->
- lists:foreach(
- fun(El) ->
- set_data(LUser, LServer, El)
- end, Els)
- end,
- mnesia:transaction(F),
- IQ#iq{type = result,
- sub_el = [{xmlelement, Name, Attrs, []}]};
- get ->
- case catch get_data(LUser, LServer, Els) of
- {'EXIT', _Reason} ->
- IQ#iq{type = error,
- sub_el = [SubEl,
- ?ERR_INTERNAL_SERVER_ERROR]};
- Res ->
- IQ#iq{type = result,
- sub_el = [{xmlelement, Name, Attrs, Res}]}
- end
- end;
- false ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
- end.
-
-set_data(LUser, LServer, El) ->
- case El of
- {xmlelement, _Name, Attrs, _Els} ->
- XMLNS = xml:get_attr_s("xmlns", Attrs),
- case XMLNS of
- "" ->
- ignore;
- _ ->
- mnesia:write(
- #private_storage{usns = {LUser, LServer, XMLNS},
- xml = El})
- end;
- _ ->
- ignore
- end.
-
-get_data(LUser, LServer, Els) ->
- get_data(LUser, LServer, Els, []).
-
-get_data(_LUser, _LServer, [], Res) ->
- lists:reverse(Res);
-get_data(LUser, LServer, [El | Els], Res) ->
- case El of
- {xmlelement, _Name, Attrs, _} ->
- XMLNS = xml:get_attr_s("xmlns", Attrs),
- case mnesia:dirty_read(private_storage, {LUser, LServer, XMLNS}) of
- [R] ->
- get_data(LUser, LServer, Els,
- [R#private_storage.xml | Res]);
- [] ->
- get_data(LUser, LServer, Els,
- [El | Res])
- end;
- _ ->
- get_data(LUser, LServer, Els, Res)
- end.
-
-
-% TODO: use mnesia:select
-remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- F = fun() ->
- lists:foreach(
- fun({U, S, _} = Key) ->
- if
- (U == LUser) and (S == LServer) ->
- mnesia:delete({private_storage, Key});
- true ->
- ok
- end
- end, mnesia:all_keys(private_storage))
- end,
- mnesia:transaction(F).
-
-
-update_table() ->
- Fields = record_info(fields, private_storage),
- case mnesia:table_info(private_storage, attributes) of
- Fields ->
- ok;
- [userns, xml] ->
- ?INFO_MSG("Converting private_storage table from "
- "{user, default, lists} format", []),
- Host = ?MYNAME,
- {atomic, ok} = mnesia:create_table(
- mod_private_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, private_storage},
- {attributes, record_info(fields, private_storage)}]),
- mnesia:transform_table(private_storage, ignore, Fields),
- F1 = fun() ->
- mnesia:write_lock_table(mod_private_tmp_table),
- mnesia:foldl(
- fun(#private_storage{usns = {U, NS}} = R, _) ->
- mnesia:dirty_write(
- mod_private_tmp_table,
- R#private_storage{usns = {U, Host, NS}})
- end, ok, private_storage)
- end,
- mnesia:transaction(F1),
- mnesia:clear_table(private_storage),
- F2 = fun() ->
- mnesia:write_lock_table(private_storage),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_private_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_private_tmp_table);
- _ ->
- ?INFO_MSG("Recreating private_storage table", []),
- mnesia:transform_table(private_storage, ignore, Fields)
- end.
-
-
diff --git a/ejabberd-1.1.2/src/mod_pubsub/Makefile.in b/ejabberd-1.1.2/src/mod_pubsub/Makefile.in
deleted file mode 100644
index e007294e0..000000000
--- a/ejabberd-1.1.2/src/mod_pubsub/Makefile.in
+++ /dev/null
@@ -1,29 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@ @ERLANG_CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@ @ERLANG_LIBS@
-
-SUBDIRS =
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-OBJS = \
- $(OUTDIR)/mod_pubsub.beam
-
-all: $(OBJS)
-
-$(OUTDIR)/%.beam: %.erl
- @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-clean:
- rm -f $(OBJS)
-
-distclean: clean
- rm -f Makefile
-
-TAGS:
- etags *.erl
-
diff --git a/ejabberd-1.1.2/src/mod_pubsub/Makefile.win32 b/ejabberd-1.1.2/src/mod_pubsub/Makefile.win32
deleted file mode 100644
index bb44dd778..000000000
--- a/ejabberd-1.1.2/src/mod_pubsub/Makefile.win32
+++ /dev/null
@@ -1,16 +0,0 @@
-
-include ..\Makefile.inc
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-
-OBJS = \
- $(OUTDIR)\mod_pubsub.beam
-
-ALL : $(OBJS)
-
-CLEAN :
- -@erase $(OBJS)
-
-$(OUTDIR)\mod_pubsub.beam : mod_pubsub.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) mod_pubsub.erl
diff --git a/ejabberd-1.1.2/src/mod_pubsub/mod_pubsub.erl b/ejabberd-1.1.2/src/mod_pubsub/mod_pubsub.erl
deleted file mode 100644
index 37eb87c17..000000000
--- a/ejabberd-1.1.2/src/mod_pubsub/mod_pubsub.erl
+++ /dev/null
@@ -1,1698 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_pubsub.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Pub/sub support (JEP-0060)
-%%% Created : 4 Jul 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_pubsub).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
--behaviour(gen_mod).
-
-%% API
--export([start_link/2,
- start/2,
- stop/1]).
-
--export([delete_item/3,
- set_entities/4,
- delete_node/2,
- create_new_node/2,
- subscribe_node/3,
- get_node_config/4,
- set_node_config/4]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
--record(state, {host, server_host, access}).
-
--define(DICT, dict).
--define(MAXITEMS, 20).
--define(MAX_PAYLOAD_SIZE, 100000).
-
--record(pubsub_node, {host_node, host_parent, info}).
--record(nodeinfo, {items = [],
- options = [],
- entities = ?DICT:new()
- }).
--record(entity, {affiliation = none,
- subscription = none}).
--record(item, {id, publisher, payload}).
-
--define(PROCNAME, ejabberd_mod_pubsub).
--define(MYJID, #jid{user = "", server = Host, resource = "",
- luser = "", lserver = Host, lresource = ""}).
-
-%%====================================================================
-%% 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) ->
- 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) ->
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- gen_server:call(Proc, stop),
- supervisor:stop_child(ejabberd_sup, Proc).
-
-delete_item(From, Node, ItemID) ->
- delete_item(get_host(), From, Node, ItemID).
-
-delete_node(From, Node) ->
- delete_node(get_host(), From, Node).
-
-create_new_node(Node, From) ->
- create_new_node(get_host(), Node, From).
-
-subscribe_node(From, JID, Node) ->
- subscribe_node(get_host(), From, JID, Node).
-
-set_node_config(From, Node, Els, Lang) ->
- set_node_config(get_host(), From, Node, Els, Lang).
-
-get_host() ->
- ejabberd_mod_pubsub ! {get_host, self()},
- receive
- {pubsub_host, Host} ->
- Host
- after 5000 ->
- timeout
- end.
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% Description: Initiates the server
-%%--------------------------------------------------------------------
-init([ServerHost, Opts]) ->
- mnesia:create_table(pubsub_node,
- [{disc_only_copies, [node()]},
- {attributes, record_info(fields, pubsub_node)}]),
- Host = gen_mod:get_opt(host, Opts, "pubsub." ++ ServerHost),
- update_table(Host),
- mnesia:add_table_index(pubsub_node, host_parent),
- ServedHosts = gen_mod:get_opt(served_hosts, Opts, []),
- Access = gen_mod:get_opt(access_createnode, Opts, all),
-
- ejabberd_router:register_route(Host),
- create_new_node(Host, ["pubsub"], ?MYJID),
- create_new_node(Host, ["pubsub", "nodes"], ?MYJID),
- create_new_node(Host, ["home"], ?MYJID),
- create_new_node(Host, ["home", ServerHost], ?MYJID),
- lists:foreach(fun(H) ->
- create_new_node(Host, ["home", H], ?MYJID)
- end, ServedHosts),
- ets:new(gen_mod:get_module_proc(Host, pubsub_presence),
- [set, named_table]),
- {ok, #state{host = Host, server_host = ServerHost, 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{server_host = ServerHost, access = Access} = State) ->
- case catch do_route(To#jid.lserver, ServerHost, Access, From, To, Packet) 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
-%%--------------------------------------------------------------------
-do_route(Host, ServerHost, Access, From, To, Packet) ->
- {xmlelement, Name, Attrs, Els} = Packet,
- case To of
- #jid{luser = "", lresource = ""} ->
- case Name of
- "iq" ->
- case jlib:iq_query_info(Packet) of
- #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS,
- sub_el = SubEl} = IQ ->
- {xmlelement, _, QAttrs, _} = SubEl,
- Node = xml:get_attr_s("node", QAttrs),
- Res = IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- QAttrs,
- iq_disco_info(Node)}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(Res));
- #iq{type = get, xmlns = ?NS_DISCO_ITEMS = XMLNS,
- sub_el = SubEl} = IQ ->
- {xmlelement, _, QAttrs, _} = SubEl,
- Node = xml:get_attr_s("node", QAttrs),
- Res =
- case iq_disco_items(Host, From, Node) of
- {result, IQRes} ->
- jlib:iq_to_xml(
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- QAttrs,
- IQRes}]});
- {error, Error} ->
- jlib:make_error_reply(
- Packet, Error)
- end,
- ejabberd_router:route(To, From, Res);
- #iq{type = Type, xmlns = ?NS_PUBSUB = XMLNS,
- sub_el = SubEl} = IQ ->
- Res =
- case iq_pubsub(Host, ServerHost, From, Type, SubEl, Access) of
- {result, IQRes} ->
- jlib:iq_to_xml(
- IQ#iq{type = result,
- sub_el = IQRes});
- {error, Error} ->
- jlib:make_error_reply(
- Packet, Error)
- end,
- ejabberd_router:route(To, From, Res);
- #iq{type = Type, xmlns = ?NS_PUBSUB_OWNER = XMLNS,
- lang = Lang, sub_el = SubEl} = IQ ->
- Res =
- case iq_pubsub_owner(
- Host, From, Type, Lang, SubEl) of
- {result, IQRes} ->
- jlib:iq_to_xml(
- IQ#iq{type = result,
- sub_el = IQRes});
- {error, Error} ->
- jlib:make_error_reply(
- Packet, Error)
- end,
- ejabberd_router:route(To, From, Res);
- #iq{type = get, xmlns = ?NS_VCARD = XMLNS,
- lang = Lang, sub_el = SubEl} = IQ ->
- Res = IQ#iq{type = result,
- sub_el = [{xmlelement, "vCard",
- [{"xmlns", XMLNS}],
- iq_get_vcard(Lang)}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(Res));
- #iq{} ->
- Err = jlib:make_error_reply(
- Packet,
- ?ERR_FEATURE_NOT_IMPLEMENTED),
- ejabberd_router:route(To, From, Err);
- _ ->
- ok
- end;
- "presence" ->
- Type = xml:get_attr_s("type", Attrs),
- if
- (Type == "unavailable") or (Type == "error") ->
- ets:delete(
- gen_mod:get_module_proc(Host, pubsub_presence),
- {From#jid.luser, From#jid.lserver});
- true ->
- ets:insert(
- gen_mod:get_module_proc(Host, pubsub_presence),
- {{From#jid.luser, From#jid.lserver}, []})
- end,
- ok;
- _ ->
- ok
- end;
- _ ->
- case xml:get_attr_s("type", Attrs) of
- "error" ->
- ok;
- "result" ->
- ok;
- _ ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_ITEM_NOT_FOUND),
- ejabberd_router:route(To, From, Err)
- end
- end.
-
-
-
-node_to_string(Node) ->
- string:strip(lists:flatten(lists:map(fun(S) -> [S, "/"] end, Node)),
- right, $/).
-
-
-iq_disco_info(SNode) ->
- Node = string:tokens(SNode, "/"),
- case Node of
- [] ->
- [{xmlelement, "identity",
- [{"category", "pubsub"},
- {"type", "generic"},
- {"name", "Publish-Subscribe"}], []},
- {xmlelement, "feature", [{"var", ?NS_PUBSUB}], []},
- {xmlelement, "feature", [{"var", ?NS_PUBSUB_EVENT}], []},
- {xmlelement, "feature", [{"var", ?NS_PUBSUB_OWNER}], []},
- {xmlelement, "feature", [{"var", ?NS_VCARD}], []}];
- _ ->
- % TODO
- []
- end.
-
-iq_disco_items(Host, From, SNode) ->
- {Node,ItemID} = case SNode of
- [] ->
- {[],none};
- _ ->
- Tokens = string:tokens(SNode, "!"),
- NodeList = string:tokens(lists:nth(1, Tokens), "/"),
- ItemName = case length(Tokens) of
- 2 -> lists:nth(2, Tokens);
- _ -> none
- end,
- {NodeList, ItemName}
- end,
- NodeFull = string:tokens(SNode,"/"),
- F = fun() ->
- case mnesia:read({pubsub_node, {Host, Node}}) of
- [#pubsub_node{info = Info}] ->
- case ItemID of
- none ->
- SubNodes = mnesia:index_read(pubsub_node,
- {Host, Node},
- #pubsub_node.host_parent),
- SubItems = lists:map(fun(#pubsub_node{host_node = {_, N}}) ->
- SN = node_to_string(N),
- {xmlelement, "item",
- [{"jid", Host},
- {"node", SN},
- {"name", lists:last(N)}], []}
- end, SubNodes),
- SN = node_to_string(Node),
- Items = lists:map(fun(#item{id = Name}) ->
- RealName = case Name of
- [] -> "item";
- _ -> Name
- end,
- {xmlelement, "item",
- [{"jid", Host},
- {"node", SN ++ "!" ++ Name},
- {"name", RealName}], []}
- end, Info#nodeinfo.items),
- SubItems ++ Items;
- _ ->
- []
- end;
- [] ->
- case Node of
- [] ->
- SubNodes = mnesia:index_read(
- pubsub_node,
- {Host, Node},
- #pubsub_node.host_parent),
- lists:map(
- fun(#pubsub_node{host_node = {_, N}}) ->
- SN = node_to_string(N),
- {xmlelement, "item",
- [{"jid", Host},
- {"node", SN},
- {"name", lists:last(N)}],
- []}
- end, SubNodes) ;
- _ ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end
- end
- end,
- case mnesia:transaction(F) of
- {atomic, {error, _} = Error} ->
- Error;
- {atomic, Res} ->
- {result, Res};
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end.
-
-iq_get_vcard(Lang) ->
- [{xmlelement, "FN", [],
- [{xmlcdata, "ejabberd/mod_pubsub"}]},
- {xmlelement, "URL", [],
- [{xmlcdata,
- "http://ejabberd.jabberstudio.org/"}]},
- {xmlelement, "DESC", [],
- [{xmlcdata, translate:translate(
- Lang,
- "ejabberd pub/sub module\n"
- "Copyright (c) 2003-2006 Alexey Shchepin")}]}].
-
-
-iq_pubsub(Host, ServerHost, From, Type, SubEl, Access) ->
- {xmlelement, _, _, SubEls} = SubEl,
- case xml:remove_cdata(SubEls) of
- [{xmlelement, Name, Attrs, Els}] ->
- SNode = xml:get_attr_s("node", Attrs),
- Node = string:tokens(SNode, "/"),
- case {Type, Name} of
- {set, "create"} ->
- create_new_node(Host, Node, From, ServerHost, Access);
- {set, "publish"} ->
- case xml:remove_cdata(Els) of
- [{xmlelement, "item", ItemAttrs, Payload}] ->
- ItemID = xml:get_attr_s("id", ItemAttrs),
- publish_item(Host, From, Node, ItemID, Payload);
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- {set, "retract"} ->
- case xml:remove_cdata(Els) of
- [{xmlelement, "item", ItemAttrs, _}] ->
- ItemID = xml:get_attr_s("id", ItemAttrs),
- delete_item(Host, From, Node, ItemID);
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- {set, "subscribe"} ->
- JID = xml:get_attr_s("jid", Attrs),
- subscribe_node(Host, From, JID, Node);
- {set, "unsubscribe"} ->
- JID = xml:get_attr_s("jid", Attrs),
- unsubscribe_node(Host, From, JID, Node);
- {get, "items"} ->
- MaxItems = xml:get_attr_s("max_items", Attrs),
- get_items(Host, From, Node, MaxItems);
- {set, "delete"} ->
- delete_node(Host, From, Node);
- {set, "purge"} ->
- purge_node(Host, From, Node);
- {get, "entities"} ->
- get_entities(Host, From, Node);
- {set, "entities"} ->
- set_entities(Host, From, Node, xml:remove_cdata(Els));
- {get, "affiliations"} ->
- get_affiliations(Host, From);
- _ ->
- {error, ?ERR_FEATURE_NOT_IMPLEMENTED}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end.
-
-
--define(XFIELD(Type, Label, Var, Val),
- {xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
- {"var", Var}],
- [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
-
--define(BOOLXFIELD(Label, Var, Val),
- ?XFIELD("boolean", Label, Var,
- case Val of
- true -> "1";
- _ -> "0"
- end)).
-
--define(STRINGXFIELD(Label, Var, Val),
- ?XFIELD("text-single", Label, Var, Val)).
-
--define(XFIELDOPT(Type, Label, Var, Val, Opts),
- {xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
- {"var", Var}],
- lists:map(fun(Opt) ->
- {xmlelement, "option", [],
- [{xmlelement, "value", [],
- [{xmlcdata, Opt}]}]}
- end, Opts) ++
- [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
-
--define(LISTXFIELD(Label, Var, Val, Opts),
- ?XFIELDOPT("list-single", Label, Var, Val, Opts)).
-
-
-
-%% Create new pubsub nodes
-%% This function is used during init to create the first bootstrap nodes
-create_new_node(Host, Node, Owner) ->
- %% This is the case use during "bootstrapping to create the initial
- %% hierarchy. Should always be ... undefined,all
- create_new_node(Host, Node, Owner, undefined, all).
-create_new_node(Host, Node, Owner, ServerHost, Access) ->
- case Node of
- [] ->
- {LOU, LOS, _} = jlib:jid_tolower(Owner),
- HomeNode = ["home", LOS, LOU],
- create_new_node(Host, HomeNode, Owner, ServerHost, Access),
- NewNode = ["home", LOS, LOU, randoms:get_string()],
- create_new_node(Host, NewNode, Owner, ServerHost, Access);
- _ ->
- LOwner = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
- Parent = lists:sublist(Node, length(Node) - 1),
- F = fun() ->
- ParentExists = (Parent == []) orelse
- case mnesia:read({pubsub_node, {Host, Parent}}) of
- [_] ->
- true;
- [] ->
- false
- end,
- case ParentExists of
- false ->
- {error, ?ERR_CONFLICT};
- _ ->
- case mnesia:read({pubsub_node, {Host, Node}}) of
- [_] ->
- {error, ?ERR_CONFLICT};
- [] ->
- Entities =
- ?DICT:store(
- LOwner,
- #entity{affiliation = owner,
- subscription = none},
- ?DICT:new()),
- mnesia:write(
- #pubsub_node{host_node = {Host, Node},
- host_parent = {Host, Parent},
- info = #nodeinfo{
- entities = Entities}}),
- ok
- end
- end
- end,
- case check_create_permission(Host, Node, Owner, ServerHost, Access) of
- true ->
- case mnesia:transaction(F) of
- {atomic, ok} ->
- Lang = "",
- broadcast_publish_item(
- Host, ["pubsub", "nodes"], node_to_string(Node),
- [{xmlelement, "x",
- [{"xmlns", ?NS_XDATA},
- {"type", "result"}],
- [?XFIELD("hidden", "", "FORM_TYPE",
- ?NS_PUBSUB_NMI),
- ?XFIELD("jid-single", "Node Creator",
- "creator",
- jlib:jid_to_string(LOwner))]}]),
- {result,
- [{xmlelement, "pubsub",
- [{"xmlns", ?NS_PUBSUB}],
- [{xmlelement, "create",
- [{"node", node_to_string(Node)}], []}]}]};
- {atomic, {error, _} = Error} ->
- Error;
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end;
- _ ->
- {error, ?ERR_NOT_ALLOWED}
- end
- end.
-
-
-publish_item(Host, JID, Node, ItemID, Payload) ->
- ejabberd_hooks:run(pubsub_publish_item, Host,
- [JID, ?MYJID, Node, ItemID, Payload]),
- Publisher = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
- F = fun() ->
- case mnesia:read({pubsub_node, {Host, Node}}) of
- [#pubsub_node{info = Info} = N] ->
- Affiliation = get_affiliation(Info, Publisher),
- Subscription = get_subscription(Info, Publisher),
- MaxSize = get_node_option(Info, max_payload_size),
- Model = get_node_option(Info, publish_model),
- Size = size(term_to_binary(Payload)),
- if
- ((Model == open) or
- ((Model == publishers) and
- ((Affiliation == owner) or
- (Affiliation == publisher))) or
- ((Model == subscribers) and
- (Subscription == subscribed))) and
- (Size =< MaxSize) ->
- NewInfo =
- insert_item(Info, ItemID,
- Publisher, Payload),
- mnesia:write(
- N#pubsub_node{info = NewInfo}),
- {result, []};
- true ->
- {error, ?ERR_NOT_ALLOWED}
- end;
- [] ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end
- end,
- case mnesia:transaction(F) of
- {atomic, {error, _} = Error} ->
- Error;
- {atomic, {result, Res}} ->
- broadcast_publish_item(Host, Node, ItemID, Payload),
- {result, Res};
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end.
-
-
-delete_item(Host, JID, Node, ItemID) ->
- Publisher = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
- F = fun() ->
- case mnesia:read({pubsub_node, {Host, Node}}) of
- [#pubsub_node{info = Info} = N] ->
- case check_item_publisher(Info, ItemID, Publisher)
- orelse
- (get_affiliation(Info, Publisher) == owner) of
- true ->
- NewInfo =
- remove_item(Info, ItemID),
- mnesia:write(
- N#pubsub_node{info = NewInfo}),
- {result, []};
- _ ->
- {error, ?ERR_NOT_ALLOWED}
- end;
- [] ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end
- end,
- case mnesia:transaction(F) of
- {atomic, {error, _} = Error} ->
- Error;
- {atomic, {result, Res}} ->
- broadcast_retract_item(Host, Node, ItemID),
- {result, Res};
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end.
-
-
-subscribe_node(Host, From, JID, Node) ->
- Sender = jlib:jid_tolower(jlib:jid_remove_resource(From)),
- SubscriberJID =
- case jlib:string_to_jid(JID) of
- error ->
- {"", "", ""};
- J ->
- J
- end,
- Subscriber = jlib:jid_tolower(SubscriberJID),
- SubscriberWithoutResource = jlib:jid_remove_resource(Subscriber),
- F = fun() ->
- case mnesia:read({pubsub_node, {Host, Node}}) of
- [#pubsub_node{info = Info} = N] ->
- Affiliation = get_affiliation(Info, Subscriber),
- AllowSubscriptions = get_node_option(Info, subscribe),
- if
- AllowSubscriptions and
- (Affiliation /= outcast) ->
- NewInfo = add_subscriber(Info, Subscriber),
- mnesia:write(N#pubsub_node{info = NewInfo}),
- {result, [], Info};
- true ->
- {error, ?ERR_NOT_ALLOWED}
- end;
- [] ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end
- end,
- if
- Sender == SubscriberWithoutResource ->
- case mnesia:transaction(F) of
- {atomic, {error, _} = Error} ->
- Error;
- {atomic, {result, Res, Info}} ->
- case get_node_option(Info, send_item_subscribe) of
- true ->
- ItemsEls =
- lists:map(
- fun(#item{id = ItemID,
- payload = Payload}) ->
- ItemAttrs = case ItemID of
- "" -> [];
- _ -> [{"id", ItemID}]
- end,
- {xmlelement, "item",
- ItemAttrs, Payload}
- end, Info#nodeinfo.items),
- Stanza =
- {xmlelement, "message",
- [],
- [{xmlelement, "x",
- [{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "items",
- [{"node", node_to_string(Node)}],
- ItemsEls}]}]},
- ejabberd_router:route(
- ?MYJID, jlib:make_jid(Subscriber), Stanza);
- false ->
- ok
- end,
- {result, Res};
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end;
- true ->
- {error, ?ERR_NOT_ALLOWED}
- end.
-
-
-unsubscribe_node(Host, From, JID, Node) ->
- Sender = jlib:jid_tolower(jlib:jid_remove_resource(From)),
- SubscriberJID =
- case jlib:string_to_jid(JID) of
- error ->
- {"", "", ""};
- J ->
- J
- end,
- Subscriber = jlib:jid_tolower(SubscriberJID),
- F = fun() ->
- case mnesia:read({pubsub_node, {Host, Node}}) of
- [#pubsub_node{info = Info} = N] ->
- Subscription = get_subscription(Info, Subscriber),
- if
- Subscription /= none ->
- NewInfo =
- remove_subscriber(Info, Subscriber),
- mnesia:write(
- N#pubsub_node{info = NewInfo}),
- {result, []};
- true ->
- {error, ?ERR_NOT_ALLOWED}
- end;
- [] ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end
- end,
- if
- Sender == Subscriber ->
- case mnesia:transaction(F) of
- {atomic, {error, _} = Error} ->
- Error;
- {atomic, {result, Res}} ->
- {result, Res};
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end;
- true ->
- {error, ?ERR_NOT_ALLOWED}
- end.
-
-
-get_items(Host, JID, Node, SMaxItems) ->
- MaxItems =
- if
- SMaxItems == "" ->
- ?MAXITEMS;
- true ->
- case catch list_to_integer(SMaxItems) of
- {'EXIT', _} ->
- {error, ?ERR_BAD_REQUEST};
- Val ->
- Val
- end
- end,
- case MaxItems of
- {error, _} = Error ->
- Error;
- _ ->
- case catch mnesia:dirty_read(pubsub_node, {Host, Node}) of
- [#pubsub_node{info = Info}] ->
- Items = lists:sublist(Info#nodeinfo.items, MaxItems),
- ItemsEls =
- lists:map(
- fun(#item{id = ItemID,
- payload = Payload}) ->
- ItemAttrs = case ItemID of
- "" -> [];
- _ -> [{"id", ItemID}]
- end,
- {xmlelement, "item", ItemAttrs, Payload}
- end, Items),
- {result, [{xmlelement, "pubsub",
- [{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "items",
- [{"node", node_to_string(Node)}],
- ItemsEls}]}]};
- _ ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end
- end.
-
-
-delete_node(Host, JID, Node) ->
- Owner = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
- F = fun() ->
- case mnesia:read({pubsub_node, {Host, Node}}) of
- [#pubsub_node{info = Info}] ->
- case get_affiliation(Info, Owner) of
- owner ->
- % TODO: don't iterate over entire table
- Removed =
- mnesia:foldl(
- fun(#pubsub_node{host_node = {_, N},
- info = NInfo}, Acc) ->
- case lists:prefix(Node, N) of
- true ->
- [{N, NInfo} | Acc];
- _ ->
- Acc
- end
- end, [], pubsub_node),
- lists:foreach(
- fun({N, _}) ->
- mnesia:delete({pubsub_node, {Host, N}})
- end, Removed),
- {removed, Removed};
- _ ->
- {error, ?ERR_NOT_ALLOWED}
- end;
- [] ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end
- end,
- case mnesia:transaction(F) of
- {atomic, {error, _} = Error} ->
- Error;
- {atomic, {removed, Removed}} ->
- broadcast_removed_node(Host, Removed),
- Lang = "",
- broadcast_retract_item(
- Host, ["pubsub", "nodes"], node_to_string(Node)),
- {result, []};
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end.
-
-
-purge_node(Host, JID, Node) ->
- Owner = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
- F = fun() ->
- case mnesia:read({pubsub_node, {Host, Node}}) of
- [#pubsub_node{info = Info} = N] ->
- case get_affiliation(Info, Owner) of
- owner ->
- NewInfo = Info#nodeinfo{items = []},
- mnesia:write(
- N#pubsub_node{info = NewInfo}),
- {result, Info#nodeinfo.items, []};
- _ ->
- {error, ?ERR_NOT_ALLOWED}
- end;
- [] ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end
- end,
- case mnesia:transaction(F) of
- {atomic, {error, _} = Error} ->
- Error;
- {atomic, {result, Items, Res}} ->
- lists:foreach(
- fun(#item{id = ItemID}) ->
- broadcast_retract_item(Host, Node, ItemID)
- end, Items),
- {result, Res};
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end.
-
-
-get_entities(Host, OJID, Node) ->
- Owner = jlib:jid_tolower(jlib:jid_remove_resource(OJID)),
- case catch mnesia:dirty_read(pubsub_node, {Host, Node}) of
- [#pubsub_node{info = Info}] ->
- case get_affiliation(Info, Owner) of
- owner ->
- Entities = Info#nodeinfo.entities,
- EntitiesEls =
- ?DICT:fold(
- fun(JID,
- #entity{affiliation = Affiliation,
- subscription = Subscription},
- Acc) ->
- [{xmlelement, "entity",
- [{"jid", jlib:jid_to_string(JID)},
- {"affiliation",
- affiliation_to_string(Affiliation)},
- {"subscription",
- subscription_to_string(Subscription)}],
- []} | Acc]
- end, [], Entities),
- {result, [{xmlelement, "pubsub",
- [{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "entities",
- [{"node", node_to_string(Node)}],
- EntitiesEls}]}]};
- _ ->
- {error, ?ERR_NOT_ALLOWED}
- end;
- _ ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end.
-
-
-set_entities(Host, OJID, Node, EntitiesEls) ->
- Owner = jlib:jid_tolower(jlib:jid_remove_resource(OJID)),
- Entities =
- lists:foldl(
- fun(El, Acc) ->
- case Acc of
- error ->
- error;
- _ ->
- case El of
- {xmlelement, "entity", Attrs, _} ->
- JID = jlib:string_to_jid(
- xml:get_attr_s("jid", Attrs)),
- Affiliation =
- case xml:get_attr_s("affiliation",
- Attrs) of
- "owner" -> owner;
- "publisher" -> publisher;
- "outcast" -> outcast;
- "none" -> none;
- _ -> false
- end,
- Subscription =
- case xml:get_attr_s("subscription",
- Attrs) of
- "subscribed" -> subscribed;
- "pending" -> pending;
- "unconfigured" -> unconfigured;
- "none" -> none;
- _ -> false
- end,
- if
- (JID == error) or
- (Affiliation == false) or
- (Subscription == false) ->
- error;
- true ->
- [{jlib:jid_tolower(JID),
- #entity{
- affiliation = Affiliation,
- subscription = Subscription}} |
- Acc]
- end
- end
- end
- end, [], EntitiesEls),
- case Entities of
- error ->
- {error, ?ERR_BAD_REQUEST};
- _ ->
- F = fun() ->
- case mnesia:read({pubsub_node, {Host, Node}}) of
- [#pubsub_node{info = Info} = N] ->
- case get_affiliation(Info, Owner) of
- owner ->
- NewInfo =
- set_info_entities(Info, Entities),
- mnesia:write(
- N#pubsub_node{info = NewInfo}),
- {result, []};
- _ ->
- {error, ?ERR_NOT_ALLOWED}
- end;
- [] ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end
- end,
- case mnesia:transaction(F) of
- {atomic, {error, _} = Error} ->
- Error;
- {atomic, {result, _}} ->
- {result, []};
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end
- end.
-
-
-get_affiliations(Host, JID) ->
- LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
- case catch mnesia:dirty_select(
- pubsub_node,
- [{#pubsub_node{_ = '_'},
- [],
- ['$_']}]) of
- {'EXIT', _} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- Nodes ->
- Entities =
- lists:flatmap(
- fun(#pubsub_node{host_node = {H, Node}, info = Info})
- when H == Host ->
- Affiliation = get_affiliation(Info, LJID),
- Subscription = get_subscription(Info, LJID),
- if
- (Affiliation /= none) or
- (Subscription /= none) ->
- [{xmlelement, "entity",
- [{"node", node_to_string(Node)},
- {"jid", jlib:jid_to_string(JID)},
- {"affiliation",
- affiliation_to_string(Affiliation)},
- {"subscription",
- subscription_to_string(Subscription)}],
- []}];
- true ->
- []
- end;
- (_) ->
- []
- end, Nodes),
- {result, [{xmlelement, "pubsub",
- [{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "affiliations", [],
- Entities}]}]}
- end.
-
-
-
-
-get_affiliation(#nodeinfo{entities = Entities}, JID) ->
- LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
- case ?DICT:find(LJID, Entities) of
- {ok, #entity{affiliation = Affiliation}} ->
- Affiliation;
- _ ->
- none
- end.
-
-get_subscription(#nodeinfo{entities = Entities}, JID) ->
- LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
- case ?DICT:find(LJID, Entities) of
- {ok, #entity{subscription = Subscription}} ->
- Subscription;
- _ ->
- none
- end.
-
-affiliation_to_string(Affiliation) ->
- case Affiliation of
- owner -> "owner";
- publisher -> "publisher";
- outcast -> "outcast";
- _ -> "none"
- end.
-
-subscription_to_string(Subscription) ->
- case Subscription of
- subscribed -> "subscribed";
- pending -> "pending";
- unconfigured -> "unconfigured";
- _ -> "none"
- end.
-
-
-check_create_permission(Host, Node, Owner, ServerHost, Access) ->
- #jid{luser = User, lserver = Server, lresource = Resource} = Owner,
- case acl:match_rule(ServerHost, Access, {User, Server, Resource}) of
- allow ->
- if Server == Host ->
- true;
- true ->
- case Node of
- ["home", Server, User | _] ->
- true;
- _ ->
- false
- end
- end;
- _ ->
- case Owner of
- ?MYJID ->
- true;
- _ ->
- false
- end
- end.
-
-insert_item(Info, ItemID, Publisher, Payload) ->
- Items = Info#nodeinfo.items,
- Items1 = lists:filter(fun(I) ->
- I#item.id /= ItemID
- end, Items),
- Items2 = [#item{id = ItemID, publisher = Publisher, payload = Payload} |
- Items1],
- Items3 = lists:sublist(Items2, get_max_items(Info)),
- Info#nodeinfo{items = Items3}.
-
-remove_item(Info, ItemID) ->
- Items = Info#nodeinfo.items,
- Items1 = lists:filter(fun(I) ->
- I#item.id /= ItemID
- end, Items),
- Info#nodeinfo{items = Items1}.
-
-check_item_publisher(Info, ItemID, Publisher) ->
- Items = Info#nodeinfo.items,
- case lists:keysearch(ItemID, #item.id, Items) of
- {value, #item{publisher = Publisher}} ->
- true;
- _ ->
- false
- end.
-
-add_subscriber(Info, Subscriber) ->
- Entities = Info#nodeinfo.entities,
- case ?DICT:find(Subscriber, Entities) of
- {ok, Entity} ->
- Info#nodeinfo{
- entities = ?DICT:store(Subscriber,
- Entity#entity{subscription = subscribed},
- Entities)};
- _ ->
- Info#nodeinfo{
- entities = ?DICT:store(Subscriber,
- #entity{subscription = subscribed},
- Entities)}
- end.
-
-remove_subscriber(Info, Subscriber) ->
- Entities = Info#nodeinfo.entities,
- case ?DICT:find(Subscriber, Entities) of
- {ok, #entity{affiliation = none}} ->
- Info#nodeinfo{
- entities = ?DICT:erase(Subscriber, Entities)};
- {ok, Entity} ->
- Info#nodeinfo{
- entities = ?DICT:store(Subscriber,
- Entity#entity{subscription = none},
- Entities)};
- _ ->
- Info
- end.
-
-
-set_info_entities(Info, Entities) ->
- NewEntities =
- lists:foldl(
- fun({JID, Ent}, Es) ->
- case Ent of
- #entity{affiliation = none, subscription = none} ->
- ?DICT:erase(JID, Es);
- _ ->
- ?DICT:store(JID, Ent, Es)
- end
- end, Info#nodeinfo.entities, Entities),
- Info#nodeinfo{entities = NewEntities}.
-
-
-
-broadcast_publish_item(Host, Node, ItemID, Payload) ->
- case catch mnesia:dirty_read(pubsub_node, {Host, Node}) of
- [#pubsub_node{info = Info}] ->
- ?DICT:fold(
- fun(JID, #entity{subscription = Subscription}, _) ->
- Present = case get_node_option(
- Info, presence_based_delivery) of
- true ->
- case ets:lookup(
- gen_mod:get_module_proc(Host, pubsub_presence),
- {element(1, JID),
- element(2, JID)}) of
- [_] ->
- true;
- [] ->
- false
- end;
- false ->
- true
- end,
- if
- (Subscription /= none) and
- (Subscription /= pending) and
- Present ->
- ItemAttrs = case ItemID of
- "" -> [];
- _ -> [{"id", ItemID}]
- end,
- Content = case get_node_option(
- Info, deliver_payloads) of
- true ->
- Payload;
- false ->
- []
- end,
- Stanza =
- {xmlelement, "message", [],
- [{xmlelement, "event",
- [{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "items",
- [{"node", node_to_string(Node)}],
- [{xmlelement, "item",
- ItemAttrs,
- Content}]}]}]},
- ejabberd_router:route(
- ?MYJID, jlib:make_jid(JID), Stanza);
- true ->
- ok
- end
- end, ok, Info#nodeinfo.entities);
- _ ->
- false
- end.
-
-
-broadcast_retract_item(Host, Node, ItemID) ->
- case catch mnesia:dirty_read(pubsub_node, {Host, Node}) of
- [#pubsub_node{info = Info}] ->
- case get_node_option(Info, notify_retract) of
- true ->
- ?DICT:fold(
- fun(JID, #entity{subscription = Subscription}, _) ->
- if
- (Subscription /= none) and
- (Subscription /= pending) ->
- ItemAttrs = case ItemID of
- "" -> [];
- _ -> [{"id", ItemID}]
- end,
- Stanza =
- {xmlelement, "message", [],
- [{xmlelement, "x",
- [{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "items",
- [{"node", node_to_string(Node)}],
- [{xmlelement, "retract",
- ItemAttrs, []}]}]}]},
- ejabberd_router:route(
- ?MYJID, jlib:make_jid(JID), Stanza);
- true ->
- ok
- end
- end, ok, Info#nodeinfo.entities);
- false ->
- ok
- end;
- _ ->
- false
- end.
-
-
-broadcast_removed_node(Host, Removed) ->
- lists:foreach(
- fun({Node, Info}) ->
- case get_node_option(Info, notify_delete) of
- true ->
- Entities = Info#nodeinfo.entities,
- ?DICT:fold(
- fun(JID, #entity{subscription = Subscription}, _) ->
- if
- (Subscription /= none) and
- (Subscription /= pending) ->
- Stanza =
- {xmlelement, "message", [],
- [{xmlelement, "x",
- [{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "delete",
- [{"node", node_to_string(Node)}],
- []}]}]},
- ejabberd_router:route(
- ?MYJID, jlib:make_jid(JID), Stanza);
- true ->
- ok
- end
- end, ok, Entities);
- false ->
- ok
- end
- end, Removed).
-
-
-broadcast_config_notification(Host, Node, Lang) ->
- case catch mnesia:dirty_read(pubsub_node, {Host, Node}) of
- [#pubsub_node{info = Info}] ->
- case get_node_option(Info, notify_config) of
- true ->
- ?DICT:fold(
- fun(JID, #entity{subscription = Subscription}, _) ->
- Present = case get_node_option(
- Info, presence_based_delivery) of
- true ->
- case ets:lookup(
- gen_mod:get_module_proc(Host, pubsub_presence),
- {element(1, JID),
- element(2, JID)}) of
- [_] ->
- true;
- [] ->
- false
- end;
- false ->
- true
- end,
- if
- (Subscription /= none) and
- (Subscription /= pending) and
- Present ->
- Fields = get_node_config_xfields(
- Node, Info, Lang),
- Content = case get_node_option(
- Info, deliver_payloads) of
- true ->
- [{xmlelement, "x",
- [{"xmlns", ?NS_XDATA},
- {"type", "form"}],
- Fields}];
- false ->
- []
- end,
- Stanza =
- {xmlelement, "message", [],
- [{xmlelement, "x",
- [{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "items",
- [{"node", node_to_string(Node)}],
- [{xmlelement, "item",
- [{"id", "configuration"}],
- Content}]}]}]},
- ejabberd_router:route(
- ?MYJID, jlib:make_jid(JID), Stanza);
- true ->
- ok
- end
- end, ok, Info#nodeinfo.entities);
- false ->
- ok
- end;
- _ ->
- false
- end.
-
-
-
-iq_pubsub_owner(Host, From, Type, Lang, SubEl) ->
- {xmlelement, _, _, SubEls} = SubEl,
- case xml:remove_cdata(SubEls) of
- [{xmlelement, Name, Attrs, Els}] ->
- SNode = xml:get_attr_s("node", Attrs),
- Node = string:tokens(SNode, "/"),
- case {Type, Name} of
- {get, "configure"} ->
- get_node_config(Host, From, Node, Lang);
- {set, "configure"} ->
- set_node_config(Host, From, Node, Els, Lang);
- _ ->
- {error, ?ERR_FEATURE_NOT_IMPLEMENTED}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end.
-
-get_node_config(Host, From, Node, Lang) ->
- case catch mnesia:dirty_read(pubsub_node, {Host, Node}) of
- [#pubsub_node{info = Info}] ->
- case get_affiliation(Info, From) of
- owner ->
- Fields = get_node_config_xfields(Node, Info, Lang),
- {result, [{xmlelement, "pubsub",
- [{"xmlns", ?NS_PUBSUB_OWNER}],
- [{xmlelement, "configure",
- [{"node", node_to_string(Node)}],
- [{xmlelement, "x", [{"xmlns", ?NS_XDATA},
- {"type", "form"}],
- Fields}]}]}]};
- _ ->
- {error, ?ERR_NOT_AUTHORIZED}
- end;
- _ ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end.
-
-% TODO: move to jlib.hrl
--define(NS_PUBSUB_NODE_CONFIG, "http://jabber.org/protocol/pubsub#node_config").
-
--define(BOOL_CONFIG_FIELD(Label, Var),
- ?BOOLXFIELD(Label, "pubsub#" ++ atom_to_list(Var),
- get_node_option(Info, Var))).
-
--define(STRING_CONFIG_FIELD(Label, Var),
- ?STRINGXFIELD(Label, "pubsub#" ++ atom_to_list(Var),
- get_node_option(Info, Var))).
-
--define(INTEGER_CONFIG_FIELD(Label, Var),
- ?STRINGXFIELD(Label, "pubsub#" ++ atom_to_list(Var),
- integer_to_list(get_node_option(Info, Var)))).
-
--define(JLIST_CONFIG_FIELD(Label, Var, Opts),
- ?LISTXFIELD(Label, "pubsub#" ++ atom_to_list(Var),
- jlib:jid_to_string(get_node_option(Info, Var)),
- [jlib:jid_to_string(O) || O <- Opts])).
-
--define(ALIST_CONFIG_FIELD(Label, Var, Opts),
- ?LISTXFIELD(Label, "pubsub#" ++ atom_to_list(Var),
- atom_to_list(get_node_option(Info, Var)),
- [atom_to_list(O) || O <- Opts])).
-
-
--define(DEFAULT_OPTIONS,
- [{deliver_payloads, true},
- {notify_config, false},
- {notify_delete, false},
- {notify_retract, true},
- {persist_items, true},
- {max_items, ?MAXITEMS div 2},
- {subscribe, true},
- {subscription_model, open},
- {publish_model, publishers},
- {max_payload_size, ?MAX_PAYLOAD_SIZE},
- {send_item_subscribe, false},
- {presence_based_delivery, false}]).
-
-get_node_option(Info, current_approver) ->
- Default = hd(get_owners_jids(Info)),
- Options = Info#nodeinfo.options,
- element(
- 2, element(2, lists:keysearch(
- current_approver, 1,
- Options ++ [{current_approver, Default}])));
-get_node_option(#nodeinfo{options = Options}, Var) ->
- element(
- 2, element(2, lists:keysearch(Var, 1, Options ++ ?DEFAULT_OPTIONS))).
-
-get_max_items(Info) ->
- case get_node_option(Info, persist_items) of
- true ->
- get_node_option(Info, max_items);
- false ->
- 0
- end.
-
-get_owners_jids(Info) ->
- Entities = Info#nodeinfo.entities,
- Owners =
- ?DICT:fold(
- fun(JID,
- #entity{affiliation = Affiliation,
- subscription = Subscription},
- Acc) ->
- case Affiliation of
- owner ->
- [JID | Acc];
- _ ->
- Acc
- end
- end, [], Entities),
- lists:sort(Owners).
-
-
-get_node_config_xfields(Node, Info, Lang) ->
- [?XFIELD("hidden", "", "FORM_TYPE", ?NS_PUBSUB_NODE_CONFIG),
- ?BOOL_CONFIG_FIELD("Deliver payloads with event notifications", deliver_payloads),
- ?BOOL_CONFIG_FIELD("Notify subscribers when the node configuration changes", notify_config),
- ?BOOL_CONFIG_FIELD("Notify subscribers when the node is deleted", notify_delete),
- ?BOOL_CONFIG_FIELD("Notify subscribers when items are removed from the node", notify_retract),
- ?BOOL_CONFIG_FIELD("Persist items to storage", persist_items),
- ?INTEGER_CONFIG_FIELD("Max # of items to persist", max_items),
- ?BOOL_CONFIG_FIELD("Whether to allow subscriptions", subscribe),
- ?ALIST_CONFIG_FIELD("Specify the subscriber model", subscription_model,
- [open]),
- ?ALIST_CONFIG_FIELD("Specify the publisher model", publish_model,
- [publishers, subscribers, open]),
- ?INTEGER_CONFIG_FIELD("Max payload size in bytes", max_payload_size),
- ?BOOL_CONFIG_FIELD("Send items to new subscribers", send_item_subscribe),
- ?BOOL_CONFIG_FIELD("Only deliver notifications to available users", presence_based_delivery),
- ?JLIST_CONFIG_FIELD("Specify the current subscription approver", current_approver,
- get_owners_jids(Info))
- ].
-
-
-set_node_config(Host, From, Node, Els, Lang) ->
- case catch mnesia:dirty_read(pubsub_node, {Host, Node}) of
- [#pubsub_node{info = Info} = N] ->
- case get_affiliation(Info, From) of
- owner ->
- case xml:remove_cdata(Els) of
- [{xmlelement, "x", _Attrs1, _Els1} = XEl] ->
- case {xml:get_tag_attr_s("xmlns", XEl),
- xml:get_tag_attr_s("type", XEl)} of
- {?NS_XDATA, "cancel"} ->
- {result, []};
- {?NS_XDATA, "submit"} ->
- CurOpts = Info#nodeinfo.options,
- set_node_config1(
- Host, From, Node, XEl, CurOpts, Lang);
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end;
- _ ->
- {error, ?ERR_NOT_AUTHORIZED}
- end;
- _ ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end.
-
-
-set_node_config1(Host, From, Node, XEl, CurOpts, Lang) ->
- XData = jlib:parse_xdata_submit(XEl),
- case XData of
- invalid ->
- {error, ?ERR_BAD_REQUEST};
- _ ->
- case set_xoption(XData, CurOpts) of
- NewOpts when is_list(NewOpts) ->
- change_node_opts(Host, NewOpts, Node, Lang);
- Err ->
- Err
- end
- end.
-
-add_opt(Key, Value, Opts) ->
- Opts1 = lists:keydelete(Key, 1, Opts),
- [{Key, Value} | Opts1].
-
-
--define(SET_BOOL_XOPT(Opt, Val),
- case Val of
- "0" -> set_xoption(Opts, add_opt(Opt, false, NewOpts));
- "1" -> set_xoption(Opts, add_opt(Opt, true, NewOpts));
- _ -> {error, ?ERR_BAD_REQUEST}
- end).
-
--define(SET_STRING_XOPT(Opt, Val),
- set_xoption(Opts, add_opt(Opt, Val, NewOpts))).
-
--define(SET_INTEGER_XOPT(Opt, Val, Min, Max),
- case catch list_to_integer(Val) of
- IVal when is_integer(IVal),
- IVal >= Min,
- IVal =< Max ->
- set_xoption(Opts, add_opt(Opt, IVal, NewOpts));
- _ ->
- {error, ?ERR_BAD_REQUEST}
- end).
-
--define(SET_ALIST_XOPT(Opt, Val, Vals),
- case lists:member(Val, [atom_to_list(V) || V <- Vals]) of
- true ->
- set_xoption(Opts, add_opt(Opt, list_to_atom(Val), NewOpts));
- false ->
- {error, ?ERR_BAD_REQUEST}
- end).
-
-
-set_xoption([], NewOpts) ->
- NewOpts;
-set_xoption([{"FORM_TYPE", _} | Opts], NewOpts) ->
- set_xoption(Opts, NewOpts);
-set_xoption([{"pubsub#deliver_payloads", [Val]} | Opts], NewOpts) ->
- ?SET_BOOL_XOPT(deliver_payloads, Val);
-set_xoption([{"pubsub#notify_config", [Val]} | Opts], NewOpts) ->
- ?SET_BOOL_XOPT(notify_config, Val);
-set_xoption([{"pubsub#notify_delete", [Val]} | Opts], NewOpts) ->
- ?SET_BOOL_XOPT(notify_delete, Val);
-set_xoption([{"pubsub#notify_retract", [Val]} | Opts], NewOpts) ->
- ?SET_BOOL_XOPT(notify_retract, Val);
-set_xoption([{"pubsub#persist_items", [Val]} | Opts], NewOpts) ->
- ?SET_BOOL_XOPT(persist_items, Val);
-set_xoption([{"pubsub#max_items", [Val]} | Opts], NewOpts) ->
- ?SET_INTEGER_XOPT(max_items, Val, 0, ?MAXITEMS);
-set_xoption([{"pubsub#subscribe", [Val]} | Opts], NewOpts) ->
- ?SET_BOOL_XOPT(subscribe, Val);
-set_xoption([{"pubsub#subscription_model", [Val]} | Opts], NewOpts) ->
- ?SET_ALIST_XOPT(subscription_model, Val, [open]);
-set_xoption([{"pubsub#publish_model", [Val]} | Opts], NewOpts) ->
- ?SET_ALIST_XOPT(publish_model, Val, [publishers, subscribers, open]);
-set_xoption([{"pubsub#max_payload_size", [Val]} | Opts], NewOpts) ->
- ?SET_INTEGER_XOPT(max_payload_size, Val, 0, ?MAX_PAYLOAD_SIZE);
-set_xoption([{"pubsub#send_item_subscribe", [Val]} | Opts], NewOpts) ->
- ?SET_BOOL_XOPT(send_item_subscribe, Val);
-set_xoption([{"pubsub#presence_based_delivery", [Val]} | Opts], NewOpts) ->
- ?SET_BOOL_XOPT(presence_based_delivery, Val);
-set_xoption([{"pubsub#current_approver", _} | Opts], NewOpts) ->
- % TODO
- set_xoption(Opts, NewOpts);
-%set_xoption([{"title", [Val]} | Opts], NewOpts) ->
-% ?SET_STRING_XOPT(title, Val);
-set_xoption([_ | _Opts], _NewOpts) ->
- {error, ?ERR_BAD_REQUEST}.
-
-
-change_node_opts(Host, NewOpts, Node, Lang) ->
- F = fun() ->
- case mnesia:read({pubsub_node, {Host, Node}}) of
- [#pubsub_node{info = Info} = N] ->
- NewInfo = Info#nodeinfo{options = NewOpts},
- mnesia:write(
- N#pubsub_node{info = NewInfo}),
- {result, []};
- [] ->
- {error, ?ERR_ITEM_NOT_FOUND}
- end
- end,
- case mnesia:transaction(F) of
- {atomic, {error, _} = Error} ->
- Error;
- {atomic, {result, Res}} ->
- broadcast_config_notification(Host, Node, Lang),
- {result, Res};
- _ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end.
-
-
-
-
-
-find_my_host(LServer) ->
- Parts = string:tokens(LServer, "."),
- find_my_host(Parts, ?MYHOSTS).
-
-find_my_host([], _Hosts) ->
- ?MYNAME;
-find_my_host([_ | Tail] = Parts, Hosts) ->
- Domain = parts_to_string(Parts),
- case lists:member(Domain, Hosts) of
- true ->
- Domain;
- false ->
- find_my_host(Tail, Hosts)
- end.
-
-parts_to_string(Parts) ->
- string:strip(lists:flatten(lists:map(fun(S) -> [S, $.] end, Parts)),
- right, $.).
-
-
-
-update_table(Host) ->
- Fields = record_info(fields, pubsub_node),
- case mnesia:table_info(pubsub_node, attributes) of
- Fields ->
- ok;
- [node, parent, info] ->
- ?INFO_MSG("Converting pubsub_node table from "
- "{node, parent, info} format", []),
- {atomic, ok} = mnesia:create_table(
- mod_pubsub_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, pubsub_node},
- {attributes, record_info(fields, pubsub_node)}]),
- mnesia:del_table_index(pubsub_node, parent),
- mnesia:transform_table(pubsub_node, ignore, Fields),
- F1 = fun() ->
- mnesia:write_lock_table(mod_pubsub_tmp_table),
- mnesia:foldl(
- fun(#pubsub_node{host_node = N,
- host_parent = P} = R, _) ->
- mnesia:dirty_write(
- mod_pubsub_tmp_table,
- R#pubsub_node{host_node = {Host, N},
- host_parent = {Host, P}})
- end, ok, pubsub_node)
- end,
- mnesia:transaction(F1),
- mnesia:clear_table(pubsub_node),
- F2 = fun() ->
- mnesia:write_lock_table(pubsub_node),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_pubsub_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_pubsub_tmp_table);
- _ ->
- ?INFO_MSG("Recreating pubsub_node table", []),
- mnesia:transform_table(pubsub_node, ignore, Fields)
- end.
-
-
-
-
diff --git a/ejabberd-1.1.2/src/mod_register.erl b/ejabberd-1.1.2/src/mod_register.erl
deleted file mode 100644
index a5621f0f3..000000000
--- a/ejabberd-1.1.2/src/mod_register.erl
+++ /dev/null
@@ -1,228 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_register.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Inband registration support
-%%% Created : 8 Dec 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_register).
--author('alexey@sevcom.net').
-
--behaviour(gen_mod).
-
--export([start/2,
- stop/1,
- stream_feature_register/1,
- unauthenticated_iq_register/3,
- process_iq/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
-start(Host, Opts) ->
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_REGISTER,
- ?MODULE, process_iq, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_REGISTER,
- ?MODULE, process_iq, IQDisc),
- ejabberd_hooks:add(c2s_stream_features, Host,
- ?MODULE, stream_feature_register, 50),
- ejabberd_hooks:add(c2s_unauthenticated_iq, Host,
- ?MODULE, unauthenticated_iq_register, 50),
- ok.
-
-stop(Host) ->
- ejabberd_hooks:delete(c2s_stream_features, Host,
- ?MODULE, stream_feature_register, 50),
- ejabberd_hooks:delete(c2s_unauthenticated_iq, Host,
- ?MODULE, unauthenticated_iq_register, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_REGISTER),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_REGISTER).
-
-
-stream_feature_register(Acc) ->
- [{xmlelement, "register",
- [{"xmlns", ?NS_FEATURE_IQREGISTER}], []} | Acc].
-
-unauthenticated_iq_register(_Acc, Server, #iq{xmlns = ?NS_REGISTER} = IQ) ->
- ResIQ = process_iq(jlib:make_jid("", "", ""),
- jlib:make_jid("", Server, ""),
- IQ),
- Res1 = jlib:replace_from_to(jlib:make_jid("", Server, ""),
- jlib:make_jid("", "", ""),
- jlib:iq_to_xml(ResIQ)),
- jlib:remove_attr("to", Res1);
-
-unauthenticated_iq_register(Acc, _Server, _IQ) ->
- Acc.
-
-process_iq(From, To,
- #iq{type = Type, lang = Lang, sub_el = SubEl, id = ID} = IQ) ->
- case Type of
- set ->
- UTag = xml:get_subtag(SubEl, "username"),
- PTag = xml:get_subtag(SubEl, "password"),
- RTag = xml:get_subtag(SubEl, "remove"),
- Server = To#jid.lserver,
- if
- (UTag /= false) and (RTag /= false) ->
- User = xml:get_tag_cdata(UTag),
- case From of
- #jid{user = User, lserver = Server} ->
- ejabberd_auth:remove_user(User, Server),
- IQ#iq{type = result, sub_el = [SubEl]};
- _ ->
- if
- PTag /= false ->
- Password = xml:get_tag_cdata(PTag),
- case ejabberd_auth:remove_user(User,
- Server,
- Password) of
- ok ->
- IQ#iq{type = result,
- sub_el = [SubEl]};
- not_allowed ->
- IQ#iq{type = error,
- sub_el =
- [SubEl, ?ERR_NOT_ALLOWED]};
- not_exists ->
- IQ#iq{type = error,
- sub_el =
- [SubEl, ?ERR_ITEM_NOT_FOUND]};
- _ ->
- IQ#iq{type = error,
- sub_el =
- [SubEl,
- ?ERR_INTERNAL_SERVER_ERROR]}
- end;
- true ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_BAD_REQUEST]}
- end
- end;
- (UTag == false) and (RTag /= false) ->
- case From of
- #jid{user = User,
- lserver = Server,
- resource = Resource} ->
- ResIQ = #iq{type = result, xmlns = ?NS_REGISTER,
- id = ID,
- sub_el = [SubEl]},
- ejabberd_router:route(
- jlib:make_jid(User, Server, Resource),
- jlib:make_jid(User, Server, Resource),
- jlib:iq_to_xml(ResIQ)),
- ejabberd_auth:remove_user(User, Server),
- ignore;
- _ ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
- end;
- (UTag /= false) and (PTag /= false) ->
- User = xml:get_tag_cdata(UTag),
- Password = xml:get_tag_cdata(PTag),
- case From of
- #jid{user = User, lserver = Server} ->
- ejabberd_auth:set_password(User, Server, Password),
- IQ#iq{type = result, sub_el = [SubEl]};
- _ ->
- case try_register(User, Server, Password) of
- ok ->
- IQ#iq{type = result, sub_el = [SubEl]};
- {error, Error} ->
- IQ#iq{type = error,
- sub_el = [SubEl, Error]}
- end
- end;
- true ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_BAD_REQUEST]}
- end;
- get ->
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", "jabber:iq:register"}],
- [{xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang,
- "Choose a username and password "
- "to register with this server")}]},
- {xmlelement, "username", [], []},
- {xmlelement, "password", [], []}]}]}
- end.
-
-
-try_register(User, Server, Password) ->
- case jlib:is_nodename(User) of
- false ->
- {error, ?ERR_BAD_REQUEST};
- _ ->
- JID = jlib:make_jid(User, Server, ""),
- Access = gen_mod:get_module_opt(Server, ?MODULE, access, all),
- case acl:match_rule(Server, Access, JID) of
- deny ->
- {error, ?ERR_CONFLICT};
- allow ->
- case ejabberd_auth:try_register(User, Server, Password) of
- {atomic, ok} ->
- send_welcome_message(JID),
- send_registration_notifications(JID),
- ok;
- {atomic, exists} ->
- {error, ?ERR_CONFLICT};
- {error, invalid_jid} ->
- {error, ?ERR_JID_MALFORMED};
- {error, not_allowed} ->
- {error, ?ERR_NOT_ALLOWED};
- {error, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
- end
- end
- end.
-
-
-send_welcome_message(JID) ->
- Host = JID#jid.lserver,
- case ejabberd_config:get_local_option({welcome_message, Host}) of
- {"", ""} ->
- ok;
- {Subj, Body} ->
- ejabberd_router:route(
- jlib:make_jid("", Host, ""),
- JID,
- {xmlelement, "message", [{"type", "normal"}],
- [{xmlelement, "subject", [], [{xmlcdata, Subj}]},
- {xmlelement, "body", [], [{xmlcdata, Body}]}]});
- _ ->
- ok
- end.
-
-send_registration_notifications(UJID) ->
- Host = UJID#jid.lserver,
- case ejabberd_config:get_local_option({registration_watchers, Host}) of
- [] -> ok;
- JIDs when is_list(JIDs) ->
- Body = lists:flatten(
- io_lib:format(
- "The user '~s' was just created on node ~w.",
- [jlib:jid_to_string(UJID), node()])),
- lists:foreach(
- fun(S) ->
- case jlib:string_to_jid(S) of
- error -> ok;
- JID ->
- ejabberd_router:route(
- jlib:make_jid("", Host, ""),
- JID,
- {xmlelement, "message", [{"type", "chat"}],
- [{xmlelement, "body", [],
- [{xmlcdata, Body}]}]})
- end
- end, JIDs);
- _ ->
- ok
- end.
-
diff --git a/ejabberd-1.1.2/src/mod_roster.erl b/ejabberd-1.1.2/src/mod_roster.erl
deleted file mode 100644
index 04d539cbf..000000000
--- a/ejabberd-1.1.2/src/mod_roster.erl
+++ /dev/null
@@ -1,766 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_roster.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Roster management
-%%% Created : 11 Dec 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_roster).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_mod).
-
--export([start/2, stop/1,
- process_iq/3,
- process_local_iq/3,
- get_user_roster/2,
- get_subscription_lists/3,
- get_in_pending_subscriptions/3,
- in_subscription/6,
- out_subscription/4,
- set_items/3,
- remove_user/2,
- get_jid_info/4]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include("mod_roster.hrl").
-
-
-start(Host, Opts) ->
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- mnesia:create_table(roster,[{disc_copies, [node()]},
- {attributes, record_info(fields, roster)}]),
- update_table(),
- mnesia:add_table_index(roster, us),
- ejabberd_hooks:add(roster_get, Host,
- ?MODULE, get_user_roster, 50),
- ejabberd_hooks:add(roster_in_subscription, Host,
- ?MODULE, in_subscription, 50),
- ejabberd_hooks:add(roster_out_subscription, Host,
- ?MODULE, out_subscription, 50),
- ejabberd_hooks:add(roster_get_subscription_lists, Host,
- ?MODULE, get_subscription_lists, 50),
- ejabberd_hooks:add(roster_get_jid_info, Host,
- ?MODULE, get_jid_info, 50),
- ejabberd_hooks:add(remove_user, Host,
- ?MODULE, remove_user, 50),
- ejabberd_hooks:add(resend_subscription_requests_hook, Host,
- ?MODULE, get_in_pending_subscriptions, 50),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
- ?MODULE, process_iq, IQDisc).
-
-stop(Host) ->
- ejabberd_hooks:delete(roster_get, Host,
- ?MODULE, get_user_roster, 50),
- ejabberd_hooks:delete(roster_in_subscription, Host,
- ?MODULE, in_subscription, 50),
- ejabberd_hooks:delete(roster_out_subscription, Host,
- ?MODULE, out_subscription, 50),
- ejabberd_hooks:delete(roster_get_subscription_lists, Host,
- ?MODULE, get_subscription_lists, 50),
- ejabberd_hooks:delete(roster_get_jid_info, Host,
- ?MODULE, get_jid_info, 50),
- ejabberd_hooks:delete(remove_user, Host,
- ?MODULE, remove_user, 50),
- ejabberd_hooks:delete(resend_subscription_requests_hook, Host,
- ?MODULE, get_in_pending_subscriptions, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ROSTER).
-
-
--define(PSI_ROSTER_WORKAROUND, true).
-
--ifdef(PSI_ROSTER_WORKAROUND).
-
-process_iq(From, To, IQ) ->
- #iq{sub_el = SubEl} = IQ,
- #jid{lserver = LServer} = From,
- case lists:member(LServer, ?MYHOSTS) of
- true ->
- ResIQ = process_local_iq(From, To, IQ),
- ejabberd_router:route(From, From,
- jlib:iq_to_xml(ResIQ)),
- ignore;
- _ ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}
- end.
-
--else.
-
-process_iq(From, To, IQ) ->
- #iq{sub_el = SubEl} = IQ,
- #jid{lserver = LServer} = From,
- case lists:member(LServer, ?MYHOSTS) of
- true ->
- process_local_iq(From, To, IQ);
- _ ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}
- end.
-
--endif.
-
-process_local_iq(From, To, #iq{type = Type} = IQ) ->
- case Type of
- set ->
- process_iq_set(From, To, IQ);
- get ->
- process_iq_get(From, To, IQ)
- end.
-
-
-
-process_iq_get(From, To, #iq{sub_el = SubEl} = IQ) ->
- LUser = From#jid.luser,
- LServer = From#jid.lserver,
- US = {LUser, LServer},
- case catch ejabberd_hooks:run_fold(roster_get, To#jid.lserver, [], [US]) of
- Items when is_list(Items) ->
- XItems = lists:map(fun item_to_xml/1, Items),
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_ROSTER}],
- XItems}]};
- _ ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
- end.
-
-get_user_roster(Acc, US) ->
- case catch mnesia:dirty_index_read(roster, US, #roster.us) of
- Items when is_list(Items) ->
- Items ++ Acc;
- _ ->
- Acc
- end.
-
-
-item_to_xml(Item) ->
- Attrs1 = [{"jid", jlib:jid_to_string(Item#roster.jid)}],
- Attrs2 = case Item#roster.name of
- "" ->
- Attrs1;
- Name ->
- [{"name", Name} | Attrs1]
- end,
- Attrs3 = case Item#roster.subscription of
- none ->
- [{"subscription", "none"} | Attrs2];
- from ->
- [{"subscription", "from"} | Attrs2];
- to ->
- [{"subscription", "to"} | Attrs2];
- both ->
- [{"subscription", "both"} | Attrs2];
- remove ->
- [{"subscription", "remove"} | Attrs2]
- end,
- Attrs4 = case ask_to_pending(Item#roster.ask) of
- out ->
- [{"ask", "subscribe"} | Attrs3];
- both ->
- [{"ask", "subscribe"} | Attrs3];
- _ ->
- Attrs3
- end,
- SubEls1 = lists:map(fun(G) ->
- {xmlelement, "group", [], [{xmlcdata, G}]}
- end, Item#roster.groups),
- SubEls = SubEls1 ++ Item#roster.xs,
- {xmlelement, "item", Attrs4, SubEls}.
-
-
-process_iq_set(From, To, #iq{sub_el = SubEl} = IQ) ->
- {xmlelement, _Name, _Attrs, Els} = SubEl,
- lists:foreach(fun(El) -> process_item_set(From, To, El) end, Els),
- IQ#iq{type = result, sub_el = []}.
-
-process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) ->
- JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
- #jid{user = User, luser = LUser, lserver = LServer} = From,
- case JID1 of
- error ->
- ok;
- _ ->
- JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
- LJID = jlib:jid_tolower(JID1),
- F = fun() ->
- Res = mnesia:read({roster, {LUser, LServer, LJID}}),
- Item = case Res of
- [] ->
- #roster{usj = {LUser, LServer, LJID},
- us = {LUser, LServer},
- jid = JID};
- [I] ->
- I#roster{jid = JID,
- name = "",
- groups = [],
- xs = []}
- end,
- Item1 = process_item_attrs(Item, Attrs),
- Item2 = process_item_els(Item1, Els),
- case Item2#roster.subscription of
- remove ->
- mnesia:delete({roster, {LUser, LServer, LJID}});
- _ ->
- mnesia:write(Item2)
- end,
- %% If the item exist in shared roster, take the
- %% subscription information from there:
- Item3 = ejabberd_hooks:run_fold(roster_process_item,
- LServer, Item2, [LServer]),
- {Item, Item3}
- end,
- case mnesia:transaction(F) of
- {atomic, {OldItem, Item}} ->
- push_item(User, LServer, To, Item),
- case Item#roster.subscription of
- remove ->
- IsTo = case OldItem#roster.subscription of
- both -> true;
- to -> true;
- _ -> false
- end,
- IsFrom = case OldItem#roster.subscription of
- both -> true;
- from -> true;
- _ -> false
- end,
- if IsTo ->
- ejabberd_router:route(
- jlib:jid_remove_resource(From),
- jlib:make_jid(OldItem#roster.jid),
- {xmlelement, "presence",
- [{"type", "unsubscribe"}],
- []});
- true -> ok
- end,
- if IsFrom ->
- ejabberd_router:route(
- jlib:jid_remove_resource(From),
- jlib:make_jid(OldItem#roster.jid),
- {xmlelement, "presence",
- [{"type", "unsubscribed"}],
- []});
- true -> ok
- end,
- ok;
- _ ->
- ok
- end;
- E ->
- ?DEBUG("ROSTER: roster item set error: ~p~n", [E]),
- ok
- end
- end;
-process_item_set(_From, _To, _) ->
- ok.
-
-process_item_attrs(Item, [{Attr, Val} | Attrs]) ->
- case Attr of
- "jid" ->
- case jlib:string_to_jid(Val) of
- error ->
- process_item_attrs(Item, Attrs);
- JID1 ->
- JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
- process_item_attrs(Item#roster{jid = JID}, Attrs)
- end;
- "name" ->
- process_item_attrs(Item#roster{name = Val}, Attrs);
- "subscription" ->
- case Val of
- "remove" ->
- process_item_attrs(Item#roster{subscription = remove},
- Attrs);
- _ ->
- process_item_attrs(Item, Attrs)
- end;
- "ask" ->
- process_item_attrs(Item, Attrs);
- _ ->
- process_item_attrs(Item, Attrs)
- end;
-process_item_attrs(Item, []) ->
- Item.
-
-
-process_item_els(Item, [{xmlelement, Name, Attrs, SEls} | Els]) ->
- case Name of
- "group" ->
- Groups = [xml:get_cdata(SEls) | Item#roster.groups],
- process_item_els(Item#roster{groups = Groups}, Els);
- _ ->
- case xml:get_attr_s("xmlns", Attrs) of
- "" ->
- process_item_els(Item, Els);
- _ ->
- XEls = [{xmlelement, Name, Attrs, SEls} | Item#roster.xs],
- process_item_els(Item#roster{xs = XEls}, Els)
- end
- end;
-process_item_els(Item, [{xmlcdata, _} | Els]) ->
- process_item_els(Item, Els);
-process_item_els(Item, []) ->
- Item.
-
-
-push_item(User, Server, From, Item) ->
- ejabberd_sm:route(jlib:make_jid("", "", ""),
- jlib:make_jid(User, Server, ""),
- {xmlelement, "broadcast", [],
- [{item,
- Item#roster.jid,
- Item#roster.subscription}]}),
- lists:foreach(fun(Resource) ->
- push_item(User, Server, Resource, From, Item)
- end, ejabberd_sm:get_user_resources(User, Server)).
-
-% TODO: don't push to those who didn't load roster
--ifdef(PSI_ROSTER_WORKAROUND).
-
-push_item(User, Server, Resource, _From, Item) ->
- ResIQ = #iq{type = set, xmlns = ?NS_ROSTER,
- id = "push",
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_ROSTER}],
- [item_to_xml(Item)]}]},
- ejabberd_router:route(
- jlib:make_jid(User, Server, Resource),
- jlib:make_jid(User, Server, Resource),
- jlib:iq_to_xml(ResIQ)).
-
--else.
-
-push_item(User, Server, Resource, From, Item) ->
- ResIQ = #iq{type = set, xmlns = ?NS_ROSTER,
- id = "push",
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_ROSTER}],
- [item_to_xml(Item)]}]},
- ejabberd_router:route(
- From,
- jlib:make_jid(User, Server, Resource),
- jlib:iq_to_xml(ResIQ)).
-
--endif.
-
-get_subscription_lists(_, User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- case mnesia:dirty_index_read(roster, US, #roster.us) of
- Items when is_list(Items) ->
- fill_subscription_lists(Items, [], []);
- _ ->
- {[], []}
- end.
-
-fill_subscription_lists([I | Is], F, T) ->
- J = element(3, I#roster.usj),
- case I#roster.subscription of
- both ->
- fill_subscription_lists(Is, [J | F], [J | T]);
- from ->
- fill_subscription_lists(Is, [J | F], T);
- to ->
- fill_subscription_lists(Is, F, [J | T]);
- _ ->
- fill_subscription_lists(Is, F, T)
- end;
-fill_subscription_lists([], F, T) ->
- {F, T}.
-
-ask_to_pending(subscribe) -> out;
-ask_to_pending(unsubscribe) -> none;
-ask_to_pending(Ask) -> Ask.
-
-
-
-in_subscription(_, User, Server, JID, Type, Reason) ->
- process_subscription(in, User, Server, JID, Type, Reason).
-
-out_subscription(User, Server, JID, Type) ->
- process_subscription(out, User, Server, JID, Type, []).
-
-process_subscription(Direction, User, Server, JID1, Type, Reason) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- LJID = jlib:jid_tolower(JID1),
- F = fun() ->
- Item = case mnesia:read({roster, {LUser, LServer, LJID}}) of
- [] ->
- JID = {JID1#jid.user,
- JID1#jid.server,
- JID1#jid.resource},
- #roster{usj = {LUser, LServer, LJID},
- us = US,
- jid = JID};
- [I] ->
- I
- end,
- NewState = case Direction of
- out ->
- out_state_change(Item#roster.subscription,
- Item#roster.ask,
- Type);
- in ->
- in_state_change(Item#roster.subscription,
- Item#roster.ask,
- Type)
- end,
- AutoReply = case Direction of
- out ->
- none;
- in ->
- in_auto_reply(Item#roster.subscription,
- Item#roster.ask,
- Type)
- end,
- AskMessage = case NewState of
- {_, both} -> Reason;
- {_, in} -> Reason;
- _ -> ""
- end,
- case NewState of
- none ->
- {none, AutoReply};
- {Subscription, Pending} ->
- NewItem = Item#roster{subscription = Subscription,
- ask = Pending,
- askmessage = list_to_binary(AskMessage)},
- mnesia:write(NewItem),
- {{push, NewItem}, AutoReply}
- end
- end,
- case mnesia:transaction(F) of
- {atomic, {Push, AutoReply}} ->
- case AutoReply of
- none ->
- ok;
- _ ->
- T = case AutoReply of
- subscribed -> "subscribed";
- unsubscribed -> "unsubscribed"
- end,
- ejabberd_router:route(
- jlib:make_jid(User, Server, ""), JID1,
- {xmlelement, "presence", [{"type", T}], []})
- end,
- case Push of
- {push, Item} ->
- push_item(User, Server,
- jlib:make_jid("", Server, ""), Item),
- true;
- none ->
- false
- end;
- _ ->
- false
- end.
-
-%% in_state_change(Subscription, Pending, Type) -> NewState
-%% NewState = none | {NewSubscription, NewPending}
--ifdef(ROSTER_GATEWAY_WORKAROUND).
--define(NNSD, {to, none}).
--define(NISD, {to, in}).
--else.
--define(NNSD, none).
--define(NISD, none).
--endif.
-
-in_state_change(none, none, subscribe) -> {none, in};
-in_state_change(none, none, subscribed) -> ?NNSD;
-in_state_change(none, none, unsubscribe) -> none;
-in_state_change(none, none, unsubscribed) -> none;
-in_state_change(none, out, subscribe) -> {none, both};
-in_state_change(none, out, subscribed) -> {to, none};
-in_state_change(none, out, unsubscribe) -> none;
-in_state_change(none, out, unsubscribed) -> {none, none};
-in_state_change(none, in, subscribe) -> none;
-in_state_change(none, in, subscribed) -> ?NISD;
-in_state_change(none, in, unsubscribe) -> {none, none};
-in_state_change(none, in, unsubscribed) -> none;
-in_state_change(none, both, subscribe) -> none;
-in_state_change(none, both, subscribed) -> {to, in};
-in_state_change(none, both, unsubscribe) -> {none, out};
-in_state_change(none, both, unsubscribed) -> {none, in};
-in_state_change(to, none, subscribe) -> {to, in};
-in_state_change(to, none, subscribed) -> none;
-in_state_change(to, none, unsubscribe) -> none;
-in_state_change(to, none, unsubscribed) -> {none, none};
-in_state_change(to, in, subscribe) -> none;
-in_state_change(to, in, subscribed) -> none;
-in_state_change(to, in, unsubscribe) -> {to, none};
-in_state_change(to, in, unsubscribed) -> {none, in};
-in_state_change(from, none, subscribe) -> none;
-in_state_change(from, none, subscribed) -> none;
-in_state_change(from, none, unsubscribe) -> {none, none};
-in_state_change(from, none, unsubscribed) -> none;
-in_state_change(from, out, subscribe) -> none;
-in_state_change(from, out, subscribed) -> {both, none};
-in_state_change(from, out, unsubscribe) -> {none, out};
-in_state_change(from, out, unsubscribed) -> {from, none};
-in_state_change(both, none, subscribe) -> none;
-in_state_change(both, none, subscribed) -> none;
-in_state_change(both, none, unsubscribe) -> {to, none};
-in_state_change(both, none, unsubscribed) -> {from, none}.
-
-out_state_change(none, none, subscribe) -> {none, out};
-out_state_change(none, none, subscribed) -> none;
-out_state_change(none, none, unsubscribe) -> none;
-out_state_change(none, none, unsubscribed) -> none;
-out_state_change(none, out, subscribe) -> {none, out}; %% We need to resend query (RFC3921, section 9.2)
-out_state_change(none, out, subscribed) -> none;
-out_state_change(none, out, unsubscribe) -> {none, none};
-out_state_change(none, out, unsubscribed) -> none;
-out_state_change(none, in, subscribe) -> {none, both};
-out_state_change(none, in, subscribed) -> {from, none};
-out_state_change(none, in, unsubscribe) -> none;
-out_state_change(none, in, unsubscribed) -> {none, none};
-out_state_change(none, both, subscribe) -> none;
-out_state_change(none, both, subscribed) -> {from, out};
-out_state_change(none, both, unsubscribe) -> {none, in};
-out_state_change(none, both, unsubscribed) -> {none, out};
-out_state_change(to, none, subscribe) -> none;
-out_state_change(to, none, subscribed) -> none;
-out_state_change(to, none, unsubscribe) -> {none, none};
-out_state_change(to, none, unsubscribed) -> none;
-out_state_change(to, in, subscribe) -> none;
-out_state_change(to, in, subscribed) -> {both, none};
-out_state_change(to, in, unsubscribe) -> {none, in};
-out_state_change(to, in, unsubscribed) -> {to, none};
-out_state_change(from, none, subscribe) -> {from, out};
-out_state_change(from, none, subscribed) -> none;
-out_state_change(from, none, unsubscribe) -> none;
-out_state_change(from, none, unsubscribed) -> {none, none};
-out_state_change(from, out, subscribe) -> none;
-out_state_change(from, out, subscribed) -> none;
-out_state_change(from, out, unsubscribe) -> {from, none};
-out_state_change(from, out, unsubscribed) -> {none, out};
-out_state_change(both, none, subscribe) -> none;
-out_state_change(both, none, subscribed) -> none;
-out_state_change(both, none, unsubscribe) -> {from, none};
-out_state_change(both, none, unsubscribed) -> {to, none}.
-
-in_auto_reply(from, none, subscribe) -> subscribed;
-in_auto_reply(from, out, subscribe) -> subscribed;
-in_auto_reply(both, none, subscribe) -> subscribed;
-in_auto_reply(none, in, unsubscribe) -> unsubscribed;
-in_auto_reply(none, both, unsubscribe) -> unsubscribed;
-in_auto_reply(to, in, unsubscribe) -> unsubscribed;
-in_auto_reply(from, none, unsubscribe) -> unsubscribed;
-in_auto_reply(from, out, unsubscribe) -> unsubscribed;
-in_auto_reply(both, none, unsubscribe) -> unsubscribed;
-in_auto_reply(_, _, _) -> none.
-
-
-remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- F = fun() ->
- lists:foreach(fun(R) ->
- mnesia:delete_object(R)
- end,
- mnesia:index_read(roster, US, #roster.us))
- end,
- mnesia:transaction(F).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-set_items(User, Server, SubEl) ->
- {xmlelement, _Name, _Attrs, Els} = SubEl,
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- F = fun() ->
- lists:foreach(fun(El) ->
- process_item_set_t(LUser, LServer, El)
- end, Els)
- end,
- mnesia:transaction(F).
-
-process_item_set_t(LUser, LServer, {xmlelement, _Name, Attrs, Els}) ->
- JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
- case JID1 of
- error ->
- ok;
- _ ->
- JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
- LJID = {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource},
- Item = #roster{usj = {LUser, LServer, LJID},
- us = {LUser, LServer},
- jid = JID},
- Item1 = process_item_attrs_ws(Item, Attrs),
- Item2 = process_item_els(Item1, Els),
- case Item2#roster.subscription of
- remove ->
- mnesia:delete({roster, {LUser, LServer, LJID}});
- _ ->
- mnesia:write(Item2)
- end
- end;
-process_item_set_t(_LUser, _LServer, _) ->
- ok.
-
-process_item_attrs_ws(Item, [{Attr, Val} | Attrs]) ->
- case Attr of
- "jid" ->
- case jlib:string_to_jid(Val) of
- error ->
- process_item_attrs_ws(Item, Attrs);
- JID1 ->
- JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
- process_item_attrs_ws(Item#roster{jid = JID}, Attrs)
- end;
- "name" ->
- process_item_attrs_ws(Item#roster{name = Val}, Attrs);
- "subscription" ->
- case Val of
- "remove" ->
- process_item_attrs_ws(Item#roster{subscription = remove},
- Attrs);
- "none" ->
- process_item_attrs_ws(Item#roster{subscription = none},
- Attrs);
- "both" ->
- process_item_attrs_ws(Item#roster{subscription = both},
- Attrs);
- "from" ->
- process_item_attrs_ws(Item#roster{subscription = from},
- Attrs);
- "to" ->
- process_item_attrs_ws(Item#roster{subscription = to},
- Attrs);
- _ ->
- process_item_attrs_ws(Item, Attrs)
- end;
- "ask" ->
- process_item_attrs_ws(Item, Attrs);
- _ ->
- process_item_attrs_ws(Item, Attrs)
- end;
-process_item_attrs_ws(Item, []) ->
- Item.
-
-get_in_pending_subscriptions(Ls, User, Server) ->
- JID = jlib:make_jid(User, Server, ""),
- US = {JID#jid.luser, JID#jid.lserver},
- case mnesia:dirty_index_read(roster, US, #roster.us) of
- Result when list(Result) ->
- Ls ++ lists:map(
- fun(R) ->
- Message = R#roster.askmessage,
- Status = if is_binary(Message) ->
- binary_to_list(Message);
- true ->
- ""
- end,
- {xmlelement, "presence",
- [{"from", jlib:jid_to_string(R#roster.jid)},
- {"to", jlib:jid_to_string(JID)},
- {"type", "subscribe"}],
- [{xmlelement, "status", [],
- [{xmlcdata, Status}]}]}
- end,
- lists:filter(
- fun(R) ->
- case R#roster.ask of
- in -> true;
- both -> true;
- _ -> false
- end
- end,
- Result));
- _ ->
- Ls
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-get_jid_info(_, User, Server, JID) ->
- LUser = jlib:nodeprep(User),
- LJID = jlib:jid_tolower(JID),
- LServer = jlib:nameprep(Server),
- case catch mnesia:dirty_read(roster, {LUser, LServer, LJID}) of
- [#roster{subscription = Subscription, groups = Groups}] ->
- {Subscription, Groups};
- _ ->
- LRJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
- if
- LRJID == LJID ->
- {none, []};
- true ->
- case catch mnesia:dirty_read(
- roster, {LUser, LServer, LRJID}) of
- [#roster{subscription = Subscription,
- groups = Groups}] ->
- {Subscription, Groups};
- _ ->
- {none, []}
- end
- end
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-update_table() ->
- Fields = record_info(fields, roster),
- case mnesia:table_info(roster, attributes) of
- Fields ->
- ok;
- [uj, user, jid, name, subscription, ask, groups, xattrs, xs] ->
- convert_table1(Fields);
- [usj, us, jid, name, subscription, ask, groups, xattrs, xs] ->
- convert_table2(Fields);
- _ ->
- ?INFO_MSG("Recreating roster table", []),
- mnesia:transform_table(roster, ignore, Fields)
- end.
-
-
-%% Convert roster table to support virtual host
-convert_table1(Fields) ->
- ?INFO_MSG("Virtual host support: converting roster table from "
- "{uj, user, jid, name, subscription, ask, groups, xattrs, xs} format", []),
- Host = ?MYNAME,
- {atomic, ok} = mnesia:create_table(
- mod_roster_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, roster},
- {attributes, record_info(fields, roster)}]),
- mnesia:del_table_index(roster, user),
- mnesia:transform_table(roster, ignore, Fields),
- F1 = fun() ->
- mnesia:write_lock_table(mod_roster_tmp_table),
- mnesia:foldl(
- fun(#roster{usj = {U, JID}, us = U} = R, _) ->
- mnesia:dirty_write(
- mod_roster_tmp_table,
- R#roster{usj = {U, Host, JID},
- us = {U, Host}})
- end, ok, roster)
- end,
- mnesia:transaction(F1),
- mnesia:clear_table(roster),
- F2 = fun() ->
- mnesia:write_lock_table(roster),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_roster_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_roster_tmp_table).
-
-
-%% Convert roster table: xattrs fields become
-convert_table2(Fields) ->
- ?INFO_MSG("Converting roster table from "
- "{usj, us, jid, name, subscription, ask, groups, xattrs, xs} format", []),
- mnesia:transform_table(roster, ignore, Fields).
diff --git a/ejabberd-1.1.2/src/mod_roster.hrl b/ejabberd-1.1.2/src/mod_roster.hrl
deleted file mode 100644
index ca882b744..000000000
--- a/ejabberd-1.1.2/src/mod_roster.hrl
+++ /dev/null
@@ -1,18 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_roster.hrl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Roster management
-%%% Created : 5 Mar 2005 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id: mod_roster.hrl 11 2005-03-06 22:36:15Z alexey $
-%%%----------------------------------------------------------------------
-
--record(roster, {usj,
- us,
- jid,
- name = "",
- subscription = none,
- ask = none,
- groups = [],
- askmessage = [],
- xs = []}).
-
diff --git a/ejabberd-1.1.2/src/mod_roster_odbc.erl b/ejabberd-1.1.2/src/mod_roster_odbc.erl
deleted file mode 100644
index 9509cc68c..000000000
--- a/ejabberd-1.1.2/src/mod_roster_odbc.erl
+++ /dev/null
@@ -1,846 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_roster_odbc.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Roster management
-%%% Created : 15 Dec 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_roster_odbc).
--author('alexey@sevcom.net').
-
--behaviour(gen_mod).
-
--export([start/2, stop/1,
- process_iq/3,
- process_local_iq/3,
- get_user_roster/2,
- get_subscription_lists/3,
- get_in_pending_subscriptions/3,
- in_subscription/6,
- out_subscription/4,
- set_items/3,
- remove_user/2,
- get_jid_info/4]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include("mod_roster.hrl").
-
-start(Host, Opts) ->
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- ejabberd_hooks:add(roster_get, Host,
- ?MODULE, get_user_roster, 50),
- ejabberd_hooks:add(roster_in_subscription, Host,
- ?MODULE, in_subscription, 50),
- ejabberd_hooks:add(roster_out_subscription, Host,
- ?MODULE, out_subscription, 50),
- ejabberd_hooks:add(roster_get_subscription_lists, Host,
- ?MODULE, get_subscription_lists, 50),
- ejabberd_hooks:add(roster_get_jid_info, Host,
- ?MODULE, get_jid_info, 50),
- ejabberd_hooks:add(remove_user, Host,
- ?MODULE, remove_user, 50),
- ejabberd_hooks:add(resend_subscription_requests_hook, Host,
- ?MODULE, get_in_pending_subscriptions, 50),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
- ?MODULE, process_iq, IQDisc).
-
-stop(Host) ->
- ejabberd_hooks:delete(roster_get, Host,
- ?MODULE, get_user_roster, 50),
- ejabberd_hooks:delete(roster_in_subscription, Host,
- ?MODULE, in_subscription, 50),
- ejabberd_hooks:delete(roster_out_subscription, Host,
- ?MODULE, out_subscription, 50),
- ejabberd_hooks:delete(roster_get_subscription_lists, Host,
- ?MODULE, get_subscription_lists, 50),
- ejabberd_hooks:delete(roster_get_jid_info, Host,
- ?MODULE, get_jid_info, 50),
- ejabberd_hooks:delete(remove_user, Host,
- ?MODULE, remove_user, 50),
- ejabberd_hooks:delete(resend_subscription_requests_hook, Host,
- ?MODULE, get_in_pending_subscriptions, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ROSTER).
-
-
--define(PSI_ROSTER_WORKAROUND, true).
-
--ifdef(PSI_ROSTER_WORKAROUND).
-
-process_iq(From, To, IQ) ->
- #iq{sub_el = SubEl} = IQ,
- #jid{lserver = LServer} = From,
- case lists:member(LServer, ?MYHOSTS) of
- true ->
- ResIQ = process_local_iq(From, To, IQ),
- ejabberd_router:route(From, From,
- jlib:iq_to_xml(ResIQ)),
- ignore;
- _ ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}
- end.
-
--else.
-
-process_iq(From, To, IQ) ->
- #iq{sub_el = SubEl} = IQ,
- #jid{lserver = LServer} = From,
- case lists:member(LServer, ?MYHOSTS) of
- true ->
- process_local_iq(From, To, IQ);
- _ ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}
- end.
-
--endif.
-
-process_local_iq(From, To, #iq{type = Type} = IQ) ->
- case Type of
- set ->
- process_iq_set(From, To, IQ);
- get ->
- process_iq_get(From, To, IQ)
- end.
-
-
-
-process_iq_get(From, To, #iq{sub_el = SubEl} = IQ) ->
- LUser = From#jid.luser,
- LServer = From#jid.lserver,
- US = {LUser, LServer},
- case catch ejabberd_hooks:run_fold(roster_get, To#jid.lserver, [], [US]) of
- Items when is_list(Items) ->
- XItems = lists:map(fun item_to_xml/1, Items),
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_ROSTER}],
- XItems}]};
- _ ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
- end.
-
-get_user_roster(Acc, {LUser, LServer}) ->
- Username = ejabberd_odbc:escape(LUser),
- case catch odbc_queries:get_roster(LServer, Username) of
- {selected, ["username", "jid", "nick", "subscription", "ask",
- "askmessage", "server", "subscribe", "type"],
- Items} when is_list(Items) ->
- JIDGroups = case catch odbc_queries:get_roster_jid_groups(LServer, Username) of
- {selected, ["jid","grp"], JGrps}
- when is_list(JGrps) ->
- JGrps;
- _ ->
- []
- end,
- RItems = lists:flatmap(
- fun(I) ->
- case raw_to_record(LServer, I) of
- error ->
- [];
- R ->
- SJID = jlib:jid_to_string(R#roster.jid),
- Groups = lists:flatmap(
- fun({S, G}) when S == SJID ->
- [G];
- (_) ->
- []
- end, JIDGroups),
- [R#roster{groups = Groups}]
- end
- end, Items),
- RItems ++ Acc;
- _ ->
- Acc
- end.
-
-
-item_to_xml(Item) ->
- Attrs1 = [{"jid", jlib:jid_to_string(Item#roster.jid)}],
- Attrs2 = case Item#roster.name of
- "" ->
- Attrs1;
- Name ->
- [{"name", Name} | Attrs1]
- end,
- Attrs3 = case Item#roster.subscription of
- none ->
- [{"subscription", "none"} | Attrs2];
- from ->
- [{"subscription", "from"} | Attrs2];
- to ->
- [{"subscription", "to"} | Attrs2];
- both ->
- [{"subscription", "both"} | Attrs2];
- remove ->
- [{"subscription", "remove"} | Attrs2]
- end,
- Attrs = case ask_to_pending(Item#roster.ask) of
- out ->
- [{"ask", "subscribe"} | Attrs3];
- both ->
- [{"ask", "subscribe"} | Attrs3];
- _ ->
- Attrs3
- end,
- SubEls = lists:map(fun(G) ->
- {xmlelement, "group", [], [{xmlcdata, G}]}
- end, Item#roster.groups),
- {xmlelement, "item", Attrs, SubEls}.
-
-
-process_iq_set(From, To, #iq{sub_el = SubEl} = IQ) ->
- {xmlelement, _Name, _Attrs, Els} = SubEl,
- lists:foreach(fun(El) -> process_item_set(From, To, El) end, Els),
- IQ#iq{type = result, sub_el = []}.
-
-process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) ->
- JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
- #jid{user = User, luser = LUser, lserver = LServer} = From,
- case JID1 of
- error ->
- ok;
- _ ->
- JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
- LJID = jlib:jid_tolower(JID1),
- Username = ejabberd_odbc:escape(LUser),
- SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)),
- F = fun() ->
- {selected,
- ["username", "jid", "nick", "subscription",
- "ask", "askmessage", "server", "subscribe", "type"],
- Res} = odbc_queries:get_roster_by_jid(LServer, Username, SJID),
- Item = case Res of
- [] ->
- #roster{usj = {LUser, LServer, LJID},
- us = {LUser, LServer},
- jid = LJID};
- [I] ->
- (raw_to_record(LServer, I))#roster{
- usj = {LUser, LServer, LJID},
- us = {LUser, LServer},
- jid = LJID,
- name = ""}
- end,
- Item1 = process_item_attrs(Item, Attrs),
- Item2 = process_item_els(Item1, Els),
- case Item2#roster.subscription of
- remove ->
- odbc_queries:del_roster(LServer, Username, SJID);
- _ ->
- ItemVals = record_to_string(Item2),
- ItemGroups = groups_to_string(Item2),
- odbc_queries:update_roster(LServer, Username, SJID, ItemVals, ItemGroups)
- end,
- %% If the item exist in shared roster, take the
- %% subscription information from there:
- Item3 = ejabberd_hooks:run_fold(roster_process_item,
- LServer, Item2, [LServer]),
- {Item, Item3}
- end,
- case odbc_queries:sql_transaction(LServer, F) of
- {atomic, {OldItem, Item}} ->
- push_item(User, LServer, To, Item),
- case Item#roster.subscription of
- remove ->
- IsTo = case OldItem#roster.subscription of
- both -> true;
- to -> true;
- _ -> false
- end,
- IsFrom = case OldItem#roster.subscription of
- both -> true;
- from -> true;
- _ -> false
- end,
- if IsTo ->
- ejabberd_router:route(
- jlib:jid_remove_resource(From),
- jlib:make_jid(OldItem#roster.jid),
- {xmlelement, "presence",
- [{"type", "unsubscribe"}],
- []});
- true -> ok
- end,
- if IsFrom ->
- ejabberd_router:route(
- jlib:jid_remove_resource(From),
- jlib:make_jid(OldItem#roster.jid),
- {xmlelement, "presence",
- [{"type", "unsubscribed"}],
- []});
- true -> ok
- end,
- ok;
- _ ->
- ok
- end;
- E ->
- ?DEBUG("ROSTER: roster item set error: ~p~n", [E]),
- ok
- end
- end;
-process_item_set(_From, _To, _) ->
- ok.
-
-process_item_attrs(Item, [{Attr, Val} | Attrs]) ->
- case Attr of
- "jid" ->
- case jlib:string_to_jid(Val) of
- error ->
- process_item_attrs(Item, Attrs);
- JID1 ->
- JID = {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource},
- process_item_attrs(Item#roster{jid = JID}, Attrs)
- end;
- "name" ->
- process_item_attrs(Item#roster{name = Val}, Attrs);
- "subscription" ->
- case Val of
- "remove" ->
- process_item_attrs(Item#roster{subscription = remove},
- Attrs);
- _ ->
- process_item_attrs(Item, Attrs)
- end;
- "ask" ->
- process_item_attrs(Item, Attrs);
- _ ->
- process_item_attrs(Item, Attrs)
- end;
-process_item_attrs(Item, []) ->
- Item.
-
-
-process_item_els(Item, [{xmlelement, Name, Attrs, SEls} | Els]) ->
- case Name of
- "group" ->
- Groups = [xml:get_cdata(SEls) | Item#roster.groups],
- process_item_els(Item#roster{groups = Groups}, Els);
- _ ->
- process_item_els(Item, Els)
- end;
-process_item_els(Item, [{xmlcdata, _} | Els]) ->
- process_item_els(Item, Els);
-process_item_els(Item, []) ->
- Item.
-
-
-push_item(User, Server, From, Item) ->
- ejabberd_sm:route(jlib:make_jid("", "", ""),
- jlib:make_jid(User, Server, ""),
- {xmlelement, "broadcast", [],
- [{item,
- Item#roster.jid,
- Item#roster.subscription}]}),
- lists:foreach(fun(Resource) ->
- push_item(User, Server, Resource, From, Item)
- end, ejabberd_sm:get_user_resources(User, Server)).
-
-% TODO: don't push to those who not load roster
--ifdef(PSI_ROSTER_WORKAROUND).
-
-push_item(User, Server, Resource, _From, Item) ->
- ResIQ = #iq{type = set, xmlns = ?NS_ROSTER,
- id = "push",
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_ROSTER}],
- [item_to_xml(Item)]}]},
- ejabberd_router:route(
- jlib:make_jid(User, Server, Resource),
- jlib:make_jid(User, Server, Resource),
- jlib:iq_to_xml(ResIQ)).
-
--else.
-
-push_item(User, Resource, From, Item) ->
- ResIQ = #iq{type = set, xmlns = ?NS_ROSTER,
- id = "push",
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_ROSTER}],
- [item_to_xml(Item)]}]},
- ejabberd_router:route(
- From,
- jlib:make_jid(User, Server, Resource),
- jlib:iq_to_xml(ResIQ)).
-
--endif.
-
-get_subscription_lists(_, User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- Username = ejabberd_odbc:escape(LUser),
- case catch odbc_queries:get_roster(LServer, Username) of
- {selected, ["username", "jid", "nick", "subscription", "ask",
- "askmessage", "server", "subscribe", "type"],
- Items} when is_list(Items) ->
- fill_subscription_lists(LServer, Items, [], []);
- _ ->
- {[], []}
- end.
-
-fill_subscription_lists(LServer, [RawI | Is], F, T) ->
- I = raw_to_record(LServer, RawI),
- J = I#roster.jid,
- case I#roster.subscription of
- both ->
- fill_subscription_lists(LServer, Is, [J | F], [J | T]);
- from ->
- fill_subscription_lists(LServer, Is, [J | F], T);
- to ->
- fill_subscription_lists(LServer, Is, F, [J | T]);
- _ ->
- fill_subscription_lists(LServer, Is, F, T)
- end;
-fill_subscription_lists(_LServer, [], F, T) ->
- {F, T}.
-
-ask_to_pending(subscribe) -> out;
-ask_to_pending(unsubscribe) -> none;
-ask_to_pending(Ask) -> Ask.
-
-
-
-in_subscription(_, User, Server, JID, Type, Reason) ->
- process_subscription(in, User, Server, JID, Type, Reason).
-
-out_subscription(User, Server, JID, Type) ->
- process_subscription(out, User, Server, JID, Type, []).
-
-process_subscription(Direction, User, Server, JID1, Type, Reason) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- LJID = jlib:jid_tolower(JID1),
- Username = ejabberd_odbc:escape(LUser),
- SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)),
- F = fun() ->
- Item =
- case odbc_queries:get_roster_by_jid(LServer, Username, SJID) of
- {selected,
- ["username", "jid", "nick", "subscription", "ask",
- "askmessage", "server", "subscribe", "type"],
- [I]} ->
- R = raw_to_record(LServer, I),
- Groups =
- case odbc_queries:get_roster_groups(LServer, Username, SJID) of
- {selected, ["grp"], JGrps} when is_list(JGrps) ->
- [JGrp || {JGrp} <- JGrps];
- _ ->
- []
- end,
- R#roster{groups = Groups};
- {selected,
- ["username", "jid", "nick", "subscription", "ask",
- "askmessage", "server", "subscribe", "type"],
- []} ->
- #roster{usj = {LUser, LServer, LJID},
- us = {LUser, LServer},
- jid = LJID}
- end,
- NewState = case Direction of
- out ->
- out_state_change(Item#roster.subscription,
- Item#roster.ask,
- Type);
- in ->
- in_state_change(Item#roster.subscription,
- Item#roster.ask,
- Type)
- end,
- AutoReply = case Direction of
- out ->
- none;
- in ->
- in_auto_reply(Item#roster.subscription,
- Item#roster.ask,
- Type)
- end,
- AskMessage = case NewState of
- {_, both} -> Reason;
- {_, in} -> Reason;
- _ -> ""
- end,
- case NewState of
- none ->
- {none, AutoReply};
- {Subscription, Pending} ->
- NewItem = Item#roster{subscription = Subscription,
- ask = Pending,
- askmessage = AskMessage},
- ItemVals = record_to_string(NewItem),
- odbc_queries:roster_subscribe(LServer, Username, SJID, ItemVals),
- {{push, NewItem}, AutoReply}
- end
- end,
- case odbc_queries:sql_transaction(LServer, F) of
- {atomic, {Push, AutoReply}} ->
- case AutoReply of
- none ->
- ok;
- _ ->
- T = case AutoReply of
- subscribed -> "subscribed";
- unsubscribed -> "unsubscribed"
- end,
- ejabberd_router:route(
- jlib:make_jid(User, Server, ""), JID1,
- {xmlelement, "presence", [{"type", T}], []})
- end,
- case Push of
- {push, Item} ->
- push_item(User, Server,
- jlib:make_jid("", Server, ""), Item),
- true;
- none ->
- false
- end;
- _ ->
- false
- end.
-
-
-%% in_state_change(Subscription, Pending, Type) -> NewState
-%% NewState = none | {NewSubscription, NewPending}
--ifdef(ROSTER_GATEWAY_WORKAROUND).
--define(NNSD, {to, none}).
--define(NISD, {to, in}).
--else.
--define(NNSD, none).
--define(NISD, none).
--endif.
-
-in_state_change(none, none, subscribe) -> {none, in};
-in_state_change(none, none, subscribed) -> ?NNSD;
-in_state_change(none, none, unsubscribe) -> none;
-in_state_change(none, none, unsubscribed) -> none;
-in_state_change(none, out, subscribe) -> {none, both};
-in_state_change(none, out, subscribed) -> {to, none};
-in_state_change(none, out, unsubscribe) -> none;
-in_state_change(none, out, unsubscribed) -> {none, none};
-in_state_change(none, in, subscribe) -> none;
-in_state_change(none, in, subscribed) -> ?NISD;
-in_state_change(none, in, unsubscribe) -> {none, none};
-in_state_change(none, in, unsubscribed) -> none;
-in_state_change(none, both, subscribe) -> none;
-in_state_change(none, both, subscribed) -> {to, in};
-in_state_change(none, both, unsubscribe) -> {none, out};
-in_state_change(none, both, unsubscribed) -> {none, in};
-in_state_change(to, none, subscribe) -> {to, in};
-in_state_change(to, none, subscribed) -> none;
-in_state_change(to, none, unsubscribe) -> none;
-in_state_change(to, none, unsubscribed) -> {none, none};
-in_state_change(to, in, subscribe) -> none;
-in_state_change(to, in, subscribed) -> none;
-in_state_change(to, in, unsubscribe) -> {to, none};
-in_state_change(to, in, unsubscribed) -> {none, in};
-in_state_change(from, none, subscribe) -> none;
-in_state_change(from, none, subscribed) -> none;
-in_state_change(from, none, unsubscribe) -> {none, none};
-in_state_change(from, none, unsubscribed) -> none;
-in_state_change(from, out, subscribe) -> none;
-in_state_change(from, out, subscribed) -> {both, none};
-in_state_change(from, out, unsubscribe) -> {none, out};
-in_state_change(from, out, unsubscribed) -> {from, none};
-in_state_change(both, none, subscribe) -> none;
-in_state_change(both, none, subscribed) -> none;
-in_state_change(both, none, unsubscribe) -> {to, none};
-in_state_change(both, none, unsubscribed) -> {from, none}.
-
-out_state_change(none, none, subscribe) -> {none, out};
-out_state_change(none, none, subscribed) -> none;
-out_state_change(none, none, unsubscribe) -> none;
-out_state_change(none, none, unsubscribed) -> none;
-out_state_change(none, out, subscribe) -> {none, out}; %% We need to resend query (RFC3921, section 9.2)
-out_state_change(none, out, subscribed) -> none;
-out_state_change(none, out, unsubscribe) -> {none, none};
-out_state_change(none, out, unsubscribed) -> none;
-out_state_change(none, in, subscribe) -> {none, both};
-out_state_change(none, in, subscribed) -> {from, none};
-out_state_change(none, in, unsubscribe) -> none;
-out_state_change(none, in, unsubscribed) -> {none, none};
-out_state_change(none, both, subscribe) -> none;
-out_state_change(none, both, subscribed) -> {from, out};
-out_state_change(none, both, unsubscribe) -> {none, in};
-out_state_change(none, both, unsubscribed) -> {none, out};
-out_state_change(to, none, subscribe) -> none;
-out_state_change(to, none, subscribed) -> none;
-out_state_change(to, none, unsubscribe) -> {none, none};
-out_state_change(to, none, unsubscribed) -> none;
-out_state_change(to, in, subscribe) -> none;
-out_state_change(to, in, subscribed) -> {both, none};
-out_state_change(to, in, unsubscribe) -> {none, in};
-out_state_change(to, in, unsubscribed) -> {to, none};
-out_state_change(from, none, subscribe) -> {from, out};
-out_state_change(from, none, subscribed) -> none;
-out_state_change(from, none, unsubscribe) -> none;
-out_state_change(from, none, unsubscribed) -> {none, none};
-out_state_change(from, out, subscribe) -> none;
-out_state_change(from, out, subscribed) -> none;
-out_state_change(from, out, unsubscribe) -> {from, none};
-out_state_change(from, out, unsubscribed) -> {none, out};
-out_state_change(both, none, subscribe) -> none;
-out_state_change(both, none, subscribed) -> none;
-out_state_change(both, none, unsubscribe) -> {from, none};
-out_state_change(both, none, unsubscribed) -> {to, none}.
-
-in_auto_reply(from, none, subscribe) -> subscribed;
-in_auto_reply(from, out, subscribe) -> subscribed;
-in_auto_reply(both, none, subscribe) -> subscribed;
-in_auto_reply(none, in, unsubscribe) -> unsubscribed;
-in_auto_reply(none, both, unsubscribe) -> unsubscribed;
-in_auto_reply(to, in, unsubscribe) -> unsubscribed;
-in_auto_reply(from, none, unsubscribe) -> unsubscribed;
-in_auto_reply(from, out, unsubscribe) -> unsubscribed;
-in_auto_reply(both, none, unsubscribe) -> unsubscribed;
-in_auto_reply(_, _, _) -> none.
-
-
-remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- Username = ejabberd_odbc:escape(LUser),
- odbc_queries:del_user_roster_t(LServer, Username),
- ok.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-set_items(User, Server, SubEl) ->
- {xmlelement, _Name, _Attrs, Els} = SubEl,
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- catch odbc_queries:transaction(
- LServer,
- lists:map(fun(El) ->
- process_item_set_t(LUser, LServer, El)
- end, Els)).
-
-process_item_set_t(LUser, LServer, {xmlelement, _Name, Attrs, Els}) ->
- JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
- case JID1 of
- error ->
- [];
- _ ->
- JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
- LJID = {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource},
- Username = ejabberd_odbc:escape(LUser),
- SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)),
- Item = #roster{usj = {LUser, LServer, LJID},
- us = {LUser, LServer},
- jid = LJID},
- Item1 = process_item_attrs_ws(Item, Attrs),
- Item2 = process_item_els(Item1, Els),
- case Item2#roster.subscription of
- remove ->
- odbc_queries:del_roster_sql(Username, SJID);
- _ ->
- ItemVals = record_to_string(Item1),
- ItemGroups = groups_to_string(Item2),
- odbc_queries:update_roster_sql(Username, SJID, ItemVals, ItemGroups)
- end
- end;
-process_item_set_t(_LUser, _LServer, _) ->
- [].
-
-process_item_attrs_ws(Item, [{Attr, Val} | Attrs]) ->
- case Attr of
- "jid" ->
- case jlib:string_to_jid(Val) of
- error ->
- process_item_attrs_ws(Item, Attrs);
- JID1 ->
- JID = {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource},
- process_item_attrs_ws(Item#roster{jid = JID}, Attrs)
- end;
- "name" ->
- process_item_attrs_ws(Item#roster{name = Val}, Attrs);
- "subscription" ->
- case Val of
- "remove" ->
- process_item_attrs_ws(Item#roster{subscription = remove},
- Attrs);
- "none" ->
- process_item_attrs_ws(Item#roster{subscription = none},
- Attrs);
- "both" ->
- process_item_attrs_ws(Item#roster{subscription = both},
- Attrs);
- "from" ->
- process_item_attrs_ws(Item#roster{subscription = from},
- Attrs);
- "to" ->
- process_item_attrs_ws(Item#roster{subscription = to},
- Attrs);
- _ ->
- process_item_attrs_ws(Item, Attrs)
- end;
- "ask" ->
- process_item_attrs_ws(Item, Attrs);
- _ ->
- process_item_attrs_ws(Item, Attrs)
- end;
-process_item_attrs_ws(Item, []) ->
- Item.
-
-get_in_pending_subscriptions(Ls, User, Server) ->
- JID = jlib:make_jid(User, Server, ""),
- LUser = JID#jid.luser,
- LServer = JID#jid.lserver,
- Username = ejabberd_odbc:escape(LUser),
- case catch odbc_queries:get_roster(LServer, Username) of
- {selected, ["username", "jid", "nick", "subscription", "ask",
- "askmessage", "server", "subscribe", "type"],
- Items} when is_list(Items) ->
- Ls ++ lists:map(
- fun(R) ->
- Message = R#roster.askmessage,
- {xmlelement, "presence",
- [{"from", jlib:jid_to_string(R#roster.jid)},
- {"to", jlib:jid_to_string(JID)},
- {"type", "subscribe"}],
- [{xmlelement, "status", [],
- [{xmlcdata, Message}]}]}
- end,
- lists:flatmap(
- fun(I) ->
- R = raw_to_record(LServer, I),
- case R#roster.ask of
- in -> [R];
- both -> [R];
- _ -> []
- end
- end,
- Items));
- _ ->
- Ls
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-get_jid_info(_, User, Server, JID) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- LJID = jlib:jid_tolower(JID),
- Username = ejabberd_odbc:escape(LUser),
- SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)),
- case catch odbc_queries:get_subscription(LServer, Username, SJID) of
- {selected, ["subscription"], [{SSubscription}]} ->
- Subscription = case SSubscription of
- "B" -> both;
- "T" -> to;
- "F" -> from;
- _ -> none
- end,
- Groups = case catch odbc_queries:get_roster_group_by_jid(LServer, Username, SJID) of
- {selected, ["grp"], JGrps} when is_list(JGrps) ->
- [JGrp || {JGrp} <- JGrps];
- _ ->
- []
- end,
- {Subscription, Groups};
- _ ->
- LRJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
- if
- LRJID == LJID ->
- {none, []};
- true ->
- SRJID = ejabberd_odbc:escape(jlib:jid_to_string(LRJID)),
- case catch odbc_queries:get_subscription(LServer, Username, SRJID) of
- {selected, ["subscription"], [{SSubscription}]} ->
- Subscription = case SSubscription of
- "B" -> both;
- "T" -> to;
- "F" -> from;
- _ -> none
- end,
- Groups = case catch odbc_queries:get_rostergroup_by_jid(LServer, Username, SRJID) of
- {selected, ["grp"], JGrps} when is_list(JGrps) ->
- [JGrp || {JGrp} <- JGrps];
- _ ->
- []
- end,
- {Subscription, Groups};
- _ ->
- {none, []}
- end
- end
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-raw_to_record(LServer, {User, SJID, Nick, SSubscription, SAsk, SAskMessage,
- _SServer, _SSubscribe, _SType}) ->
- case jlib:string_to_jid(SJID) of
- error ->
- error;
- JID ->
- LJID = jlib:jid_tolower(JID),
- Subscription = case SSubscription of
- "B" -> both;
- "T" -> to;
- "F" -> from;
- _ -> none
- end,
- Ask = case SAsk of
- "S" -> subscribe;
- "U" -> unsubscribe;
- "B" -> both;
- "O" -> out;
- "I" -> in;
- _ -> none
- end,
- #roster{usj = {User, LServer, LJID},
- us = {User, LServer},
- jid = LJID,
- name = Nick,
- subscription = Subscription,
- ask = Ask,
- askmessage = SAskMessage}
- end.
-
-record_to_string(#roster{us = {User, _Server},
- jid = JID,
- name = Name,
- subscription = Subscription,
- ask = Ask,
- askmessage = AskMessage}) ->
- Username = ejabberd_odbc:escape(User),
- SJID = ejabberd_odbc:escape(jlib:jid_to_string(jlib:jid_tolower(JID))),
- Nick = ejabberd_odbc:escape(Name),
- SSubscription = case Subscription of
- both -> "B";
- to -> "T";
- from -> "F";
- none -> "N"
- end,
- SAsk = case Ask of
- subscribe -> "S";
- unsubscribe -> "U";
- both -> "B";
- out -> "O";
- in -> "I";
- none -> "N"
- end,
- ["'", Username, "',"
- "'", SJID, "',"
- "'", Nick, "',"
- "'", SSubscription, "',"
- "'", SAsk, "',"
- "'", AskMessage, "',"
- "'N', '', 'item'"].
-
-groups_to_string(#roster{us = {User, _Server},
- jid = JID,
- groups = Groups}) ->
- Username = ejabberd_odbc:escape(User),
- SJID = ejabberd_odbc:escape(jlib:jid_to_string(jlib:jid_tolower(JID))),
-
- %% Empty groups do not need to be converted to string to be inserted in
- %% the database
- lists:foldl(fun([], Acc) -> Acc;
- (Group, Acc) ->
- String = ["'", Username, "',"
- "'", SJID, "',"
- "'", ejabberd_odbc:escape(Group), "'"],
- [String|Acc] end, [], Groups).
-
diff --git a/ejabberd-1.1.2/src/mod_service_log.erl b/ejabberd-1.1.2/src/mod_service_log.erl
deleted file mode 100644
index aa664015d..000000000
--- a/ejabberd-1.1.2/src/mod_service_log.erl
+++ /dev/null
@@ -1,59 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_service_log.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Copy user messages to logger service
-%%% Created : 24 Aug 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_service_log).
--author('alexey@sevcom.net').
-
--behaviour(gen_mod).
-
--export([start/2,
- stop/1,
- log_user_send/3,
- log_user_receive/4]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
-start(Host, _Opts) ->
- ejabberd_hooks:add(user_send_packet, Host,
- ?MODULE, log_user_send, 50),
- ejabberd_hooks:add(user_receive_packet, Host,
- ?MODULE, log_user_receive, 50),
- ok.
-
-stop(Host) ->
- ejabberd_hooks:delete(user_send_packet, Host,
- ?MODULE, log_user_send, 50),
- ejabberd_hooks:delete(user_receive_packet, Host,
- ?MODULE, log_user_receive, 50),
- ok.
-
-log_user_send(From, To, Packet) ->
- log_packet(From, To, Packet, From#jid.lserver).
-
-log_user_receive(_JID, From, To, Packet) ->
- log_packet(From, To, Packet, To#jid.lserver).
-
-
-log_packet(From, To, {xmlelement, Name, Attrs, Els}, Host) ->
- Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers, []),
- ServerJID = #jid{user = "", server = Host, resource = "",
- luser = "", lserver = Host, lresource = ""},
- NewAttrs = jlib:replace_from_to_attrs(jlib:jid_to_string(From),
- jlib:jid_to_string(To),
- Attrs),
- FixedPacket = {xmlelement, Name, NewAttrs, Els},
- lists:foreach(
- fun(Logger) ->
- ejabberd_router:route(
- ServerJID,
- #jid{user = "", server = Logger, resource = "",
- luser = "", lserver = Logger, lresource = ""},
- {xmlelement, "route", [], [FixedPacket]})
- end, Loggers).
-
diff --git a/ejabberd-1.1.2/src/mod_shared_roster.erl b/ejabberd-1.1.2/src/mod_shared_roster.erl
deleted file mode 100644
index a0160b959..000000000
--- a/ejabberd-1.1.2/src/mod_shared_roster.erl
+++ /dev/null
@@ -1,354 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_shared_roster.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Shared roster management
-%%% Created : 5 Mar 2005 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id: mod_shared_roster.erl 24 2005-04-14 01:15:31Z alexey $
-%%%----------------------------------------------------------------------
-
--module(mod_shared_roster).
--author('alexey@sevcom.net').
-
--behaviour(gen_mod).
-
--export([start/2, stop/1,
- get_user_roster/2,
- get_subscription_lists/3,
- get_jid_info/4,
- process_item/2,
- in_subscription/6,
- out_subscription/4,
- list_groups/1,
- create_group/2,
- create_group/3,
- delete_group/2,
- get_group_opts/2,
- set_group_opts/3,
- get_group_users/2,
- get_group_explicit_users/2,
- add_user_to_group/3,
- remove_user_from_group/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include("mod_roster.hrl").
-
--record(sr_group, {group_host, opts}).
--record(sr_user, {us, group_host}).
-
-start(Host, _Opts) ->
- mnesia:create_table(sr_group,
- [{disc_copies, [node()]},
- {attributes, record_info(fields, sr_group)}]),
- mnesia:create_table(sr_user,
- [{disc_copies, [node()]},
- {type, bag},
- {attributes, record_info(fields, sr_user)}]),
- mnesia:add_table_index(sr_user, group_host),
- ejabberd_hooks:add(roster_get, Host,
- ?MODULE, get_user_roster, 70),
- ejabberd_hooks:add(roster_in_subscription, Host,
- ?MODULE, in_subscription, 30),
- ejabberd_hooks:add(roster_out_subscription, Host,
- ?MODULE, out_subscription, 30),
- ejabberd_hooks:add(roster_get_subscription_lists, Host,
- ?MODULE, get_subscription_lists, 70),
- ejabberd_hooks:add(roster_get_jid_info, Host,
- ?MODULE, get_jid_info, 70),
- ejabberd_hooks:add(roster_process_item, Host,
- ?MODULE, process_item, 50).
- %ejabberd_hooks:add(remove_user, Host,
- % ?MODULE, remove_user, 50),
-
-stop(Host) ->
- ejabberd_hooks:delete(roster_get, Host,
- ?MODULE, get_user_roster, 70),
- ejabberd_hooks:delete(roster_in_subscription, Host,
- ?MODULE, in_subscription, 30),
- ejabberd_hooks:delete(roster_out_subscription, Host,
- ?MODULE, out_subscription, 30),
- ejabberd_hooks:delete(roster_get_subscription_lists, Host,
- ?MODULE, get_subscription_lists, 70),
- ejabberd_hooks:delete(roster_get_jid_info, Host,
- ?MODULE, get_jid_info, 70),
- ejabberd_hooks:delete(roster_process_item, Host,
- ?MODULE, process_item, 50).
- %ejabberd_hooks:delete(remove_user, Host,
- % ?MODULE, remove_user, 50),
-
-
-get_user_roster(Items, US) ->
- {U, S} = US,
- DisplayedGroups = get_user_displayed_groups(US),
- %% Get shared roster users in all groups and remove self:
- SRUsers =
- lists:foldl(
- fun(Group, Acc1) ->
- lists:foldl(
- fun(User, Acc2) ->
- if User == US -> Acc2;
- true -> dict:append(User,
- get_group_name(S, Group),
- Acc2)
- end
- end, Acc1, get_group_users(S, Group))
- end, dict:new(), DisplayedGroups),
-
- %% If partially subscribed users are also in shared roster, show them as
- %% totally subscribed:
- {NewItems1, SRUsersRest} =
- lists:mapfoldl(
- fun(Item, SRUsers1) ->
- {_, _, {U1, S1, _}} = Item#roster.usj,
- US1 = {U1, S1},
- case dict:find(US1, SRUsers1) of
- {ok, _GroupNames} ->
- {Item#roster{subscription = both, ask = none},
- dict:erase(US1, SRUsers1)};
- error ->
- {Item, SRUsers1}
- end
- end, SRUsers, Items),
-
- %% Export items in roster format:
- SRItems = [#roster{usj = {U, S, {U1, S1, ""}},
- us = US,
- jid = {U1, S1, ""},
- name = "",
- subscription = both,
- ask = none,
- groups = GroupNames} ||
- {{U1, S1}, GroupNames} <- dict:to_list(SRUsersRest)],
- SRItems ++ NewItems1.
-
-%% This function in use to rewrite the roster entries when moving or renaming
-%% them in the user contact list.
-process_item(RosterItem, Host) ->
- USFrom = RosterItem#roster.us,
- {User,Server,_Resource} = RosterItem#roster.jid,
- USTo = {User,Server},
- DisplayedGroups = get_user_displayed_groups(USFrom),
- CommonGroups = lists:filter(fun(Group) ->
- is_user_in_group(USTo, Group, Host)
- end, DisplayedGroups),
- case CommonGroups of
- [] -> RosterItem;
- %% Roster item cannot be removed: We simply reset the original groups:
- _ when RosterItem#roster.subscription == remove ->
- GroupNames = lists:map(fun(Group) ->
- get_group_name(Host, Group)
- end, CommonGroups),
- RosterItem#roster{subscription = both, ask = none,
- groups=[GroupNames]};
- _ -> RosterItem#roster{subscription = both, ask = none}
- end.
-
-get_subscription_lists({F, T}, User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- DisplayedGroups = get_user_displayed_groups(US),
- SRUsers =
- lists:usort(
- lists:flatmap(
- fun(Group) ->
- get_group_users(LServer, Group)
- end, DisplayedGroups)),
- SRJIDs = [{U1, S1, ""} || {U1, S1} <- SRUsers],
- {lists:usort(SRJIDs ++ F), lists:usort(SRJIDs ++ T)}.
-
-get_jid_info({Subscription, Groups}, User, Server, JID) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- {U1, S1, _} = jlib:jid_tolower(JID),
- US1 = {U1, S1},
- DisplayedGroups = get_user_displayed_groups(US),
- SRUsers =
- lists:foldl(
- fun(Group, Acc1) ->
- lists:foldl(
- fun(User1, Acc2) ->
- dict:append(
- User1, get_group_name(LServer, Group), Acc2)
- end, Acc1, get_group_users(LServer, Group))
- end, dict:new(), DisplayedGroups),
- case dict:find(US1, SRUsers) of
- {ok, GroupNames} ->
- NewGroups = if
- Groups == [] -> GroupNames;
- true -> Groups
- end,
- {both, NewGroups};
- error ->
- {Subscription, Groups}
- end.
-
-in_subscription(Acc, User, Server, JID, Type, _Reason) ->
- process_subscription(in, User, Server, JID, Type, Acc).
-
-out_subscription(User, Server, JID, Type) ->
- process_subscription(out, User, Server, JID, Type, false).
-
-process_subscription(Direction, User, Server, JID, _Type, Acc) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- {U1, S1, _} = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
- US1 = {U1, S1},
- DisplayedGroups = get_user_displayed_groups(US),
- SRUsers =
- lists:usort(
- lists:flatmap(
- fun(Group) ->
- get_group_users(LServer, Group)
- end, DisplayedGroups)),
- case lists:member(US1, SRUsers) of
- true ->
- case Direction of
- in ->
- {stop, false};
- out ->
- stop
- end;
- false ->
- Acc
- end.
-
-list_groups(Host) ->
- mnesia:dirty_select(
- sr_group,
- [{#sr_group{group_host = {'$1', '$2'},
- _ = '_'},
- [{'==', '$2', Host}],
- ['$1']}]).
-
-create_group(Host, Group) ->
- create_group(Host, Group, []).
-
-create_group(Host, Group, Opts) ->
- R = #sr_group{group_host = {Group, Host}, opts = Opts},
- F = fun() ->
- mnesia:write(R)
- end,
- mnesia:transaction(F).
-
-delete_group(Host, Group) ->
- GroupHost = {Group, Host},
- F = fun() ->
- %% Delete the group ...
- mnesia:delete({sr_group, GroupHost}),
- %% ... and its users
- Users = mnesia:index_read(sr_user, GroupHost, #sr_user.group_host),
- lists:foreach(fun(UserEntry) ->
- mnesia:delete_object(UserEntry)
- end, Users)
- end,
- mnesia:transaction(F).
-
-get_group_opts(Host, Group) ->
- case catch mnesia:dirty_read(sr_group, {Group, Host}) of
- [#sr_group{opts = Opts}] ->
- Opts;
- _ ->
- error
- end.
-
-set_group_opts(Host, Group, Opts) ->
- R = #sr_group{group_host = {Group, Host}, opts = Opts},
- F = fun() ->
- mnesia:write(R)
- end,
- mnesia:transaction(F).
-
-get_user_groups(US) ->
- Host = element(2, US),
- case catch mnesia:dirty_read(sr_user, US) of
- Rs when is_list(Rs) ->
- [Group || #sr_user{group_host = {Group, H}} <- Rs, H == Host];
- _ ->
- []
- end ++ get_all_users_groups(Host).
-
-is_group_enabled(Host, Group) ->
- case catch mnesia:dirty_read(sr_group, {Group, Host}) of
- [#sr_group{opts = Opts}] ->
- not lists:member(disabled, Opts);
- _ ->
- false
- end.
-
-get_group_opt(Host, Group, Opt, Default) ->
- case catch mnesia:dirty_read(sr_group, {Group, Host}) of
- [#sr_group{opts = Opts}] ->
- case lists:keysearch(Opt, 1, Opts) of
- {value, {_, Val}} ->
- Val;
- false ->
- Default
- end;
- _ ->
- false
- end.
-
-get_group_users(Host, Group) ->
- case get_group_opt(Host, Group, all_users, false) of
- true ->
- ejabberd_auth:get_vh_registered_users(Host);
- false ->
- []
- end ++ get_group_explicit_users(Host, Group).
-
-get_group_explicit_users(Host, Group) ->
- case catch mnesia:dirty_index_read(
- sr_user, {Group, Host}, #sr_user.group_host) of
- Rs when is_list(Rs) ->
- [R#sr_user.us || R <- Rs];
- _ ->
- []
- end.
-
-get_group_name(Host, Group) ->
- get_group_opt(Host, Group, name, Group).
-
-get_all_users_groups(Host) ->
- lists:filter(
- fun(Group) -> get_group_opt(Host, Group, all_users, false) end,
- list_groups(Host)).
-
-get_user_displayed_groups(US) ->
- Host = element(2, US),
- DisplayedGroups1 =
- lists:usort(
- lists:flatmap(
- fun(Group) ->
- case is_group_enabled(Host, Group) of
- true ->
- get_group_opt(Host, Group, displayed_groups, []);
- false ->
- []
- end
- end, get_user_groups(US))),
- [Group || Group <- DisplayedGroups1, is_group_enabled(Host, Group)].
-
-is_user_in_group(US, Group, Host) ->
- case catch mnesia:dirty_match_object(
- #sr_user{us=US, group_host={Group, Host}}) of
- [] -> false;
- _ -> true
- end.
-
-add_user_to_group(Host, US, Group) ->
- R = #sr_user{us = US, group_host = {Group, Host}},
- F = fun() ->
- mnesia:write(R)
- end,
- mnesia:transaction(F).
-
-remove_user_from_group(Host, US, Group) ->
- GroupHost = {Group, Host},
- R = #sr_user{us = US, group_host = GroupHost},
- F = fun() ->
- mnesia:delete_object(R)
- end,
- mnesia:transaction(F).
diff --git a/ejabberd-1.1.2/src/mod_stats.erl b/ejabberd-1.1.2/src/mod_stats.erl
deleted file mode 100644
index f379b295f..000000000
--- a/ejabberd-1.1.2/src/mod_stats.erl
+++ /dev/null
@@ -1,234 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_stats.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 11 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_stats).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_mod).
-
--export([start/2,
- stop/1,
- process_local_iq/3]).
-
--include("jlib.hrl").
-
-start(Host, Opts) ->
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_STATS,
- ?MODULE, process_local_iq, IQDisc).
-
-stop(Host) ->
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_STATS).
-
-
-process_local_iq(From, To, #iq{id = ID, type = Type,
- xmlns = XMLNS, sub_el = SubEl} = IQ) ->
- Lang = xml:get_tag_attr_s("xml:lang", SubEl),
- case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- {xmlelement, _, Attrs, Els} = SubEl,
- Node = string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
- Names = get_names(Els, []),
-
- case get_local_stats(To#jid.server, Node, Names) of
- {result, Res} ->
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", XMLNS}],
- Res}]};
- {error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]}
- end
- end.
-
-
-get_names([], Res) ->
- Res;
-get_names([{xmlelement, "stat", Attrs, _} | Els], Res) ->
- Name = xml:get_attr_s("name", Attrs),
- case Name of
- "" ->
- get_names(Els, Res);
- _ ->
- get_names(Els, [Name | Res])
- end;
-get_names([_ | Els], Res) ->
- get_names(Els, Res).
-
-
--define(STAT(Name), {xmlelement, "stat", [{"name", Name}], []}).
-
-get_local_stats(_Server, [], []) ->
- {result,
- [?STAT("users/online"),
- ?STAT("users/total"),
- ?STAT("users/all-hosts/online"),
- ?STAT("users/all-hosts/total")
- ]};
-
-get_local_stats(Server, [], Names) ->
- {result, lists:map(fun(Name) ->
- get_local_stat(Server, [], Name)
- end, Names)};
-
-get_local_stats(_Server, ["running nodes", _], []) ->
- {result,
- [?STAT("time/uptime"),
- ?STAT("time/cputime"),
- ?STAT("users/online"),
- ?STAT("transactions/commited"),
- ?STAT("transactions/aborted"),
- ?STAT("transactions/restarted"),
- ?STAT("transactions/logged")
- ]};
-
-get_local_stats(_Server, ["running nodes", ENode], Names) ->
- case search_running_node(ENode) of
- false ->
- {error, ?ERR_ITEM_NOT_FOUND};
- Node ->
- {result,
- lists:map(fun(Name) -> get_node_stat(Node, Name) end, Names)}
- end;
-
-get_local_stats(_Server, _, _) ->
- {error, ?ERR_FEATURE_NOT_IMPLEMENTED}.
-
-
-
--define(STATVAL(Val, Unit),
- {xmlelement, "stat",
- [{"name", Name},
- {"units", Unit},
- {"value", Val}
- ], []}).
-
--define(STATERR(Code, Desc),
- {xmlelement, "stat",
- [{"name", Name}],
- [{xmlelement, "error",
- [{"code", Code}],
- [{xmlcdata, Desc}]}]}).
-
-
-get_local_stat(Server, [], Name) when Name == "users/online" ->
- case catch ejabberd_sm:get_vh_session_list(Server) of
- {'EXIT', Reason} ->
- ?STATERR("500", "Internal Server Error");
- Users ->
- ?STATVAL(integer_to_list(length(Users)), "users")
- end;
-
-get_local_stat(Server, [], Name) when Name == "users/total" ->
- LServer = jlib:nameprep(Server),
- case catch ejabberd_auth:get_vh_registered_users(Server) of
- {'EXIT', Reason} ->
- ?STATERR("500", "Internal Server Error");
- Users ->
- ?STATVAL(integer_to_list(length(Users)), "users")
- end;
-
-get_local_stat(_Server, [], Name) when Name == "users/all-hosts/online" ->
- case catch mnesia:table_info(session, size) of
- {'EXIT', Reason} ->
- ?STATERR("500", "Internal Server Error");
- Users ->
- ?STATVAL(integer_to_list(Users), "users")
- end;
-
-get_local_stat(_Server, [], Name) when Name == "users/all-hosts/total" ->
- case catch mnesia:table_info(passwd, size) of
- {'EXIT', Reason} ->
- ?STATERR("500", "Internal Server Error");
- Users ->
- ?STATVAL(integer_to_list(Users), "users")
- end;
-
-get_local_stat(_Server, _, Name) ->
- ?STATERR("404", "Not Found").
-
-
-
-get_node_stat(Node, Name) when Name == "time/uptime" ->
- case catch rpc:call(Node, erlang, statistics, [wall_clock]) of
- {badrpc, Reason} ->
- ?STATERR("500", "Internal Server Error");
- CPUTime ->
- ?STATVAL(
- io_lib:format("~.3f", [element(1, CPUTime)/1000]), "seconds")
- end;
-
-get_node_stat(Node, Name) when Name == "time/cputime" ->
- case catch rpc:call(Node, erlang, statistics, [runtime]) of
- {badrpc, Reason} ->
- ?STATERR("500", "Internal Server Error");
- RunTime ->
- ?STATVAL(
- io_lib:format("~.3f", [element(1, RunTime)/1000]), "seconds")
- end;
-
-get_node_stat(Node, Name) when Name == "users/online" ->
- case catch rpc:call(Node, ejabberd_sm, dirty_get_my_sessions_list, []) of
- {badrpc, Reason} ->
- ?STATERR("500", "Internal Server Error");
- Users ->
- ?STATVAL(integer_to_list(length(Users)), "users")
- end;
-
-get_node_stat(Node, Name) when Name == "transactions/commited" ->
- case catch rpc:call(Node, mnesia, system_info, [transaction_commits]) of
- {badrpc, Reason} ->
- ?STATERR("500", "Internal Server Error");
- Transactions ->
- ?STATVAL(integer_to_list(Transactions), "transactions")
- end;
-
-get_node_stat(Node, Name) when Name == "transactions/aborted" ->
- case catch rpc:call(Node, mnesia, system_info, [transaction_failures]) of
- {badrpc, Reason} ->
- ?STATERR("500", "Internal Server Error");
- Transactions ->
- ?STATVAL(integer_to_list(Transactions), "transactions")
- end;
-
-get_node_stat(Node, Name) when Name == "transactions/restarted" ->
- case catch rpc:call(Node, mnesia, system_info, [transaction_restarts]) of
- {badrpc, Reason} ->
- ?STATERR("500", "Internal Server Error");
- Transactions ->
- ?STATVAL(integer_to_list(Transactions), "transactions")
- end;
-
-get_node_stat(Node, Name) when Name == "transactions/logged" ->
- case catch rpc:call(Node, mnesia, system_info, [transaction_log_writes]) of
- {badrpc, Reason} ->
- ?STATERR("500", "Internal Server Error");
- Transactions ->
- ?STATVAL(integer_to_list(Transactions), "transactions")
- end;
-
-get_node_stat(_, Name) ->
- ?STATERR("404", "Not Found").
-
-
-search_running_node(SNode) ->
- search_running_node(SNode, mnesia:system_info(running_db_nodes)).
-
-search_running_node(_, []) ->
- false;
-search_running_node(SNode, [Node | Nodes]) ->
- case atom_to_list(Node) of
- SNode ->
- Node;
- _ ->
- search_running_node(SNode, Nodes)
- end.
-
diff --git a/ejabberd-1.1.2/src/mod_time.erl b/ejabberd-1.1.2/src/mod_time.erl
deleted file mode 100644
index 7ad13ad63..000000000
--- a/ejabberd-1.1.2/src/mod_time.erl
+++ /dev/null
@@ -1,44 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_time.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_time).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_mod).
-
--export([start/2,
- stop/1,
- process_local_iq/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
-
-start(Host, Opts) ->
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_TIME,
- ?MODULE, process_local_iq, IQDisc).
-
-stop(Host) ->
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_TIME).
-
-process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- UTC = jlib:timestamp_to_iso(calendar:universal_time()),
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_TIME}],
- [{xmlelement, "utc", [],
- [{xmlcdata, UTC}]}]}]}
- end.
-
-
diff --git a/ejabberd-1.1.2/src/mod_vcard.erl b/ejabberd-1.1.2/src/mod_vcard.erl
deleted file mode 100644
index 2115d7783..000000000
--- a/ejabberd-1.1.2/src/mod_vcard.erl
+++ /dev/null
@@ -1,807 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_vcard.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 2 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_vcard).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_mod).
-
--export([start/2, init/3, stop/1,
- get_sm_features/5,
- process_local_iq/3,
- process_sm_iq/3,
- reindex_vcards/0,
- remove_user/2]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
-
--define(JUD_MATCHES, 30).
-
--record(vcard_search, {us,
- user, luser,
- fn, lfn,
- family, lfamily,
- given, lgiven,
- middle, lmiddle,
- nickname, lnickname,
- bday, lbday,
- ctry, lctry,
- locality, llocality,
- email, lemail,
- orgname, lorgname,
- orgunit, lorgunit
- }).
--record(vcard, {us, vcard}).
-
--define(PROCNAME, ejabberd_mod_vcard).
-
-start(Host, Opts) ->
- mnesia:create_table(vcard, [{disc_only_copies, [node()]},
- {attributes, record_info(fields, vcard)}]),
- mnesia:create_table(vcard_search,
- [{disc_copies, [node()]},
- {attributes, record_info(fields, vcard_search)}]),
- update_tables(),
- mnesia:add_table_index(vcard_search, luser),
- mnesia:add_table_index(vcard_search, lfn),
- mnesia:add_table_index(vcard_search, lfamily),
- mnesia:add_table_index(vcard_search, lgiven),
- mnesia:add_table_index(vcard_search, lmiddle),
- mnesia:add_table_index(vcard_search, lnickname),
- mnesia:add_table_index(vcard_search, lbday),
- mnesia:add_table_index(vcard_search, lctry),
- mnesia:add_table_index(vcard_search, llocality),
- mnesia:add_table_index(vcard_search, lemail),
- mnesia:add_table_index(vcard_search, lorgname),
- mnesia:add_table_index(vcard_search, lorgunit),
-
- ejabberd_hooks:add(remove_user, Host,
- ?MODULE, remove_user, 50),
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
- ?MODULE, process_local_iq, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
- ?MODULE, process_sm_iq, IQDisc),
- ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
- MyHost = gen_mod:get_opt(host, Opts, "vjud." ++ Host),
- Search = gen_mod:get_opt(search, Opts, true),
- register(gen_mod:get_module_proc(Host, ?PROCNAME),
- spawn(?MODULE, init, [MyHost, Host, Search])).
-
-
-init(Host, ServerHost, Search) ->
- case Search of
- false ->
- loop(Host, ServerHost);
- _ ->
- ejabberd_router:register_route(Host),
- loop(Host, ServerHost)
- end.
-
-loop(Host, ServerHost) ->
- receive
- {route, From, To, Packet} ->
- case catch do_route(ServerHost, From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]);
- _ ->
- ok
- end,
- loop(Host, ServerHost);
- stop ->
- ejabberd_router:unregister_route(Host),
- ok;
- _ ->
- loop(Host, ServerHost)
- end.
-
-stop(Host) ->
- ejabberd_hooks:delete(remove_user, Host,
- ?MODULE, remove_user, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
- ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- Proc ! stop,
- {wait, Proc}.
-
-get_sm_features({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
- Acc;
-
-get_sm_features(Acc, _From, _To, Node, _Lang) ->
- case Node of
- [] ->
- case Acc of
- {result, Features} ->
- {result, [?NS_VCARD | Features]};
- empty ->
- {result, [?NS_VCARD]}
- end;
- _ ->
- Acc
- end.
-
-process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- IQ#iq{type = result,
- sub_el = [{xmlelement, "vCard",
- [{"xmlns", ?NS_VCARD}],
- [{xmlelement, "FN", [],
- [{xmlcdata, "ejabberd"}]},
- {xmlelement, "URL", [],
- [{xmlcdata,
- "http://ejabberd.jabberstudio.org/"}]},
- {xmlelement, "DESC", [],
- [{xmlcdata,
- translate:translate(
- Lang,
- "Erlang Jabber Server\n"
- "Copyright (c) 2002-2006 Alexey Shchepin")}]},
- {xmlelement, "BDAY", [],
- [{xmlcdata, "2002-11-16"}]}
- ]}]}
- end.
-
-
-process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- #jid{user = User, lserver = LServer} = From,
- case lists:member(LServer, ?MYHOSTS) of
- true ->
- set_vcard(User, LServer, SubEl),
- IQ#iq{type = result, sub_el = []};
- false ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
- end;
- get ->
- #jid{luser = LUser, lserver = LServer} = To,
- US = {LUser, LServer},
- F = fun() ->
- mnesia:read({vcard, US})
- end,
- Els = case mnesia:transaction(F) of
- {atomic, Rs} ->
- lists:map(fun(R) ->
- R#vcard.vcard
- end, Rs);
- {aborted, _Reason} ->
- []
- end,
- IQ#iq{type = result, sub_el = Els}
- end.
-
-set_vcard(User, LServer, VCARD) ->
- FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]),
- Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]),
- Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]),
- Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]),
- Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]),
- BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]),
- CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]),
- Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},cdata]),
- EMail1 = xml:get_path_s(VCARD, [{elem, "EMAIL"}, {elem, "USERID"},cdata]),
- EMail2 = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]),
- OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
- OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
- EMail = case EMail1 of
- "" ->
- EMail2;
- _ ->
- EMail1
- end,
-
- LUser = jlib:nodeprep(User),
- LFN = stringprep:tolower(FN),
- LFamily = stringprep:tolower(Family),
- LGiven = stringprep:tolower(Given),
- LMiddle = stringprep:tolower(Middle),
- LNickname = stringprep:tolower(Nickname),
- LBDay = stringprep:tolower(BDay),
- LCTRY = stringprep:tolower(CTRY),
- LLocality = stringprep:tolower(Locality),
- LEMail = stringprep:tolower(EMail),
- LOrgName = stringprep:tolower(OrgName),
- LOrgUnit = stringprep:tolower(OrgUnit),
-
- US = {LUser, LServer},
-
- if
- (LUser == error) or
- (LFN == error) or
- (LFamily == error) or
- (LGiven == error) or
- (LMiddle == error) or
- (LNickname == error) or
- (LBDay == error) or
- (LCTRY == error) or
- (LLocality == error) or
- (LEMail == error) or
- (LOrgName == error) or
- (LOrgUnit == error) ->
- {error, badarg};
- true ->
- F = fun() ->
- mnesia:write(#vcard{us = US, vcard = VCARD}),
- mnesia:write(
- #vcard_search{us = US,
- user = {User, LServer},
- luser = LUser,
- fn = FN, lfn = LFN,
- family = Family, lfamily = LFamily,
- given = Given, lgiven = LGiven,
- middle = Middle, lmiddle = LMiddle,
- nickname = Nickname, lnickname = LNickname,
- bday = BDay, lbday = LBDay,
- ctry = CTRY, lctry = LCTRY,
- locality = Locality, llocality = LLocality,
- email = EMail, lemail = LEMail,
- orgname = OrgName, lorgname = LOrgName,
- orgunit = OrgUnit, lorgunit = LOrgUnit
- })
- end,
- mnesia:transaction(F)
- end.
-
--define(TLFIELD(Type, Label, Var),
- {xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
- {"var", Var}], []}).
-
-
--define(FORM(JID),
- [{xmlelement, "instructions", [],
- [{xmlcdata, translate:translate(Lang, "You need an x:data capable client to search")}]},
- {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}],
- [{xmlelement, "title", [],
- [{xmlcdata, translate:translate(Lang, "Search users in ") ++
- jlib:jid_to_string(JID)}]},
- {xmlelement, "instructions", [],
- [{xmlcdata, translate:translate(Lang, "Fill in the form to search "
- "for any matching Jabber User "
- "(Add * to the end of field to "
- "match substring)")}]},
- ?TLFIELD("text-single", "User", "user"),
- ?TLFIELD("text-single", "Full Name", "fn"),
- ?TLFIELD("text-single", "Name", "given"),
- ?TLFIELD("text-single", "Middle Name", "middle"),
- ?TLFIELD("text-single", "Family Name", "family"),
- ?TLFIELD("text-single", "Nickname", "nickname"),
- ?TLFIELD("text-single", "Birthday", "bday"),
- ?TLFIELD("text-single", "Country", "ctry"),
- ?TLFIELD("text-single", "City", "locality"),
- ?TLFIELD("text-single", "Email", "email"),
- ?TLFIELD("text-single", "Organization Name", "orgname"),
- ?TLFIELD("text-single", "Organization Unit", "orgunit")
- ]}]).
-
-
-
-
-do_route(ServerHost, From, To, Packet) ->
- #jid{user = User, resource = Resource} = To,
- if
- (User /= "") or (Resource /= "") ->
- Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router ! {route, To, From, Err};
- true ->
- IQ = jlib:iq_query_info(Packet),
- case IQ of
- #iq{type = Type, xmlns = ?NS_SEARCH, lang = Lang, sub_el = SubEl} ->
- case Type of
- set ->
- XDataEl = find_xdata_el(SubEl),
- case XDataEl of
- false ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_BAD_REQUEST),
- ejabberd_router:route(To, From, Err);
- _ ->
- XData = jlib:parse_xdata_submit(XDataEl),
- case XData of
- invalid ->
- Err = jlib:make_error_reply(
- Packet,
- ?ERR_BAD_REQUEST),
- ejabberd_router:route(To, From,
- Err);
- _ ->
- ResIQ =
- IQ#iq{
- type = result,
- sub_el =
- [{xmlelement,
- "query",
- [{"xmlns", ?NS_SEARCH}],
- [{xmlelement, "x",
- [{"xmlns", ?NS_XDATA},
- {"type", "result"}],
- search_result(Lang, To, ServerHost, XData)
- }]}]},
- ejabberd_router:route(
- To, From, jlib:iq_to_xml(ResIQ))
- end
- end;
- get ->
- ResIQ = IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_SEARCH}],
- ?FORM(To)
- }]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = Type, xmlns = ?NS_DISCO_INFO} ->
- case Type of
- set ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_NOT_ALLOWED),
- ejabberd_router:route(To, From, Err);
- get ->
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_DISCO_INFO}],
- [{xmlelement, "identity",
- [{"category", "directory"},
- {"type", "user"},
- {"name",
- "vCard User Search"}],
- []},
- {xmlelement, "feature",
- [{"var", ?NS_SEARCH}], []},
- {xmlelement, "feature",
- [{"var", ?NS_VCARD}], []}
- ]
- }]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = Type, xmlns = ?NS_DISCO_ITEMS} ->
- case Type of
- set ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_NOT_ALLOWED),
- ejabberd_router:route(To, From, Err);
- get ->
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_DISCO_ITEMS}],
- []}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} ->
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "vCard",
- [{"xmlns", ?NS_VCARD}],
- iq_get_vcard(Lang)}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ));
- _ ->
- Err = jlib:make_error_reply(Packet,
- ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router:route(To, From, Err)
- end
- end.
-
-iq_get_vcard(Lang) ->
- [{xmlelement, "FN", [],
- [{xmlcdata, "ejabberd/mod_vcard"}]},
- {xmlelement, "URL", [],
- [{xmlcdata,
- "http://ejabberd.jabberstudio.org/"}]},
- {xmlelement, "DESC", [],
- [{xmlcdata, translate:translate(
- Lang,
- "ejabberd vCard module\n"
- "Copyright (c) 2003-2006 Alexey Shchepin")}]}].
-
-find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) ->
- find_xdata_el1(SubEls).
-
-find_xdata_el1([]) ->
- false;
-find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_XDATA ->
- {xmlelement, Name, Attrs, SubEls};
- _ ->
- find_xdata_el1(Els)
- end;
-find_xdata_el1([_ | Els]) ->
- find_xdata_el1(Els).
-
--define(LFIELD(Label, Var),
- {xmlelement, "field", [{"label", translate:translate(Lang, Label)},
- {"var", Var}], []}).
-
-search_result(Lang, JID, ServerHost, Data) ->
- [{xmlelement, "title", [],
- [{xmlcdata, translate:translate(Lang, "Search Results for ") ++
- jlib:jid_to_string(JID)}]},
- {xmlelement, "reported", [],
- [?LFIELD("Jabber ID", "jid"),
- ?LFIELD("Full Name", "fn"),
- ?LFIELD("Name", "given"),
- ?LFIELD("Middle Name", "middle"),
- ?LFIELD("Family Name", "family"),
- ?LFIELD("Nickname", "nickname"),
- ?LFIELD("Birthday", "bday"),
- ?LFIELD("Country", "ctry"),
- ?LFIELD("City", "locality"),
- ?LFIELD("Email", "email"),
- ?LFIELD("Organization Name", "orgname"),
- ?LFIELD("Organization Unit", "orgunit")
- ]}] ++ lists:map(fun record_to_item/1, search(ServerHost, Data)).
-
--define(FIELD(Var, Val),
- {xmlelement, "field", [{"var", Var}],
- [{xmlelement, "value", [],
- [{xmlcdata, Val}]}]}).
-
-record_to_item(R) ->
- {User, Server} = R#vcard_search.user,
- {xmlelement, "item", [],
- [
- ?FIELD("jid", User ++ "@" ++ Server),
- ?FIELD("fn", R#vcard_search.fn),
- ?FIELD("family", R#vcard_search.family),
- ?FIELD("given", R#vcard_search.given),
- ?FIELD("middle", R#vcard_search.middle),
- ?FIELD("nickname", R#vcard_search.nickname),
- ?FIELD("bday", R#vcard_search.bday),
- ?FIELD("ctry", R#vcard_search.ctry),
- ?FIELD("locality", R#vcard_search.locality),
- ?FIELD("email", R#vcard_search.email),
- ?FIELD("orgname", R#vcard_search.orgname),
- ?FIELD("orgunit", R#vcard_search.orgunit)
- ]
- }.
-
-
-search(LServer, Data) ->
- MatchSpec = make_matchspec(LServer, Data),
- AllowReturnAll = gen_mod:get_module_opt(LServer, ?MODULE,
- allow_return_all, false),
- if
- (MatchSpec == #vcard_search{_ = '_'}) and (not AllowReturnAll) ->
- [];
- true ->
- case catch mnesia:dirty_select(vcard_search,
- [{MatchSpec, [], ['$_']}]) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]),
- [];
- Rs ->
- case gen_mod:get_module_opt(LServer, ?MODULE,
- matches, ?JUD_MATCHES) of
- infinity ->
- Rs;
- Val when is_integer(Val) and (Val > 0) ->
- lists:sublist(Rs, Val);
- Val ->
- ?ERROR_MSG("Illegal option value ~p. "
- "Default value ~p substituted.",
- [{matches, Val}, ?JUD_MATCHES]),
- lists:sublist(Rs, ?JUD_MATCHES)
- end
- end
- end.
-
-
-make_matchspec(LServer, Data) ->
- GlobMatch = #vcard_search{_ = '_'},
- Match = filter_fields(Data, GlobMatch, LServer),
- Match.
-
-filter_fields([], Match, _LServer) ->
- Match;
-filter_fields([{SVar, [Val]} | Ds], Match, LServer)
- when is_list(Val) and (Val /= "") ->
- LVal = stringprep:tolower(Val),
- NewMatch = case SVar of
- "user" ->
- case gen_mod:get_module_opt(LServer, ?MODULE,
- search_all_hosts, true) of
- true ->
- Match#vcard_search{luser = make_val(LVal)};
- false ->
- Host = find_my_host(LServer),
- Match#vcard_search{us = {make_val(LVal), Host}}
- end;
- "fn" -> Match#vcard_search{lfn = make_val(LVal)};
- "family" -> Match#vcard_search{lfamily = make_val(LVal)};
- "given" -> Match#vcard_search{lgiven = make_val(LVal)};
- "middle" -> Match#vcard_search{lmiddle = make_val(LVal)};
- "nickname" -> Match#vcard_search{lnickname = make_val(LVal)};
- "bday" -> Match#vcard_search{lbday = make_val(LVal)};
- "ctry" -> Match#vcard_search{lctry = make_val(LVal)};
- "locality" -> Match#vcard_search{llocality = make_val(LVal)};
- "email" -> Match#vcard_search{lemail = make_val(LVal)};
- "orgname" -> Match#vcard_search{lorgname = make_val(LVal)};
- "orgunit" -> Match#vcard_search{lorgunit = make_val(LVal)};
- _ -> Match
- end,
- filter_fields(Ds, NewMatch, LServer);
-filter_fields([_ | Ds], Match, LServer) ->
- filter_fields(Ds, Match, LServer).
-
-make_val(Val) ->
- case lists:suffix("*", Val) of
- true ->
- lists:sublist(Val, length(Val) - 1) ++ '_';
- _ ->
- Val
- end.
-
-find_my_host(LServer) ->
- Parts = string:tokens(LServer, "."),
- find_my_host(Parts, ?MYHOSTS).
-
-find_my_host([], _Hosts) ->
- ?MYNAME;
-find_my_host([_ | Tail] = Parts, Hosts) ->
- Domain = parts_to_string(Parts),
- case lists:member(Domain, Hosts) of
- true ->
- Domain;
- false ->
- find_my_host(Tail, Hosts)
- end.
-
-parts_to_string(Parts) ->
- string:strip(lists:flatten(lists:map(fun(S) -> [S, $.] end, Parts)),
- right, $.).
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-set_vcard_t(R, _) ->
- US = R#vcard.us,
- User = US,
- VCARD = R#vcard.vcard,
-
- FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]),
- Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]),
- Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]),
- Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]),
- Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]),
- BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]),
- CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]),
- Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},cdata]),
- EMail = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]),
- OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
- OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
-
- {LUser, _LServer} = US,
- LFN = stringprep:tolower(FN),
- LFamily = stringprep:tolower(Family),
- LGiven = stringprep:tolower(Given),
- LMiddle = stringprep:tolower(Middle),
- LNickname = stringprep:tolower(Nickname),
- LBDay = stringprep:tolower(BDay),
- LCTRY = stringprep:tolower(CTRY),
- LLocality = stringprep:tolower(Locality),
- LEMail = stringprep:tolower(EMail),
- LOrgName = stringprep:tolower(OrgName),
- LOrgUnit = stringprep:tolower(OrgUnit),
-
- if
- (LUser == error) or
- (LFN == error) or
- (LFamily == error) or
- (LGiven == error) or
- (LMiddle == error) or
- (LNickname == error) or
- (LBDay == error) or
- (LCTRY == error) or
- (LLocality == error) or
- (LEMail == error) or
- (LOrgName == error) or
- (LOrgUnit == error) ->
- {error, badarg};
- true ->
- mnesia:write(
- #vcard_search{us = US,
- user = User, luser = LUser,
- fn = FN, lfn = LFN,
- family = Family, lfamily = LFamily,
- given = Given, lgiven = LGiven,
- middle = Middle, lmiddle = LMiddle,
- nickname = Nickname, lnickname = LNickname,
- bday = BDay, lbday = LBDay,
- ctry = CTRY, lctry = LCTRY,
- locality = Locality, llocality = LLocality,
- email = EMail, lemail = LEMail,
- orgname = OrgName, lorgname = LOrgName,
- orgunit = OrgUnit, lorgunit = LOrgUnit
- })
- end.
-
-
-reindex_vcards() ->
- F = fun() ->
- mnesia:foldl(fun set_vcard_t/2, [], vcard)
- end,
- mnesia:transaction(F).
-
-
-remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- F = fun() ->
- mnesia:delete({vcard, US}),
- mnesia:delete({vcard_search, US})
- end,
- mnesia:transaction(F).
-
-
-update_tables() ->
- update_vcard_table(),
- update_vcard_search_table().
-
-update_vcard_table() ->
- Fields = record_info(fields, vcard),
- case mnesia:table_info(vcard, attributes) of
- Fields ->
- ok;
- [user, vcard] ->
- ?INFO_MSG("Converting vcard table from "
- "{user, vcard} format", []),
- Host = ?MYNAME,
- {atomic, ok} = mnesia:create_table(
- mod_vcard_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, vcard},
- {attributes, record_info(fields, vcard)}]),
- mnesia:transform_table(vcard, ignore, Fields),
- F1 = fun() ->
- mnesia:write_lock_table(mod_vcard_tmp_table),
- mnesia:foldl(
- fun(#vcard{us = U} = R, _) ->
- mnesia:dirty_write(
- mod_vcard_tmp_table,
- R#vcard{us = {U, Host}})
- end, ok, vcard)
- end,
- mnesia:transaction(F1),
- mnesia:clear_table(vcard),
- F2 = fun() ->
- mnesia:write_lock_table(vcard),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_vcard_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_vcard_tmp_table);
- _ ->
- ?INFO_MSG("Recreating vcard table", []),
- mnesia:transform_table(vcard, ignore, Fields)
- end.
-
-
-update_vcard_search_table() ->
- Fields = record_info(fields, vcard_search),
- case mnesia:table_info(vcard_search, attributes) of
- Fields ->
- ok;
- [user, luser,
- fn, lfn,
- family, lfamily,
- given, lgiven,
- middle, lmiddle,
- nickname, lnickname,
- bday, lbday,
- ctry, lctry,
- locality, llocality,
- email, lemail,
- orgname, lorgname,
- orgunit, lorgunit] ->
- ?INFO_MSG("Converting vcard_search table from "
- "{user, luser, fn, lfn, family, lfamily, given, lgiven, middle, lmiddle, nickname, lnickname, bday, lbday, ctry, lctry, locality, llocality, email, lemail, orgname, lorgname, orgunit, lorgunit} format", []),
- Host = ?MYNAME,
- {atomic, ok} = mnesia:create_table(
- mod_vcard_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, vcard_search},
- {attributes, record_info(fields, vcard_search)}]),
- F1 = fun() ->
- mnesia:write_lock_table(mod_vcard_tmp_table),
- mnesia:foldl(
- fun({vcard_search,
- User, LUser,
- FN, LFN,
- Family, LFamily,
- Given, LGiven,
- Middle, LMiddle,
- Nickname, LNickname,
- BDay, LBDay,
- CTRY, LCTRY,
- Locality, LLocality,
- EMail, LEMail,
- OrgName, LOrgName,
- OrgUnit, LOrgUnit
- }, _) ->
- mnesia:dirty_write(
- mod_vcard_tmp_table,
- #vcard_search{
- us = {LUser, Host},
- user = {User, Host},
- luser = LUser,
- fn = FN, lfn = LFN,
- family = Family, lfamily = LFamily,
- given = Given, lgiven = LGiven,
- middle = Middle, lmiddle = LMiddle,
- nickname = Nickname, lnickname = LNickname,
- bday = BDay, lbday = LBDay,
- ctry = CTRY, lctry = LCTRY,
- locality = Locality, llocality = LLocality,
- email = EMail, lemail = LEMail,
- orgname = OrgName, lorgname = LOrgName,
- orgunit = OrgUnit, lorgunit = LOrgUnit
- })
- end, ok, vcard_search)
- end,
- mnesia:transaction(F1),
- lists:foreach(fun(I) ->
- mnesia:del_table_index(
- vcard_search,
- element(I, {vcard_search,
- user, luser,
- fn, lfn,
- family, lfamily,
- given, lgiven,
- middle, lmiddle,
- nickname, lnickname,
- bday, lbday,
- ctry, lctry,
- locality, llocality,
- email, lemail,
- orgname, lorgname,
- orgunit, lorgunit}))
- end, mnesia:table_info(vcard_search, index)),
- mnesia:clear_table(vcard_search),
- mnesia:transform_table(vcard_search, ignore, Fields),
- F2 = fun() ->
- mnesia:write_lock_table(vcard_search),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_vcard_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_vcard_tmp_table);
- _ ->
- ?INFO_MSG("Recreating vcard_search table", []),
- mnesia:transform_table(vcard_search, ignore, Fields)
- end.
-
diff --git a/ejabberd-1.1.2/src/mod_vcard_ldap.erl b/ejabberd-1.1.2/src/mod_vcard_ldap.erl
deleted file mode 100644
index 0921ce92f..000000000
--- a/ejabberd-1.1.2/src/mod_vcard_ldap.erl
+++ /dev/null
@@ -1,803 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_vcard_ldap.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Support for VCards from LDAP storage.
-%%% Created : 2 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_vcard_ldap).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
--behaviour(gen_mod).
-
-%% gen_server callbacks.
--export([init/1,
- handle_info/2,
- handle_call/3,
- handle_cast/2,
- terminate/2,
- code_change/3
- ]).
-
--export([start/2,
- start_link/2,
- stop/1,
- get_sm_features/5,
- process_local_iq/3,
- process_sm_iq/3,
- remove_user/1
- ]).
-
--include("ejabberd.hrl").
--include("eldap/eldap.hrl").
--include("jlib.hrl").
-
--define(PROCNAME, ejabberd_mod_vcard_ldap).
-
--record(state, {serverhost,
- myhost,
- eldap_id,
- search,
- servers,
- port,
- dn,
- base,
- password,
- uid,
- uid_format,
- vcard_map,
- vcard_map_attrs,
- user_filter,
- search_filter,
- search_fields,
- search_reported,
- search_reported_attrs
- }).
-
--define(VCARD_MAP,
- [{"NICKNAME", "%u", []},
- {"FN", "%s", ["displayName"]},
- {"FAMILY", "%s", ["sn"]},
- {"GIVEN", "%s", ["givenName"]},
- {"MIDDLE", "%s", ["initials"]},
- {"ORGNAME", "%s", ["o"]},
- {"ORGUNIT", "%s", ["ou"]},
- {"CTRY", "%s", ["c"]},
- {"LOCALITY", "%s", ["l"]},
- {"STREET", "%s", ["street"]},
- {"REGION", "%s", ["st"]},
- {"PCODE", "%s", ["postalCode"]},
- {"TITLE", "%s", ["title"]},
- {"URL", "%s", ["labeleduri"]},
- {"DESC", "%s", ["description"]},
- {"TEL", "%s", ["telephoneNumber"]},
- {"EMAIL", "%s", ["mail"]},
- {"BDAY", "%s", ["birthDay"]},
- {"ROLE", "%s", ["employeeType"]},
- {"PHOTO", "%s", ["jpegPhoto"]}
- ]).
-
--define(SEARCH_FIELDS,
- [{"User", "%u"},
- {"Full Name", "displayName"},
- {"Given Name", "givenName"},
- {"Middle Name", "initials"},
- {"Family Name", "sn"},
- {"Nickname", "%u"},
- {"Birthday", "birthDay"},
- {"Country", "c"},
- {"City", "l"},
- {"Email", "mail"},
- {"Organization Name", "o"},
- {"Organization Unit", "ou"}
- ]).
-
--define(SEARCH_REPORTED,
- [{"Full Name", "FN"},
- {"Given Name", "GIVEN"},
- {"Middle Name", "MIDDLE"},
- {"Family Name", "FAMILY"},
- {"Nickname", "NICKNAME"},
- {"Birthday", "BDAY"},
- {"Country", "CTRY"},
- {"City", "LOCALITY"},
- {"Email", "EMAIL"},
- {"Organization Name", "ORGNAME"},
- {"Organization Unit", "ORGUNIT"}
- ]).
-
-%% Unused callbacks.
-handle_cast(_Request, State) ->
- {noreply, State}.
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-%% -----
-
-
-start(Host, Opts) ->
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- ChildSpec = {
- Proc, {?MODULE, start_link, [Host, Opts]},
- permanent, 1000, worker, [?MODULE]
- },
- supervisor:start_child(ejabberd_sup, ChildSpec).
-
-stop(Host) ->
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- gen_server:call(Proc, stop),
- supervisor:terminate_child(ejabberd_sup, Proc),
- supervisor:delete_child(ejabberd_sup, Proc).
-
-terminate(_Reason, State) ->
- Host = State#state.serverhost,
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
- ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
- case State#state.search of
- true ->
- ejabberd_router:unregister_route(State#state.myhost);
- _ ->
- ok
- end.
-
-start_link(Host, Opts) ->
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
-
-init([Host, Opts]) ->
- State = parse_options(Host, Opts),
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
- ?MODULE, process_local_iq, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
- ?MODULE, process_sm_iq, IQDisc),
- ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
- eldap:start_link(State#state.eldap_id,
- State#state.servers,
- State#state.port,
- State#state.dn,
- State#state.password),
- case State#state.search of
- true ->
- ejabberd_router:register_route(State#state.myhost);
- _ ->
- ok
- end,
- {ok, State}.
-
-handle_info({route, From, To, Packet}, State) ->
- case catch do_route(State, From, To, Packet) of
- {'EXIT', Reason} ->
- Err = jlib:make_error_reply(Packet, ?ERR_INTERNAL_SERVER_ERROR),
- ejabberd_router:route(To, From, Err),
- %% Fail-Stop. Let the supervisor restarts us
- {stop, Reason, State};
- _ ->
- {noreply, State}
- end;
-
-handle_info(_Info, State) ->
- {noreply, State}.
-
-get_sm_features({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
- Acc;
-get_sm_features(Acc, _From, _To, Node, _Lang) ->
- case Node of
- [] ->
- case Acc of
- {result, Features} ->
- {result, [?NS_VCARD | Features]};
- empty ->
- {result, [?NS_VCARD]}
- end;
- _ ->
- Acc
- end.
-
-process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- IQ#iq{type = result,
- sub_el = [{xmlelement, "vCard",
- [{"xmlns", ?NS_VCARD}],
- [{xmlelement, "FN", [],
- [{xmlcdata, "ejabberd"}]},
- {xmlelement, "URL", [],
- [{xmlcdata,
- "http://ejabberd.jabber.ru/"}]},
- {xmlelement, "DESC", [],
- [{xmlcdata,
- translate:translate(
- Lang,
- "Erlang Jabber Server\n"
- "Copyright (c) 2002-2006 Alexey Shchepin")}]},
- {xmlelement, "BDAY", [],
- [{xmlcdata, "2002-11-16"}]}
- ]}]}
- end.
-
--define(SM_IQ_TIMEOUT, 20000).
-
-process_sm_iq(From, #jid{lserver=LServer} = To, #iq{sub_el = SubEl} = IQ) ->
- Proc = gen_mod:get_module_proc(LServer, ?PROCNAME),
- case catch gen_server:call(Proc,
- {process_sm_iq, From, To, IQ}, ?SM_IQ_TIMEOUT) of
- {'EXIT', Reason} ->
- case Reason of
- {timeout, _} ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_REMOTE_SERVER_TIMEOUT]};
- _ ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
- end;
- Other ->
- Other
- end.
-
-handle_call({process_sm_iq, _From, To, IQ}, _FromPid, State) ->
- #iq{type = Type, sub_el = SubEl} = IQ,
- Reply = case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- #jid{luser = LUser} = To,
- LServer = State#state.serverhost,
- case ejabberd_auth:is_user_exists(LUser, LServer) of
- true ->
- VCardMap = State#state.vcard_map,
- case find_ldap_user(LUser, State) of
- #eldap_entry{attributes = Attributes} ->
- Vcard = ldap_attributes_to_vcard(Attributes, VCardMap, {LUser, LServer}),
- IQ#iq{type = result, sub_el = Vcard};
- _ ->
- IQ#iq{type = result, sub_el = []}
- end;
- _ ->
- IQ#iq{type = result, sub_el = []}
- end
- end,
- {reply, Reply, State};
-
-handle_call(stop, _From, State) ->
- {stop, normal, ok, State};
-
-handle_call(_Request, _From, State) ->
- {reply, bad_request, State}.
-
-find_ldap_user(User, State) ->
- Base = State#state.base,
- RFC2254_Filter = State#state.user_filter,
- Eldap_ID = State#state.eldap_id,
- VCardAttrs = State#state.vcard_map_attrs,
- case eldap_filter:parse(RFC2254_Filter, [{"%u", User}]) of
- {ok, EldapFilter} ->
- case eldap:search(Eldap_ID, [{base, Base},
- {filter, EldapFilter},
- {attributes, VCardAttrs}]) of
- #eldap_search_result{entries = [E | _]} ->
- E;
- _ ->
- false
- end;
- _ ->
- false
- end.
-
-ldap_attributes_to_vcard(Attributes, VCardMap, UD) ->
- Attrs = lists:map(
- fun({VCardName, _, _}) ->
- {stringprep:tolower(VCardName),
- map_vcard_attr(VCardName, Attributes, VCardMap, UD)}
- end, VCardMap),
- Elts = [ldap_attribute_to_vcard(vCard, Attr) || Attr <- Attrs],
- NElts = [ldap_attribute_to_vcard(vCardN, Attr) || Attr <- Attrs],
- OElts = [ldap_attribute_to_vcard(vCardO, Attr) || Attr <- Attrs],
- AElts = [ldap_attribute_to_vcard(vCardA, Attr) || Attr <- Attrs],
- [{xmlelement, "vCard", [{"xmlns", ?NS_VCARD}],
- lists:append([X || X <- Elts, X /= none],
- [{xmlelement,"N",[], [X || X <- NElts, X /= none]},
- {xmlelement,"ORG",[], [X || X <- OElts, X /= none]},
- {xmlelement,"ADR",[], [X || X <- AElts, X /= none]}])
- }].
-
-ldap_attribute_to_vcard(vCard, {"fn", Value}) ->
- {xmlelement,"FN",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCard, {"nickname", Value}) ->
- {xmlelement,"NICKNAME",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCard, {"title", Value}) ->
- {xmlelement,"TITLE",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCard, {"bday", Value}) ->
- {xmlelement,"BDAY",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCard, {"url", Value}) ->
- {xmlelement,"URL",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCard, {"desc", Value}) ->
- {xmlelement,"DESC",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCard, {"role", Value}) ->
- {xmlelement,"ROLE",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCard, {"tel", Value}) ->
- {xmlelement,"TEL",[],[{xmlelement,"VOICE",[],[]},
- {xmlelement,"WORK",[],[]},
- {xmlelement,"NUMBER",[],[{xmlcdata,Value}]}]};
-
-ldap_attribute_to_vcard(vCard, {"email", Value}) ->
- {xmlelement,"EMAIL",[],[{xmlelement,"INTERNET",[],[]},
- {xmlelement,"PREF",[],[]},
- {xmlelement,"USERID",[],[{xmlcdata,Value}]}]};
-
-ldap_attribute_to_vcard(vCard, {"photo", Value}) ->
- {xmlelement,"PHOTO",[],[
- {xmlelement,"BINVAL",[],[{xmlcdata, jlib:encode_base64(Value)}]}]};
-
-ldap_attribute_to_vcard(vCardN, {"family", Value}) ->
- {xmlelement,"FAMILY",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCardN, {"given", Value}) ->
- {xmlelement,"GIVEN",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCardN, {"middle", Value}) ->
- {xmlelement,"MIDDLE",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCardO, {"orgname", Value}) ->
- {xmlelement,"ORGNAME",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCardO, {"orgunit", Value}) ->
- {xmlelement,"ORGUNIT",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCardA, {"locality", Value}) ->
- {xmlelement,"LOCALITY",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCardA, {"street", Value}) ->
- {xmlelement,"STREET",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCardA, {"ctry", Value}) ->
- {xmlelement,"CTRY",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCardA, {"region", Value}) ->
- {xmlelement,"REGION",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(vCardA, {"pcode", Value}) ->
- {xmlelement,"PCODE",[],[{xmlcdata,Value}]};
-
-ldap_attribute_to_vcard(_, _) ->
- none.
-
--define(TLFIELD(Type, Label, Var),
- {xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
- {"var", Var}], []}).
-
--define(FORM(JID, SearchFields),
- [{xmlelement, "instructions", [],
- [{xmlcdata, translate:translate(Lang, "You need an x:data capable client to search")}]},
- {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}],
- [{xmlelement, "title", [],
- [{xmlcdata, translate:translate(Lang, "Search users in ") ++
- jlib:jid_to_string(JID)}]},
- {xmlelement, "instructions", [],
- [{xmlcdata, translate:translate(Lang, "Fill in fields to search "
- "for any matching Jabber User")}]}
- ] ++ lists:map(fun({X,Y}) -> ?TLFIELD("text-single", X, Y) end, SearchFields)}]).
-
-do_route(State, From, To, Packet) ->
- #jid{user = User, resource = Resource} = To,
- if
- (User /= "") or (Resource /= "") ->
- Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router:route(To, From, Err);
- true ->
- IQ = jlib:iq_query_info(Packet),
- case IQ of
- #iq{type = Type, xmlns = ?NS_SEARCH, lang = Lang, sub_el = SubEl} ->
- case Type of
- set ->
- XDataEl = find_xdata_el(SubEl),
- case XDataEl of
- false ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_BAD_REQUEST),
- ejabberd_router:route(To, From, Err);
- _ ->
- XData = jlib:parse_xdata_submit(XDataEl),
- case XData of
- invalid ->
- Err = jlib:make_error_reply(
- Packet,
- ?ERR_BAD_REQUEST),
- ejabberd_router:route(To, From,
- Err);
- _ ->
- ResIQ =
- IQ#iq{
- type = result,
- sub_el =
- [{xmlelement,
- "query",
- [{"xmlns", ?NS_SEARCH}],
- [{xmlelement, "x",
- [{"xmlns", ?NS_XDATA},
- {"type", "result"}],
- search_result(Lang, To, State, XData)
- }]}]},
- ejabberd_router:route(
- To, From, jlib:iq_to_xml(ResIQ))
- end
- end;
- get ->
- SearchFields = State#state.search_fields,
- ResIQ = IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_SEARCH}],
- ?FORM(To, SearchFields)
- }]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = Type, xmlns = ?NS_DISCO_INFO} ->
- case Type of
- set ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_NOT_ALLOWED),
- ejabberd_router:route(To, From, Err);
- get ->
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_DISCO_INFO}],
- [{xmlelement, "identity",
- [{"category", "directory"},
- {"type", "user"},
- {"name",
- "vCard User Search"}],
- []},
- {xmlelement, "feature",
- [{"var", ?NS_SEARCH}], []},
- {xmlelement, "feature",
- [{"var", ?NS_VCARD}], []}
- ]
- }]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = Type, xmlns = ?NS_DISCO_ITEMS} ->
- case Type of
- set ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_NOT_ALLOWED),
- ejabberd_router:route(To, From, Err);
- get ->
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_DISCO_ITEMS}],
- []}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} ->
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "vCard",
- [{"xmlns", ?NS_VCARD}],
- iq_get_vcard(Lang)}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ));
- _ ->
- Err = jlib:make_error_reply(Packet,
- ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router:route(To, From, Err)
- end
- end.
-
-iq_get_vcard(Lang) ->
- [{xmlelement, "FN", [],
- [{xmlcdata, "ejabberd/mod_vcard"}]},
- {xmlelement, "URL", [],
- [{xmlcdata,
- "http://ejabberd.jabber.ru/"}]},
- {xmlelement, "DESC", [],
- [{xmlcdata, translate:translate(
- Lang,
- "ejabberd vCard module\n"
- "Copyright (c) 2003-2006 Alexey Shchepin")}]}].
-
--define(LFIELD(Label, Var),
- {xmlelement, "field", [{"label", translate:translate(Lang, Label)},
- {"var", Var}], []}).
-
-search_result(Lang, JID, State, Data) ->
- SearchReported = State#state.search_reported,
- Header = [{xmlelement, "title", [],
- [{xmlcdata, translate:translate(Lang, "Search Results for ") ++
- jlib:jid_to_string(JID)}]},
- {xmlelement, "reported", [],
- [?LFIELD("Jabber ID", "jid")] ++
- lists:map(
- fun({Name, Value}) -> ?LFIELD(Name, Value) end,
- SearchReported)
- }],
- case search(State, Data) of
- error ->
- Header;
- Result ->
- Header ++ Result
- end.
-
--define(FIELD(Var, Val),
- {xmlelement, "field", [{"var", Var}],
- [{xmlelement, "value", [],
- [{xmlcdata, Val}]}]}).
-
-search(State, Data) ->
- Base = State#state.base,
- SearchFilter = State#state.search_filter,
- Eldap_ID = State#state.eldap_id,
- UA = State#state.uid,
- UAF = State#state.uid_format,
- ReportedAttrs = State#state.search_reported_attrs,
- Filter = eldap:'and'([SearchFilter, make_filter(Data, UA, UAF)]),
- case eldap:search(Eldap_ID, [{base, Base},
- {filter, Filter},
- {attributes, ReportedAttrs}]) of
- #eldap_search_result{entries = E} ->
- search_items(E, State);
- _ ->
- error
- end.
-
-search_items(Entries, State) ->
- LServer = State#state.serverhost,
- SearchReported = State#state.search_reported,
- VCardMap = State#state.vcard_map,
- UIDAttr = State#state.uid,
- UIDAttrFormat = State#state.uid_format,
- Attributes = lists:map(
- fun(E) ->
- #eldap_entry{attributes = Attrs} = E,
- Attrs
- end, Entries),
- lists:flatmap(
- fun(Attrs) ->
- U = get_ldap_attr(UIDAttr, Attrs),
- case get_user_part(U, UIDAttrFormat) of
- {ok, Username} ->
- case ejabberd_auth:is_user_exists(Username, LServer) of
- true ->
- RFields = lists:map(
- fun({_, VCardName}) ->
- {VCardName,
- map_vcard_attr(
- VCardName,
- Attrs,
- VCardMap,
- {Username, ?MYNAME})}
- end, SearchReported),
- Result = [?FIELD("jid", Username ++ "@" ++ LServer)] ++
- [?FIELD(Name, Value) || {Name, Value} <- RFields],
- [{xmlelement, "item", [], Result}];
- _ ->
- []
- end;
- _ ->
- []
- end
- end, Attributes).
-
-make_filter(Data, UAttr, UAttrFormat) ->
- Filter = lists:flatmap(
- fun({Name, [Value | _]}) ->
- case Name of
- "%u" when Value /= "" ->
- {ok, UAF, _} = regexp:sub(UAttrFormat, "%u", "*%u*"),
- case eldap_filter:parse(
- "("++UAttr++"="++UAF++")", [{"%u", Value}]) of
- {ok, F} -> [F];
- _ -> []
- end;
- _ when Value /= "" ->
- [eldap:substrings(Name, [{any, Value}])];
- _ ->
- []
- end
- end, Data),
- case Filter of
- [F] ->
- F;
- _ ->
- eldap:'and'(Filter)
- end.
-
-remove_user(_User) ->
- true.
-
-%%%-----------------------
-%%% Auxiliary functions.
-%%%-----------------------
-
-get_user_part(String, Pattern) ->
- F = fun(S, P) ->
- First = string:str(P, "%u"),
- TailLength = length(P) - (First+1),
- string:sub_string(S, First, length(S) - TailLength)
- end,
- case catch F(String, Pattern) of
- {'EXIT', _} ->
- {error, badmatch};
- Result ->
- case regexp:sub(Pattern, "%u", Result) of
- {ok, String, _} -> {ok, Result};
- _ -> {error, badmatch}
- end
- end.
-
-case_insensitive_match(X, Y) ->
- X1 = stringprep:tolower(X),
- Y1 = stringprep:tolower(Y),
- if
- X1 == Y1 -> true;
- true -> false
- end.
-
-map_vcard_attr(VCardName, Attributes, Pattern, UD) ->
- Res = lists:filter(
- fun({Name, _, _}) ->
- case_insensitive_match(Name, VCardName)
- end, Pattern),
- case Res of
- [{_, Str, Attrs}] ->
- process_pattern(Str, UD,
- [get_ldap_attr(X, Attributes) || X<-Attrs]);
- _ -> ""
- end.
-
-process_pattern(Str, {User, Domain}, AttrValues) ->
- eldap_filter:do_sub(Str,
- [{"%s", V, 1} || V <- AttrValues] ++ [{"%u", User},{"%d", Domain}]).
-
-get_ldap_attr(LDAPAttr, Attributes) ->
- Res = lists:filter(
- fun({Name, _}) ->
- case_insensitive_match(Name, LDAPAttr)
- end, Attributes),
- case Res of
- [{_, [Value|_]}] -> Value;
- _ -> ""
- end.
-
-find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) ->
- find_xdata_el1(SubEls).
-
-find_xdata_el1([]) ->
- false;
-find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_XDATA ->
- {xmlelement, Name, Attrs, SubEls};
- _ ->
- find_xdata_el1(Els)
- end;
-find_xdata_el1([_ | Els]) ->
- find_xdata_el1(Els).
-
-parse_options(Host, Opts) ->
- MyHost = gen_mod:get_opt(host, Opts, "vjud." ++ Host),
- Search = gen_mod:get_opt(search, Opts, true),
- Eldap_ID = atom_to_list(gen_mod:get_module_proc(Host, ?PROCNAME)),
- LDAPServers = case gen_mod:get_opt(ldap_servers, Opts, undefined) of
- undefined ->
- ejabberd_config:get_local_option({ldap_servers, Host});
- S -> S
- end,
- LDAPPort = case gen_mod:get_opt(ldap_port, Opts, undefined) of
- undefined ->
- case ejabberd_config:get_local_option({ldap_port, Host}) of
- undefined -> 389;
- P -> P
- end;
- P -> P
- end,
- LDAPBase = case gen_mod:get_opt(ldap_base, Opts, undefined) of
- undefined ->
- ejabberd_config:get_local_option({ldap_base, Host});
- B -> B
- end,
- UIDAttr = case gen_mod:get_opt(ldap_uidattr, Opts, undefined) of
- undefined ->
- case ejabberd_config:get_local_option({ldap_uidattr, Host}) of
- undefined -> "uid";
- UA -> UA
- end;
- UA -> UA
- end,
- UIDAttrFormat = case gen_mod:get_opt(ldap_uidattr_format, Opts, undefined) of
- undefined ->
- case ejabberd_config:get_local_option({ldap_uidattr_format, Host}) of
- undefined -> "%u";
- UAF -> UAF
- end;
- UAF -> UAF
- end,
- RootDN = case gen_mod:get_opt(ldap_rootdn, Opts, undefined) of
- undefined ->
- case ejabberd_config:get_local_option({ldap_rootdn, Host}) of
- undefined -> "";
- RDN -> RDN
- end;
- RDN -> RDN
- end,
- Password = case gen_mod:get_opt(ldap_password, Opts, undefined) of
- undefined ->
- case ejabberd_config:get_local_option({ldap_password, Host}) of
- undefined -> "";
- Pass -> Pass
- end;
- Pass -> Pass
- end,
- SubFilter = "("++UIDAttr++"="++UIDAttrFormat++")",
- UserFilter = case gen_mod:get_opt(ldap_filter, Opts, undefined) of
- undefined ->
- case ejabberd_config:get_local_option({ldap_filter, Host}) of
- undefined -> SubFilter;
- "" -> SubFilter;
- F -> "(&" ++ SubFilter ++ F ++ ")"
- end;
- "" -> SubFilter;
- F -> "(&" ++ SubFilter ++ F ++ ")"
- end,
- {ok, SearchFilter} = eldap_filter:parse(
- eldap_filter:do_sub(UserFilter, [{"%u","*"}])),
- VCardMap = gen_mod:get_opt(ldap_vcard_map, Opts, ?VCARD_MAP),
- SearchFields = gen_mod:get_opt(ldap_search_fields, Opts, ?SEARCH_FIELDS),
- SearchReported = gen_mod:get_opt(ldap_search_reported, Opts, ?SEARCH_REPORTED),
- %% In search requests we need to fetch only attributes defined
- %% in vcard-map and search-reported. In some cases,
- %% this will essentially reduce network traffic from an LDAP server.
- VCardMapAttrs = lists:usort(
- lists:append([A || {_, _, A} <- VCardMap]) ++ [UIDAttr]),
- SearchReportedAttrs =
- lists:usort(lists:flatmap(
- fun({_, N}) ->
- case lists:keysearch(N, 1, VCardMap) of
- {value, {_, _, L}} -> L;
- _ -> []
- end
- end, SearchReported) ++ [UIDAttr]),
- #state{serverhost = Host,
- myhost = MyHost,
- eldap_id = Eldap_ID,
- search = Search,
- servers = LDAPServers,
- port = LDAPPort,
- dn = RootDN,
- base = LDAPBase,
- password = Password,
- uid = UIDAttr,
- uid_format = UIDAttrFormat,
- vcard_map = VCardMap,
- vcard_map_attrs = VCardMapAttrs,
- user_filter = UserFilter,
- search_filter = SearchFilter,
- search_fields = SearchFields,
- search_reported = SearchReported,
- search_reported_attrs = SearchReportedAttrs
- }.
diff --git a/ejabberd-1.1.2/src/mod_vcard_odbc.erl b/ejabberd-1.1.2/src/mod_vcard_odbc.erl
deleted file mode 100644
index 3f03d6532..000000000
--- a/ejabberd-1.1.2/src/mod_vcard_odbc.erl
+++ /dev/null
@@ -1,655 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_vcard.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : vCard support via ODBC
-%%% Created : 2 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_vcard_odbc).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_mod).
-
--export([start/2, init/3, stop/1,
- get_sm_features/5,
- process_local_iq/3,
- process_sm_iq/3,
- %reindex_vcards/0,
- remove_user/2]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
-
--define(JUD_MATCHES, 30).
--define(PROCNAME, ejabberd_mod_vcard).
-
-start(Host, Opts) ->
- ejabberd_hooks:add(remove_user, Host,
- ?MODULE, remove_user, 50),
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
- ?MODULE, process_local_iq, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
- ?MODULE, process_sm_iq, IQDisc),
- ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
- MyHost = gen_mod:get_opt(host, Opts, "vjud." ++ Host),
- Search = gen_mod:get_opt(search, Opts, true),
- register(gen_mod:get_module_proc(Host, ?PROCNAME),
- spawn(?MODULE, init, [MyHost, Host, Search])).
-
-
-init(Host, ServerHost, Search) ->
- case Search of
- false ->
- loop(Host, ServerHost);
- _ ->
- ejabberd_router:register_route(Host),
- loop(Host, ServerHost)
- end.
-
-loop(Host, ServerHost) ->
- receive
- {route, From, To, Packet} ->
- case catch do_route(ServerHost, From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]);
- _ ->
- ok
- end,
- loop(Host, ServerHost);
- stop ->
- ejabberd_router:unregister_route(Host),
- ok;
- _ ->
- loop(Host, ServerHost)
- end.
-
-stop(Host) ->
- ejabberd_hooks:delete(remove_user, Host,
- ?MODULE, remove_user, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
- ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
- Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- Proc ! stop,
- {wait, Proc}.
-
-get_sm_features({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
- Acc;
-
-get_sm_features(Acc, _From, _To, Node, _Lang) ->
- case Node of
- [] ->
- case Acc of
- {result, Features} ->
- {result, [?NS_VCARD | Features]};
- empty ->
- {result, [?NS_VCARD]}
- end;
- _ ->
- Acc
- end.
-
-process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- IQ#iq{type = result,
- sub_el = [{xmlelement, "vCard",
- [{"xmlns", ?NS_VCARD}],
- [{xmlelement, "FN", [],
- [{xmlcdata, "ejabberd"}]},
- {xmlelement, "URL", [],
- [{xmlcdata,
- "http://ejabberd.jabberstudio.org/"}]},
- {xmlelement, "DESC", [],
- [{xmlcdata,
- translate:translate(
- Lang,
- "Erlang Jabber Server\n"
- "Copyright (c) 2002-2006 Alexey Shchepin")}]},
- {xmlelement, "BDAY", [],
- [{xmlcdata, "2002-11-16"}]}
- ]}]}
- end.
-
-
-process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- #jid{user = User, lserver = LServer} = From,
- case lists:member(LServer, ?MYHOSTS) of
- true ->
- set_vcard(User, LServer, SubEl),
- IQ#iq{type = result, sub_el = []};
- false ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
- end;
- get ->
- #jid{luser = LUser, lserver = LServer} = To,
- Username = ejabberd_odbc:escape(LUser),
- case catch ejabberd_odbc:sql_query(
- LServer,
- ["select vcard from vcard "
- "where username='", Username, "';"]) of
- {selected, ["vcard"], [{SVCARD}]} ->
- case xml_stream:parse_element(SVCARD) of
- {error, _Reason} ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
- VCARD ->
- IQ#iq{type = result, sub_el = [VCARD]}
- end;
- {selected, ["vcard"], []} ->
- IQ#iq{type = result, sub_el = []};
- {'EXIT', _Reason} ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
- end
- end.
-
-set_vcard(User, LServer, VCARD) ->
- FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]),
- Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]),
- Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]),
- Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]),
- Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]),
- BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]),
- CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]),
- Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},cdata]),
- EMail1 = xml:get_path_s(VCARD, [{elem, "EMAIL"}, {elem, "USERID"},cdata]),
- EMail2 = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]),
- OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
- OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
- EMail = case EMail1 of
- "" ->
- EMail2;
- _ ->
- EMail1
- end,
-
- LUser = jlib:nodeprep(User),
- LFN = stringprep:tolower(FN),
- LFamily = stringprep:tolower(Family),
- LGiven = stringprep:tolower(Given),
- LMiddle = stringprep:tolower(Middle),
- LNickname = stringprep:tolower(Nickname),
- LBDay = stringprep:tolower(BDay),
- LCTRY = stringprep:tolower(CTRY),
- LLocality = stringprep:tolower(Locality),
- LEMail = stringprep:tolower(EMail),
- LOrgName = stringprep:tolower(OrgName),
- LOrgUnit = stringprep:tolower(OrgUnit),
-
- if
- (LUser == error) or
- (LFN == error) or
- (LFamily == error) or
- (LGiven == error) or
- (LMiddle == error) or
- (LNickname == error) or
- (LBDay == error) or
- (LCTRY == error) or
- (LLocality == error) or
- (LEMail == error) or
- (LOrgName == error) or
- (LOrgUnit == error) ->
- {error, badarg};
- true ->
- Username = ejabberd_odbc:escape(User),
- LUsername = ejabberd_odbc:escape(LUser),
- SVCARD = ejabberd_odbc:escape(
- lists:flatten(xml:element_to_string(VCARD))),
-
- SFN = ejabberd_odbc:escape(FN),
- SLFN = ejabberd_odbc:escape(LFN),
- SFamily = ejabberd_odbc:escape(Family),
- SLFamily = ejabberd_odbc:escape(LFamily),
- SGiven = ejabberd_odbc:escape(Given),
- SLGiven = ejabberd_odbc:escape(LGiven),
- SMiddle = ejabberd_odbc:escape(Middle),
- SLMiddle = ejabberd_odbc:escape(LMiddle),
- SNickname = ejabberd_odbc:escape(Nickname),
- SLNickname = ejabberd_odbc:escape(LNickname),
- SBDay = ejabberd_odbc:escape(BDay),
- SLBDay = ejabberd_odbc:escape(LBDay),
- SCTRY = ejabberd_odbc:escape(CTRY),
- SLCTRY = ejabberd_odbc:escape(LCTRY),
- SLocality = ejabberd_odbc:escape(Locality),
- SLLocality = ejabberd_odbc:escape(LLocality),
- SEMail = ejabberd_odbc:escape(EMail),
- SLEMail = ejabberd_odbc:escape(LEMail),
- SOrgName = ejabberd_odbc:escape(OrgName),
- SLOrgName = ejabberd_odbc:escape(LOrgName),
- SOrgUnit = ejabberd_odbc:escape(OrgUnit),
- SLOrgUnit = ejabberd_odbc:escape(LOrgUnit),
-
- ejabberd_odbc:sql_transaction(
- LServer,
- [["delete from vcard where username='", LUsername, "';"],
- ["insert into vcard(username, vcard) "
- "values ('", LUsername, "', '", SVCARD, "');"],
- ["delete from vcard_search where lusername='", LUsername, "';"],
- ["insert into vcard_search("
- " username, lusername, fn, lfn, family, lfamily,"
- " given, lgiven, middle, lmiddle, nickname, lnickname,"
- " bday, lbday, ctry, lctry, locality, llocality,"
- " email, lemail, orgname, lorgname, orgunit, lorgunit)"
- "values (",
- " '", Username, "', '", LUsername, "',"
- " '", SFN, "', '", SLFN, "',"
- " '", SFamily, "', '", SLFamily, "',"
- " '", SGiven, "', '", SLGiven, "',"
- " '", SMiddle, "', '", SLMiddle, "',"
- " '", SNickname, "', '", SLNickname, "',"
- " '", SBDay, "', '", SLBDay, "',"
- " '", SCTRY, "', '", SLCTRY, "',"
- " '", SLocality, "', '", SLLocality, "',"
- " '", SEMail, "', '", SLEMail, "',"
- " '", SOrgName, "', '", SLOrgName, "',"
- " '", SOrgUnit, "', '", SLOrgUnit, "');"]])
- end.
-
--define(TLFIELD(Type, Label, Var),
- {xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
- {"var", Var}], []}).
-
-
--define(FORM(JID),
- [{xmlelement, "instructions", [],
- [{xmlcdata, translate:translate(Lang, "You need an x:data capable client to search")}]},
- {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}],
- [{xmlelement, "title", [],
- [{xmlcdata, translate:translate(Lang, "Search users in ") ++
- jlib:jid_to_string(JID)}]},
- {xmlelement, "instructions", [],
- [{xmlcdata, translate:translate(Lang, "Fill in the form to search "
- "for any matching Jabber User "
- "(Add * to the end of field to "
- "match substring)")}]},
- ?TLFIELD("text-single", "User", "user"),
- ?TLFIELD("text-single", "Full Name", "fn"),
- ?TLFIELD("text-single", "Name", "given"),
- ?TLFIELD("text-single", "Middle Name", "middle"),
- ?TLFIELD("text-single", "Family Name", "family"),
- ?TLFIELD("text-single", "Nickname", "nickname"),
- ?TLFIELD("text-single", "Birthday", "bday"),
- ?TLFIELD("text-single", "Country", "ctry"),
- ?TLFIELD("text-single", "City", "locality"),
- ?TLFIELD("text-single", "Email", "email"),
- ?TLFIELD("text-single", "Organization Name", "orgname"),
- ?TLFIELD("text-single", "Organization Unit", "orgunit")
- ]}]).
-
-do_route(ServerHost, From, To, Packet) ->
- #jid{user = User, resource = Resource} = To,
- if
- (User /= "") or (Resource /= "") ->
- Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router:route(To, From, Err);
- true ->
- IQ = jlib:iq_query_info(Packet),
- case IQ of
- #iq{type = Type, xmlns = ?NS_SEARCH, lang = Lang, sub_el = SubEl} ->
- case Type of
- set ->
- XDataEl = find_xdata_el(SubEl),
- case XDataEl of
- false ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_BAD_REQUEST),
- ejabberd_router:route(To, From, Err);
- _ ->
- XData = jlib:parse_xdata_submit(XDataEl),
- case XData of
- invalid ->
- Err = jlib:make_error_reply(
- Packet,
- ?ERR_BAD_REQUEST),
- ejabberd_router:route(To, From,
- Err);
- _ ->
- ResIQ =
- IQ#iq{
- type = result,
- sub_el =
- [{xmlelement,
- "query",
- [{"xmlns", ?NS_SEARCH}],
- [{xmlelement, "x",
- [{"xmlns", ?NS_XDATA},
- {"type", "result"}],
- search_result(Lang, To, ServerHost, XData)
- }]}]},
- ejabberd_router:route(
- To, From, jlib:iq_to_xml(ResIQ))
- end
- end;
- get ->
- ResIQ = IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_SEARCH}],
- ?FORM(To)
- }]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = Type, xmlns = ?NS_DISCO_INFO} ->
- case Type of
- set ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_NOT_ALLOWED),
- ejabberd_router:route(To, From, Err);
- get ->
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_DISCO_INFO}],
- [{xmlelement, "identity",
- [{"category", "directory"},
- {"type", "user"},
- {"name",
- "vCard User Search"}],
- []},
- {xmlelement, "feature",
- [{"var", ?NS_SEARCH}], []},
- {xmlelement, "feature",
- [{"var", ?NS_VCARD}], []}
- ]
- }]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = Type, xmlns = ?NS_DISCO_ITEMS} ->
- case Type of
- set ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_NOT_ALLOWED),
- ejabberd_router:route(To, From, Err);
- get ->
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_DISCO_ITEMS}],
- []}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} ->
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "vCard",
- [{"xmlns", ?NS_VCARD}],
- iq_get_vcard(Lang)}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ));
- _ ->
- Err = jlib:make_error_reply(Packet,
- ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router:route(To, From, Err)
- end
- end.
-
-iq_get_vcard(Lang) ->
- [{xmlelement, "FN", [],
- [{xmlcdata, "ejabberd/mod_vcard"}]},
- {xmlelement, "URL", [],
- [{xmlcdata,
- "http://ejabberd.jabberstudio.org/"}]},
- {xmlelement, "DESC", [],
- [{xmlcdata, translate:translate(
- Lang,
- "ejabberd vCard module\n"
- "Copyright (c) 2003-2006 Alexey Shchepin")}]}].
-
-find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) ->
- find_xdata_el1(SubEls).
-
-find_xdata_el1([]) ->
- false;
-find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_XDATA ->
- {xmlelement, Name, Attrs, SubEls};
- _ ->
- find_xdata_el1(Els)
- end;
-find_xdata_el1([_ | Els]) ->
- find_xdata_el1(Els).
-
--define(LFIELD(Label, Var),
- {xmlelement, "field", [{"label", translate:translate(Lang, Label)},
- {"var", Var}], []}).
-
-search_result(Lang, JID, ServerHost, Data) ->
- [{xmlelement, "title", [],
- [{xmlcdata, translate:translate(Lang, "Search Results for ") ++
- jlib:jid_to_string(JID)}]},
- {xmlelement, "reported", [],
- [?LFIELD("Jabber ID", "jid"),
- ?LFIELD("Full Name", "fn"),
- ?LFIELD("Name", "given"),
- ?LFIELD("Middle Name", "middle"),
- ?LFIELD("Family Name", "family"),
- ?LFIELD("Nickname", "nickname"),
- ?LFIELD("Birthday", "bday"),
- ?LFIELD("Country", "ctry"),
- ?LFIELD("City", "locality"),
- ?LFIELD("Email", "email"),
- ?LFIELD("Organization Name", "orgname"),
- ?LFIELD("Organization Unit", "orgunit")
- ]}] ++ lists:map(fun(R) -> record_to_item(ServerHost, R) end,
- search(ServerHost, Data)).
-
--define(FIELD(Var, Val),
- {xmlelement, "field", [{"var", Var}],
- [{xmlelement, "value", [],
- [{xmlcdata, Val}]}]}).
-
-
-record_to_item(LServer, {Username, FN, Family, Given, Middle,
- Nickname, BDay, CTRY, Locality,
- EMail, OrgName, OrgUnit}) ->
- {xmlelement, "item", [],
- [
- ?FIELD("jid", Username ++ "@" ++ LServer),
- ?FIELD("fn", FN),
- ?FIELD("family", Family),
- ?FIELD("given", Given),
- ?FIELD("middle", Middle),
- ?FIELD("nickname", Nickname),
- ?FIELD("bday", BDay),
- ?FIELD("ctry", CTRY),
- ?FIELD("locality", Locality),
- ?FIELD("email", EMail),
- ?FIELD("orgname", OrgName),
- ?FIELD("orgunit", OrgUnit)
- ]
- }.
-
-
-search(LServer, Data) ->
- MatchSpec = make_matchspec(LServer, Data),
- AllowReturnAll = gen_mod:get_module_opt(LServer, ?MODULE,
- allow_return_all, false),
- if
- (MatchSpec == "") and (not AllowReturnAll) ->
- [];
- true ->
- Limit = case gen_mod:get_module_opt(LServer, ?MODULE,
- matches, ?JUD_MATCHES) of
- infinity ->
- "";
- Val when is_integer(Val) and (Val > 0) ->
- [" LIMIT ", integer_to_list(Val)];
- Val ->
- ?ERROR_MSG("Illegal option value ~p. "
- "Default value ~p substituted.",
- [{matches, Val}, ?JUD_MATCHES]),
- [" LIMIT ", integer_to_list(?JUD_MATCHES)]
- end,
- case catch ejabberd_odbc:sql_query(
- LServer,
- ["select username, fn, family, given, middle, "
- " nickname, bday, ctry, locality, "
- " email, orgname, orgunit from vcard_search ",
- MatchSpec, Limit, ";"]) of
- {selected, ["username", "fn", "family", "given", "middle",
- "nickname", "bday", "ctry", "locality",
- "email", "orgname", "orgunit"],
- Rs} when is_list(Rs) ->
- Rs;
- Error ->
- ?ERROR_MSG("~p", [Error]),
- []
- end
- end.
-
-
-make_matchspec(LServer, Data) ->
- filter_fields(Data, "", LServer).
-
-filter_fields([], Match, _LServer) ->
- case Match of
- "" ->
- "";
- _ ->
- [" where ", Match]
- end;
-filter_fields([{SVar, [Val]} | Ds], Match, LServer)
- when is_list(Val) and (Val /= "") ->
- LVal = stringprep:tolower(Val),
- NewMatch = case SVar of
- "user" -> make_val(Match, "lusername", LVal);
- "fn" -> make_val(Match, "lfn", LVal);
- "family" -> make_val(Match, "lfamily", LVal);
- "given" -> make_val(Match, "lgiven", LVal);
- "middle" -> make_val(Match, "lmiddle", LVal);
- "nickname" -> make_val(Match, "lnickname", LVal);
- "bday" -> make_val(Match, "lbday", LVal);
- "ctry" -> make_val(Match, "lctry", LVal);
- "locality" -> make_val(Match, "llocality", LVal);
- "email" -> make_val(Match, "lemail", LVal);
- "orgname" -> make_val(Match, "lorgname", LVal);
- "orgunit" -> make_val(Match, "lorgunit", LVal);
- _ -> Match
- end,
- filter_fields(Ds, NewMatch, LServer);
-filter_fields([_ | Ds], Match, LServer) ->
- filter_fields(Ds, Match, LServer).
-
-make_val(Match, Field, Val) ->
- Condition =
- case lists:suffix("*", Val) of
- true ->
- Val1 = lists:sublist(Val, length(Val) - 1),
- SVal = ejabberd_odbc:escape_like(Val1) ++ "%",
- [Field, " LIKE '", SVal, "'"];
- _ ->
- SVal = ejabberd_odbc:escape(Val),
- [Field, " = '", SVal, "'"]
- end,
- case Match of
- "" ->
- Condition;
- _ ->
- [Match, " and ", Condition]
- end.
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%set_vcard_t(R, _) ->
-% US = R#vcard.us,
-% User = US,
-% VCARD = R#vcard.vcard,
-%
-% FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]),
-% Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]),
-% Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]),
-% Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]),
-% Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]),
-% BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]),
-% CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]),
-% Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},cdata]),
-% EMail = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]),
-% OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
-% OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
-%
-% {LUser, _LServer} = US,
-% LFN = stringprep:tolower(FN),
-% LFamily = stringprep:tolower(Family),
-% LGiven = stringprep:tolower(Given),
-% LMiddle = stringprep:tolower(Middle),
-% LNickname = stringprep:tolower(Nickname),
-% LBDay = stringprep:tolower(BDay),
-% LCTRY = stringprep:tolower(CTRY),
-% LLocality = stringprep:tolower(Locality),
-% LEMail = stringprep:tolower(EMail),
-% LOrgName = stringprep:tolower(OrgName),
-% LOrgUnit = stringprep:tolower(OrgUnit),
-%
-% if
-% (LUser == error) or
-% (LFN == error) or
-% (LFamily == error) or
-% (LGiven == error) or
-% (LMiddle == error) or
-% (LNickname == error) or
-% (LBDay == error) or
-% (LCTRY == error) or
-% (LLocality == error) or
-% (LEMail == error) or
-% (LOrgName == error) or
-% (LOrgUnit == error) ->
-% {error, badarg};
-% true ->
-% mnesia:write(
-% #vcard_search{us = US,
-% user = User, luser = LUser,
-% fn = FN, lfn = LFN,
-% family = Family, lfamily = LFamily,
-% given = Given, lgiven = LGiven,
-% middle = Middle, lmiddle = LMiddle,
-% nickname = Nickname, lnickname = LNickname,
-% bday = BDay, lbday = LBDay,
-% ctry = CTRY, lctry = LCTRY,
-% locality = Locality, llocality = LLocality,
-% email = EMail, lemail = LEMail,
-% orgname = OrgName, lorgname = LOrgName,
-% orgunit = OrgUnit, lorgunit = LOrgUnit
-% })
-% end.
-%
-%
-%reindex_vcards() ->
-% F = fun() ->
-% mnesia:foldl(fun set_vcard_t/2, [], vcard)
-% end,
-% mnesia:transaction(F).
-
-
-remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- Username = ejabberd_odbc:escape(LUser),
- ejabberd_odbc:sql_transaction(
- LServer,
- [["delete from vcard where username='", Username, "';"],
- ["delete from vcard_search where lusername='", Username, "';"]]).
-
-
diff --git a/ejabberd-1.1.2/src/mod_version.erl b/ejabberd-1.1.2/src/mod_version.erl
deleted file mode 100644
index c62e27a0d..000000000
--- a/ejabberd-1.1.2/src/mod_version.erl
+++ /dev/null
@@ -1,67 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : mod_version.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(mod_version).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_mod).
-
--export([start/2,
- stop/1,
- process_local_iq/3]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
-
-
-
-start(Host, Opts) ->
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VERSION,
- ?MODULE, process_local_iq, IQDisc).
-
-stop(Host) ->
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VERSION).
-
-
-process_local_iq(From, To, #iq{id = ID, type = Type,
- xmlns = XMLNS, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- OSType = case os:type() of
- {Osfamily, Osname} ->
- atom_to_list(Osfamily) ++ "/" ++
- atom_to_list(Osname);
- Osfamily ->
- atom_to_list(Osfamily)
- end,
- OSVersion = case os:version() of
- {Major, Minor, Release} ->
- lists:flatten(
- io_lib:format("~w.~w.~w",
- [Major, Minor, Release]));
- VersionString ->
- VersionString
- end,
- OS = OSType ++ " " ++ OSVersion,
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_VERSION}],
- [{xmlelement, "name", [],
- [{xmlcdata, "ejabberd"}]},
- {xmlelement, "version", [],
- [{xmlcdata, ?VERSION}]},
- {xmlelement, "os", [],
- [{xmlcdata, OS}]}
- ]}]}
- end.
-
-
diff --git a/ejabberd-1.1.2/src/msgs/cs.msg b/ejabberd-1.1.2/src/msgs/cs.msg
deleted file mode 100644
index ecfbc5c49..000000000
--- a/ejabberd-1.1.2/src/msgs/cs.msg
+++ /dev/null
@@ -1,397 +0,0 @@
-% $Id$
-% Czech translation
-% Authors: Milos Svasek [DuxforD] from openheads.net
-
-
-% jlib.hrl
-{"No resource provided", "Nebyl poskytnutý žádny zdroj"}.
-
-% mod_configure.erl
-{"Choose storage type of tables", "Vyberte typ úložiště pro tabulky"}.
-{"RAM copy", "Kopie RAM"}.
-{"RAM and disc copy", "Kopie RAM a disku"}.
-{"Disc only copy", "Jen kopie disku"}.
-{"Remote copy", "Vzdálená kopie"}.
-{"Stop Modules at ", "Zastavit moduly na "}.
-{"Choose modules to stop", "Vyberte moduly, které mají být zastavené"}.
-{"Start Modules at ", "Spustit moduly na "}.
-{"Enter list of {Module, [Options]}", "Vložte seznam modulů {Modul, [Parametre]}"}.
-{"List of modules to start", "Seznam modulů, které mají být spuštěné"}.
-{"Backup to File at ", "Záloha do souboru na "}.
-{"Enter path to backup file", "Zadajte cestu k souboru se zálohou"}.
-{"Path to File", "Cesta k souboru"}.
-{"Restore Backup from File at ", "Obnovit zálohu ze souboru na "}.
-{"Dump Backup to Text File at ", "Uložit zálohu do textového souboru na "}.
-{"Enter path to text file", "Zadajte cestu k textovému souboru"}.
-{"Import User from File at ", "Importovat uživatele ze souboru na "}.
-{"Enter path to jabberd1.4 spool file", "Zadejte cestu k spool souboru jabberd1.4"}.
-{"Import Users from Dir at ", "Importovat uživatele z adresáře na "}.
-{"Enter path to jabberd1.4 spool dir", "Zadejte cestu k jabberd1.4 spool adresáři"}.
-{"Path to Dir", "Cesta k adresáři"}.
-{"Hostname Configuration", "Konfigurace jména serveru"}.
-{"Choose host name", "Vyberte jméno serveru"}.
-{"Host name", "Jméno serveru"}.
-{"Access Control List Configuration", "Konfigurace seznamu přístupových práv (ACL)"}.
-{"Access control lists", "Seznamy přístupových práv (ACL)"}.
-{"Access Configuration", "Konfigurace přístupů"}.
-{"Access rules", "Pravidla přístupů"}.
-{"Remove Users", "Odstranit uživatele"}.
-{"Choose users to remove", "Vybrat uživatele, kteří budou odstraněni"}.
-{"Administration of ", "Administrace "}.
-{"Action on user", "Akce aplikovaná na uživatele"}.
-{"Edit Properties", "Upravit vlastnosti"}.
-{"Remove User", "Odstranit uživatele"}.
-
-% mod_disco.erl
-{"Configuration", "Konfigurace"}.
-{"Online Users", "Online uživatelé"}.
-{"All Users", "Všichni uživatelé"}.
-{"To ~s", "Pre ~s"}.
-{"From ~s", "Od ~s"}.
-{"Running Nodes", "Bežící uzly"}.
-{"Stopped Nodes", "Zastavené uzly"}.
-{"Host Name", "Jméno serveru"}.
-{"Access Control Lists", "Seznamy přístupových práv (ACL)"}.
-{"Access Rules", "Pravidla přístupů"}.
-{"Remove Users", "Odstranit uživatele"}.
-{"Modules", "Moduly"}.
-{"Start Modules", "Spustit moduly"}.
-{"Stop Modules", "Zastavit moduly"}.
-{"Backup Management", "Správa zálohování"}.
-{"Backup", "Zálohovat"}.
-{"Restore", "Obnovit"}.
-{"Dump to Text File", "Uložit do textového souboru"}.
-{"Import File", "Import souboru"}.
-{"Import Directory", "Import adresáře"}.
-
-% mod_register.erl
-{"Choose a username and password to register with this server",
- "Zadejte jméno uživatele a heslo pro registraci na tomto serveru"}.
-
-% mod_vcard.erl
-{"You need an x:data capable client to search",
- "K vyhledávání potřebujete klienta podporujícího x:data"}.
-{"Search users in ", "Hledat uživatele v "}.
-{"Fill in fields to search for any matching Jabber User",
- "Vyplňte políčka pro vyhledávání Jabber uživatele"}.
-
-{"User", "Uživatel: "}.
-{"Full Name", "Celé jméno: "}.
-{"Name", "Jméno: "}.
-{"Middle Name", "Prostřední jméno: "}.
-{"Family Name", "Příjmení: "}.
-{"Nickname", "Přezdívka: "}.
-{"Birthday", "Datum narození: "}.
-{"Country", "Země: "}.
-{"City", "Město: "}.
-{"Organization Name", "Název firmy: "}.
-{"Organization Unit", "Oddělení: "}.
-
-% mod_muc/mod_muc.erl
-{"You need an x:data capable client to register nickname",
- "K registraci přezdívky potřebujete klienta podporujícího z x:data"}.
-{"Nickname Registration at ", "Registrace prezdívky na "}.
-{"Enter nickname you want to register", "Zadajte prezdívku, kterou chete zaregistrovat"}.
-{"Only service administrators are allowed to send service messages",
- "Pouze správci služby mají povolené odesílání servisních zpráv"}.
-{"Conference room does not exist", "Konferenční místnost neexistuje"}.
-{"Access denied by service policy", "Přístup byl zamítnutý nastavením služby"}.
-{"Specified nickname is already registered", "Zadaná prezdívka je již registrována"}.
-
-% mod_muc/mod_muc_room.erl
-{" has set the subject to: ", "změnil(a) téma na: "}.
-{"You need an x:data capable client to configure room",
- "Ke konfiguraci místnosti potřebujete klienta podporujícího z x:data"}.
-{"Configuration for ", "Konfigurace pre "}.
-{"Room title", "Název místnosti"}.
-{"Password", "Heslo"}.
-{"Only moderators and participants are allowed to change subject in this room",
- "Jen moderátoři a účastníci mají povoleno měnit téma této místnosti"}.
-{"Only moderators are allowed to change subject in this room",
- "Jen moderátoři mají povoleno měnit téma místnosti"}.
-{"Visitors are not allowed to send messages to all occupants",
- "Návštevníci nemají povoleno zsílat zprávy všem přihlášeným do konference"}.
-{"Only occupants are allowed to send messages to the conference",
- "Jen členové mají povolené zasílat správy do konference"}.
-{"It is not allowed to send normal messages to the conference",
- "Není povoleno odesílat normální zprávy do konference"}.
-{"It is not allowed to send private messages to the conference",
- "Není povoleno odesílat soukromé zprávy do konference"}.
-{"Improper message type", "Nesprávný typ zprávy"}.
-{"Nickname is already in use by another occupant", "Prezdívka je již používána jiným členem"}.
-{"Nickname is registered by another person", "Prezdívka je registrována jinou osobou"}.
-{"It is not allowed to send private messages of type \"groupchat\"",
- "Není dovoleno odeslání soukromé zprávy typu \"Skupinová zpráva\" "}.
-{"Recipient is not in the conference room", "Příjemce se nenachází v konferenční místnosti"}.
-{"Only occupants are allowed to send queries to the conference",
- "Jen členové mohou odesílat požadavky (query) do konference"}.
-{"Queries to the conference members are not allowed in this room",
- "Požadavky (queries) na členy konference nejsou v této místnosti povolené"}.
-{"You have been banned from this room", "Byl jste vyloučen z této místnosti"}.
-{"Membership required to enter this room", "Pro vstup do místnosti musíte být členem"}.
-{"Password required to enter this room", "Pro vstup do místnosti musíte zadat heslo"}.
-{"Incorrect password", "Nesprávne heslo"}.
-{"Administrator privileges required", "Jsou potřebná práva administrátora"}.
-{"Moderator privileges required", "Jsou potřebná práva moderátora"}.
-{"JID ~s is invalid", "JID ~s je neplatné"}.
-{"Nickname ~s does not exist in the room", "Prezdívka ~s v místnosti neexistuje"}.
-{"Invalid affiliation: ~s", "Neplatné přiřazení: ~s"}.
-{"Invalid role: ~s", "Neplatná role: ~s"}.
-{"Owner privileges required", "Jsou vyžadována práva vlastníka"}.
-{"private, ", "soukromá, "}.
-{"Present real JIDs to", "Zjisti skutečné JIDy pro"}.
-{"moderators only", "pouze pro moderátory"}.
-{"anyone", "každý"}.
-
-% mod_irc/mod_irc.erl
-{"You need an x:data capable client to configure mod_irc settings",
- "Pro konfiguraci mod_irc potřebujete klienta podporujícího x:data"}.
-{"Registration in mod_irc for ", "Registrace do mod_irc na "}.
-{"Enter username and encodings you wish to use for connecting to IRC servers",
- "Vložte jméno uživatele a kódování, které chcete používat při připojení na IRC server"}.
-{"IRC Username", "IRC prezdívka"}.
-{"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].",
- "Příklad: [{\"irc.freenode.net\",\"utf-8\"}, {\irc.freenode.net\", \"iso8859-2\"}]."}.
-{"Encodings", "Kódování"}.
-
-% web/ejabberd_web_admin.erl
-{"Users", "Uživatelé"}.
-{"Nodes", "Uzly"}.
-{"Statistics", "Statistiky"}.
-{"Submitted", "Odeslané"}.
-{"CPU Time:", "Čas procesoru"}.
-{"Delete Selected", "Smazat vybrané"}.
-{"Submit", "Odeslat"}.
-{"~s access rule configuration", "~s konfigurace pravidla přístupu"}.
-{"Node not found", "Uzel nenalezen"}.
-{"Add New", "Přidat nový"}.
-{"Change Password", "Změnit heslo"}.
-{"Connected Resources:", "Připojené zdroje:"}.
-{"Password:", "Heslo:"}.
-{"None", "Nic"}.
-{"Node ", "Uzel "}.
-{"Restart", "Restart"}.
-{"Stop", "Stop"}.
-{"Name", "Jméno"}.
-{"Storage Type", "Typ úložiště"}.
-{"Size", "Velikost"}.
-{"Memory", "Paměť"}.
-{"OK", "OK"}.
-{"Listened Ports at ", "Otevřené porty na "}.
-{"Port", "Port"}.
-{"Module", "Modul"}.
-{"Options", "Nastavení"}.
-{"Update", "Aktualizovat"}.
-{"Delete", "Smazat"}.
-{"Add User", "Přidat uživatele"}.
-{"Last Activity", "Poslední aktivita"}.
-{"Never", "Nikdy"}.
-{"Time", "Čas"}.
-{"From", "Od"}.
-{"To", "Pro"}.
-{"Packet", "Paket"}.
-{"Roster", "Seznam kontaktů"}.
-{"Nickname", "Prezdívka"}.
-{"Subscription", "Přihlášení"}.
-{"Pending", "Čekající"}.
-{"Groups", "Skupiny"}.
-{"Remove", "Odstranit"}.
-{"User ", "Uživatel "}.
-{"Roster of ", "Seznam kontaktů "}.
-{"Shared Roster", "Sdílený seznam kontaktů"}.
-{"Online", "Online"}.
-{"Validate", "Ověřit"}.
-{"Name:", "Jméno:"}.
-{"Description:", "Popis:"}.
-{"Members:", "Členové:"}.
-{"Displayed Groups:", "Zobrazené skupiny:"}.
-{"Group ", "Skupina "}.
-{"Period: ", "Čas:"}.
-{"Last month", "Poslední měsíc"}.
-{"Last year", "Poslední rok"}.
-{"All activity", "Všechny aktivity"}.
-{"Show Ordinary Table", "Zobrazit bežnou tabulku"}.
-{"Show Integral Table", "Zobrazit kompletní tabulku"}.
-{"Start", "Start"}.
-{"Modules at ", "Moduly na "}.
-{"Virtual Hosts", "Virtuální servery"}.
-{"ejabberd virtual hosts", "Ejabberd virtuální servery"}.
-{"Host", "Server"}.
-{"ejabberd Web Interface", "Ejabberd Web rozhraní"}.
-
-% mod_vcard_odbc.erl
-{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)",
- "Pro vyhledání Jabber uživatele vyplňte formulář (přidejte znak * na konec, pro vyhledání podřetězce)"}.
-
-% ejabberd_c2s.erl
-{"Use of STARTTLS required", "Je vyžadováno STARTTLS."}.
-{"Replaced by new connection", "Nahrazeno novým spojením"}.
-
-% mod_pubsub/mod_pubsub.erl
-{[], " "}.
-{"Node Creator", "Majitel uzlu"}.
-{"Deliver payloads with event notifications", "Doručovat náklad s upozorněním na událost"}.
-{"Notify subscribers when the node configuration changes", "Upozornit členy na změnu nastavení uzlu"}.
-{"Notify subscribers when the node is deleted", "Upozornit členy na smazaní uzlu"}.
-{"Notify subscribers when items are removed from the node", "Upozornit členy na odstranění položek z uzlu"}.
-{"Persist items to storage", "Uložit položky natrvalo do úložiště"}.
-{"Max # of items to persist", "Maximální počet položek, které je možné natrvalo uložit"}.
-{"Whether to allow subscriptions", "Povolit přihlašování"}.
-{"Specify the subscriber model", "Specifikovat přihlašovací model"}.
-{"Specify the publisher model", "Specifikovat model pro publikování"}.
-{"Max payload size in bytes", "Maximální náklad v bajtech"}.
-{"Send items to new subscribers", "Odeslat položky novým uživatelům"}.
-{"Only deliver notifications to available users", "Doručovat upozornení jen aktuálně přihlášeným uživatelům"}.
-{"Specify the current subscription approver", "Zadat současného schvalovatele přihlášení "}.
-
-% mod_irc/mod_irc.erl
-{"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.",
- "Pokud chcete zadat jiné kódování pro IRC servery, vyplňte seznam s hodnotami ve formátě '{\"irc server\",\"encoding\"}'. Předvolené kódování pro tuto službu je \"~s\"."}.
-
-% mod_muc/mod_muc.erl
-{"Room creation is denied by service policy", "Vytváranie miestnosti nie je povolené"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_vcard_odbc.erl
-{"Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin",
- "Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"Email", "E-mail"}.
-{"ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin",
- "Ejabberd vCard modul\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-{"Search Results for ", "Hledat výsledky pro "}.
-{"Jabber ID", "Jabber ID"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_adhoc.erl
-{"Commands", "Příkazy"}.
-{"Ping", "Ping"}.
-{"Pong", "Pong"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/ejabberd_c2s.erl
-{"Replaced by new connection", "Nahrazeno novým spojením"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_announce.erl
-{"Really delete message of the day?", "Skutečně smazat správu dne?"}.
-{"Subject", "Předmět"}.
-{"Message body", "Tělo zprávy"}.
-{"No body provided for announce message", "Zpráva neobsahuje text"}.
-{"Announcements", "Oznámení"}.
-{"Send announcement to all users", "Odeslat seznam všech uživatelů"}.
-{"Send announcement to all online users", "Odeslat seznam všech online uživatelů"}.
-{"Send announcement to all online users on all hosts", "Odeslat seznam všech online uživatelů na všech serverech"}.
-{"Set message of the day and send to online users", "Nastavit zprávu dne a odeslat jí online uživatelům"}.
-{"Update message of the day (don't send)", "Aktualizovat zprávu dne (neodesíelat)"}.
-{"Delete message of the day", "Smazat zprávu dne"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_configure.erl
-{"Database", "Databáze"}.
-{"Outgoing s2s Connections", "Odchozí s2s spojení"}.
-{"Import Users From jabberd 1.4 Spool Files", "Importovat uživatelů z jabber 1.4 spool souborů"}.
-{"Database Tables Configuration at ", "Konfigurace databázových tabulek "}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_pubsub/mod_pubsub.erl
-{"ejabberd pub/sub module\nCopyright (c) 2003-2006 Alexey Shchepin",
- "ejabberd pub/sub modul\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/web/ejabberd_web_admin.erl
-{"ejabberd Web Interface", "Ejabberd Web rozhraní"}.
-{"Administration", "Administrace"}.
-{"ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One",
- "Ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One"}.
-{"(Raw)", "(Zdroj)"}.
-{"Bad format", "Nesprávný formát"}.
-{"Raw", "Zdroj"}.
-{"Users Last Activity", "Poslední aktivita uživatele"}.
-{"Registered Users", "Registrovaní uživatelé"}.
-{"Offline Messages", "Offline zprávy"}.
-{"Registered Users:", "Registrovaní živatelé:"}.
-{"Authenticated Users:", "Ověření uživatelé:"}.
-{"Online Users:", "Online uživatelé:"}.
-{"Outgoing s2s Connections:", "Odchozí s2s spojení:"}.
-{"Outgoing s2s Servers:", "Odchozí s2s servery:"}.
-{"Offline Messages:", "Offline zprávy"}.
-{"~s's Offline Messages Queue", "~s Offline zpráv"}.
-{"Add Jabber ID", "Přidat JID"}.
-{"No Data", "Žádná data"}.
-{"Listened Ports", "Otevřené porty"}.
-{"RPC Call Error", "Chyba RPC volání"}.
-{"Database Tables at ", "Databázové tabulky na "}.
-{"Backup of ", "Záloha na "}.
-{"Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.",
- "Podotýkáme, že tato nastavení budou zálohované do zabudované databáze Mnesia. Pokud používáte ODBC modul, musíte zálohovat vaší SQL databázi separátně."}.
-{"Store binary backup:", "Uložit binární zálohu:"}.
-{"Restore binary backup immediately:", "Okamžitě obnovit binární zálohu:"}.
-{"Restore binary backup after next ejabberd restart (requires less memory):",
- "Obnovit binární zálohu při následujícím restartu Ejabberd (vyžaduje méně paměti)"}.
-{"Store plain text backup:", "Uložit zálohu do textového souboru:"}.
-{"Restore plain text backup immediately:", "Okamžitě obnovit zálohu z textového souboru:"}.
-{"Statistics of ~p", "Statistiky ~p"}.
-{"Uptime:", "Čas běhu"}.
-{"Transactions Commited:", "Transakce potvrzena"}.
-{"Transactions Aborted:", "Transakce zrušena"}.
-{"Transactions Restarted:", "Transakce restartována"}.
-{"Transactions Logged:", "Transakce zaznamenána"}.
-{"Update ", "Aktualizovat "}.
-{"Update plan", "Aktualizovat plán"}.
-{"Updated modules", "Aktualizované moduly"}.
-{"Update script", "Aktualizované skripty"}.
-{"Low level update script", "Nízkoúrovňový aktualizační skript"}.
-{"Script check", "Kontrola skriptu"}.
-{"Not Found", "Nenalezeno"}.
-{"Shared Roster Groups", "Skupiny pro zdílený seznam kontaktů"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_irc/mod_irc.erl
-{"ejabberd IRC module\nCopyright (c) 2003-2006 Alexey Shchepin", "Ejabberd IRC modul\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_muc/mod_muc_log.erl
-{"Chatroom configuration modified", "Nastavení diskuzní místnosti bylo změněno"}.
-{"joins the room", "vstoupil(a) do místnosti"}.
-{"leaves the room", "opustil(a) místnost"}.
-{"has been kicked", "byl(a) vyhozen(á) z místnosti"}.
-{"has been banned", "byl(a) zablokován(a)"}.
-{"is now known as", "se přejmenoval(a) na"}.
-{"Monday", "Pondělí"}.
-{"Tuesday", "Úterý"}.
-{"Wednesday", "Středa"}.
-{"Thursday", "Čtvrtek"}.
-{"Friday", "Pátek"}.
-{"Saturday", "Sobota"}.
-{"Sunday", "Neděle"}.
-{"January", "Leden"}.
-{"February", "Únor"}.
-{"March", "Březen"}.
-{"April", "Duben"}.
-{"May", "Květen"}.
-{"June", "Červen"}.
-{"July", "Červenec"}.
-{"August", "Srpen"}.
-{"September", "Září"}.
-{"October", "říjen"}.
-{"November", "Listopad"}.
-{"December", "Prosinec"}.
-{"Room Configuration", "Nastavení místnosti"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_muc/mod_muc.erl
-{"You must fill in field \"Nickname\" in the form",
- "Musíte vyplnit políčko \"Prezdívka\" ve formuláři"}.
-{"ejabberd MUC module\nCopyright (c) 2003-2006 Alexey Shchepin",
- "Ejabberd MUC modul\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_muc/mod_muc_room.erl
-{"This room is not anonymous", "Tato místnost není anonymní"}.
-{"Make room persistent", "Nastavit místnost jako stálou"}.
-{"Make room public searchable", "Nastavit místnost jako veřejně prohldávatelnou"}.
-{"Make participants list public", "Nastavit seznam účastníků jako veřejný"}.
-{"Make room password protected", "Chránit místnost heslem"}.
-{"Make room members-only", "Nastavit místnost jen pro členy"}.
-{"Make room moderated", "Nastavit místnost jako moderovanou"}.
-{"Default users as participants", "Uživatelé jsou implicitně členy"}.
-{"Allow users to change subject", "Povolit uživatelům měnit téma této místnosti"}.
-{"Allow users to send private messages", "Povolit uživatelům odesíelat soukromé zprávy"}.
-{"Allow users to query other users", "Povolit uživatelům odesíela požadavky (query) ostatním uživatelům"}.
-{"Allow users to send invites", "povolit uživatelům posíelání pozvánek"}.
-{"Enable logging", "Zapnout ukládání historie"}.
-{"Description", "Popis"}.
-{"Number of occupants", "Počet účastníků"}.
-
-% Local Variables:
-% mode: erlang
-% End:
diff --git a/ejabberd-1.1.2/src/msgs/de.msg b/ejabberd-1.1.2/src/msgs/de.msg
deleted file mode 100644
index c47821434..000000000
--- a/ejabberd-1.1.2/src/msgs/de.msg
+++ /dev/null
@@ -1,368 +0,0 @@
-% $Id$
-
-% jlib.hrl
-{"No resource provided", "Keine Ressource zur Verfügung"}.
-
-% mod_configure.erl
-{"Choose storage type of tables", "Wähle Speichertyp der Tabellen"}.
-{"RAM copy", "Kopie im RAM"}.
-{"RAM and disc copy", "Kopie im RAM und auf der Festplatte"}.
-{"Disc only copy", "Kopie nur auf Festplatte"}.
-{"Remote copy", "Fernkopie"}.
-{"Stop Modules at ", "Stop Module bei "}.
-{"Choose modules to stop", "Wähle zu stoppende Module"}.
-{"Start Modules at ", "Start Module bei "}.
-{"Enter list of {Module, [Options]}", "Geben Sie die Liste der Module ein {Module, [Optionen]}"}.
-{"List of modules to start", "Liste der zu startenden Module"}.
-{"Backup to File at ", "Datensicherung bei "}.
-{"Enter path to backup file", "Geben Sie den Pfad zur Datensicherung ein"}.
-{"Path to File", "Pfad zur Datei"}.
-{"Restore Backup from File at ", "Datenwiederherstellung von Datei "}.
-{"Dump Backup to Text File at ", "Ausgabe der Sicherung in diese Textdatei "}.
-{"Enter path to text file", "Geben Sie den Pfad zur Textdatei ein"}.
-{"Import User from File at ", "Benutzer aus dieser Datei importieren "}.
-{"Enter path to jabberd1.4 spool file", "Geben Sie den Pfad zur jabberd1.4 spool Datei ein"}.
-{"Import Users from Dir at ", "Benutzer vom Verzeichnis importieren "}.
-{"Enter path to jabberd1.4 spool dir", "Geben Sie den Pfad zum jabberd1.4 spool Verzeichnis ein"}.
-{"Path to Dir", "Pfad zum Verzeichnis"}.
-{"Hostname Configuration", "Konfiguration des Hostnamens"}.
-{"Choose host name", "Wählen Sie den Hostnamen"}.
-{"Host name", "Hostname"}.
-{"Access Control List Configuration", "Access Control List(ACL) Konfiguration"}.
-{"Access control lists", "Access Control Listen"}.
-{"Access Configuration", "Zugangskonfiguration"}.
-{"Access rules", "Zugangsregeln"}.
-{"Remove Users", "Benutzer löschen"}.
-{"Choose users to remove", "Wählen Sie die zu löschenden Benutzer"}.
-{"Administration of ", "Administration der "}.
-{"Action on user", "Aktion auf Benutzer"}.
-{"Edit Properties", "Einstellungen ändern"}.
-{"Remove User", "Benutzer löschen"}.
-
-% mod_disco.erl
-{"Configuration", "Konfiguration"}.
-{"Online Users", "Online Benutzer"}.
-{"All Users", "Alle Benutzer"}.
-{"To ~s", "An ~s"}.
-{"From ~s", "Von ~s"}.
-{"Running Nodes", "Aktive Knoten"}.
-{"Stopped Nodes", "Inaktive Knoten"}.
-{"Host Name", "Hostname"}.
-{"Access Control Lists", "Zugangskontrolllisten"}.
-{"Access Rules", "Zugangsregeln"}.
-{"Remove Users", "Benutzer löschen"}.
-{"Modules", "Module"}.
-{"Start Modules", "Module starten"}.
-{"Stop Modules", "Module stoppen"}.
-{"Backup Management", "Datensicherungsmanagement"}.
-{"Backup", "Sicherung"}.
-{"Restore", "Wiederherstellung"}.
-{"Dump to Text File", "Ausgabe in Textdatei"}.
-{"Import File", "Datei importieren"}.
-{"Import Directory", "Verzeichnis importieren"}.
-
-% mod_register.erl
-{"Choose a username and password to register with this server",
- "Wählen Sie zum Registrieren einen Benutzernamen und ein Passwort"}.
-
-% mod_vcard.erl
-{"ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin", "ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-{"You need an x:data capable client to search",
- "Sie brauchen einen x:data kompatiblen Client um suchen zu können"}.
-{"Search users in ", "Benutzer suchen in "}.
-{"Fill in fields to search for any matching Jabber User",
- "Felder ausfüllen, um nach passenden Jabber Benutzern zu suchen"}.
-
-{"User", "Benutzer"}.
-{"Full Name", "Ganzer Name"}.
-{"Name", "Vorname"}.
-{"Middle Name", "Mittelname"}.
-{"Family Name", "Nachname"}.
-{"Nickname", "Spitzname"}.
-{"Birthday", "Geburtsdatum"}.
-{"Country", "Land"}.
-{"City", "Stadt"}.
-{"Organization Name", "Firmenname"}.
-{"Organization Unit", "Abteilung"}.
-
-% mod_pubsub/mod_pubsub.erl
-{"ejabberd pub/sub module\nCopyright (c) 2003-2006 Alexey Shchepin", "ejabberd pub/sub module\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-{[], " "}.
-{"Node Creator", "Knoten Erschaffer"}.
-{"Deliver payloads with event notifications", "Nutzlast mit Benachrichtigungen versenden"}.
-{"Notify subscribers when the node configuration changes", "Benutzer benachrichtigen, wenn die Knotenkonfiguration sich ändert"}.
-{"Notify subscribers when the node is deleted", "Benutzer benachrichtigen, wenn der Knoten gelöscht wird"}.
-{"Notify subscribers when items are removed from the node", "Benutzer benachrichtigen, wenn Einträge vom Knoten entfernt werden"}.
-{"Persist items to storage", "Einträge dauerhaft speichern"}.
-{"Max # of items to persist", "Maximale Anzahl dauerhaft zu speichernder Einträge"}.
-{"Whether to allow subscriptions", "Ob Abonnements erlaubt sind"}.
-{"Specify the subscriber model", "Geben Sie das Abonnementsmodell an"}.
-{"Specify the publisher model", "Geben Sie das Publikationsmodell an"}.
-{"Max payload size in bytes", "Maximale Nutzlastgröße in Bytes"}.
-{"Send items to new subscribers", "Einträge an neue Abonnenten schicken"}.
-{"Only deliver notifications to available users", "Benachrichtigungen nur an User schicken, die verfügbar sind"}.
-{"Specify the current subscription approver", "Geben Sie an, wer die Abonnements bestätigt"}.
-
-% mod_muc/mod_muc.erl
-{"You need an x:data capable client to register nickname",
- "Sie brauchen einen für x:data geeigneten Client, um sich mit dem Spitznamen zu registrieren"}.
-{"Nickname Registration at ", "Registrieren des Spitznamens "}.
-{"Enter nickname you want to register", "Geben Sie den zu registrierenden Spitznamen ein"}.
-{"ejabberd MUC module\nCopyright (c) 2003-2006 Alexey Shchepin", "ejabberd MUC module\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-{"Only service administrators are allowed to send service messages",
- "Nur Service Administratoren sind berechtigt, Servicenachrichten zu senden"}.
-{"Conference room does not exist", "Konferenzraum existiert nicht"}.
-{"Access denied by service policy", "Zutritt verweigert von der Service Policy"}.
-{"You must fill in field \"Nickname\" in the form", "Sie müssen etwas ins Feld \"Nickname\" eintragen"}.
-{"Specified nickname is already registered", "Der angegebene Name ist bereits vergeben"}.
-{"Room creation is denied by service policy", "Anlegen des Raumes aufgrund von Servereinstellungen verweigert"}.
-
-% mod_muc/mod_muc_room.erl
-{" has set the subject to: ", " hat das Thema geändert zu "}.
-{"You need an x:data capable client to configure room",
- "Sie brauchen einen für x:data geeigneten Client um den Raum zu konfigurieren"}.
-{"Configuration for ", "Konfiguration für "}.
-{"Room title", "Raumname"}.
-{"Password", "Passwort"}.
-{"Only moderators and participants are allowed to change subject in this room",
- "Nur Moderatoren und Teilnehmer dürfen das Thema in diesem Raum ändern"}.
-{"Only moderators are allowed to change subject in this room",
- "Nur Moderatoren dürfen das Thema in diesem Raum ändern"}.
-{"Visitors are not allowed to send messages to all occupants",
- "Besucher dürfen nicht an alle im Raum Nachrichten verschicken"}.
-{"Only occupants are allowed to send messages to the conference",
- "Nur Leute im Raum dürfen Nachrichten an die Konferenz schicken"}.
-{"It is not allowed to send normal messages to the conference",
- "Es ist nicht erlaubt normale Nachrichten an die Konferenz zu schicken"}.
-{"It is not allowed to send private messages to the conference",
- "Es ist nicht erlaubt private Nachrichten an die Konferenz zu schicken"}.
-{"Improper message type", "Unzulässiger Nachrichtentyp"}.
-{"Nickname is already in use by another occupant", "Spitzname wird schon von jemand anderem genutzt"}.
-{"Nickname is registered by another person", "Spitzname wurde schon von jemand anderem registriert"}.
-{"It is not allowed to send private messages of type \"groupchat\"",
- "Es ist nicht erlaubt private Nachrichten des Typs \"Gruppenchat\" zu senden"}.
-{"Recipient is not in the conference room", "Der Empfänger ist nicht im Konferenzraum"}.
-{"Only occupants are allowed to send queries to the conference",
- "Nur Teilnehmer sind berechtig Anfragen an die Konferenz zu senden"}.
-{"Queries to the conference members are not allowed in this room",
- "Anfragen an die Konferenzmitglieder sind in diesem Raum nicht erlaubt"}.
-{"You have been banned from this room", "Sie wurden aus diesem Raum verbannt"}.
-{"Membership required to enter this room", "Um diesen Raum zu betreten müssen sie ein Mitglied sein"}.
-{"Password required to enter this room", "Sie brauchen ein Passwort um diesen Raum zu betreten"}.
-{"Incorrect password", "Falsches Passwort"}.
-{"Administrator privileges required", "Administratorenrechte benötigt"}.
-{"Moderator privileges required", "Moderatorrechte benötigt"}.
-{"JID ~s is invalid", "JID ~s ist ungültig"}.
-{"Nickname ~s does not exist in the room", "Spitzname ~s funktioniert im Raum nicht"}.
-{"Invalid affiliation: ~s", "Ungültige Option: ~s"}.
-{"Invalid role: ~s", "Ungültige Funktion: ~s"}.
-{"Owner privileges required", "Besitzerrechte benötigt"}.
-{"private, ", "privat"}.
-
-% mod_irc/mod_irc.erl
-{"ejabberd IRC module\nCopyright (c) 2003-2006 Alexey Shchepin", "ejabberd IRC module\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-{"You need an x:data capable client to configure mod_irc settings",
- "Sie brauchen einen x:data kompatiblen Client um die mod_irc Einstellungen zu konfigurieren"}.
-{"Registration in mod_irc for ", "Registrierung in mod_irc für "}.
-{"Enter username and encodings you wish to use for connecting to IRC servers",
- "Geben Sie Benutzernamen und Verschlüsselung für die Verbindung zum IRC Server an"}.
-{"IRC Username", "IRC Benutzername"}.
-{"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].",
- "Beispiel: [{\"irc.lucky.net\",\"koi8-r\"}, {\vendetta.fef.net\", \"iso8859-1\"}]."}.
-{"Encodings", "Verschlüsselungen"}.
-{"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.", "Wenn Sie verschiedene Verschlüsselungen für IRC Server angeben, schreiben Sie diese im Format '{\"irc server\", \"encoding\"}'. Standardmäßig benutzt der Dienst die \"~s\" Verschlüsselung"}.
-
-% web/ejabberd_web_admin.erl
-{"Users", "Benutzer"}.
-{"Nodes", "Knoten(nodes)"}.
-{"Statistics", "Statistik"}.
-{"Delete Selected", "Lösche Markiertes"}.
-{"Submit", "Bestätigen"}.
-{"~s access rule configuration", "~s Zurtrittsregel Konfiguration"}.
-{"Node not found", "Knoten nicht gefunden"}.
-{"Add New", "Neuen hinzufügen"}.
-{"Change Password", "Passwort ändern"}.
-{"Connected Resources:", "Verbundene Resourcen"}.
-{"Password:", "Passwort:"}.
-{"None", "Keine"}.
-{"Node ", "Knoten "}.
-{"Restart", "Neustart"}.
-{"Stop", "Stop"}.
-{"Name", "Name"}.
-{"Storage Type", "Speichertyp"}.
-{"Size", "Größe"}.
-{"Memory", "Speicher"}.
-{"OK", "OK"}.
-{"Listened Ports at ", "Überwachte Ports "}.
-{"Port", "Port"}.
-{"Module", "Modul"}.
-{"Options", "Optionen"}.
-{"Update", "Aktualisieren"}.
-{"Delete", "Löschen"}.
-{"Add User", "Benutzer hinzufügen"}.
-{"Last Activity", "Letzte Aktion"}.
-{"Never", "Nie"}.
-{"Time", "Uhrzeit"}.
-{"From", "Von"}.
-{"To", "Zu"}.
-{"Packet", "Paket"}.
-{"Roster", "Liste"}.
-{"Nickname", "Spitzname"}.
-{"Subscription", "Subskription"}.
-{"Pending", "schwebend"}.
-{"Groups", "Gruppe"}.
-{"Remove", "Entfernen"}.
-{"User ", "Benutzer "}.
-{"Roster of ", "Liste von "}.
-{"Virtual Hosts", "Virtuelle Hosts"}.
-{"ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One", "ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One"}.
-{"Shared Roster", "Gemeinsame Kontaktliste"}.
-{"ejabberd virtual hosts", "ejabberd virtuelle Hosts"}.
-{"Period: ", "Zeitraum"}.
-{"Last month", "Letzter Monat"}.
-{"Last year", "Letztes Jahr"}.
-{"All activity", "Alle Aktivitäten"}.
-{"Show Ordinary Table", "Normale Tabelle anzeigen"}.
-{"Show Integral Table", "Vollständige Tabelle anzeigen"}.
-{"Host", "Host"}.
-{"Online", "Online"}.
-{"Validate", "Validieren"}.
-{"Modules at ", "Module auf "}.
-{"Start", "Anfang"}.
-{"Name:", "Name"}.
-{"Description:", "Beschreibung:"}.
-{"Members:", "Mitglieder:"}.
-{"Displayed Groups:", "Angezeigte Gruppen:"}.
-{"Group ", "Gruppe "}.
-{"ejabberd Web Interface", "ejabberd Web Interface"}.
-
-% ejabberd_c2s.erl
-{"Use of STARTTLS required", "Verwendung von STARTTLS erforderlich"}.
-{"Replaced by new connection", "Durch neue Verbindung ersetzt"}.
-
-% mod_vcard_odbc.erl
-{"Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin", "Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)", "Füllen Sie die Felder aus, um nach passenden Jabber benutzern zu suchen (beenden Sie ein Feld mit *, um auch nach Teilzeichenketten zu suchen)"}.
-{"Email", "E-Mail"}.
-{"Search Results for ", "Suchergebnisse für"}.
-{"Jabber ID", "Jabber ID"}.
-
-% mod_adhoc.erl
-{"Commands", "Befehle"}.
-{"Ping", "Ping"}.
-{"Pong", "Pong"}.
-
-% mod_announce.erl
-{"Really delete message of the day?", "Wirklich die Nachricht des Tages löschen ?"}.
-{"Subject", "Betreff"}.
-{"Message body", "Nachrichtentext"}.
-{"No body provided for announce message", "Keinen Text für die Ankündigung angegeben"}.
-{"Announcements", "Ankündigungen"}.
-{"Send announcement to all users", "Sende Ankündigung an alle Benutzer"}.
-{"Send announcement to all online users", "Sende Ankündigung an alle online Benutzer"}.
-{"Send announcement to all online users on all hosts", "Sende Ankündigung an alle online Benutzer auf allen Hosts"}.
-{"Set message of the day and send to online users", "Setze Nachricht des Tages und sende sie an alle online Benutzer"}.
-{"Update message of the day (don't send)", "Aktualisiere Nachricht des Tages (nicht senden)"}.
-{"Delete message of the day", "Lösche Nachricht des Tages"}.
-
-% mod_configure.erl
-{"Database", "Datenbank"}.
-{"Outgoing s2s Connections", "Ausgehende s2s Verbindungen"}.
-{"Import Users From jabberd 1.4 Spool Files", "Importiere Benutzer von jabberd 1.4 Spool Dateien"}.
-{"Database Tables Configuration at ", "Datenbank Tabellen Konfiguration bei "}.
-
-% web/ejabberd_web_admin.erl
-{"Administration", "Verwaltung"}.
-{"(Raw)", "(Roh)"}.
-{"Submitted", "Bestätigt"}.
-{"Bad format", "Ungültiges Format"}.
-{"Raw", "Roh"}.
-{"Users Last Activity", "Letzte Benutzeraktivität"}.
-{"Registered Users", "Registrierte Benutzer"}.
-{"Offline Messages", "Offline Nachrichten"}.
-{"Registered Users:", "Registrierte Benutzer:"}.
-{"Authenticated Users:", "Überprüfte Benutzer:"}.
-{"Online Users:", "Online Benutzer:"}.
-{"Outgoing s2s Connections:", "Ausgehende s2s Verbindungen:"}.
-{"Outgoing s2s Servers:", "Ausgehende s2s Server:"}.
-{"Offline Messages:", "Offline Nachrichten:"}.
-{"~s's Offline Messages Queue", "~s's Offline Nachrichten Warteschlange"}.
-{"Add Jabber ID", "Jabber ID hinzufügen"}.
-{"No Data", "Keine Daten"}.
-{"Listened Ports", "Überwachte Ports"}.
-{"RPC Call Error", "RPC Abruf-Fehler"}.
-{"Database Tables at ", "Datenbank Tabellen bei "}.
-{"Backup of ", "Sicherung von "}.
-{"Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.", "Beachten sie, daß diese Optionen nur die eingebaute Mnesia Datenbank sichert. Wenn sie das ODBC Modul verwenden, müssen sie die SQL Datenbank manuell sichern."}.
-{"Store binary backup:", "Speichere binäres Sicherung:"}.
-{"Restore binary backup immediately:", "Stelle binäre Sicherung sofort wiederher:"}.
-{"Restore binary backup after next ejabberd restart (requires less memory):", "Stelle binäre Sicherung beim nächsten ejabberd Neustart wiederher (benötigt weniger Speicher):"}.
-{"Store plain text backup:", "Speichere plaintext Sicherung:"}.
-{"Restore plain text backup immediately:", "Stelle plaintext Sicherung sofort wiederher:"}.
-{"Statistics of ~p", "Statistiken von ~p"}.
-{"Uptime:", "Betriebszeit:"}.
-{"CPU Time:", "CPU Zeit:"}.
-{"Transactions Commited:", "Vorgänge durchgeführt:"}.
-{"Transactions Aborted:", "Vorgänge abgebrochen:"}.
-{"Transactions Restarted:", "Vorgänge neu gestartet:"}.
-{"Transactions Logged:", "Vorgänge protokolliert:"}.
-{"Update ", "Aktualisierung"}.
-{"Update plan", "Aktualisierungsplan"}.
-{"Updated modules", "Aktualisierte Module"}.
-{"Update script", "Aktualisierungsscript"}.
-{"Low level update script", "Low level Aktualisierungsscript"}.
-{"Script check", "Script Überprüfung"}.
-{"Not Found", "Nicht gefunden"}.
-{"Shared Roster Groups", "Gruppen der gemeinsamen Kontaktliste"}.
-
-% mod_muc/mod_muc_log.erl
-{"Chatroom configuration modified", "Chatraum Konfiguration verändert"}.
-{"joins the room", "kommt in den Raum"}.
-{"leaves the room", "verlässt den Raum"}.
-{"has been kicked", "wurde gekickt"}.
-{"has been banned", "wurde gebannt"}.
-{"is now known as", "ist nun bekannt als"}.
-{"Monday", "Montag"}.
-{"Tuesday", "Dienstag"}.
-{"Wednesday", "Mittwoch"}.
-{"Thursday", "Donnerstag"}.
-{"Friday", "Freitag"}.
-{"Saturday", "Samstag"}.
-{"Sunday", "Sonntag"}.
-{"January", "Jänner"}.
-{"February", "Feber"}.
-{"March", "März"}.
-{"April", "April"}.
-{"May", "Mai"}.
-{"June", "Juni"}.
-{"July", "Juli"}.
-{"August", "August"}.
-{"September", "September"}.
-{"October", "Oktober"}.
-{"November", "November"}.
-{"December", "Dezember"}.
-{"Room Configuration", "Raum Konfiguration"}.
-
-% mod_muc/mod_muc_room.erl
-{"This room is not anonymous", "Dieser Raum ist nicht anonym"}.
-{"Make room persistent", "Raum persistent machen"}.
-{"Make room public searchable", "Raum öffentlich durchsuchbar machen"}.
-{"Make participants list public", "Teilnehmerliste öffentlich machen"}.
-{"Make room password protected", "Raum passwortgeschützt machen"}.
-{"Make room members-only", "Raum members-only machen"}.
-{"Make room moderated", "Raum modieriert machen"}.
-{"Default users as participants", "Standartbenutzer als Teilnehmer"}.
-{"Allow users to change subject", "Erlaube Benutzern Thema zu ändern"}.
-{"Allow users to send private messages", "Erlaube Benutzern private Nachrichten zu senden"}.
-{"Allow users to query other users", "Erlaube Benutzern andere Benutzer zu sehen(query)"}.
-{"Allow users to send invites", "Erlaube Benutzern Einladungen zu senden"}.
-{"Enable logging", "Log-Funktion aktivieren"}.
-{"Description", "Beschreibung"}.
-{"Number of occupants", "Anzahl der Teilnehmer"}.
-{"Present real JIDs to", "Echte Jabber IDs anzeigen für"}.
-{"moderators only", "nur Moderatoren"}.
-{"anyone", "jeden"}.
-
-% Local Variables:
-% mode: erlang
-% End:
diff --git a/ejabberd-1.1.2/src/msgs/es.msg b/ejabberd-1.1.2/src/msgs/es.msg
deleted file mode 100644
index 7dfe27b48..000000000
--- a/ejabberd-1.1.2/src/msgs/es.msg
+++ /dev/null
@@ -1,347 +0,0 @@
-% $Id$
-
-% Ejabberd - Spanish - badlop AT jabberes.org
-
-% jlib.hrl
-{"No resource provided", "No se ha proporcionado recurso"}.
-
-% mod_configure.erl
-{"Choose storage type of tables", "Selecciona tipo de almacenamiento de las tablas"}.
-{"RAM copy", "Copia en RAM"}.
-{"RAM and disc copy", "Copia en RAM y disco"}.
-{"Disc only copy", "Copia en disco solamente"}.
-{"Remote copy", "Copia remota"}.
-{"Stop Modules at ", "Detener módulos en "}.
-{"Choose modules to stop", "Selecciona módulos a detener"}.
-{"Start Modules at ", "Iniciar módulos en "}.
-{"Enter list of {Module, [Options]}", "Introduce lista de {módulo, [opciones]}"}.
-{"List of modules to start", "Lista de módulos a iniciar"}.
-{"Backup to File at ", "Guardar copia de seguridad en fichero en "}.
-{"Enter path to backup file", "Introduce ruta al fichero de copia de seguridad"}.
-{"Path to File", "Ruta al fichero"}.
-{"Restore Backup from File at ", "Restaura copia de seguridad desde el fichero en "}.
-{"Dump Backup to Text File at ", "Exporta copia de seguridad a fichero de texto en "}.
-{"Enter path to text file", "Introduce ruta al fichero de texto"}.
-{"Import User from File at ", "Importa usuario desde fichero en "}.
-{"Enter path to jabberd1.4 spool file", "Introduce ruta al fichero jabberd1.4 spool"}.
-{"Import Users from Dir at ", "Importar usuarios desde el directorio en "}.
-{"Enter path to jabberd1.4 spool dir", "Introduce la ruta al directorio de jabberd1.4 spools"}.
-{"Path to Dir", "Ruta al directorio"}.
-{"Hostname Configuration", "Configuración del nombre de máquina"}.
-{"Choose host name", "Indica el nombre de la máquina"}.
-{"Host name", "Nombre de la máquina"}.
-{"Access Control List Configuration", "Configuración de la Lista de Control de Acceso"}.
-{"Access control lists", "Listas de Control de Acceso"}.
-{"Access Configuration", "Configuración de accesos"}.
-{"Access rules", "Reglas de acceso"}.
-{"Remove Users", "Eliminar usuarios"}.
-{"Choose users to remove", "Selecciona usuarios a eliminar"}.
-{"Administration of ", "Administración de "}.
-{"Action on user", "Acción en el usuario"}.
-{"Edit Properties", "Editar propiedades"}.
-{"Remove User", "Eliminar usuario"}.
-{"Database", "Base de datos"}.
-{"Outgoing s2s Connections", "Conexiones S2S salientes"}.
-{"Import Users From jabberd 1.4 Spool Files", "Importar usuarios de ficheros spool de jabberd-1.4"}.
-{"Database Tables Configuration at ", "Configuración de tablas de la base de datos en "}.
-
-% mod_disco.erl
-{"Configuration", "Configuración"}.
-{"Online Users", "Usuarios conectados"}.
-{"All Users", "Todos los usuarios"}.
-{"To ~s", "A ~s"}.
-{"From ~s", "De ~s"}.
-{"Running Nodes", "Nodos funcionando"}.
-{"Stopped Nodes", "Nodos detenidos"}.
-{"Host Name", "Nombre de la máquina"}.
-{"Access Control Lists", "Listas de Control de Acceso"}.
-{"Access Rules", "Reglas de Acceso"}.
-{"Remove Users", "Eliminar usuarios"}.
-{"Modules", "Módulos"}.
-{"Start Modules", "Iniciar módulos"}.
-{"Stop Modules", "Detener módulos"}.
-{"Backup", "Guardar copia de seguridad"}.
-{"Restore", "Restaurar"}.
-{"Dump to Text File", "Exportar a fichero de texto"}.
-{"Import File", "Importar fichero"}.
-{"Import Directory", "Importar directorio"}.
-
-% mod_register.erl
-{"Choose a username and password to register with this server", "Escoge un nombre de usuario y contraseña para registrarte en este servidor"}.
-
-% mod_vcard.erl
-{"Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin", "Servidor Jabber en Erlang\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)", "Rellena el formulario para buscar usuarios Jabber. Añade * al final de un campo para buscar subcadenas."}.
-{"ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin", "Módulo vCard para ejabberd\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"You need an x:data capable client to search", "Necesitas un cliente con soporte de x:data para poder buscar"}.
-{"Search users in ", "Buscar usuarios en "}.
-
-% mod_vcard_odbc.erl
-{"Email", "correo"}.
-{"Search Results for ", "Buscar resultados por "}.
-{"Jabber ID", "Jabber ID"}.
-
-{"User", "Usuario"}.
-{"Full Name", "Nombre completo"}.
-{"Name", "Nombre"}.
-{"Middle Name", "Segundo nombre"}.
-{"Family Name", "Apellido"}.
-{"Nickname", "Apodo"}.
-{"Birthday", "Cumpleaños"}.
-{"Country", "País"}.
-{"City", "Ciudad"}.
-{"Organization Name", "Nombre de la organización"}.
-{"Organization Unit", "Unidad de la organización"}.
-
-% mod_pubsub/mod_pubsub.erl
-{"ejabberd pub/sub module\nCopyright (c) 2003-2006 Alexey Shchepin", "Módulo Pub/Sub para ejabberd\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"Node Creator", "Creador del nodo"}.
-{[], " "}.
-{"Deliver payloads with event notifications", "Enviar payloads junto con las notificaciones de eventos"}.
-{"Notify subscribers when the node configuration changes", "Notificar subscriptores cuando cambia la configuración del nodo"}.
-{"Notify subscribers when the node is deleted", "Notificar subscriptores cuando el nodo se borra"}.
-{"Notify subscribers when items are removed from the node", "Notificar subscriptores cuando los elementos se borran del nodo"}.
-{"Persist items to storage", "Persistir elementos al almacenar"}.
-{"Max # of items to persist", "Máximo # de elementos que persisten"}.
-{"Whether to allow subscriptions", "Permitir subscripciones"}.
-{"Specify the subscriber model", "Especificar el modelo del subscriptor"}.
-{"Specify the publisher model", "Especificar el modelo del publicante"}.
-{"Max payload size in bytes", "Máximo tamaño del payload en bytes"}.
-{"Send items to new subscribers", "Enviar elementos a los nuevos subscriptores"}.
-{"Only deliver notifications to available users", "Solo enviar notificaciones a los usuarios disponibles"}.
-{"Specify the current subscription approver", "Especificar el aprobador de subscripción actual"}.
-
-% mod_muc/mod_muc.erl
-{"You need an x:data capable client to register nickname", "Necesitas un cliente con soporte de x:data para poder registrar el apodo"}.
-{"Nickname Registration at ", "Registro del apodo en "}.
-{"Enter nickname you want to register", "Introduce el apodo que quieras registrar"}.
-{"Only service administrators are allowed to send service messages", "Solo los administradores del servicio tienen permiso para enviar mensajes de servicio"}.
-{"Conference room does not exist", "La sala de conferencias no existe"}.
-{"Access denied by service policy", "Acceso denegado por la política del servicio"}.
-{"You must fill in field \"Nickname\" in the form", "Debes rellenar el campo \"Apodo\" en el formulario"}.
-{"Specified nickname is already registered", "El apodo especificado ya está registrado, tendrás que buscar otro"}.
-{"Room creation is denied by service policy", "Se te ha denegado crear la sala por política del servicio"}.
-{"ejabberd MUC module\nCopyright (c) 2003-2006 Alexey Shchepin", "Módulo de MUC para ejabbed\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-
-% mod_muc/mod_muc_room.erl
-{" has set the subject to: ", " ha puesto el asunto: "}.
-{"You need an x:data capable client to configure room", "Necesitas un cliente con soporte de x:data para configurar la sala"}.
-{"Configuration for ", "Configuración para "}.
-{"Room title", "Título de la sala"}.
-{"Allow users to change subject", "Permitir a los usuarios cambiar el asunto"}.
-{"Allow users to query other users", "Permitir a los usuarios consultar a otros usuarios"}.
-{"Allow users to send private messages", "Permitir a los usuarios enviar mensajes privados"}.
-{"Make room public searchable", "Sala públicamente visible"}.
-{"Make participants list public", "La lista de participantes es pública"}.
-{"Make room persistent", "Sala permanente"}.
-{"Make room moderated", "Sala moderada"}.
-{"Default users as participants", "Los usuarios son participantes por defecto"}.
-{"Make room members-only", "Sala sólo para miembros"}.
-{"Allow users to send invites", "Permitir a los usuarios enviar invitaciones"}.
-{"Make room password protected", "Proteger la sala con contraseña"}.
-{"Password", "Contraseña"}.
-{"This room is not anonymous", "Sala no anónima"}.
-{"Enable logging", "Guardar históricos"}.
-{"Only moderators and participants are allowed to change subject in this room", "Solo los moderadores y participantes pueden cambiar el asunto de esta sala"}.
-{"Only moderators are allowed to change subject in this room", "Solo los moderadores pueden cambiar el asunto de esta sala"}.
-{"Visitors are not allowed to send messages to all occupants", "Los visitantes no pueden enviar mensajes a todos los ocupantes"}.
-{"Only occupants are allowed to send messages to the conference", "Solo los ocupantes pueden enviar mensajes a la sala"}.
-{"It is not allowed to send normal messages to the conference", "Impedir el envio de mensajes normales a la sala"}.
-{"It is not allowed to send private messages to the conference", "Impedir el envio de mensajes privados a la sala"}.
-{"Improper message type", "Tipo de mensaje incorrecto"}.
-{"Nickname is already in use by another occupant", "El apodo ya está siendo usado por otro ocupante"}.
-{"Nickname is registered by another person", "El apodo ya está registrado por otra persona"}.
-{"It is not allowed to send private messages of type \"groupchat\"", "No está permitido enviar mensajes privados del tipo \"groupchat\""}.
-{"Recipient is not in the conference room", "El receptor no está en la sala de conferencia"}.
-{"Only occupants are allowed to send queries to the conference", "Solo los ocupantes pueden enviar solicitudes a la sala"}.
-{"Queries to the conference members are not allowed in this room", "En esta sala no se permiten solicitudes a los miembros de la sala"}.
-{"You have been banned from this room", "Has sido bloqueado en esta sala"}.
-{"Membership required to enter this room", "Necesitas ser miembro de esta sala para poder entrar"}.
-{"Password required to enter this room", "Se necesita contraseña para entrar en esta sala"}.
-{"Incorrect password", "Contraseña incorrecta"}.
-{"Administrator privileges required", "Se necesita privilegios de administrador"}.
-{"Moderator privileges required", "Se necesita privilegios de moderador"}.
-{"JID ~s is invalid", "El JID ~s no es válido"}.
-{"Nickname ~s does not exist in the room", "El apodo ~s no existe en la sala"}.
-{"Invalid affiliation: ~s", "Afiliación no válida: ~s"}.
-{"Invalid role: ~s", "Rol no válido: ~s"}.
-{"Owner privileges required", "Se requieren privilegios de propietario de la sala"}.
-{"private, ", "privado"}.
-{"Description", "Descripción"}.
-{"Number of occupants", "Número de ocupantes"}.
-{"Present real JIDs to", "Los JID reales pueden verlos"}.
-{"moderators only", "solo moderadores"}.
-{"anyone", "cualquiera"}.
-
-% mod_muc/mod_muc_log.erl
-{"Chatroom configuration modified", "Configuración de la sala modificada"}.
-{"joins the room", "entra en la sala"}.
-{"leaves the room", "sale de la sala"}.
-{"has been kicked", "ha sido expulsado"}.
-{"has been banned", "ha sido bloqueado"}.
-{"is now known as", "se cambia el nombre a"}.
-{"Monday", "lunes"}.
-{"Tuesday", "martes"}.
-{"Wednesday", "miércoles"}.
-{"Thursday", "jueves"}.
-{"Friday", "viernes"}.
-{"Saturday", "sábado"}.
-{"Sunday", "domingo"}.
-{"January", "enero"}.
-{"February", "febrero"}.
-{"March", "marzo"}.
-{"April", "abril"}.
-{"May", "mayo"}.
-{"June", "junio"}.
-{"July", "julio"}.
-{"August", "agosto"}.
-{"September", "septiembre"}.
-{"October", "octubre"}.
-{"November", "noviembre"}.
-{"December", "diciembre"}.
-{"Room Configuration", "Configuración de la sala"}.
-% mod_irc/mod_irc.erl
-{"You need an x:data capable client to configure mod_irc settings", "Necesitas un cliente con soporte de x:data para configurar las opciones de mod_irc"}.
-{"Registration in mod_irc for ", "Registro en mod_irc para"}.
-{"Enter username and encodings you wish to use for connecting to IRC servers", "Introduce el nombre de usuario y codificaciones de carácteres que quieras usar al conectar en los servidores de IRC"}.
-{"IRC Username", "Nombre de usuario en IRC"}.
-{"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.", "Si quieres especificar codificaciones de carácteres distintos para cada servidor IRC rellena esta lista con valores en el formato '{\"servidor irc\", \"codificación\"}'. Este servicio usa por defecto la codificación \"~s\"."}.
-{"Encodings", "Codificaciones"}.
-{"ejabberd IRC module\nCopyright (c) 2003-2006 Alexey Shchepin", "Módulo de IRC para ejabberd\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].", "Ejemplo: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}]."}.
-
-% web/ejabberd_web_admin.erl
-{"Users", "Usuarios"}.
-{"Nodes", "Nodos"}.
-{"Statistics", "Estadísticas"}.
-{"Delete Selected", "Eliminar los seleccionados"}.
-{"Submit", "Enviar"}.
-{"~s access rule configuration", "Configuración de las Regla de Acceso ~s"}.
-{"Node not found", "Nodo no encontrado"}.
-{"Add New", "Añadir nuevo"}.
-{"Change Password", "Cambiar contraseña"}.
-{"Connected Resources:", "Recursos conectados:"}.
-{"Password:", "Contraseña:"}.
-{"None", "Ninguno"}.
-{"Node ", "Nodo "}.
-{"Restart", "Reiniciar"}.
-{"Stop", "Detener"}.
-{"Name", "Nombre"}.
-{"Storage Type", "Tipo de almacenamiento"}.
-{"Size", "Tamaño"}.
-{"Memory", "Memoria"}.
-{"Backup Management", "Gestión de copia de seguridad"}.
-{"OK", "Aceptar"}.
-{"Listened Ports at ", "Puertos de escucha en "}.
-{"Port", "Puerto"}.
-{"Module", "Módulo"}.
-{"Options", "Opciones"}.
-{"Update", "Actualizar"}.
-{"Delete", "Eliminar"}.
-{"Add User", "Añadir usuario"}.
-{"Last Activity", "Última actividad"}.
-{"Never", "Nunca"}.
-{"Time", "Fecha"}.
-{"From", "De"}.
-{"To", "Para"}.
-{"Packet", "Paquete"}.
-{"Roster", "Lista de contactos"}.
-{"Nickname", "Apodo"}.
-{"Subscription", "Subscripción"}.
-{"Pending", "Pendiente"}.
-{"Groups", "Grupos"}.
-{"Remove", "Borrar"}.
-{"User ", "Usuario "}.
-{"Roster of ", "Lista de contactos de "}.
-{"ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One", "ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One"}.
-{"Shared Roster", "Grupos Compartidos"}.
-{"Online", "Conectado"}.
-{"Validate", "Validar"}.
-{"Name:", "Nombre:"}.
-{"Description:", "Descripción:"}.
-{"Members:", "Miembros:"}.
-{"Displayed Groups:", "Mostrar grupos:"}.
-{"Group ", "Grupo "}.
-{"Period: ", "Periodo: "}.
-{"Last month", "Último mes"}.
-{"Last year", "Último año"}.
-{"All activity", "Toda la actividad"}.
-{"Show Ordinary Table", "Mostrar Tabla Ordinaria"}.
-{"Show Integral Table", "Mostrar Tabla Integral"}.
-{"Modules at ", "Módulos en "}.
-{"Start", "Iniciar"}.
-{"Virtual Hosts", "Hosts Virtuales"}.
-{"ejabberd virtual hosts", "Hosts virtuales de ejabberd"}.
-{"Host", "Host"}.
-{"ejabberd Web Interface", "Interfaz Web de ejabberd"}.
-{"Restore plain text backup immediately:", "Restaurar copias de seguridad de texto plano inmediatamente:"}.
-{"Statistics of ~p", "Estadísticas de ~p"}.
-{"Uptime:", "Tiempo desde el inicio:"}.
-{"CPU Time:", "Tiempo consumido de CPU:"}.
-{"Transactions Commited:", "Transacciones finalizadas:"}.
-{"Transactions Aborted:", "Transacciones abortadas:"}.
-{"Transactions Restarted:", "Transacciones reiniciadas:"}.
-{"Transactions Logged:", "Transacciones registradas:"}.
-{"Update ", "Actualizar"}.
-{"Update plan", "Plan de actualización"}.
-{"Updated modules", "Módulos actualizados"}.
-{"Update script", "Script de actualización"}.
-{"Low level update script", "Script de actualización a bajo nivel"}.
-{"Script check", "Comprobación de script"}.
-{"Not Found", "No encontrado"}.
-{"Shared Roster Groups", "Grupos Compartidos"}.
-{"Administration", "Administración"}.
-{"(Raw)", "(Crudo)"}.
-{"Submitted", "Enviado"}.
-{"Bad format", "Mal formato"}.
-{"Raw", "Crudo"}.
-{"Users Last Activity", "Última actividad de los usuarios"}.
-{"Registered Users", "Usuarios registrados"}.
-{"Offline Messages", "Mensajes diferidos"}.
-{"Registered Users:", "Usuarios registrados:"}.
-{"Authenticated Users:", "Usuarios autenticados:"}.
-{"Online Users:", "Usuarios conectados:"}.
-{"Outgoing s2s Connections:", "Conexiones S2S salientes:"}.
-{"Outgoing s2s Servers:", "Servidores S2S salientes:"}.
-{"Offline Messages:", "Mensajes diferidos:"}.
-{"~s's Offline Messages Queue", "Cola de mensajes diferidos de ~s"}.
-{"Add Jabber ID", "Añadir Jabber ID"}.
-{"No Data", "Sin datos"}.
-{"Listened Ports", "Puertos de escucha"}.
-{"RPC Call Error", "Error en la llamada RPC"}.
-{"Database Tables at ", "Tablas de la base de datos en "}.
-{"Backup of ", "Copia de seguridad de "}.
-{"Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.", "Ten en cuenta que estas opciones solo harán copia de seguridad de la base de datos Mnesia embebida. Si estás usando ODBC tendrás que hacer también copia de seguridad de tu base de datos SQL."}.
-{"Store binary backup:", "Guardar copia de seguridad binaria:"}.
-{"Restore binary backup immediately:", "Restaurar inmediatamente copia de seguridad binaria:"}.
-{"Restore binary backup after next ejabberd restart (requires less memory):", "Restaurar copia de seguridad binaria en el siguiente reinicio de ejabberd (requiere menos memoria que si instantánea):"}.
-{"Store plain text backup:", "Guardar copia de seguridad en texto plano:"}.
-
-% ejabberd_c2s.erl
-{"Use of STARTTLS required", "Es obligatorio usar STARTTLS"}.
-{"Replaced by new connection", "Reemplazado por una nueva conexión"}.
-
-% mod_vcard_ldap.erl
-{"Fill in fields to search for any matching Jabber User", "Rellena campos para buscar usuarios Jabber que concuerden"}.
-
-% mod_adhoc.erl
-{"Commands", "Comandos"}.
-{"Ping", "Ping"}.
-{"Pong", "Pong"}.
-
-% mod_announce.erl
-{"Really delete message of the day?", "¿Está seguro de quere borrar el mensaje del dia?"}.
-{"Subject", "Asunto"}.
-{"Message body", "Cuerpo del mensaje"}.
-{"No body provided for announce message", "No se ha proporcionado cuerpo de mensaje para el anuncio"}.
-{"Announcements", "Anuncios"}.
-{"Send announcement to all users", "Enviar anuncio a todos los usuarios"}.
-{"Send announcement to all online users", "Enviar anuncio a todos los usuarios conectados"}.
-{"Send announcement to all online users on all hosts", "Enviar anuncio a todos los usuarios conectados en todos los dominios"}.
-{"Set message of the day and send to online users", "Poner mensaje del dia y enviar a todos los usuarios conectados"}.
-{"Update message of the day (don't send)", "Actualizar mensaje del dia, pero no enviarlo"}.
-{"Delete message of the day", "Borrar mensaje del dia"}.
-
-% Local Variables:
-% mode: erlang
-% End:
diff --git a/ejabberd-1.1.2/src/msgs/fr.msg b/ejabberd-1.1.2/src/msgs/fr.msg
deleted file mode 100644
index f84ab1576..000000000
--- a/ejabberd-1.1.2/src/msgs/fr.msg
+++ /dev/null
@@ -1,347 +0,0 @@
-% $Id$
-
-% jlib.hrl
-{"No resource provided", "Aucune ressource fournie"}.
-
-% mod_configure.erl
-{"Choose storage type of tables", "Choisissez un type de stockage pour les tables"}.
-{"RAM copy", "Copie en mémoire vive (RAM)"}.
-{"RAM and disc copy", "Copie en mémoire vive (RAM) et sur disque"}.
-{"Disc only copy", "Copie sur disque uniquement"}.
-{"Remote copy", "Copie distante"}.
-{"Stop Modules at ", "Arrêter les modules sur "}.
-{"Choose modules to stop", "Sélectionnez les modules à�arrêter"}.
-{"Start Modules at ", "Démarrer les modules sur "}.
-{"Enter list of {Module, [Options]}", "Entrez une liste de {Module, [Options]}"}.
-{"List of modules to start", "Liste des modules à�démarrer"}.
-{"Backup to File at ", "Sauvegarde sur fichier sur "}.
-{"Enter path to backup file", "Entrez le chemin vers le fichier de sauvegarde"}.
-{"Path to File", "Chemin vers le fichier"}.
-{"Restore Backup from File at ", "Restaurer la sauvegarde depuis le fichier sur "}.
-{"Dump Backup to Text File at ", "Enregistrer la sauvegarde dans un fichier texte sur "}.
-{"Enter path to text file", "Entrez le chemin vers le fichier texte"}.
-{"Import User from File at ", "Importer un utilisateur depuis le fichier sur "}.
-{"Enter path to jabberd1.4 spool file", "Entrez le chemin vers le fichier spool jabberd1.4"}.
-{"Import Users from Dir at ", "Importer des utilisateurs depuis le répertoire sur "}.
-{"Enter path to jabberd1.4 spool dir", "Entrez le chemin vers le répertoire de spool jabberd1.4"}.
-{"Path to Dir", "Chemin vers le répertoire"}.
-{"Hostname Configuration", "Configuration du nom d'hôte"}.
-{"Choose host name", "Choisissez le nom d'hôte"}.
-{"Host name", "Nom d'hôte"}.
-{"Access Control List Configuration", "Configuration des droits (ACL)"}.
-{"Access control lists", "Droits (ACL)"}.
-{"Access Configuration", "Configuration d'accès"}.
-{"Access rules", "Règles d'accès"}.
-{"Remove Users", "Supprimer des utilisateurs"}.
-{"Choose users to remove", "Sélectionner les utilisateurs à supprimer"}.
-{"Administration of ", "Administration de "}.
-{"Action on user", "Action sur l'utilisateur"}.
-{"Edit Properties", "Modifier les propriétés"}.
-{"Remove User", "Supprimer l'utilisateur"}.
-{"Database", "Base de données"}.
-{"Outgoing s2s Connections", "Connexions s2s sortantes"}.
-{"Import Users From jabberd 1.4 Spool Files", "Importer des utilisateurs depuis un fichier spool Jabberd 1.4"}.
-{"Database Tables Configuration at ", "Configuration des tables de base de données sur "}.
-
-% src/ejabberd_c2s.erl
-{"Use of STARTTLS required", "L'utilisation de STARTTLS est impérative"}.
-{"Replaced by new connection", "Remplacé par une nouvelle connexion"}.
-
-% mod_disco.erl
-{"Configuration", "Configuration"}.
-{"Online Users", "Utilisateurs en ligne"}.
-{"All Users", "Tous les utilisateurs"}.
-{"To ~s", "A ~s"}.
-{"From ~s", "De ~s"}.
-{"Running Nodes", "Noeuds actifs"}.
-{"Stopped Nodes", "Noeuds arrêtés"}.
-{"Host Name", "Nom du serveur"}.
-{"Access Control Lists", "Droits (ACL)"}.
-{"Access Rules", "Règles d'accès"}.
-{"Remove Users", "Supprimer des utilisateurs"}.
-{"Modules", "Modules"}.
-{"Start Modules", "Modules de démarrage"}.
-{"Stop Modules", "Modules d'arrêt"}.
-{"Backup Management", "Gestion des sauvegardes"}.
-{"Backup", "Sauvegarde"}.
-{"Restore", "Restauration"}.
-{"Dump to Text File", "Sauvegarder dans un fichier texte"}.
-{"Import File", "Importer un fichier"}.
-{"Import Directory", "Importer une répertoire"}.
-
-% mod_register.erl
-{"Choose a username and password to register with this server", "Choisissez un nom d'utilisateur et un mot de passe pour s'enregistrer sur ce serveur"}.
-
-% src/mod_vcard_ldap.erl
-{"Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin", "Serveur Jabber Erlang\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin", "Module vCard ejabberd\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-{"Email", "Email"}.
-{"Search Results for ", "Résultats de recherche pour "}.
-{"Jabber ID", "Jabber ID"}.
-
-% mod_vcard.erl
-{"You need an x:data capable client to search",
- "Vous avez besoin d'un client supportant x:data pour faire une recherche"}.
-{"Search users in ", "Rechercher des utilisateurs "}.
-
-{"Fill in fields to search for any matching Jabber User",
- "Remplissez les champs pour rechercher un utilisateur Jabber"}.
-{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)", "Remplissez le formulaire pour recherche un utilisateur Jabber (Ajouter * à la fin du champ pour chercher n'importe quelle fin de chaîne"}.
-
-{"User", "Utilisateur"}.
-{"Full Name", "Nom complet"}.
-{"Name", "Nom"}.
-{"Middle Name", "Autre nom"}.
-{"Family Name", "Nom de famille"}.
-{"Nickname", "Surnom"}.
-{"Birthday", "Date d'anniversaire"}.
-{"Country", "Pays"}.
-{"City", "Ville"}.
-{"Organization Name", "Nom de l'organisation"}.
-{"Organization Unit", "Unité de l'organisation"}.
-
-% mod_adhoc.erl
-{"Commands", "Commandes"}.
-{"Ping", "Ping"}.
-{"Pong", "Pong"}.
-
-% mod_announce.erl
-{"Really delete message of the day?", "Confirmer la suppression du message du jour ?"}.
-{"Subject", "Sujet"}.
-{"Message body", "Corps du message"}.
-{"No body provided for announce message", "Pas de corps de message pour l'annonce"}.
-{"Announcements", "Annonces"}.
-{"Send announcement to all users", "Envoyer l'annonce à tous les utilisateurs"}.
-{"Send announcement to all online users", "Envoyer l'annonce à tous les utilisateurs en ligne"}.
-{"Send announcement to all online users on all hosts", "Envoyer l'annonce à tous les utilisateurs en ligne sur tous les serveurs"}.
-{"Set message of the day and send to online users", "Définir le message du jour et l'envoyer aux utilisateurs en ligne"}.
-{"Update message of the day (don't send)", "Mise à jour du message du jour (pas d'envoi)"}.
-{"Delete message of the day", "Supprimer le message du jour"}.
-
-% mod_pubsub/mod_pubsub.erl
-{"ejabberd pub/sub module\nCopyright (c) 2003-2006 Alexey Shchepin", "Module pub/sub ejabberd \nCopyright (c) 2003-2006 Alexey Shchepin"}.
-{[], ""}.
-{"Node Creator", "Créateur du noeud"}.
-{"Deliver payloads with event notifications", "Inclure le contenu du message avec la notification"}.
-{"Notify subscribers when the node configuration changes", "Avertir les abonnés lorsque la configuration du noeud change"}.
-{"Notify subscribers when the node is deleted", "Avertir les abonnés lorsque le noeud est supprimé"}.
-{"Notify subscribers when items are removed from the node", "Avertir les abonnés lorsque des éléments sont supprimés sur le noeud"}.
-{"Persist items to storage", "Stockage persistant des éléments"}.
-{"Max # of items to persist", "Nombre maximum d'éléments à stocker"}.
-{"Whether to allow subscriptions", "Autoriser l'abonnement ?"}.
-{"Specify the subscriber model", "Définir le modèle d'abonnement"}.
-{"Specify the publisher model", "Définir le modèle de publication"}.
-{"Max payload size in bytes", "Taille maximum pour le contenu du message en octet"}.
-{"Send items to new subscribers", "Envoyer les anciens éléments aux nouveaux abonnés"}.
-{"Only deliver notifications to available users", "Envoyer les notifications uniquement aux utilisateurs disponibles"}.
-{"Specify the current subscription approver", "Définir l'utilisateur qui valide les abonnements"}.
-
-% mod_muc/mod_muc_log.erl
-{"Chatroom configuration modified", "Configuration du salon modifiée"}.
-{"joins the room", "rejoint le salon"}.
-{"leaves the room", "quitte le salon"}.
-{"has been kicked", "a été expulsé"}.
-{"has been banned", "a été banni"}.
-{"is now known as", "est maintenant connu comme"}.
-{"Monday", "Lundi"}.
-{"Tuesday", "Mardi"}.
-{"Wednesday", "Mercredi"}.
-{"Thursday", "Jeudi"}.
-{"Friday", "Vendredi"}.
-{"Saturday", "Samedi"}.
-{"Sunday", "Dimanche"}.
-{"January", "Janvier"}.
-{"February", "Février"}.
-{"March", "Mars"}.
-{"April", "Avril"}.
-{"May", "Mai"}.
-{"June", "Juin"}.
-{"July", "Juillet"}.
-{"August", "Août"}.
-{"September", "Septembre"}.
-{"October", "Octobre"}.
-{"November", "Novembre"}.
-{"December", "Décembre"}.
-{"Room Configuration", "Configuration du salon"}.
-
-% mod_muc/mod_muc.erl
-{"You need an x:data capable client to register nickname", "Vous avez besoin d'un client supportant x:data pour enregistrer un pseudo"}.
-{"Nickname Registration at ", "Enregistrement d'un pseudo sur "}.
-{"Enter nickname you want to register", "Entrez le pseudo que vous souhaitez enregistrer"}.
-{"ejabberd MUC module\nCopyright (c) 2003-2006 Alexey Shchepin", "Module MUC ejabberd\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-{"Only service administrators are allowed to send service messages", "Seuls les administrateurs du service sont autoriser à envoyer des messages de service"}.
-{"Room creation is denied by service policy", "La création de salons est interdite par le service"}.
-{"Conference room does not exist", "La salle de conférence n'existe pas"}.
-{"Access denied by service policy", "L'accès au service est refusé"}.
-{"Specified nickname is already registered", "Le pseudo demandé est déjà enregistré"}.
-{"You must fill in field \"Nickname\" in the form", "Vous devez préciser le champ \"pseudo\" dans le formulaire"}.
-
-% mod_muc/mod_muc_room.erl
-{" has set the subject to: ", " a changé le sujet pour: "}.
-{"You need an x:data capable client to configure room", "Vous avez besoin d'un client supportant x:data pour configurer le salon"}.
-{"Configuration for ", "Configuration pour "}.
-{"Room title", "Titre du salon"}.
-{"Password", "Mot de passe"}.
-{"Only moderators and participants are allowed to change subject in this room", "Seuls les modérateurs et les participants peuvent changer le sujet dans ce salon"}.
-{"Only moderators are allowed to change subject in this room", "Seuls les modérateurs peuvent changer le sujet dans ce salon"}.
-{"Visitors are not allowed to send messages to all occupants", "Les visiteurs ne sont pas autorisés à envoyer des messages à tout les occupants"}.
-{"Only occupants are allowed to send messages to the conference", "Seuls les occupants peuvent envoyer des messages à la conférence"}.
-{"It is not allowed to send normal messages to the conference", "Il n'est pas permis d'envoyer des messages \"normaux\" à la conférence"}.
-{"It is not allowed to send private messages to the conference", "Il n'est pas permis d'envoyer des messages \"normaux\" à la conférence"}.
-{"Improper message type", "Mauvais type de message"}.
-{"Nickname is already in use by another occupant", "Le pseudo est déjà utilisé par un autre occupant"}.
-{"Nickname is registered by another person", "Le pseudo est enregistré par une autre personne"}.
-{"It is not allowed to send private messages of type \"groupchat\"", "Il n'est pas permis d'envoyer des messages privés de type \"groupchat\""}.
-{"Recipient is not in the conference room", "Le destinataire n'est pas dans la conférence"}.
-{"Only occupants are allowed to send queries to the conference", "Seuls les occupants sont autorisés à envoyer des requêtes à la conférence"}.
-{"Queries to the conference members are not allowed in this room", "Les requêtes sur les membres de la conférence ne sont pas autorisé dans ce salon"}.
-{"You have been banned from this room", "Vous avez été exclus de ce salon"}.
-{"Membership required to enter this room", "Vous devez être membre pour accèder à ce salon"}.
-{"Password required to enter this room", "Un mot de passe est nécessaire pour accèder à ce salon"}.
-{"Incorrect password", "Mot de passe incorrect"}.
-{"Administrator privileges required", "Les droits d'administrateur sont nécessaires"}.
-{"Moderator privileges required", "Les droits de modérateur sont nécessaires"}.
-{"JID ~s is invalid", "Le JID ~s n'est pas valide"}.
-{"Nickname ~s does not exist in the room", "Le pseudo ~s n'existe pas dans ce salon"}.
-{"Invalid affiliation: ~s", "Affiliation invalide: ~s"}.
-{"Invalid role: ~s", "Role invalide: ~s"}.
-{"Owner privileges required", "Les droits de propriétaire sont nécessaires"}.
-{"private, ", "privé"}.
-{"This room is not anonymous", "Ce salon n'est pas anonyme"}.
-{"Make room persistent", "Rendre le salon persistant"}.
-{"Make room public searchable", "Rendre le salon public"}.
-{"Make participants list public", "Rendre la liste des participants publique"}.
-{"Make room password protected", "Protéger le salon par mot de passe"}.
-{"Make room members-only", "Réserver le salon aux membres uniquement"}.
-{"Make room moderated", "Rendre le salon modéré"}.
-{"Default users as participants", "Les utilisateurs sont par défaut participant"}.
-{"Allow users to change subject", "Autoriser les utilisateurs à changer le sujet"}.
-{"Allow users to send private messages", "Autoriser les utilisateurs à envoyer des messages privés"}.
-{"Allow users to query other users", "Permettre aux utilisateurs d'envoyer des requêtes aux autres utilisateurs"}.
-{"Allow users to send invites", "Permettre aux utilisateurs d'envoyer des invitations"}.
-{"Enable logging", "Activer l'archivage"}.
-{"Description", "Description"}.
-{"Number of occupants", "Nombre d'occupants"}.
-{"Present real JIDs to", "Rendre le JID réel visible pour"}.
-{"moderators only", "modérateurs seulement"}.
-{"anyone", "tout le monde"}.
-
-% mod_irc/mod_irc.erl
-{"ejabberd IRC module\nCopyright (c) 2003-2006 Alexey Shchepin", "Module IRC ejabberd\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-{"You need an x:data capable client to configure mod_irc settings", "Vous avez besoin d'un client supportant x:data pour configurer le module IRC"}.
-{"Registration in mod_irc for ", "Enregistrement du mod_irc pour "}.
-{"Enter username and encodings you wish to use for connecting to IRC servers", "Entrez le nom d'utilisateur et les encodages que vous souhaitez utiliser pour vous connecter aux serveurs IRC"}.
-{"IRC Username", "Nom d'utilisateur IRC"}.
-{"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.", "Si vous voulez préciser différents encodages pour les serveurs IRC, remplissez cette liste avec des valeurs dans le format '{\"serveur irc\", \"encodage\"}'. Par défaut ce service utilise l'encodage \"~s\"."}.
-{"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].", "Exemple: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}]."}.
-{"Encodings", "Encodages"}.
-
-% web/ejabberd_web_admin.erl
-{"Administration", "Administration"}.
-{"Users", "Utilisateurs"}.
-{"Nodes", "Noeuds"}.
-{"Shared Roster", "Liste de contacts partagée"}.
-{"Statistics", "Statistiques"}.
-{"ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One", "ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One"}.
-{"(Raw)", "(Brut)"}.
-{"Submitted", "Soumis"}.
-{"Bad format", "Mauvais format"}.
-{"Raw", "Brut"}.
-{"Delete Selected", "Suppression des éléments sélectionnés"}.
-{"Submit", "Soumettre"}.
-{"~s access rule configuration", "Configuration des règles d'accès ~s"}.
-{"Node not found", "Noeud non trouvé"}.
-{"Add New", "Ajouter"}.
-{"Registered Users", "Utilisateurs enregistrés"}.
-{"Registered Users:", "Utilisateurs enregistrés:"}.
-{"Change Password", "Modifier le mot de passe"}.
-{"Connected Resources:", "Ressources connectées:"}.
-{"Password:", "Mot de passe:"}.
-{"None", "Aucun"}.
-{"Node ", "Noeud "}.
-{"Listened Ports", "Ports ouverts"}.
-{"Restart", "Redémarrer"}.
-{"Stop", "Arrêter"}.
-{"RPC Call Error", "Erreur d'appel RPC"}.
-{"Name", "Nom"}.
-{"Storage Type", "Type de stockage"}.
-{"Size", "Taille"}.
-{"Memory", "Mémoire"}.
-{"OK", "OK"}.
-{"Listened Ports at ", "Ports ouverts sur "}.
-{"Uptime:", "Temps depuis le démarrage:"}.
-{"CPU Time:", "Temps CPU:"}.
-{"Transactions Commited:", "Transactions commitées:"}.
-{"Transactions Aborted:", "Transactions annulées:"}.
-{"Transactions Restarted:", "Transactions redémarrées:"}.
-{"Transactions Logged:", "Transactions journalisées:"}.
-{"Port", "Port"}.
-{"Module", "Module"}.
-{"Options", "Options"}.
-{"Update", "Mettre à jour"}.
-{"Delete", "Supprimer"}.
-{"Add User", "Ajouter un utilisateur"}.
-{"Offline Messages", "Messages en attente"}.
-{"Users Last Activity", "Dernière activité des utilisateurs"}.
-{"Never", "Jamais"}.
-{"~s's Offline Messages Queue", "~s messages en file d'attente"}.
-{"Time", "Heure"}.
-{"From", "De"}.
-{"To", "A"}.
-{"Packet", "Paquet"}.
-{"Offline Messages:", "Messages en attente:"}.
-{"Roster", "Liste de contacts"}.
-{"Nickname", "Pseudo"}.
-{"Subscription", "Abonnement"}.
-{"Pending", "En suspend"}.
-{"Groups", "Groupes"}.
-{"Remove", "Enlever"}.
-{"Add Jabber ID", "Ajouter un Jabber ID"}.
-{"User ", "Utilisateur"}.
-{"Roster of ", "Liste de contact de "}.
-{"Online", "En ligne"}.
-{"Validate", "Valider"}.
-{"Name:", "Nom:"}.
-{"Description:", "Description:"}.
-{"Members:", "Membres:"}.
-{"Displayed Groups:", "Groupes affichés:"}.
-{"Group ", "Groupe "}.
-{"Period: ", "Période:"}.
-{"Last month", "Dernier mois"}.
-{"Last year", "Dernière année"}.
-{"All activity", "Toute activité"}.
-{"Show Ordinary Table", "Montrer la table ordinaire"}.
-{"Show Integral Table", "Montrer la table intégralement"}.
-{"Modules at ", "Modules sur "}.
-{"Start", "Démarrer"}.
-{"Virtual Hosts", "Serveurs virtuels"}.
-{"ejabberd virtual hosts", "Serveurs virtuels d'ejabberd"}.
-{"Host", "Serveur"}.
-{"Authenticated Users:", "Utilisateurs authentifiés:"}.
-{"No Data", "Aucune information disponible"}.
-{"ejabberd Web Interface", "Ejabberd - Interface Web"}.
-{"Online Users:", "Utilisateurs connectés:"}.
-{"Outgoing s2s Connections:", "Connexions s2s sortantes:"}.
-{"Outgoing s2s Servers:", "Serveurs s2s sortants"}.
-{"Database Tables at ", "Tables de base de données sur "}.
-{"Backup of ", "Sauvegarde de "}.
-{"Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.", "Ces options sauvegardent uniquement la base de données interne Mnesia. Si vous utilisez le module ODBC vous devez sauvegarde votre base SQL séparément."}.
-{"Store binary backup:", "Sauvegarde binaire:"}.
-{"Restore binary backup immediately:", "Restauration immédiate d'une sauvegarde binaire:"}.
-{"Restore binary backup after next ejabberd restart (requires less memory):", "Restauration de la sauvegarde binaire après redémarrage (nécessite moins de mémoire):"}.
-{"Store plain text backup:", "Sauvegarde texte:"}.
-{"Restore plain text backup immediately:", "Restauration immédiate d'une sauvegarde texte:"}.
-{"Statistics of ~p", "Statistiques de ~p"}.
-{"Update ", "Mise à jour "}.
-{"Update plan", "Plan de mise à jour"}.
-{"Updated modules", "Modules mis à jours"}.
-{"Update script", "Script de mise à jour"}.
-{"Low level update script", "Script de mise à jour de bas-niveau"}.
-{"Script check", "Validation du script"}.
-{"Not Found", "Non trouvé"}.
-{"Shared Roster Groups", "Groupes de liste de contacts partagée"}.
-{"Last Activity", "Dernière Activité"}.
-
-% Local Variables:
-% mode: erlang
-% End:
diff --git a/ejabberd-1.1.2/src/msgs/nl.msg b/ejabberd-1.1.2/src/msgs/nl.msg
deleted file mode 100644
index c6b87a65e..000000000
--- a/ejabberd-1.1.2/src/msgs/nl.msg
+++ /dev/null
@@ -1,334 +0,0 @@
-% $Id$
-
-% mod_vcard_ldap.erl
-{"Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin", "Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"You need an x:data capable client to search", "U hebt een client nodig die x:data ondersteunt om te zoeken"}.
-{"Search users in ", "Gebruikers zoeken in "}.
-{"Fill in fields to search for any matching Jabber User", "Vul de velden in om te zoeken naar Jabber-gebruikers op deze server"}.
-{"User", "Gebruiker"}.
-{"Full Name", "Volledige naam"}.
-{"Middle Name", "Tussennaam"}.
-{"Family Name", "Achternaam"}.
-{"Nickname", "Bijnaam"}.
-{"Birthday", "Geboortedatum"}.
-{"Country", "Land"}.
-{"City", "Plaats"}.
-{"Email", "E-mail"}.
-{"Organization Name", "Organisatie"}.
-{"Organization Unit", "Afdeling"}.
-{"ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin", "ejabberd's vCard-module\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-{"Search Results for ", "Zoekresultaten voor "}.
-{"Jabber ID", "Jabber ID"}.
-
-% mod_vcard.erl
-{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)", "Gebruik de velden om te zoeken (Voeg achteraan het teken * toe om te zoeken naar alles wat met het eerste deel begint.)."}.
-{"Name", "Naam"}.
-% Probably needs to be "Given Name"
-
-% mod_configure.erl
-{"Configuration", "Instellingen"}.
-{"Database", "Database"}.
-{"Start Modules", "Modules starten"}.
-{"Stop Modules", "Modules stoppen"}.
-{"Backup", "Backup"}.
-{"Restore", "Binaire backup direct herstellen"}.
-{"Dump to Text File", "Backup naar een tekstbestand schrijven"}.
-{"Import File", "Bestand importeren"}.
-{"Import Directory", "Directory importeren"}.
-{"Host Name", "Hostnaam"}.
-{"Access Control Lists", "Access control lists"}.
-{"Access Rules", "Access rules"}.
-{"Online Users", "Online gebruikers"}.
-{"All Users", "Alle gebruikers"}.
-{"Outgoing s2s Connections", "Uitgaande s2s-verbindingen"}.
-{"Running Nodes", "Draaiende nodes"}.
-{"Stopped Nodes", "Gestopte nodes"}.
-{"Modules", "Modules"}.
-{"Backup Management", "Backup"}.
-{"Import Users From jabberd 1.4 Spool Files", "Importeer gebruikers via spool-bestanden van jabberd 1.4"}.
-{"To ~s", "Naar ~s"}.
-{"From ~s", "Van ~s"}.
-{"Database Tables Configuration at ", "Instellingen van databasetabellen op "}.
-{"Choose storage type of tables", "Opslagmethode voor tabellen kiezen"}.
-{"RAM copy", "RAM"}.
-{"RAM and disc copy", "RAM en harde schijf"}.
-{"Disc only copy", "Harde schijf"}.
-{"Remote copy", "Op andere nodes in de cluster"}.
-{"Stop Modules at ", "Modules stoppen op "}.
-{"Choose modules to stop", "Selecteer de modules die u wilt stoppen"}.
-{"Start Modules at ", "Modules starten op "}.
-{"Enter list of {Module, [Options]}", "Voer lijst met op te starten modules als volgt in: {Module, [Opties]}"}.
-{"List of modules to start", "Lijst met op te starten modules"}.
-{"Backup to File at ", "Binaire backup maken op "}.
-{"Enter path to backup file", "Voer pad naar backupbestand in"}.
-{"Path to File", "Pad naar bestand"}.
-{"Restore Backup from File at ", "Binaire backup direct herstellen op "}.
-{"Dump Backup to Text File at ", "Backup naar een tekstbestand schrijven op "}.
-{"Enter path to text file", "Voer pad naar backupbestand in"}.
-{"Import User from File at ", "Importeer gebruiker via bestand op "}.
-{"Enter path to jabberd1.4 spool file", "Voer pad naar jabberd 1.4-spool-bestand in"}.
-{"Import Users from Dir at ", "Gebruikers importeren vanaf directory op "}.
-{"Enter path to jabberd1.4 spool dir", "Voer pad naar jabberd 1.4-spool-directory in"}.
-{"Path to Dir", "Pad naar directory"}.
-{"Hostname Configuration", "Instellingen van hostnaam"}.
-{"Choose host name", "Hostnaam kiezen"}.
-{"Host name", "Hostnaam"}.
-{"Access Control List Configuration", "Instellingen van access control lists"}.
-{"Access control lists", "Access control lists"}.
-{"Access Configuration", "Toegangsinstellingen"}.
-{"Access rules", "Access rules"}.
-{"Remove Users", "Gebruikers verwijderen"}.
-{"Choose users to remove", "Selecteer de gebruikers die u wilt verwijderen"}.
-{"Administration of ", "Beheer van "}.
-{"Action on user", "Actie op gebruiker"}.
-{"Edit Properties", "Eigenschappen bewerken"}.
-{"Remove User", "Gebruiker verwijderen"}.
-{"Password", "Wachtwoord"}.
-
-% mod_register.erl
-{"Choose a username and password to register with this server", "Kies een gebruikersnaam en een wachtwoord om u te registreren op deze server"}.
-
-% ejabberd_c2s.erl
-{"Use of STARTTLS required", "Gebruik van STARTTLS is vereist"}.
-{"No resource provided", "Geen bron opgegeven"}.
-{"Replaced by new connection", "Vervangen door een nieuwe verbinding"}.
-
-% mod_muc/mod_muc_log.erl
-{"Chatroom configuration modified", "De instellingen van de chatruimte werden veranderd"}.
-{"joins the room", "betrad de chatruimte"}.
-{"leaves the room", "verliet de chatruimte"}.
-{"has been kicked", "werd gekicked"}.
-{"has been banned", "werd verbannen"}.
-{"is now known as", "heet nu"}.
-{" has set the subject to: ", " veranderde het onderwerp in: "}.
-{"Monday", "maandag"}.
-{"Tuesday", "dinsdag"}.
-{"Wednesday", "woensdag"}.
-{"Thursday", "donderdag"}.
-{"Friday", "vrijdag"}.
-{"Saturday", "zaterdag"}.
-{"Sunday", "zondag"}.
-{"January", "januari"}.
-{"February", "februari"}.
-{"March", "maart"}.
-{"April", "april"}.
-{"May", "mei"}.
-{"June", "juni"}.
-{"July", "juli"}.
-{"August", "augustus"}.
-{"September", "september"}.
-{"October", "oktober"}.
-{"November", "november"}.
-{"December", "december"}.
-{"Room Configuration", "Instellingen van de chatruimte"}.
-{"Room title", "Naam van de chatruimte"}.
-
-% mod_muc/mod_muc.erl
-{"Access denied by service policy", "De toegang werd geweigerd door het beleid van deze dienst"}.
-{"Only service administrators are allowed to send service messages", "Alleen beheerders van deze dienst mogen mededelingen verzenden naar alle chatruimtes"}.
-{"Room creation is denied by service policy", "De aanmaak van de chatruimte is verhinderd door de instellingen van deze server"}.
-{"Conference room does not exist", "De chatruimte bestaat niet"}.
-{"You need an x:data capable client to register nickname", "U hebt een client nodig die x:data ondersteunt om een bijnaam te registreren"}.
-{"Nickname Registration at ", "Registratie van een bijnaam op "}.
-{"Enter nickname you want to register", "Voer de bijnaam in die u wilt registreren"}.
-{"Specified nickname is already registered", "De gekozen bijnaam is al geregistreerd"}.
-{"You must fill in field \"Nickname\" in the form", "U moet het veld \"bijnaam\" invullen"}.
-{"ejabberd MUC module\nCopyright (c) 2003-2006 Alexey Shchepin", "ejabberd's MUC module\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-
-% mod_muc/mod_muc_room.erl
-{"Only moderators and participants are allowed to change subject in this room", "Alleen moderators en deelnemers mogen het onderwerp van deze chatruimte veranderen"}.
-{"Only moderators are allowed to change subject in this room", "Alleen moderators mogen het onderwerp van deze chatruimte veranderen"}.
-{"Visitors are not allowed to send messages to all occupants", "Bezoekers mogen geen berichten verzenden naar alle aanwezigen"}.
-{"It is not allowed to send private messages to the conference", "Er mogen geen privéberichten naar de chatruimte worden verzonden"}.
-{"It is not allowed to send normal messages to the conference", "Er mogen geen normale berichten naar de chatruimte worden verzonden"}.
-{"Improper message type", "Onjuist berichttype"}.
-{"Only occupants are allowed to send messages to the conference", "Alleen aanwezigen mogen berichten naar de chatruimte verzenden"}.
-{"Nickname is already in use by another occupant", "Deze bijnaam is al in gebruik door een andere aanwezige"}.
-{"Nickname is registered by another person", "Deze bijnaam is al geregistreerd door iemand anders"}.
-{"It is not allowed to send private messages of type \"groupchat\"", "Er mogen geen privéberichten van het type \"groupchat\" worden verzonden"}.
-{"Recipient is not in the conference room", "De ontvanger is niet in de chatruimte"}.
-{"Only occupants are allowed to send queries to the conference", "Alleen aanwezigen mogen verzoeken verzenden naar de chatruimte"}.
-{"Queries to the conference members are not allowed in this room", "Er mogen geen verzoeken verzenden worden naar deelnemers in deze chatruimte"}.
-{"private, ", "privé, "}.
-{"You have been banned from this room", "U werd verbannen uit deze chatruimte"}.
-{"Membership required to enter this room", "U moet lid zijn om deze chatruimte te kunnen betreden"}.
-{"This room is not anonymous", "Deze chatruimte is niet anoniem"}.
-{"Password required to enter this room", "U hebt een wachtwoord nodig om deze chatruimte te kunnen betreden"}.
-{"Incorrect password", "Foutief wachtwoord"}.
-{"Administrator privileges required", "U hebt beheerdersprivileges nodig"}.
-{"Moderator privileges required", "U hebt moderatorprivileges nodig"}.
-{"JID ~s is invalid", "De Jabber ID ~s is ongeldig"}.
-{"Nickname ~s does not exist in the room", "De bijnaam ~s bestaat niet in deze chatruimte"}.
-{"Invalid affiliation: ~s", "Ongeldige affiliatie: ~s"}.
-{"Invalid role: ~s", "Ongeldige rol: ~s"}.
-{"Owner privileges required", "U hebt eigenaarsprivileges nodig"}.
-{"Configuration for ", "Instellingen van "}.
-{"Make room persistent", "Chatruimte blijvend maken"}.
-{"Make room public searchable", "Chatruimte doorzoekbaar maken"}.
-{"Make participants list public", "Deelnemerslijst publiek maken"}.
-{"Make room password protected", "Chatruimte beveiligen met een wachtwoord"}.
-{"Make room members-only", "Chatruimte enkel toegankelijk maken voor leden"}.
-{"Make room moderated", "Chatruimte gemodereerd maken"}.
-{"Default users as participants", "Gebruikers standaard instellen als deelnemers"}.
-{"Allow users to change subject", "Gebruikers mogen het onderwerp veranderen"}.
-{"Allow users to send private messages", "Gebruikers mogen privéberichten verzenden"}.
-{"Allow users to query other users", "Gebruikers mogen naar andere gebruikers verzoeken verzenden"}.
-{"Allow users to send invites", "Gebruikers mogen uitnodigingen verzenden"}.
-{"Enable logging", "Logs aanzetten"}.
-{"You need an x:data capable client to configure room", "U hebt een client nodig die x:data ondersteunt om deze chatruimte in te stellen"}.
-{"Description", "Beschrijving"}.
-{"Number of occupants", "Aantal aanwezigen"}.
-{"Present real JIDs to", "Jabber ID's kunnen achterhaald worden door"}.
-{"moderators only", "moderators"}.
-{"anyone", "iedereen"}.
-
-% mod_irc/mod_irc.erl
-{"ejabberd IRC module\nCopyright (c) 2003-2006 Alexey Shchepin", "ejabberd's IRC-module\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-{"You need an x:data capable client to configure mod_irc settings", "U hebt een client nodig die x:data ondersteunt om dit IRC-transport in te stellen"}.
-{"Registration in mod_irc for ", "Registratie van "}.
-{"Enter username and encodings you wish to use for connecting to IRC servers", "Voer de gebruikersnaam en de coderingen in die u wilt gebruiken voor verbindingen met IRC-servers"}.
-{"IRC Username", "Gebruikersnaam voor IRC:"}.
-{"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.", "Als u verschillende coderingen wilt opgeven voor elke IRC-server, ga dan voor elke server te werk op als volgt: '{\"IRC-server\", \"codering\"}'. Standaard gebruikt dit IRC-transport de codering \"~s\"."}.
-{"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].", "Voorbeeld: [{\"irc.example.org\", \"koi8-r\"}, {\"vendetta.example.net\", \"iso8859-1\"}]."}.
-{"Encodings", "Coderingen:"}.
-
-% mod_adhoc.erl
-{"Commands", "Commando's"}.
-{"Ping", "Ping"}.
-{"Pong", "Pong"}.
-
-% mod_announce.erl
-{"Really delete message of the day?", "Wilt u het bericht van de dag verwijderen?"}.
-{"Subject", "Onderwerp"}.
-{"Message body", "Bericht"}.
-{"No body provided for announce message", "De mededeling bevat geen bericht"}.
-{"Announcements", "Mededelingen"}.
-{"Send announcement to all users", "Mededeling verzenden naar alle gebruikers"}.
-{"Send announcement to all online users", "Mededeling verzenden naar alle online gebruikers"}.
-{"Send announcement to all online users on all hosts", "Mededeling verzenden naar alle online gebruikers op alle virtuele hosts"}.
-{"Set message of the day and send to online users", "Bericht van de dag instellen en verzenden naar online gebruikers"}.
-{"Update message of the day (don't send)", "Bericht van de dag bijwerken (niet verzenden)"}.
-{"Delete message of the day", "Bericht van de dag verwijderen"}.
-
-% mod_pubsub/mod_pubsub.erl
-{"ejabberd pub/sub module\nCopyright (c) 2003-2006 Alexey Shchepin", "ejabberd's pub/sub module\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-{[], "[]"}.
-{"Node Creator", "Auteur van de node"}.
-{"Deliver payloads with event notifications", "Berichten bezorgen samen met gebeurtenisnotificaties"}.
-{"Notify subscribers when the node configuration changes", "Abonnees informeren wanneer de instellingen van de node veranderen"}.
-{"Notify subscribers when the node is deleted", "Abonnees informeren wanneer de node verwijderd word"}.
-{"Notify subscribers when items are removed from the node", "Abonnees informeren wanneer items verwijderd worden uit de node"}.
-{"Persist items to storage", "Items in het geheugen bewaren"}.
-{"Max # of items to persist", "Maximum aantal in het geheugen te bewaren items"}.
-{"Whether to allow subscriptions", "Abonnementsaanvraag toestaan"}.
-{"Specify the subscriber model", "Abonnementstype opgeven"}.
-{"Specify the publisher model", "Publicatietype opgeven"}.
-{"Max payload size in bytes", "Maximumgrootte van bericht in bytes"}.
-{"Send items to new subscribers", "Items naar nieuwe abonnees verzenden"}.
-{"Only deliver notifications to available users", "Notificaties alleen verzenden naar online gebruikers"}.
-{"Specify the current subscription approver", "Huidige verlener van abonnementen opgeven"}.
-
-% web/ejabberd_web_admin.erl
-{"ejabberd Web Interface", "ejabberd's webinterface"}.
-{"Administration", "Beheer"}.
-{"Virtual Hosts", "Virtuele hosts"}.
-{"Nodes", "Nodes"}.
-{"Statistics", "Statistieken"}.
-{"ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One", "ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One"}.
-{"Users", "Gebruikers"}.
-{"Last Activity", "Laatste activiteit"}.
-{"Shared Roster", "Gedeeld roster"}.
-{"(Raw)", "(Ruw)"}.
-{"Submitted", "Verzonden"}.
-{"Bad format", "Slecht formaat"}.
-{"Submit", "Verzenden"}.
-{"Raw", "Ruw"}.
-{"Delete Selected", "Geselecteerde verwijderen"}.
-{"~s access rule configuration", "Access rules op ~s"}.
-{"ejabberd virtual hosts", "Virtuele hosts"}.
-{"Users Last Activity", "Laatste activiteit van gebruikers"}.
-{"Period: ", "Periode: "}.
-{"Last month", "Afgelopen maand"}.
-{"Last year", "Afgelopen jaar"}.
-{"All activity", "Alle activiteit"}.
-{"Show Ordinary Table", "Deel van tabel laten zien"}.
-{"Show Integral Table", "Volledige tabel laten zien"}.
-{"Node not found", "Node niet gevonden"}.
-{"Add New", "Toevoegen"}.
-{"Host", "Host"}.
-{"Registered Users", "Geregistreerde gebruikers"}.
-{"Add User", "Gebruiker toevoegen"}.
-{"Offline Messages", "Offline berichten"}.
-{"Never", "Nooit"}.
-{"Online", "Online"}.
-{"Registered Users:", "Geregistreerde gebruikers:"}.
-{"Authenticated Users:", "Aangemelde gebruikers:"}.
-{"Online Users:", "Online gebruikers:"}.
-{"Outgoing s2s Connections:", "Uitgaande s2s-verbindingen:"}.
-{"Outgoing s2s Servers:", "Uitgaande s2s-verbindingen:"}.
-{"None", "Geen"}.
-{"Change Password", "Wachtwoord wijzigen"}.
-{"User ", "Gebruiker "}.
-{"Connected Resources:", "Verbonden bronnen:"}.
-{"Password:", "Wachtwoord:"}.
-{"Offline Messages:", "Offline berichten:"}.
-{"Roster", "Roster"}.
-{"~s's Offline Messages Queue", "offline berichten van ~s"}.
-{"Time", "Tijd"}.
-{"From", "Van"}.
-{"To", "Aan"}.
-{"Packet", "Pakket"}.
-{"Subscription", "Inschrijving"}.
-{"Pending", "Bezig"}.
-{"Groups", "Groepen"}.
-{"Validate", "Bevestigen"}.
-{"Remove", "Verwijderen"}.
-{"Roster of ", "Roster van "}.
-{"Add Jabber ID", "Jabber ID toevoegen"}.
-{"No Data", "Geen gegevens"}.
-{"Node ", "Node "}.
-{"Listened Ports", "Openstaande poorten"}.
-{"Update", "Bijwerken"}.
-{"Restart", "Herstarten"}.
-{"Stop", "Stoppen"}.
-{"RPC Call Error", "RPC-oproepfout"}.
-{"Database Tables at ", "Databasetabellen van "}.
-{"Storage Type", "Opslagmethode"}.
-{"Size", "Grootte"}.
-{"Memory", "Geheugen"}.
-{"Backup of ", "Backup maken van "}.
-{"Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.", "Merk op dat volgende opties enkel backups maken van de ingebouwde database Mnesia. Als u (een) andere database(s) gebruikt dan moet u daarvan (een) afzonderlijke backup(s) maken."}.
-{"Store binary backup:", "Binaire backup maken:"}.
-{"OK", "OK"}.
-{"Restore binary backup immediately:", "Binaire backup direct herstellen:"}.
-{"Restore binary backup after next ejabberd restart (requires less memory):", "Binaire backup herstellen na herstart van ejabberd (vereist minder geheugen):"}.
-{"Store plain text backup:", "Backup naar een tekstbestand schrijven:"}.
-{"Restore plain text backup immediately:", "Backup in een tekstbestand direct herstellen:"}.
-{"Listened Ports at ", "Openstaande poorten op "}.
-{"Modules at ", "Modules op "}.
-{"Statistics of ~p", "Statistieken van ~p"}.
-{"Uptime:", "Uptime:"}.
-{"CPU Time:", "Processortijd:"}.
-{"Transactions Commited:", "Bevestigde transacties:"}.
-{"Transactions Aborted:", "Afgebroken transacties:"}.
-{"Transactions Restarted:", "Herstarte transacties:"}.
-{"Transactions Logged:", "Gelogde transacties:"}.
-{"Update ", "Opwaarderen van "}.
-{"Update plan", "Plan voor de opwaardering"}.
-{"Updated modules", "Modules opwaarderen"}.
-{"Update script", "Script voor de opwaardering"}.
-{"Low level update script", "Lowlevel script voor de opwaardering"}.
-{"Script check", "Controle van script"}.
-{"Not Found", "Niet gevonden"}.
-{"Port", "Poort"}.
-{"Module", "Module"}.
-{"Options", "Opties"}.
-{"Delete", "Verwijderen"}.
-{"Start", "Starten"}.
-{"Shared Roster Groups", "Gedeelde rostergroepen"}.
-{"Name:", "Naam:"}.
-{"Description:", "Beschrijving:"}.
-{"Members:", "Groepsleden:"}.
-{"Displayed Groups:", "Weergegeven groepen:"}.
-{"Group ", "Groep "}.
-
diff --git a/ejabberd-1.1.2/src/msgs/pl.msg b/ejabberd-1.1.2/src/msgs/pl.msg
deleted file mode 100644
index 05dff9f78..000000000
--- a/ejabberd-1.1.2/src/msgs/pl.msg
+++ /dev/null
@@ -1,425 +0,0 @@
-% $Id$
-
-% jlib.hrl
-{"No resource provided", "Brak dostarczonych zasobów"}.
-
-% mod_configure.erl
-{"Choose storage type of tables", "Wybierz typ przechowalni tablic"}.
-{"RAM copy", "Kopia RAM"}.
-{"RAM and disc copy", "Kopia ramu i dysku"}.
-{"Disc only copy", "Kopia samego dysku"}.
-{"Remote copy", "Zdalna kopia"}.
-{"Stop Modules at ", "Zatrzymaj moduł o "}.
-{"Choose modules to stop", "Wybierz moduły do zatrzymania"}.
-{"Start Modules at ", "Uruchom moduł o "}.
-{"Enter list of {Module, [Options]}", "Wprowadź listę {Moduł, [Opcje]}"}.
-{"List of modules to start", "Lista modułów do uruchomienia"}.
-{"Backup to File at ", "Stwórz kopię do pliku na "}.
-{"Enter path to backup file", "Wprowadź scieżkę do pliku kopii zapasowej"}.
-{"Path to File", "Scieżka do pliku"}.
-{"Restore Backup from File at ", "Przywróć kopię zapasową z pliku na "}.
-{"Dump Backup to Text File at ", "Zrzuć kopię zapasową do pliku tekstowego na "}.
-{"Enter path to text file", "Wprowadź scieżkę do pliku tekstowego"}.
-{"Import User from File at ", "Importuj użytkownika z pliku na "}.
-{"Enter path to jabberd1.4 spool file", "Wprowadź ścieżkę do pliku spool dla serwera jabberd1.4"}.
-{"Import Users from Dir at ", "Importuj użytkowników z katalogu na "}.
-{"Enter path to jabberd1.4 spool dir", "Wprowadź ścieżkę do katalogu spool serwera jabberd1.4"}.
-{"Path to Dir", "Ścieżka do katalogu"}.
-{"Hostname Configuration", "Konfiguracja hosta"}.
-{"Choose host name", "Wybierz nazwę hosta"}.
-{"Host name", "Nazwa hosta"}.
-{"Access Control List Configuration", "Konfiguracja listy dostępowej"}.
-{"Access control lists", "Lista dostępu"}.
-{"Access Configuration", "Konfiguracja dostępu"}.
-{"Access rules", "Zasady dostępu"}.
-{"Remove Users", "Usuń użytkowników"}.
-{"Choose users to remove", "Wybierz użytkowników do usunięcia"}.
-{"Administration of ", "Administracja "}.
-{"Action on user", "Akcja dla użytkownika"}.
-{"Edit Properties", "Edytuj właściwości"}.
-{"Remove User", "Usuń użytkownika"}.
-
-% mod_disco.erl
-{"Configuration", "Konfiguracja"}.
-{"Online Users", "Użytkownicy zalogowani"}.
-{"All Users", "Wszyscy użytkownicy"}.
-{"To ~s", "Do ~s"}.
-{"From ~s", "Z ~s"}.
-{"Running Nodes", "Uruchomione gałęzie"}.
-{"Stopped Nodes", "Zatrzymane gałęzie"}.
-{"Host Name", "Nazwa hosta"}.
-{"Access Control Lists", "Lista dostępowa"}.
-{"Access Rules", "Zasady dostępu"}.
-{"Remove Users", "Usuń użytkowników"}.
-{"Modules", "Moduły"}.
-{"Start Modules", "Uruchom moduły"}.
-{"Stop Modules", "Zatrzymaj moduły"}.
-{"Backup Management", "Zarządzanie kopiami zapasowymi"}.
-{"Backup", "Tworzenie kopii"}.
-{"Restore", "Odtwarzanie kopii"}.
-{"Dump to Text File", "Zrzucanie do pliku tekstowego"}.
-{"Import File", "Importuj plik"}.
-{"Import Directory", "Importuj katalog"}.
-
-% mod_register.erl
-{"Choose a username and password to register with this server",
- "Wybierz nazwę użytkownika i hasło aby zarejestrować się na tym serwerze"}.
-
-% mod_vcard.erl
-{"You need an x:data capable client to search",
- "Potrzebujesz klienta kompatybilnego z x:data aby wyszukiwać"}.
-{"Search users in ", "Wyszukaj użytkowników w "}.
-{"Fill in fields to search for any matching Jabber User",
- "Wypełnij pola aby znaleźdź pasujących użytkowników Jabbera"}.
-
-{"User", "Użytkownik: "}.
-{"Full Name", "Pełna nazwa: "}.
-{"Name", "Imię: "}.
-{"Middle Name", "Nazwisko: "}.
-{"Family Name", "Nazwisko rodowe: "}.
-{"Nickname", "Nick: "}.
-{"Birthday", "Data urodzenia: "}.
-{"Country", "Państwo: "}.
-{"City", "Miasto: "}.
-{"Organization Name", "Nazwa organizacji: "}.
-{"Organization Unit", "Dział: "}.
-
-% mod_muc/mod_muc.erl
-{"You need an x:data capable client to register nickname",
- "Potrzebujesz klienta kompatybilnego z x:data aby zarejestrować nick"}.
-{"Nickname Registration at ", "Rejestracja nicka na "}.
-{"Enter nickname you want to register", "Wprowadz nicka którego chcesz zarejestrować"}.
-{"Only service administrators are allowed to send service messages",
- "Jedynie administrator może wysyłać wiadomości serwisowe"}.
-{"Conference room does not exist", "Pokój konferencyjny nie istnieje"}.
-{"Access denied by service policy", "Dostęp zabroniony przez zabezpieczenia serwera"}.
-{"Specified nickname is already registered", "Podany nick jest już zarejestrowany"}.
-
-% mod_muc/mod_muc_room.erl
-{" has set the subject to: ", "zmieł(a) temat na: "}.
-{"You need an x:data capable client to configure room",
- "Potrzebujesz klienta kompatybilnego z x:data aby skonfigurować pokój"}.
-{"Configuration for ", "Konfiguracja dla "}.
-{"Room title", "Tytuł pokoju"}.
-{"Password", "Hasło"}.
-{"Only moderators and participants are allowed to change subject in this room",
- "Tylko moderatorzy i wlasciciele mogą zmienić temat tego pokoju"}.
-{"Only moderators are allowed to change subject in this room",
- "Tylko moderatorzy mogą zmienić temat tego pokoju"}.
-{"Visitors are not allowed to send messages to all occupants",
- "Odwiedzający nie mogą wysyłać wiadomości do wszystkich obecnych"}.
-{"Only occupants are allowed to send messages to the conference",
- "Tylko obecni mogą wysyłać wiadomości na konferencje"}.
-{"It is not allowed to send normal messages to the conference",
- "Nie można wysyłać normalnych wiadomości na konferencje"}.
-{"It is not allowed to send private messages to the conference",
- "Nie wolno wysyłac prywatnych wiadomości na konferencje"}.
-{"Improper message type", "Nieprawidłowy typ wiadomości"}.
-{"Nickname is already in use by another occupant", "Nick jest używany przez innego użytkownika"}.
-{"Nickname is registered by another person", "Nick jest już zarejestrowany przez inną osobę"}.
-{"It is not allowed to send private messages of type \"groupchat\"",
- "Nie mozna wysyłac prywatnych wiadomości typu \"Groupchat\" "}.
-{"Recipient is not in the conference room", "Odbiorca nie jest obecny w pokoju"}.
-{"Only occupants are allowed to send queries to the conference",
- "Tylko użytkownicy mogą wysyłać zapytania do pokoju konferencyjnego"}.
-{"Queries to the conference members are not allowed in this room",
- "Zapytania do członków konferencji nie są dozwolone w tym pokoju"}.
-{"You have been banned from this room", "Zostałeś zabanowany w tym pokoju"}.
-{"Membership required to enter this room", "Aby wejść do pokoju wymagane jest jego członkostwo"}.
-{"Password required to enter this room", "Aby wejść do pokoju wymagane jest hasło"}.
-{"Incorrect password", "Nieprawidłowe hasło"}.
-{"Administrator privileges required", "Wymagane prawa administratora"}.
-{"Moderator privileges required", "Wymagane prawa moderatora"}.
-{"JID ~s is invalid", "JID ~s jest niepoprawny"}.
-{"Nickname ~s does not exist in the room", "Nick ~s nie istnieje w tym pokoju"}.
-{"Invalid affiliation: ~s", "Nieprawidłowe powiązanie: ~s"}.
-{"Invalid role: ~s", "Nieprawidłowa rola: ~s"}.
-{"Owner privileges required", "Wymagane uprawnienia właściciela "}.
-{"private, ", "prywatny, "}.
-{"Present real JIDs to", "Kto może widzieć prawdziwe JID-y?"}.
-{"moderators only", "tylko moderatorzy"}.
-{"anyone", "wszyscy"}.
-
-
-% mod_irc/mod_irc.erl
-{"You need an x:data capable client to configure mod_irc settings",
- "Potrzebujesz klienta kompatybilnego z x:data aby skonfigurować mod_irc"}.
-{"Registration in mod_irc for ", "Rejestracja w mod_irc dla "}.
-{"Enter username and encodings you wish to use for connecting to IRC servers",
- "Wprowadź nazwę użytkownika i kodowanie których chcesz używać do łączenia z serwerami IRC"}.
-{"IRC Username", "Nazwa użytkownika"}.
-{"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].",
- "Przykład: [{\"wroclaw.irc.pl\",\"utf-8\"}, {\warszawa.irc.pl\", \"iso8859-2\"}]."}.
-{"Encodings", "Kodowania"}.
-
-% web/ejabberd_web_admin.erl
-{"Users", "Użytkownicy"}.
-{"Nodes", "Gałęzie"}.
-{"Statistics", "Statystyki"}.
-{"Delete Selected", "Usuń zaznaczone"}.
-{"Submit", "Wprowadź"}.
-{"~s access rule configuration", "~s konfiguracja zasad dostępu"}.
-{"Node not found", "Gałąź nie znaleziona"}.
-{"Add New", "Dodaj nowe"}.
-{"Change Password", "Zmień hasło"}.
-{"Connected Resources:", "Zasoby podłączone"}.
-{"Password:", "Hasło:"}.
-{"None", "Brak"}.
-{"Node ", "Gałąź "}.
-{"Restart", "Restart"}.
-{"Stop", "Stop"}.
-{"Name", "Nazwa"}.
-{"Storage Type", "Typ bazy"}.
-{"Size", "Wielkość"}.
-{"Memory", "Pamięć"}.
-{"OK", "OK"}.
-{"Listened Ports at ", "Porty nasłuchujące "}.
-{"Port", "Port"}.
-{"Module", "Moduł"}.
-{"Options", "Opcje"}.
-{"Update", "Aktualizacja"}.
-{"Delete", "Usuń"}.
-{"Add User", "Dodaj użytkownika"}.
-{"Last Activity", "Ostatnia aktywność"}.
-{"Never", "Nigdy"}.
-{"Time", "Czas"}.
-{"From", "Od"}.
-{"To", "Do"}.
-{"Packet", "Pakiet "}.
-{"Roster", "Roster "}.
-{"Nickname", "Nick "}.
-{"Subscription", "Subskrypcja "}.
-{"Pending", "Oczekiwanie "}.
-{"Groups", "Grupy "}.
-{"Remove", "Usuń "}.
-{"User ", "Użytkownik "}.
-{"Roster of ", "Roster "}.
-{"Shared Roster", "Roster współdzielony"}.
-{"Online", "Dostępny"}.
-{"Validate", "Zatwierdź"}.
-{"Name:", "Nazwa:"}.
-{"Description:", "Opis:"}.
-{"Members:", "Członkowie:"}.
-{"Displayed Groups:", "Wyświetlane grupy:"}.
-{"Group ", "Grupa "}.
-{"Period: ", "Przedział czasu "}.
-{"Last month", "Ostatni miesiąc"}.
-{"Last year", "Ostatni rok"}.
-{"All activity", "Cała aktywność"}.
-{"Show Ordinary Table", "Pokaż zwykłą tabelę"}.
-{"Show Integral Table", "Pokaż tabelę całkowitą"}.
-{"Start", "Start"}.
-{"Modules at ", "Moduły na "}.
-{"Virtual Hosts", "Wirtualne hosty"}.
-{"ejabberd virtual hosts", "wirtualne hosty ejabberda"}.
-{"Host", "Host"}.
-{"ejabberd Web Interface", ""}.
-
-% mod_vcard_odbc.erl
-{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)", "Wypełnij formularz aby wyszukać pasujących użytkowników Jabbera (dodaj * na koniec pola aby dopasować)"}.
-
-% ejabberd_c2s.erl
-{"Use of STARTTLS required", "Wymagane użycie STARTTLS"}.
-{"Replaced by new connection", ""}.
-
-% mod_pubsub/mod_pubsub.erl
-{[], " "}.
-{"Node Creator", "Tworzenie gałęzi"}.
-{"Deliver payloads with event notifications", "Dołącz zawartość publikowanego przedmiotu podczas wysyłania powiadomienia o publikacji"}.
-{"Notify subscribers when the node configuration changes", "Informuj subskrybentów gdy konfiguracja gałęzi się zmieni"}.
-{"Notify subscribers when the node is deleted", "Informuj subskrybentów gdy gałąż zostanie wykasowana"}.
-{"Notify subscribers when items are removed from the node", "Informuj subskrybentów kiedy zostaną z gałęzi usunięte jakieś elementy"}.
-{"Persist items to storage", "Przechowuj przedmioty pub/sub w pamięci"}.
-{"Max # of items to persist", "Maksymalna ilość przechowywanych przedmiotów"}.
-{"Whether to allow subscriptions", "Czy pozwolić na subskrypcje"}.
-{"Specify the subscriber model", "Oznacz model subskrybenta"}.
-{"Specify the publisher model", "Oznacz model publikującego"}.
-{"Max payload size in bytes", "Maksymalna wielkość powiadomienia w bajtach"}.
-{"Send items to new subscribers", "Wysyłaj rzeczy do nowych subskrybentów"}.
-{"Only deliver notifications to available users", "Dostarczaj notyfikacje tylko do osiągalnych użytkowników"}.
-{"Specify the current subscription approver", "Wyznacz aprobującego obecne subskrypcje "}.
-
-% mod_irc/mod_irc.erl
-{"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.", "Jeśli chcesz ustawić inne kodowanie dla serwerów IRC, wypełnij tą listę wartościami w formacie '{\"irc server\",\"encoding\"}'. Jako domyślne ten serwis używa kodowania \"~s\"."}.
-
-% mod_muc/mod_muc.erl
-{"Room creation is denied by service policy", "Tworzenie pokoju jest zabronione przez polisę"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_vcard_odbc.erl
-{"Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin", "Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"Email", ""}.
-{"ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin", "Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"Search Results for ", "Wyniki wyszukiwania dla "}.
-{"Jabber ID", "Jabber ID"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_adhoc.erl
-{"Commands", "Polecenia"}.
-{"Ping", "Ping"}.
-{"Pong", "Pong"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/ejabberd_c2s.erl
-{"Replaced by new connection", "Podmienione przez nowe połączenie"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_announce.erl
-{"Really delete message of the day?", "Na pewno usunąć wiadomość dnia?"}.
-{"Subject", "Temat"}.
-{"Message body", "Treść wiadomości"}.
-{"No body provided for announce message", "Nikt nie jest uprawniony do rozsyłania oznajmień"}.
-{"Announcements", "Oznajmienia"}.
-{"Send announcement to all users", "Wyślij oznajmienie do wszystkich użytkowników"}.
-{"Send announcement to all online users", "Wyślij oznajmienie do wszystkich użytkowników online"}.
-{"Send announcement to all online users on all hosts", "Wyślij oznajmienie do wszystkich użytkowników online na wszystkich hostach"}.
-{"Set message of the day and send to online users", "Wyślij wiadomość dnia do wszystkich użytkowników online"}.
-{"Update message of the day (don't send)", "Zmień wiadomość dnia (nie wysyłaj)"}.
-{"Delete message of the day", "Usuń wiadomość dnia"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_configure.erl
-{"Database", "Baza"}.
-{"Outgoing s2s Connections", "Wychodzące połączenia s2s"}.
-{"Import Users From jabberd 1.4 Spool Files", "Importuj użytkowników z plików spool serwera jabber 1.4"}.
-{"Database Tables Configuration at ", "Konfiguracja tabel bazy na "}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_pubsub/mod_pubsub.erl
-{"ejabberd pub/sub module\nCopyright (c) 2003-2006 Alexey Shchepin", ""}.
-
-% /usr/home/src/ejabberd/ejabberd/src/web/ejabberd_web_admin.erl
-{"ejabberd Web Interface", "Interfejs WWW serwera ejabberd"}.
-{"Administration", "Administracja"}.
-{"ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One", ""}.
-{"(Raw)", ""}.
-{"Submitted", "Wprowadzone"}.
-{"Bad format", "Zły format"}.
-{"Raw", ""}.
-{"Users Last Activity", "Ostatnia aktywność użytkowników"}.
-{"Registered Users", "Użytkownicy zarejestrowani"}.
-{"Offline Messages", "Wiadomości offline"}.
-{"Registered Users:", "Użytkownicy zarejestrowani:"}.
-{"Authenticated Users:", "Użytkownicy autoryzowani:"}.
-{"Online Users:", "Użytkownicy online:"}.
-{"Outgoing s2s Connections:", "Wychodzące połączenia s2s:"}.
-{"Outgoing s2s Servers:", "Serwery zewnętrzne s2s:"}.
-{"Offline Messages:", "Wiadomości offline"}.
-{"~s's Offline Messages Queue", "~s skolejkowanych wiadomości offline"}.
-{"Add Jabber ID", "Dodaj JID"}.
-{"No Data", "Brak danych"}.
-{"Listened Ports", "Porty nasłuchujące"}.
-{"RPC Call Error", "Błąd odwołania RPC"}.
-{"Database Tables at ", "Tabele bazy na "}.
-{"Backup of ", "Kopia zapasowa "}.
-{"Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.", "Te opcje backupują jedynie bazę Mnesia. Jeśli używasz modułu ODBC - musisz wykonać kopię SQL oddzielnie"}.
-{"Store binary backup:", "Zachowaj kopię binarną:"}.
-{"Restore binary backup immediately:", "Natychmiast odtwórz kopię binarną:"}.
-{"Restore binary backup after next ejabberd restart (requires less memory):", "Odtwórz kopię binarną podczas następnego restaru ejabberd-a (wymaga mniej pamięci)"}.
-{"Store plain text backup:", "Zachowaj kopię w czystym tekście"}.
-{"Restore plain text backup immediately:", "Odtwórz kopię z czystego tekstu"}.
-{"Statistics of ~p", "Statystyki ~p"}.
-{"Uptime:", "Uptime"}.
-{"CPU Time:", "Czas CPU"}.
-{"Transactions Commited:", "Transakcje zakończone"}.
-{"Transactions Aborted:", "Transakcje anulowane"}.
-{"Transactions Restarted:", "Transakcje uruchomione ponownie"}.
-{"Transactions Logged:", "Transakcje logowane"}.
-{"Update ", "Uaktualnij"}.
-{"Update plan", "Uaktualnij plan"}.
-{"Updated modules", "Uaktualnione moduły"}.
-{"Update script", "Uaktualnij skrypt"}.
-{"Low level update script", ""}.
-{"Script check", "Sprawdź skrypt"}.
-{"Not Found", "Nie znaleziono"}.
-{"Shared Roster Groups", "Grupy współdzielone"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_irc/mod_irc.erl
-{"ejabberd IRC module\nCopyright (c) 2003-2006 Alexey Shchepin", ""}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_muc/mod_muc_log.erl
-{"Chatroom configuration modified", "Konfiguracja pokoju zmodyfikowana"}.
-{"joins the room", "dołączył(a) się do pokoju"}.
-{"leaves the room", "opóścił(a) pokój"}.
-{"has been kicked", "został(a) kopnięty(a)"}.
-{"has been banned", "został(a) zabanowany(a)"}.
-{"is now known as", "jest teraz znany(a) jako"}.
-{"Monday", "Poniedziałek"}.
-{"Tuesday", "Wtorek"}.
-{"Wednesday", "Środa"}.
-{"Thursday", "Czwartek"}.
-{"Friday", "Piątek"}.
-{"Saturday", "Sobota"}.
-{"Sunday", "Niedziela"}.
-{"January", "Styczeń"}.
-{"February", "Luty"}.
-{"March", "Marzec"}.
-{"April", "Kwiecień"}.
-{"May", "Maj"}.
-{"June", "Czerwiec"}.
-{"July", "Lipiec"}.
-{"August", "Sierpień"}.
-{"September", "Wrzesień"}.
-{"October", "Październik"}.
-{"November", "Listopad"}.
-{"December", "Grudzień"}.
-{"Room Configuration", "Konfiguracja pokoju"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_muc/mod_muc.erl
-{"You must fill in field \"Nickname\" in the form", "Musisz wypełnić pole NICKNAME w formularzu"}.
-{"ejabberd MUC module\nCopyright (c) 2003-2006 Alexey Shchepin", ""}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_muc/mod_muc_room.erl
-{"This room is not anonymous", "Pokój nie jest nieznany"}.
-{"Make room persistent", "Utwórz pokój na stałe"}.
-{"Make room public searchable", "Pozwól wyszukiwać pokój"}.
-{"Make participants list public", "Upublicznij listę uczestników"}.
-{"Make room password protected", "Zabezpiecz pokój hasłem"}.
-{"Make room members-only", "Utwórz pokój tylko dla uczestnikóww"}.
-{"Make room moderated", "Moderuj pokój"}.
-{"Default users as participants", "Domyślni użytkownicy jako uczestnicy"}.
-{"Allow users to change subject", "Pozwól użytkownikom zmienić tytuł pokoju"}.
-{"Allow users to send private messages", "Pozwól użytkownikom wysyłać prywatne wiadomości"}.
-{"Allow users to query other users", "Pozwól użytkownikom pobierać informacje o innych użytkownikach"}.
-{"Allow users to send invites", "Pozwól użytkownikom wysyłać zaproszenia"}.
-{"Enable logging", "Włącz logowanie"}.
-{"Description", "Opis"}.
-{"Number of occupants", "Liczba uczestników"}.
-
-% mod_vcard_ldap.erl
-{"Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin", "Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin", "ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-{"Jabber ID", "Jabber ID"}.
-
-% ./mod_presence.erl
-{"You need an x:data capable client to register presence", "Potrzebujesz klinta kompatybilnego z x:data aby zarejestrować widoczność "}.
-{"Presence registration at ", "Rejestracja widoczności na "}.
-{"What presence features do you want to register?", "Jakie usługi widoczności chcesz zarejestrować?"}.
-{"Raw XML", ""}.
-{"Specified presence is already registered", "Określona widoczność już jest zarejestrowana"}.
-{"You must fill in field \"Xml\" in the form", "Musisz wypełnić w formularzu pole \"XML\""}.
-{"You must fill in field \"Icon\" in the form", "Musisz wypełnić w formularzu pole \"Icon\""}.
-{"ejabberd presence module\nCopyright (c) 2006 Igor Goryachev", ""}.
-
-% ./mod_presence/mod_presence.erl
-{"Raw XML export", "Eksport XML do raw"}.
-{"Allow icon export", "Pozwól na eksport ikon"}.
-
-% ./mod_stats2file.erl
-{"CPUtime", "Czas procesora"}.
-
-% ./mod_vcard_odbc.erl
-{"Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin", ""}.
-{"Email", ""}.
-{"ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin", ""}.
-{"Jabber ID", ""}.
-
-% ./mod_pubsub/mod_pubsub.erl
-{"ejabberd pub/sub module\nCopyright (c) 2003-2006 Alexey Shchepin", ""}.
-
-% ./web/ejabberd_web_admin.erl
-{"ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One", ""}.
-{"(Raw)", ""}.
-{"Raw", ""}.
-{"Low level update script", "Skrypt aktualizacyjny niskiego poziomu"}.
-
-% ./mod_irc/mod_irc.erl
-{"ejabberd IRC module\nCopyright (c) 2003-2006 Alexey Shchepin", ""}.
-
-% ./mod_muc/mod_muc.erl
-{"ejabberd MUC module\nCopyright (c) 2003-2006 Alexey Shchepin", ""}.
-
diff --git a/ejabberd-1.1.2/src/msgs/pt-br.msg b/ejabberd-1.1.2/src/msgs/pt-br.msg
deleted file mode 100644
index 6cc5f4052..000000000
--- a/ejabberd-1.1.2/src/msgs/pt-br.msg
+++ /dev/null
@@ -1,380 +0,0 @@
-% $Id$
-% Brazilian Portuguese translation
-% Authors: Victor Hugo dos Santos, Lucius Curado
-
-
-
-% jlib.hrl
-{"No resource provided", "Recurso não foi fornecido"}.
-
-
-% mod_configure.erl
-{"Access Configuration", "Configuração de Acesso"}.
-{"Access Control List Configuration", "Configuração da Lista de Controle de Acesso"}.
-{"Access control lists", "Listas de Controle de Acesso"}.
-{"Access rules", "Regras de acesso"}.
-{"Action on user", "Ação no usuário"}.
-{"Administration of ", "Administração de "}.
-{"Backup to File at ", "Salvar cópia de segurança para arquivo em "}.
-{"Choose modules to stop", "Selecione módulos a parar"}.
-{"Choose storage type of tables", "Selecione o tipo de armazenamento das tabelas"}.
-{"Choose users to remove", "Selecione usuários para remoção"}.
-{"Disc only copy", "Copia em disco somente"}.
-{"Dump Backup to Text File at ", "Exporta cópia de segurança para arquivo de texto em "}.
-{"Edit Properties", "Editar propriedades"}.
-{"Enter list of {Module, [Options]}", "Introduza lista de {módulo, [opções]}"}.
-{"Enter path to backup file", "Introduza o caminho do arquivo de cópia de segurança"}.
-{"Enter path to jabberd1.4 spool dir", "Introduza o caminho para o diretório de spools do jabberd1.4"}.
-{"Enter path to jabberd1.4 spool file", "Introduza o caminho para o arquivo de spool do jabberd1.4"}.
-{"Enter path to text file", "Introduza caminho para o arquivo de texto"}.
-{"Import User from File at ", "Importar usuário a partir do arquivo em "}.
-{"Import Users from Dir at ", "Importar usuários a partir do diretório em "}.
-{"Path to Dir", "Caminho para o diretório"}.
-{"Path to File", "Caminho do arquivo"}.
-{"RAM and disc copy", "Copia em RAM y disco"}.
-{"RAM copy", "Copia em RAM"}.
-{"Remote copy", "Copia remota"}.
-{"Remove User", "Remover usuário"}.
-{"Remove Users", "Remover usuários"}.
-{"Restore Backup from File at ", "Restaura cópia de segurança a partir do arquivo em "}.
-{"Start Modules at ", "Iniciar módulos em "}.
-
-
-% mod_disco.erl
-{"Access Control Lists", "Listas de Controle de Acesso"}.
-{"Access Rules", "Regras de Aceso"}.
-{"All Users", "Todos os usuários"}.
-{"Backup", "Salvar cópia de segurança"}.
-{"Backup Management", "Gestão de copia de segurança"}.
-{"Configuration", "Configuração"}.
-{"Dump to Text File", "Exportar para arquivo de texto"}.
-{"From ~s", "De ~s"}.
-{"Import Directory", "Importar diretório"}.
-{"Import File", "Importar arquivo"}.
-{"Modules", "Módulos"}.
-{"Online Users", "Usuários conectados"}.
-{"Remove Users", "Remover usuários"}.
-{"Restore", "Restaurar"}.
-{"Running Nodes", "Nos em execução"}.
-{"Start Modules", "Iniciar módulos"}.
-{"Stop Modules", "Parar módulos"}.
-{"Stopped Nodes", "Nos parados"}.
-{"To ~s", "Para ~s"}.
-
-
-% mod_register.erl
-{"Choose a username and password to register with this server", "Escolha um nome de usuário e senha para registrar-se neste servidor"}.
-
-
-% mod_vcard.erl
-{"Birthday","Aniversário"}.
-{"City", "Cidade"}.
-{"Country","País"}.
-{"ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin", "Módulo vCard para ejabberd\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin", "Servidor Jabber em Erlang\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"Family Name", "Nome de família"}.
-{"Fill in fields to search for any matching Jabber User", "Preencha os campos para procurar usuários Jabber coincidentes"}.
-{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)", "Preencha o formulário para buscar usuários Jabber. Agrega * ao final de um campo para buscar sub-palavras."}.
-{"Full Name", "Nome completo"}.
-{"Middle Name", "Apelido"}.
-{"Name", "Nome"}.
-{"Nickname", "Nick"}.
-{"Organization Name", "Nome da organização"}.
-{"Organization Unit", "Unidade da organização"}.
-{"Search users in ", "Procurar usuários em "}.
-{"User", "Usuário"}.
-{"You need an x:data capable client to search", "Necessitas um cliente com suporte de x:data para poder buscar"}.
-% mod_pubsub/mod_pubsub.erl
-
-
-{[], " "}.
-{"Deliver payloads with event notifications", "Enviar payloads junto com as notificações de eventos"}.
-{"ejabberd pub/sub module\nCopyright (c) 2003-2006 Alexey Shchepin", "Módulo Pub/Sub para ejabberd\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"Max # of items to persist", "Máximo # de elementos que persistem"}.
-{"Max payload size in bytes", "Máximo tamanho do payload em bytes"}.
-{"Node Creator", "Criador do nodo"}.
-{"Notify subscribers when items are removed from the node", "Notificar subscritores quando os elementos se eliminem do nodo"}.
-{"Notify subscribers when the node configuration changes", "Notificar subscritores quando cambia la configuração do nodo"}.
-{"Notify subscribers when the node is deleted", "Notificar subscritores quando o nodo se elimine"}.
-{"Only deliver notifications to available users", "Solo enviar notificações aos usuários disponíveis"}.
-{"Persist items to storage", "Persistir elementos ao armazenar"}.
-{"Send items to new subscribers", "Enviar elementos aos novos subscritores"}.
-{"Specify the current subscription approver", "Especificar o aprobador da subscrição atual"}.
-{"Specify the publisher model", "Especificar o modelo do publicante"}.
-{"Specify the subscriber model", "Especificar o modelo de subscrição"}.
-{"Whether to allow subscriptions", "Permitir subscrições"}.
-
-% mod_muc/mod_muc.erl
-{"Access denied by service policy", "Aceso denegado por la política do serviço"}.
-{"Conference room does not exist", "La sala de conferencias não existe"}.
-{"ejabberd MUC module\nCopyright (c) 2003-2006 Alexey Shchepin", "Módulo de MUC para ejabbed\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"Enter nickname you want to register", "Introduza o apelido que quer registrar"}.
-{"Incorrect password", "Senha incorreta"}.
-{"Nickname is already in use by another occupant", "O apelido já está em uso por outro ocupante"}.
-{"Nickname is registered by another person", "O apelido já está registrado por outra pessoa"}.
-{"Nickname Registration at ", "Registro do apelido em "}.
-{"Nickname ~s does not exist in the room", "Apelido ~s não existe na sala"}.
-{"Password required to enter this room", "É necessária a senha para poder entrar nesta sala"}.
-{"Password", "Senha"}.
-{"Room creation is denied by service policy", "Se te a denegado criar la sala por política do serviço"}.
-{"Specified nickname is already registered", "O apelido especificado já está registrado"}.
-{"You need an x:data capable client to register nickname", "Necessitas um cliente com suporte de x:data para poder registrar o nick"}.
-
-% mod_muc/mod_muc_room.erl
-{"Administrator privileges required", "Se necessita privilégios de administrador"}.
-{"Configuration for ", "Configuração para "}.
-{" has set the subject to: ", " a posto o assunto: "}.
-{"Improper message type", "Tipo de mensagem incorreto"}.
-{"Incorrect password", "Senha incorreta"}.
-{"Invalid affiliation: ~s", "Afiliação não válida: ~s"}.
-{"Invalid role: ~s", "Rol não válido: ~s"}.
-{"It is not allowed to send normal messages to the conference", "Impedir o envio de mensagens normais a la sala"}.
-{"It is not allowed to send private messages of type \"groupchat\"", "No está permitido enviar mensagens privados do tipo \"groupchat\""}.
-{"It is not allowed to send private messages to the conference", "Impedir o envio de mensagens privados a la sala"}.
-{"JID ~s is invalid", "O JID ~s não es válido"}.
-{"Membership required to enter this room", "Necessitas ser membro de esta sala para poder entrar"}.
-{"Moderator privileges required", "Se necessita privilégios de moderador"}.
-{"Nickname is already in use by another occupant", "O nick já está sendo usado por outro ocupante"}.
-{"Nickname is registered by another person", "O nick já está registrado por outra pessoa"}.
-{"Nickname ~s does not exist in the room", "O nick ~s não existe em la sala"}.
-{"Only moderators and participants are allowed to change subject in this room", "Solo os moderadores y participantes podem cambiar o assunto de esta sala"}.
-{"Only moderators are allowed to change subject in this room", "Solo os moderadores podem cambiar o assunto de esta sala"}.
-{"Only occupants are allowed to send messages to the conference", "Solo os ocupantes podem enviar mensagens a la sala"}.
-{"Only occupants are allowed to send queries to the conference", "Solo os ocupantes podem enviar consultas a la sala"}.
-{"Owner privileges required", "Se requere privilégios de proprietário da sala"}.
-{"Password", "Senha"}.
-{"Password required to enter this room", "Se necessita senha para entrar em esta sala"}.
-{"private, ", "privado"}.
-{"Queries to the conference members are not allowed in this room", "Nesta sala não se permite consultas aos membros da sala"}.
-{"Recipient is not in the conference room", "O receptor não está em la sala de conferencia"}.
-{"Room title", "Título da sala"}.
-{"Visitors are not allowed to send messages to all occupants", "Os visitantes não podem enviar mensagens a todos os ocupantes"}.
-{"You have been banned from this room", "As sido bloqueado em esta sala"}.
-{"You need an x:data capable client to configure room", "Necessitas um cliente com suporte de x:data para configurar la sala"}.
-
-
-% mod_irc/mod_irc.erl
-{"ejabberd IRC module\nCopyright (c) 2003-2006 Alexey Shchepin", "Módulo de IRC para ejabberd\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"Encodings", "Codificação"}.
-{"Enter username and encodings you wish to use for connecting to IRC servers", "Introduza o nome de usuário e codificações de caracteres que quer usar ao conectar-se aos servidores de IRC"}.
-{"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].", "Exemplo: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}]."}.
-{"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.", "Se deseja especificar codificações de caracteres diferentes para cada servidor IRC preencha esta lista com valores no formato '{\"servidor irc\", \"codificação\"}'. Este serviço usa por padrão a codificação \"~s\"."}.
-{"IRC Username", "Nome de usuário no IRC"}.
-{"Registration in mod_irc for ", "Registro em mod_irc para"}.
-{"You need an x:data capable client to configure mod_irc settings", "Necessitas um cliente com suporte de x:data para configurar las opções de mod_irc"}.
-
-
-% web/ejabberd_web_admin.erl
-{"Add New", "Adicionar novo"}.
-{"Add User", "Adicionar usuário"}.
-{"All activity", "Toda la atividade"}.
-{"Change Password", "Mudar senha"}.
-{"Connected Resources:", "Recursos conectados:"}.
-{"Delete", "Eliminar"}.
-{"Delete Selected", "Remover os selecionados"}.
-{"ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One", "ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One"}.
-{"ejabberd virtual hosts", "Maquinas virtuais de ejabberd"}.
-{"From", "De"}.
-{"Group ", "Grupo "}.
-{"Groups", "Grupos"}.
-{"Host", "Máquina"}.
-{"Last Activity", "Última atividade"}.
-{"Last month", "Último mês"}.
-{"Last year", "Último ano"}.
-{"Listened Ports at ", "Portas de escuta em "}.
-{"Members:", "Miembros:"}.
-{"Memory", "Memória"}.
-{"Module", "Módulo"}.
-{"Modules at ", "Módulos em "}.
-{"Name:", "Nome:"}.
-{"Name", "Nome"}.
-{"Never", "Nunca"}.
-{"Nickname", "Apelido"}.
-{"Online", "Conectado"}.
-{"Options", "Opções"}.
-{"Packet", "Pacote"}.
-{"Password:", "Senha:"}.
-{"Pending", "Pendente"}.
-{"Period: ", "Período: "}.
-{"Port", "Porta"}.
-{"Remove", "Borrar"}.
-{"Restart", "Reiniciar"}.
-{"Roster", "Lista de contatos"}.
-{"Roster of ", "Lista de contatos de "}.
-{"~s access rule configuration", "Configuração da Regra de Acesso ~s"}.
-{"Shared Roster", "Lista de contatos compartilhada"}.
-{"Show Integral Table", "Mostrar Tabela Integral"}.
-{"Show Ordinary Table", "Mostrar Tabela Ordinária"}.
-{"Size", "Tamanho"}.
-{"Start", "Iniciar"}.
-{"Statistics", "Estatísticas"}.
-{"Stop", "Parar"}.
-{"Storage Type", "Tipo de armazenamento"}.
-{"Submit", "Enviar"}.
-{"Subscription", "Subscrição"}.
-{"Time", "Fecha"}.
-{"To", "Para"}.
-
-{"Update", "Atualizar"}.
-{"Users", "Usuários"}.
-{"User ", "Usuário"}.
-{"Validate", "Validar"}.
-{"Virtual Hosts", "Maquinas Virtuais"}.
-
-% ejabberd_c2s.erl
-{"Use of STARTTLS required", "É obrigatório usar STARTTLS"}.
-
-
-% mod_vcard_ldap.erl
-{"Fill in fields to search for any matching Jabber User", "Preencha campos para buscar usuários Jabber que concordem"}.
-
-
-
-% mod_adhoc.erl
-{"Commands", "Comandos"}.
-{"Ping", "Ping"}.
-{"Pong", "Pong"}.
-
-% mod_vcard_odbc.erl
-{"Email", "e-mail"}.
-{"Search Results for ", "Resultados de pesquisa para"}.
-{"Jabber ID", "ID Jabber"}.
-
-% ejabberd_c2s.erl
-{"Replaced by new connection", "Substituído por nova conexão"}.
-
-% mod_announce.erl
-{"Really delete message of the day?", "Deletar realmente a mensagem do dia?"}.
-{"Subject", "Assunto"}.
-{"Message body", "Corpo da mensagem"}.
-{"No body provided for announce message", "Nenhum corpo de texto fornecido para anunciar mensagem"}.
-{"Announcements", "Anúncios"}.
-{"Send announcement to all users", "Enviar anúncio a todos os usuários"}.
-{"Send announcement to all online users", "Enviar anúncio a todos os usuárions online"}.
-{"Send announcement to all online users on all hosts", "Enviar anúncio a todos usuários online em todas as máquinas"}.
-{"Set message of the day and send to online users", "Definir mensagem do dia e enviar a todos usuários online"}.
-{"Update message of the day (don't send)", "Atualizar mensagem do dia (não enviar)"}.
-{"Delete message of the day", "Apagar mensagem do dia"}.
-
-% mod_configure.erl
-{"Database", "Base de dados"}.
-{"Host Name", "Nome da máquina"}.
-{"Outgoing s2s Connections", "Conexões que partam de s2s"}.
-{"Import Users From jabberd 1.4 Spool Files", "Importar usuários de arquivos jabberd 1.4"}.
-{"Database Tables Configuration at ", "Configuração de Tabelas de Base de dados em "}.
-{"Stop Modules at ", "Parar módulos em "}.
-{"List of modules to start", "Listas de módulos para inicializar"}.
-{"Hostname Configuration", "Configuração do Hostname"}.
-{"Choose host name", "Definir nome da máquina"}.
-{"Host name", "Nome da máquina"}.
-
-% mod_pubsub/mod_pubsub.erl
-
-% web/ejabberd_web_admin.erl
-{"ejabberd Web Interface", "Interface Web do ejabberd"}.
-{"Administration", "Administração"}.
-{"Nodes", "Nós"}.
-{"(Raw)", "(Intocado)"}.
-{"Submitted", "Submetido"}.
-{"Bad format", "Formato incorreto"}.
-{"Raw", "Intocado"}.
-{"Users Last Activity", "Ultimas atividades dos usuários"}.
-{"Node not found", "Nó não encontrado"}.
-{"Registered Users", "Usuários Registrados"}.
-{"Offline Messages", "Mensagens offline"}.
-{"Registered Users:", "Usuários registrados"}.
-{"Authenticated Users:", "Usuários Autenticados"}.
-{"Online Users:", "Usuários online"}.
-{"Outgoing s2s Connections:", "Conexões que partem de s2s"}.
-{"Outgoing s2s Servers:", "Servidores que partem de s2s"}.
-{"None", "Nenhum"}.
-{"Offline Messages:", "Mensagens offline"}.
-{"~s's Offline Messages Queue", "~s's Fila de Mensagens Offline"}.
-{"Add Jabber ID", "Adicionar ID jabber"}.
-{"No Data", "Nenhum dado"}.
-{"Node ", "Nó"}.
-{"Listened Ports", "Portas escutadas"}.
-{"RPC Call Error", "Erro de chamada RPC"}.
-{"Database Tables at ", "Tabelas de base de dados em"}.
-{"Backup of ", "Backup de"}.
-{"Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.", "Observe que tais opções farão backup apenas da base de dados Mnesia. Caso você esteja utilizando o modulo ODBC, você precisará fazer backup de sua base de dados SQL separadamente."}.
-{"Store binary backup:", "Armazenar backup binário:"}.
-{"OK", "OK"}.
-{"Restore binary backup immediately:", "Restaurar backup binário imediatamente"}.
-{"Restore binary backup after next ejabberd restart (requires less memory):", "Restaurar backup binário após próximo reinicialização do ejabberd (requer menos memória):"}.
-{"Store plain text backup:", "Armazenar backup plain text"}.
-{"Restore plain text backup immediately:", "Restaurar backup plain text imediatamente:"}.
-{"Statistics of ~p", "Estatísticas de ~p"}.
-{"Uptime:", "Uptime:"}.
-{"CPU Time:", "Tempo de CPU"}.
-{"Transactions Commited:", "Transações:"}.
-{"Transactions Aborted:", "Transações abortadas:"}.
-{"Transactions Restarted:", "Transações restauradas:"}.
-{"Transactions Logged:", "Transações de log:"}.
-{"Update ", "Atualizar"}.
-{"Update plan", "Plano de Atualização"}.
-{"Updated modules", "Módulos atualizados"}.
-{"Update script", "Script de atualização"}.
-{"Low level update script", "Script de atualização low level"}.
-{"Script check", "Verificação de Script"}.
-{"Not Found", "Não encontrado"}.
-{"Shared Roster Groups", "Grupos Shared Roster"}.
-{"Description:", "Descrição:"}.
-{"Displayed Groups:", "Grupos Indicados"}.
-
-% mod_muc/mod_muc_log.erl
-{"Chatroom configuration modified", "Configuração da sala de bate-papo modificada"}.
-{"joins the room", "Entrar na sala"}.
-{"leaves the room", "Sair da sala"}.
-{"has been kicked", "foi removido"}.
-{"has been banned", "foi banido"}.
-{"is now known as", ""}.
-{"Monday", "Segunda"}.
-{"Tuesday", "Terça"}.
-{"Wednesday", "Quarta"}.
-{"Thursday", "Quinta"}.
-{"Friday", "Sexta"}.
-{"Saturday", "Sábado"}.
-{"Sunday", "Domingo"}.
-{"January", "Janeiro"}.
-{"February", "Fevereiro"}.
-{"March", "Março"}.
-{"April", "Abril"}.
-{"May", "Maio"}.
-{"June", "Junho"}.
-{"July", "Julho"}.
-{"August", "Agosto"}.
-{"September", "Setembro"}.
-{"October", "Outubro"}.
-{"November", "Novembro"}.
-{"December", "Dezembro"}.
-{"Room Configuration", "Configuração de salas"}.
-
-% mod_muc/mod_muc.erl
-{"Only service administrators are allowed to send service messages", "Apenas administradores possuem permissão para enviar mensagens de serviço"}.
-{"You must fill in field \"Nickname\" in the form", "Você deve completar o campo \"Apelido\" no formulário"}.
-
-% mod_muc/mod_muc_room.erl
-{"This room is not anonymous", "Essa sala não é anônima"}.
-{"Make room persistent", "Tornar sala persistente"}.
-{"Make room public searchable", "Tornar sala pública possível de ser encontrada"}.
-{"Make participants list public", "Tornar pública a lista de participantes"}.
-{"Make room password protected", "Tornar protegida a senha da sala"}.
-{"Make room members-only", "Tornar sala apenas para membros"}.
-{"Make room moderated", "Tornar a sala moderada"}.
-{"Default users as participants", "Usuários padrões como participantes"}.
-{"Allow users to change subject", "Permitir a usuários modificar o assunto"}.
-{"Allow users to send private messages", "Permitir a usuários enviarem mensagens privadas"}.
-{"Allow users to query other users", "Permitir a usuários pesquisar informações sobre os demais"}.
-{"Allow users to send invites", "Permitir a usuários envio de convites"}.
-{"Enable logging", "Permitir criação de logs"}.
-{"Description", "Descrição"}.
-{"Number of occupants", "Número de participantes"}.
-{"Present real JIDs to", "Tornar o JID real visível por"}.
-{"moderators only", "apenas moderadores"}.
-{"anyone", "qualquer um"}.
-{"is now known as", "é agora conhecido como"}.
-
-% Local Variables:
-% mode: erlang
-% End:
diff --git a/ejabberd-1.1.2/src/msgs/pt.msg b/ejabberd-1.1.2/src/msgs/pt.msg
deleted file mode 100644
index 357e51230..000000000
--- a/ejabberd-1.1.2/src/msgs/pt.msg
+++ /dev/null
@@ -1,243 +0,0 @@
-% $Id$
-
-% ejabberd - Portuguese
-
-% jlib.hrl
-{"No resource provided", "Não foi passado nenhum recurso"}.
-
-% mod_configure.erl
-{"DB Tables Configuration at ", "Configuração de tabelas da BD em "}.
-{"Choose storage type of tables", "Seleccione o tipo de armazenagem das tabelas"}.
-{"RAM copy", "Cópia em RAM"}.
-{"RAM and disc copy", "Cópia em RAM e em disco"}.
-{"Disc only copy", "Cópia apenas em disco"}.
-{"Remote copy", "Cópia remota"}.
-{"Stop Modules at ", "Parar módulos em "}.
-{"Choose modules to stop", "Seleccione os módulos a parar"}.
-{"Start Modules at ", "Iniciar os módulos em "}.
-{"Enter list of {Module, [Options]}", "Introduza lista de {módulos, [opções]}"}.
-{"List of modules to start", "Lista de módulos a iniciar"}.
-{"Backup to File at ", "Guardar cópia de segurança para ficheiro em "}.
-{"Enter path to backup file", "Introduza o caminho do ficheiro de cópia de segurança"}.
-{"Path to File", "Caminho do ficheiro"}.
-{"Restore Backup from File at ", "Restaura cópia de segurança a partir do ficheiro em "}.
-{"Dump Backup to Text File at ", "Exporta cópia de segurança para ficheiro de texto em "}.
-{"Enter path to text file", "Introduza caminho para o ficheiro de texto"}.
-{"Import User from File at ", "Importar utilizador a partir do ficheiro em "}.
-{"Enter path to jabberd1.4 spool file", "Introduza o caminho para o ficheiro de spool do jabberd1.4"}.
-{"Import Users from Dir at ", "Importar utilizadores a partir do directório em "}.
-{"Enter path to jabberd1.4 spool dir", "Introduza o caminho para o directório de spools do jabberd1.4"}.
-{"Path to Dir", "Caminho para o directório"}.
-{"Hostname Configuration", "Configuração do nome do servidor"}.
-{"Choose host name", "Introduza o nome do servidor"}.
-{"Host name", "Nome do servidor"}.
-{"Access Control List Configuration", "Configuração da Lista de Controlo de Acesso"}.
-{"Access control lists", "Listas de Controlo de Acesso"}.
-{"Access Configuration", "Configuração de acessos"}.
-{"Access rules", "Regras de acesso"}.
-{"Remove Users", "Eliminar utilizadores"}.
-{"Choose users to remove", "Seleccione utilizadores a eliminar"}.
-{"Administration of ", "Administração de "}.
-{"Action on user", "Acção no utilizador"}.
-{"Edit Properties", "Editar propriedades"}.
-{"Remove User", "Eliminar utilizador"}.
-
-% mod_disco.erl
-{"Configuration", "Configuração"}.
-{"Online Users", "Utilizadores ligados"}.
-{"All Users", "Todos os utilizadores"}.
-{"Outgoing S2S connections", "Conexões S2S para fora"}.
-{"To ~s", "A ~s"}.
-{"From ~s", "De ~s"}.
-{"Running Nodes", "Nodos a correr"}.
-{"Stopped Nodes", "Nodos parados"}.
-{"Host Name", "Nome do servidor"}.
-{"Access Control Lists", "Listas de Controlo de Acesso"}.
-{"Access Rules", "Regras de Acesso"}.
-{"Remove Users", "Eliminar utilizadores"}.
-{"DB", "BD"}.
-{"Modules", "Módulos"}.
-{"Start Modules", "Iniciar módulos"}.
-{"Stop Modules", "Parar módulos"}.
-{"Backup Management", "Gestão de cópias de segurança"}.
-{"Import users from jabberd1.4 spool files", "Importar utilizadores a partir de ficheiros da spool do jabberd1.4"}.
-{"Backup", "Guardar cópia de segurança"}.
-{"Restore", "Restaurar"}.
-{"Dump to Text File", "Exportar para ficheiro de texto"}.
-{"Import File", "Importar ficheiro"}.
-{"Import Directory", "Importar directório"}.
-
-% mod_register.erl
-{"Choose a username and password to register with this server", "Escolha um nome de utilizador e palavra-chave para se registar neste servidor"}.
-
-% mod_vcard.erl
-{"Erlang Jabber Server\nCopyright (c) 2002-2005 Alexey Shchepin", "Servidor Jabber em Erlang\nCopyright (c) 2002-2005 Alexey Shchepin"}.
-{"ejabberd vCard module\nCopyright (c) 2003-2005 Alexey Shchepin", "Módulo vCard de ejabberd\nCopyright (c) 2003-2005 Alexey Shchepin"}.
-{"You need an x:data capable client to search", "É necessário um cliente com suporte de x:data para poder procurar"}.
-{"Search users in ", "Procurar utilizadores em "}.
-{"Fill in fields to search for any matching Jabber User", "Preencha os campos para procurar utilizadores Jabber coincidentes"}.
-{"Results of search in ", "Resultados da procura em "}.
-
-{"User", "Utilizador"}.
-{"Full Name", "Nome completo"}.
-{"Name", "Nome"}.
-{"Middle Name", "Segundo nome"}.
-{"Family Name", "Apelido"}.
-{"Nickname", "Alcunha"}.
-{"Birthday", "Data de nascimento"}.
-{"Country", "País"}.
-{"City", "Cidade"}.
-{"email", "email"}.
-{"Organization Name", "Nome da organização"}.
-{"Organization Unit", "Unidade da organização"}.
-
-% mod_pubsub/mod_pubsub.erl
-{"ejabberd pub/sub module\nCopyright (c) 2003-2005 Alexey Shchepin", "Módulo pub/sub de ejabberd\nCopyright (c) 2003-2005 Alexey Shchepin"}.
-
-% mod_muc/mod_muc.erl
-{"You need an x:data capable client to register nickname", "É necessário um cliente com suporte de x:data para poder registar a alcunha"}.
-{"Nickname Registration at ", "Registo da alcunha em "}.
-{"Enter nickname you want to register", "Introduza a alcunha que quer registar"}.
-{"ejabberd MUC module\nCopyright (c) 2003-2005 Alexey Shchepin", "Módulo MUC de ejabberd\nCopyright (c) 2003-2005 Alexey Shchepin"}.
-{"Only service administrators are allowed to send service messages", "Só os administradores do serviço têm permissão para enviar mensagens de serviço"}.
-{"Conference room does not exist", "A sala não existe"}.
-{"Access denied by service policy", "Acesso negado pela política de serviço"}.
-{"You must fill in field \"nick\" in the form", "Deve preencher o campo \"alcunha\" no formulário"}.
-{"Specified nickname is already registered", "A alcunha especificada já está registada"}.
-
-% mod_muc/mod_muc_room.erl
-{" has set the subject to: ", " colocou o tópico: "}.
-{"You need an x:data capable client to configure room", "É necessário um cliente com suporte de x:data para configurar a sala"}.
-{"Configuration for ", "Configuração para "}.
-{"Room title", "Título da sala"}.
-{"Allow users to change subject?", "Permitir aos utilizadores mudar o tópico?"}.
-{"Allow users to query other users?", "Permitir aos utilizadores consultar outros utilizadores?"}.
-{"Allow users to send private messages?", "Permitir que os utilizadores enviem mensagens privadas?"}.
-{"Make room public searchable?", "Tornar a sala publicamente visível?"}.
-{"Make participants list public?", "Tornar pública a lista de participantes?"}.
-{"Make room persistent?", "Tornar a sala permanente?"}.
-{"Make room moderated?", "Tornar a sala moderada?"}.
-{"Default users as members?", "Os utilizadores são membros por omissão?"}.
-{"Make room members only?", "Tornar a sala exclusiva a membros?"}.
-{"Allow users to send invites?", "Permitir que os utilizadores enviem convites?"}.
-{"Make room password protected?", "Proteger a sala com palavra-chave?"}.
-{"Password", "Palavra-chave"}.
-{"Make room anonymous?", "Tornar a sala anónima?"}.
-{"Enable logging?", "Guardar históricos?"}.
-{"Only moderators and participants are allowed to change subject in this room", "Só os moderadores e os participantes podem mudar o tópico desta sala"}.
-{"Only moderators are allowed to change subject in this room", "Só os moderadores podem mudar o tópico desta sala"}.
-{"Visitors are not allowed to send messages to all occupants", "Os visitantes não podem enviar mensagens para todos os ocupantes"}.
-{"Only occupants are allowed to send messages to the conference", "Só os ocupantes podem enviar mensagens para a sala"}.
-{"It is not allowed to send normal messages to the conference", "Impedir o envio de mensagens normais para a sala"}.
-{"It is not allowed to send private messages to the conference", "Impedir o envio de mensagens privadas para a sala"}.
-{"Improper message type", "Tipo de mensagem incorrecto"}.
-{"Nickname is already in use by another occupant", "A alcunha já está a ser usado por outro ocupante"}.
-{"Nickname is registered by another person", "A alcunha já está registada por outra pessoa"}.
-{"It is not allowed to send private messages of type \"groupchat\"", "Não é permitido enviar mensagens privadas do tipo \"groupchat\""}.
-{"Recipient is not in the conference room", "O destinatário não está na sala"}.
-{"Only occupants are allowed to send queries to the conference", "Só os ocupantes podem enviar consultas para a sala"}.
-{"Queries to the conference members are not allowed in this room", "Nesta sala não são permitidas consultas aos seus membros"}.
-{"You have been banned from this room", "Foi banido desta sala"}.
-{"Membership required to enter this room", "É necessário ser membro desta sala para poder entrar"}.
-{"Password required to enter this room", "É necessária a palavra-chave para poder entrar nesta sala"}.
-{"Incorrect password", "Palavra-chave incorrecta"}.
-{"Administrator privileges required", "São necessários privilégios de administrador"}.
-{"Moderator privileges required", "São necessários privilégios de moderador"}.
-{"JID ~s is invalid", "O JID ~s não é válido"}.
-{"Nickname ~s does not exist in the room", "A alcunha ~s não existe na sala"}.
-{"Invalid affiliation: ~s", "Afiliação inválida: ~s"}.
-{"Invalid role: ~s", "Papel inválido: ~s"}.
-{"Owner privileges required", "São necessários privilégios de dono"}.
-{"private, ", "privado"}.
-
-% mod_irc/mod_irc.erl
-{"ejabberd IRC module\nCopyright (c) 2003-2005 Alexey Shchepin", "Módulo de IRC ejabberd\nCopyright (c) 2003-2005 Alexey Shchepin"}.
-{"You need an x:data capable client to configure mod_irc settings", "É necessário um cliente com suporte de x:data para configurar as opções do mod_irc"}.
-{"Registration in mod_irc for ", "Registo no mod_irc para"}.
-{"Enter username and encodings you wish to use for connecting to IRC servers", "Introduza o nome de utilizador e codificações de caracteres que quer usar ao conectar-se aos servidores de IRC"}.
-{"IRC Username", "Nome do utilizador de IRC"}.
-{"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.", "Se deseja especificar codificações de caracteres diferentes para cada servidor IRC preencha esta lista con valores no formato '{\"servidor irc\", \"codificação\"}'. Este serviço usa por omissão a codificação \"~s\"."}.
-{"Encodings", "Codificações"}.
-
-% web/ejabberd_web_admin.erl
-{"ejabberd administration", "Administração do ejabberd"}.
-{"Users", "Utilizadores"}.
-{"Nodes", "Nodos"}.
-{"Statistics", "Estatísticas"}.
-{"(raw)", "(modo texto)"}.
-{"submitted", "enviado"}.
-{"bad format", "formato inválido"}.
-{"raw", "modo texto"}.
-{"ejabberd access control lists configuration", "Configuração das Listas de Controlo de Acesso do ejabberd"}.
-{"Delete Selected", "Eliminar os seleccionados"}.
-{"Submit", "Enviar"}.
-{"ejabberd access rules configuration", "Configuração das Regras de Acesso do ejabberd"}.
-{"~s access rule configuration", "Configuração das Regra de Acesso ~s"}.
-{"ejabberd users", "Utilizadores do ejabberd"}.
-{"ejabberd stats", "Estatísticas do ejabberd"}.
-{"Node not found", "Nodo não encontrado"}.
-{"Add New", "Adicionar novo"}.
-{"Registered users", "Utilizadores registados"}.
-{"Online users", "Utilizadores ligados"}.
-{"Outgoing S2S servers", "Servidores S2S de saída"}.
-{"Change Password", "Mudar palavra-chave"}.
-{"Connected Resources:", "Recursos conectados:"}.
-{"Password:", "Palavra-chave:"}.
-{"None", "Nenhum"}.
-{"Node ", "Nodo"}.
-{"DB Management", "Gestão da BD"}.
-{"Listened Ports Management", "Gestão das portas em escuta"}.
-{"Restart", "Reiniciar"}.
-{"Stop", "Parar"}.
-{"RPC call error", "Erro na chamada RPC"}.
-{"DB Tables at ", "Tabelas da BD em "}.
-{"Name", "Nome"}.
-{"Storage Type", "Tipo de armazenagem"}.
-{"Size", "Tamanho"}.
-{"Memory", "Memória"}.
-{"Backup Management at ", "Gestão da cópia de segurança em "}.
-{"Store a backup in a file", "Armazenar uma cópia de segurança no ficheiro"}.
-{"OK", "OK"}.
-{"Restore a backup from a file", "Recuperar uma cópia de segurança a partir de ficheiro"}.
-{"Install a database fallback from a file", "Instalar uma recuperação de BD desde um ficheiro"}.
-{"Dump a database in a text file", "Exportar uma Base de Dados para um ficheiro de texto"}.
-{"Restore a database from a text file", "Restaurar uma Base de Dados a partir de ficheiro de texto"}.
-{"Listened Ports at ", "Portas em escuta em "}.
-{"~p statistics", "Estatísticas de ~p"}.
-{"Uptime", "Tempo de funcionamento"}.
-{"CPU Time", "Tempo de processador consumido"}.
-{"Transactions commited", "Transacções realizadas"}.
-{"Transactions aborted", "Transacções abortadas"}.
-{"Transactions restarted", "Transacções reiniciadas"}.
-{"Transactions logged", "Transacções armazenadas"}.
-{"Port", "Porta"}.
-{"Module", "Módulo"}.
-{"Options", "Opções"}.
-{"Update", "Actualizar"}.
-{"Delete", "Eliminar"}.
-{"Add User", "Adicionar utilizador"}.
-{"ejabberd (c) 2002-2005 Alexey Shchepin, 2005 Process One", "ejabberd (c) 2002-2005 Alexey Shchepin, 2005 Process One"}.
-{"Offline messages", "Mensagens diferidas"}.
-{"Last Activity", "Última actividade"}.
-{"Online", "Ligado"}.
-{"Never", "Nunca"}.
-{"~s offline messages queue", "~s fila de mensagens diferidas"}.
-{"Time", "Data"}.
-{"From", "De"}.
-{"To", "Para"}.
-{"Packet", "Pacote"}.
-{"Offline messages:", "Mensagens diferidas:"}.
-{"Roster", "Lista de contactos"}.
-{"Nickname", "Alcunha"}.
-{"Subscription", "Subscrição"}.
-{"Pending", "Pendente"}.
-{"Groups", "Grupos"}.
-{"Remove", "Remover"}.
-{"Add JID", "Adicionar JID"}.
-{"User ", "Utilizador"}.
-{"Roster of ", "Lista de contactos de "}.
-{"Shared Roster", "Lista de contactos partilhada"}.
-
-% Local Variables:
-% mode: erlang
-% End:
diff --git a/ejabberd-1.1.2/src/msgs/ru.msg b/ejabberd-1.1.2/src/msgs/ru.msg
deleted file mode 100644
index d8a877816..000000000
--- a/ejabberd-1.1.2/src/msgs/ru.msg
+++ /dev/null
@@ -1,377 +0,0 @@
-% $Id$
-
-% ejabberd_c2s.erl
-{"Use of STARTTLS required", "Вы обязаны использовать STARTTLS"}.
-{"Replaced by new connection", "Заменено новым соединением"}.
-
-% jlib.hrl
-{"No resource provided", "Не указан ресурс"}.
-{"Illegal resource format", "Неправильный формат ресурса"}.
-{"Resource conflict", "Конфликт ресурсов"}.
-
-% mod_adhoc.erl
-{"Commands", "Команды"}.
-{"Ping", "Пинг"}.
-{"Pong", "Понг"}.
-
-% mod_announce.erl
-{"Really delete message of the day?", "Действительно удалить сообщение дня?"}.
-{"Subject", "Тема"}.
-{"Message body", "Тело сообщения"}.
-{"No body provided for announce message", "Тело объявления не должно быть пустым"}.
-{"Announcements", "Объявления"}.
-{"Send announcement to all users", "Разослать объявление всем пользователям"}.
-{"Send announcement to all online users", "Разослать объявление всем подключённым пользователям"}.
-{"Send announcement to all online users on all hosts",
- "Разослать объявление всем подключённым пользователям на всех виртуальных серверах"}.
-{"Set message of the day and send to online users",
- "Установить сообщение дня и разослать его подключённым пользователям"}.
-{"Update message of the day (don't send)", "Обновить сообщение дня (не рассылать)"}.
-{"Delete message of the day", "Удалить сообщение дня"}.
-
-% mod_configure.erl
-{"Database Tables Configuration at ", "Конфигурация таблиц базы данных на "}.
-{"Choose storage type of tables", "Выберите тип хранения таблиц"}.
-{"RAM copy", "ОЗУ"}.
-{"RAM and disc copy", "ОЗУ и диск"}.
-{"Disc only copy", "только диск"}.
-{"Remote copy", "не хранится локально"}.
-{"Stop Modules at ", "Остановка модулей на "}.
-{"Choose modules to stop", "Выберите модули, которые следует остановить"}.
-{"Start Modules at ", "Запуск модулей на "}.
-{"Enter list of {Module, [Options]}", "Введите список вида {Module, [Options]}"}.
-{"List of modules to start", "Список запускаемых модулей"}.
-{"Backup to File at ", "Резервное копирование в файл на "}.
-{"Enter path to backup file", "Введите путь к резервному файлу"}.
-{"Path to File", "Путь к файлу"}.
-{"Restore Backup from File at ", "Восстановление из резервной копии на "}.
-{"Dump Backup to Text File at ", "Копирование в текстовый файл на "}.
-{"Enter path to text file", "Введите путь к текстовому файлу"}.
-{"Import User from File at ", "Импорт пользователя из файла на "}.
-{"Enter path to jabberd1.4 spool file", "Введите путь к файлу из спула jabberd1.4"}.
-{"Import Users from Dir at ", "Импорт пользователей из директории на "}.
-{"Enter path to jabberd1.4 spool dir", "Введите путь к директории спула jabberd1.4"}.
-{"Path to Dir", "Путь к директории"}.
-{"Hostname Configuration", "Конфигурация имени хоста"}.
-{"Choose host name", "Выберите имя хоста"}.
-{"Host name", "Имя хоста"}.
-{"Access Control List Configuration", "Конфигурация списков управления доступом"}.
-{"Access control lists", "Списки управления доступом"}.
-{"Access Configuration", "Конфигурация доступа"}.
-{"Access rules", "Правила доступа"}.
-{"Remove Users", "Удаление пользователей"}.
-{"Choose users to remove", "Выберите пользователей, которых следует удалить"}.
-{"Administration of ", "Администрирование "}.
-{"Action on user", "Действие над пользователем"}.
-{"Edit Properties", "Изменить параметры"}.
-{"Remove User", "Удалить пользователя"}.
-
-% mod_disco.erl
-{"Configuration", "Конфигурация"}.
-{"Online Users", "Подключённые пользователи"}.
-{"All Users", "Все пользователи"}.
-{"Outgoing s2s Connections", "Исходящие s2s-соединения"}.
-{"To ~s", "К ~s"}.
-{"From ~s", "От ~s"}.
-{"Running Nodes", "Работающие узлы"}.
-{"Stopped Nodes", "Остановленные узлы"}.
-{"Host Name", "Имя хоста"}.
-{"Access Control Lists", "Списки управления доступом"}.
-{"Access Rules", "Правила доступа"}.
-{"Remove Users", "Удаление пользователей"}.
-{"Database", "База данных"}.
-{"Modules", "Модули"}.
-{"Start Modules", "Запуск модулей"}.
-{"Stop Modules", "Остановка модулей"}.
-{"Backup Management", "Управление резервным копированием"}.
-{"Import Users From jabberd 1.4 Spool Files", "Импорт пользователей из спула jabberd 1.4"}.
-{"Backup", "Резервное копирование"}.
-{"Restore", "Восстановление из резервной копии"}.
-{"Dump to Text File", "Копирование в текстовый файл"}.
-{"Import File", "Импорт из файла"}.
-{"Import Directory", "Импорт из директории"}.
-
-% mod_register.erl
-{"Choose a username and password to register with this server",
- "Выберите имя пользователя и пароль для регистрации на этом сервере"}.
-
-% mod_vcard.erl
-{"Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin",
- "Erlang Jabber Server\nCopyright (c) 2002-2006 Алексей Щепин"}.
-{"ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin",
- "ejabberd vCard модуль\nCopyright (c) 2003-2006 Алексей Щепин"}.
-{"You need an x:data capable client to search",
- "Чтобы воспользоваться поиском, требуется x:data-совместимый клиент"}.
-{"Search users in ", "Поиск пользователей в "}.
-{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)",
-"Заполните форму для поиска пользователя Jabber (Если добавить * в конец поля, то происходит поиск подстроки)"}.
-{"Search Results for ", "Результаты поиска в "}.
-{"Jabber ID", "Jabber ID"}.
-{"User", "Пользователь"}.
-{"Full Name", "Полное имя"}.
-{"Name", "Имя"}.
-{"Middle Name", "Отчество"}.
-{"Family Name", "Фамилия"}.
-{"Nickname", "Псевдоним"}.
-{"Birthday", "День рождения"}.
-{"Country", "Страна"}.
-{"City", "Город"}.
-{"Email", "Электронная почта"}.
-{"Organization Name", "Название организации"}.
-{"Organization Unit", "Отдел организации"}.
-
-% mod_vcard_ldap.erl
-{"Fill in fields to search for any matching Jabber User", "Заполните форму для поиска пользователя Jabber"}.
-{"Given Name", "Имя"}.
-
-% mod_pubsub/mod_pubsub.erl
-{"ejabberd pub/sub module\nCopyright (c) 2003-2006 Alexey Shchepin",
- "ejabberd pub/sub модуль\nCopyright (c) 2003-2006 Алексей Щепин"}.
-{"Node Creator", "Создатель сборника"}.
-{"Deliver payloads with event notifications", "Доставлять вместе с уведомлениями o публикациях сами публикации"}.
-{"Notify subscribers when the node configuration changes", "Уведомлять подписчиков об изменении конфигурации сборника"}.
-{"Notify subscribers when the node is deleted", "Уведомлять подписчиков об удалении сборника"}.
-{"Notify subscribers when items are removed from the node", "Уведомлять подписчиков об удалении публикаций из сборника"}.
-{"Persist items to storage", "Сохранять публикации в хранилище"}.
-{"Max # of items to persist", "Максимальное число сохраняемых публикаций"}.
-{"Whether to allow subscriptions", "Разрешить подписку"}.
-{"Specify the subscriber model", "Условия подписки"}.
-{"Specify the publisher model", "Условия публикации"}.
-{"Max payload size in bytes", "Максимальный размер полезной нагрузки в байтах"}.
-{"Send items to new subscribers", "Отправлять публикации новым подписчикам"}.
-{"Only deliver notifications to available users", "Доставлять уведомления только доступным пользователям"}.
-{"Specify the current subscription approver", "JID пользователя, утверждающего подписку"}.
-
-% mod_muc/mod_muc.erl
-{"You need an x:data capable client to register nickname",
- "Чтобы зарегистрировать псевдоним, требуется x:data-совместимый клиент"}.
-{"Nickname Registration at ", "Регистрация псевдонима на "}.
-{"Enter nickname you want to register", "Введите псевдоним, который Вы хотели бы зарегистрировать"}.
-{"ejabberd MUC module\nCopyright (c) 2003-2006 Alexey Shchepin",
- "ejabberd MUC модуль\nCopyright (c) 2003-2006 Алексей Щепин"}.
-{"Only service administrators are allowed to send service messages",
- "Только администратор службы может посылать служебные сообщения"}.
-{"Room creation is denied by service policy",
- "Cоздавать конференцию запрещено политикой службы"}.
-{"Conference room does not exist", "Конференция не существует"}.
-{"Access denied by service policy", "Доступ запрещён политикой службы"}.
-{"You must fill in field \"Nickname\" in the form",
- "Вы должны заполнить поле \"Псевдоним\" в форме"}.
-{"Specified nickname is already registered", "Указанный псевдоним уже зарегистрирован"}.
-
-% mod_muc/mod_muc_log.erl
-{"Chatroom configuration modified", "Конфигурация комнаты изменилась"}.
-{"joins the room", "вошёл(а) в комнату"}.
-{"leaves the room", "вышел(а) из комнаты"}.
-{"has been kicked", "выгнали из комнаты"}.
-{"has been banned", "запретили входить в комнату"}.
-{"is now known as", "изменил(а) имя на"}.
-{"Monday", "Понедельник"}.
-{"Tuesday", "Вторник"}.
-{"Wednesday", "Среда"}.
-{"Thursday", "Четверг"}.
-{"Friday", "Пятница"}.
-{"Saturday", "Суббота"}.
-{"Sunday", "Воскресенье"}.
-{"January", "января"}.
-{"February", "февраля"}.
-{"March", "марта"}.
-{"April", "апреля"}.
-{"May", "мая"}.
-{"June", "июня"}.
-{"July", "июля"}.
-{"August", "августа"}.
-{"September", "сентября"}.
-{"October", "октября"}.
-{"November", "ноября"}.
-{"December", "декабря"}.
-{"Room Configuration", "Конфигурация комнаты"}.
-
-% mod_muc/mod_muc_room.erl
-{"This room is not anonymous", "Эта комната не анонимная"}.
-{" has set the subject to: ", " установил(а) тему: "}.
-{"You need an x:data capable client to configure room",
- "Чтобы сконфигурировать комнату, требуется x:data-совместимый клиент"}.
-{"Configuration for ", "Конфигурация "}.
-{"Room title", "Название комнаты"}.
-{"Allow users to change subject", "Разрешить пользователям изменять тему"}.
-{"Allow users to query other users",
- "Разрешить iq-запросы к пользователям"}.
-{"Allow users to send private messages",
- "Разрешить приватные сообщения"}.
-{"Make room public searchable", "Сделать комнату видимой всем"}.
-{"Make participants list public", "Сделать список участников видимым всем"}.
-{"Make room persistent", "Сделать комнату постоянной"}.
-{"Make room moderated", "Сделать комнату модерируемой"}.
-{"Default users as participants",
- "Сделать пользователей участниками по умолчанию"}.
-{"Make room members-only",
- "Комната только для зарегистрированных участников"}.
-{"Allow users to send invites",
- "Разрешить пользователям посылать приглашения"}.
-{"Make room password protected", "Сделать комнату защищённой паролем"}.
-{"Password", "Пароль"}.
-{"Present real JIDs to", "Сделать реальные JID участников видимыми"}.
-{"moderators only", "только модераторам"}.
-{"anyone", "всем участникам"}.
-{"Enable logging", "Включить журналирование"}.
-{"Only moderators and participants are allowed to change subject in this room",
- "Только модераторы и участники могут изменять тему в этой комнате"}.
-{"Only moderators are allowed to change subject in this room",
- "Только модераторы могут изменять тему в этой комнате"}.
-{"Visitors are not allowed to send messages to all occupants",
- "Посетителям не разрешается посылать сообщения всем присутствующим"}.
-{"Only occupants are allowed to send messages to the conference",
- "Только присутствующим разрешается посылать сообщения в конференцию"}.
-{"It is not allowed to send normal messages to the conference",
- "Нельзя посылать обычные сообщения в конференцию"}.
-{"It is not allowed to send private messages to the conference",
- "Не разрешается посылать частные сообщения прямо в конференцию"}.
-{"Improper message type", "Неправильный тип сообщения"}.
-{"Nickname is already in use by another occupant", "Псевдоним занят кем-то из присутствующих"}.
-{"Nickname is registered by another person", "Псевдоним зарегистирован кем-то другим"}.
-{"It is not allowed to send private messages of type \"groupchat\"",
- "Нельзя посылать частные сообщения типа \"groupchat\""}.
-{"Recipient is not in the conference room", "Адресата нет в конференции"}.
-{"Only occupants are allowed to send queries to the conference",
- "Только присутствующим разрешается посылать запросы в конференцию"}.
-{"Queries to the conference members are not allowed in this room",
- "Запросы к пользователям в этой конференции запрещены"}.
-{"You have been banned from this room", "Вам запрещено входить в эту конференцию"}.
-{"Membership required to enter this room", "В эту конференцию могут входить только её члены"}.
-{"Password required to enter this room", "Чтобы войти в эту конференцию, нужен пароль"}.
-{"Incorrect password", "Неправильный пароль"}.
-{"Administrator privileges required", "Требуются права администратора"}.
-{"Moderator privileges required", "Требуются права модератора"}.
-{"JID ~s is invalid", "JID ~s недопустимый"}.
-{"Nickname ~s does not exist in the room", "Псевдоним ~s в комнате отсутствует"}.
-{"Invalid affiliation: ~s", "Недопустимый ранг: ~s"}.
-{"Invalid role: ~s", "Недопустимая роль: ~s"}.
-{"Owner privileges required", "Требуются права владельца"}.
-{"private, ", "приватная, "}.
-{"Description", "Описание"}.
-{"Number of occupants", "Число присутствующих"}.
-
-% mod_irc/mod_irc.erl
-{"ejabberd IRC module\nCopyright (c) 2003-2006 Alexey Shchepin",
- "ejabberd IRC модуль\nCopyright (c) 2003-2006 Алексей Щепин"}.
-{"You need an x:data capable client to configure mod_irc settings",
- "Чтобы настроить параметры mod_irc, требуется x:data-совместимый клиент"}.
-{"Registration in mod_irc for ", "Регистрация в mod_irc для "}.
-{"Enter username and encodings you wish to use for connecting to IRC servers",
- "Введите имя пользователя и кодировки, которые будут использоваться при подключении к IRC-серверам"}.
-{"IRC Username", "Имя пользователя IRC"}.
-{"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.", "Чтобы указать различные кодировки для разных серверов IRC, заполните список значениями в формате '{\"irc server\", \"encoding\"}'. По умолчанию эта служба использует кодировку \"~s\"."}.
-{"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].", "Примеры: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}]."}.
-{"Encodings", "Кодировки"}.
-
-% web/ejabberd_web_admin.erl
-{"ejabberd Web Interface", "Web-интерфейс ejabberd"}.
-{"Administration", "Администрирование"}.
-{"Users", "Пользователи"}.
-{"Nodes", "Узлы"}.
-{"Statistics", "Статистика"}.
-{"(Raw)", "(Необработанный формат)"}.
-{"Submitted", "Отправлено"}.
-{"Bad format", "Неправильный формат"}.
-{"Raw", "Необработанный формат"}.
-{"Delete Selected", "Удалить выделенные"}.
-{"Submit", "Отправить"}.
-{"~s access rule configuration", "Конфигурация правила доступа ~s"}.
-{"Node not found", "Узел не найден"}.
-{"Add New", "Добавить"}.
-{"Registered Users", "Зарегистрированные пользователи"}.
-{"Registered Users:", "Зарегистрированные пользователи:"}.
-{"Authenticated Users:", "Аутентифицированные пользователи:"}.
-{"Online Users", "Подключённые пользователи"}.
-{"Online Users:", "Подключённые пользователи:"}.
-{"Outgoing s2s Connections:", "Исходящие s2s-серверы:"}.
-{"Outgoing s2s Servers:", "Исходящие s2s-серверы:"}.
-{"Change Password", "Сменить пароль"}.
-{"Connected Resources:", "Подключённые ресурсы:"}.
-{"Password:", "Пароль:"}.
-{"None", "Нет"}.
-{"Node ", "Узел "}.
-{"Listened Ports", "Прослушиваемые порты"}.
-{"Restart", "Перезапустить"}.
-{"Stop", "Остановить"}.
-{"RPC Call Error", "Ошибка вызова RPC"}.
-{"Database Tables at ", "Таблицы базы данных на "}.
-{"Name", "Название"}.
-{"Storage Type", "Тип таблицы"}.
-{"Size", "Размер"}.
-{"Memory", "Память"}.
-{"Backup of ", "Резервное копирование "}.
-{"Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.", "Заметьте, что здесь производится резервное копирование только встроенной базы данных Mnesia. Если Вы также используете другое хранилище данных (например с помощью модуля ODBC), то его резервное копирование следует осуществлять отдельно."}.
-{"Store binary backup:", "Сохранить бинарную резервную копию:"}.
-{"OK", "Продолжить"}.
-{"Restore binary backup immediately:", "Восстановить из бинарной резервной копии немедленно:"}.
-{"Restore binary backup after next ejabberd restart (requires less memory):", "Восстановить из бинарной резервной копии при следующем запуске (требует меньше памяти):"}.
-{"Store plain text backup:", "Сохранить текстовую резервную копию:"}.
-{"Restore plain text backup immediately:", "Восстановить из текстовой резервной копии немедленно:"}.
-{"Listened Ports at ", "Прослушиваемые порты на "}.
-{"Statistics of ~p", "статистика узла ~p"}.
-{"Uptime:", "Время работы:"}.
-{"CPU Time:", "Процессорное время:"}.
-{"Transactions Commited:", "Транзакции завершенные:"}.
-{"Transactions Aborted:", "Транзакции отмененные:"}.
-{"Transactions Restarted:", "Транзакции перезапущенные:"}.
-{"Transactions Logged:", "Транзакции запротоколированные:"}.
-{"Update ", "Обновление "}.
-{"Update plan", "План обновления"}.
-{"Updated modules", "Обновлённые модули"}.
-{"Update script", "Сценарий обновления"}.
-{"Low level update script", "Низкоуровневый сценарий обновления"}.
-{"Script check", "Проверка сценария"}.
-{"Port", "Порт"}.
-{"Module", "Модуль"}.
-{"Options", "Параметры"}.
-{"Update", "Обновить"}.
-{"Delete", "Удалить"}.
-{"Add User", "Добавить пользователя"}.
-{"ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One", "ejabberd (c) 2002-2006 Алексей Щепин, 2004-2006 Process One"}.
-{"Offline Messages", "Офлайновые сообщения"}.
-{"Offline Messages:", "Офлайновые сообщения:"}.
-{"Last Activity", "Последнее подключение"}.
-{"Never", "Никогда"}.
-{"~s's Offline Messages Queue", "Oчередь офлайновых сообщений ~s"}.
-{"Time", "Время"}.
-{"From", "От кого"}.
-{"To", "Кому"}.
-{"Packet", "Пакет"}.
-{"Roster", "Ростер"}.
-{"Nickname", "Псевдоним"}.
-{"Subscription", "Подписка"}.
-{"Pending", "Ожидание"}.
-{"Groups", "Группы"}.
-{"Remove", "Удалить"}.
-{"Add Jabber ID", "Добавить Jabber ID"}.
-{"User ", "Пользователь "}.
-{"Roster of ", "Ростер пользователя "}.
-{"Shared Roster", "Общие контакты"}.
-{"Online", "Подключён"}.
-{"Validate", "Утвердить"}.
-{"Not Found", "Не найдено"}.
-{"Shared Roster Groups", "Группы общих контактов"}.
-{"Name:", "Название:"}.
-{"Description:", "Описание:"}.
-{"Members:", "Члены:"}.
-{"Displayed Groups:", "Видимые группы:"}.
-{"Group ", "Группа "}.
-{"Users Last Activity", "Статистика последнего подключения пользователей"}.
-{"Period: ", "Период"}.
-{"Last month", "За последний месяц"}.
-{"Last year", "За последний год"}.
-{"All activity", "Вся статистика"}.
-{"Show Ordinary Table", "Показать обычную таблицу"}.
-{"Show Integral Table", "Показать интегральную таблицу"}.
-{"Start", "Запустить"}.
-{"Modules at ", "Модули на "}.
-{"No Data", "Нет данных"}.
-{"Virtual Hosts", "Виртуальные хосты"}.
-{"ejabberd virtual hosts", "Виртуальные хосты ejabberd"}.
-{"Host", "Хост"}.
-
-% Local Variables:
-% mode: erlang
-% End:
diff --git a/ejabberd-1.1.2/src/msgs/sk.msg b/ejabberd-1.1.2/src/msgs/sk.msg
deleted file mode 100644
index fafad9b8d..000000000
--- a/ejabberd-1.1.2/src/msgs/sk.msg
+++ /dev/null
@@ -1,463 +0,0 @@
-% $Id$
-
-% jlib.hrl
-{"No resource provided", "Nebol poskytnutý žiadny zdroj"}.
-
-% mod_configure.erl
-{"Choose storage type of tables", "Vyberte typ úložiska pre tabuľky"}.
-{"RAM copy", "Kópia RAM"}.
-{"RAM and disc copy", "Kópia RAM a disku"}.
-{"Disc only copy", "Len kópia disku"}.
-{"Remote copy", "Vzdialená kópia"}.
-{"Stop Modules at ", "Zastaviť moduly na "}.
-{"Choose modules to stop", "Vyberte moduly, ktoré majú byť zastavené"}.
-{"Start Modules at ", "Spustiť moduly na "}.
-{"Enter list of {Module, [Options]}", "Vložte zoznam modulov {Modul, [Parametre]}"}.
-{"List of modules to start", "Zoznam modulov, ktoré majú byť spustené"}.
-{"Backup to File at ", "Záloha do súboru na "}.
-{"Enter path to backup file", "Zadajte cestu k súboru so zálohou"}.
-{"Path to File", "Cesta k súboru"}.
-{"Restore Backup from File at ", "Obnoviť zálohu zo súboru na "}.
-{"Dump Backup to Text File at ", "Uložiť zálohu do textového súboru na "}.
-{"Enter path to text file", "Zadajte cestu k textovému súboru"}.
-{"Import User from File at ", "Importovať používateľa zo súboru na "}.
-{"Enter path to jabberd1.4 spool file", "Zadajte cestu k spool súboru jabberd1.4"}.
-{"Import Users from Dir at ", "Importovať používateľov z adresára na "}.
-{"Enter path to jabberd1.4 spool dir", "Zadajte cestu k jabberd1.4 spool adresáru"}.
-{"Path to Dir", "Cesta k adresáru"}.
-{"Hostname Configuration", "Konfigurácia mena servera"}.
-{"Choose host name", "Vyberte meno servera"}.
-{"Host name", "Host name"}.
-{"Access Control List Configuration", "Konfigurácia zoznamu prístupových oprávnení (ACL)"}.
-{"Access control lists", "Zoznamy prístupových oprávnení (ACL)"}.
-{"Access Configuration", "Konfigurácia prístupu"}.
-{"Access rules", "Prístupové pravidlá"}.
-{"Remove Users", "Odstrániť používateľov"}.
-{"Choose users to remove", "Zvoliť používateľov, ktorí budú odstránení"}.
-{"Administration of ", "Administrácia "}.
-{"Action on user", "Operácia aplikovaná na používateľa"}.
-{"Edit Properties", "Editovať vlastnosti"}.
-{"Remove User", "Odstrániť používateľa"}.
-
-% mod_disco.erl
-{"Configuration", "Konfigurácia"}.
-{"Online Users", "Online používatelia"}.
-{"All Users", "Všetci používatelia"}.
-{"Outgoing S2S connections", "Odchádzajúce spojenie S2S"}.
-{"To ~s", "Pre ~s"}.
-{"From ~s", "Od ~s"}.
-{"Running Nodes", "Bežiace uzly"}.
-{"Stopped Nodes", "Zastavené uzly"}.
-{"Host Name", "Host name"}.
-{"Access Control Lists", "Zoznamy prístupových oprávnení (ACL)"}.
-{"Access Rules", "Prístupové pravidlá"}.
-{"Remove Users", "Odstrániť používateľov"}.
-{"DB", "DB"}.
-{"Modules", "Moduly"}.
-{"Start Modules", "Spustiť moduly"}.
-{"Stop Modules", "Zastaviť moduly"}.
-{"Backup Management", "Správa zálohovania"}.
-{"Import users from jabberd1.4 spool files", "Importovať používateľov z jabberd1.4 spool súborov"}.
-{"Backup", "Zálohovať"}.
-{"Restore", "Obnoviť"}.
-{"Dump to Text File", "Uložiť do textového súboru"}.
-{"Import File", "Import súboru"}.
-{"Import Directory", "Import adresára"}.
-
-% mod_register.erl
-{"Choose a username and password to register with this server",
- "Vybrať meno používateľa a heslo pre registráciu na tomto serveri"}.
-
-% mod_vcard.erl
-{"You need an x:data capable client to search",
- "Na vyhľadávanie potrebujete klienta podporujúceho x:data"}.
-{"Search users in ", "Hľadať používateľov v "}.
-{"Fill in fields to search for any matching Jabber User",
- "Vyplnte políčka pre vyhľadávanie Jabber používateľa"}.
-{"Results of search in ", "Výsledky vyhľadávania v "}.
-
-{"User", "Používateľ: "}.
-{"Full Name", "Celé meno: "}.
-{"Name", "Meno: "}.
-{"Middle Name", "Prostredné meno: "}.
-{"Family Name", "Priezvisko: "}.
-{"Nickname", "Prezývka: "}.
-{"Birthday", "Dátum narodenia: "}.
-{"Country", "Krajina: "}.
-{"City", "Mesto: "}.
-{"email", "E-mail: "}.
-{"Organization Name", "Meno organizácie: "}.
-{"Organization Unit", "Organizačná jednotka: "}.
-
-% mod_muc/mod_muc.erl
-{"You need an x:data capable client to register nickname",
- "Na registráciu prezývky potrebujete klienta podporujúceho z x:data"}.
-{"Nickname Registration at ", "Registrácia prezývky na "}.
-{"Enter nickname you want to register", "Zadajte prezývku, ktorú chete registrovať"}.
-{"Only service administrators are allowed to send service messages",
- "Iba správcovia služby majú povolené odosielanie servisných správ"}.
-{"Conference room does not exist", "Konferenčná miestnosť neexistuje"}.
-{"Access denied by service policy", "Prístup bol zamiestnutý nastavení služby"}.
-{"You must fill in field \"nick\" in the form", "Musíte vyplniť políčko \"prezývka\" vo formulári"}.
-{"Specified nickname is already registered", "Zadaná prezývka je už registrovaná"}.
-
-% mod_muc/mod_muc_room.erl
-{" has set the subject to: ", "zmiel(a) tému na: "}.
-{"You need an x:data capable client to configure room",
- "Na konfiguráciu miestnosti potrebujete klienta podporujúceho x:data"}.
-{"Configuration for ", "Konfigurácia pre "}.
-{"Room title", "Názov miestnosti"}.
-{"Allow users to change subject?", "Povoliť používateľom meniť tému?"}.
-{"Allow users to query other users?",
- "Povoliť používateľom odosielať požiadavky (query) ostatným používateľom?"}.
-{"Allow users to send private messages?",
- "Povoliť používateľom odosielať súkromné správy?"}.
-{"Make room public searchable?", "Nastaviť miestnosť ako verejne prehľadávateľnú?"}.
-{"Make participants list public?", "Nastaviť zoznam zúčastnených ako verejný?"}.
-{"Make room persistent?", "Nastaviť miestnosť ako trvalú (persistent)?"}.
-{"Make room moderated?", "Nastaviť miestnosť ako moderovanú?"}.
-{"Default users as members?",
- "Používatelia sú implicitne členmi?"}.
-{"Make room members only?",
- "Nastaviť miestnosť len pre členov?"}.
-{"Allow users to send invites?",
- "Povoliť používateľom odosielať pozvánky?"}.
-{"Make room password protected?", "Chrániť miestnosť heslom?"}.
-{"Password", "Heslo"}.
-{"Make room anonymous?", "Nastaviť miestnosť ako anonymnú?"}.
-{"Enable logging?", "Zapnúť zaznamenávanie histórie?"}.
-{"Only moderators and participants are allowed to change subject in this room",
- "Len moderátori a zúčastnený majú povolené meniť tému tejto miestnosti"}.
-{"Only moderators are allowed to change subject in this room",
- "Len moderátori majú povolené meniť tému miestnosti"}.
-{"Visitors are not allowed to send messages to all occupants",
- "Návštevníci nemajú povolené zasielať správy všetkým prihláseným do konferencie"}.
-{"Only occupants are allowed to send messages to the conference",
- "Len členovia majú povolené zasielať správy do konferencie"}.
-{"It is not allowed to send normal messages to the conference",
- "Nie je povolené odosielať normálne správy do konferencie"}.
-{"It is not allowed to send private messages to the conference",
- "Nie je povolené odosielať súkromné správy do konferencie"}.
-{"Improper message type", "Nesprávny typ správy"}.
-{"Nickname is already in use by another occupant", "Prezývka je už používaná iným členom"}.
-{"Nickname is registered by another person", "Prezývka je registrovaná inou osobou"}.
-{"It is not allowed to send private messages of type \"groupchat\"",
- "Nie je dovolené odoslanie súkromnej správy typu \"Skupinová správa\" "}.
-{"Recipient is not in the conference room", "Príjemca sa nenachádza v konferenčnej miestnosti"}.
-{"Only occupants are allowed to send queries to the conference",
- "Len členovia majú povolené odosielať požiadavky (query) do konferencie"}.
-{"Queries to the conference members are not allowed in this room",
- "Požiadavky (queries) na členov konferencie nie sú povolené v tejto miestnosti"}.
-{"You have been banned from this room", "Boli ste vylúčený z tejto miestnosti"}.
-{"Membership required to enter this room", "Pre vstup do miestnosti je potrebné byť členom"}.
-{"Password required to enter this room", "Pre vstup do miestnosti je potrebné heslo"}.
-{"Incorrect password", "Nesprávne heslo"}.
-{"Administrator privileges required", "Sú potrebné práva administrátora"}.
-{"Moderator privileges required", "Sú potrebné práva moderátora"}.
-{"JID ~s is invalid", "JID ~s je neplatné"}.
-{"Nickname ~s does not exist in the room", "Prezývka ~s v miestnosti neexistuje"}.
-{"Invalid affiliation: ~s", "Neplatné priradenie: ~s"}.
-{"Invalid role: ~s", "Neplatná rola: ~s"}.
-{"Owner privileges required", "Sú vyžadované práva vlastníka"}.
-{"private, ", "súkromná, "}.
-
-% mod_irc/mod_irc.erl
-{"You need an x:data capable client to configure mod_irc settings",
- "Pre konfiguráciu mod_irc potrebujete klienta podporujúceho x:data"}.
-{"Registration in mod_irc for ", "Registrácia do mod_irc na "}.
-{"Enter username and encodings you wish to use for connecting to IRC servers",
- "Vložte meno používateľa a kódovanie, ktoré chcete používať pri pripojení na IRC server"}.
-{"IRC Username", "IRC prezývka"}.
-{"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].",
- "Príklad: [{\"irc.freenode.net\",\"utf-8\"}, {\irc.freenode.net\", \"iso8859-2\"}]."}.
-{"Encodings", "Kódovania"}.
-
-% web/ejabberd_web_admin.erl
-{"ejabberd administration", "Administrácia Ejabberd"}.
-{"Users", "Používatelia"}.
-{"Nodes", "Uzly"}.
-{"Statistics", "Štatistiky"}.
-{"(raw)", "(raw)"}.
-{"submitted", "odoslané"}.
-{"bad format", "zlý formát"}.
-{"raw", "raw"}.
-{"ejabberd access control lists configuration", "Konfigurácia zoznamu prístupových oprávnení (ACL) Ejabberd"}.
-{"Delete Selected", "Zmazať vybrané"}.
-{"Submit", "Odoslať"}.
-{"ejabberd access rules configuration", "Konfigurácia prístupových pravidiel Ejabberd"}.
-{"~s access rule configuration", "~s konfigurácia prístupového pravidla"}.
-{"ejabberd users", "Používatelia Ejabberd"}.
-{"ejabberd stats", "Štatistiky Ejabberd"}.
-{"Node not found", "Uzol nenájdený"}.
-{"Add New", "Pridať nový"}.
-{"Registered users", "Registrovaní používatelia"}.
-{"Online users", "Online používatelia"}.
-{"Outgoing S2S servers", "Servery S2S pre odchádzajúcu komunikáciu"}.
-{"Change Password", "Zmeniť heslo"}.
-{"Connected Resources:", "Pripojené zdroje:"}.
-{"Password:", "Heslo:"}.
-{"None", "Nič"}.
-{"Node ", "Uzol "}.
-{"DB Management", "Správa databázy"}.
-{"Listened Ports Management", "Správa otvorených portov"}.
-{"Restart", "Reštart"}.
-{"Stop", "Stop"}.
-{"RPC call error", "Chyba RPC volania"}.
-{"DB Tables at ", "Databázové tabuľky na "}.
-{"Name", "Meno"}.
-{"Storage Type", "Typ úložiska"}.
-{"Size", "Veľkosť"}.
-{"Memory", "Pamäť"}.
-{"Backup Management at ", "Správa záloh na "}.
-{"Store a backup in a file", "Uložiť zálohu do súboru "}.
-{"OK", "OK"}.
-{"Restore a backup from a file", "Obnoviť zálohu zo súboru"}.
-{"Install a database fallback from a file", "Inštalovať fallback pre databázu zo súboru"}.
-{"Dump a database in a text file", "Uložiť databázu do textového súboru"}.
-{"Restore a database from a text file", "Obnoviť databázu z textového súboru"}.
-{"Listened Ports at ", "Otvorené porty na "}.
-{"~p statistics", "~p štatistiky"}.
-{"Uptime", "Uptime"}.
-{"CPU Time", "Čas procesoru"}.
-{"Transactions commited", "Transakcie potvrdená"}.
-{"Transactions aborted", "Transakcie zrušená"}.
-{"Transactions restarted", "Transakcie reštartovaná"}.
-{"Transactions logged", "Transakcie zaznamenaná"}.
-{"Port", "Port"}.
-{"Module", "Modul"}.
-{"Options", "Nastavenia"}.
-{"Update", "Aktualizovať"}.
-{"Delete", "Zmazať"}.
-{"Add User", "Pridať používateľa"}.
-{"Offline messages", "Offline správy"}.
-{"Last Activity", "Posledná aktivita"}.
-{"Never", "Nikdy"}.
-{"~s offline messages queue", "~s offline správy"}.
-{"Time", "Čas"}.
-{"From", "Od"}.
-{"To", "Pre"}.
-{"Packet", "Paket"}.
-{"Offline messages:", "Offline správy:"}.
-{"Roster", "Zoznam kontaktov"}.
-{"Nickname", "Prezývka"}.
-{"Subscription", "Prihlásenie"}.
-{"Pending", "Čakajúce"}.
-{"Groups", "Skupiny"}.
-{"Remove", "Odstrániť"}.
-{"Add JID", "Pridať JID"}.
-{"User ", "Používateľ "}.
-{"Roster of ", "Zoznam kontaktov "}.
-{"Shared Roster", "Zdieľaný zoznam kontaktov"}.
-{"Online", "Online"}.
-{"Validate", "Overiť"}.
-{"Not found", "Nenájdené"}.
-{"Shared roster groups", "Skupiny pre zdieľaný zoznam kontaktov"}.
-{"Name:", "Meno:"}.
-{"Description:", "Popis:"}.
-{"Members:", "Členovia:"}.
-{"Displayed Groups:", "Zobrazené skupiny:"}.
-{"Group ", "Skupina "}.
-{"Users last activity", "Posledná aktivita používateľa"}.
-{"Period: ", "Čas:"}.
-{"Last month", "Posledný mesiac"}.
-{"Last year", "Posledný rok"}.
-{"All activity", "Všetky aktivity"}.
-{"Show Ordinary Table", "Zobraziť bežnú tabuľku"}.
-{"Show Integral Table", "Zobraziť kompletnú tabuľku"}.
-{"Start", "Štart"}.
-{"Modules Management", "Správa modulov"}.
-{"Modules at ", "Moduly na "}.
-{"No data", "Žiadne dáta"}.
-{"Virtual Hosts", "Virtuálne servery"}.
-{"ejabberd virtual hosts", "Ejabberd virtuálne servery"}.
-{"Host", "Server"}.
-{"ejabberd Web Interface", "Ejabberd Web rozhranie"}.
-
-% mod_vcard_odbc.erl
-{"Erlang Jabber Server\nCopyright (c) 2002-2005 Alexey Shchepin", "Erlang Jabber Server\nCopyright (c) 2002-2005 Alexey Shchepin"}.
-{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)", "Pre vyhľadanie Jabber používateľa vyplňte formulár (pridajte znak * na koniec, pre vyhľadanie podreťazca)"}.
-{"ejabberd vCard module\nCopyright (c) 2003-2005 Alexey Shchepin", "Ejabberd vCard modul\nCopyright (c) 2003-2005 Alexey Shchepin"}.
-{"JID", "JID"}.
-
-% ejabberd_c2s.erl
-{"Use of STARTTLS required", "Použitie STARTTLS je vyžadované"}.
-{"Replaced by new connection", "Nahradené novým spojením"}.
-
-% mod_configure.erl
-{"DB Tables Configuration at ", "Databázové tabuľky s konfiguráciou na "}.
-
-% mod_vcard_ldap.erl
-{"Given Name", "Meno"}.
-
-% mod_pubsub/mod_pubsub.erl
-{"ejabberd pub/sub module\nCopyright (c) 2003-2005 Alexey Shchepin", "Ejabberd pub/sub modul\nCopyright (c) 2003-2005 Alexey Shchepin"}.
-{[], " "}.
-{"Node Creator", "Tvorca uzlu"}.
-{"Deliver payloads with event notifications", "Doručovanie payload s upozorňovaním na udalosti"}.
-{"Notify subscribers when the node configuration changes", "Upozorniť prihlásených používateľov na zmenu nastavenia uzlu"}.
-{"Notify subscribers when the node is deleted", "Upozorniť prihlásených používateľov na zmazanie uzlu"}.
-{"Notify subscribers when items are removed from the node", "Upozorniť prihlásených používateľov na odstránenie položiek z uzlu"}.
-{"Persist items to storage", "Uložiť položky natrvalo do úložiska"}.
-{"Max # of items to persist", "Maximálny počet položiek, ktoré je možné natrvalo uložiť"}.
-{"Whether to allow subscriptions", "Povoliť prihlasovanie"}.
-{"Specify the subscriber model", "Špecifikovať prihlasovací model"}.
-{"Specify the publisher model", "Špecifikovať model publikovania"}.
-{"Max payload size in bytes", "Maximálny payload v bajtoch"}.
-{"Send items to new subscribers", "Odoslať položky novým používateľom"}.
-{"Only deliver notifications to available users", "Doručovať upozornenia len aktuálne prihláseným používateľom"}.
-{"Specify the current subscription approver", "Zadať súčasného schvaľovateľa prihlásení "}.
-
-% web/ejabberd_web_admin.erl
-{"ejabberd (c) 2002-2005 Alexey Shchepin, 2004-2005 Process One", "Ejabberd (c) 2002-2005 Alexey Shchepin, 2004-2005 Process One"}.
-{"(raw)", "(raw)"}.
-{"raw", "raw"}.
-{"Authenticated users", "Autentifikovaný používatelia"}.
-
-% mod_irc/mod_irc.erl
-{"ejabberd IRC module\nCopyright (c) 2003-2005 Alexey Shchepin", "Ejabberd IRC module\nCopyright (c) 2003-2005 Alexey Shchepin"}.
-{"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.", "Ak chcete zadať iné kódovania pre IRC servery, vyplnte zoznam s hodnotami vo formáte '{\"irc server\",\"encoding\"}'. Predvolené kódovanie pre túto službu je \"~s\"."}.
-
-% mod_muc/mod_muc.erl
-{"Room creation is denied by service policy", "Vytváranie miestnosti nie je povolené"}.
-{"ejabberd MUC module\nCopyright (c) 2003-2005 Alexey Shchepin", "Ejabberd MUC modul\nCopyright (c) 2003-2005 Alexey Shchepin"}.
-
-% Local Variables:
-% mode: erlang
-% End:
-
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_vcard_odbc.erl
-{"Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin", "Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin"}.
-{"Email", "E-mail"}.
-{"ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin", "Ejabberd vCard modul\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-{"Search Results for ", "Hľadať výsledky pre "}.
-{"Jabber ID", "Jabber ID"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_adhoc.erl
-{"Commands", "Príkazy"}.
-{"Ping", "Ping"}.
-{"Pong", "Pong"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/ejabberd_c2s.erl
-{"Replaced by new connection", "Nahradené novým spojením"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_announce.erl
-{"Really delete message of the day?", "Skutočne zmazať správu dňa?"}.
-{"Subject", "Predmet"}.
-{"Message body", "Telo správy"}.
-{"No body provided for announce message", "Správa neobsahuje text"}.
-{"Announcements", "Oznámenia"}.
-{"Send announcement to all users", "Odoslať oznam všetkým používateľom"}.
-{"Send announcement to all online users", "Odoslať zoznam všetkým online používateľom"}.
-{"Send announcement to all online users on all hosts", "Odoslať oznam všetkým online používateľom na všetkých serveroch"}.
-{"Set message of the day and send to online users", "Nastaviť správu dňa a odoslať ju online používateľom"}.
-{"Update message of the day (don't send)", "Aktualizovať správu dňa (neodosielať)"}.
-{"Delete message of the day", "Zmazať správu dňa"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_configure.erl
-{"Database", "Databáza"}.
-{"Outgoing s2s Connections", "Odchdazájuce s2s spojenie"}.
-{"Import Users From jabberd 1.4 Spool Files", "Importovať používateľov z jabber 1.4 spool súborov"}.
-{"Database Tables Configuration at ", "Konfigurácia databázových tabuliek "}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_pubsub/mod_pubsub.erl
-{"ejabberd pub/sub module\nCopyright (c) 2003-2006 Alexey Shchepin", "ejabberd pub/sub modul\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/web/ejabberd_web_admin.erl
-{"ejabberd Web Interface", "Ejabberd Web rozhranie"}.
-{"Administration", "Administrácia"}.
-{"ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One", "Ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One"}.
-{"(Raw)", "(Raw)"}.
-{"Submitted", "Odoslané"}.
-{"Bad format", "Zlý formát"}.
-{"Raw", "Raw"}.
-{"Users Last Activity", "Posledná aktivita používateľa"}.
-{"Registered Users", "Registrovaní používatelia"}.
-{"Offline Messages", "Offline správy"}.
-{"Registered Users:", "Registrovaní používatelia:"}.
-{"Authenticated Users:", "Autentifikovaný používatelia:"}.
-{"Online Users:", "Online používatelia:"}.
-{"Outgoing s2s Connections:", "Odchádzajúce s2s spojenia:"}.
-{"Outgoing s2s Servers:", "Odchádzajúce s2s servery:"}.
-{"Offline Messages:", "Offline správy"}.
-{"~s's Offline Messages Queue", "~s Offline správy"}.
-{"Add Jabber ID", "Pridať JID"}.
-{"No Data", "Žiadne dáta"}.
-{"Listened Ports", "Otvorené portov"}.
-{"RPC Call Error", "Chyba RPC volania"}.
-{"Database Tables at ", "Databázové tabuľky na "}.
-{"Backup of ", "Záloha na "}.
-{"Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.", "Podotýkame, že tieto nastavenia budú zálohované do zabudovanej Mnesia databázy. Ak používate ODBC modul, musíte zálohovať vašu SQL databázu separátne."}.
-{"Store binary backup:", "Uložiť binárnu zálohu:"}.
-{"Restore binary backup immediately:", "Okamžite obnoviť binárnu zálohu:"}.
-{"Restore binary backup after next ejabberd restart (requires less memory):", "Obnoviť binárnu zálohu pri nasledujúcom reštarte Ejabberd (vyžaduje menej pamäte)"}.
-{"Store plain text backup:", "Uložiť zálohu do textového súboru:"}.
-{"Restore plain text backup immediately:", "Okamžite obnoviť zálohu z textového súboru:"}.
-{"Statistics of ~p", "Štatistiky ~p"}.
-{"Uptime:", "Uptime"}.
-{"CPU Time:", "Čas procesoru"}.
-{"Transactions Commited:", "Transakcie potvrdená"}.
-{"Transactions Aborted:", "Transakcie zrušená"}.
-{"Transactions Restarted:", "Transakcie reštartovaná"}.
-{"Transactions Logged:", "Transakcie zaznamenaná"}.
-{"Update ", "Aktualizovať "}.
-{"Update plan", "Aktualizovať plán"}.
-{"Updated modules", "Aktualizované moduly"}.
-{"Update script", "Aktualizované skripty"}.
-{"Low level update script", "Nízkoúrovňový aktualizačný skript"}.
-{"Script check", "Kontrola skriptu"}.
-{"Not Found", "Nenájdené"}.
-{"Shared Roster Groups", "Skupiny pre zdieľaný zoznam kontaktov"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_irc/mod_irc.erl
-{"ejabberd IRC module\nCopyright (c) 2003-2006 Alexey Shchepin", "Ejabberd IRC modul\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_muc/mod_muc_log.erl
-{"Chatroom configuration modified", "Nastavenie diskusnej miestnosti bolo zmenené"}.
-{"joins the room", "vstúpil(a) do miestnosti"}.
-{"leaves the room", "odišiel(a) z miestnosti"}.
-{"has been kicked", "bol(a) vyhodený(á) z miestnosti"}.
-{"has been banned", "bol(a) zablokovaný(á)"}.
-{"is now known as", "sa premenoval(a) na"}.
-{"Monday", "Pondelok"}.
-{"Tuesday", "Utorok"}.
-{"Wednesday", "Streda"}.
-{"Thursday", "Štvrtok"}.
-{"Friday", "Piatok"}.
-{"Saturday", "Sobota"}.
-{"Sunday", "Nedeľa"}.
-{"January", "Január"}.
-{"February", "Február"}.
-{"March", "Marec"}.
-{"April", "Apríl"}.
-{"May", "Máj"}.
-{"June", "Jún"}.
-{"July", "Júl"}.
-{"August", "August"}.
-{"September", "September"}.
-{"October", "Október"}.
-{"November", "November"}.
-{"December", "December"}.
-{"Room Configuration", "Nastavenia miestnosti"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_muc/mod_muc.erl
-{"You must fill in field \"Nickname\" in the form", "Musíte vyplniť políčko \"Prezývka\" vo formulári"}.
-{"ejabberd MUC module\nCopyright (c) 2003-2006 Alexey Shchepin", "Ejabberd MUC modul\nCopyright (c) 2003-2006 Alexey Shchepin"}.
-
-% /usr/home/src/ejabberd/ejabberd/src/mod_muc/mod_muc_room.erl
-{"This room is not anonymous", "Táto miestnosť nie je anonymná"}.
-{"Make room persistent", "Nastaviť miestnosť ako trvalú"}.
-{"Make room public searchable", "Nastaviť miestnosť ako verejne prehľadávateľnú"}.
-{"Make participants list public", "Nastaviť zoznam zúčastnených ako verejný"}.
-{"Make room password protected", "Chrániť miestnosť heslom"}.
-{"Make room semianonymous", "Nastaviť miestnosť ako čiastočne anonymnú"}.
-{"Make room members-only", "Nastaviť miestnosť len pre členov"}.
-{"Make room moderated", "Nastaviť miestnosť ako moderovanú"}.
-{"Default users as participants", "Používatelia sú implicitne členmi"}.
-{"Allow users to change subject", "Povoliť používateľom zmeniť tému tejto miestnosti"}.
-{"Allow users to send private messages", "Povoliť používateľom odosielať súkromné správy"}.
-{"Allow users to query other users", "Povoliť používateľom odosielať požiadavky (query) ostatným používateľom"}.
-{"Allow users to send invites", "povoliť používateľom posielanie pozvánok"}.
-{"Enable logging", "Zapnúť zaznamenávanie histórie"}.
-{"Description", "Popis"}.
-{"Number of occupants", "Počet zúčastnených"}.
diff --git a/ejabberd-1.1.2/src/msgs/sv.msg b/ejabberd-1.1.2/src/msgs/sv.msg
deleted file mode 100644
index 557a10ed5..000000000
--- a/ejabberd-1.1.2/src/msgs/sv.msg
+++ /dev/null
@@ -1,321 +0,0 @@
-% $Id$
-
-% ejabberd_c2s.erl
-{"Use of STARTTLS required", "Du måste använda STARTTLS"}.
-{"Replaced by new connection", "Ersatt av ny anslutning"}.
-
-% jlib.hrl
-{"No resource provided", "Ingen resurs angiven"}.
-
-% mod_configure.erl
-{"DB Tables Configuration at ", "Konfigurera DB-tabeller på "}.
-{"Choose storage type of tables", "Välj lagringstyp för tabeller"}.
-{"RAM copy", "RAM-kopia"}.
-{"RAM and disc copy", "RAM- och diskkopia"}.
-{"Disc only copy", "Endast diskkopia"}.
-{"Remote copy", "Sparas inte lokalt"}.
-{"Stop Modules at ", "Stoppa moduler på "}.
-{"Choose modules to stop", "Välj vilka moduler som skall stoppas"}.
-{"Start Modules at ", "Starta moduler på "}.
-{"Enter list of {Module, [Options]}", "Skriv in en lista av {Module, [Options]}"}.
-{"List of modules to start", "Lista av moduler som skall startas"}.
-{"Backup to File at ", "Säkerhetskopiera till fil på "}.
-{"Enter path to backup file", "Skriv in sökväg till fil för säkerhetskopia"}.
-{"Path to File", "Sökväg till fil"}.
-{"Restore Backup from File at ", "Återställ säkerhetskopia från fil på "}.
-{"Dump Backup to Text File at ", "Dumpa säkerhetskopia till textfil på "}.
-{"Enter path to text file", "Skriv in sökväg till textfil"}.
-{"Import User from File at ", "Importera användare från fil på "}.
-{"Enter path to jabberd1.4 spool file", "Skriv in sökväg till spoolfil från jabberd1.4"}.
-{"Import Users from Dir at ", "Importera användare från katalog på "}.
-{"Enter path to jabberd1.4 spool dir", "Skriv in sökväg till spoolkatalog från jabberd1.4"}.
-{"Path to Dir", "Sökväg till katalog"}.
-{"Hostname Configuration", "Värdnamnkonfiguration"}.
-{"Choose host name", "Välj värdnamn"}.
-{"Host name", "Värdnamn"}.
-{"Access Control List Configuration", "Konfiguera ACL"}.
-{"Access control lists", "ACL"}.
-{"Access Configuration", "Åtkomstkonfiguration"}.
-{"Access rules", "Åtkomstregler"}.
-{"Remove Users", "Ta bort användare"}.
-{"Choose users to remove", "Välj användare att ta bort"}.
-{"Administration of ", "Administration av "}.
-{"Action on user", "Handling mot användare"}.
-{"Edit Properties", "Redigera egenskaper"}.
-{"Remove User", "Ta bort användare"}.
-
-% mod_disco.erl
-{"Configuration", "Konfiguration"}.
-{"Online Users", "Anslutna användare"}.
-{"All Users", "Alla användare"}.
-{"Outgoing S2S connections", "Utgående S2S-anslutningar"}.
-{"To ~s", "Till ~s"}.
-{"From ~s", "Från ~s"}.
-{"Running Nodes", "Körande noder"}.
-{"Stopped Nodes", "Stannade noder"}.
-{"Host Name", "Värdnamn"}.
-{"Access Control Lists", "ACL"}.
-{"Access Rules", "Åtkomstregler"}.
-{"Remove Users", "Ta bort användare"}.
-{"DB", "DB"}.
-{"Modules", "Moduler"}.
-{"Start Modules", "Starta moduler"}.
-{"Stop Modules", "Stanna moduler"}.
-{"Backup Management", "Hantera säkerhetskopior"}.
-{"Import users from jabberd1.4 spool files", "Importera användare från spoolfiler från jabberd1.4"}.
-{"Backup", "Säkerhetskopiera"}.
-{"Restore", "Återställ"}.
-{"Dump to Text File", "Dumpa till textfil"}.
-{"Import File", "Importera fil"}.
-{"Import Directory", "Importera katalog"}.
-
-% mod_register.erl
-{"Choose a username and password to register with this server",
- "Välj ett användarnamn och lösenord för att registrera mot denna server"}.
-
-% mod_vcard.erl
-{"Erlang Jabber Server\nCopyright (c) 2002-2005 Alexey Shchepin",
- "Erlang Jabber Server\nCopyright (c) 2002-2005 Alexej Sjtjepin"}.
-{"ejabberd vCard module\nCopyright (c) 2003-2005 Alexey Shchepin",
- "ejabberd vCard-modul\nCopyright (c) 2003-2005 Alexej Sjtjepin"}.
-{"You need an x:data capable client to search",
- "Du behöver en klient som stödjer x:data, för att kunna söka"}.
-{"Search users in ", "Sök efter användare på "}.
-{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)",
-"Fyll i formuläret för att söka efter en användare (lägg till * på slutet av fältet för att hitta alla som börjar så)"}.
-{"Results of search in ", "Sökresultat på "}.
-{"User", "Användarnamn"}.
-{"Full Name", "Fullständigt namn"}.
-{"Name", "Förnamn"}.
-{"Middle Name", "Mellannamn"}.
-{"Family Name", "Efternamn"}.
-{"Nickname", "Smeknamn"}.
-{"Birthday", "Födelsedag"}.
-{"Country", "Land"}.
-{"City", "Stad"}.
-{"email", "email"}.
-{"Organization Name", "Organisationsnamn"}.
-{"Organization Unit", "Organisationsenhet"}.
-
-% mod_vcard_ldap.erl
-{"Fill in fields to search for any matching Jabber User", "Fyll i fält för att söka efter jabberanvändare"}.
-{"Given Name", "Förnamn"}.
-
-% mod_vcard_odbc.erl
-{"JID", "JID"}.
-
-% mod_pubsub/mod_pubsub.erl
-{"ejabberd pub/sub module\nCopyright (c) 2003-2005 Alexey Shchepin",
- "ejabberd pub/sub-modul\nCopyright (c) 2003-2005 Alexej Sjtjepin"}.
-{"Node Creator", "Nodskapare"}.
-{[], " "}.
-{"Deliver payloads with event notifications", "Skicka innehåll tillsammans med notifikationer"}.
-{"Notify subscribers when the node configuration changes", "Meddela prenumeranter när nodens konfiguration ändras"}.
-{"Notify subscribers when the node is deleted", "Meddela prenumeranter när noden tas bort"}.
-{"Notify subscribers when items are removed from the node", "Meddela prenumeranter när dataposter tas bort från noden"}.
-{"Persist items to storage", "Spara dataposter permanent"}.
-{"Max # of items to persist", "Högsta antal dataposter som sparas"}.
-{"Whether to allow subscriptions", "Tillåta prenumerationer?"}.
-{"Specify the subscriber model", "Ange prenumerationsmodell"}.
-{"Specify the publisher model", "Ange publiceringsmodell"}.
-{"Max payload size in bytes", "Högsta innehållsstorlek i bytes"}.
-{"Send items to new subscribers", "Skicka dataposter till nya prenumeranter"}.
-{"Only deliver notifications to available users", "Skicka notifikationer bara till uppkopplade användare"}.
-{"Specify the current subscription approver", "Ange prenumerationsgodkännare"}.
-
-% mod_muc/mod_muc.erl
-{"You need an x:data capable client to register nickname",
- "Du behöver en klient som stödjer x:data för att registrera smeknamn"}.
-{"Nickname Registration at ", "Registrera smeknamn på "}.
-{"Enter nickname you want to register", "Skriv in smeknamnet du vill registrera"}.
-{"ejabberd MUC module\nCopyright (c) 2003-2005 Alexey Shchepin",
- "ejabberd MUC modul\nCopyright (c) 2003-2005 Alexej Sjtjepin"}.
-{"Only service administrators are allowed to send service messages",
- "Endast administratörer får skicka tjänstmeddelanden"}.
-{"Room creation is denied by service policy",
- "Skapandet av rum är förbjudet enligt lokal policy"}.
-{"Conference room does not exist", "Rummet finns inte"}.
-{"Access denied by service policy", "Åtkomst nekad enligt lokal policy"}.
-{"You must fill in field \"nick\" in the form",
- "Du måste fylla i fältet \"nick\" i formuläret"}.
-{"Specified nickname is already registered", "Detta smeknamnet är redan registrerat"}.
-
-% mod_muc/mod_muc_room.erl
-{" has set the subject to: ", " har satt ämnet till: "}.
-{"You need an x:data capable client to configure room",
- "Du behöver en klient som stödjer x:data för att konfiguera detta rum"}.
-{"Configuration for ", "Konfiguration för "}.
-{"Room title", "Rumstitel"}.
-{"Allow users to change subject?", "Tillåt användare att ändra ämnet?"}.
-{"Allow users to query other users?",
- "Tillåt användare att skicka iq-queries"}.
-{"Allow users to send private messages?",
- "Tillåt användare att skicka privata meddelanden"}.
-{"Make room public searchable?", "Gör rummet synligt för alla?"}.
-{"Make participants list public?", "Gör användarlistan publik?"}.
-{"Make room persistent?", "Gör rummet permanent?"}.
-{"Make room moderated?", "Gör rummet modererat?"}.
-{"Default users as members?",
- "Gör användare deltagare som standard?"}.
-{"Make room members only?",
- "Stäng ute icke medlemmar?"}.
-{"Allow users to send invites?",
- "Tillåt användare att skicka inbjudningar?"}.
-{"Make room password protected?", "Lösenordsskydda rummet?"}.
-{"Password", "Lösenord"}.
-{"Make room anonymous?", "Anonymt rum?"}.
-{"Enable logging?", "Aktivera loggning?"}.
-{"Only moderators and participants are allowed to change subject in this room",
- "Endast moderatorer och deltagare har tillåtelse att ändra ämnet i det här rummet"}.
-{"Only moderators are allowed to change subject in this room",
- "Endast moderatorer får ändra ämnet i det här rummet"}.
-{"Visitors are not allowed to send messages to all occupants",
- "Besökare får inte skicka medelande till alla"}.
-{"Only occupants are allowed to send messages to the conference",
- "Utomstående får inte skicka medelanden till den här konferensen"}.
-{"It is not allowed to send normal messages to the conference",
- "Det är inte tillåtet att skicka normala medelanden till den här konferensen"}.
-{"It is not allowed to send private messages to the conference",
- "Det är inte tillåtet att skicka privata medelanden till den här konferensen"}.
-{"Improper message type", "Felaktig medelandetyp"}.
-{"Nickname is already in use by another occupant", "Smeknamnet används redan"}.
-{"Nickname is registered by another person", "Smeknamnet är reserverat"}.
-{"It is not allowed to send private messages of type \"groupchat\"",
- "Det är inte tillåtet att skicka privata medelanden med typen \"groupchat\""}.
-{"Recipient is not in the conference room", "Mottagaren finns inte i rummet"}.
-{"Only occupants are allowed to send queries to the conference",
- "Utomstående får inte skicka iq-queries till den här konferensen"}.
-{"Queries to the conference members are not allowed in this room",
- "Det är förbjudet att skicka iq-queries till konferensdeltagare"}.
-{"You have been banned from this room", "Du har blivit bannlyst från det här rummet"}.
-{"Membership required to enter this room", "Du måste vara medlem för att komma in i det här rummet"}.
-{"Password required to enter this room", "Lösenord erfordras"}.
-{"Incorrect password", "Fel lösenord"}.
-{"Administrator privileges required", "Administrationsprivilegier krävs"}.
-{"Moderator privileges required", "Moderatorprivilegier krävs"}.
-{"JID ~s is invalid", "Otillåtet JID ~s"}.
-{"Nickname ~s does not exist in the room", "Smeknamnet ~s existerar inte i det här rummet"}.
-{"Invalid affiliation: ~s", "Ogiltlig rang: ~s"}.
-{"Invalid role: ~s", "Ogiltlig roll: ~s"}.
-{"Owner privileges required", "Ägarprivilegier krävs"}.
-{"private, ", "privat, "}.
-
-% mod_irc/mod_irc.erl
-{"ejabberd IRC module\nCopyright (c) 2003-2005 Alexey Shchepin",
- "ejabberd IRC-modul\nCopyright (c) 2003-2005 Alexej Sjtjepin"}.
-{"You need an x:data capable client to configure mod_irc settings",
- "Du behöer en klient som stöjer x:data för att konfigurera mod_irc"}.
-{"Registration in mod_irc for ", "mod_irc-registrering för "}.
-{"Enter username and encodings you wish to use for connecting to IRC servers",
- "Skriv in användarnamn och textkodning du vill använda för att ansluta till IRC-servrar"}.
-{"IRC Username", "IRC-användarnamn"}.
-{"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.", "Om du vill specifiera textkodning för IRC-servrar, fyll i listan med värden i formatet '{\"irc server\", \"encoding\"}'. Som standard används \"~s\"."}.
-{"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].", "Exempel: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}]."}.
-{"Encodings", "Textkodningar"}.
-
-% web/ejabberd_web_admin.erl
-{"ejabberd administration", "ejabberd-administration"}.
-{"Users", "Användare"}.
-{"Nodes", "Noder"}.
-{"Statistics", "Statistik"}.
-{"(raw)", "(obehandlat format)"}.
-{"submitted", "inskickat"}.
-{"bad format", "otillåtet format"}.
-{"raw", "obehandlat format"}.
-{"ejabberd access control lists configuration", "ejabberd ACL-konfiguration"}.
-{"Delete Selected", "Tabort valda"}.
-{"Submit", "Skicka"}.
-{"ejabberd access rules configuration", "ejabberd åtkomstregler-konfiguration"}.
-{"~s access rule configuration", "Åtkomstregelkonfiguration för ~s"}.
-{"ejabberd users", "ejabberd-användare"}.
-{"ejabberd stats", "ejabberd-statistik"}.
-{"Node not found", "Noden finns inte"}.
-{"Add New", "Lägg till ny"}.
-{"Registered users", "Registrerade användare"}.
-{"Authenticated users", "Inloggade användare"}.
-{"Online users", "Anslutna användare"}.
-{"Outgoing S2S servers", "Utgående S2S-servrar"}.
-{"Change Password", "Ändra lösenord"}.
-{"Connected Resources:", "Anslutna resurser:"}.
-{"Password:", "Lösenord:"}.
-{"None", "Inga"}.
-{"Node ", "Nod "}.
-{"DB Management", "DB-hantering"}.
-{"Listened Ports Management", "Hantering av lyssnande portar"}.
-{"Restart", "Omstart"}.
-{"Stop", "Stoppa"}.
-{"RPC call error", "RPC-fel"}.
-{"DB Tables at ", "DB-tabeller på "}.
-{"Name", "Namn"}.
-{"Storage Type", "Lagringstyp"}.
-{"Size", "Storlek"}.
-{"Memory", "Minne"}.
-{"Backup Management at ", "Hantering av säkerhetskopiering på "}.
-{"Store a backup in a file", "Lagra en säkerhetskopiering i en fil"}.
-{"OK", "OK"}.
-{"Restore a backup from a file", "Återställ en säkerhetskopia från en fil"}.
-{"Install a database fallback from a file", "Installera en databasfallback från en fil"}.
-{"Dump a database in a text file", "Dumpa en databas i en textfil"}.
-{"Restore a database from a text file", "Återställ en databas från en textfil"}.
-{"Listened Ports at ", "Lyssnande portar på "}.
-{"~p statistics", "~p-statistik"}.
-{"Uptime", "Driftstid"}.
-{"CPU Time", "CPU-tid"}.
-{"Transactions commited", "Skickade transaktioner"}.
-{"Transactions aborted", "Avbrutna transaktioner"}.
-{"Transactions restarted", "Omstartade transaktioner"}.
-{"Transactions logged", "Loggade transaktioner"}.
-{"Port", "Port"}.
-{"Module", "Modul"}.
-{"Options", "Parametrar"}.
-{"Update", "Uppdatera"}.
-{"Delete", "Ta bort"}.
-{"Add User", "Lägg till användare"}.
-{"ejabberd (c) 2002-2005 Alexey Shchepin, 2004-2005 Process One", "ejabberd (c) 2002-2005 Alexej Sjtjepin, 2004-2005 Process One"}.
-{"Offline messages", "Offline-medelanden"}.
-{"Last Activity", "Senast aktivitet"}.
-{"Never", "Aldrig"}.
-{"~s offline messages queue", "~s offlinemedelande i kö"}.
-{"Time", "Tid"}.
-{"From", "Från"}.
-{"To", "Till"}.
-{"Packet", "Paket"}.
-{"Offline messages:", "Offlinemedelande:"}.
-{"Roster", "Kontaktlista"}.
-{"Nickname", "Smeknamn"}.
-{"Subscription", "Prenumeration"}.
-{"Pending", "Ännu inte godkända"}.
-{"Groups", "Grupper"}.
-{"Remove", "Ta bort"}.
-{"Add JID", "Lägg till JID"}.
-{"User ", "Användare "}.
-{"Roster of ", "Kontaktlista för "}.
-{"Shared Roster", "Gemensam kontaktlista"}.
-{"Online", "Ansluten"}.
-{"Validate", "Validera"}.
-{"Not found", "Finns inte"}.
-{"Shared roster groups", "Gemensamma kontaktlistagrupper"}.
-{"Name:", "Namn:"}.
-{"Description:", "Beskrivning:"}.
-{"Members:", "Medlemmar:"}.
-{"Displayed Groups:", "Visade grupper:"}.
-{"Group ", "Grupp "}.
-{"Virtual Hosts", "Virtuella servrar"}.
-{"ejabberd virtual hosts", "Virtuella ejabberd-servrar"}.
-{"Users last activity", "Senaste aktivitet från användare"}.
-{"Period: ", "Period: "}.
-{"Last month", "Senaste månaden"}.
-{"Last year", "Senaste året"}.
-{"All activity", "All aktivitet"}.
-{"Show Ordinary Table", "Visa normal tabell"}.
-{"Show Integral Table", "Visa kumulativ tabell"}.
-{"Host", "Server"}.
-{"No data", "Inga data"}.
-{"Modules Management", "Modulhantering"}.
-{"Modules at ", "Moduler på"}.
-{"Start", "Starta"}.
-{"ejabberd Web Interface", "Webbgränssnitt till ejabberd"}.
-
-% Local Variables:
-% mode: erlang
-% End:
diff --git a/ejabberd-1.1.2/src/msgs/uk.msg b/ejabberd-1.1.2/src/msgs/uk.msg
deleted file mode 100644
index b14ef23e6..000000000
--- a/ejabberd-1.1.2/src/msgs/uk.msg
+++ /dev/null
@@ -1,377 +0,0 @@
-% $Id$
-
-% ejabberd_c2s.erl
-{"Use of STARTTLS required", "Ви мусите використовувати STARTTLS"}.
-{"Replaced by new connection", "Замінено новим з'єднанням"}.
-
-% jlib.hrl
-{"No resource provided", "Не вказаний ресурс"}.
-{"Illegal resource format", "Неправильний формат ресурсу"}.
-{"Resource conflict", "Конфлікт ресурсів"}.
-
-% mod_adhoc.erl
-{"Commands", "Команди"}.
-{"Ping", "Пінг"}.
-{"Pong", "Понг"}.
-
-% mod_announce.erl
-{"Really delete message of the day?", "Дійсно видалити повідомлення дня"}.
-{"Subject", "Тема"}.
-{"Message body", "Тіло повідомлення"}.
-{"No body provided for announce message", "Тіло оголошення має бути непустим"}.
-{"Announcements", "Оголошення"}.
-{"Send announcement to all users", "Надіслати оголошення всім користувачам"}.
-{"Send announcement to all online users", "Надіслати оголошення всім підключеним користувачам"}.
-{"Send announcement to all online users on all hosts", "Надіслати оголошення всім підключеним користувачам на всіх віртуальних серверах"}.
-{"Set message of the day and send to online users", "Встановити повідомлення дня та надіслати його підключеним користувачам"}.
-{"Update message of the day (don't send)", "Поновити повідомлення дня (не надсилати)"}.
-{"Delete message of the day", "Видалити повідомлення дня"}.
-
-% mod_configure.erl
-{"Database Tables Configuration at ", "Конфігурація таблиць бази даних на "}.
-{"Choose storage type of tables", "Оберіть тип збереження таблиць"}.
-{"RAM copy", "ОЗП"}.
-{"RAM and disc copy", "ОЗП та диск"}.
-{"Disc only copy", "тільки диск"}.
-{"Remote copy", "не зберігаеться локально"}.
-{"Stop Modules at ", "Зупинка модулів на "}.
-{"Choose modules to stop", "Виберіть модулі, які необхідно зупинити"}.
-{"Start Modules at ", "Запуск модулів на "}.
-{"Enter list of {Module, [Options]}", "Введіть перелік такого виду {Module, [Options]}"}.
-{"List of modules to start", "Список завантажуваних модулів"}.
-{"Backup to File at ", "Резервне копіювання в файл на "}.
-{"Enter path to backup file", "Введіть шлях до резервного файла"}.
-{"Path to File", "Шлях до файла"}.
-{"Restore Backup from File at ", "Відновлення з резервної копії на "}.
-{"Dump Backup to Text File at ", "Копіювання в текстовий файл на "}.
-{"Enter path to text file", "Введіть шлях до текстового файла"}.
-{"Import User from File at ", "Імпортування користувача з файла на "}.
-{"Enter path to jabberd1.4 spool file", "Введіть шлях до файла зі спула jabberd1.4"}.
-{"Import Users from Dir at ", "Імпортування користувача з директорії на "}.
-{"Enter path to jabberd1.4 spool dir", "Введіть шлях до директорії спула jabberd1.4"}.
-{"Path to Dir", "шлях до директорії"}.
-{"Hostname Configuration", "Конфігурація назви хоста"}.
-{"Choose host name", "Оберіть назву хоста"}.
-{"Host name", "Назва хоста"}.
-{"Access Control List Configuration", "Конфігурація списків керування доступом"}.
-{"Access control lists", "Списки керування доступом"}.
-{"Access Configuration", "Конфігурація доступа"}.
-{"Access rules", "Правила доступу"}.
-{"Remove Users", "Видалення користувачів"}.
-{"Choose users to remove", "Оберіть користувачів, яких необхідно видалити"}.
-{"Administration of ", "Адміністрування "}.
-{"Action on user", "Дія над користувачем"}.
-{"Edit Properties", "Змінити параметри"}.
-{"Remove User", "Видалити користувача"}.
-
-% mod_disco.erl
-{"Configuration", "Конфігурація"}.
-{"Online Users", "Підключені користувачі"}.
-{"All Users", "Всі користувачі"}.
-{"Outgoing s2s Connections", "Вихідні s2s-з'єднання"}.
-{"To ~s", "До ~s"}.
-{"From ~s", "Від ~s"}.
-{"Running Nodes", "Працюючі вузли"}.
-{"Stopped Nodes", "Зупинені вузли"}.
-{"Host Name", "Назва хоста"}.
-{"Access Control Lists", "Списки керування доступом"}.
-{"Access Rules", "Правила доступу"}.
-{"Remove Users", "Видалення користувачів"}.
-{"Database", "База даних"}.
-{"Modules", "Модулі"}.
-{"Start Modules", "Запуск модулів"}.
-{"Stop Modules", "Зупинка модулів"}.
-{"Backup Management", "Керування резервним копіюванням"}.
-{"Import Users From jabberd 1.4 Spool Files", "Імпорт користувачів зі спулу jabberd 1.4"}.
-{"Backup", "Резервне копіювання"}.
-{"Restore", "Відновлення з резервної копії"}.
-{"Dump to Text File", "Копіювання в текстовий файл"}.
-{"Import File", "Імпорт з файла"}.
-{"Import Directory", "Імпорт з директорії"}.
-
-% mod_register.erl
-{"Choose a username and password to register with this server",
- "Виберіть назву користувача та пароль для реєстрації на цьому сервері"}.
-
-% mod_vcard.erl
-{"Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin",
- "Erlang Jabber Server\nCopyright (c) 2002-2006 Олексій Щепін"}.
-{"ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin",
- "ejabberd vCard модуль\nCopyright (c) 2003-2006 Олексій Щепін"}.
-{"You need an x:data capable client to search",
- "Для пошуку необхідний x:data-придатний клієнт"}.
-{"Search users in ", "Пошук користувачів в "}.
-{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)",
- "Заповніть поля для пошуку користувача Jabber (Додайте * в кінець поля для пошуку підрядка)"}.
-{"Search Results for ", "Результати пошуку в "}.
-{"Jabber ID", "Jabber ID"}.
-{"User", "Користувач"}.
-{"Full Name", "Повне ім'я"}.
-{"Name", "Ім'я"}.
-{"Middle Name", "По-батькові"}.
-{"Family Name", "Прізвище"}.
-{"Nickname", "Псевдонім"}.
-{"Birthday", "День народження"}.
-{"Country", "Країна"}.
-{"City", "Місто"}.
-{"Email", "Електронна пошта"}.
-{"Organization Name", "Назва організації"}.
-{"Organization Unit", "Відділ організації"}.
-
-% mod_vcard_ldap.erl
-{"Given Name", "Ім'я"}.
-{"Fill in fields to search for any matching Jabber User",
- "Заповніть поля для пошуку користувача Jabber"}.
-
-% mod_pubsub/mod_pubsub.erl
-{"ejabberd pub/sub module\nCopyright (c) 2003-2006 Alexey Shchepin",
- "ejabberd pub/sub модуль\nCopyright (c) 2003-2006 Олексій Щепін"}.
-{"Node Creator", "Створювач збірника"}.
-{"Deliver payloads with event notifications", "Доставляти разом з повідомленнями про публікації самі публікації"}.
-{"Notify subscribers when the node configuration changes", "Повідомляти передплатників про зміни в конфігурації збірника"}.
-{"Notify subscribers when the node is deleted", "Повідомляти передплатників про видалення збірника"}.
-{"Notify subscribers when items are removed from the node", "Повідомляти передплатників про видалення публікацій із збірника"}.
-{"Persist items to storage", "Зберегати публікації до сховища"}.
-{"Max # of items to persist", "Максимальне число збережених публікацій"}.
-{"Whether to allow subscriptions", "Дозволити передплату"}.
-{"Specify the subscriber model", "Умови передплати"}.
-{"Specify the publisher model", "Умови публікації"}.
-{"Max payload size in bytes", "Максимальний розмір корисного навантаження в байтах"}.
-{"Send items to new subscribers", "Відправляти публікації новим передплатникам"}.
-{"Only deliver notifications to available users", "Доставляти повідомленнями тільки доступним користувачам"}.
-{"Specify the current subscription approver", "JID користувача, який затверджує передплату"}.
-
-% mod_muc/mod_muc.erl
-{"You need an x:data capable client to register nickname",
- "Для реєстрації псевдоніму необхідний x:data-придатний клієнт"}.
-{"Nickname Registration at ", "Реєстрація псевдоніма на "}.
-{"Enter nickname you want to register", "Введіть псевдонім, який ви хочете зареєструвати"}.
-{"ejabberd MUC module\nCopyright (c) 2003-2006 Alexey Shchepin",
- "ejabberd MUC модуль\nCopyright (c) 2003-2006 Алексей Щепин"}.
-{"Only service administrators are allowed to send service messages",
- "Тільки адміністратор сервісу може надсилати службові повідомлення"}.
-{"Room creation is denied by service policy",
- "Створювати конференцію заборонено політикою служби"}.
-{"Conference room does not exist", "Конференція не існує"}.
-{"Access denied by service policy", "Доступ заборонений політикою служби"}.
-{"You must fill in field \"Nickname\" in the form",
- "Вам необхідно заповнити поле \"Псевдонім\" у формі"}.
-{"Specified nickname is already registered", "Вказаний псевдонім вже зареєстрований"}.
-
-% /home/sergei/src/ejabberd/ejabberd/src/mod_muc/mod_muc_log.erl
-{"Chatroom configuration modified", "Конфігурація кімнати змінилась"}.
-{"joins the room", "увійшов(ла) в кімнату"}.
-{"leaves the room", "вийшов(ла) з кімнати"}.
-{"has been kicked", "вигнали з кімнати"}.
-{"has been banned", "заборонили вхід в кімнату"}.
-{"is now known as", "змінив(ла) им'я на"}.
-{"Monday", "Понеділок"}.
-{"Tuesday", "Вівторок"}.
-{"Wednesday", "Середа"}.
-{"Thursday", "Четвер"}.
-{"Friday", "П'ятниця"}.
-{"Saturday", "Субота"}.
-{"Sunday", "Неділя"}.
-{"January", "січня"}.
-{"February", "лютого"}.
-{"March", "березня"}.
-{"April", "квітня"}.
-{"May", "травня"}.
-{"June", "червня"}.
-{"July", "липня"}.
-{"August", "серпня"}.
-{"September", "вересня"}.
-{"October", "грудня"}.
-{"November", "листопада"}.
-{"December", "грудня"}.
-{"Room Configuration", "Конфігурація кімнати"}.
-
-% mod_muc/mod_muc_room.erl
-{" has set the subject to: ", " встановив(ла) тему: "}.
-{"This room is not anonymous", "Ця кімната не анонімна"}.
-{"You need an x:data capable client to configure room",
- "Для конфігурування кімнати необхідний x:data-придатний кліент"}.
-{"Configuration for ", "Конфігурація "}.
-{"Room title", "Назва кімнати"}.
-{"Allow users to change subject", "Дозволити користувачам змінювати тему"}.
-{"Allow users to query other users",
- "Дозволити iq-запити до користувачів"}.
-{"Allow users to send private messages",
- "Дозволити приватні повідомлення"}.
-{"Make room public searchable", "Зробити кімнату видимою всім"}.
-{"Make participants list public", "Зробити список учасників видимим всім"}.
-{"Make room persistent", "Зробити кімнату постійною"}.
-{"Make room moderated", "Зробити кімнату модерованою"}.
-{"Default users as participants",
- "Зробити користувачів учасниками за замовчуванням"}.
-{"Make room members-only",
- "Кімната тільки для зареєтрованых учасників"}.
-{"Allow users to send invites",
- "Дозволити користувачам надсилати запрошення"}.
-{"Make room password protected", "Зробити кімнату захищеною паролем"}.
-{"Password", "Пароль"}.
-{"Present real JIDs to", "Зробити реальні JID учасників видимими"}.
-{"moderators only", "тільки модераторам"}.
-{"anyone", "всім учасникам"}.
-{"Enable logging", "Включити журнал роботи"}.
-{"Only moderators and participants are allowed to change subject in this room",
- "Тільки модератори та учасники можуть змінювати тему в цій кімнаті"}.
-{"Only moderators are allowed to change subject in this room",
- "Тільки модератори можуть змінювати тему в цій кімнаті"}.
-{"Visitors are not allowed to send messages to all occupants",
- "Відвідувачам не дозволяється надсилати повідомлення всім присутнім"}.
-{"Only occupants are allowed to send messages to the conference",
- "Тільки присутнім дозволяється надсилати повідомленняя в конференцію"}.
-{"It is not allowed to send normal messages to the conference",
- "Не дозволяється надсилати звичайні повідомлення в конференцію"}.
-{"It is not allowed to send private messages to the conference",
- "Не дозволяється надсилати приватні повідомлення в конференцію"}.
-{"Improper message type", "Неправильний тип повідомлення"}.
-{"Nickname is already in use by another occupant", "Псевдонім зайнятий кимось з присутніх"}.
-{"Nickname is registered by another person", "Псевдонім зареєстрований кимось іншим"}.
-{"It is not allowed to send private messages of type \"groupchat\"",
- "Не дозволяється надсилати приватні повідомлення типу \"groupchat\""}.
-{"Recipient is not in the conference room", "Адресата немає в конференції"}.
-{"Only occupants are allowed to send queries to the conference",
- "Тільки присутнім дозволяється відправляти запити в конференцію"}.
-{"Queries to the conference members are not allowed in this room",
- "Запити до користувачів в цій конференції зоборонені"}.
-{"You have been banned from this room", "Вам заборонено входити в цю конференцію"}.
-{"Membership required to enter this room", "В цю конференціию можуть входити тільки її члени"}.
-{"Password required to enter this room", "Щоб зайти в цю конференцію, необхідний пароль"}.
-{"Incorrect password", "Неправильний пароль"}.
-{"Administrator privileges required", "Необхідні права адміністратора"}.
-{"Moderator privileges required", "Необхідні права модератора"}.
-{"JID ~s is invalid", "JID ~s недопустимий"}.
-{"Nickname ~s does not exist in the room", "Псевдонім ~s в кімнаті відсутній"}.
-{"Invalid affiliation: ~s", "Недопустимий ранг: ~s"}.
-{"Invalid role: ~s", "Недопустима роль: ~s"}.
-{"Owner privileges required", "Необхідні права власника"}.
-{"private, ", "приватна, "}.
-{"Description", "Опис"}.
-{"Number of occupants", "Кількість присутніх"}.
-
-% mod_irc/mod_irc.erl
-{"ejabberd IRC module\nCopyright (c) 2003-2006 Alexey Shchepin",
- "ejabberd IRC модуль\nCopyright (c) 2003-2006 Олексій Щепін"}.
-{"You need an x:data capable client to configure mod_irc settings",
- "Для налагодження параметрів mod_irc необхідний x:data-придатний клієнт"}.
-{"Registration in mod_irc for ", "Реєстрація в mod_irc для "}.
-{"Enter username and encodings you wish to use for connecting to IRC servers",
- "Введіть ім'я користувача та кодування, які будуть використовуватися при підключенні до IRC-серверів"}.
-{"IRC Username", "Ім'я користувача IRC"}.
-{"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.", "Щоб вказати різні кодування для різних серверів IRC, заповніть список значеннями в форматі '{\"irc server\", \"encoding\"}'. За замовчуванням ця служба використовує кодування \"~s\"."}.
-{"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].", "Приклад: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}]."}.
-{"Encodings", "Кодування"}.
-
-% web/ejabberd_web_admin.erl
-{"ejabberd Web Interface", "Web-інтерфейс ejabberd"}.
-{"Administration", "Адміністрування"}.
-{"Users", "Користувачі"}.
-{"Nodes", "Вузли"}.
-{"Statistics", "Статистика"}.
-{"(Raw)", "(Необроблений формат)"}.
-{"Submitted", "Відправлено"}.
-{"Bad format", "Неправильний формат"}.
-{"Raw", "необроблений формат"}.
-{"Delete Selected", "Видалити виділені"}.
-{"Submit", "Відправити"}.
-{"~s access rule configuration", "Конфігурація правила доступу ~s"}.
-{"Node not found", "Вузол не знайдено"}.
-{"Add New", "Додати"}.
-{"Registered Users", "Зареєстровані користувачі"}.
-{"Registered Users:", "Зареєстровані користувачі:"}.
-{"Authenticated Users:", "Аутентифіковані користувачі:"}.
-{"Online Users", "Підключені користувачі"}.
-{"Online Users:", "Підключені користувачі:"}.
-{"Outgoing s2s Connections:", "Вихідні s2s-з'єднання:"}.
-{"Outgoing s2s Servers:", "Вихідні s2s-сервери:"}.
-{"Change Password", "Змінити пароль"}.
-{"Connected Resources:", "Підключені ресурси:"}.
-{"Password:", "Пароль:"}.
-{"None", "Немає"}.
-{"Node ", "Вузол "}.
-{"Listened Ports", "Відкриті порти"}.
-{"Restart", "Перезапустити"}.
-{"Stop", "Зупинити"}.
-{"RPC Call Error", "Помилка виклику RPC"}.
-{"Database Tables at ", "Таблиці бази даних на "}.
-{"Name", "Назва"}.
-{"Storage Type", "Тип таблиці"}.
-{"Size", "Розмір"}.
-{"Memory", "Пам'ять"}.
-{"Backup of ", "Резервне копіювання "}.
-{"Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.", "Зауважте, що тут відбувається резервне копіювання тільки вбудованної бази даних Mnesia. Якщо Ви також використовуєте інше сховище для даних (наприклад за допомогою модуля ODBC), то його резервне копіювання потрібно робити окремо."}.
-{"Store binary backup:", "Зберегти бінарну резервну копію:"}.
-{"OK", "Продовжити"}.
-{"Restore binary backup immediately:", "Відновити з бінарної резервної копії негайно:"}.
-{"Restore binary backup after next ejabberd restart (requires less memory):", "Відновити з бінарної резервної копії при наступному запуску (потребує менше пам'яті):"}.
-{"Store plain text backup:", "Зберегти текстову резервну копію:"}.
-{"Restore plain text backup immediately:", "Відновити з текстової резервної копії негайно:"}.
-{"Listened Ports at ", "Відкриті порти на "}.
-{"Statistics of ~p", "статистика вузла ~p"}.
-{"Uptime:", "Час роботи:"}.
-{"CPU Time:", "Процесорний час:"}.
-{"Transactions Commited:", "Транзакції завершені:"}.
-{"Transactions Aborted:", "Транзакції відмінені:"}.
-{"Transactions Restarted:", "Транзакції перезапущені:"}.
-{"Transactions Logged:", "Транзакції запротокольовані:"}.
-{"Update ", "Поновлення "}.
-{"Update plan", "План поновлення"}.
-{"Updated modules", "Поновлені модулі"}.
-{"Update script", "Сценарій поновлення"}.
-{"Low level update script", "Низькорівневий сценарій поновлення"}.
-{"Script check", "Перевірка сценарію"}.
-{"Port", "Порт"}.
-{"Module", "Модуль"}.
-{"Options", "Параметри"}.
-{"Update", "Обновити"}.
-{"Delete", "Видалити"}.
-{"Add User", "Додати користувача"}.
-{"ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One",
- "ejabberd (c) 2002-2006 Олексій Щепін, 2004-2006 Process One"}.
-{"Offline Messages", "Офлайнові повідомлення"}.
-{"Offline Messages:", "Офлайнові повідомлення:"}.
-{"Last Activity", "Останнє підключення"}.
-{"Never", "Ніколи"}.
-{"~s's Offline Messages Queue", "Черга офлайнових повідомлень ~s"}.
-{"Time", "Час"}.
-{"From", "Від кого"}.
-{"To", "Кому"}.
-{"Packet", "Пакет"}.
-{"Roster", "Ростер"}.
-{"Nickname", "Псевдонім"}.
-{"Subscription", "Підписка"}.
-{"Pending", "Очікування"}.
-{"Groups", "Групи"}.
-{"Remove", "Видалити"}.
-{"Add Jabber ID", "Додати Jabber ID"}.
-{"User ", "Користувач "}.
-{"Roster of ", "Ростер користувача "}.
-{"Shared Roster", "Спільні контакти"}.
-{"Online", "Підключений"}.
-{"Validate", "Затвердити"}.
-{"Not Found", "Не знайдено"}.
-{"Shared Roster Groups", "Спільні групи контактів"}.
-{"Name:", "Назва:"}.
-{"Description:", "Опис:"}.
-{"Members:", "Члени:"}.
-{"Displayed Groups:", "Видимі групи:"}.
-{"Group ", "Група "}.
-{"Users Last Activity", "Статистика останнього підключення користувачів"}.
-{"Period: ", "Період"}.
-{"Last month", "За останній місяць"}.
-{"Last year", "За останній рік"}.
-{"All activity", "Вся статистика"}.
-{"Show Ordinary Table", "Показати звичайну таблицю"}.
-{"Show Integral Table", "Показати інтегральну таблицю"}.
-{"Start", "Запустити"}.
-{"Modules at ", "Модулі на "}.
-{"No Data", "Немає даних"}.
-{"Virtual Hosts", "Віртуальні хости"}.
-{"ejabberd virtual hosts", "віртуальні хости ejabberd"}.
-{"Host", "Хост"}.
-
-% Local Variables:
-% mode: erlang
-% End:
diff --git a/ejabberd-1.1.2/src/odbc/Makefile.in b/ejabberd-1.1.2/src/odbc/Makefile.in
deleted file mode 100644
index af2a2463f..000000000
--- a/ejabberd-1.1.2/src/odbc/Makefile.in
+++ /dev/null
@@ -1,33 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@ @ERLANG_CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@ @ERLANG_LIBS@
-
-SUBDIRS =
-
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-OBJS = \
- $(OUTDIR)/ejabberd_odbc.beam \
- $(OUTDIR)/ejabberd_odbc_sup.beam \
- $(OUTDIR)/odbc_queries.beam
-
-all: $(OBJS)
-
-$(OUTDIR)/%.beam: %.erl
- @ERLC@ -W $(EFLAGS) -D@db_type@ -o $(OUTDIR) $<
-
-
-clean:
- rm -f $(OBJS)
-
-distclean: clean
- rm -f Makefile
-
-TAGS:
- etags *.erl
-
diff --git a/ejabberd-1.1.2/src/odbc/Makefile.win32 b/ejabberd-1.1.2/src/odbc/Makefile.win32
deleted file mode 100644
index cd9fbfbe2..000000000
--- a/ejabberd-1.1.2/src/odbc/Makefile.win32
+++ /dev/null
@@ -1,25 +0,0 @@
-
-include ..\Makefile.inc
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-
-OBJS = \
- $(OUTDIR)\ejabberd_odbc.beam \
- $(OUTDIR)\ejabberd_odbc_sup.beam \
- $(OUTDIR)\odbc_queries.beam
-
-ALL : $(OBJS)
-
-CLEAN :
- -@erase $(OBJS)
-
-$(OUTDIR)\ejabberd_odbc.beam : ejabberd_odbc.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_odbc.erl
-
-$(OUTDIR)\ejabberd_odbc_sup.beam : ejabberd_odbc_sup.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_odbc_sup.erl
-
-$(OUTDIR)\odbc_queries.beam : odbc_queries.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) -D$(DBTYPE) odbc_queries.erl
-
diff --git a/ejabberd-1.1.2/src/odbc/ejabberd_odbc.erl b/ejabberd-1.1.2/src/odbc/ejabberd_odbc.erl
deleted file mode 100644
index b4fd41244..000000000
--- a/ejabberd-1.1.2/src/odbc/ejabberd_odbc.erl
+++ /dev/null
@@ -1,298 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_odbc.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Serve ODBC connection
-%%% Created : 8 Dec 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_odbc).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
-
-%% External exports
--export([start/1, start_link/1,
- sql_query/2,
- sql_query_t/1,
- sql_transaction/2,
- escape/1,
- escape_like/1]).
-
-%% gen_server callbacks
--export([init/1,
- handle_call/3,
- handle_cast/2,
- code_change/3,
- handle_info/2,
- terminate/2]).
-
--include("ejabberd.hrl").
-
--record(state, {db_ref, db_type}).
-
--define(STATE_KEY, ejabberd_odbc_state).
--define(MAX_TRANSACTION_RESTARTS, 10).
--define(MYSQL_PORT, 3306).
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-start(Host) ->
- gen_server:start(ejabberd_odbc, [Host], []).
-
-start_link(Host) ->
- gen_server:start_link(ejabberd_odbc, [Host], []).
-
-sql_query(Host, Query) ->
- gen_server:call(ejabberd_odbc_sup:get_random_pid(Host),
- {sql_query, Query}, 60000).
-
-%% SQL transaction based on a list of queries
-%% This function automatically
-sql_transaction(Host, Queries) when is_list(Queries) ->
- F = fun() ->
- lists:foreach(fun(Query) ->
- sql_query_t(Query)
- end,
- Queries)
- end,
- sql_transaction(Host, F);
-%% SQL transaction, based on a erlang anonymous function (F = fun)
-sql_transaction(Host, F) ->
- gen_server:call(ejabberd_odbc_sup:get_random_pid(Host),
- {sql_transaction, F}, 60000).
-
-%% This function is intended to be used from inside an sql_transaction:
-sql_query_t(Query) ->
- State = get(?STATE_KEY),
- QRes = sql_query_internal(State, Query),
- case QRes of
- {error, "No SQL-driver information available."} ->
- % workaround for odbc bug
- {updated, 0};
- {error, _} ->
- throw(aborted);
- Rs when is_list(Rs) ->
- case lists:keymember(error, 1, Rs) of
- true ->
- throw(aborted);
- _ ->
- QRes
- end;
- _ ->
- QRes
- end.
-
-%% Escape character that will confuse an SQL engine
-escape(S) when is_list(S) ->
- [odbc_queries:escape(C) || C <- S].
-
-%% Escape character that will confuse an SQL engine
-%% Percent and underscore only need to be escaped for pattern matching like
-%% statement
-escape_like(S) when is_list(S) ->
- [escape_like(C) || C <- S];
-escape_like($%) -> "\\%";
-escape_like($_) -> "\\_";
-escape_like(C) -> odbc_queries:escape(C).
-
-
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_server
-%%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%%----------------------------------------------------------------------
-init([Host]) ->
- SQLServer = ejabberd_config:get_local_option({odbc_server, Host}),
- case SQLServer of
- {pgsql, Server, DB, Username, Password} ->
- pgsql_connect(Server, DB, Username, Password);
- {mysql, Server, DB, Username, Password} ->
- mysql_connect(Server, DB, Username, Password);
- _ when is_list(SQLServer) ->
- odbc_connect(SQLServer)
- end.
-
-
-%%----------------------------------------------------------------------
-%% Func: handle_call/3
-%% Returns: {reply, Reply, State} |
-%% {reply, Reply, State, Timeout} |
-%% {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, Reply, State} | (terminate/2 is called)
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-handle_call({sql_query, Query}, _From, State) ->
- Reply = sql_query_internal(State, Query),
- {reply, Reply, State};
-
-handle_call({sql_transaction, F}, _From, State) ->
- Reply = execute_transaction(State, F, ?MAX_TRANSACTION_RESTARTS),
- {reply, Reply, State};
-
-handle_call(_Request, _From, State) ->
- Reply = ok,
- {reply, Reply, State}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_cast/2
-%% Returns: {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-handle_cast(_Msg, State) ->
- {noreply, State}.
-
-
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/2
-%% Returns: {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State} (terminate/2 is called)
-%%----------------------------------------------------------------------
-%% We receive the down signal when we loose the MySQL connection (we are
-%% monitoring the connection)
-%% => We exit and let the supervisor restart the connection.
-handle_info({'DOWN', _MonitorRef, process, _Pid, _Info}, State) ->
- {stop, connection_dropped, State};
-handle_info(_Info, State) ->
- {noreply, State}.
-
-%%----------------------------------------------------------------------
-%% Func: terminate/2
-%% Purpose: Shutdown the server
-%% Returns: any (ignored by gen_server)
-%%----------------------------------------------------------------------
-terminate(_Reason, _State) ->
- ok.
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-sql_query_internal(State, Query) ->
- case State#state.db_type of
- odbc ->
- odbc:sql_query(State#state.db_ref, Query);
- pgsql ->
- pgsql_to_odbc(pgsql:squery(State#state.db_ref, Query));
- mysql ->
- mysql_to_odbc(mysql_conn:fetch(State#state.db_ref, Query, self()))
- end.
-
-execute_transaction(_State, _F, 0) ->
- {aborted, restarts_exceeded};
-execute_transaction(State, F, NRestarts) ->
- put(?STATE_KEY, State),
- sql_query_internal(State, "begin;"),
- case catch F() of
- aborted ->
- execute_transaction(State, F, NRestarts - 1);
- {'EXIT', Reason} ->
- sql_query_internal(State, "rollback;"),
- {aborted, Reason};
- Res ->
- sql_query_internal(State, "commit;"),
- {atomic, Res}
- end.
-
-%% == pure ODBC code
-
-%% part of init/1
-%% Open an ODBC database connection
-odbc_connect(SQLServer) ->
- case odbc:connect(SQLServer,[{scrollable_cursors, off}]) of
- {ok, Ref} ->
- erlang:monitor(process, Ref),
- {ok, #state{db_ref = Ref, db_type = odbc}};
- {error, Reason} ->
- ?ERROR_MSG("ODBC connection (~s) failed: ~p~n",
- [SQLServer, Reason]),
- %% If we can't connect we wait for 30 seconds before retrying
- timer:sleep(30000),
- {stop, odbc_connection_failed}
- end.
-
-
-%% == Native PostgreSQL code
-
-%% part of init/1
-%% Open a database connection to PostgreSQL
-pgsql_connect(Server, DB, Username, Password) ->
- case pgsql:connect(Server, DB, Username, Password) of
- {ok, Ref} ->
- {ok, #state{db_ref = Ref, db_type = pgsql}};
- {error, Reason} ->
- ?ERROR_MSG("PostgreSQL connection failed: ~p~n", [Reason]),
- %% If we can't connect we wait for 30 seconds before retrying
- timer:sleep(30000),
- {stop, pgsql_connection_failed}
- end.
-
-%% Convert PostgreSQL query result to Erlang ODBC result formalism
-pgsql_to_odbc({ok, PGSQLResult}) ->
- case PGSQLResult of
- [Item] ->
- pgsql_item_to_odbc(Item);
- Items ->
- [pgsql_item_to_odbc(Item) || Item <- Items]
- end.
-
-pgsql_item_to_odbc({"SELECT", Rows, Recs}) ->
- {selected,
- [element(1, Row) || Row <- Rows],
- [list_to_tuple(Rec) || Rec <- Recs]};
-pgsql_item_to_odbc("INSERT " ++ OIDN) ->
- [_OID, N] = string:tokens(OIDN, " "),
- {updated, list_to_integer(N)};
-pgsql_item_to_odbc("DELETE " ++ N) ->
- {updated, list_to_integer(N)};
-pgsql_item_to_odbc({error, Error}) ->
- {error, Error};
-pgsql_item_to_odbc(_) ->
- {updated,undefined}.
-
-%% == Native MySQL code
-
-%% part of init/1
-%% Open a database connection to MySQL
-mysql_connect(Server, DB, Username, Password) ->
- NoLogFun = fun(_Level,_Format,_Argument) -> ok end,
- case mysql_conn:start(Server, ?MYSQL_PORT, Username, Password, DB, NoLogFun) of
- {ok, Ref} ->
- erlang:monitor(process, Ref),
- {ok, #state{db_ref = Ref, db_type = mysql}};
- {error, Reason} ->
- ?ERROR_MSG("MySQL connection failed: ~p~n", [Reason]),
- %% If we can't connect we wait for 30 seconds before retrying
- timer:sleep(30000),
- {stop, mysql_connection_failed}
- end.
-
-%% Convert MySQL query result to Erlang ODBC result formalism
-mysql_to_odbc({updated, MySQLRes}) ->
- {updated, mysql:get_result_affected_rows(MySQLRes)};
-mysql_to_odbc({data, MySQLRes}) ->
- mysql_item_to_odbc(mysql:get_result_field_info(MySQLRes),
- mysql:get_result_rows(MySQLRes));
-mysql_to_odbc({error, MySQLRes}) ->
- {error, mysql:get_result_reason(MySQLRes)}.
-
-%% When tabular data is returned, convert it to the ODBC formalism
-mysql_item_to_odbc(Columns, Recs) ->
- %% For now, there is a bug and we do not get the correct value from MySQL
- %% module:
- {selected,
- [element(2, Column) || Column <- Columns],
- [list_to_tuple(Rec) || Rec <- Recs]}.
diff --git a/ejabberd-1.1.2/src/odbc/ejabberd_odbc_sup.erl b/ejabberd-1.1.2/src/odbc/ejabberd_odbc_sup.erl
deleted file mode 100644
index 7bb3a583f..000000000
--- a/ejabberd-1.1.2/src/odbc/ejabberd_odbc_sup.erl
+++ /dev/null
@@ -1,48 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_odbc_sup.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : ODBC connections supervisor
-%%% Created : 22 Dec 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_odbc_sup).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([start_link/1,
- init/1,
- get_pids/1,
- get_random_pid/1
- ]).
-
--include("ejabberd.hrl").
-
-start_link(Host) ->
- supervisor:start_link({local, gen_mod:get_module_proc(Host, ?MODULE)},
- ?MODULE, [Host]).
-
-init([Host]) ->
- % TODO
- N = 10,
- {ok, {{one_for_one, 10, 6},
- lists:map(
- fun(I) ->
- {I,
- {ejabberd_odbc, start_link, [Host]},
- transient,
- brutal_kill,
- worker,
- [?MODULE]}
- end, lists:seq(1, N))}}.
-
-get_pids(Host) ->
- Proc = gen_mod:get_module_proc(Host, ?MODULE),
- [Child ||
- {_Id, Child, _Type, _Modules} <- supervisor:which_children(Proc),
- Child /= undefined].
-
-get_random_pid(Host) ->
- Pids = get_pids(Host),
- lists:nth(erlang:phash(now(), length(Pids)), Pids).
-
diff --git a/ejabberd-1.1.2/src/odbc/mssql.sql b/ejabberd-1.1.2/src/odbc/mssql.sql
deleted file mode 100644
index 49fcd218c..000000000
--- a/ejabberd-1.1.2/src/odbc/mssql.sql
+++ /dev/null
@@ -1,899 +0,0 @@
-SET ANSI_NULLS ON
-GO
-SET QUOTED_IDENTIFIER ON
-GO
-
-exec sp_dboption N'ejabberd', N'autoclose', N'false'
-GO
-
-exec sp_dboption N'ejabberd', N'bulkcopy', N'true'
-GO
-
-exec sp_dboption N'ejabberd', N'trunc. log', N'false'
-GO
-
-exec sp_dboption N'ejabberd', N'torn page detection', N'true'
-GO
-
-exec sp_dboption N'ejabberd', N'read only', N'false'
-GO
-
-exec sp_dboption N'ejabberd', N'dbo use', N'false'
-GO
-
-exec sp_dboption N'ejabberd', N'single', N'false'
-GO
-
-exec sp_dboption N'ejabberd', N'autoshrink', N'false'
-GO
-
-exec sp_dboption N'ejabberd', N'ANSI null default', N'false'
-GO
-
-exec sp_dboption N'ejabberd', N'recursive triggers', N'false'
-GO
-
-exec sp_dboption N'ejabberd', N'ANSI nulls', N'false'
-GO
-
-exec sp_dboption N'ejabberd', N'concat null yields null', N'false'
-GO
-
-exec sp_dboption N'ejabberd', N'cursor close on commit', N'false'
-GO
-
-exec sp_dboption N'ejabberd', N'default to local cursor', N'false'
-GO
-
-exec sp_dboption N'ejabberd', N'quoted identifier', N'false'
-GO
-
-exec sp_dboption N'ejabberd', N'ANSI warnings', N'false'
-GO
-
-exec sp_dboption N'ejabberd', N'auto create statistics', N'true'
-GO
-
-exec sp_dboption N'ejabberd', N'auto update statistics', N'true'
-GO
-
-use [ejabberd]
-GO
-
-if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[last]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
-drop table [dbo].[last]
-GO
-
-if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[rostergroups]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
-drop table [dbo].[rostergroups]
-GO
-
-if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[rosterusers]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
-drop table [dbo].[rosterusers]
-GO
-
-if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[spool]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
-drop table [dbo].[spool]
-GO
-
-if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[users]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
-drop table [dbo].[users]
-GO
-
-if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[vcard]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
-drop table [dbo].[vcard]
-GO
-
-CREATE TABLE [dbo].[last] (
- [username] [varchar] (250) NOT NULL ,
- [seconds] [varchar] (50) NOT NULL ,
- [state] [varchar] (100) NULL ,
-) ON [PRIMARY]
-GO
-
-CREATE TABLE [dbo].[rostergroups] (
- [username] [varchar] (250) NOT NULL ,
- [jid] [varchar] (250) NOT NULL ,
- [grp] [varchar] (100) NOT NULL
-) ON [PRIMARY]
-GO
-
-CREATE TABLE [dbo].[rosterusers] (
- [username] [varchar] (250) NOT NULL ,
- [jid] [varchar] (250) NOT NULL ,
- [nick] [varchar] (50) NULL ,
- [subscription] [char] (1) NOT NULL ,
- [ask] [char] (1) NOT NULL ,
- [askmessage] [varchar] (250) NULL ,
- [server] [char] (1) NOT NULL ,
- [subscribe] [varchar] (200) NULL ,
- [type] [varchar] (50) NULL
-) ON [PRIMARY]
-GO
-
-CREATE TABLE [dbo].[spool] (
- [id] [numeric](19, 0) IDENTITY (1, 1) NOT NULL ,
- [username] [varchar] (250) NOT NULL ,
- [xml] [text] NULL ,
- [notifyprocessed] [bit] NULL ,
- [created] [datetime] NULL ,
-) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
-GO
-
-CREATE TABLE [dbo].[users] (
- [username] [varchar] (250) NOT NULL ,
- [password] [varchar] (50) NOT NULL ,
- [created] [datetime] NULL
-) ON [PRIMARY]
-GO
-
-CREATE TABLE [dbo].[vcard] (
- [username] [varchar] (250) NOT NULL ,
- [full_name] [varchar] (250) NULL ,
- [first_name] [varchar] (50) NULL ,
- [last_name] [varchar] (50) NULL ,
- [nick_name] [varchar] (50) NULL ,
- [url] [varchar] (1024) NULL ,
- [address1] [varchar] (50) NULL ,
- [address2] [varchar] (50) NULL ,
- [locality] [varchar] (50) NULL ,
- [region] [varchar] (50) NULL ,
- [pcode] [varchar] (50) NULL ,
- [country] [varchar] (50) NULL ,
- [telephone] [varchar] (50) NULL ,
- [email] [varchar] (250) NULL ,
- [orgname] [varchar] (50) NULL ,
- [orgunit] [varchar] (50) NULL ,
- [title] [varchar] (50) NULL ,
- [role] [varchar] (50) NULL ,
- [b_day] [datetime] NULL ,
- [descr] [varchar] (500) NULL
-) ON [PRIMARY]
-GO
-
-ALTER TABLE [dbo].[last] WITH NOCHECK ADD
- CONSTRAINT [PK_last] PRIMARY KEY CLUSTERED
- (
- [username]
- ) WITH FILLFACTOR = 90 ON [PRIMARY]
-GO
-
-ALTER TABLE [dbo].[rostergroups] WITH NOCHECK ADD
- CONSTRAINT [PK_rostergroups] PRIMARY KEY CLUSTERED
- (
- [username],
- [jid],
- [grp]
- ) WITH FILLFACTOR = 90 ON [PRIMARY]
-GO
-
-ALTER TABLE [dbo].[spool] WITH NOCHECK ADD
- CONSTRAINT [PK_spool] PRIMARY KEY CLUSTERED
- (
- [username],
- [id]
- ) WITH FILLFACTOR = 90 ON [PRIMARY]
-GO
-
-ALTER TABLE [dbo].[users] WITH NOCHECK ADD
- CONSTRAINT [PK_users] PRIMARY KEY CLUSTERED
- (
- [username]
- ) WITH FILLFACTOR = 90 ON [PRIMARY]
-GO
-
-ALTER TABLE [dbo].[vcard] WITH NOCHECK ADD
- CONSTRAINT [PK_vcard] PRIMARY KEY CLUSTERED
- (
- [username]
- ) WITH FILLFACTOR = 90 ON [PRIMARY]
-GO
-
- CREATE CLUSTERED INDEX [IX_rosterusers_user] ON [dbo].[rosterusers]([username]) WITH FILLFACTOR = 90 ON [PRIMARY]
-GO
-
-ALTER TABLE [dbo].[last] WITH NOCHECK ADD
- CONSTRAINT [DF_last_updated] DEFAULT (getdate()) FOR [Modify_Date]
-GO
-
-ALTER TABLE [dbo].[spool] WITH NOCHECK ADD
- CONSTRAINT [DF_spool_notifyprocessed] DEFAULT (0) FOR [notifyprocessed],
- CONSTRAINT [DF_spool_created] DEFAULT (getdate()) FOR [created],
- CONSTRAINT [DF_spool_MustDelete] DEFAULT (0) FOR [MustDelete]
-GO
-
-ALTER TABLE [dbo].[users] WITH NOCHECK ADD
- CONSTRAINT [DF_users_created] DEFAULT (getdate()) FOR [created]
-GO
-
- CREATE INDEX [IX_rostergroups_jid] ON [dbo].[rostergroups]([jid]) WITH FILLFACTOR = 90 ON [PRIMARY]
-GO
-
- CREATE INDEX [IX_rostergroups_user] ON [dbo].[rostergroups]([username]) WITH FILLFACTOR = 90 ON [PRIMARY]
-GO
-
- CREATE INDEX [IX_rosterusers_jid] ON [dbo].[rosterusers]([username], [jid]) WITH FILLFACTOR = 90 ON [PRIMARY]
-GO
-
- CREATE INDEX [IX_spool_user] ON [dbo].[spool]([username]) WITH FILLFACTOR = 90 ON [PRIMARY]
-GO
-
- CREATE INDEX [IX_spool_process] ON [dbo].[spool]([created], [notifyprocessed]) WITH FILLFACTOR = 90 ON [PRIMARY]
-GO
-
- CREATE INDEX [IK_Spool_Del] ON [dbo].[spool]([MustDelete]) WITH FILLFACTOR = 90 ON [PRIMARY]
-GO
-
- CREATE INDEX [IK_Spool_Created] ON [dbo].[spool]([created]) WITH FILLFACTOR = 90 ON [PRIMARY]
-GO
-
-/*********************************************************/
-/** These store procedures are for use with ejabberd **/
-/** 1.1 and Microsoft Sql Server 2000 **/
-/** **/
-/** The stored procedures reduce the need to sql **/
-/** compilation of the database and also allow for also **/
-/** provide each of database integration. The store **/
-/** procedure have been optimized to increase database **/
-/** performance and a reduction of 80% in CPU was **/
-/** achive over the use of standard sql. **/
-/*********************************************************/
-
-/****** Object: StoredProcedure [dbo].[add_roster] ******/
-/** Add or update user entries in the roster **/
-/*********************************************************/
-CREATE PROCEDURE [dbo].[add_roster]
- @Username varchar(250),
- @JID varchar(250),
- @Nick varchar(50),
- @Subscription char(1),
- @Ask char(1),
- @AskMessage varchar(250),
- @Server char(1),
- @Subscribe varchar(200),
- @Type varchar(50),
- @Grp varchar(100)
-AS
-BEGIN
- BEGIN TRANSACTION
- --- Update Roster if user exist else add roster item
- IF EXISTS (SELECT username FROM rosterusers WITH (NOLOCK) WHERE rosterusers.username=@Username AND rosterusers.jid=@JID)
- BEGIN
- UPDATE rosterusers
- SET rosterusers.username=@Username,
- rosterusers.jid=@JID,
- rosterusers.nick=@Nick,
- rosterusers.subscription=@Subscription,
- rosterusers.ask=@Ask,
- rosterusers.askmessage=@AskMessage,
- rosterusers.server=@Server,
- rosterusers.subscribe=@Subscribe,
- rosterusers.type=@Type
- WHERE (rosterusers.username=@Username) AND (rosterusers.jid=@JID);
- END
- ELSE
- BEGIN
- INSERT INTO rosterusers
- ( rosterusers.username,
- rosterusers.jid,
- rosterusers.nick,
- rosterusers.subscription,
- rosterusers.ask,
- rosterusers.askmessage,
- rosterusers.server,
- rosterusers.subscribe,
- rosterusers.type
- )
- VALUES
- ( @Username,
- @JID,
- @Nick,
- @Subscription,
- @Ask,
- @AskMessage,
- @Server,
- @Subscribe,
- @Type
- );
- END
-
- --- Update Roster Groups if exist else add group entry
- IF NOT EXISTS (SELECT username FROM rostergroups WITH (NOLOCK) WHERE rostergroups.username=@Username AND rostergroups.jid=@JID AND rostergroups.grp=@Grp)
- BEGIN
- INSERT INTO rostergroups
- ( rostergroups.username,
- rostergroups.jid,
- rostergroups.grp
- )
- VALUES
- ( @Username,
- @JID,
- @Grp
- );
- END
-
- COMMIT
-END
-GO
-
-/***************************************************************/
-/****** Object: StoredProcedure [dbo].[add_roster_group] ******/
-/** Add or update user group entries in the roster groups **/
-/***************************************************************/
-CREATE PROCEDURE [dbo].[add_roster_group]
- @Username varchar(250),
- @JID varchar(250),
- @Grp varchar(100)
-AS
-BEGIN
- --- Update Roster Groups if exist else add group
- IF NOT EXISTS (SELECT username FROM rostergroups WHERE rostergroups.username=@Username AND rostergroups.jid=@JID AND rostergroups.grp=@Grp)
- BEGIN
- INSERT INTO rostergroups
- ( rostergroups.username,
- rostergroups.jid,
- rostergroups.grp
- )
- VALUES
- ( @Username,
- @JID,
- @Grp
- )
- END
-END
-GO
-
-/***************************************************************/
-/****** Object: StoredProcedure [dbo].[add_roster_user] ******/
-/** Add or update user entries in the roster **/
-/***************************************************************/
-CREATE PROCEDURE [dbo].[add_roster_user]
- @Username varchar(250),
- @JID varchar(250),
- @Nick varchar(50),
- @Subscription char(1),
- @Ask char(1),
- @AskMessage varchar(250),
- @Server char(1),
- @Subscribe varchar(200),
- @Type varchar(50),
- @Grp varchar(100) = Null
-AS
-BEGIN
- BEGIN TRANSACTION
- --- Update Roster Users if exist of add new user
- IF EXISTS (SELECT username FROM rosterusers WHERE rosterusers.username=@Username AND rosterusers.jid=@JID)
- BEGIN
- UPDATE rosterusers
- SET rosterusers.username=@Username,
- rosterusers.jid=@JID,
- rosterusers.nick=@Nick,
- rosterusers.subscription=@Subscription,
- rosterusers.ask=@Ask,
- rosterusers.askmessage=@AskMessage,
- rosterusers.server=@Server,
- rosterusers.subscribe=@Subscribe,
- rosterusers.type=@Type
- WHERE (rosterusers.username=@Username) AND (rosterusers.jid=@JID);
- END
- ELSE
- BEGIN
- INSERT INTO rosterusers
- ( rosterusers.username,
- rosterusers.jid,
- rosterusers.nick,
- rosterusers.subscription,
- rosterusers.ask,
- rosterusers.askmessage,
- rosterusers.server,
- rosterusers.subscribe,
- rosterusers.type
- )
- VALUES
- ( @Username,
- @JID,
- @Nick,
- @Subscription,
- @Ask,
- @AskMessage,
- @Server,
- @Subscribe,
- @Type
- );
- END
-
- --- Update Roster Group if exist of add new group
- IF @Grp IS NOT NULL
- EXECUTE [dbo].[add_roster_group] @Username, @JID, @Grp
-
- COMMIT
-END
-GO
-
-/***************************************************************/
-/****** Object: StoredProcedure [dbo].[del_roster_groups] ******/
-/** Remove user group entries from the roster groups table **/
-/***************************************************************/
-CREATE PROCEDURE [dbo].[del_roster_groups]
- @Username varchar(250),
- @JID varchar(250)
-AS
-BEGIN
- DELETE FROM rostergroups
- WITH (ROWLOCK)
- WHERE (rostergroups.username = @Username) AND (rostergroups.jid = @JID);
-END
-GO
-
-/***************************************************************/
-/****** Object: StoredProcedure [dbo].[add_spool] ******/
-/** Add a entry to the spool table **/
-/***************************************************************/
-CREATE PROCEDURE [dbo].[add_spool]
- @Username varchar(250),
- @XML varchar(8000)
-AS
-BEGIN
- INSERT INTO spool
- ( spool.username,
- spool.xml
- )
- VALUES
- ( @Username,
- @XML
- )
-END
-GO
-
-/***************************************************************/
-/****** Object: StoredProcedure [dbo].[add_user] ******/
-/** Add or update user entries to jabber **/
-/***************************************************************/
-CREATE PROCEDURE [dbo].[add_user]
- @Username varchar(200),
- @Password varchar(50)
-AS
-BEGIN
- INSERT INTO users
- ( username,
- [password]
- )
- VALUES
- ( @Username,
- @Password
- );
-END
-GO
-
-/******************************************************************/
-/****** Object: StoredProcedure [dbo].[set_password] **/
-/** Update users password **/
-/******************************************************************/
-CREATE PROCEDURE [dbo].[set_password]
- @Username varchar(200),
- @Password varchar(50)
-AS
-BEGIN
- IF EXISTS (SELECT username FROM users WITH (NOLOCK) WHERE username=@Username)
- BEGIN
- UPDATE users SET username=@Username, password=@Password WHERE username=@Username;
- END
- ELSE
- BEGIN
- INSERT INTO users (username, password) VALUES (@Username, @Password);
- END
-END
-GO
-/******************************************************************/
-/****** Object: StoredProcedure [dbo].[get_password] **/
-/** Retrive the user password **/
-/******************************************************************/
-CREATE PROCEDURE [dbo].[get_password]
- @Username varchar(200)
-AS
-BEGIN
- SELECT users.password as password
- FROM users WITH (NOLOCK)
- WHERE username=@Username;
-END
-GO
-
-/***************************************************************/
-/****** Object: StoredProcedure [dbo].[clean_spool_msg] ******/
-/** Delete messages older that 3 days from spool **/
-/***************************************************************/
-CREATE PROCEDURE [dbo].[clean_spool_msg]
-AS
-DECLARE
- @dt datetime,
- @myRowCount int
-BEGIN
- -- Delete small amounts because if locks the database table
- SET ROWCOUNT 500
- SET @myRowCount = 1
-
- WHILE (@myRowCount) > 0
- BEGIN
- BEGIN TRANSACTION
- SELECT @dt = DATEADD(d, -3, GETDATE())
- DELETE FROM spool
- WITH (ROWLOCK)
- WHERE (MustDelete=1) OR (Created < @dt);
-
- SET @myRowCount = @@RowCount
- COMMIT
- END
-END
-GO
-
-/***************************************************************/
-/****** Object: StoredProcedure [dbo].[del_last] ******/
-/** Delete an entry from the last table **/
-/***************************************************************/
-CREATE PROCEDURE [dbo].[del_last]
- @Username varchar(250)
-AS
-BEGIN
- DELETE FROM [last]
- WITH (ROWLOCK)
- WHERE [last].username=@Username;
-END
-GO
-
-/***************************************************************/
-/****** Object: StoredProcedure [dbo].[del_roster] ******/
-/** Delete an entry from the roster **/
-/***************************************************************/
-CREATE PROCEDURE [dbo].[del_roster]
- @Username varchar(250),
- @JID varchar(250)
-AS
-BEGIN
- BEGIN TRANSACTION
- DELETE FROM rosterusers
- WITH (ROWLOCK)
- WHERE (rosterusers.username = @Username) AND (rosterusers.jid = @JID);
-
- DELETE FROM rostergroups
- WITH (ROWLOCK)
- WHERE (rostergroups.username = @Username) AND (rostergroups.jid = @JID);
-
- COMMIT
-END
-GO
-
-
-/***************************************************************/
-/****** Object: StoredProcedure [dbo].[del_spool_msg] ******/
-/** Delete an entry from the spool table **/
-/***************************************************************/
-CREATE PROCEDURE [dbo].[del_spool_msg]
- @Username varchar(250)
-AS
-BEGIN
- DELETE FROM spool
- WITH (ROWLOCK)
- WHERE spool.username=@Username;
-END
-GO
-
-/***************************************************************/
-/****** Object: StoredProcedure [dbo].[del_user] ******/
-/** Delete an entry from the user table **/
-/***************************************************************/
-CREATE PROCEDURE [dbo].[del_user]
- @Username varchar(200)
-AS
-BEGIN
- DELETE FROM users
- WITH (ROWLOCK)
- WHERE username=@Username;
-END
-GO
-
-/******************************************************************/
-/****** Object: StoredProcedure [dbo].[del_user_return_password]**/
-/** Delete an entry from the user table and return user password **/
-/******************************************************************/
-CREATE PROCEDURE [dbo].[del_user_return_password]
- @Username varchar(250)
-AS
-DECLARE
- @Pwd varchar(50)
-BEGIN
- EXECUTE @Pwd = dbo.get_password @Username
- DELETE FROM users
- WITH (ROWLOCK)
- WHERE username=@Username
-
- SELECT @Pwd;
-END
-GO
-
-
-/******************************************************************/
-/****** Object: StoredProcedure [dbo].[del_user_roster] **/
-/** Delete the users roster **/
-/******************************************************************/
-CREATE PROCEDURE [dbo].[del_user_roster]
- @Username varchar(250)
-AS
-BEGIN
- BEGIN TRANSACTION
- DELETE FROM rosterusers
- WITH (ROWLOCK)
- WHERE rosterusers.username = @Username;
-
- DELETE FROM rostergroups
- WITH (ROWLOCK)
- WHERE rostergroups.username = @Username;
-
- COMMIT
-END
-GO
-
-
-/******************************************************************/
-/****** Object: StoredProcedure [dbo].[get_and_del_spool_msg] **/
-/** Fetch and delete the users offline messages **/
-/******************************************************************/
-CREATE PROCEDURE [dbo].[get_and_del_spool_msg]
- @Username varchar(250)
-AS
-DECLARE
- @vSpool table( username varchar(1),
- xml varchar(1))
-BEGIN
- IF EXISTS (SELECT username FROM spool with (nolock) WHERE spool.username=@Username)
- BEGIN
- SELECT spool.username AS username,
- spool.xml AS xml
- FROM spool WITH (NOLOCK)
- WHERE spool.username=@Username;
-
- DELETE spool
- WITH (ROWLOCK)
- WHERE spool.username=@Username
- END
- ELSE
- BEGIN
- SELECT * FROM @vSpool;
- END
-END
-GO
-
-/******************************************************************/
-/****** Object: StoredProcedure [dbo].[get_last] **/
-/** Retrive the last user login **/
-/******************************************************************/
-CREATE PROCEDURE [dbo].[get_last]
- @Username varchar(250)
-AS
-BEGIN
- SELECT last.seconds AS seconds,
- last.state AS state
- FROM last WITH (NOLOCK)
- WHERE last.username=@Username;
-END
-GO
-
-/******************************************************************/
-/****** Object: StoredProcedure [dbo].[get_roster] **/
-/** Retrive the user roster **/
-/******************************************************************/
-CREATE PROCEDURE [dbo].[get_roster]
- @Username varchar(200)
-AS
-DECLARE
- @vRosterusers table( username varchar(1),
- jid varchar(1),
- nick varchar(1),
- subscription varchar(1),
- ask varchar(1),
- askmessage varchar(1),
- server varchar(1),
- subscribe varchar(1),
- type varchar(1))
-BEGIN
- IF EXISTS (SELECT username FROM rosterusers with (nolock) WHERE rosterusers.username = @Username)
- BEGIN
- SELECT rosterusers.username AS username,
- rosterusers.jid AS jid,
- rosterusers.nick AS nick,
- rosterusers.subscription AS subscription,
- rosterusers.ask AS ask,
- rosterusers.askmessage AS askmessage,
- rosterusers.server AS server,
- rosterusers.subscribe AS subscribe,
- rosterusers.type AS type
- FROM rosterusers WITH (NOLOCK)
- WHERE rosterusers.username = @Username;
- END
- ELSE
- BEGIN
- SELECT * FROM @vRosterusers
- END
-END
-GO
-
-/******************************************************************/
-/****** Object: StoredProcedure [dbo].[get_roster_by_jid] **/
-/** Retrive the user roster via JID **/
-/******************************************************************/
-CREATE PROCEDURE [dbo].[get_roster_by_jid]
- @Username varchar(200),
- @JID varchar(250)
-AS
-DECLARE
- @vRosterusers table( username varchar(1),
- jid varchar(1),
- nick varchar(1),
- subscription varchar(1),
- ask varchar(1),
- askmessage varchar(1),
- server varchar(1),
- subscribe varchar(1),
- type varchar(1))
-BEGIN
- IF EXISTS (SELECT username FROM rosterusers with (nolock) WHERE (rosterusers.username = @Username) AND (rosterusers.jid = @JID))
- BEGIN
- SELECT rosterusers.username AS username,
- rosterusers.jid AS jid,
- rosterusers.nick AS nick,
- rosterusers.subscription AS subscription,
- rosterusers.ask AS ask,
- rosterusers.askmessage AS askmessage,
- rosterusers.server AS server,
- rosterusers.subscribe AS subscribe,
- rosterusers.type AS type
- FROM rosterusers WITH (NOLOCK)
- WHERE (rosterusers.username = @Username) AND (rosterusers.jid = @JID);
- END
- ELSE
- BEGIN
- SELECT * FROM @vRosterusers
- END
-END
-GO
-
-/******************************************************************/
-/****** Object: StoredProcedure [dbo].[get_roster_jid_groups] **/
-/** Retrieve the user roster groups **/
-/******************************************************************/
-CREATE PROCEDURE [dbo].[get_roster_jid_groups]
- @Username varchar(200)
-AS
-DECLARE
- @vrostergroups table( jid varchar(1),
- grp varchar(1))
-BEGIN
- IF EXISTS (SELECT username FROM rostergroups with (nolock) WHERE rostergroups.username = @Username)
- BEGIN
- SELECT rostergroups.jid AS jid,
- rostergroups.grp AS grp
- FROM rostergroups WITH (NOLOCK)
- WHERE rostergroups.username = @Username;
- END
- ELSE
- BEGIN
- SELECT * FROM @vrostergroups
- END
-END
-GO
-
-/******************************************************************/
-/****** Object: StoredProcedure [dbo].[get_roster_groups] **/
-/** Retrive the user roster groups **/
-/******************************************************************/
-CREATE PROCEDURE [dbo].[get_roster_groups]
- @Username varchar(200),
- @JID varchar(250)
-AS
-DECLARE
- @vrostergroups table( grp varchar(1))
-BEGIN
- IF EXISTS (SELECT username FROM rostergroups with (nolock) WHERE rostergroups.username = @Username)
- BEGIN
- SELECT rostergroups.grp AS grp
- FROM rostergroups WITH (NOLOCK)
- WHERE (rostergroups.username = @Username) AND (rostergroups.jid = @JID);
- END
- ELSE
- BEGIN
- SELECT * FROM @vrostergroups
- END
-END
-GO
-
-/******************************************************************/
-/****** Object: StoredProcedure [dbo].[get_rostergroup_by_jid] **/
-/** Retrive the user roster groups via JID **/
-/******************************************************************/
-CREATE PROCEDURE [dbo].[get_rostergroup_by_jid]
- @Username varchar(250),
- @JID varchar(250)
-AS
-DECLARE
- @vrostergroups table(grp varchar(1))
-BEGIN
- IF EXISTS (SELECT username FROM rostergroups with (nolock) WHERE rostergroups.username=@Username AND rostergroups.jid=@JID)
- BEGIN
- SELECT rostergroups.grp AS grp
- FROM rostergroups WITH (NOLOCK)
- WHERE rostergroups.username=@Username AND rostergroups.jid=@JID;
- END
- ELSE
- BEGIN
- SELECT * FROM @vrostergroups
- END
-END
-GO
-
-/******************************************************************/
-/****** Object: StoredProcedure [dbo].[get_subscription] **/
-/** Retrive the user subscription requests **/
-/******************************************************************/
-CREATE PROCEDURE [dbo].[get_subscription]
- @Username varchar(250),
- @JID varchar(250)
-AS
-DECLARE
- @vrosterusers table( subscription varchar(1))
-BEGIN
- IF EXISTS (SELECT username FROM rosterusers with (nolock) WHERE rosterusers.username=@Username AND rosterusers.jid=@JID)
- BEGIN
- SELECT rosterusers.subscription AS subscription
- FROM rosterusers WITH (NOLOCK)
- WHERE rosterusers.username=@Username AND rosterusers.jid=@JID;
- END
- ELSE
- BEGIN
- SELECT * FROM @vrosterusers
- END
-END
-GO
-
-/******************************************************************/
-/****** Object: StoredProcedure [dbo].[list_users] **/
-/** Retrive a list of all users **/
-/******************************************************************/
-CREATE PROCEDURE [dbo].[list_users]
-AS
-BEGIN
- SELECT users.username AS username FROM users WITH (NOLOCK);
-END
-GO
-
-/******************************************************************/
-/****** Object: StoredProcedure [dbo].[set_last] **/
-/** Update users last login status **/
-/******************************************************************/
-CREATE PROCEDURE [dbo].[set_last]
- @Username varchar(250),
- @Seconds varchar(50),
- @State varchar(100)
-AS
-BEGIN
- IF EXISTS (SELECT username FROM [last] WITH (NOLOCK) WHERE username=@Username)
- BEGIN
- UPDATE [last]
- SET [last].username = @Username,
- [last].seconds = @Seconds,
- [last].state = @State
- WHERE last.username=@Username;
- END
- ELSE
- BEGIN
- INSERT INTO [last]
- ( [last].username,
- [last].seconds,
- [last].state
- )
- VALUES
- ( @Username,
- @Seconds,
- @State
- )
- END
-END
-GO
diff --git a/ejabberd-1.1.2/src/odbc/mysql.sql b/ejabberd-1.1.2/src/odbc/mysql.sql
deleted file mode 100644
index 8642d72a4..000000000
--- a/ejabberd-1.1.2/src/odbc/mysql.sql
+++ /dev/null
@@ -1,96 +0,0 @@
--- Needs MySQL max with innodb back-end
-
-CREATE TABLE users (
- username varchar(250) PRIMARY KEY,
- password text NOT NULL
-) TYPE=InnoDB CHARACTER SET utf8;
-
-
-CREATE TABLE last (
- username varchar(250) PRIMARY KEY,
- seconds text NOT NULL,
- state text
-) TYPE=InnoDB CHARACTER SET utf8;
-
-
-CREATE TABLE rosterusers (
- username varchar(250) NOT NULL,
- jid varchar(250) NOT NULL,
- nick text,
- subscription character(1) NOT NULL,
- ask character(1) NOT NULL,
- askmessage text,
- server character(1) NOT NULL,
- subscribe text,
- type text
-) TYPE=InnoDB CHARACTER SET utf8;
-
-CREATE UNIQUE INDEX i_rosteru_user_jid USING HASH ON rosterusers(username(75), jid(75));
-CREATE INDEX i_rosteru_username USING HASH ON rosterusers(username);
-CREATE INDEX i_rosteru_jid USING HASH ON rosterusers(jid);
-
-CREATE TABLE rostergroups (
- username varchar(250) NOT NULL,
- jid varchar(250) NOT NULL,
- grp text NOT NULL
-) TYPE=InnoDB CHARACTER SET utf8;
-
-CREATE INDEX pk_rosterg_user_jid USING HASH ON rostergroups(username(75), jid(75));
-
-
-CREATE TABLE spool (
- username varchar(250) NOT NULL,
- xml text,
- seq SERIAL
-) TYPE=InnoDB CHARACTER SET utf8;
-
-CREATE INDEX i_despool USING BTREE ON spool(username);
-
-
-CREATE TABLE vcard (
- username varchar(250) PRIMARY KEY,
- vcard text NOT NULL
-) TYPE=InnoDB CHARACTER SET utf8;
-
-
-CREATE TABLE vcard_search (
- username varchar(250) NOT NULL,
- lusername varchar(250) PRIMARY KEY,
- fn text NOT NULL,
- lfn varchar(250) NOT NULL,
- family text NOT NULL,
- lfamily varchar(250) NOT NULL,
- given text NOT NULL,
- lgiven varchar(250) NOT NULL,
- middle text NOT NULL,
- lmiddle varchar(250) NOT NULL,
- nickname text NOT NULL,
- lnickname varchar(250) NOT NULL,
- bday text NOT NULL,
- lbday varchar(250) NOT NULL,
- ctry text NOT NULL,
- lctry varchar(250) NOT NULL,
- locality text NOT NULL,
- llocality varchar(250) NOT NULL,
- email text NOT NULL,
- lemail varchar(250) NOT NULL,
- orgname text NOT NULL,
- lorgname varchar(250) NOT NULL,
- orgunit text NOT NULL,
- lorgunit varchar(250) NOT NULL
-) TYPE=InnoDB CHARACTER SET utf8;
-
-CREATE INDEX i_vcard_search_lfn ON vcard_search(lfn);
-CREATE INDEX i_vcard_search_lfamily ON vcard_search(lfamily);
-CREATE INDEX i_vcard_search_lgiven ON vcard_search(lgiven);
-CREATE INDEX i_vcard_search_lmiddle ON vcard_search(lmiddle);
-CREATE INDEX i_vcard_search_lnickname ON vcard_search(lnickname);
-CREATE INDEX i_vcard_search_lbday ON vcard_search(lbday);
-CREATE INDEX i_vcard_search_lctry ON vcard_search(lctry);
-CREATE INDEX i_vcard_search_llocality ON vcard_search(llocality);
-CREATE INDEX i_vcard_search_lemail ON vcard_search(lemail);
-CREATE INDEX i_vcard_search_lorgname ON vcard_search(lorgname);
-CREATE INDEX i_vcard_search_lorgunit ON vcard_search(lorgunit);
-
---- To update from 1.x:
--- ALTER TABLE rosterusers ADD COLUMN askmessage text AFTER ask;
diff --git a/ejabberd-1.1.2/src/odbc/odbc_queries.erl b/ejabberd-1.1.2/src/odbc/odbc_queries.erl
deleted file mode 100644
index 7732e62a7..000000000
--- a/ejabberd-1.1.2/src/odbc/odbc_queries.erl
+++ /dev/null
@@ -1,434 +0,0 @@
-%% Copyrigh 2006, Process-one
-%% This module is intended to take into account relational databases behaviour
-%% differences
--module(odbc_queries).
--author("mickael.remond@process-one.net").
-
--export([get_db_type/0,
- sql_transaction/2,
- get_last/2,
- set_last_t/4,
- del_last/2,
- get_password/2,
- set_password_t/3,
- add_user/3,
- del_user/2,
- del_user_return_password/3,
- list_users/1,
- add_spool_sql/2,
- add_spool/2,
- get_and_del_spool_msg_t/2,
- del_spool_msg/2,
- get_roster/2,
- get_roster_jid_groups/2,
- get_roster_groups/3,
- del_user_roster_t/2,
- get_roster_by_jid/3,
- get_rostergroup_by_jid/3,
- del_roster/3,
- del_roster_sql/2,
- update_roster/5,
- update_roster_sql/4,
- roster_subscribe/4,
- get_subscription/3,
- escape/1]).
-
-%-define(generic, true).
-%-define(mssql, true).
-
-%% -----------------
-%% Generic queries
--ifdef(generic).
-
-get_db_type() ->
- generic.
-
-sql_transaction(LServer, F) ->
- ejabberd_odbc:sql_transaction(LServer, F).
-
-get_last(LServer, Username) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["select seconds, state from last "
- "where username='", Username, "'"]).
-
-set_last_t(LServer, Username, Seconds, State) ->
- %% MREMOND: I think this should be turn into a non transactional behaviour
- ejabberd_odbc:sql_transaction(
- LServer,
- [["delete from last where username='", Username, "';"],
- ["insert into last(username, seconds, state) "
- "values ('", Username, "', '", Seconds, "', '", State, "');"]]).
-
-del_last(LServer, Username) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["delete from last where username='", Username, "'"]).
-
-get_password(LServer, Username) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["select password from users "
- "where username='", Username, "';"]).
-
-set_password_t(LServer, Username, Pass) ->
- ejabberd_odbc:sql_transaction(
- LServer,
- [["delete from users where username='", Username ,"';"],
- ["insert into users(username, password) "
- "values ('", Username, "', '", Pass, "');"]]).
-
-add_user(LServer, Username, Pass) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["insert into users(username, password) "
- "values ('", Username, "', '", Pass, "');"]).
-
-del_user(LServer, Username) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["delete from users where username='", Username ,"';"]).
-
-del_user_return_password(_LServer, Username, Pass) ->
- ejabberd_odbc:sql_query_t(
- ["select password from users where username='",
- Username, "';"]),
- ejabberd_odbc:sql_query_t(["delete from users "
- "where username='", Username,
- "' and password='", Pass, "';"]).
-
-list_users(LServer) ->
- ejabberd_odbc:sql_query(
- LServer,
- "select username from users").
-
-add_spool_sql(Username, XML) ->
- ["insert into spool(username, xml) "
- "values ('", Username, "', '",
- XML,
- "');"].
-
-add_spool(LServer, Queries) ->
- ejabberd_odbc:sql_transaction(
- LServer, Queries).
-
-get_and_del_spool_msg_t(LServer, Username) ->
- F = fun() ->
- Result = ejabberd_odbc:sql_query_t(
- ["select username, xml from spool where username='", Username, "'"
- " order by seq;"]),
- ejabberd_odbc:sql_query_t(
- ["delete from spool where username='", Username, "';"]),
- Result
- end,
- ejabberd_odbc:sql_transaction(LServer,F).
-
-del_spool_msg(LServer, Username) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["delete from spool where username='", Username, "';"]).
-
-get_roster(LServer, Username) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["select username, jid, nick, subscription, ask, "
- "askmessage, server, subscribe, type from rosterusers "
- "where username='", Username, "'"]).
-
-get_roster_jid_groups(LServer, Username) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["select jid, grp from rostergroups "
- "where username='", Username, "'"]).
-
-get_roster_groups(_LServer, Username, SJID) ->
- ejabberd_odbc:sql_query_t(
- ["select grp from rostergroups "
- "where username='", Username, "' "
- "and jid='", SJID, "';"]).
-
-del_user_roster_t(LServer, Username) ->
- ejabberd_odbc:sql_transaction(
- LServer,
- fun() ->
- ejabberd_odbc:sql_query_t(
- ["delete from rosterusers "
- " where username='", Username, "';"]),
- ejabberd_odbc:sql_query_t(
- ["delete from rostergroups "
- " where username='", Username, "';"])
- end).
-
-get_roster_by_jid(_LServer, Username, SJID) ->
- ejabberd_odbc:sql_query_t(
- ["select username, jid, nick, subscription, "
- "ask, askmessage, server, subscribe, type from rosterusers "
- "where username='", Username, "' "
- "and jid='", SJID, "';"]).
-
-get_rostergroup_by_jid(LServer, Username, SJID) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["select grp from rostergroups "
- "where username='", Username, "' "
- "and jid='", SJID, "'"]).
-
-del_roster(_LServer, Username, SJID) ->
- ejabberd_odbc:sql_query_t(
- ["delete from rosterusers "
- " where username='", Username, "' "
- " and jid='", SJID, "';"]),
- ejabberd_odbc:sql_query_t(
- ["delete from rostergroups "
- " where username='", Username, "' "
- " and jid='", SJID, "';"]).
-
-del_roster_sql(Username, SJID) ->
- [["delete from rosterusers "
- " where username='", Username, "' "
- " and jid='", SJID, "';"],
- ["delete from rostergroups "
- " where username='", Username, "' "
- " and jid='", SJID, "';"]].
-
-update_roster(_LServer, Username, SJID, ItemVals, ItemGroups) ->
- ejabberd_odbc:sql_query_t(
- ["delete from rosterusers "
- " where username='", Username, "' "
- " and jid='", SJID, "';"]),
- ejabberd_odbc:sql_query_t(
- ["insert into rosterusers("
- " username, jid, nick, "
- " subscription, ask, askmessage, "
- " server, subscribe, type) "
- " values (", ItemVals, ");"]),
- ejabberd_odbc:sql_query_t(
- ["delete from rostergroups "
- " where username='", Username, "' "
- " and jid='", SJID, "';"]),
- lists:foreach(fun(ItemGroup) ->
- ejabberd_odbc:sql_query_t(
- ["insert into rostergroups("
- " username, jid, grp) "
- " values (", ItemGroup, ");"])
- end,
- ItemGroups).
-
-update_roster_sql(Username, SJID, ItemVals, ItemGroups) ->
- [["delete from rosterusers "
- " where username='", Username, "' "
- " and jid='", SJID, "';"],
- ["insert into rosterusers("
- " username, jid, nick, "
- " subscription, ask, askmessage"
- " server, subscribe, type) "
- " values (", ItemVals, ");"],
- ["delete from rostergroups "
- " where username='", Username, "' "
- " and jid='", SJID, "';"],
- [["insert into rostergroups("
- " username, jid, grp) "
- " values (", ItemGroup, ");"] ||
- ItemGroup <- ItemGroups]].
-
-roster_subscribe(_LServer, Username, SJID, ItemVals) ->
- ejabberd_odbc:sql_query_t(
- ["delete from rosterusers "
- " where username='", Username, "' "
- " and jid='", SJID, "';"]),
- ejabberd_odbc:sql_query_t(
- ["insert into rosterusers("
- " username, jid, nick, "
- " subscription, ask, askmessage, "
- " server, subscribe, type) "
- " values (", ItemVals, ");"]).
-
-get_subscription(LServer, Username, SJID) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["select subscription from rosterusers "
- "where username='", Username, "' "
- "and jid='", SJID, "'"]).
-
-%% Characters to escape
-escape($\0) -> "\\0";
-escape($\n) -> "\\n";
-escape($\t) -> "\\t";
-escape($\b) -> "\\b";
-escape($\r) -> "\\r";
-escape($') -> "\\'";
-escape($") -> "\\\"";
-escape($\\) -> "\\\\";
-escape(C) -> C.
-
--endif.
-
-%% -----------------
-%% MSSQL queries
--ifdef(mssql).
-
-get_db_type() ->
- mssql.
-
-sql_transaction(_LServer, F) ->
- {atomic, catch F()}.
-
-get_last(LServer, Username) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.get_last '", Username, "'"]).
-
-set_last_t(LServer, Username, Seconds, State) ->
- Result = ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.set_last '", Username, "', '", Seconds,
- "', '", State, "'"]),
- {atomic, Result}.
-
-del_last(LServer, Username) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.del_last '", Username, "'"]).
-
-get_password(LServer, Username) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.get_password '", Username, "'"]).
-
-set_password_t(LServer, Username, Pass) ->
- Result = ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.set_password '", Username, "', '", Pass, "'"]),
- {atomic, Result}.
-
-add_user(LServer, Username, Pass) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.add_user '", Username, "', '", Pass, "'"]).
-
-del_user(LServer, Username) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.del_user '", Username ,"'"]).
-
-del_user_return_password(LServer, Username, Pass) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.del_user_return_password '", Username, "'"]),
- Pass.
-
-list_users(LServer) ->
- ejabberd_odbc:sql_query(
- LServer,
- "EXECUTE dbo.list_users").
-
-add_spool_sql(Username, XML) ->
- ["EXECUTE dbo.add_spool '", Username, "' , '",XML,"'"].
-
-add_spool(LServer, Queries) ->
- lists:foreach(fun(Query) ->
- ejabberd_odbc:sql_query(LServer, Query)
- end,
- Queries).
-
-get_and_del_spool_msg_t(LServer, Username) ->
- [Result] = case ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.get_and_del_spool_msg '", Username, "'"]) of
- Rs when list(Rs) ->
- lists:filter(fun({selected, _Header, _Row}) ->
- true;
- ({updated, _N}) ->
- false
- end,
- Rs);
- Rs -> [Rs]
- end,
- {atomic, Result}.
-
-del_spool_msg(LServer, Username) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.del_spool_msg '", Username, "'"]).
-
-get_roster(LServer, Username) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.get_roster '", Username, "'"]).
-
-get_roster_jid_groups(LServer, Username) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.get_roster_jid_groups '", Username, "'"]).
-
-get_roster_groups(LServer, Username, SJID) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.get_roster_groups '", Username, "' , '", SJID, "'"]).
-
-del_user_roster_t(LServer, Username) ->
- Result = ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.del_user_roster '", Username, "'"]),
- {atomic, Result}.
-
-get_roster_by_jid(LServer, Username, SJID) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.get_roster_by_jid '", Username, "' , '", SJID, "'"]).
-
-get_rostergroup_by_jid(LServer, Username, SJID) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.get_rostergroup_by_jid '", Username, "' , '", SJID, "'"]).
-
-del_roster(LServer, Username, SJID) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.del_roster '", Username, "', '", SJID, "'"]).
-
-del_roster_sql(Username, SJID) ->
- ["EXECUTE dbo.del_roster '", Username, "', '", SJID, "'"].
-
-update_roster(LServer, Username, SJID, ItemVals, ItemGroups) ->
- Query1 = ["EXECUTE dbo.del_roster '", Username, "', '", SJID, "' "],
- ejabberd_odbc:sql_query(LServer, lists:flatten(Query1)),
- Query2 = ["EXECUTE dbo.add_roster_user ", ItemVals],
- ejabberd_odbc:sql_query(LServer, lists:flatten(Query2)),
- Query3 = ["EXECUTE dbo.del_roster_groups '", Username, "', '", SJID, "' "],
- ejabberd_odbc:sql_query(LServer, lists:flatten(Query3)),
- lists:foreach(fun(ItemGroup) ->
- Query = ["EXECUTE dbo.add_roster_group ",
- ItemGroup],
- ejabberd_odbc:sql_query(LServer,
- lists:flatten(Query))
- end,
- ItemGroups).
-
-update_roster_sql(Username, SJID, ItemVals, ItemGroups) ->
- ["BEGIN TRANSACTION ",
- "EXECUTE dbo.del_roster_groups '", Username, "','", SJID, "' ",
- "EXECUTE dbo.add_roster_user ", ItemVals, " "] ++
- [lists:flatten("EXECUTE dbo.add_roster_group ", ItemGroup, " ")
- || ItemGroup <- ItemGroups] ++
- ["COMMIT"].
-
-roster_subscribe(LServer, _Username, _SJID, ItemVals) ->
- catch ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.add_roster_user ", ItemVals]).
-
-get_subscription(LServer, Username, SJID) ->
- ejabberd_odbc:sql_query(
- LServer,
- ["EXECUTE dbo.get_subscription '", Username, "' , '", SJID, "'"]).
-
-%% Characters to escape
-escape($\0) -> "\\0";
-escape($\t) -> "\\t";
-escape($\b) -> "\\b";
-escape($\r) -> "\\r";
-escape($') -> "\''";
-escape($") -> "\\\"";
-escape(C) -> C.
--endif.
diff --git a/ejabberd-1.1.2/src/odbc/pg.sql b/ejabberd-1.1.2/src/odbc/pg.sql
deleted file mode 100644
index 32f20fdd0..000000000
--- a/ejabberd-1.1.2/src/odbc/pg.sql
+++ /dev/null
@@ -1,104 +0,0 @@
-
-CREATE TABLE users (
- username text PRIMARY KEY,
- "password" text NOT NULL
-);
-
-
-CREATE TABLE last (
- username text PRIMARY KEY,
- seconds text NOT NULL,
- state text
-);
-
-
-CREATE TABLE rosterusers (
- username text NOT NULL,
- jid text NOT NULL,
- nick text,
- subscription character(1) NOT NULL,
- ask character(1) NOT NULL,
- askmessage text,
- server character(1) NOT NULL,
- subscribe text,
- "type" text
-);
-
-CREATE UNIQUE INDEX i_rosteru_user_jid ON rosterusers USING btree (username, jid);
-CREATE INDEX i_rosteru_username ON rosterusers USING btree (username);
-CREATE INDEX i_rosteru_jid ON rosterusers USING btree (jid);
-
-
-CREATE TABLE rostergroups (
- username text NOT NULL,
- jid text NOT NULL,
- grp text NOT NULL
-);
-
-CREATE INDEX pk_rosterg_user_jid ON rostergroups USING btree (username, jid);
-
-
-CREATE TABLE spool (
- username text NOT NULL,
- xml text,
- seq SERIAL
-);
-
-CREATE INDEX i_despool ON spool USING btree (username);
-
-
-CREATE TABLE vcard (
- username text PRIMARY KEY,
- vcard text NOT NULL
-);
-
-CREATE TABLE vcard_search (
- username text NOT NULL,
- lusername text PRIMARY KEY,
- fn text NOT NULL,
- lfn text NOT NULL,
- family text NOT NULL,
- lfamily text NOT NULL,
- given text NOT NULL,
- lgiven text NOT NULL,
- middle text NOT NULL,
- lmiddle text NOT NULL,
- nickname text NOT NULL,
- lnickname text NOT NULL,
- bday text NOT NULL,
- lbday text NOT NULL,
- ctry text NOT NULL,
- lctry text NOT NULL,
- locality text NOT NULL,
- llocality text NOT NULL,
- email text NOT NULL,
- lemail text NOT NULL,
- orgname text NOT NULL,
- lorgname text NOT NULL,
- orgunit text NOT NULL,
- lorgunit text NOT NULL
-);
-
-CREATE INDEX i_vcard_search_lfn ON vcard_search(lfn);
-CREATE INDEX i_vcard_search_lfamily ON vcard_search(lfamily);
-CREATE INDEX i_vcard_search_lgiven ON vcard_search(lgiven);
-CREATE INDEX i_vcard_search_lmiddle ON vcard_search(lmiddle);
-CREATE INDEX i_vcard_search_lnickname ON vcard_search(lnickname);
-CREATE INDEX i_vcard_search_lbday ON vcard_search(lbday);
-CREATE INDEX i_vcard_search_lctry ON vcard_search(lctry);
-CREATE INDEX i_vcard_search_llocality ON vcard_search(llocality);
-CREATE INDEX i_vcard_search_lemail ON vcard_search(lemail);
-CREATE INDEX i_vcard_search_lorgname ON vcard_search(lorgname);
-CREATE INDEX i_vcard_search_lorgunit ON vcard_search(lorgunit);
-
---- To update from 0.9.8:
--- CREATE SEQUENCE spool_seq_seq;
--- ALTER TABLE spool ADD COLUMN seq integer;
--- ALTER TABLE spool ALTER COLUMN seq SET DEFAULT nextval('spool_seq_seq');
--- UPDATE spool SET seq = DEFAULT;
--- ALTER TABLE spool ALTER COLUMN seq SET NOT NULL;
-
---- To update from 1.x:
--- ALTER TABLE rosterusers ADD COLUMN askmessage text;
--- UPDATE rosterusers SET askmessage = '';
--- ALTER TABLE rosterusers ALTER COLUMN askmessage SET NOT NULL;
diff --git a/ejabberd-1.1.2/src/randoms.erl b/ejabberd-1.1.2/src/randoms.erl
deleted file mode 100644
index b7e4be070..000000000
--- a/ejabberd-1.1.2/src/randoms.erl
+++ /dev/null
@@ -1,42 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : randoms.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 13 Dec 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(randoms).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([get_string/0]).
-
--export([start/0, init/0]).
-
-
-start() ->
- register(random_generator, spawn(randoms, init, [])).
-
-init() ->
- {A1, A2, A3} = now(),
- random:seed(A1,A2,A3),
- loop().
-
-loop() ->
- receive
- {From, get_random, N} ->
- From ! {random, random:uniform(N)},
- loop();
- _ ->
- loop()
- end.
-
-
-get_string() ->
- random_generator ! {self(), get_random, 65536*65536},
- receive
- {random, R} ->
- integer_to_list(R)
- end.
-
diff --git a/ejabberd-1.1.2/src/sha.erl b/ejabberd-1.1.2/src/sha.erl
deleted file mode 100644
index f48d6928f..000000000
--- a/ejabberd-1.1.2/src/sha.erl
+++ /dev/null
@@ -1,32 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : sha.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 20 Dec 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(sha).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([start/0, sha/1]).
-
-start() ->
- crypto:start().
-
-digit_to_xchar(D) when (D >= 0) and (D < 10) ->
- D + 48;
-digit_to_xchar(D) ->
- D + 87.
-
-sha(Text) ->
- Bin = crypto:sha(Text),
- lists:reverse(ints_to_rxstr(binary_to_list(Bin), [])).
-
-ints_to_rxstr([], Res) ->
- Res;
-ints_to_rxstr([N | Ns], Res) ->
- ints_to_rxstr(Ns, [digit_to_xchar(N rem 16),
- digit_to_xchar(N div 16) | Res]).
-
diff --git a/ejabberd-1.1.2/src/shaper.erl b/ejabberd-1.1.2/src/shaper.erl
deleted file mode 100644
index 19a557c73..000000000
--- a/ejabberd-1.1.2/src/shaper.erl
+++ /dev/null
@@ -1,59 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : shaper.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Functions to control connections traffic
-%%% Created : 9 Feb 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(shaper).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([new/1, new1/1, update/2]).
-
--record(maxrate, {maxrate, lastrate, lasttime}).
-
-
-new(Name) ->
- Data = case ejabberd_config:get_global_option({shaper, Name}) of
- undefined ->
- none;
- D ->
- D
- end,
- new1(Data).
-
-
-new1(none) ->
- none;
-new1({maxrate, MaxRate}) ->
- #maxrate{maxrate = MaxRate,
- lastrate = 0,
- lasttime = now_to_usec(now())}.
-
-
-update(none, _Size) ->
- {none, 0};
-update(#maxrate{} = State, Size) ->
- MinInterv = 1000 * Size /
- (2 * State#maxrate.maxrate - State#maxrate.lastrate),
- Interv = (now_to_usec(now()) - State#maxrate.lasttime) / 1000,
- %io:format("State: ~p, Size=~p~nM=~p, I=~p~n",
- % [State, Size, MinInterv, Interv]),
- Pause = if
- MinInterv > Interv ->
- 1 + trunc(MinInterv - Interv);
- true ->
- 0
- end,
- NextNow = now_to_usec(now()) + Pause * 1000,
- {State#maxrate{
- lastrate = (State#maxrate.lastrate +
- 1000000 * Size / (NextNow - State#maxrate.lasttime))/2,
- lasttime = NextNow},
- Pause}.
-
-
-now_to_usec({MSec, Sec, USec}) ->
- (MSec*1000000 + Sec)*1000000 + USec.
diff --git a/ejabberd-1.1.2/src/stringprep/Makefile.in b/ejabberd-1.1.2/src/stringprep/Makefile.in
deleted file mode 100644
index 2d858cc2e..000000000
--- a/ejabberd-1.1.2/src/stringprep/Makefile.in
+++ /dev/null
@@ -1,46 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@ @ERLANG_CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@ @ERLANG_LIBS@
-
-ifeq ($(shell uname),Darwin)
-DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
-else
-# Assume Linux-style dynamic library flags
-DYNAMIC_LIB_CFLAGS = -fpic -shared
-endif
-
-SUBDIRS =
-
-ERLSHLIBS = ../stringprep_drv.so
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-OBJS = \
- $(OUTDIR)/stringprep.beam
-
-all: $(OBJS) $(ERLSHLIBS)
-
-$(OUTDIR)/%.beam: %.erl
- @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-#all: $(ERLSHLIBS)
-# erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt
-
-$(ERLSHLIBS): ../%.so: %.c uni_data.c uni_norm.c
- gcc -Wall -O2 $(CFLAGS) $(LDFLAGS) $(INCLUDES) \
- $(subst ../,,$(subst .so,.c,$@)) $(LIBS) \
- -o $@ $(DYNAMIC_LIB_CFLAGS)
-
-clean:
- rm -f $(OBJS) $(ERLSHLIBS)
-
-distclean: clean
- rm -f Makefile
-
-TAGS:
- etags *.erl
-
diff --git a/ejabberd-1.1.2/src/stringprep/Makefile.win32 b/ejabberd-1.1.2/src/stringprep/Makefile.win32
deleted file mode 100644
index 37e806a1a..000000000
--- a/ejabberd-1.1.2/src/stringprep/Makefile.win32
+++ /dev/null
@@ -1,35 +0,0 @@
-
-include ..\Makefile.inc
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-
-SOURCE = stringprep_drv.c
-AUXIL = uni_data.c uni_norm.c
-OBJECT = stringprep_drv.o
-DLL = $(OUTDIR)\stringprep_drv.dll
-
-ALL : $(DLL) $(OUTDIR)\stringprep.beam
-
-CLEAN :
- -@erase $(DLL)
- -@erase $(OUTDIR)\stringprep_drv.exp
- -@erase $(OUTDIR)\stringprep_drv.lib
- -@erase $(OBJECT)
- -@erase $(OUTDIR)\stringprep.beam
-
-$(OUTDIR)\stringprep.beam : stringprep.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) stringprep.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"
-
-LD=link.exe
-LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.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) $(AUXIL)
- $(CC) $(CC_FLAGS) -c -Fo$(OBJECT) $(SOURCE)
-
diff --git a/ejabberd-1.1.2/src/stringprep/stringprep.erl b/ejabberd-1.1.2/src/stringprep/stringprep.erl
deleted file mode 100644
index f2a4e0f58..000000000
--- a/ejabberd-1.1.2/src/stringprep/stringprep.erl
+++ /dev/null
@@ -1,97 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : stringprep.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Interface to stringprep_drv
-%%% Created : 16 Feb 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(stringprep).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
-
--export([start/0, start_link/0,
- tolower/1,
- nameprep/1,
- nodeprep/1,
- resourceprep/1]).
-
-%% Internal exports, call-back functions.
--export([init/1,
- handle_call/3,
- handle_cast/2,
- handle_info/2,
- code_change/3,
- terminate/2]).
-
--define(STRINGPREP_PORT, stringprep_port).
-
--define(NAMEPREP_COMMAND, 1).
--define(NODEPREP_COMMAND, 2).
--define(RESOURCEPREP_COMMAND, 3).
-
-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(), stringprep_drv) of
- ok -> ok;
- {error, already_loaded} -> ok
- end,
- Port = open_port({spawn, stringprep_drv}, []),
- register(?STRINGPREP_PORT, Port),
- {ok, Port}.
-
-
-%%% --------------------------------------------------------
-%%% The call-back functions.
-%%% --------------------------------------------------------
-
-handle_call(_, _, State) ->
- {noreply, State}.
-
-handle_cast(_, State) ->
- {noreply, State}.
-
-handle_info({'EXIT', Pid, Reason}, Port) ->
- {noreply, Port};
-
-handle_info({'EXIT', Port, Reason}, Port) ->
- {stop, {port_died, Reason}, Port};
-handle_info(_, State) ->
- {noreply, State}.
-
-code_change(OldVsn, State, Extra) ->
- {ok, State}.
-
-terminate(_Reason, Port) ->
- Port ! {self, close},
- ok.
-
-
-
-tolower(String) ->
- control(0, String).
-
-nameprep(String) ->
- control(?NAMEPREP_COMMAND, String).
-
-nodeprep(String) ->
- control(?NODEPREP_COMMAND, String).
-
-resourceprep(String) ->
- control(?RESOURCEPREP_COMMAND, String).
-
-control(Command, String) ->
- case port_control(?STRINGPREP_PORT, Command, String) of
- [0 | _] -> error;
- [1 | Res] -> Res
- end.
-
-
-
diff --git a/ejabberd-1.1.2/src/stringprep/stringprep_drv.c b/ejabberd-1.1.2/src/stringprep/stringprep_drv.c
deleted file mode 100644
index a12ec9a8e..000000000
--- a/ejabberd-1.1.2/src/stringprep/stringprep_drv.c
+++ /dev/null
@@ -1,392 +0,0 @@
-/* $Id$ */
-
-#include <stdio.h>
-#include <string.h>
-#include <erl_driver.h>
-#include <ei.h>
-
-#include "uni_data.c"
-#include "uni_norm.c"
-
-#define NAMEPREP_COMMAND 1
-#define NODEPREP_COMMAND 2
-#define RESOURCEPREP_COMMAND 3
-
-typedef struct {
- ErlDrvPort port;
-} stringprep_data;
-
-
-static ErlDrvData stringprep_erl_start(ErlDrvPort port, char *buff)
-{
- stringprep_data* d = (stringprep_data*)driver_alloc(sizeof(stringprep_data));
- d->port = port;
-
- //set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
-
- return (ErlDrvData)d;
-}
-
-static void stringprep_erl_stop(ErlDrvData handle)
-{
- driver_free((char*)handle);
-}
-
-
-/* Hangul constants */
-#define SBase 0xAC00
-#define LBase 0x1100
-#define VBase 0x1161
-#define TBase 0x11A7
-#define LCount 19
-#define VCount 21
-#define TCount 28
-#define NCount (VCount * TCount)
-#define SCount (LCount * NCount)
-
-/*
- * "canonical_ordering" and "compose" functions are based on nfkc.c from Gnome
- * library
- */
-
-static void canonical_ordering(int *str, int len)
-{
- int i, j, t;
- int last, next;
-
- last = GetUniCharCClass(str[0]);
- for (i = 0; i < len - 1; i++)
- {
- next = GetUniCharCClass(str[i + 1]);
- if (next != 0 && last > next)
- {
- for (j = i; j >= 0; j--)
- {
- if (GetUniCharCClass(str[j]) <= next)
- break;
- t = str[j + 1];
- str[j + 1] = str[j];
- str[j] = t;
- }
- next = last;
- }
- last = next;
- }
-}
-
-
-static int compose(int ch1, int ch2)
-{
- int info1, info2;
-
- if (LBase <= ch1 && ch1 < LBase + LCount &&
- VBase <= ch2 && ch2 < VBase + VCount) {
- return SBase + ((ch1 - LBase) * VCount + (ch2 - VBase)) * TCount;
- }
-
- if (SBase <= ch1 && ch1 < SBase + SCount && ((ch1 - SBase) % TCount) == 0 &&
- TBase <= ch2 && ch2 < TBase + TCount) {
- return ch1 + ch2 - TBase;
- }
-
- info1 = GetUniCharCompInfo(ch1);
- if (info1 != -1 && info1 & CompSingleMask) {
- if (!(info1 & CompSecondMask) &&
- ch2 == compFirstList[info1 & CompMask][0]) {
- return compFirstList[info1 & CompMask][1];
- } else
- return 0;
- }
-
- info2 = GetUniCharCompInfo(ch2);
- if (info2 != -1 && info2 & CompSingleMask) {
- if ((info2 & CompSecondMask) &&
- ch1 == compSecondList[info2 & CompMask][0]) {
- return compSecondList[info2 & CompMask][1];
- } else
- return 0;
- }
-
- if (info1 != -1 && info2 != -1 &&
- !(info1 & CompSecondMask) && (info2 & CompSecondMask))
- return compBothList[info1][info2 & CompMask];
- else
- return 0;
-}
-
-
-#define ADD_UCHAR(ruc) \
- if (ruc <= 0x7F) { \
- if (pos >= size) { \
- size = 2*size + 1; \
- rstring = driver_realloc(rstring, size); \
- } \
- rstring[pos] = (char) ruc; \
- pos++; \
- } else if (ruc <= 0x7FF) { \
- if (pos + 1 >= size) { \
- size = 2*size + 2; \
- rstring = driver_realloc(rstring, size); \
- } \
- rstring[pos] = (char) ((ruc >> 6) | 0xC0); \
- rstring[pos+1] = (char) ((ruc | 0x80) & 0xBF); \
- pos += 2; \
- } else if (ruc <= 0xFFFF) { \
- if (pos + 2 >= size) { \
- size = 2*size + 3; \
- rstring = driver_realloc(rstring, size); \
- } \
- rstring[pos] = (char) ((ruc >> 12) | 0xE0); \
- rstring[pos+1] = (char) (((ruc >> 6) | 0x80) & 0xBF); \
- rstring[pos+2] = (char) ((ruc | 0x80) & 0xBF); \
- pos += 3; \
- } else if (ruc <= 0x1FFFFF) { \
- if (pos + 3 >= size) { \
- size = 2*size + 4; \
- rstring = driver_realloc(rstring, size); \
- } \
- rstring[pos] = (char) ((ruc >> 18) | 0xF0); \
- rstring[pos+1] = (char) (((ruc >> 12) | 0x80) & 0xBF); \
- rstring[pos+2] = (char) (((ruc >> 6) | 0x80) & 0xBF); \
- rstring[pos+3] = (char) ((ruc | 0x80) & 0xBF); \
- pos += 4; \
- }
-
-#define ADD_UCHAR32(str, pos, len, ch) \
- if (pos >= len) { \
- len = 2*len + 1; \
- str = driver_realloc(str, len * sizeof(int)); \
- } \
- str[pos] = ch; \
- pos++;
-
-
-#define ADD_DECOMP(ruc) \
- info = GetUniCharDecompInfo(ruc); \
- if (info >= 0) { \
- decomp_len = GetDecompLen(info); \
- decomp_shift = GetDecompShift(info); \
- for (j = 0; j < decomp_len; j++) { \
- ADD_UCHAR32(str32, str32pos, str32len, \
- decompList[decomp_shift + j]); \
- } \
- } else { \
- ADD_UCHAR32(str32, str32pos, str32len, ruc); \
- }
-
-
-
-static int stringprep_erl_control(ErlDrvData drv_data,
- unsigned int command,
- char *buf, int len,
- char **rbuf, int rlen)
-{
- int i, j, pos=1;
- unsigned char c;
- int bad = 0;
- int uc = 0, ruc;
- int size;
- int info;
- int prohibit = 0, tolower = 0;
- char *rstring;
- int *mc;
- int *str32;
- int str32len, str32pos = 0;
- int decomp_len, decomp_shift;
- int comp_pos, comp_starter_pos;
- int cclass_prev, cclass2;
- int ch1, ch2;
- int first_ral, last_ral, have_ral, have_l;
-
- size = len + 1;
-
- rstring = driver_alloc(size);
- rstring[0] = 0;
-
- str32len = len + 1;
-
- str32 = driver_alloc(str32len * sizeof(int));
-
- switch (command)
- {
- case 0:
- prohibit = ACMask;
- tolower = 1;
- break;
-
- case NAMEPREP_COMMAND:
- prohibit = ACMask;
- tolower = 1;
- break;
-
- case NODEPREP_COMMAND:
- prohibit = ACMask | C11Mask | C21Mask | XNPMask;
- tolower = 1;
- break;
-
- case RESOURCEPREP_COMMAND:
- prohibit = ACMask | C21Mask;
- tolower = 0;
- break;
- }
-
- for (i = 0; i < len; i++)
- {
- c = buf[i];
- if (c < 0x80) {
- uc = c;
- } else if (c < 0xC0) {
- bad = 1;
- } else if (c < 0xE0) {
- if (i+1 < len && (buf[i+1] & 0xC0) == 0x80) {
- uc = ((c & 0x1F) << 6) | (buf[i+1] & 0x3F);
- i++;
- } else {
- bad = 1;
- }
- } else if (c < 0xF0) {
- if (i+2 < len && (buf[i+1] & 0xC0) == 0x80 &&
- (buf[i+2] & 0xC0) == 0x80) {
- uc = ((c & 0x0F) << 12)
- | ((buf[i+1] & 0x3F) << 6)
- | (buf[i+2] & 0x3F);
- i += 2;
- } else {
- bad = 1;
- }
- } else if (c < 0xF8) {
- if (i+3 < len &&
- (buf[i+1] & 0xC0) == 0x80 &&
- (buf[i+2] & 0xC0) == 0x80 &&
- (buf[i+3] & 0xC0) == 0x80) {
- uc = ((c & 0x07) << 18)
- | ((buf[i+1] & 0x3F) << 12)
- | ((buf[i+2] & 0x3F) << 6)
- | (buf[i+3] & 0x3F);
- i += 3;
- if (uc > 0x10FFFF)
- bad = 1;
- } else {
- bad = 1;
- }
- } else {
- bad = 1;
- }
-
- if (bad) {
- *rbuf = rstring;
- driver_free(str32);
- return 1;
- }
-
- info = GetUniCharInfo(uc);
-
- if (!(info & B1Mask))
- {
- if (tolower) {
- if (!(info & MCMask))
- {
- ruc = uc + GetDelta(info);
- ADD_DECOMP(ruc);
- } else {
- mc = GetMC(info);
- for (j = 1; j <= mc[0]; j++) {
- ruc = mc[j];
- ADD_DECOMP(ruc);
- }
- }
- } else {
- ruc = uc;
- ADD_DECOMP(ruc);
- }
- }
- }
-
- if (str32pos == 0) {
- rstring[0] = 1;
- *rbuf = rstring;
- driver_free(str32);
- return 1;
- }
-
- canonical_ordering(str32, str32pos);
-
- comp_pos = 1;
- comp_starter_pos = 0;
- ch1 = str32[0];
- cclass_prev = GetUniCharCClass(ch1);
- for (i = 1; i < str32pos; i++)
- {
- ch2 = str32[i];
- cclass2 = GetUniCharCClass(ch2);
- if ((cclass_prev == 0 || cclass2 > cclass_prev) &&
- (ruc = compose(ch1, ch2))) {
- ch1 = ruc;
- } else {
- if (cclass2 == 0) {
- str32[comp_starter_pos] = ch1;
- comp_starter_pos = comp_pos++;
- ch1 = ch2;
- cclass_prev = 0;
- } else {
- str32[comp_pos++] = ch2;
- cclass_prev = cclass2;
- }
- }
- }
- str32[comp_starter_pos] = ch1;
- str32pos = comp_pos;
-
- last_ral = have_ral = have_l = 0;
- info = GetUniCharInfo(str32[0]);
- first_ral = info & D1Mask;
- for (i = 0; i < str32pos; i++)
- {
- ruc = str32[i];
- info = GetUniCharInfo(ruc);
- if (info & prohibit) {
- *rbuf = rstring;
- driver_free(str32);
- return 1;
- }
- last_ral = info & D1Mask;
- have_ral = have_ral || last_ral;
- have_l = info & D2Mask;
- ADD_UCHAR(ruc);
- }
-
- if (have_ral && (!first_ral || !last_ral || have_l)) {
- *rbuf = rstring;
- driver_free(str32);
- return 1;
- }
-
- rstring[0] = 1;
- *rbuf = rstring;
- driver_free(str32);
-
- return pos;
-}
-
-
-
-ErlDrvEntry stringprep_driver_entry = {
- NULL, /* F_PTR init, N/A */
- stringprep_erl_start, /* L_PTR start, called when port is opened */
- stringprep_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 */
- "stringprep_drv", /* char *driver_name, the argument to open_port */
- NULL, /* F_PTR finish, called when unloaded */
- NULL, /* handle */
- stringprep_erl_control, /* F_PTR control, port_command callback */
- NULL, /* F_PTR timeout, reserved */
- NULL /* F_PTR outputv, reserved */
-};
-
-DRIVER_INIT(stringprep_erl) /* must match name in driver_entry */
-{
- return &stringprep_driver_entry;
-}
-
diff --git a/ejabberd-1.1.2/src/stringprep/uni_data.c b/ejabberd-1.1.2/src/stringprep/uni_data.c
deleted file mode 100644
index 1c76ee811..000000000
--- a/ejabberd-1.1.2/src/stringprep/uni_data.c
+++ /dev/null
@@ -1,1257 +0,0 @@
-/*
- * uni_data.c --
- *
- * Declarations of Unicode character information tables. This file is
- * automatically generated by the uni_parse.tcl script. Do not
- * modify this file by hand.
- *
- * Copyright (c) 1998 by Scriptics Corporation.
- * All rights reserved.
- *
- * Modified for ejabberd by Alexey Shchepin
- *
- * RCS: @(#) $Id$
- */
-
-/*
- * A 16-bit Unicode character is split into two parts in order to index
- * into the following tables. The lower OFFSET_BITS comprise an offset
- * into a page of characters. The upper bits comprise the page number.
- */
-
-#define OFFSET_BITS 8
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters. Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char pageMap[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 8, 8, 8, 8, 8, 25, 26, 27, 28, 29, 30, 31, 29,
- 32, 33, 29, 29, 29, 8, 8, 8, 34, 35, 36, 37, 38, 39, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 40, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 41, 21, 21, 21, 21, 42, 8, 8, 8, 8, 8, 8, 8, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 21, 45, 46, 47, 48, 49, 50, 8, 8, 8, 51, 52, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 53, 54, 8, 8, 55,
- 56, 57, 58, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 59, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 21, 21, 60, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 61
-};
-
-/*
- * The groupMap is indexed by combining the alternate page number with
- * the page offset and returns a group number that identifies a unique
- * set of character attributes.
- */
-
-static unsigned short int groupMap[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2,
- 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
- 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 7, 2, 2, 2, 2, 2, 2, 2, 8, 2, 2,
- 2, 2, 5, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 9, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5,
- 5, 5, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 11, 5, 10, 5, 10, 5, 10, 5, 5,
- 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 12, 10, 5,
- 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 13, 10, 5, 10, 5, 10, 5, 14, 5, 15, 10, 5, 10, 5,
- 16, 10, 5, 17, 17, 10, 5, 5, 18, 19, 20, 10, 5, 17, 21, 5, 22, 23,
- 10, 5, 5, 5, 22, 24, 5, 25, 10, 5, 10, 5, 10, 5, 26, 10, 5, 26, 5,
- 5, 10, 5, 26, 10, 5, 27, 27, 10, 5, 10, 5, 28, 10, 5, 5, 5, 10, 5,
- 5, 5, 5, 5, 5, 5, 29, 10, 5, 29, 10, 5, 29, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 5, 10, 5, 10, 5, 10, 5, 10, 5,
- 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 30, 29, 10, 5, 10, 5, 31, 32, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 33,
- 6, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5,
- 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 34, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 2, 2,
- 6, 6, 6, 6, 35, 6, 6, 6, 2, 6, 6, 6, 6, 6, 2, 2, 36, 2, 37, 37, 37,
- 6, 38, 6, 39, 39, 40, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 41, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 6, 42, 43, 44, 45, 46, 47, 48, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 49, 50,
- 51, 5, 52, 53, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5,
- 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 5, 2, 2, 2,
- 2, 6, 2, 2, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5,
- 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 5,
- 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 6, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 6, 6, 10, 5, 6, 6, 6,
- 6, 6, 6, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, 5, 5, 5, 5, 5, 5,
- 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 56, 6, 5, 2, 6,
- 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 6, 2, 2, 2, 57, 2, 57, 2, 2, 57, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 6, 6, 57, 57, 57,
- 57, 57, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 57, 6, 6, 6,
- 57, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 6, 6, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 2, 2, 2, 2, 2, 2, 2, 58, 2, 2, 2, 2, 2, 2, 2, 57, 57, 2,
- 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 57, 57, 57, 57,
- 57, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6,
- 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 57, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 5, 6, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 6, 6, 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 2,
- 6, 6, 5, 2, 2, 2, 2, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 2, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 6, 6,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6,
- 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 6, 6, 5, 5, 5, 5, 6, 6, 2, 6, 5, 5, 5,
- 2, 2, 2, 2, 6, 6, 5, 5, 6, 6, 5, 5, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5,
- 6, 6, 6, 6, 5, 5, 6, 5, 5, 5, 2, 2, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 2, 6, 6, 5,
- 5, 5, 5, 5, 5, 6, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5,
- 6, 5, 5, 6, 5, 5, 6, 6, 2, 6, 5, 5, 5, 2, 2, 6, 6, 6, 6, 2, 2, 6, 6,
- 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 6, 5, 6, 6, 6,
- 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 5, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5,
- 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 6, 5, 5, 5, 5, 5, 6, 6, 2, 5,
- 5, 5, 5, 2, 2, 2, 2, 2, 6, 2, 2, 5, 6, 5, 5, 2, 6, 6, 5, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 5,
- 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5,
- 6, 5, 5, 6, 6, 5, 5, 5, 5, 6, 6, 2, 5, 5, 2, 5, 2, 2, 2, 6, 6, 6, 5,
- 5, 6, 6, 5, 5, 2, 6, 6, 6, 6, 6, 6, 6, 6, 2, 5, 6, 6, 6, 6, 5, 5, 6,
- 5, 5, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 5, 6, 5, 5, 5, 5, 5, 5, 6, 6,
- 6, 5, 5, 5, 6, 5, 5, 5, 5, 6, 6, 6, 5, 5, 6, 5, 6, 5, 5, 6, 6, 6, 5,
- 5, 6, 6, 6, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 6,
- 6, 6, 6, 5, 5, 2, 5, 5, 6, 6, 6, 5, 5, 5, 6, 5, 5, 5, 2, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 6, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 6, 6, 6, 6, 2, 2, 2, 5, 5, 5, 5,
- 6, 2, 2, 2, 6, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 2, 2, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 5, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 5, 5, 5, 5, 5,
- 5, 5, 5, 6, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5,
- 5, 5, 6, 6, 6, 6, 5, 2, 5, 5, 5, 5, 5, 6, 2, 5, 5, 6, 5, 5, 2, 2, 6,
- 6, 6, 6, 6, 6, 6, 5, 5, 6, 6, 6, 6, 6, 6, 6, 5, 6, 5, 5, 6, 6, 6, 6,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 6, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 5, 5, 5, 2,
- 2, 2, 6, 6, 5, 5, 5, 6, 5, 5, 5, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6,
- 6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 2, 6,
- 6, 6, 6, 5, 5, 5, 2, 2, 2, 6, 2, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6,
- 2, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 6,
- 5, 6, 6, 5, 5, 6, 5, 6, 6, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 6, 5, 5,
- 5, 5, 5, 5, 5, 6, 5, 5, 5, 6, 5, 6, 5, 6, 6, 5, 5, 6, 5, 5, 5, 5, 2,
- 5, 5, 2, 2, 2, 2, 2, 2, 6, 2, 2, 5, 6, 6, 5, 5, 5, 5, 5, 6, 5, 6, 2,
- 2, 2, 2, 2, 2, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 5, 2, 2, 2,
- 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2,
- 2, 2, 2, 2, 5, 2, 2, 5, 5, 5, 5, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2,
- 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 5, 5, 5, 5, 5, 5, 5, 5,
- 2, 5, 5, 5, 5, 5, 5, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 5, 5, 5, 5, 5, 6, 5, 5, 6, 5, 2, 2, 2, 2, 5, 2, 6, 6, 6, 2, 2, 5,
- 2, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5,
- 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6,
- 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 6, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6,
- 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5,
- 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5,
- 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 6, 5,
- 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
- 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 2, 2, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 5, 5, 5, 5, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 5, 5, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 6, 5, 5, 5, 6, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5,
- 5, 2, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 2,
- 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 7, 2, 2, 2,
- 2, 7, 7, 7, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6,
- 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 5, 10, 5, 10, 5,
- 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 59, 60, 61, 62, 63, 64, 6, 6, 6, 6, 10, 5, 10, 5,
- 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10,
- 5, 10, 5, 10, 5, 10, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 65,
- 65, 65, 65, 65, 65, 65, 65, 5, 5, 5, 5, 5, 5, 6, 6, 65, 65, 65, 65,
- 65, 65, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 65, 65, 65, 65, 65, 65, 65, 65,
- 5, 5, 5, 5, 5, 5, 5, 5, 65, 65, 65, 65, 65, 65, 65, 65, 5, 5, 5, 5,
- 5, 5, 6, 6, 65, 65, 65, 65, 65, 65, 6, 6, 66, 5, 67, 5, 68, 5, 69,
- 5, 6, 65, 6, 65, 6, 65, 6, 65, 5, 5, 5, 5, 5, 5, 5, 5, 65, 65, 65,
- 65, 65, 65, 65, 65, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6,
- 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
- 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
- 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
- 117, 5, 5, 118, 119, 120, 6, 121, 122, 65, 65, 123, 123, 124, 2, 125,
- 2, 2, 2, 126, 127, 128, 6, 129, 130, 131, 131, 131, 131, 132, 2, 2,
- 2, 5, 5, 133, 134, 6, 6, 135, 136, 65, 65, 137, 137, 6, 2, 2, 2, 5,
- 5, 138, 139, 140, 5, 141, 142, 65, 65, 143, 143, 144, 2, 2, 2, 6, 6,
- 145, 146, 147, 6, 148, 149, 150, 150, 151, 151, 152, 2, 2, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 153, 153, 153, 154, 58, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6,
- 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 2, 6, 6, 6,
- 6, 6, 6, 6, 6, 153, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2,
- 5, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 2, 2, 2, 2, 2, 2, 2, 2, 155, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 2, 2, 156, 157, 2, 2, 2, 158, 2, 159, 5, 160, 161,
- 162, 5, 5, 163, 164, 165, 5, 2, 163, 166, 2, 2, 167, 167, 167, 168,
- 169, 2, 2, 170, 171, 172, 2, 168, 2, 173, 2, 174, 2, 175, 176, 177,
- 177, 2, 5, 178, 178, 2, 179, 5, 5, 5, 5, 5, 5, 2, 6, 6, 5, 180, 181,
- 2, 2, 2, 2, 2, 182, 5, 5, 5, 5, 2, 2, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 183, 183, 183, 183, 183, 183, 183, 183,
- 183, 183, 183, 183, 183, 183, 183, 183, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184,
- 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6,
- 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 2, 2, 2, 2, 6, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 6, 2, 2, 2, 2, 6, 6, 6, 2, 6,
- 2, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 5, 5, 5, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 2, 2,
- 5, 5, 5, 5, 5, 2, 2, 2, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 6, 6, 2, 2, 2, 2, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 6, 6, 6, 6, 6, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 185, 5,
- 186, 5, 187, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 188, 189, 190, 191, 192,
- 193, 194, 195, 5, 5, 196, 197, 198, 5, 5, 5, 199, 200, 201, 202, 203,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 204, 205,
- 206, 207, 5, 5, 5, 5, 5, 5, 5, 208, 209, 210, 211, 212, 213, 214, 215,
- 216, 217, 218, 219, 220, 221, 5, 222, 5, 5, 5, 223, 224, 225, 5, 226,
- 5, 227, 228, 5, 5, 5, 5, 5, 5, 5, 5, 229, 5, 230, 231, 5, 232, 233,
- 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 234, 235, 236, 237, 238, 239, 240, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 241, 242, 243, 244, 245, 6, 6, 6,
- 6, 6, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 57, 57, 57, 57, 57, 6, 57,
- 6, 57, 57, 6, 57, 57, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 6, 6, 6, 6, 57, 57, 57, 57,
- 57, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 6, 6, 153, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2,
- 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 6, 6,
- 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 5, 6, 6, 6, 2,
- 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6,
- 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 2, 2, 2, 2, 2, 2, 2, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 247,
- 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
- 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 248,
- 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
- 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 5, 5, 5, 5,
- 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 250,
- 6, 250, 250, 6, 6, 250, 6, 6, 250, 250, 6, 6, 250, 250, 250, 250, 6,
- 250, 250, 250, 250, 250, 250, 250, 250, 5, 5, 5, 5, 6, 5, 6, 5, 5,
- 5, 5, 6, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 251, 251, 251, 251,
- 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
- 251, 251, 251, 251, 251, 251, 251, 251, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 252, 252, 6, 252,
- 252, 252, 252, 6, 6, 252, 252, 252, 252, 252, 252, 252, 252, 6, 252,
- 252, 252, 252, 252, 252, 252, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 253, 253, 6, 253, 253, 253,
- 253, 6, 253, 253, 253, 253, 253, 6, 253, 6, 6, 6, 253, 253, 253, 253,
- 253, 253, 253, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 254, 254, 254, 254, 254, 254, 254, 254,
- 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
- 254, 254, 254, 254, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 257, 257, 257, 257, 257, 257, 257, 257,
- 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257,
- 257, 257, 257, 257, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 258, 258, 258, 258, 258, 258, 258, 258,
- 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258,
- 258, 258, 258, 258, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 259, 259, 259, 259, 259, 259, 259, 259,
- 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259,
- 259, 259, 259, 259, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 260, 260, 260, 260, 260,
- 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 260,
- 260, 260, 260, 260, 260, 260, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 262, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 263,
- 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263,
- 263, 263, 264, 263, 263, 263, 263, 263, 263, 263, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 265, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266,
- 266, 266, 266, 266, 266, 266, 267, 266, 266, 266, 266, 266, 266, 266,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 268, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 269, 269, 269, 269, 269, 269, 269,
- 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 270, 269, 269, 269,
- 269, 269, 269, 269, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 271, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 272, 272, 272,
- 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272,
- 273, 272, 272, 272, 272, 272, 272, 272, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 274, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 6, 6
-};
-
-/*
- * Each group represents a unique set of character attributes. The attributes
- * are encoded into a 32-bit value as follows:
- *
- * Bit 0 A.1 | C.1.2 | C.2.2 | C.3 -- C.9
- *
- * Bit 1 C.1.1
- *
- * Bit 2 C.2.1
- *
- * Bit 3 B.1
- *
- * Bit 4 D.1
- *
- * Bit 5 D.2
- *
- * Bit 6 XNP
- *
- * Bit 7 Case maps to several characters
- *
- * Bits 8-10 Reserved for future use.
- *
- * Bits 11-31 Case delta: delta for case conversions. This should be the
- * highest field so we can easily sign extend.
- */
-
-static int groups[] = {
- 4, 2, 0, 64, 65568, 32, 1, 8, 1587232, 160, 2080, 2208, 4256,
- -247776, -548832, 430112, 421920, 419872, 161824, 413728, 415776,
- 423968, 432160, 428064, 436256, 438304, 446496, 444448, 448544,
- 4128, 6304, -198624, -114656, -266208, 237568, 8352, 77856, 75808,
- 131104, 129056, 10400, 12448, -61408, -51168, -26592, -12256,
- -18400, -30688, -45024, -110560, -98272, -96224, -122848, -131040,
- 163872, 98336, 14496, 16, 17, 16544, 18592, 20640, 22688, 24736,
- -118752, -16352, 26784, 28832, 30880, 32928, 34976, 37024, 39072,
- 41120, 43168, 45216, 47264, 49312, 51360, 53408, 55456, 57504,
- 59552, 61600, 63648, 65696, 67744, 69792, 71840, 73888, 75936,
- 77984, 80032, 82080, 84128, 86176, 88224, 90272, 92320, 94368,
- 96416, 98464, 100512, 102560, 104608, 106656, 108704, 110752,
- 112800, 114848, 116896, 118944, 120992, 123040, 125088, 127136,
- 129184, 131232, 133280, 135328, 137376, 139424, 141472, -151520,
- 143520, -14690272, 145568, 147616, 149664, 151712, 153760, -176096,
- 155808, 157856, 159904, 161952, 164000, -204768, 166048, 168096,
- 170144, 172192, 174240, -229344, -14304, 176288, 178336, 180384,
- 182432, 184480, -262112, -258016, 186528, 9, 33, 188544, -17102816,
- 190592, -16080864, 192640, -17111008, -17113056, -17115104, -17119200,
- -17121248, -17117152, 194688, -17123296, -17125344, -17127392,
- 196736, 198784, 200832, -15394784, -17133536, -17168352, -16920544,
- -17190880, -17192928, -17182688, -15488992, -15464416, -17237984,
- 32800, 53280, 202912, 204960, 207008, 209056, 211104, 213152,
- 215200, 217248, 219296, 221344, 223392, 225440, 227488, 229536,
- 231584, 233632, 235680, 237728, 239776, 241824, 243872, 245920,
- 247968, 250016, 252064, 254112, 256160, 258208, 260256, 262304,
- 264352, 266400, 268448, 270496, 272544, 274592, 276640, 278688,
- 280736, 282784, 284832, 286880, 288928, 290976, 293024, 295072,
- 297120, 299168, 301216, 303264, 305312, 307360, 309408, 311456,
- 313504, 315552, 317600, 319648, 321696, 323744, 325792, 81952,
- -245168096, -245274592, -245381088, -245487584, -245594080, -245700576,
- -245807072, -245913568, -246020064, -246126560, -246233056, -246339552,
- -246446048, -244824032, -244844512, -244875232, -244942816, -244963296,
- -244994016, -245061600, -245082080, -245112800, -245180384, -245200864,
- -245231584, -245299168, -245319648, -245350368
-};
-
-/*
- * Table for characters that lowercased to multiple ones
- */
-
-static int multiCaseTable[][4] = {
- {2, 115, 115},
- {2, 105, 775},
- {2, 700, 110},
- {2, 106, 780},
- {2, 32, 953},
- {3, 953, 776, 769},
- {3, 965, 776, 769},
- {2, 1381, 1410},
- {2, 104, 817},
- {2, 116, 776},
- {2, 119, 778},
- {2, 121, 778},
- {2, 97, 702},
- {2, 965, 787},
- {3, 965, 787, 768},
- {3, 965, 787, 769},
- {3, 965, 787, 834},
- {2, 7936, 953},
- {2, 7937, 953},
- {2, 7938, 953},
- {2, 7939, 953},
- {2, 7940, 953},
- {2, 7941, 953},
- {2, 7942, 953},
- {2, 7943, 953},
- {2, 7936, 953},
- {2, 7937, 953},
- {2, 7938, 953},
- {2, 7939, 953},
- {2, 7940, 953},
- {2, 7941, 953},
- {2, 7942, 953},
- {2, 7943, 953},
- {2, 7968, 953},
- {2, 7969, 953},
- {2, 7970, 953},
- {2, 7971, 953},
- {2, 7972, 953},
- {2, 7973, 953},
- {2, 7974, 953},
- {2, 7975, 953},
- {2, 7968, 953},
- {2, 7969, 953},
- {2, 7970, 953},
- {2, 7971, 953},
- {2, 7972, 953},
- {2, 7973, 953},
- {2, 7974, 953},
- {2, 7975, 953},
- {2, 8032, 953},
- {2, 8033, 953},
- {2, 8034, 953},
- {2, 8035, 953},
- {2, 8036, 953},
- {2, 8037, 953},
- {2, 8038, 953},
- {2, 8039, 953},
- {2, 8032, 953},
- {2, 8033, 953},
- {2, 8034, 953},
- {2, 8035, 953},
- {2, 8036, 953},
- {2, 8037, 953},
- {2, 8038, 953},
- {2, 8039, 953},
- {2, 8048, 953},
- {2, 945, 953},
- {2, 940, 953},
- {2, 945, 834},
- {3, 945, 834, 953},
- {2, 945, 953},
- {2, 8052, 953},
- {2, 951, 953},
- {2, 942, 953},
- {2, 951, 834},
- {3, 951, 834, 953},
- {2, 951, 953},
- {3, 953, 776, 768},
- {3, 953, 776, 769},
- {2, 953, 834},
- {3, 953, 776, 834},
- {3, 965, 776, 768},
- {3, 965, 776, 769},
- {2, 961, 787},
- {2, 965, 834},
- {3, 965, 776, 834},
- {2, 8060, 953},
- {2, 969, 953},
- {2, 974, 953},
- {2, 969, 834},
- {3, 969, 834, 953},
- {2, 969, 953},
- {2, 114, 115},
- {2, 176, 99},
- {2, 176, 102},
- {2, 110, 111},
- {2, 115, 109},
- {3, 116, 101, 108},
- {2, 116, 109},
- {3, 104, 112, 97},
- {2, 97, 117},
- {2, 111, 118},
- {2, 112, 97},
- {2, 110, 97},
- {2, 956, 97},
- {2, 109, 97},
- {2, 107, 97},
- {2, 107, 98},
- {2, 109, 98},
- {2, 103, 98},
- {2, 112, 102},
- {2, 110, 102},
- {2, 956, 102},
- {2, 104, 122},
- {3, 107, 104, 122},
- {3, 109, 104, 122},
- {3, 103, 104, 122},
- {3, 116, 104, 122},
- {2, 112, 97},
- {3, 107, 112, 97},
- {3, 109, 112, 97},
- {3, 103, 112, 97},
- {2, 112, 118},
- {2, 110, 118},
- {2, 956, 118},
- {2, 109, 118},
- {2, 107, 118},
- {2, 109, 118},
- {2, 112, 119},
- {2, 110, 119},
- {2, 956, 119},
- {2, 109, 119},
- {2, 107, 119},
- {2, 109, 119},
- {2, 107, 969},
- {2, 109, 969},
- {2, 98, 113},
- {3, 99, 111, 46},
- {2, 100, 98},
- {2, 103, 121},
- {2, 104, 112},
- {2, 107, 107},
- {2, 107, 109},
- {2, 112, 104},
- {3, 112, 112, 109},
- {2, 112, 114},
- {2, 115, 118},
- {2, 119, 98},
- {2, 102, 102},
- {2, 102, 105},
- {2, 102, 108},
- {3, 102, 102, 105},
- {3, 102, 102, 108},
- {2, 115, 116},
- {2, 115, 116},
- {2, 1396, 1398},
- {2, 1396, 1381},
- {2, 1396, 1387},
- {2, 1406, 1398},
- {2, 1396, 1389}
-};
-
-/*
- * The following constants are used to determine the category of a
- * Unicode character.
- */
-
-#define ACMask (1 << 0)
-#define C11Mask (1 << 1)
-#define C21Mask (1 << 2)
-#define B1Mask (1 << 3)
-#define D1Mask (1 << 4)
-#define D2Mask (1 << 5)
-#define XNPMask (1 << 6)
-#define MCMask (1 << 7)
-
-/*
- * The following macros extract the fields of the character info. The
- * GetDelta() macro is complicated because we can't rely on the C compiler
- * to do sign extension on right shifts.
- */
-
-#define GetCaseType(info) (((info) & 0xE0) >> 5)
-#define GetCategory(info) ((info) & 0x1F)
-#define GetDelta(info) (((info) > 0) ? ((info) >> 11) : (~(~((info)) >> 11)))
-#define GetMC(info) (multiCaseTable[GetDelta(info)])
-
-/*
- * This macro extracts the information about a character from the
- * Unicode character tables.
- */
-
-#define GetUniCharInfo(ch) (groups[groupMap[(pageMap[(((int)(ch)) & 0x1fffff) >> OFFSET_BITS] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1))]])
-
diff --git a/ejabberd-1.1.2/src/stringprep/uni_norm.c b/ejabberd-1.1.2/src/stringprep/uni_norm.c
deleted file mode 100644
index 7575f1405..000000000
--- a/ejabberd-1.1.2/src/stringprep/uni_norm.c
+++ /dev/null
@@ -1,3264 +0,0 @@
-/*
- * uni_norm.c --
- *
- * Declarations of Unicode character information tables. This file is
- * automatically generated by the uni_parse2.tcl script. Do not
- * modify this file by hand.
- *
- * Copyright (c) 1998 by Scriptics Corporation.
- * All rights reserved.
- *
- * Modified for ejabberd by Alexey Shchepin
- *
- * RCS: @(#) $Id$
- */
-
-/*
- * A 16-bit Unicode character is split into two parts in order to index
- * into the following tables. The lower CCLASS_OFFSET_BITS comprise an offset
- * into a page of characters. The upper bits comprise the page number.
- */
-
-#define CCLASS_OFFSET_BITS 8
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters. Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char cclassPageMap[] = {
- 0, 0, 0, 1, 2, 3, 4, 5, 0, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0,
- 0, 0, 14, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/*
- * The cclassGroupMap is indexed by combining the alternate page number with
- * the page offset and returns a combining class number.
- */
-
-static unsigned char cclassGroupMap[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
- 230, 230, 230, 230, 230, 230, 230, 230, 230, 232, 220, 220, 220, 220,
- 232, 216, 220, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 202,
- 202, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 1, 1, 1,
- 1, 1, 220, 220, 220, 220, 230, 230, 230, 230, 230, 230, 230, 230, 240,
- 230, 220, 220, 220, 230, 230, 230, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 234, 233, 230, 230, 230, 230, 230,
- 230, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 230, 230, 230, 230, 220, 230, 230,
- 230, 222, 220, 230, 230, 230, 230, 230, 230, 0, 220, 220, 220, 220,
- 220, 230, 230, 220, 230, 230, 222, 228, 230, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 0, 20, 21, 22, 0, 23, 0, 24, 25, 0, 230, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32,
- 33, 34, 230, 230, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230,
- 230, 230, 230, 230, 230, 230, 0, 0, 230, 230, 230, 230, 220, 230, 0,
- 0, 230, 230, 0, 220, 230, 230, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 230, 230, 220, 230, 230, 220,
- 220, 220, 230, 220, 220, 230, 220, 230, 230, 230, 220, 230, 220, 230,
- 220, 230, 220, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 230, 220, 230,
- 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 84, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, 103, 9, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 118, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 122, 122, 122, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 220, 0, 220, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 130, 0, 132,
- 0, 0, 0, 0, 0, 130, 130, 130, 130, 0, 0, 130, 0, 230, 230, 9, 0, 230,
- 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 1,
- 1, 230, 230, 230, 230, 1, 1, 1, 230, 230, 0, 0, 0, 0, 230, 0, 0, 0,
- 1, 1, 230, 220, 230, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 218, 228, 232, 222, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 216, 216, 1, 1, 1, 0, 0, 0, 226, 216, 216,
- 216, 216, 216, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220, 220,
- 220, 220, 0, 0, 230, 230, 230, 230, 230, 220, 220, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-#define GetUniCharCClass(ch) (cclassGroupMap[(cclassPageMap[(((int)(ch)) & 0x1fffff) >> CCLASS_OFFSET_BITS] << CCLASS_OFFSET_BITS) | ((ch) & ((1 << CCLASS_OFFSET_BITS)-1))])
-
-
-#define DECOMP_OFFSET_BITS 8
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters. Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char decompPageMap[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 16, 17, 18, 19, 20, 21, 22, 7, 7, 7, 7,
- 7, 23, 7, 7, 7, 24, 25, 26, 27, 28, 29, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 37, 7, 7, 38, 39, 40,
- 41, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 42, 43, 44, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-};
-
-/*
- * The decompGroupMap is indexed by combining the alternate page number with
- * the page offset and returns a group number that identifies a length and
- * shift of decomposition sequence in decompList
- */
-
-static int decompGroupMap[] = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 65536, -1, -1, -1, -1, -1, -1, -1, 131073,
- -1, 65539, -1, -1, -1, -1, 131076, -1, -1, 65542, 65543, 131080, 65546,
- -1, -1, 131083, 65549, 65550, -1, 196623, 196626, 196629, -1, 131096,
- 131098, 131100, 131102, 131104, 131106, -1, 131108, 131110, 131112,
- 131114, 131116, 131118, 131120, 131122, 131124, -1, 131126, 131128,
- 131130, 131132, 131134, 131136, -1, -1, 131138, 131140, 131142, 131144,
- 131146, -1, -1, 131148, 131150, 131152, 131154, 131156, 131158, -1,
- 131160, 131162, 131164, 131166, 131168, 131170, 131172, 131174, 131176,
- -1, 131178, 131180, 131182, 131184, 131186, 131188, -1, -1, 131190,
- 131192, 131194, 131196, 131198, -1, 131200, 131202, 131204, 131206,
- 131208, 131210, 131212, 131214, 131216, 131218, 131220, 131222, 131224,
- 131226, 131228, 131230, 131232, -1, -1, 131234, 131236, 131238, 131240,
- 131242, 131244, 131246, 131248, 131250, 131252, 131254, 131256, 131258,
- 131260, 131262, 131264, 131266, 131268, 131270, 131272, -1, -1, 131274,
- 131276, 131278, 131280, 131282, 131284, 131286, 131288, 131290, -1,
- 131292, 131294, 131296, 131298, 131300, 131302, -1, 131304, 131306,
- 131308, 131310, 131312, 131314, 131316, 131318, -1, -1, 131320, 131322,
- 131324, 131326, 131328, 131330, 131332, -1, -1, 131334, 131336, 131338,
- 131340, 131342, 131344, -1, -1, 131346, 131348, 131350, 131352, 131354,
- 131356, 131358, 131360, 131362, 131364, 131366, 131368, 131370, 131372,
- 131374, 131376, 131378, 131380, -1, -1, 131382, 131384, 131386, 131388,
- 131390, 131392, 131394, 131396, 131398, 131400, 131402, 131404, 131406,
- 131408, 131410, 131412, 131414, 131416, 131418, 131420, 131422, 131424,
- 131426, 65892, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 131429, 131431, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 131433, 131435, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 196973, 196976, 196979, 131446, 131448,
- 131450, 131452, 131454, 131456, 131458, 131460, 131462, 131464, 131466,
- 131468, 131470, 131472, 197010, 197013, 197016, 197019, 197022, 197025,
- 197028, 197031, -1, 197034, 197037, 197040, 197043, 131510, 131512,
- -1, -1, 131514, 131516, 131518, 131520, 131522, 131524, 197062, 197065,
- 131532, 131534, 131536, 131538, 131540, 131542, 131544, 131546, -1,
- -1, 131548, 131550, 197088, 197091, 131558, 131560, 131562, 131564,
- 131566, 131568, 131570, 131572, 131574, 131576, 131578, 131580, 131582,
- 131584, 131586, 131588, 131590, 131592, 131594, 131596, 131598, 131600,
- 131602, 131604, 131606, 131608, 131610, 131612, 131614, 131616, 131618,
- 131620, -1, -1, 131622, 131624, -1, -1, -1, -1, -1, -1, 131626, 131628,
- 131630, 131632, 197170, 197173, 197176, 197179, 131646, 131648, 197186,
- 197189, 131656, 131658, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66124, 66125, 66126, 66127,
- 66128, 66129, 66130, 66131, 66132, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 131669, 131671, 131673, 131675, 131677, 131679,
- -1, -1, 66145, 66146, 65892, 66147, 66148, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 66149, 66150, -1, 66151, 131688, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 66154, -1, -1, -1, -1, -1, 131691, -1, -1, -1, 66157,
- -1, -1, -1, -1, -1, 131080, 197230, 131697, 66163, 131700, 131702,
- 131704, -1, 131706, -1, 131708, 131710, 197248, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 131715, 131717, 131719, 131721, 131723, 131725, 197263,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 131730, 131732, 131734, 131736, 131738,
- -1, 66204, 66205, 66206, 131708, 131717, 66207, 66208, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 66209, 66210, 66211, -1, 66212, 66213, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 131750, 131752, -1, 131754, -1, -1,
- -1, 131756, -1, -1, -1, -1, 131758, 131760, 131762, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 131764, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 131766, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131768, 131770, -1,
- 131772, -1, -1, -1, 131774, -1, -1, -1, -1, 131776, 131778, 131780,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 131782, 131784, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131786,
- 131788, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131790,
- 131792, 131794, 131796, -1, -1, 131798, 131800, -1, -1, 131802, 131804,
- 131806, 131808, 131810, 131812, -1, -1, 131814, 131816, 131818, 131820,
- 131822, 131824, -1, -1, 131826, 131828, 131830, 131832, 131834, 131836,
- 131838, 131840, 131842, 131844, 131846, 131848, -1, -1, 131850, 131852,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 131854, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 131856, 131858, 131860, 131862, 131864,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131866, 131868, 131870, 131872,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 131874, -1, 131876, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 131878, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131880, -1, -1, -1, -1, -1,
- -1, -1, 131882, -1, -1, 131884, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 131886, 131888, 131890, 131892,
- 131894, 131896, 131898, 131900, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131902, 131904,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131906,
- 131908, -1, 131910, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 131912, -1, -1, 131914, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 131916, 131918, 131920, -1, -1,
- 131922, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131924, -1,
- -1, 131926, 131928, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 131930, 131932, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131934, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131936, 131938,
- 131940, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 131942, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 131944, -1, -1, -1, -1, -1, -1, 131946,
- 131948, -1, 131950, 197488, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131955, 131957,
- 131959, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 131961, -1, 131963, 197501, 131968, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131970,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 131972, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131974,
- 131976, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66442, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 131979, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131981, -1, -1,
- -1, -1, 131983, -1, -1, -1, -1, 131985, -1, -1, -1, -1, 131987, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131989, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 131991, -1, 131993, 131995, 197533, 132000, 197538,
- -1, -1, -1, -1, -1, -1, -1, 132005, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 132007, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 132009, -1, -1, -1, -1, 132011, -1, -1, -1, -1, 132013,
- -1, -1, -1, -1, 132015, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 132017, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 132019, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 132021, 132023, 132025, 132027, 132029,
- 132031, 132033, 132035, 197573, 197576, 132043, 132045, 132047, 132049,
- 132051, 132053, 132055, 132057, 132059, 132061, 197599, 197602, 197605,
- 197608, 132075, 132077, 132079, 132081, 197619, 197622, 132089, 132091,
- 132093, 132095, 132097, 132099, 132101, 132103, 132105, 132107, 132109,
- 132111, 132113, 132115, 132117, 132119, 197657, 197660, 132127, 132129,
- 132131, 132133, 132135, 132137, 132139, 132141, 197679, 197682, 132149,
- 132151, 132153, 132155, 132157, 132159, 132161, 132163, 132165, 132167,
- 132169, 132171, 132173, 132175, 132177, 132179, 132181, 132183, 197721,
- 197724, 197727, 197730, 197733, 197736, 197739, 197742, 132209, 132211,
- 132213, 132215, 132217, 132219, 132221, 132223, 197761, 197764, 132231,
- 132233, 132235, 132237, 132239, 132241, 197779, 197782, 197785, 197788,
- 197791, 197794, 132261, 132263, 132265, 132267, 132269, 132271, 132273,
- 132275, 132277, 132279, 132281, 132283, 132285, 132287, 197825, 197828,
- 197831, 197834, 132301, 132303, 132305, 132307, 132309, 132311, 132313,
- 132315, 132317, 132319, 132321, 132323, 132325, 132327, 132329, 132331,
- 132333, 132335, 132337, 132339, 132341, 132343, 132345, 132347, 132349,
- 132351, 132353, 132355, 132357, 132359, 132361, 132237, -1, -1, -1,
- -1, 132363, 132365, 132367, 132369, 197907, 197910, 197913, 197916,
- 197919, 197922, 197925, 197928, 197931, 197934, 197937, 197940, 197943,
- 197946, 197949, 197952, 197955, 197958, 197961, 197964, 132431, 132433,
- 132435, 132437, 132439, 132441, 197979, 197982, 197985, 197988, 197991,
- 197994, 197997, 198000, 198003, 198006, 132473, 132475, 132477, 132479,
- 132481, 132483, 132485, 132487, 198025, 198028, 198031, 198034, 198037,
- 198040, 198043, 198046, 198049, 198052, 198055, 198058, 198061, 198064,
- 198067, 198070, 198073, 198076, 198079, 198082, 132549, 132551, 132553,
- 132555, 198093, 198096, 198099, 198102, 198105, 198108, 198111, 198114,
- 198117, 198120, 132587, 132589, 132591, 132593, 132595, 132597, 132599,
- 132601, -1, -1, -1, -1, -1, -1, 132603, 132605, 198143, 198146, 198149,
- 198152, 198155, 198158, 132625, 132627, 198165, 198168, 198171, 198174,
- 198177, 198180, 132647, 132649, 198187, 198190, 198193, 198196, -1,
- -1, 132663, 132665, 198203, 198206, 198209, 198212, -1, -1, 132679,
- 132681, 198219, 198222, 198225, 198228, 198231, 198234, 132701, 132703,
- 198241, 198244, 198247, 198250, 198253, 198256, 132723, 132725, 198263,
- 198266, 198269, 198272, 198275, 198278, 132745, 132747, 198285, 198288,
- 198291, 198294, 198297, 198300, 132767, 132769, 198307, 198310, 198313,
- 198316, -1, -1, 132783, 132785, 198323, 198326, 198329, 198332, -1,
- -1, 132799, 132801, 198339, 198342, 198345, 198348, 198351, 198354,
- -1, 132821, -1, 198359, -1, 198362, -1, 198365, 132832, 132834, 198372,
- 198375, 198378, 198381, 198384, 198387, 132854, 132856, 198394, 198397,
- 198400, 198403, 198406, 198409, 132876, 131719, 132878, 131721, 132880,
- 131723, 132882, 131725, 132884, 131734, 132886, 131736, 132888, 131738,
- -1, -1, 198426, 198429, 263968, 263972, 263976, 263980, 263984, 263988,
- 198456, 198459, 263998, 264002, 264006, 264010, 264014, 264018, 198486,
- 198489, 264028, 264032, 264036, 264040, 264044, 264048, 198516, 198519,
- 264058, 264062, 264066, 264070, 264074, 264078, 198546, 198549, 264088,
- 264092, 264096, 264100, 264104, 264108, 198576, 198579, 264118, 264122,
- 264126, 264130, 264134, 264138, 133070, 133072, 198610, 133077, 198615,
- -1, 133082, 198620, 133087, 133089, 133091, 131697, 133093, 133095,
- 67561, 133095, 133098, 198636, 198639, 133106, 198644, -1, 133111,
- 198649, 133116, 131700, 133118, 131702, 133120, 198658, 198661, 198664,
- 133131, 133133, 198671, 197248, -1, -1, 133138, 198676, 133143, 133145,
- 133147, 131704, -1, 198685, 198688, 198691, 133158, 133160, 198698,
- 197263, 133165, 133167, 133169, 198707, 133174, 133176, 133178, 131708,
- 133180, 198718, 197230, 67649, -1, -1, 198722, 133189, 198727, -1,
- 133194, 198732, 133199, 131706, 133201, 131710, 133203, 131080, 133205,
- -1, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536,
- 65536, 65536, -1, -1, -1, -1, -1, -1, 67671, -1, -1, -1, -1, -1, 133208,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67674, 133211, 198749,
- -1, -1, -1, -1, -1, -1, -1, -1, 65536, -1, -1, -1, 133216, 198754,
- -1, 133221, 198759, -1, -1, -1, -1, 133226, -1, 133228, -1, -1, -1,
- -1, -1, -1, -1, -1, 133230, 133232, 133234, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 264308, -1, -1, -1, -1, -1, -1, -1, 65536,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67704,
- 67705, -1, -1, 67706, 67707, 67708, 67709, 67710, 67711, 67712, 67713,
- 67714, 67715, 67716, 67717, 67704, 65549, 65542, 65543, 67706, 67707,
- 67708, 67709, 67710, 67711, 67712, 67713, 67714, 67715, 67716, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 133254, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 198792, 198795, 67726,
- 133263, -1, 198801, 198804, 67735, -1, 133272, 67738, 67739, 67739,
- 67739, 66124, 67740, 67741, 67741, 67742, 66146, -1, 67743, 133280,
- -1, -1, 67746, 67747, 67748, 67748, 67748, -1, -1, 133285, 198823,
- 133290, -1, 67756, -1, 67757, -1, 67756, -1, 67758, 131106, 67759,
- 67726, -1, 67760, 67761, 67762, -1, 67763, 65550, 67764, 67765, 67766,
- 67767, 67705, -1, -1, -1, 67768, 67769, 67770, 67771, -1, -1, -1, -1,
- 67772, 67773, 67760, 67705, 66126, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 198846, 198849, 198852, 198855, 198858, 198861, 198864, 198867,
- 198870, 198873, 198876, 198879, 133346, 67741, 133348, 198886, 133353,
- 67819, 133356, 198894, 264433, 133365, 67831, 133368, 198906, 67742,
- 67726, 67772, 67763, 67705, 133373, 198911, 133378, 67844, 133381,
- 198919, 264458, 133390, 66147, 133392, 198930, 66146, 67861, 67773,
- 67862, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133399, 133401, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133403,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133405, 133407,
- 133409, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 133411, -1, -1, -1, -1, 133413, -1, -1, 133415, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 133417, -1, 133419, -1, -1, -1, -1, -1, 133421, 198959,
- -1, 133426, 198964, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 133431, -1, -1, 133433, -1, -1, 133435, -1, 133437,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 133439, -1, 133441, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 133443, 133445, 133447, 133449, 133451, -1, -1, 133453,
- 133455, -1, -1, 133457, 133459, -1, -1, -1, -1, -1, -1, 133461, 133463,
- -1, -1, 133465, 133467, -1, -1, 133469, 133471, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133473, 133475, 133477,
- 133479, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133481,
- 133483, 133485, 133487, -1, -1, -1, -1, -1, -1, 133489, 133491, 133493,
- 133495, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67961, 67962, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65549,
- 65542, 65543, 67706, 67707, 67708, 67709, 67710, 67711, 133499, 133501,
- 133503, 133505, 133507, 133509, 133511, 133513, 133515, 133517, 133519,
- 199057, 199060, 199063, 199066, 199069, 199072, 199075, 199078, 199081,
- 264620, 264624, 264628, 264632, 264636, 264640, 264644, 264648, 264652,
- 264656, 264660, 133592, 133594, 133596, 133598, 133600, 133602, 133604,
- 133606, 133608, 199146, 199149, 199152, 199155, 199158, 199161, 199164,
- 199167, 199170, 199173, 199176, 199179, 199182, 199185, 199188, 199191,
- 199194, 199197, 199200, 199203, 199206, 199209, 199212, 199215, 199218,
- 199221, 199224, 199227, 199230, 199233, 199236, 199239, 199242, 199245,
- 199248, 199251, 199254, 68185, 67759, 67726, 67772, 67761, 67762, 68186,
- 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747,
- 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539,
- 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196,
- 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200,
- 67844, 66131, 66147, 66132, 68201, 67704, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 264810, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 199278, 133745, 199283,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133750,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 68216, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 68217, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 68218, 68219, 68220, 68221, 68222, 68223, 68224, 68225,
- 68226, 68227, 68228, 68229, 68230, 68231, 68232, 68233, 68234, 68235,
- 68236, 68237, 68238, 68239, 68240, 68241, 68242, 68243, 68244, 68245,
- 68246, 68247, 68248, 68249, 68250, 68251, 68252, 68253, 68254, 68255,
- 68256, 68257, 68258, 68259, 68260, 68261, 68262, 68263, 68264, 68265,
- 68266, 68267, 68268, 68269, 68270, 68271, 68272, 68273, 68274, 68275,
- 68276, 68277, 68278, 68279, 68280, 68281, 68282, 68283, 68284, 68285,
- 68286, 68287, 68288, 68289, 68290, 68291, 68292, 68293, 68294, 68295,
- 68296, 68297, 68298, 68299, 68300, 68301, 68302, 68303, 68304, 68305,
- 68306, 68307, 68308, 68309, 68310, 68311, 68312, 68313, 68314, 68315,
- 68316, 68317, 68318, 68319, 68320, 68321, 68322, 68323, 68324, 68325,
- 68326, 68327, 68328, 68329, 68330, 68331, 68332, 68333, 68334, 68335,
- 68336, 68337, 68338, 68339, 68340, 68341, 68342, 68343, 68344, 68345,
- 68346, 68347, 68348, 68349, 68350, 68351, 68352, 68353, 68354, 68355,
- 68356, 68357, 68358, 68359, 68360, 68361, 68362, 68363, 68364, 68365,
- 68366, 68367, 68368, 68369, 68370, 68371, 68372, 68373, 68374, 68375,
- 68376, 68377, 68378, 68379, 68380, 68381, 68382, 68383, 68384, 68385,
- 68386, 68387, 68388, 68389, 68390, 68391, 68392, 68393, 68394, 68395,
- 68396, 68397, 68398, 68399, 68400, 68401, 68402, 68403, 68404, 68405,
- 68406, 68407, 68408, 68409, 68410, 68411, 68412, 68413, 68414, 68415,
- 68416, 68417, 68418, 68419, 68420, 68421, 68422, 68423, 68424, 68425,
- 68426, 68427, 68428, 68429, 68430, 68431, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 65536, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 68432, -1, 68241, 68433, 68434, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133971, -1, 133973,
- -1, 133975, -1, 133977, -1, 133979, -1, 133981, -1, 133983, -1, 133985,
- -1, 133987, -1, 133989, -1, 133991, -1, 133993, -1, -1, 133995, -1,
- 133997, -1, 133999, -1, -1, -1, -1, -1, -1, 134001, 134003, -1, 134005,
- 134007, -1, 134009, 134011, -1, 134013, 134015, -1, 134017, 134019,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 134021, -1, -1, -1, -1, -1, -1, 134023, 134025,
- -1, 134027, 134029, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 134031, -1, 134033, -1, 134035, -1, 134037, -1, 134039, -1, 134041,
- -1, 134043, -1, 134045, -1, 134047, -1, 134049, -1, 134051, -1, 134053,
- -1, -1, 134055, -1, 134057, -1, 134059, -1, -1, -1, -1, -1, -1, 134061,
- 134063, -1, 134065, 134067, -1, 134069, 134071, -1, 134073, 134075,
- -1, 134077, 134079, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 134081, -1, -1, 134083, 134085,
- 134087, 134089, -1, -1, -1, 134091, 134093, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 68559, 68560, 68561, 68562, 68563,
- 68564, 68565, 68566, 68567, 68568, 68569, 68570, 68571, 68572, 68573,
- 68574, 68575, 68576, 68577, 68578, 68579, 68580, 68581, 68582, 68583,
- 68584, 68585, 68586, 68587, 68588, 68589, 68590, 68591, 68592, 68593,
- 68594, 68595, 68596, 68597, 68598, 68599, 68600, 68601, 68602, 68603,
- 68604, 68605, 68606, 68607, 68608, 68609, 68610, 68611, 68612, 68613,
- 68614, 68615, 68616, 68617, 68618, 68619, 68620, 68621, 68622, 68623,
- 68624, 68625, 68626, 68627, 68628, 68629, 68630, 68631, 68632, 68633,
- 68634, 68635, 68636, 68637, 68638, 68639, 68640, 68641, 68642, 68643,
- 68644, 68645, 68646, 68647, 68648, 68649, 68650, 68651, 68652, -1,
- -1, -1, 68218, 68224, 68653, 68654, 68655, 68656, 68657, 68658, 68222,
- 68659, 68660, 68661, 68662, 68226, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 199735, 199738, 199741, 199744, 199747, 199750, 199753,
- 199756, 199759, 199762, 199765, 199768, 199771, 199774, 265313, 265317,
- 265321, 265325, 265329, 265333, 265337, 265341, 265345, 265349, 265353,
- 265357, 265361, 265365, 265369, -1, -1, -1, 199837, 199840, 199843,
- 199846, 199849, 199852, 199855, 199858, 199861, 199864, 199867, 199870,
- 199873, 199876, 199879, 199882, 199885, 199888, 199891, 199894, 199897,
- 199900, 199903, 199906, 199909, 199912, 199915, 199918, 199921, 199924,
- 199927, 199930, 199933, 199936, 199939, 199942, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 134409, 134411, 134413, 134415, 134417,
- 134419, 134421, 134423, 134425, 134427, 134429, 134431, 134433, 134435,
- 134437, 68559, 68562, 68565, 68567, 68575, 68576, 68579, 68581, 68582,
- 68584, 68585, 68586, 68587, 68588, 134439, 134441, 134443, 134445,
- 134447, 134449, 134451, 134453, 134455, 134457, 134459, 134461, 134463,
- 134465, -1, -1, -1, -1, 68218, 68224, 68653, 68654, 68931, 68932, 68933,
- 68229, 68934, 68241, 68291, 68303, 68302, 68292, 68384, 68249, 68289,
- 68935, 68936, 68937, 68938, 68939, 68940, 68941, 68942, 68943, 68944,
- 68255, 68945, 68946, 68947, 68948, 68949, 68950, 68951, 68952, 68655,
- 68656, 68657, 68953, 68954, 68955, 68956, 68957, 68958, 68959, 68960,
- 68961, 68962, 134499, 134501, 134503, 134505, 134507, 134509, 134511,
- 134513, 134515, 134517, 134519, 134521, 134523, 134525, 134527, 134529,
- 134531, 134533, 134535, 134537, 134539, 134541, 134543, 134545, 200083,
- 200086, 200089, -1, -1, -1, -1, 69020, 69021, 69022, 69023, 69024,
- 69025, 69026, 69027, 69028, 69029, 69030, 69031, 69032, 69033, 69034,
- 69035, 69036, 69037, 69038, 69039, 69040, 69041, 69042, 69043, 69044,
- 69045, 69046, 69047, 69048, 69049, 69050, 69051, 69052, 69053, 69054,
- 69055, 69056, 69057, 69058, 69059, 69060, 69061, 69062, 69063, 69064,
- 69065, 69066, -1, 331211, 265680, 331220, 200153, 331228, 200161, 200164,
- 396775, 265709, 200177, 200180, 200183, 265722, 265726, 265730, 265734,
- 265738, 265742, 265746, 396822, 134684, 396830, 396836, 331306, 265775,
- 396851, 396857, 265791, 200259, 200262, 265801, 265805, 331345, 331350,
- 200283, 200286, 265825, 200293, 200296, 134763, 134765, 200303, 200306,
- 396917, 265851, 331391, 396932, 265866, 200334, 200337, 396948, 265882,
- 396958, 200356, 331431, 200364, 265903, 200371, 265910, 331450, 265919,
- 331459, 265928, 134860, 331470, 200403, 200406, 265945, 200413, 200416,
- 200419, 331494, 265963, 134895, 397041, 200439, 331514, 265983, 265987,
- 200455, 200458, 265997, 134929, 266003, 331543, 134940, 397086, 200484,
- 134951, 134953, 134955, 134957, 134959, 134961, 134963, 134965, 134967,
- 134969, 200507, 200510, 200513, 200516, 200519, 200522, 200525, 200528,
- 200531, 200534, 200537, 200540, 200543, 200546, 200549, 200552, 135019,
- 135021, 200559, 135026, 135028, -1, -1, -1, -1, 135030, 135032, 135034,
- 135036, 266110, 135042, 135044, 135046, 135048, 135050, 135052, 135054,
- 135056, 200594, 266133, 135065, 135067, 135069, 135071, 135073, 135075,
- 135077, 200615, 200618, 200621, 200624, 135091, 135093, 135095, 135097,
- 135099, 135101, 135103, 135105, 135107, 135109, 200647, 200650, 135117,
- 200655, 200658, 200661, 135128, 200666, 200669, 266208, 135140, 200678,
- 200681, 200684, 200687, 331762, 397303, 135165, 135167, 135169, 135171,
- 135173, 135175, 135177, 135179, 135181, 135183, 135185, 135187, 135189,
- 135191, 135193, 135195, 135197, 135199, 266273, 135205, 135207, 135209,
- 266283, 200751, 135218, 135220, 135222, 135224, 135226, 135228, 135230,
- 135232, 135234, 135236, 200774, 135241, 135243, 200781, 200784, 135251,
- 266325, 200793, 135260, 135262, 135264, 135266, -1, -1, 135268, 135270,
- 135272, 135274, 135276, 135278, 135280, 135282, 135284, 200822, 200825,
- 200828, 200831, 200834, 200837, 200840, 200843, 200846, 200849, 200852,
- 200855, 200858, 200861, 200864, 200867, 200870, 200873, 200876, 200879,
- 200882, 200885, -1, 69816, 69817, 68376, 69818, 69819, 69820, 69821,
- 68430, 68430, 69822, 68384, 69823, 69824, 69825, 69826, 69827, 69828,
- 69829, 69830, 69831, 69832, 69833, 69834, 69835, 69836, 69837, 69838,
- 69839, 69840, 69841, 69842, 69843, 69844, 69845, 69846, 69847, 69848,
- 69849, 69850, 69851, 69852, 69853, 69854, 69855, 69856, 69857, 69858,
- 69859, 69860, 69861, 69862, 69863, 68342, 69864, 69865, 69866, 69867,
- 69868, 69869, 69870, 69871, 69872, 69873, 69874, 68415, 69875, 69876,
- 69877, 69878, 69879, 69880, 69881, 69882, 69883, 69884, 69885, 69886,
- 69887, 69888, 69889, 69890, 69891, 69892, 69893, 69894, 69895, 69896,
- 69897, 69898, 69899, 69900, 69901, 69832, 69902, 69903, 69904, 69905,
- 69906, 69907, 69908, 69909, 69910, 69911, 69912, 69913, 69914, 69915,
- 69916, 69917, 69918, 69919, 69920, 69921, 68378, 69922, 69923, 69924,
- 69925, 69926, 69927, 69928, 69929, 69930, 69931, 69932, 69933, 69934,
- 69935, 69936, 68255, 69937, 69938, 69939, 69940, 69941, 69942, 69943,
- 69944, 68236, 69945, 69946, 69947, 69948, 69949, 69950, 69951, 69952,
- 69953, 69954, 69955, 69956, 69957, 69958, 69959, 69960, 69961, 69962,
- 69963, 69964, 69965, 69966, 69920, 69967, 69968, 69969, 69970, 69971,
- 69972, 69973, 69974, 69904, 69975, 69976, 69977, 69978, 69979, 69980,
- 69981, 69982, 69983, 69984, 69985, 69986, 69987, 69988, 69989, 69990,
- 69991, 69992, 69993, 69994, 69832, 69995, 69996, 69997, 69998, 68429,
- 69999, 70000, 70001, 70002, 70003, 70004, 70005, 70006, 70007, 70008,
- 70009, 70010, 68932, 70011, 70012, 70013, 70014, 70015, 70016, 70017,
- 70018, 70019, 69906, 70020, 70021, 70022, 70023, 70024, 70025, 70026,
- 70027, 70028, 70029, 70030, 70031, 70032, 68383, 70033, 70034, 70035,
- 70036, 70037, 70038, 70039, 70040, 70041, 70042, 70043, 70044, 70045,
- 68334, 70046, 70047, 70048, 70049, 70050, 70051, 70052, 70053, 70054,
- 70055, 70056, 70057, 70058, 70059, 70060, 70061, 68361, 70062, 68364,
- 70063, 70064, 70065, -1, -1, 70066, -1, 70067, -1, -1, 70068, 70069,
- 70070, 70071, 70072, 70073, 70074, 70075, 70076, 68341, -1, 70077,
- -1, 70078, -1, -1, 70079, 70080, -1, -1, -1, 70081, 70082, 70083, 70084,
- -1, -1, 70085, 70086, 70087, 70088, 70089, 70090, 70091, 70092, 70093,
- 70094, 70095, 70096, 68262, 70097, 70098, 70099, 70100, 70101, 70102,
- 70103, 70104, 70105, 70106, 70107, 70108, 70109, 70110, 70111, 68937,
- 70112, 70113, 70114, 70115, 68941, 70116, 70117, 70118, 70119, 70120,
- 69956, 70121, 70122, 70123, 70124, 70125, 70126, 70126, 70127, 70128,
- 70129, 70130, 70131, 70132, 70133, 70134, 70079, 70135, 70136, 70137,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 135674, 135676,
- 135678, 201216, 201219, 135686, 135686, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 135688, 135690, 135692, 135694, 135696, -1, -1,
- -1, -1, -1, 135698, -1, 135700, 70166, 67764, 67767, 70167, 70168,
- 70169, 70170, 70171, 70172, 67712, 135709, 135711, 201249, 201252,
- 135719, 135721, 135723, 135725, 135727, 135729, 135731, 135733, 135735,
- -1, 135737, 135739, 135741, 135743, 135745, -1, 135747, -1, 135749,
- 135751, -1, 135753, 135755, -1, 135757, 135759, 135761, 135763, 135765,
- 135767, 135769, 135771, 135773, 135775, 70241, 70241, 70242, 70242,
- 70242, 70242, 70243, 70243, 70243, 70243, 70244, 70244, 70244, 70244,
- 70245, 70245, 70245, 70245, 70246, 70246, 70246, 70246, 70247, 70247,
- 70247, 70247, 70248, 70248, 70248, 70248, 70249, 70249, 70249, 70249,
- 70250, 70250, 70250, 70250, 70251, 70251, 70251, 70251, 70252, 70252,
- 70252, 70252, 70253, 70253, 70253, 70253, 70254, 70254, 70255, 70255,
- 70256, 70256, 70257, 70257, 70258, 70258, 70259, 70259, 70260, 70260,
- 70260, 70260, 70261, 70261, 70261, 70261, 70262, 70262, 70262, 70262,
- 70263, 70263, 70263, 70263, 70264, 70264, 70265, 70265, 70265, 70265,
- 131874, 131874, 70266, 70266, 70266, 70266, 70267, 70267, 70267, 70267,
- 70268, 70268, 131878, 131878, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 70269, 70269, 70269, 70269, 70270, 70270, 70271,
- 70271, 70272, 70272, 131870, 70273, 70273, 70274, 70274, 70275, 70275,
- 70276, 70276, 70276, 70276, 70277, 70277, 201350, 201350, 201353, 201353,
- 201356, 201356, 201359, 201359, 201362, 201362, 201365, 201365, 201368,
- 201368, 201368, 201371, 201371, 201371, 70302, 70302, 70302, 70302,
- 201375, 201378, 201381, 201371, 201384, 135851, 135853, 135855, 135857,
- 135859, 135861, 135863, 135865, 135867, 135869, 135871, 135873, 135875,
- 135877, 135879, 135881, 135883, 135885, 135887, 135889, 135891, 135893,
- 135895, 135897, 135899, 135901, 135903, 135905, 135907, 135909, 135911,
- 135913, 135915, 135917, 135919, 135921, 135923, 135925, 135927, 135929,
- 135931, 135933, 135935, 135937, 135939, 135941, 135943, 135945, 135947,
- 135949, 135951, 135953, 135955, 135957, 135959, 135961, 135963, 135965,
- 135967, 135969, 135971, 135973, 135975, 135977, 135979, 135981, 135983,
- 135985, 135987, 135989, 135991, 135993, 135995, 135997, 135999, 136001,
- 136003, 136005, 136007, 136009, 136011, 136013, 136015, 136017, 136019,
- 136021, 136023, 136025, 136027, 201565, 201568, 201571, 201574, 201577,
- 201580, 201583, 201586, 201381, 201589, 201371, 201384, 136056, 136058,
- 135857, 136060, 135859, 135861, 136062, 136064, 135869, 136066, 135871,
- 135873, 136068, 136070, 135877, 136072, 135879, 135881, 135939, 135941,
- 135947, 135949, 135951, 135959, 135961, 135963, 135965, 135973, 135975,
- 135977, 136074, 135985, 136076, 136078, 135997, 136080, 135999, 136001,
- 136027, 136082, 136084, 136017, 136086, 136019, 136021, 201375, 201378,
- 201624, 201381, 201627, 135851, 135853, 135855, 135857, 136094, 135863,
- 135865, 135867, 135869, 136096, 135877, 135883, 135885, 135887, 135889,
- 135891, 135895, 135897, 135899, 135901, 135903, 135905, 136098, 135907,
- 135909, 135911, 135913, 135915, 135917, 135921, 135923, 135925, 135927,
- 135929, 135931, 135933, 135935, 135937, 135943, 135945, 135953, 135955,
- 135957, 135959, 135961, 135967, 135969, 135971, 135973, 136100, 135979,
- 135981, 135983, 135985, 135991, 135993, 135995, 135997, 136102, 136003,
- 136005, 136104, 136011, 136013, 136015, 136017, 136106, 201381, 201627,
- 135857, 136094, 135869, 136096, 135877, 136108, 135903, 136110, 136112,
- 136114, 135959, 135961, 135973, 135997, 136102, 136017, 136106, 201652,
- 201655, 201658, 136125, 136127, 136129, 136131, 136133, 136135, 136137,
- 136139, 136141, 136143, 136145, 136147, 136149, 136151, 136153, 136155,
- 136157, 136159, 136161, 136163, 136165, 136167, 136169, 136112, 136171,
- 136173, 136175, 136177, 136125, 136127, 136129, 136131, 136133, 136135,
- 136137, 136139, 136141, 136143, 136145, 136147, 136149, 136151, 136153,
- 136155, 136157, 136159, 136161, 136163, 136165, 136167, 136169, 136112,
- 136171, 136173, 136175, 136177, 136165, 136167, 136169, 136112, 136110,
- 136114, 135919, 135897, 135899, 135901, 136165, 136167, 136169, 135919,
- 135921, 136179, 136179, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 201717, 201720, 201720, 201723, 201726,
- 201729, 201732, 201735, 201738, 201738, 201741, 201744, 201747, 201750,
- 201753, 201756, 201756, 201759, 201762, 201762, 201765, 201765, 201768,
- 201771, 201771, 201774, 201777, 201777, 201780, 201780, 201783, 201786,
- 201786, 201789, 201789, 201792, 201795, 201798, 201801, 201801, 201804,
- 201807, 201810, 201813, 201816, 201816, 201819, 201822, 201825, 201828,
- 201831, 201834, 201834, 201837, 201837, 201840, 201840, 201843, 201846,
- 201849, 201852, 201855, 201858, 201861, -1, -1, 201864, 201867, 201870,
- 201873, 201876, 201879, 201879, 201882, 201885, 201888, 201891, 201891,
- 201894, 201897, 201900, 201903, 201906, 201909, 201912, 201915, 201918,
- 201921, 201924, 201927, 201930, 201933, 201936, 201939, 201942, 201945,
- 201948, 201951, 201954, 201957, 201819, 201825, 201960, 201963, 201966,
- 201969, 201972, 201975, 201972, 201966, 201978, 201981, 201984, 201987,
- 201990, 201975, 201798, 201768, 201993, 201996, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 201999, 202002, 267541, 267545, 267549, 267553, 267557, 267561,
- 267565, 202033, 1185076, 529734, 267598, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133211, 70994, 70995, 70996,
- 70996, 67715, 67716, 70997, 70998, 70999, 71000, 71001, 71002, 71003,
- 71004, 67961, 67962, 71005, 71006, 71007, 71008, -1, -1, -1, -1, 133228,
- 133228, 133228, 133228, 70996, 70996, 70996, 71009, 71010, 67674, -1,
- 66157, 71011, 71012, 71013, 70994, 67715, 67716, 70997, 70998, 70999,
- 71000, 71014, 71015, 71016, 67712, 71017, 71018, 71019, 67714, -1,
- 71020, 71021, 71022, 71023, -1, -1, -1, -1, 136560, 136562, 136564,
- -1, 136566, -1, 136568, 136570, 136572, 136574, 136576, 136578, 136580,
- 136582, 136584, 136586, 71052, 131856, 131856, 131858, 131858, 131860,
- 131860, 131862, 131862, 131864, 131864, 131864, 131864, 71053, 71053,
- 71054, 71054, 71054, 71054, 71055, 71055, 71056, 71056, 71056, 71056,
- 71057, 71057, 71057, 71057, 71058, 71058, 71058, 71058, 71059, 71059,
- 71059, 71059, 71060, 71060, 71060, 71060, 71061, 71061, 71062, 71062,
- 71063, 71063, 71064, 71064, 71065, 71065, 71065, 71065, 71066, 71066,
- 71066, 71066, 71067, 71067, 71067, 71067, 71068, 71068, 71068, 71068,
- 71069, 71069, 71069, 71069, 71070, 71070, 71070, 71070, 71071, 71071,
- 71071, 71071, 71072, 71072, 71072, 71072, 71073, 71073, 71073, 71073,
- 71074, 71074, 71074, 71074, 71075, 71075, 71075, 71075, 71076, 71076,
- 71076, 71076, 71077, 71077, 71077, 71077, 71078, 71078, 71078, 71078,
- 71079, 71079, 71079, 71079, 71080, 71080, 70277, 70277, 71081, 71081,
- 71081, 71081, 202154, 202154, 202157, 202157, 202160, 202160, 136627,
- 136627, -1, -1, -1, -1, 71013, 71093, 71014, 71021, 71022, 71015, 71094,
- 67715, 67716, 71016, 67712, 71009, 71017, 67674, 71095, 67704, 65549,
- 65542, 65543, 67706, 67707, 67708, 67709, 67710, 67711, 71011, 66157,
- 71018, 67714, 71019, 71012, 71023, 68185, 67759, 67726, 67772, 67761,
- 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188,
- 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193,
- 67756, 71096, 71020, 71097, 71098, 70996, 67649, 65539, 68194, 67861,
- 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862,
- 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131,
- 66147, 66132, 68201, 70997, 71099, 70998, 71100, 71101, 71102, 71103,
- 71005, 71006, 71010, 71104, 69066, 71105, 71106, 71107, 71108, 71109,
- 71110, 71111, 71112, 71113, 71114, 69020, 69021, 69022, 69023, 69024,
- 69025, 69026, 69027, 69028, 69029, 69030, 69031, 69032, 69033, 69034,
- 69035, 69036, 69037, 69038, 69039, 69040, 69041, 69042, 69043, 69044,
- 69045, 69046, 69047, 69048, 69049, 69050, 69051, 69052, 69053, 69054,
- 69055, 69056, 69057, 69058, 69059, 69060, 69061, 69062, 69063, 71115,
- 71116, 71117, 68610, 68559, 68560, 68561, 68562, 68563, 68564, 68565,
- 68566, 68567, 68568, 68569, 68570, 68571, 68572, 68573, 68574, 68575,
- 68576, 68577, 68578, 68579, 68580, 68581, 68582, 68583, 68584, 68585,
- 68586, 68587, 68588, -1, -1, -1, 68589, 68590, 68591, 68592, 68593,
- 68594, -1, -1, 68595, 68596, 68597, 68598, 68599, 68600, -1, -1, 68601,
- 68602, 68603, 68604, 68605, 68606, -1, -1, 68607, 68608, 68609, -1,
- -1, -1, 71118, 71119, 71120, 131076, 71121, 71122, 71123, -1, 71124,
- 71125, 71126, 71127, 71128, 71129, 71130, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 136667, 136669, 202207, 202210, 202213, 202216, 202219, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 136686, 136688, 202226, 202229, 202232, 202235, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 68185, 67759, 67726, 67772, 67761, 67762,
- 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746,
- 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756,
- 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126,
- 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199,
- 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 67772,
- 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743,
- 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831,
- 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, -1,
- 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127,
- 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759,
- 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742,
- 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819,
- 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195,
- 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197,
- 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201,
- 68185, -1, 67726, 67772, -1, -1, 68186, -1, -1, 68187, 67758, -1, -1,
- 67743, 68188, 67746, 67747, -1, 68189, 68190, 68191, 67819, 68192,
- 67831, 68193, 67756, 65539, 68194, 67861, 67773, -1, 68195, -1, 66124,
- 67705, 66126, 68196, -1, 67862, 67717, -1, 68197, 68198, 66127, 65892,
- 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726,
- 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763,
- 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192,
- 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738,
- 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198,
- 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185,
- 67759, -1, 67772, 67761, 67762, 68186, -1, -1, 68187, 67758, 67742,
- 67763, 67743, 68188, 67746, 67747, -1, 68189, 68190, 68191, 67819,
- 68192, 67831, 68193, -1, 65539, 68194, 67861, 67773, 67760, 68195,
- 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197,
- 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201,
- 68185, 67759, -1, 67772, 67761, 67762, 68186, -1, 67741, 68187, 67758,
- 67742, 67763, -1, 68188, -1, -1, -1, 68189, 68190, 68191, 67819, 68192,
- 67831, 68193, -1, 65539, 68194, 67861, 67773, 67760, 68195, 67738,
- 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198,
- 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185,
- 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758,
- 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191,
- 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760,
- 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550,
- 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132,
- 68201, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741,
- 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189,
- 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861,
- 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862,
- 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131,
- 66147, 66132, 68201, 68185, 67759, 67726, 67772, 67761, 67762, 68186,
- 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747,
- 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539,
- 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196,
- 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200,
- 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 67772, 67761,
- 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188,
- 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193,
- 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705,
- 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892,
- 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726,
- 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763,
- 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192,
- 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738,
- 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198,
- 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185,
- 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758,
- 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191,
- 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760,
- 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550,
- 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132,
- 68201, -1, -1, -1, -1, 71166, 71167, 67769, 71168, 71169, 71170, 71171,
- 66212, 71172, 71173, 71174, 71175, 71176, 71177, 71178, 67770, 71179,
- 66212, 71180, 71181, 66206, 71182, 71183, 71184, 67757, 71185, 71186,
- 66204, 67768, 71187, 66213, 71188, 71189, 66205, 67561, 66209, 71190,
- 65546, 71191, 71192, 71193, 66208, 66210, 66211, 71194, 71195, 71196,
- 66207, 71197, 71198, 71199, 71200, 66213, 66205, 66209, 66207, 66210,
- 66208, 71166, 71167, 67769, 71168, 71169, 71170, 71171, 66212, 71172,
- 71173, 71174, 71175, 71176, 71177, 71178, 67770, 71179, 66212, 71180,
- 71181, 66206, 71182, 71183, 71184, 67757, 71185, 71186, 66204, 67768,
- 71187, 66213, 71188, 71189, 66205, 67561, 66209, 71190, 65546, 71191,
- 71192, 71193, 66208, 66210, 66211, 71194, 71195, 71196, 66207, 71197,
- 71198, 71199, 71200, 66213, 66205, 66209, 66207, 66210, 66208, 71166,
- 71167, 67769, 71168, 71169, 71170, 71171, 66212, 71172, 71173, 71174,
- 71175, 71176, 71177, 71178, 67770, 71179, 66212, 71180, 71181, 66206,
- 71182, 71183, 71184, 67757, 71185, 71186, 66204, 67768, 71187, 66213,
- 71188, 71189, 66205, 67561, 66209, 71190, 65546, 71191, 71192, 71193,
- 66208, 66210, 66211, 71194, 71195, 71196, 66207, 71197, 71198, 71199,
- 71200, 66213, 66205, 66209, 66207, 66210, 66208, 71166, 71167, 67769,
- 71168, 71169, 71170, 71171, 66212, 71172, 71173, 71174, 71175, 71176,
- 71177, 71178, 67770, 71179, 66212, 71180, 71181, 66206, 71182, 71183,
- 71184, 67757, 71185, 71186, 66204, 67768, 71187, 66213, 71188, 71189,
- 66205, 67561, 66209, 71190, 65546, 71191, 71192, 71193, 66208, 66210,
- 66211, 71194, 71195, 71196, 66207, 71197, 71198, 71199, 71200, 66213,
- 66205, 66209, 66207, 66210, 66208, 71166, 71167, 67769, 71168, 71169,
- 71170, 71171, 66212, 71172, 71173, 71174, 71175, 71176, 71177, 71178,
- 67770, 71179, 66212, 71180, 71181, 66206, 71182, 71183, 71184, 67757,
- 71185, 71186, 66204, 67768, 71187, 66213, 71188, 71189, 66205, 67561,
- 66209, 71190, 65546, 71191, 71192, 71193, 66208, 66210, 66211, 71194,
- 71195, 71196, 66207, 71197, 71198, 71199, 71200, 66213, 66205, 66209,
- 66207, 66210, 66208, -1, -1, -1, -1, 67704, 65549, 65542, 65543, 67706,
- 67707, 67708, 67709, 67710, 67711, 67704, 65549, 65542, 65543, 67706,
- 67707, 67708, 67709, 67710, 67711, 67704, 65549, 65542, 65543, 67706,
- 67707, 67708, 67709, 67710, 67711, 67704, 65549, 65542, 65543, 67706,
- 67707, 67708, 67709, 67710, 67711, 67704, 65549, 65542, 65543, 67706,
- 67707, 67708, 67709, 67710, 67711, 71201, 71202, 71203, 71204, 71205,
- 70085, 71206, 71207, 71208, 71209, 70086, 71210, 71211, 71212, 70087,
- 71213, 71214, 71215, 71216, 71217, 71218, 71219, 71220, 71221, 71222,
- 71223, 71224, 71225, 71226, 68234, 71227, 71228, 71229, 71230, 71231,
- 71232, 71233, 71234, 70088, 70089, 71235, 71236, 71237, 69908, 71238,
- 70090, 71239, 71240, 71241, 71242, 71242, 71242, 71243, 71244, 71245,
- 71246, 71247, 71248, 71249, 71250, 71251, 71252, 71253, 71254, 71255,
- 71256, 71257, 71258, 71259, 71260, 71260, 71261, 71262, 71263, 71264,
- 71265, 70092, 71266, 71267, 71268, 70054, 71269, 71270, 71271, 71272,
- 71273, 71274, 71275, 71276, 71277, 71278, 71279, 71280, 71281, 71282,
- 71283, 71284, 71285, 71286, 71287, 71288, 71289, 71290, 71291, 71292,
- 71293, 71294, 71294, 71295, 71296, 71297, 69904, 71298, 71299, 71300,
- 71301, 71302, 68260, 71303, 71304, 68262, 71305, 71306, 71307, 71308,
- 71309, 71310, 71311, 71312, 71313, 71314, 71315, 71316, 71317, 71318,
- 71319, 71320, 71321, 71322, 71323, 71324, 71325, 69852, 71326, 68272,
- 71327, 71327, 71328, 71329, 71329, 71330, 71331, 71332, 71333, 71334,
- 71335, 71336, 71337, 71338, 71339, 71340, 71341, 71342, 70097, 71343,
- 71344, 71345, 71346, 71347, 71346, 71348, 70099, 71349, 71350, 71351,
- 71352, 70100, 69825, 71353, 71354, 71355, 71356, 71357, 71358, 71359,
- 71360, 71361, 71362, 71363, 71364, 71365, 71366, 71367, 71368, 71369,
- 71370, 71371, 71372, 71373, 71374, 70101, 71375, 71376, 71377, 71378,
- 71379, 71380, 70103, 71381, 71382, 71383, 71384, 71385, 71386, 71387,
- 71388, 69853, 71389, 71390, 71391, 71392, 71393, 71394, 71395, 71396,
- 71397, 70104, 71398, 71399, 71400, 71401, 71402, 71403, 71404, 71405,
- 71406, 71407, 71408, 71409, 71410, 71411, 71412, 71413, 71414, 71415,
- 69921, 71416, 71417, 71418, 71419, 71420, 71421, 71422, 71423, 71424,
- 71425, 71426, 70105, 70004, 71427, 71428, 71429, 71430, 71431, 71432,
- 71433, 71434, 71435, 71436, 71437, 71438, 71439, 71440, 71441, 71442,
- 71443, 71444, 71445, 71446, 71447, 71448, 71449, 71450, 71451, 71452,
- 71453, 71454, 71455, 71456, 71457, 71458, 71459, 71460, 71461, 71462,
- 71463, 71464, 71465, 71466, 71467, 71468, 71468, 71469, 71470, 71471,
- 71472, 71473, 71474, 71475, 71476, 71477, 71478, 69907, 71479, 71480,
- 71481, 71482, 71483, 71484, 71485, 71486, 71487, 71488, 71489, 71490,
- 71491, 71492, 71492, 71493, 71494, 71495, 71496, 71497, 71498, 71499,
- 69870, 71500, 71501, 71502, 70115, 71503, 71504, 70074, 71505, 71506,
- 70118, 71507, 71508, 71509, 71510, 71510, 71511, 71512, 71513, 71514,
- 71515, 71516, 71517, 71518, 71519, 71520, 71521, 71522, 71523, 71524,
- 71525, 71526, 71527, 71528, 71529, 71530, 71531, 71532, 71533, 71534,
- 71535, 71536, 71537, 70124, 71538, 71539, 71540, 71541, 71542, 71543,
- 71544, 71545, 71546, 71547, 71548, 71549, 71550, 71551, 71552, 71553,
- 71328, 71554, 71555, 71556, 71557, 71558, 71559, 71560, 71561, 71562,
- 71563, 71564, 71565, 69924, 71566, 71567, 71568, 71569, 71570, 71571,
- 70127, 71572, 71573, 71574, 71575, 71576, 71577, 71578, 71579, 71580,
- 71581, 71582, 71583, 71584, 71585, 71586, 71587, 71588, 71589, 71590,
- 71591, 69865, 71592, 71593, 71594, 71595, 71596, 71597, 71598, 71599,
- 71600, 71601, 71602, 71603, 71604, 71605, 71606, 68362, 71607, 71608,
- 71609, 71610, 71611, 71612, 71613, 71614, 71615, 71616, 71617, 71618,
- 71619, 68369, 71620, 71621, 71622, 71623, 71624, 71625, 71626, 71627,
- 71628, 71629, 71630, 71631, 71632, 71633, 71634, 71635, 71636, 71637,
- 71638, 71639, 71640, 71641, 71642, 71643, 71644, 71645, 71646, 71647,
- 71648, 71649, 71650, 71651, 71652, 71653, 71654, 71655, 71656, 71657,
- 71658, 71659, 71660, 71661, 71662, 71663, 71663, 71664, 71665, 71666,
- 71667, 71668, 71669, 71670, 71671, 71672, 71673, 71674, 71675, 71676,
- 71677, 71678, 71679, 71680, 71681, 71682, 71683, 71684, 68417, 71685,
- 68421, 71686, 71687, 71688, 71689, 68426, 71690, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-/*
- * List of decomposition sequences
- */
-
-static int decompList[] = {
- 32, 32, 776, 97, 32, 772, 50, 51, 32, 769, 956, 32, 807, 49, 111, 49,
- 8260, 52, 49, 8260, 50, 51, 8260, 52, 65, 768, 65, 769, 65, 770, 65,
- 771, 65, 776, 65, 778, 67, 807, 69, 768, 69, 769, 69, 770, 69, 776,
- 73, 768, 73, 769, 73, 770, 73, 776, 78, 771, 79, 768, 79, 769, 79,
- 770, 79, 771, 79, 776, 85, 768, 85, 769, 85, 770, 85, 776, 89, 769,
- 97, 768, 97, 769, 97, 770, 97, 771, 97, 776, 97, 778, 99, 807, 101,
- 768, 101, 769, 101, 770, 101, 776, 105, 768, 105, 769, 105, 770, 105,
- 776, 110, 771, 111, 768, 111, 769, 111, 770, 111, 771, 111, 776, 117,
- 768, 117, 769, 117, 770, 117, 776, 121, 769, 121, 776, 65, 772, 97,
- 772, 65, 774, 97, 774, 65, 808, 97, 808, 67, 769, 99, 769, 67, 770,
- 99, 770, 67, 775, 99, 775, 67, 780, 99, 780, 68, 780, 100, 780, 69,
- 772, 101, 772, 69, 774, 101, 774, 69, 775, 101, 775, 69, 808, 101,
- 808, 69, 780, 101, 780, 71, 770, 103, 770, 71, 774, 103, 774, 71, 775,
- 103, 775, 71, 807, 103, 807, 72, 770, 104, 770, 73, 771, 105, 771,
- 73, 772, 105, 772, 73, 774, 105, 774, 73, 808, 105, 808, 73, 775, 73,
- 74, 105, 106, 74, 770, 106, 770, 75, 807, 107, 807, 76, 769, 108, 769,
- 76, 807, 108, 807, 76, 780, 108, 780, 76, 183, 108, 183, 78, 769, 110,
- 769, 78, 807, 110, 807, 78, 780, 110, 780, 700, 110, 79, 772, 111,
- 772, 79, 774, 111, 774, 79, 779, 111, 779, 82, 769, 114, 769, 82, 807,
- 114, 807, 82, 780, 114, 780, 83, 769, 115, 769, 83, 770, 115, 770,
- 83, 807, 115, 807, 83, 780, 115, 780, 84, 807, 116, 807, 84, 780, 116,
- 780, 85, 771, 117, 771, 85, 772, 117, 772, 85, 774, 117, 774, 85, 778,
- 117, 778, 85, 779, 117, 779, 85, 808, 117, 808, 87, 770, 119, 770,
- 89, 770, 121, 770, 89, 776, 90, 769, 122, 769, 90, 775, 122, 775, 90,
- 780, 122, 780, 115, 79, 795, 111, 795, 85, 795, 117, 795, 68, 90, 780,
- 68, 122, 780, 100, 122, 780, 76, 74, 76, 106, 108, 106, 78, 74, 78,
- 106, 110, 106, 65, 780, 97, 780, 73, 780, 105, 780, 79, 780, 111, 780,
- 85, 780, 117, 780, 85, 776, 772, 117, 776, 772, 85, 776, 769, 117,
- 776, 769, 85, 776, 780, 117, 776, 780, 85, 776, 768, 117, 776, 768,
- 65, 776, 772, 97, 776, 772, 65, 775, 772, 97, 775, 772, 198, 772, 230,
- 772, 71, 780, 103, 780, 75, 780, 107, 780, 79, 808, 111, 808, 79, 808,
- 772, 111, 808, 772, 439, 780, 658, 780, 106, 780, 68, 90, 68, 122,
- 100, 122, 71, 769, 103, 769, 78, 768, 110, 768, 65, 778, 769, 97, 778,
- 769, 198, 769, 230, 769, 216, 769, 248, 769, 65, 783, 97, 783, 65,
- 785, 97, 785, 69, 783, 101, 783, 69, 785, 101, 785, 73, 783, 105, 783,
- 73, 785, 105, 785, 79, 783, 111, 783, 79, 785, 111, 785, 82, 783, 114,
- 783, 82, 785, 114, 785, 85, 783, 117, 783, 85, 785, 117, 785, 83, 806,
- 115, 806, 84, 806, 116, 806, 72, 780, 104, 780, 65, 775, 97, 775, 69,
- 807, 101, 807, 79, 776, 772, 111, 776, 772, 79, 771, 772, 111, 771,
- 772, 79, 775, 111, 775, 79, 775, 772, 111, 775, 772, 89, 772, 121,
- 772, 104, 614, 106, 114, 633, 635, 641, 119, 121, 32, 774, 32, 775,
- 32, 778, 32, 808, 32, 771, 32, 779, 611, 108, 120, 661, 768, 769, 787,
- 776, 769, 697, 32, 837, 59, 32, 776, 769, 913, 769, 183, 917, 769,
- 919, 769, 921, 769, 927, 769, 933, 769, 937, 769, 953, 776, 769, 921,
- 776, 933, 776, 945, 769, 949, 769, 951, 769, 953, 769, 965, 776, 769,
- 953, 776, 965, 776, 959, 769, 965, 769, 969, 769, 946, 952, 933, 966,
- 960, 954, 961, 962, 920, 949, 1045, 768, 1045, 776, 1043, 769, 1030,
- 776, 1050, 769, 1048, 768, 1059, 774, 1048, 774, 1080, 774, 1077, 768,
- 1077, 776, 1075, 769, 1110, 776, 1082, 769, 1080, 768, 1091, 774, 1140,
- 783, 1141, 783, 1046, 774, 1078, 774, 1040, 774, 1072, 774, 1040, 776,
- 1072, 776, 1045, 774, 1077, 774, 1240, 776, 1241, 776, 1046, 776, 1078,
- 776, 1047, 776, 1079, 776, 1048, 772, 1080, 772, 1048, 776, 1080, 776,
- 1054, 776, 1086, 776, 1256, 776, 1257, 776, 1069, 776, 1101, 776, 1059,
- 772, 1091, 772, 1059, 776, 1091, 776, 1059, 779, 1091, 779, 1063, 776,
- 1095, 776, 1067, 776, 1099, 776, 1381, 1410, 1575, 1619, 1575, 1620,
- 1608, 1620, 1575, 1621, 1610, 1620, 1575, 1652, 1608, 1652, 1735, 1652,
- 1610, 1652, 1749, 1620, 1729, 1620, 1746, 1620, 2344, 2364, 2352, 2364,
- 2355, 2364, 2325, 2364, 2326, 2364, 2327, 2364, 2332, 2364, 2337, 2364,
- 2338, 2364, 2347, 2364, 2351, 2364, 2503, 2494, 2503, 2519, 2465, 2492,
- 2466, 2492, 2479, 2492, 2610, 2620, 2616, 2620, 2582, 2620, 2583, 2620,
- 2588, 2620, 2603, 2620, 2887, 2902, 2887, 2878, 2887, 2903, 2849, 2876,
- 2850, 2876, 2962, 3031, 3014, 3006, 3015, 3006, 3014, 3031, 3142, 3158,
- 3263, 3285, 3270, 3285, 3270, 3286, 3270, 3266, 3270, 3266, 3285, 3398,
- 3390, 3399, 3390, 3398, 3415, 3545, 3530, 3545, 3535, 3545, 3535, 3530,
- 3545, 3551, 3661, 3634, 3789, 3762, 3755, 3737, 3755, 3745, 3851, 3906,
- 4023, 3916, 4023, 3921, 4023, 3926, 4023, 3931, 4023, 3904, 4021, 3953,
- 3954, 3953, 3956, 4018, 3968, 4018, 3953, 3968, 4019, 3968, 4019, 3953,
- 3968, 3953, 3968, 3986, 4023, 3996, 4023, 4001, 4023, 4006, 4023, 4011,
- 4023, 3984, 4021, 4133, 4142, 65, 805, 97, 805, 66, 775, 98, 775, 66,
- 803, 98, 803, 66, 817, 98, 817, 67, 807, 769, 99, 807, 769, 68, 775,
- 100, 775, 68, 803, 100, 803, 68, 817, 100, 817, 68, 807, 100, 807,
- 68, 813, 100, 813, 69, 772, 768, 101, 772, 768, 69, 772, 769, 101,
- 772, 769, 69, 813, 101, 813, 69, 816, 101, 816, 69, 807, 774, 101,
- 807, 774, 70, 775, 102, 775, 71, 772, 103, 772, 72, 775, 104, 775,
- 72, 803, 104, 803, 72, 776, 104, 776, 72, 807, 104, 807, 72, 814, 104,
- 814, 73, 816, 105, 816, 73, 776, 769, 105, 776, 769, 75, 769, 107,
- 769, 75, 803, 107, 803, 75, 817, 107, 817, 76, 803, 108, 803, 76, 803,
- 772, 108, 803, 772, 76, 817, 108, 817, 76, 813, 108, 813, 77, 769,
- 109, 769, 77, 775, 109, 775, 77, 803, 109, 803, 78, 775, 110, 775,
- 78, 803, 110, 803, 78, 817, 110, 817, 78, 813, 110, 813, 79, 771, 769,
- 111, 771, 769, 79, 771, 776, 111, 771, 776, 79, 772, 768, 111, 772,
- 768, 79, 772, 769, 111, 772, 769, 80, 769, 112, 769, 80, 775, 112,
- 775, 82, 775, 114, 775, 82, 803, 114, 803, 82, 803, 772, 114, 803,
- 772, 82, 817, 114, 817, 83, 775, 115, 775, 83, 803, 115, 803, 83, 769,
- 775, 115, 769, 775, 83, 780, 775, 115, 780, 775, 83, 803, 775, 115,
- 803, 775, 84, 775, 116, 775, 84, 803, 116, 803, 84, 817, 116, 817,
- 84, 813, 116, 813, 85, 804, 117, 804, 85, 816, 117, 816, 85, 813, 117,
- 813, 85, 771, 769, 117, 771, 769, 85, 772, 776, 117, 772, 776, 86,
- 771, 118, 771, 86, 803, 118, 803, 87, 768, 119, 768, 87, 769, 119,
- 769, 87, 776, 119, 776, 87, 775, 119, 775, 87, 803, 119, 803, 88, 775,
- 120, 775, 88, 776, 120, 776, 89, 775, 121, 775, 90, 770, 122, 770,
- 90, 803, 122, 803, 90, 817, 122, 817, 104, 817, 116, 776, 119, 778,
- 121, 778, 97, 702, 65, 803, 97, 803, 65, 777, 97, 777, 65, 770, 769,
- 97, 770, 769, 65, 770, 768, 97, 770, 768, 65, 770, 777, 97, 770, 777,
- 65, 770, 771, 97, 770, 771, 65, 803, 770, 97, 803, 770, 65, 774, 769,
- 97, 774, 769, 65, 774, 768, 97, 774, 768, 65, 774, 777, 97, 774, 777,
- 65, 774, 771, 97, 774, 771, 65, 803, 774, 97, 803, 774, 69, 803, 101,
- 803, 69, 777, 101, 777, 69, 771, 101, 771, 69, 770, 769, 101, 770,
- 769, 69, 770, 768, 101, 770, 768, 69, 770, 777, 101, 770, 777, 69,
- 770, 771, 101, 770, 771, 69, 803, 770, 101, 803, 770, 73, 777, 105,
- 777, 73, 803, 105, 803, 79, 803, 111, 803, 79, 777, 111, 777, 79, 770,
- 769, 111, 770, 769, 79, 770, 768, 111, 770, 768, 79, 770, 777, 111,
- 770, 777, 79, 770, 771, 111, 770, 771, 79, 803, 770, 111, 803, 770,
- 79, 795, 769, 111, 795, 769, 79, 795, 768, 111, 795, 768, 79, 795,
- 777, 111, 795, 777, 79, 795, 771, 111, 795, 771, 79, 795, 803, 111,
- 795, 803, 85, 803, 117, 803, 85, 777, 117, 777, 85, 795, 769, 117,
- 795, 769, 85, 795, 768, 117, 795, 768, 85, 795, 777, 117, 795, 777,
- 85, 795, 771, 117, 795, 771, 85, 795, 803, 117, 795, 803, 89, 768,
- 121, 768, 89, 803, 121, 803, 89, 777, 121, 777, 89, 771, 121, 771,
- 945, 787, 945, 788, 945, 787, 768, 945, 788, 768, 945, 787, 769, 945,
- 788, 769, 945, 787, 834, 945, 788, 834, 913, 787, 913, 788, 913, 787,
- 768, 913, 788, 768, 913, 787, 769, 913, 788, 769, 913, 787, 834, 913,
- 788, 834, 949, 787, 949, 788, 949, 787, 768, 949, 788, 768, 949, 787,
- 769, 949, 788, 769, 917, 787, 917, 788, 917, 787, 768, 917, 788, 768,
- 917, 787, 769, 917, 788, 769, 951, 787, 951, 788, 951, 787, 768, 951,
- 788, 768, 951, 787, 769, 951, 788, 769, 951, 787, 834, 951, 788, 834,
- 919, 787, 919, 788, 919, 787, 768, 919, 788, 768, 919, 787, 769, 919,
- 788, 769, 919, 787, 834, 919, 788, 834, 953, 787, 953, 788, 953, 787,
- 768, 953, 788, 768, 953, 787, 769, 953, 788, 769, 953, 787, 834, 953,
- 788, 834, 921, 787, 921, 788, 921, 787, 768, 921, 788, 768, 921, 787,
- 769, 921, 788, 769, 921, 787, 834, 921, 788, 834, 959, 787, 959, 788,
- 959, 787, 768, 959, 788, 768, 959, 787, 769, 959, 788, 769, 927, 787,
- 927, 788, 927, 787, 768, 927, 788, 768, 927, 787, 769, 927, 788, 769,
- 965, 787, 965, 788, 965, 787, 768, 965, 788, 768, 965, 787, 769, 965,
- 788, 769, 965, 787, 834, 965, 788, 834, 933, 788, 933, 788, 768, 933,
- 788, 769, 933, 788, 834, 969, 787, 969, 788, 969, 787, 768, 969, 788,
- 768, 969, 787, 769, 969, 788, 769, 969, 787, 834, 969, 788, 834, 937,
- 787, 937, 788, 937, 787, 768, 937, 788, 768, 937, 787, 769, 937, 788,
- 769, 937, 787, 834, 937, 788, 834, 945, 768, 949, 768, 951, 768, 953,
- 768, 959, 768, 965, 768, 969, 768, 945, 787, 837, 945, 788, 837, 945,
- 787, 768, 837, 945, 788, 768, 837, 945, 787, 769, 837, 945, 788, 769,
- 837, 945, 787, 834, 837, 945, 788, 834, 837, 913, 787, 837, 913, 788,
- 837, 913, 787, 768, 837, 913, 788, 768, 837, 913, 787, 769, 837, 913,
- 788, 769, 837, 913, 787, 834, 837, 913, 788, 834, 837, 951, 787, 837,
- 951, 788, 837, 951, 787, 768, 837, 951, 788, 768, 837, 951, 787, 769,
- 837, 951, 788, 769, 837, 951, 787, 834, 837, 951, 788, 834, 837, 919,
- 787, 837, 919, 788, 837, 919, 787, 768, 837, 919, 788, 768, 837, 919,
- 787, 769, 837, 919, 788, 769, 837, 919, 787, 834, 837, 919, 788, 834,
- 837, 969, 787, 837, 969, 788, 837, 969, 787, 768, 837, 969, 788, 768,
- 837, 969, 787, 769, 837, 969, 788, 769, 837, 969, 787, 834, 837, 969,
- 788, 834, 837, 937, 787, 837, 937, 788, 837, 937, 787, 768, 837, 937,
- 788, 768, 837, 937, 787, 769, 837, 937, 788, 769, 837, 937, 787, 834,
- 837, 937, 788, 834, 837, 945, 774, 945, 772, 945, 768, 837, 945, 837,
- 945, 769, 837, 945, 834, 945, 834, 837, 913, 774, 913, 772, 913, 768,
- 913, 837, 32, 787, 953, 32, 834, 32, 776, 834, 951, 768, 837, 951,
- 837, 951, 769, 837, 951, 834, 951, 834, 837, 917, 768, 919, 768, 919,
- 837, 32, 787, 768, 32, 787, 769, 32, 787, 834, 953, 774, 953, 772,
- 953, 776, 768, 953, 834, 953, 776, 834, 921, 774, 921, 772, 921, 768,
- 32, 788, 768, 32, 788, 769, 32, 788, 834, 965, 774, 965, 772, 965,
- 776, 768, 961, 787, 961, 788, 965, 834, 965, 776, 834, 933, 774, 933,
- 772, 933, 768, 929, 788, 32, 776, 768, 96, 969, 768, 837, 969, 837,
- 969, 769, 837, 969, 834, 969, 834, 837, 927, 768, 937, 768, 937, 837,
- 32, 788, 8208, 32, 819, 46, 46, 46, 46, 46, 46, 8242, 8242, 8242, 8242,
- 8242, 8245, 8245, 8245, 8245, 8245, 33, 33, 32, 773, 63, 63, 63, 33,
- 33, 63, 8242, 8242, 8242, 8242, 48, 105, 52, 53, 54, 55, 56, 57, 43,
- 8722, 61, 40, 41, 110, 82, 115, 97, 47, 99, 97, 47, 115, 67, 176, 67,
- 99, 47, 111, 99, 47, 117, 400, 176, 70, 103, 72, 295, 73, 76, 78, 78,
- 111, 80, 81, 82, 83, 77, 84, 69, 76, 84, 77, 90, 937, 75, 66, 101,
- 69, 70, 77, 1488, 1489, 1490, 1491, 947, 915, 928, 8721, 68, 100, 49,
- 8260, 51, 50, 8260, 51, 49, 8260, 53, 50, 8260, 53, 51, 8260, 53, 52,
- 8260, 53, 49, 8260, 54, 53, 8260, 54, 49, 8260, 56, 51, 8260, 56, 53,
- 8260, 56, 55, 8260, 56, 49, 8260, 73, 73, 73, 73, 73, 73, 86, 86, 86,
- 73, 86, 73, 73, 86, 73, 73, 73, 73, 88, 88, 88, 73, 88, 73, 73, 105,
- 105, 105, 105, 105, 105, 118, 118, 118, 105, 118, 105, 105, 118, 105,
- 105, 105, 105, 120, 120, 105, 120, 105, 105, 99, 109, 8592, 824, 8594,
- 824, 8596, 824, 8656, 824, 8660, 824, 8658, 824, 8707, 824, 8712, 824,
- 8715, 824, 8739, 824, 8741, 824, 8747, 8747, 8747, 8747, 8747, 8750,
- 8750, 8750, 8750, 8750, 8764, 824, 8771, 824, 8773, 824, 8776, 824,
- 61, 824, 8801, 824, 8781, 824, 60, 824, 62, 824, 8804, 824, 8805, 824,
- 8818, 824, 8819, 824, 8822, 824, 8823, 824, 8826, 824, 8827, 824, 8834,
- 824, 8835, 824, 8838, 824, 8839, 824, 8866, 824, 8872, 824, 8873, 824,
- 8875, 824, 8828, 824, 8829, 824, 8849, 824, 8850, 824, 8882, 824, 8883,
- 824, 8884, 824, 8885, 824, 12296, 12297, 49, 48, 49, 49, 49, 50, 49,
- 51, 49, 52, 49, 53, 49, 54, 49, 55, 49, 56, 49, 57, 50, 48, 40, 49,
- 41, 40, 50, 41, 40, 51, 41, 40, 52, 41, 40, 53, 41, 40, 54, 41, 40,
- 55, 41, 40, 56, 41, 40, 57, 41, 40, 49, 48, 41, 40, 49, 49, 41, 40,
- 49, 50, 41, 40, 49, 51, 41, 40, 49, 52, 41, 40, 49, 53, 41, 40, 49,
- 54, 41, 40, 49, 55, 41, 40, 49, 56, 41, 40, 49, 57, 41, 40, 50, 48,
- 41, 49, 46, 50, 46, 51, 46, 52, 46, 53, 46, 54, 46, 55, 46, 56, 46,
- 57, 46, 49, 48, 46, 49, 49, 46, 49, 50, 46, 49, 51, 46, 49, 52, 46,
- 49, 53, 46, 49, 54, 46, 49, 55, 46, 49, 56, 46, 49, 57, 46, 50, 48,
- 46, 40, 97, 41, 40, 98, 41, 40, 99, 41, 40, 100, 41, 40, 101, 41, 40,
- 102, 41, 40, 103, 41, 40, 104, 41, 40, 105, 41, 40, 106, 41, 40, 107,
- 41, 40, 108, 41, 40, 109, 41, 40, 110, 41, 40, 111, 41, 40, 112, 41,
- 40, 113, 41, 40, 114, 41, 40, 115, 41, 40, 116, 41, 40, 117, 41, 40,
- 118, 41, 40, 119, 41, 40, 120, 41, 40, 121, 41, 40, 122, 41, 65, 71,
- 74, 79, 83, 84, 85, 87, 89, 98, 102, 107, 112, 113, 116, 117, 122,
- 8747, 8747, 8747, 8747, 58, 58, 61, 61, 61, 61, 61, 61, 10973, 824,
- 27597, 40863, 19968, 20008, 20022, 20031, 20057, 20101, 20108, 20128,
- 20154, 20799, 20837, 20843, 20866, 20886, 20907, 20960, 20981, 20992,
- 21147, 21241, 21269, 21274, 21304, 21313, 21340, 21353, 21378, 21430,
- 21448, 21475, 22231, 22303, 22763, 22786, 22794, 22805, 22823, 22899,
- 23376, 23424, 23544, 23567, 23586, 23608, 23662, 23665, 24027, 24037,
- 24049, 24062, 24178, 24186, 24191, 24308, 24318, 24331, 24339, 24400,
- 24417, 24435, 24515, 25096, 25142, 25163, 25903, 25908, 25991, 26007,
- 26020, 26041, 26080, 26085, 26352, 26376, 26408, 27424, 27490, 27513,
- 27571, 27595, 27604, 27611, 27663, 27668, 27700, 28779, 29226, 29238,
- 29243, 29247, 29255, 29273, 29275, 29356, 29572, 29577, 29916, 29926,
- 29976, 29983, 29992, 30000, 30091, 30098, 30326, 30333, 30382, 30399,
- 30446, 30683, 30690, 30707, 31034, 31160, 31166, 31348, 31435, 31481,
- 31859, 31992, 32566, 32593, 32650, 32701, 32769, 32780, 32786, 32819,
- 32895, 32905, 33251, 33258, 33267, 33276, 33292, 33307, 33311, 33390,
- 33394, 33400, 34381, 34411, 34880, 34892, 34915, 35198, 35211, 35282,
- 35328, 35895, 35910, 35925, 35960, 35997, 36196, 36208, 36275, 36523,
- 36554, 36763, 36784, 36789, 37009, 37193, 37318, 37324, 37329, 38263,
- 38272, 38428, 38582, 38585, 38632, 38737, 38750, 38754, 38761, 38859,
- 38893, 38899, 38913, 39080, 39131, 39135, 39318, 39321, 39340, 39592,
- 39640, 39647, 39717, 39727, 39730, 39740, 39770, 40165, 40565, 40575,
- 40613, 40635, 40643, 40653, 40657, 40697, 40701, 40718, 40723, 40736,
- 40763, 40778, 40786, 40845, 40860, 40864, 12306, 21316, 21317, 12363,
- 12441, 12365, 12441, 12367, 12441, 12369, 12441, 12371, 12441, 12373,
- 12441, 12375, 12441, 12377, 12441, 12379, 12441, 12381, 12441, 12383,
- 12441, 12385, 12441, 12388, 12441, 12390, 12441, 12392, 12441, 12399,
- 12441, 12399, 12442, 12402, 12441, 12402, 12442, 12405, 12441, 12405,
- 12442, 12408, 12441, 12408, 12442, 12411, 12441, 12411, 12442, 12358,
- 12441, 32, 12441, 32, 12442, 12445, 12441, 12424, 12426, 12459, 12441,
- 12461, 12441, 12463, 12441, 12465, 12441, 12467, 12441, 12469, 12441,
- 12471, 12441, 12473, 12441, 12475, 12441, 12477, 12441, 12479, 12441,
- 12481, 12441, 12484, 12441, 12486, 12441, 12488, 12441, 12495, 12441,
- 12495, 12442, 12498, 12441, 12498, 12442, 12501, 12441, 12501, 12442,
- 12504, 12441, 12504, 12442, 12507, 12441, 12507, 12442, 12454, 12441,
- 12527, 12441, 12528, 12441, 12529, 12441, 12530, 12441, 12541, 12441,
- 12467, 12488, 4352, 4353, 4522, 4354, 4524, 4525, 4355, 4356, 4357,
- 4528, 4529, 4530, 4531, 4532, 4533, 4378, 4358, 4359, 4360, 4385, 4361,
- 4362, 4363, 4364, 4365, 4366, 4367, 4368, 4369, 4370, 4449, 4450, 4451,
- 4452, 4453, 4454, 4455, 4456, 4457, 4458, 4459, 4460, 4461, 4462, 4463,
- 4464, 4465, 4466, 4467, 4468, 4469, 4448, 4372, 4373, 4551, 4552, 4556,
- 4558, 4563, 4567, 4569, 4380, 4573, 4575, 4381, 4382, 4384, 4386, 4387,
- 4391, 4393, 4395, 4396, 4397, 4398, 4399, 4402, 4406, 4416, 4423, 4428,
- 4593, 4594, 4439, 4440, 4441, 4484, 4485, 4488, 4497, 4498, 4500, 4510,
- 4513, 19977, 22235, 19978, 20013, 19979, 30002, 19993, 19969, 22825,
- 22320, 40, 4352, 41, 40, 4354, 41, 40, 4355, 41, 40, 4357, 41, 40,
- 4358, 41, 40, 4359, 41, 40, 4361, 41, 40, 4363, 41, 40, 4364, 41, 40,
- 4366, 41, 40, 4367, 41, 40, 4368, 41, 40, 4369, 41, 40, 4370, 41, 40,
- 4352, 4449, 41, 40, 4354, 4449, 41, 40, 4355, 4449, 41, 40, 4357, 4449,
- 41, 40, 4358, 4449, 41, 40, 4359, 4449, 41, 40, 4361, 4449, 41, 40,
- 4363, 4449, 41, 40, 4364, 4449, 41, 40, 4366, 4449, 41, 40, 4367, 4449,
- 41, 40, 4368, 4449, 41, 40, 4369, 4449, 41, 40, 4370, 4449, 41, 40,
- 4364, 4462, 41, 40, 19968, 41, 40, 20108, 41, 40, 19977, 41, 40, 22235,
- 41, 40, 20116, 41, 40, 20845, 41, 40, 19971, 41, 40, 20843, 41, 40,
- 20061, 41, 40, 21313, 41, 40, 26376, 41, 40, 28779, 41, 40, 27700,
- 41, 40, 26408, 41, 40, 37329, 41, 40, 22303, 41, 40, 26085, 41, 40,
- 26666, 41, 40, 26377, 41, 40, 31038, 41, 40, 21517, 41, 40, 29305,
- 41, 40, 36001, 41, 40, 31069, 41, 40, 21172, 41, 40, 20195, 41, 40,
- 21628, 41, 40, 23398, 41, 40, 30435, 41, 40, 20225, 41, 40, 36039,
- 41, 40, 21332, 41, 40, 31085, 41, 40, 20241, 41, 40, 33258, 41, 40,
- 33267, 41, 50, 49, 50, 50, 50, 51, 50, 52, 50, 53, 50, 54, 50, 55,
- 50, 56, 50, 57, 51, 48, 51, 49, 51, 50, 51, 51, 51, 52, 51, 53, 4352,
- 4449, 4354, 4449, 4355, 4449, 4357, 4449, 4358, 4449, 4359, 4449, 4361,
- 4449, 4363, 4449, 4364, 4449, 4366, 4449, 4367, 4449, 4368, 4449, 4369,
- 4449, 4370, 4449, 20116, 20845, 19971, 20061, 26666, 26377, 31038,
- 21517, 29305, 36001, 31069, 21172, 31192, 30007, 36969, 20778, 21360,
- 27880, 38917, 20241, 20889, 27491, 24038, 21491, 21307, 23447, 23398,
- 30435, 20225, 36039, 21332, 22812, 51, 54, 51, 55, 51, 56, 51, 57,
- 52, 48, 52, 49, 52, 50, 52, 51, 52, 52, 52, 53, 52, 54, 52, 55, 52,
- 56, 52, 57, 53, 48, 49, 26376, 50, 26376, 51, 26376, 52, 26376, 53,
- 26376, 54, 26376, 55, 26376, 56, 26376, 57, 26376, 49, 48, 26376, 49,
- 49, 26376, 49, 50, 26376, 12450, 12452, 12454, 12456, 12458, 12459,
- 12461, 12463, 12465, 12467, 12469, 12471, 12473, 12475, 12477, 12479,
- 12481, 12484, 12486, 12488, 12490, 12491, 12492, 12493, 12494, 12495,
- 12498, 12501, 12504, 12507, 12510, 12511, 12512, 12513, 12514, 12516,
- 12518, 12520, 12521, 12522, 12523, 12524, 12525, 12527, 12528, 12529,
- 12530, 12450, 12495, 12442, 12540, 12488, 12450, 12523, 12501, 12449,
- 12450, 12531, 12504, 12442, 12450, 12450, 12540, 12523, 12452, 12491,
- 12531, 12463, 12441, 12452, 12531, 12481, 12454, 12457, 12531, 12456,
- 12473, 12463, 12540, 12488, 12441, 12456, 12540, 12459, 12540, 12458,
- 12531, 12473, 12458, 12540, 12512, 12459, 12452, 12522, 12459, 12521,
- 12483, 12488, 12459, 12525, 12522, 12540, 12459, 12441, 12525, 12531,
- 12459, 12441, 12531, 12510, 12461, 12441, 12459, 12441, 12461, 12441,
- 12491, 12540, 12461, 12517, 12522, 12540, 12461, 12441, 12523, 12479,
- 12441, 12540, 12461, 12525, 12461, 12525, 12463, 12441, 12521, 12512,
- 12461, 12525, 12513, 12540, 12488, 12523, 12461, 12525, 12527, 12483,
- 12488, 12463, 12441, 12521, 12512, 12463, 12441, 12521, 12512, 12488,
- 12531, 12463, 12523, 12475, 12441, 12452, 12525, 12463, 12525, 12540,
- 12493, 12465, 12540, 12473, 12467, 12523, 12490, 12467, 12540, 12507,
- 12442, 12469, 12452, 12463, 12523, 12469, 12531, 12481, 12540, 12512,
- 12471, 12522, 12531, 12463, 12441, 12475, 12531, 12481, 12475, 12531,
- 12488, 12479, 12441, 12540, 12473, 12486, 12441, 12471, 12488, 12441,
- 12523, 12488, 12531, 12490, 12494, 12494, 12483, 12488, 12495, 12452,
- 12484, 12495, 12442, 12540, 12475, 12531, 12488, 12495, 12442, 12540,
- 12484, 12495, 12441, 12540, 12524, 12523, 12498, 12442, 12450, 12473,
- 12488, 12523, 12498, 12442, 12463, 12523, 12498, 12442, 12467, 12498,
- 12441, 12523, 12501, 12449, 12521, 12483, 12488, 12441, 12501, 12451,
- 12540, 12488, 12501, 12441, 12483, 12471, 12455, 12523, 12501, 12521,
- 12531, 12504, 12463, 12479, 12540, 12523, 12504, 12442, 12477, 12504,
- 12442, 12491, 12498, 12504, 12523, 12484, 12504, 12442, 12531, 12473,
- 12504, 12442, 12540, 12471, 12441, 12504, 12441, 12540, 12479, 12507,
- 12442, 12452, 12531, 12488, 12507, 12441, 12523, 12488, 12507, 12531,
- 12507, 12442, 12531, 12488, 12441, 12507, 12540, 12523, 12507, 12540,
- 12531, 12510, 12452, 12463, 12525, 12510, 12452, 12523, 12510, 12483,
- 12495, 12510, 12523, 12463, 12510, 12531, 12471, 12519, 12531, 12511,
- 12463, 12525, 12531, 12511, 12522, 12511, 12522, 12495, 12441, 12540,
- 12523, 12513, 12459, 12441, 12513, 12459, 12441, 12488, 12531, 12513,
- 12540, 12488, 12523, 12516, 12540, 12488, 12441, 12516, 12540, 12523,
- 12518, 12450, 12531, 12522, 12483, 12488, 12523, 12522, 12521, 12523,
- 12498, 12442, 12540, 12523, 12540, 12501, 12441, 12523, 12524, 12512,
- 12524, 12531, 12488, 12465, 12441, 12531, 12527, 12483, 12488, 48,
- 28857, 49, 28857, 50, 28857, 51, 28857, 52, 28857, 53, 28857, 54, 28857,
- 55, 28857, 56, 28857, 57, 28857, 49, 48, 28857, 49, 49, 28857, 49,
- 50, 28857, 49, 51, 28857, 49, 52, 28857, 49, 53, 28857, 49, 54, 28857,
- 49, 55, 28857, 49, 56, 28857, 49, 57, 28857, 50, 48, 28857, 50, 49,
- 28857, 50, 50, 28857, 50, 51, 28857, 50, 52, 28857, 104, 80, 97, 100,
- 97, 65, 85, 98, 97, 114, 111, 86, 112, 99, 24179, 25104, 26157, 21644,
- 22823, 27491, 26126, 27835, 26666, 24335, 20250, 31038, 112, 65, 110,
- 65, 956, 65, 109, 65, 107, 65, 75, 66, 77, 66, 71, 66, 99, 97, 108,
- 107, 99, 97, 108, 112, 70, 110, 70, 956, 70, 956, 103, 109, 103, 107,
- 103, 72, 122, 107, 72, 122, 77, 72, 122, 71, 72, 122, 84, 72, 122,
- 956, 108, 109, 108, 100, 108, 107, 108, 102, 109, 110, 109, 956, 109,
- 109, 109, 99, 109, 107, 109, 109, 109, 50, 99, 109, 50, 109, 50, 107,
- 109, 50, 109, 109, 51, 99, 109, 51, 109, 51, 107, 109, 51, 109, 8725,
- 115, 109, 8725, 115, 50, 80, 97, 107, 80, 97, 77, 80, 97, 71, 80, 97,
- 114, 97, 100, 114, 97, 100, 8725, 115, 114, 97, 100, 8725, 115, 50,
- 112, 115, 110, 115, 956, 115, 109, 115, 112, 86, 110, 86, 956, 86,
- 109, 86, 107, 86, 77, 86, 112, 87, 110, 87, 956, 87, 109, 87, 107,
- 87, 77, 87, 107, 937, 77, 937, 97, 46, 109, 46, 66, 113, 99, 99, 99,
- 100, 67, 8725, 107, 103, 67, 111, 46, 100, 66, 71, 121, 104, 97, 72,
- 80, 105, 110, 75, 75, 75, 77, 107, 116, 108, 109, 108, 110, 108, 111,
- 103, 108, 120, 109, 98, 109, 105, 108, 109, 111, 108, 80, 72, 112,
- 46, 109, 46, 80, 80, 77, 80, 82, 115, 114, 83, 118, 87, 98, 49, 26085,
- 50, 26085, 51, 26085, 52, 26085, 53, 26085, 54, 26085, 55, 26085, 56,
- 26085, 57, 26085, 49, 48, 26085, 49, 49, 26085, 49, 50, 26085, 49,
- 51, 26085, 49, 52, 26085, 49, 53, 26085, 49, 54, 26085, 49, 55, 26085,
- 49, 56, 26085, 49, 57, 26085, 50, 48, 26085, 50, 49, 26085, 50, 50,
- 26085, 50, 51, 26085, 50, 52, 26085, 50, 53, 26085, 50, 54, 26085,
- 50, 55, 26085, 50, 56, 26085, 50, 57, 26085, 51, 48, 26085, 51, 49,
- 26085, 35912, 26356, 36040, 28369, 20018, 21477, 22865, 21895, 22856,
- 25078, 30313, 32645, 34367, 34746, 35064, 37007, 27138, 27931, 28889,
- 29662, 33853, 37226, 39409, 20098, 21365, 27396, 29211, 34349, 40478,
- 23888, 28651, 34253, 35172, 25289, 33240, 34847, 24266, 26391, 28010,
- 29436, 37070, 20358, 20919, 21214, 25796, 27347, 29200, 30439, 34310,
- 34396, 36335, 38706, 39791, 40442, 30860, 31103, 32160, 33737, 37636,
- 35542, 22751, 24324, 31840, 32894, 29282, 30922, 36034, 38647, 22744,
- 23650, 27155, 28122, 28431, 32047, 32311, 38475, 21202, 32907, 20956,
- 20940, 31260, 32190, 33777, 38517, 35712, 25295, 35582, 20025, 23527,
- 24594, 29575, 30064, 21271, 30971, 20415, 24489, 19981, 27852, 25976,
- 32034, 21443, 22622, 30465, 33865, 35498, 27578, 27784, 25342, 33509,
- 25504, 30053, 20142, 20841, 20937, 26753, 31975, 33391, 35538, 37327,
- 21237, 21570, 24300, 26053, 28670, 31018, 38317, 39530, 40599, 40654,
- 26310, 27511, 36706, 24180, 24976, 25088, 25754, 28451, 29001, 29833,
- 31178, 32244, 32879, 36646, 34030, 36899, 37706, 21015, 21155, 21693,
- 28872, 35010, 24265, 24565, 25467, 27566, 31806, 29557, 20196, 22265,
- 23994, 24604, 29618, 29801, 32666, 32838, 37428, 38646, 38728, 38936,
- 20363, 31150, 37300, 38584, 24801, 20102, 20698, 23534, 23615, 26009,
- 29134, 30274, 34044, 36988, 26248, 38446, 21129, 26491, 26611, 27969,
- 28316, 29705, 30041, 30827, 32016, 39006, 25134, 38520, 20523, 23833,
- 28138, 36650, 24459, 24900, 26647, 38534, 21033, 21519, 23653, 26131,
- 26446, 26792, 27877, 29702, 30178, 32633, 35023, 35041, 38626, 21311,
- 28346, 21533, 29136, 29848, 34298, 38563, 40023, 40607, 26519, 28107,
- 33256, 31520, 31890, 29376, 28825, 35672, 20160, 33590, 21050, 20999,
- 24230, 25299, 31958, 23429, 27934, 26292, 36667, 38477, 24275, 20800,
- 21952, 22618, 26228, 20958, 29482, 30410, 31036, 31070, 31077, 31119,
- 38742, 31934, 34322, 35576, 36920, 37117, 39151, 39164, 39208, 40372,
- 20398, 20711, 20813, 21193, 21220, 21329, 21917, 22022, 22120, 22592,
- 22696, 23652, 24724, 24936, 24974, 25074, 25935, 26082, 26257, 26757,
- 28023, 28186, 28450, 29038, 29227, 29730, 30865, 31049, 31048, 31056,
- 31062, 31117, 31118, 31296, 31361, 31680, 32265, 32321, 32626, 32773,
- 33261, 33401, 33879, 35088, 35222, 35585, 35641, 36051, 36104, 36790,
- 38627, 38911, 38971, 102, 102, 102, 105, 102, 108, 102, 102, 105, 102,
- 102, 108, 115, 116, 1396, 1398, 1396, 1381, 1396, 1387, 1406, 1398,
- 1396, 1389, 1497, 1460, 1522, 1463, 1506, 1492, 1499, 1500, 1501, 1512,
- 1514, 1513, 1473, 1513, 1474, 1513, 1468, 1473, 1513, 1468, 1474, 1488,
- 1463, 1488, 1464, 1488, 1468, 1489, 1468, 1490, 1468, 1491, 1468, 1492,
- 1468, 1493, 1468, 1494, 1468, 1496, 1468, 1497, 1468, 1498, 1468, 1499,
- 1468, 1500, 1468, 1502, 1468, 1504, 1468, 1505, 1468, 1507, 1468, 1508,
- 1468, 1510, 1468, 1511, 1468, 1512, 1468, 1513, 1468, 1514, 1468, 1493,
- 1465, 1489, 1471, 1499, 1471, 1508, 1471, 1488, 1500, 1649, 1659, 1662,
- 1664, 1658, 1663, 1657, 1700, 1702, 1668, 1667, 1670, 1671, 1677, 1676,
- 1678, 1672, 1688, 1681, 1705, 1711, 1715, 1713, 1722, 1723, 1729, 1726,
- 1746, 1709, 1735, 1734, 1736, 1739, 1733, 1737, 1744, 1609, 1610, 1620,
- 1575, 1610, 1620, 1749, 1610, 1620, 1608, 1610, 1620, 1735, 1610, 1620,
- 1734, 1610, 1620, 1736, 1610, 1620, 1744, 1610, 1620, 1609, 1740, 1610,
- 1620, 1580, 1610, 1620, 1581, 1610, 1620, 1605, 1610, 1620, 1610, 1576,
- 1580, 1576, 1581, 1576, 1582, 1576, 1605, 1576, 1609, 1576, 1610, 1578,
- 1580, 1578, 1581, 1578, 1582, 1578, 1605, 1578, 1609, 1578, 1610, 1579,
- 1580, 1579, 1605, 1579, 1609, 1579, 1610, 1580, 1581, 1580, 1605, 1581,
- 1580, 1581, 1605, 1582, 1580, 1582, 1581, 1582, 1605, 1587, 1580, 1587,
- 1581, 1587, 1582, 1587, 1605, 1589, 1581, 1589, 1605, 1590, 1580, 1590,
- 1581, 1590, 1582, 1590, 1605, 1591, 1581, 1591, 1605, 1592, 1605, 1593,
- 1580, 1593, 1605, 1594, 1580, 1594, 1605, 1601, 1580, 1601, 1581, 1601,
- 1582, 1601, 1605, 1601, 1609, 1601, 1610, 1602, 1581, 1602, 1605, 1602,
- 1609, 1602, 1610, 1603, 1575, 1603, 1580, 1603, 1581, 1603, 1582, 1603,
- 1604, 1603, 1605, 1603, 1609, 1603, 1610, 1604, 1580, 1604, 1581, 1604,
- 1582, 1604, 1605, 1604, 1609, 1604, 1610, 1605, 1580, 1605, 1581, 1605,
- 1582, 1605, 1605, 1605, 1609, 1605, 1610, 1606, 1580, 1606, 1581, 1606,
- 1582, 1606, 1605, 1606, 1609, 1606, 1610, 1607, 1580, 1607, 1605, 1607,
- 1609, 1607, 1610, 1610, 1580, 1610, 1581, 1610, 1582, 1610, 1605, 1610,
- 1609, 1610, 1610, 1584, 1648, 1585, 1648, 1609, 1648, 32, 1612, 1617,
- 32, 1613, 1617, 32, 1614, 1617, 32, 1615, 1617, 32, 1616, 1617, 32,
- 1617, 1648, 1610, 1620, 1585, 1610, 1620, 1586, 1610, 1620, 1606, 1576,
- 1585, 1576, 1586, 1576, 1606, 1578, 1585, 1578, 1586, 1578, 1606, 1579,
- 1585, 1579, 1586, 1579, 1606, 1605, 1575, 1606, 1585, 1606, 1586, 1606,
- 1606, 1610, 1585, 1610, 1586, 1610, 1606, 1610, 1620, 1582, 1610, 1620,
- 1607, 1576, 1607, 1578, 1607, 1589, 1582, 1604, 1607, 1606, 1607, 1607,
- 1648, 1610, 1607, 1579, 1607, 1587, 1607, 1588, 1605, 1588, 1607, 1600,
- 1614, 1617, 1600, 1615, 1617, 1600, 1616, 1617, 1591, 1609, 1591, 1610,
- 1593, 1609, 1593, 1610, 1594, 1609, 1594, 1610, 1587, 1609, 1587, 1610,
- 1588, 1609, 1588, 1610, 1581, 1609, 1581, 1610, 1580, 1609, 1580, 1610,
- 1582, 1609, 1582, 1610, 1589, 1609, 1589, 1610, 1590, 1609, 1590, 1610,
- 1588, 1580, 1588, 1581, 1588, 1582, 1588, 1585, 1587, 1585, 1589, 1585,
- 1590, 1585, 1575, 1611, 1578, 1580, 1605, 1578, 1581, 1580, 1578, 1581,
- 1605, 1578, 1582, 1605, 1578, 1605, 1580, 1578, 1605, 1581, 1578, 1605,
- 1582, 1580, 1605, 1581, 1581, 1605, 1610, 1581, 1605, 1609, 1587, 1581,
- 1580, 1587, 1580, 1581, 1587, 1580, 1609, 1587, 1605, 1581, 1587, 1605,
- 1580, 1587, 1605, 1605, 1589, 1581, 1581, 1589, 1605, 1605, 1588, 1581,
- 1605, 1588, 1580, 1610, 1588, 1605, 1582, 1588, 1605, 1605, 1590, 1581,
- 1609, 1590, 1582, 1605, 1591, 1605, 1581, 1591, 1605, 1605, 1591, 1605,
- 1610, 1593, 1580, 1605, 1593, 1605, 1605, 1593, 1605, 1609, 1594, 1605,
- 1605, 1594, 1605, 1610, 1594, 1605, 1609, 1601, 1582, 1605, 1602, 1605,
- 1581, 1602, 1605, 1605, 1604, 1581, 1605, 1604, 1581, 1610, 1604, 1581,
- 1609, 1604, 1580, 1580, 1604, 1582, 1605, 1604, 1605, 1581, 1605, 1581,
- 1580, 1605, 1581, 1605, 1605, 1581, 1610, 1605, 1580, 1581, 1605, 1580,
- 1605, 1605, 1582, 1580, 1605, 1582, 1605, 1605, 1580, 1582, 1607, 1605,
- 1580, 1607, 1605, 1605, 1606, 1581, 1605, 1606, 1581, 1609, 1606, 1580,
- 1605, 1606, 1580, 1609, 1606, 1605, 1610, 1606, 1605, 1609, 1610, 1605,
- 1605, 1576, 1582, 1610, 1578, 1580, 1610, 1578, 1580, 1609, 1578, 1582,
- 1610, 1578, 1582, 1609, 1578, 1605, 1610, 1578, 1605, 1609, 1580, 1605,
- 1610, 1580, 1581, 1609, 1580, 1605, 1609, 1587, 1582, 1609, 1589, 1581,
- 1610, 1588, 1581, 1610, 1590, 1581, 1610, 1604, 1580, 1610, 1604, 1605,
- 1610, 1610, 1581, 1610, 1610, 1580, 1610, 1610, 1605, 1610, 1605, 1605,
- 1610, 1602, 1605, 1610, 1606, 1581, 1610, 1593, 1605, 1610, 1603, 1605,
- 1610, 1606, 1580, 1581, 1605, 1582, 1610, 1604, 1580, 1605, 1603, 1605,
- 1605, 1580, 1581, 1610, 1581, 1580, 1610, 1605, 1580, 1610, 1601, 1605,
- 1610, 1576, 1581, 1610, 1587, 1582, 1610, 1606, 1580, 1610, 1589, 1604,
- 1746, 1602, 1604, 1746, 1575, 1604, 1604, 1607, 1575, 1603, 1576, 1585,
- 1605, 1581, 1605, 1583, 1589, 1604, 1593, 1605, 1585, 1587, 1608, 1604,
- 1593, 1604, 1610, 1607, 1608, 1587, 1604, 1605, 1589, 1604, 1609, 1589,
- 1604, 1609, 32, 1575, 1604, 1604, 1607, 32, 1593, 1604, 1610, 1607,
- 32, 1608, 1587, 1604, 1605, 1580, 1604, 32, 1580, 1604, 1575, 1604,
- 1607, 1585, 1740, 1575, 1604, 8212, 8211, 95, 123, 125, 12308, 12309,
- 12304, 12305, 12298, 12299, 12300, 12301, 12302, 12303, 44, 12289,
- 58, 63, 33, 35, 38, 42, 45, 60, 62, 92, 36, 37, 64, 32, 1611, 1600,
- 1611, 32, 1612, 32, 1613, 32, 1614, 1600, 1614, 32, 1615, 1600, 1615,
- 32, 1616, 1600, 1616, 32, 1617, 1600, 1617, 32, 1618, 1600, 1618, 1569,
- 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586,
- 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1601, 1602, 1603, 1604,
- 1605, 1606, 1607, 1608, 1610, 1604, 1575, 1619, 1604, 1575, 1620, 1604,
- 1575, 1621, 1604, 1575, 34, 39, 47, 91, 93, 94, 124, 126, 10629, 10630,
- 12290, 12539, 12449, 12451, 12453, 12455, 12457, 12515, 12517, 12519,
- 12483, 12540, 12531, 12441, 12442, 162, 163, 172, 166, 165, 8361, 9474,
- 8592, 8593, 8594, 8595, 9632, 9675, 119127, 119141, 119128, 119141,
- 119128, 119141, 119150, 119128, 119141, 119151, 119128, 119141, 119152,
- 119128, 119141, 119153, 119128, 119141, 119154, 119225, 119141, 119226,
- 119141, 119225, 119141, 119150, 119226, 119141, 119150, 119225, 119141,
- 119151, 119226, 119141, 119151, 913, 914, 916, 917, 918, 919, 921,
- 922, 923, 924, 925, 926, 927, 929, 931, 932, 934, 935, 936, 8711, 945,
- 948, 950, 951, 955, 957, 958, 959, 963, 964, 965, 967, 968, 969, 8706,
- 20029, 20024, 20033, 131362, 20320, 20411, 20482, 20602, 20633, 20687,
- 13470, 132666, 20820, 20836, 20855, 132380, 13497, 20839, 20877, 132427,
- 20887, 20900, 20172, 20908, 20917, 168415, 20995, 13535, 21051, 21062,
- 21106, 21111, 13589, 21191, 21242, 21253, 21254, 21321, 21338, 21363,
- 21373, 21375, 133676, 28784, 21450, 21471, 133987, 21483, 21489, 21510,
- 21662, 21560, 21576, 21608, 21666, 21750, 21776, 21843, 21859, 21892,
- 21913, 21931, 21939, 21954, 22294, 22295, 22097, 22132, 22766, 22478,
- 22516, 22541, 22411, 22578, 22577, 22700, 136420, 22770, 22775, 22790,
- 22810, 22818, 22882, 136872, 136938, 23020, 23067, 23079, 23000, 23142,
- 14062, 136042, 23304, 23358, 137672, 23491, 23512, 23539, 138008, 23551,
- 23558, 24371, 14209, 23648, 23744, 23693, 138724, 23875, 138726, 23918,
- 23915, 23932, 24033, 24034, 14383, 24061, 24104, 24125, 24169, 14434,
- 139651, 14460, 24240, 24243, 24246, 172946, 140081, 33281, 24354, 14535,
- 144056, 156122, 24418, 24427, 14563, 24474, 24525, 24535, 24569, 24705,
- 14650, 14620, 141012, 24775, 24904, 24908, 24910, 24954, 25010, 24996,
- 25007, 25054, 25104, 25115, 25181, 25265, 25300, 25424, 142092, 25405,
- 25340, 25448, 25475, 25572, 142321, 25634, 25541, 25513, 14894, 25705,
- 25726, 25757, 25719, 14956, 25964, 143370, 26083, 26360, 26185, 15129,
- 15112, 15076, 20882, 20885, 26368, 26268, 32941, 17369, 26395, 26401,
- 26462, 26451, 144323, 15177, 26618, 26501, 26706, 144493, 26766, 26655,
- 26900, 15261, 26946, 27043, 27114, 27304, 145059, 27355, 15384, 27425,
- 145575, 27476, 15438, 27506, 27551, 27579, 146061, 138507, 146170,
- 27726, 146620, 27839, 27853, 27751, 27926, 27966, 28009, 28024, 28037,
- 146718, 27956, 28207, 28270, 15667, 28363, 28359, 147153, 28153, 28526,
- 147294, 147342, 28614, 28729, 28702, 28699, 15766, 28746, 28797, 28791,
- 28845, 132389, 28997, 148067, 29084, 17323, 29224, 29237, 29264, 149000,
- 29312, 29333, 149301, 149524, 29562, 29579, 16044, 29605, 16056, 29767,
- 29788, 29809, 29829, 29898, 16155, 29988, 150582, 30014, 150674, 139679,
- 30224, 151457, 151480, 151620, 16380, 16392, 30452, 151795, 151794,
- 151833, 151859, 30494, 30495, 30538, 16441, 30603, 16454, 16534, 152605,
- 30798, 30924, 16611, 153126, 153242, 153285, 31211, 16687, 31306, 31311,
- 153980, 154279, 31406, 16898, 154539, 31686, 31689, 16935, 154752,
- 31954, 17056, 31976, 31971, 32000, 155526, 32099, 17153, 32199, 32258,
- 32325, 17204, 156200, 156231, 17241, 156377, 32634, 156478, 32661,
- 32762, 156890, 156963, 32864, 157096, 32880, 144223, 17365, 32946,
- 33027, 17419, 33086, 23221, 157607, 157621, 144275, 144284, 33284,
- 36766, 17515, 33425, 33419, 33437, 21171, 33457, 33459, 33469, 33510,
- 158524, 33565, 33635, 33709, 33571, 33725, 33767, 33619, 33738, 33740,
- 33756, 158774, 159083, 158933, 17707, 34033, 34035, 34070, 160714,
- 34148, 159532, 17757, 17761, 159665, 159954, 17771, 34384, 34407, 34409,
- 34473, 34440, 34574, 34530, 34681, 34600, 34667, 34694, 19799, 34785,
- 34817, 17913, 34912, 161383, 35031, 35038, 17973, 35066, 13499, 161966,
- 162150, 18110, 18119, 35488, 35565, 35722, 162984, 36011, 36033, 36123,
- 36215, 163631, 133124, 36299, 36284, 36336, 133342, 36564, 36664, 165330,
- 165357, 37012, 37105, 37137, 165678, 37147, 37432, 37591, 37592, 37500,
- 37881, 37909, 166906, 38283, 18837, 38327, 167287, 18918, 38595, 23986,
- 38691, 168261, 168474, 19054, 19062, 38880, 168970, 19122, 169110,
- 38923, 38953, 169398, 39138, 19251, 39209, 39335, 39362, 39422, 19406,
- 170800, 39698, 40000, 40189, 19662, 19693, 40295, 172238, 19704, 172293,
- 172558, 172689, 19798, 40702, 40709, 40719, 40726, 173568
-};
-
-
-/*
- * This macro extracts the information about a character from the
- * Unicode character tables.
- */
-
-#define GetUniCharDecompInfo(ch) (decompGroupMap[(decompPageMap[(((int)(ch)) & 0x1fffff) >> DECOMP_OFFSET_BITS] << DECOMP_OFFSET_BITS) | ((ch) & ((1 << DECOMP_OFFSET_BITS)-1))])
-
-#define GetDecompShift(info) ((info) & 0xffff)
-#define GetDecompLen(info) ((info) >> 16)
-
-
-#define COMP_OFFSET_BITS 8
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters. Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char compPageMap[] = {
- 0, 1, 2, 3, 4, 5, 6, 5, 5, 7, 5, 8, 9, 10, 5, 5, 11, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 12, 13, 5, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5
-};
-
-/*
- * The groupMap is indexed by combining the alternate page number with
- * the page offset and returns a group number that identifies a unique
- * set of character attributes.
- */
-
-static int compGroupMap[] = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 65564, 65640, 65738, -1, -1, 30,
- 91, 141, 65, 121, 65701, 38, 94, 1, 65604, 124, 44, 100, 12, 76, 77,
- -1, 48, 105, 17, 84, 136, 54, 113, 23, 24, -1, -1, -1, -1, -1, -1,
- 140, 64, 120, 71, 123, 65573, 99, 10, 75, 129, 47, 104, 16, 15, 83,
- 135, -1, 110, 22, 86, 137, 59, 117, 118, 28, 89, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 102, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1,
- 65713, 65575, 101, 65550, -1, -1, 42, -1, -1, -1, -1, 65576, -1, -1,
- -1, -1, 130, 50, 65678, -1, 65628, -1, -1, -1, 115, -1, -1, -1, -1,
- -1, 32, -1, 65742, 65600, 67, 65704, -1, -1, 5, -1, -1, -1, -1, 65549,
- -1, -1, -1, -1, 107, 20, 65626, -1, 65587, -1, -1, -1, 87, -1, -1,
- -1, -1, -1, 142, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 106, 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 37, 93, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 65624, 65722, -1, -1, -1, -1, 65632, 65730,
- -1, -1, -1, -1, -1, -1, 65597, 65699, 65567, 65649, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65728,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 81, 131,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 119, 33, -1, -1,
- -1, -1, -1, -1, 65546, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 65593, 65696, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65675,
- 65554, 65625, 65724, -1, -1, -1, -1, 65731, 65590, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 65729, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 131073, 131074, 131075, 131077, 131079, -1, 131080, 131082, 131083,
- 131084, 131098, 131102, 131085, -1, -1, 131086, -1, 131087, -1, 131076,
- 131078, -1, -1, -1, -1, -1, -1, 131103, -1, -1, -1, -1, -1, -1, -1,
- 131088, 131104, 131101, 131097, 131092, 131089, -1, -1, -1, -1, 131094,
- 131093, -1, 131090, 131095, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 131091, -1, -1, 131072, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 34, -1, -1, -1, 122, -1, 96, -1, 8, -1, -1, -1, -1, -1, 80,
- -1, 65586, -1, -1, -1, 85, -1, -1, -1, 26, -1, -1, 65539, -1, 65707,
- -1, -1, 2, -1, -1, -1, 95, -1, 7, -1, 125, -1, -1, -1, -1, -1, 51,
- -1, 111, -1, -1, -1, 56, -1, -1, -1, 0, 138, 62, -1, -1, 65664, -1,
- -1, -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 65736, -1, -1, -1, -1, -1, -1, -1, -1, -1, 97, -1, -1,
- 65714, -1, 103, 14, 65622, 132, -1, 65581, -1, -1, -1, 65727, -1, -1,
- -1, -1, 139, -1, -1, -1, 65566, -1, -1, -1, 65706, -1, 65663, -1, -1,
- 72, -1, -1, 65670, -1, 79, 133, 65582, 52, -1, 65556, -1, -1, -1, 65687,
- -1, -1, -1, -1, 63, -1, -1, -1, 65744, -1, -1, -1, 65659, -1, 65595,
- -1, -1, -1, -1, -1, -1, -1, -1, 65658, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 65661, 65545, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 65651, 65542, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 65682, 65559, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 65733, -1, 65657, -1, -1, -1, -1, -1, -1, -1, -1, 196618, 131108, 196619,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 65618, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 65612, -1, -1, 65611, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 65734, -1, -1, -1, -1, -1, -1, -1,
- 65656, -1, -1, 65655, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 196611, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 196612,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 196613, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 196614, 196615, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 65577, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131105, -1, -1,
- -1, -1, -1, -1, -1, 98, 65584, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 131106, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65578,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 65716, -1, -1, 196616, -1, -1, -1, 127, -1, -1, -1, 65630, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 131107, 196617, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131096, -1,
- -1, -1, -1, -1, -1, -1, 19, 65695, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 196610, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 131081, -1, -1, -1, -1, 196608, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 3, -1, -1, 65538, -1, -1, 196609, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65616, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65679,
- 65557, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 65685, 65561, -1, -1, -1, -1, -1, -1, 65743, 65601, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 114, 25, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65673, 65553,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 65540, 65605, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 82, 134, 65591, 65692, 65693, 65565, 65641, 65739, 58,
- 116, 65568, 65652, 65543, 65609, 65610, 65710, 36, 92, -1, -1, -1,
- -1, -1, -1, 9, 73, -1, -1, -1, -1, -1, -1, 53, 108, 65690, 65563, 65639,
- 65737, 65598, 65700, 27, 88, 65541, 65606, 65607, 65709, 65572, 65667,
- 11, 69, -1, -1, -1, -1, -1, -1, 126, 45, -1, -1, -1, -1, -1, -1, 13,
- 78, -1, -1, -1, -1, -1, -1, 55, 112, -1, -1, -1, -1, -1, -1, 29, 90,
- -1, -1, -1, -1, -1, -1, -1, 70, -1, -1, -1, -1, -1, -1, 128, 46, 65683,
- 65560, 65635, 65732, 65592, 65694, 109, 21, 65642, 65740, 65599, 65702,
- 65569, 65653, 65544, -1, -1, -1, 65574, -1, -1, -1, -1, -1, -1, -1,
- 65552, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 65537, -1, -1, -1, -1, -1, -1, -1,
- -1, 40, -1, -1, -1, -1, -1, -1, 65680, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 65570, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 65705, -1, 65660, -1, 65614, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 65698, -1, 65644, -1, 65741, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 65711, -1, -1, -1, -1, 65619, -1, -1, 65676,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 65668, -1, 65548, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65648,
- -1, -1, -1, -1, -1, -1, 65547, -1, 65715, -1, -1, 65551, -1, -1, -1,
- -1, 65681, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 65596, -1, -1, 65647, 65536, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 65721, 65583, -1, -1, 65558, 65631, -1,
- -1, 65688, 65562, 65637, 65735, -1, -1, -1, -1, 65646, 65745, -1, -1,
- 65571, 65662, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65580, 65579, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65602, -1,
- -1, -1, -1, -1, 65613, 65712, -1, 65669, -1, -1, -1, -1, -1, -1, 65555,
- 65629, 65725, 65588, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65718, -1, -1,
- -1, -1, 65708, -1, 65703, -1, 65697, -1, 65686, -1, 65684, -1, 65677,
- -1, 65671, -1, 65665, -1, 65650, -1, 65645, -1, 65638, -1, 65633, -1,
- -1, 65623, -1, 65620, -1, 65615, -1, -1, -1, -1, -1, -1, 60, -1, -1,
- 74, -1, -1, 68, -1, -1, 61, -1, -1, 57, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 131099, 131100, -1, -1, 65717, -1, -1, -1, -1,
- -1, -1, -1, -1, 65691, -1, -1, -1, -1, 65674, -1, 65672, -1, 65666,
- -1, 65654, -1, 65643, -1, 65636, -1, 65634, -1, 65627, -1, 65621, -1,
- 65617, -1, 65608, -1, 65603, -1, -1, 65594, -1, 65589, -1, 65585, -1,
- -1, -1, -1, -1, -1, 41, -1, -1, 31, -1, -1, 49, -1, -1, 43, -1, -1,
- 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 65726, 65723, 65720, 65719, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 65689, -1, -1
-};
-
-/*
- * Lists of compositions for characters that appears only in one composition
- */
-
-static int compFirstList[][2] = {
- {824, 8817}, {837, 8119}, {3530, 3549}, {837, 8116}, {770, 7896},
- {837, 8090}, {776, 1243}, {837, 8076}, {837, 8114}, {783, 1143},
- {780, 494}, {824, 8772}, {824, 8742}, {769, 7727}, {769, 7688},
- {824, 8777}, {837, 8178}, {770, 7879}, {772, 481}, {824, 8938},
- {769, 1116}, {772, 7737}, {824, 8824}, {776, 1259}, {837, 8099},
- {772, 7773}, {824, 8833}, {837, 8083}, {824, 8814}, {837, 8069},
- {776, 1268}, {776, 7802}, {837, 8074}, {837, 8110}, {837, 8183},
- {824, 8840}, {837, 8094}, {775, 7711}, {837, 8130}, {769, 506},
- {769, 7726}, {3031, 2964}, {3158, 3144}, {824, 8931}, {824, 8930},
- {769, 1036}, {776, 1247}, {824, 8821}, {3006, 3019}, {12441, 12489},
- {788, 8172}, {769, 511}, {824, 8941}, {12441, 12487}, {772, 561},
- {837, 8066}, {837, 8102}, {772, 492}, {12441, 12485}, {776, 1261},
- {824, 8802}, {769, 7800}, {837, 8086}, {837, 8108}, {769, 507},
- {775, 7785}, {824, 8876}, {12441, 12482}, {770, 308}, {770, 7897},
- {837, 8091}, {837, 8092}, {12441, 12480}, {837, 8077}, {837, 8078},
- {1620, 1728}, {1620, 1747}, {824, 8877}, {824, 8622}, {12441, 12393},
- {4142, 4134}, {12441, 12478}, {1620, 1730}, {824, 8713},
- {12441, 12391}, {12441, 12476}, {776, 1246}, {12441, 12389},
- {775, 7780}, {774, 7708}, {772, 555}, {12441, 12474}, {769, 510},
- {824, 8939}, {3285, 3275}, {824, 8825}, {775, 7782}, {12441, 12386},
- {12441, 12472}, {837, 8100}, {12441, 12470}, {824, 8928},
- {12441, 12384}, {837, 8084}, {824, 8800}, {837, 8070}, {837, 8106},
- {12441, 12468}, {824, 8655}, {12441, 12382}, {824, 8836},
- {824, 8816}, {824, 8769}, {776, 7803}, {12441, 12380}, {776, 1242},
- {837, 8075}, {837, 8111}, {12441, 12466}, {2364, 2356}, {2364, 2353},
- {1620, 1574}, {776, 1111}, {776, 1273}, {824, 8603}, {783, 1142},
- {824, 8841}, {776, 1260}, {837, 8180}, {12441, 12378}, {12441, 12464},
- {837, 8095}, {824, 8740}, {824, 8879}, {769, 1107}, {12441, 12376},
- {12441, 12462}, {770, 7878}, {12441, 12460}, {772, 480},
- {824, 8716}, {12441, 12374}, {772, 554}, {772, 7736}, {837, 8135},
- {824, 8813}, {776, 1258}, {837, 8098}, {12441, 12372}, {772, 7772},
- {12441, 12370}, {776, 1255}, {824, 8832}, {12441, 12542},
- {837, 8082}, {12441, 12532}, {837, 8067}, {837, 8068}, {837, 8103},
- {3390, 3403}, {772, 493}, {12441, 12368}, {824, 8653}, {769, 7801},
- {837, 8087}, {775, 7710}, {837, 8109}, {12441, 12366}, {769, 7689},
- {824, 8602}, {776, 1272}, {837, 8132}, {12441, 12364}, {837, 8093},
- {837, 8079}, {824, 8708}, {824, 8878}, {772, 478}, {769, 1027},
- {824, 8775}, {3285, 3264}, {12441, 12446}, {12441, 12436},
- {12441, 12538}, {12441, 12537}, {824, 8820}, {775, 7781},
- {12441, 12536}, {774, 7709}, {824, 8940}, {12441, 12535},
- {776, 1254}, {775, 7835}, {780, 495}, {775, 7783}, {772, 560},
- {837, 8101}, {1620, 1572}, {2364, 2345}, {824, 8929}, {776, 1031},
- {837, 8085}, {824, 8815}, {837, 8071}, {837, 8107}, {824, 8654},
- {772, 479}, {775, 7784}, {776, 1269}, {824, 8837}
-};
-
-static int compSecondList[][2] = {
- {3545, 3548}, {3545, 3550}, {3398, 3404}, {2503, 2507}, {2503, 2508},
- {2887, 2891}, {2887, 2888}, {2887, 2892}, {3270, 3274}, {3270, 3272},
- {1575, 1570}, {1575, 1573}
-};
-
-/*
- * Compositions matrix
- */
-
-static int compBothList[144][37] = {
- {
- 8179, 8060, 974, 0, 8032, 0, 8033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 8182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 204, 205, 206, 0, 296, 0, 298, 300, 0, 304, 207, 7880, 463,
- 520, 522, 7882, 302, 7724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0
- },
- {
- 8115, 8048, 940, 0, 7936, 0, 7937, 8113, 8112, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 8118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 3546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8157, 8158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 8159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7873, 7871, 0, 0, 7877, 0, 0, 0, 0, 0, 0, 7875, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7846, 7844, 0, 0, 7850, 0, 0, 0, 0, 0, 0, 7848, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8131, 8052, 942, 0, 7968, 0, 7969, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 8134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8154, 906, 0, 7992, 0, 7993, 8153, 8152, 0, 0, 938, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0
- },
- {
- 0, 7962, 7964, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 293, 0, 0, 0, 0, 0, 0, 7715, 7719, 0, 543, 0, 0, 7717,
- 0, 0, 0, 7721, 7723, 0, 7830, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0
- },
- {
- 0, 7986, 7988, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 7990, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 504, 323, 0, 0, 209, 0, 0, 0, 0, 7748, 0, 0, 327, 0, 0, 7750,
- 0, 0, 0, 325, 0, 7754, 7752, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0
- },
- {
- 0, 8002, 8004, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 1217, 0, 0, 1244, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 505, 324, 0, 0, 241, 0, 0, 0, 0, 7749, 0, 0, 328, 0, 0, 7751,
- 0, 0, 0, 326, 0, 7755, 7753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0
- },
- {
- 0, 0, 7743, 0, 0, 0, 0, 0, 0, 0, 7745, 0, 0, 0, 0, 0, 7747, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7786, 0, 0, 356, 0, 0, 7788, 0, 0,
- 0, 354, 0, 7792, 7790, 0, 538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7701, 7703, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 3402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 7757, 0, 0, 0, 0, 557, 0, 0, 0, 7759, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8105, 8043, 8045, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 8047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 347, 349, 0, 0, 0, 0, 0, 0, 7777, 0, 0, 353, 0, 0, 7779,
- 0, 0, 0, 351, 0, 0, 0, 0, 537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7922, 221, 374, 0, 7928, 0, 562, 0, 0, 7822, 376, 7926, 0, 0,
- 0, 7924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0
- },
- {
- 0, 0, 377, 7824, 0, 0, 0, 0, 0, 0, 379, 0, 0, 381, 0, 0, 7826,
- 0, 0, 0, 0, 0, 0, 7828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 7853, 0, 0, 0, 0, 7863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8188, 8186, 911, 0, 8040, 0, 8041, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8088, 7978, 7980, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 7982, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7923, 253, 375, 0, 7929, 0, 563, 0, 0, 7823, 255, 7927, 0, 0,
- 0, 7925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7833, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0
- },
- {
- 0, 8018, 8020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 8022, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 192, 193, 194, 0, 195, 0, 256, 258, 0, 550, 196, 7842, 461,
- 512, 514, 7840, 260, 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 7680, 0,
- 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 12499, 12500, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7847, 7845, 0, 0, 7851, 0, 0, 0, 0, 0, 0, 7849, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7915, 7913, 0, 0, 7919, 0, 0, 0, 0, 0, 0, 7917, 0, 0, 0, 7921,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8124, 8122, 902, 0, 7944, 0, 7945, 8121, 8120, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 12508, 12509, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7954, 7956, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7760, 7762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 500, 284, 0, 0, 0, 7712, 286, 0, 288, 0, 0, 486, 0, 0, 0,
- 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 979, 0, 0, 0, 0, 0, 0, 0, 0, 980, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8141, 8142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 8143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 12496, 12497, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7872, 7870, 0, 0, 7876, 0, 0, 0, 0, 0, 0, 7874, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 12505, 12506, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 317, 0, 0, 7734, 0, 0,
- 0, 315, 0, 7740, 7738, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7995, 7997, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 7999, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8097, 8035, 8037, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 8039, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 7729, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 489, 0, 0, 7731, 0, 0,
- 0, 311, 0, 0, 7733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 340, 0, 0, 0, 0, 0, 0, 0, 7768, 0, 0, 344, 528, 530, 7770,
- 0, 0, 0, 342, 0, 0, 7774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 12502, 12503, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 7756, 0, 0, 0, 0, 556, 0, 0, 0, 7758, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8056, 972, 0, 8000, 0, 8001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 1117, 0, 0, 0, 0, 0, 1251, 1081, 0, 0, 1253, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8080, 7970, 7972, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 7974, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7808, 7810, 372, 0, 0, 0, 0, 0, 0, 7814, 7812, 0, 0, 0, 0, 7816,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8010, 8012, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8058, 973, 0, 8016, 0, 8017, 8161, 8160, 0, 0, 971, 0, 0, 0,
- 0, 0, 0, 0, 8166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 12412, 12413, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8072, 7946, 7948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 7950, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 7805, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7807, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 12400, 12401, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 12409, 12410, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8162, 944, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8167,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 1263, 1118, 0, 0, 1265, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1267, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7683, 0, 0, 0, 0, 0, 7685, 0, 0,
- 0, 0, 0, 0, 7687, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7690, 0, 0, 270, 0, 0, 7692, 0, 0,
- 0, 7696, 0, 7698, 7694, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7857, 7855, 0, 0, 7861, 0, 0, 0, 0, 0, 0, 7859, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 509, 0, 0, 0, 0, 483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 12406, 12407, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7987, 7989, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 7991, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8027, 8029, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 8031, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7691, 0, 0, 271, 0, 0, 7693, 0, 0,
- 0, 7697, 0, 7699, 7695, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 1233, 0, 0, 1235, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7963, 7965, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 12403, 12404, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 236, 237, 238, 0, 297, 0, 299, 301, 0, 0, 239, 7881, 464, 521,
- 523, 7883, 303, 7725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0
- },
- {
- 0, 210, 211, 212, 0, 213, 0, 332, 334, 0, 558, 214, 7886, 465,
- 524, 526, 7884, 490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 336, 416,
- 0, 0, 0, 0, 0
- },
- {
- 0, 0, 7764, 0, 0, 0, 0, 0, 0, 0, 7766, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8003, 8005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 1104, 0, 0, 0, 0, 0, 0, 1239, 0, 0, 1105, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8184, 908, 0, 8008, 0, 8009, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7900, 7898, 0, 0, 7904, 0, 0, 0, 0, 0, 0, 7902, 0, 0, 0, 7906,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8064, 7938, 7940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 7942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 242, 243, 244, 0, 245, 0, 333, 335, 0, 559, 246, 7887, 466,
- 525, 527, 7885, 491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 337, 417,
- 0, 0, 0, 0, 0
- },
- {
- 0, 217, 218, 219, 0, 360, 0, 362, 364, 0, 0, 220, 7910, 467, 532,
- 534, 7908, 370, 7796, 0, 0, 0, 7798, 0, 0, 0, 366, 0, 0, 0, 368,
- 431, 7794, 0, 0, 0, 0
- },
- {
- 0, 8170, 910, 0, 0, 0, 8025, 8169, 8168, 0, 0, 939, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7787, 7831, 0, 357, 0, 0, 7789, 0,
- 0, 0, 355, 0, 7793, 7791, 0, 539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0
- },
- {
- 0, 476, 472, 0, 0, 0, 0, 470, 0, 0, 0, 0, 0, 474, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8089, 7979, 7981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 7983, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 378, 7825, 0, 0, 0, 0, 0, 0, 380, 0, 0, 382, 0, 0, 7827,
- 0, 0, 0, 0, 0, 0, 7829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8019, 8021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 8023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7682, 0, 0, 0, 0, 0, 7684, 0, 0,
- 0, 0, 0, 0, 7686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7955, 7957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7761, 7763, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 292, 0, 0, 0, 0, 0, 0, 7714, 7718, 0, 542, 0, 0, 7716,
- 0, 0, 0, 7720, 7722, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0
- },
- {
- 0, 8050, 941, 0, 7952, 0, 7953, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8140, 8138, 905, 0, 7976, 0, 7977, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 1232, 0, 0, 1234, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3018, 3020, 0, 0
- },
- {
- 0, 0, 501, 285, 0, 0, 0, 7713, 287, 0, 289, 0, 0, 487, 0, 0, 0,
- 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 7742, 0, 0, 0, 0, 0, 0, 0, 7744, 0, 0, 0, 0, 0, 7746, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 508, 0, 0, 0, 0, 482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8173, 901, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8129,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 1024, 0, 0, 0, 0, 0, 0, 1238, 0, 0, 1025, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318, 0, 0, 7735, 0, 0,
- 0, 316, 0, 7741, 7739, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 346, 348, 0, 0, 0, 0, 0, 0, 7776, 0, 0, 352, 0, 0, 7778,
- 0, 0, 0, 350, 0, 0, 0, 0, 536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7700, 7702, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7891, 7889, 0, 0, 7895, 0, 0, 0, 0, 0, 0, 7893, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8081, 7971, 7973, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 7975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8104, 8042, 8044, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 8046, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 7769, 0, 0, 345, 529, 531, 7771,
- 0, 0, 0, 343, 0, 0, 7775, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-
- },
- {
- 0, 0, 0, 0, 8164, 0, 8165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8011, 8013, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7818, 7820, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 7852, 0, 0, 0, 0, 7862, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 475, 471, 0, 0, 0, 0, 469, 0, 0, 0, 0, 0, 473, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8073, 7947, 7949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 7951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7809, 7811, 373, 0, 0, 0, 0, 0, 0, 7815, 7813, 0, 0, 0, 0, 7817,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 7832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7819, 7821, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7914, 7912, 0, 0, 7918, 0, 0, 0, 0, 0, 0, 7916, 0, 0, 0, 7920,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 263, 265, 0, 0, 0, 0, 0, 0, 267, 0, 0, 269, 0, 0, 0, 0, 0,
- 0, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 200, 201, 202, 0, 7868, 0, 274, 276, 0, 278, 203, 7866, 282,
- 516, 518, 7864, 280, 7706, 0, 552, 0, 7704, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8136, 904, 0, 7960, 0, 7961, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 232, 233, 234, 0, 7869, 0, 275, 277, 0, 279, 235, 7867, 283,
- 517, 519, 7865, 281, 7707, 0, 553, 0, 7705, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 7728, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 488, 0, 0, 7730, 0, 0,
- 0, 310, 0, 0, 7732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 8054, 943, 0, 7984, 0, 7985, 8145, 8144, 0, 0, 970, 0, 0, 0,
- 0, 0, 0, 0, 8150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0
- },
- {
- 0, 7994, 7996, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 7998, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3271, 0
- },
- {
- 8096, 8034, 8036, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 8038, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7890, 7888, 0, 0, 7894, 0, 0, 0, 0, 0, 0, 7892, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7901, 7899, 0, 0, 7905, 0, 0, 0, 0, 0, 0, 7903, 0, 0, 0, 7907,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 1037, 0, 0, 0, 0, 0, 1250, 1049, 0, 0, 1252, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 1218, 0, 0, 1245, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 8065, 7939, 7941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 7943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 7765, 0, 0, 0, 0, 0, 0, 0, 7767, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 7804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7806, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 249, 250, 251, 0, 361, 0, 363, 365, 0, 0, 252, 7911, 468, 533,
- 535, 7909, 371, 7797, 0, 0, 0, 7799, 0, 0, 0, 367, 0, 0, 0, 369,
- 432, 7795, 0, 0, 0, 0
- },
- {
- 0, 8146, 912, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8151,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 1262, 1038, 0, 0, 1264, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1266, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 224, 225, 226, 0, 227, 0, 257, 259, 0, 551, 228, 7843, 462,
- 513, 515, 7841, 261, 0, 0, 0, 0, 0, 0, 0, 0, 229, 0, 0, 7681, 0,
- 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 262, 264, 0, 0, 0, 0, 0, 0, 266, 0, 0, 268, 0, 0, 0, 0, 0,
- 0, 199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 7856, 7854, 0, 0, 7860, 0, 0, 0, 0, 0, 0, 7858, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1571
- },
-};
-
-
-#define GetUniCharCompInfo(ch) (compGroupMap[(compPageMap[(((int)(ch)) & 0x1fffff) >> COMP_OFFSET_BITS] << COMP_OFFSET_BITS) | ((ch) & ((1 << COMP_OFFSET_BITS)-1))])
-
-#define CompSingleMask (1 << 16)
-#define CompMask ((1 << 16) - 1)
-#define CompSecondMask (1 << 17)
-
diff --git a/ejabberd-1.1.2/src/stringprep/uni_parse.tcl b/ejabberd-1.1.2/src/stringprep/uni_parse.tcl
deleted file mode 100644
index 100631b6b..000000000
--- a/ejabberd-1.1.2/src/stringprep/uni_parse.tcl
+++ /dev/null
@@ -1,437 +0,0 @@
-# uni_parse.tcl --
-#
-# This program parses the UnicodeData file and generates the
-# corresponding uni_data.c file with compressed character
-# data tables. The input to this program should be rfc3454.txt
-#
-# Copyright (c) 1998-1999 by Scriptics Corporation.
-# All rights reserved.
-#
-# Modified for ejabberd by Alexey Shchepin
-#
-# RCS: @(#) $Id$
-
-
-namespace eval uni {
- set shift 8; # number of bits of data within a page
- # This value can be adjusted to find the
- # best split to minimize table size
-
- variable pMap; # map from page to page index, each entry is
- # an index into the pages table, indexed by
- # page number
- variable pages; # map from page index to page info, each
- # entry is a list of indices into the groups
- # table, the list is indexed by the offset
- variable groups; # list of character info values, indexed by
- # group number, initialized with the
- # unassigned character group
-}
-
-proc uni::getValue {i} {
- variable casemap
- variable casemap2
- variable tablemap
-
- if {[info exists tablemap($i)]} {
- set tables $tablemap($i)
- } else {
- set tables {}
- }
-
- if {[info exists casemap2($i)]} {
- set multicase 1
- set delta $casemap2($i)
- } else {
- set multicase 0
- if {[info exists casemap($i)]} {
- set delta $casemap($i)
- } else {
- set delta 0
- }
- }
-
- if {abs($delta) > 0xFFFFF} {
- puts "delta must be less than 22 bits wide"
- exit
- }
-
- set ac 0
- set c11 0
- set c21 0
- set b1 0
- set d1 0
- set d2 0
- set xnp 0
-
- foreach tab $tables {
- switch -glob -- $tab {
- C.1.1 {set c11 1}
- C.2.1 {set c21 1}
- C.* {set ac 1}
- A.1 {set ac 1}
- B.1 {set b1 1}
- D.1 {set d1 1}
- D.2 {set d2 1}
- XNP {set xnp 1}
- }
- }
-
- set val [expr {($ac << 0) |
- ($c11 << 1) |
- ($c21 << 2) |
- ($b1 << 3) |
- ($d1 << 4) |
- ($d2 << 5) |
- ($xnp << 6) |
- ($multicase << 7) |
- ($delta << 11)}]
-
- return $val
-}
-
-proc uni::getGroup {value} {
- variable groups
-
- set gIndex [lsearch -exact $groups $value]
- if {$gIndex == -1} {
- set gIndex [llength $groups]
- lappend groups $value
- }
- return $gIndex
-}
-
-proc uni::addPage {info} {
- variable pMap
- variable pages
- variable pages_map
-
- if {[info exists pages_map($info)]} {
- lappend pMap $pages_map($info)
- } else {
- set pIndex [llength $pages]
- lappend pages $info
- set pages_map($info) $pIndex
- lappend pMap $pIndex
- }
- return
-}
-
-
-proc uni::load_tables {data} {
- variable casemap
- variable casemap2
- variable multicasemap
- variable tablemap
-
- set multicasemap {}
- set table ""
-
- foreach line [split $data \n] {
- if {$table == ""} {
- if {[regexp { ----- Start Table (.*) -----} $line temp table]} {
- #puts "Start table '$table'"
- }
- } else {
- if {[regexp { ----- End Table (.*) -----} $line temp table1]} {
- set table ""
- } else {
- if {$table == "B.1"} {
- if {[regexp {^ ([[:xdigit:]]+); ;} $line \
- temp val]} {
- scan $val %x val
- if {$val <= 0x10ffff} {
- lappend tablemap($val) $table
- }
- }
- } elseif {$table == "B.2"} {
- if {[regexp {^ ([[:xdigit:]]+); ([[:xdigit:]]+);} $line \
- temp from to]} {
- scan $from %x from
- scan $to %x to
- if {$from <= 0x10ffff && $to <= 0x10ffff} {
- set casemap($from) [expr {$to - $from}]
- }
- } elseif {[regexp {^ ([[:xdigit:]]+); ([[:xdigit:]]+) ([[:xdigit:]]+);} $line \
- temp from to1 to2]} {
- scan $from %x from
- scan $to1 %x to1
- scan $to2 %x to2
- if {$from <= 0x10ffff && \
- $to1 <= 0x10ffff && $to2 <= 0x10ffff} {
- set casemap2($from) [llength $multicasemap]
- lappend multicasemap [list $to1 $to2]
- }
- } elseif {[regexp {^ ([[:xdigit:]]+); ([[:xdigit:]]+) ([[:xdigit:]]+) ([[:xdigit:]]+);} $line \
- temp from to1 to2 to3]} {
- scan $from %x from
- scan $to1 %x to1
- scan $to2 %x to2
- scan $to3 %x to3
- if {$from <= 0x10ffff && \
- $to1 <= 0x10ffff && $to2 <= 0x10ffff && \
- $to3 <= 0x10ffff} {
- set casemap2($from) [llength $multicasemap]
- lappend multicasemap [list $to1 $to2 $to3]
- }
- } else {
- #puts "missed: $line"
- }
-
- } elseif {$table != "B.3"} {
- if {[regexp {^ ([[:xdigit:]]+)-([[:xdigit:]]+)} $line \
- temp from to]} {
- scan $from %x from
- scan $to %x to
- for {set i $from} {$i <= $to && $i <= 0x10ffff} {incr i} {
- lappend tablemap($i) $table
- }
- } elseif {[regexp {^ ([[:xdigit:]]+)} $line \
- temp val]} {
- scan $val %x val
- if {$val <= 0x10ffff} {
- lappend tablemap($val) $table
- }
- }
- }
- }
- }
- }
-
- # XMPP nodeprep prohibited
- foreach val {22 26 27 2f 3a 3c 3e 40} {
- scan $val %x val
- lappend tablemap($val) XNP
- }
-}
-
-proc uni::buildTables {} {
- variable shift
-
- variable casemap
- variable tablemap
-
- variable pMap {}
- variable pages {}
- variable groups {}
- set info {} ;# temporary page info
-
- set mask [expr {(1 << $shift) - 1}]
-
- set next 0
-
- for {set i 0} {$i <= 0x10ffff} {incr i} {
- set gIndex [getGroup [getValue $i]]
-
- # Split character index into offset and page number
- set offset [expr {$i & $mask}]
- set page [expr {($i >> $shift)}]
-
- # Add the group index to the info for the current page
- lappend info $gIndex
-
- # If this is the last entry in the page, add the page
- if {$offset == $mask} {
- addPage $info
- set info {}
- }
- }
- return
-}
-
-proc uni::main {} {
- global argc argv0 argv
- variable pMap
- variable pages
- variable groups
- variable shift
- variable multicasemap
-
- if {$argc != 2} {
- puts stderr "\nusage: $argv0 <datafile> <outdir>\n"
- exit 1
- }
- set f [open [lindex $argv 0] r]
- set data [read $f]
- close $f
-
- load_tables $data
- buildTables
- puts "X = [llength $pMap] Y= [llength $pages] A= [llength $groups]"
- set size [expr {[llength $pMap] + [llength $pages]*(1<<$shift)}]
- puts "shift = $shift, space = $size"
-
- set f [open [file join [lindex $argv 1] uni_data.c] w]
- fconfigure $f -translation lf
- puts $f "/*
- * uni_data.c --
- *
- * Declarations of Unicode character information tables. This file is
- * automatically generated by the uni_parse.tcl script. Do not
- * modify this file by hand.
- *
- * Copyright (c) 1998 by Scriptics Corporation.
- * All rights reserved.
- *
- * Modified for ejabberd by Alexey Shchepin
- *
- * RCS: @(#) \$Id\$
- */
-
-/*
- * A 16-bit Unicode character is split into two parts in order to index
- * into the following tables. The lower OFFSET_BITS comprise an offset
- * into a page of characters. The upper bits comprise the page number.
- */
-
-#define OFFSET_BITS $shift
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters. Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char pageMap\[\] = {"
- set line " "
- set last [expr {[llength $pMap] - 1}]
- for {set i 0} {$i <= $last} {incr i} {
- append line [lindex $pMap $i]
- if {$i != $last} {
- append line ", "
- }
- if {[string length $line] > 70} {
- puts $f $line
- set line " "
- }
- }
- puts $f $line
- puts $f "};
-
-/*
- * The groupMap is indexed by combining the alternate page number with
- * the page offset and returns a group number that identifies a unique
- * set of character attributes.
- */
-
-static unsigned short int groupMap\[\] = {"
- set line " "
- set lasti [expr {[llength $pages] - 1}]
- for {set i 0} {$i <= $lasti} {incr i} {
- set page [lindex $pages $i]
- set lastj [expr {[llength $page] - 1}]
- for {set j 0} {$j <= $lastj} {incr j} {
- append line [lindex $page $j]
- if {$j != $lastj || $i != $lasti} {
- append line ", "
- }
- if {[string length $line] > 70} {
- puts $f $line
- set line " "
- }
- }
- }
- puts $f $line
- puts $f "};
-
-/*
- * Each group represents a unique set of character attributes. The attributes
- * are encoded into a 32-bit value as follows:
- *
- * Bit 0 A.1 | C.1.2 | C.2.2 | C.3 -- C.9
- *
- * Bit 1 C.1.1
- *
- * Bit 2 C.2.1
- *
- * Bit 3 B.1
- *
- * Bit 4 D.1
- *
- * Bit 5 D.2
- *
- * Bit 6 XNP
- *
- * Bit 7 Case maps to several characters
- *
- * Bits 8-10 Reserved for future use.
- *
- * Bits 11-31 Case delta: delta for case conversions. This should be the
- * highest field so we can easily sign extend.
- */
-
-static int groups\[\] = {"
- set line " "
- set last [expr {[llength $groups] - 1}]
- for {set i 0} {$i <= $last} {incr i} {
- set val [lindex $groups $i]
-
- append line [format "%d" $val]
- if {$i != $last} {
- append line ", "
- }
- if {[string length $line] > 65} {
- puts $f $line
- set line " "
- }
- }
- puts $f $line
- puts $f "};
-
-/*
- * Table for characters that lowercased to multiple ones
- */
-
-static int multiCaseTable\[\]\[4\] = {"
- set last [expr {[llength $multicasemap] - 1}]
- for {set i 0} {$i <= $last} {incr i} {
- set val [lindex $multicasemap $i]
-
- set line " "
- append line [format "{%d, %s}" [llength $val] [join $val ", "]]
- if {$i != $last} {
- append line ", "
- }
- puts $f $line
- }
- puts $f "};
-
-/*
- * The following constants are used to determine the category of a
- * Unicode character.
- */
-
-#define ACMask (1 << 0)
-#define C11Mask (1 << 1)
-#define C21Mask (1 << 2)
-#define B1Mask (1 << 3)
-#define D1Mask (1 << 4)
-#define D2Mask (1 << 5)
-#define XNPMask (1 << 6)
-#define MCMask (1 << 7)
-
-/*
- * The following macros extract the fields of the character info. The
- * GetDelta() macro is complicated because we can't rely on the C compiler
- * to do sign extension on right shifts.
- */
-
-#define GetCaseType(info) (((info) & 0xE0) >> 5)
-#define GetCategory(info) ((info) & 0x1F)
-#define GetDelta(info) (((info) > 0) ? ((info) >> 11) : (~(~((info)) >> 11)))
-#define GetMC(info) (multiCaseTable\[GetDelta(info)\])
-
-/*
- * This macro extracts the information about a character from the
- * Unicode character tables.
- */
-
-#define GetUniCharInfo(ch) (groups\[groupMap\[(pageMap\[(((int)(ch)) & 0x1fffff) >> OFFSET_BITS\] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1))\]\])
-"
-
- close $f
-}
-
-uni::main
-
-return
diff --git a/ejabberd-1.1.2/src/stringprep/uni_parse2.tcl b/ejabberd-1.1.2/src/stringprep/uni_parse2.tcl
deleted file mode 100644
index 950090a09..000000000
--- a/ejabberd-1.1.2/src/stringprep/uni_parse2.tcl
+++ /dev/null
@@ -1,702 +0,0 @@
-# uni_parse2.tcl --
-#
-# This program parses the UnicodeData file and generates the
-# corresponding uni_norm.c file with compressed character
-# data tables. The input to this program should be
-# UnicodeData-3.2.0.txt and CompositionExclusions-3.2.0.txt files from:
-# ftp://ftp.unicode.org/Public/UNIDATA/
-#
-# Copyright (c) 1998-1999 by Scriptics Corporation.
-# All rights reserved.
-#
-# Modified for ejabberd by Alexey Shchepin
-#
-# RCS: @(#) $Id$
-
-
-namespace eval uni {
- set cclass_shift 8
- set decomp_shift 8
- set comp_shift 8
- set shift 5; # number of bits of data within a page
- # This value can be adjusted to find the
- # best split to minimize table size
-
- variable pMap; # map from page to page index, each entry is
- # an index into the pages table, indexed by
- # page number
- variable pages; # map from page index to page info, each
- # entry is a list of indices into the groups
- # table, the list is indexed by the offset
- variable groups; # list of character info values, indexed by
- # group number, initialized with the
- # unassigned character group
-
- variable categories {
- Cn Lu Ll Lt Lm Lo Mn Me Mc Nd Nl No Zs Zl Zp
- Cc Cf Co Cs Pc Pd Ps Pe Pi Pf Po Sm Sc Sk So
- }; # Ordered list of character categories, must
- # match the enumeration in the header file.
-
- variable titleCount 0; # Count of the number of title case
- # characters. This value is used in the
- # regular expression code to allocate enough
- # space for the title case variants.
-}
-
-proc uni::getValue {items index} {
- variable categories
- variable titleCount
-
- # Extract character info
-
- set category [lindex $items 2]
- if {[scan [lindex $items 12] %4x toupper] == 1} {
- set toupper [expr {$index - $toupper}]
- } else {
- set toupper {}
- }
- if {[scan [lindex $items 13] %4x tolower] == 1} {
- set tolower [expr {$tolower - $index}]
- } else {
- set tolower {}
- }
- if {[scan [lindex $items 14] %4x totitle] == 1} {
- set totitle [expr {$index - $totitle}]
- } else {
- set totitle {}
- }
-
- set categoryIndex [lsearch -exact $categories $category]
- if {$categoryIndex < 0} {
- puts "Unexpected character category: $index($category)"
- set categoryIndex 0
- } elseif {$category == "Lt"} {
- incr titleCount
- }
-
- return "$categoryIndex,$toupper,$tolower,$totitle"
-}
-
-proc uni::getGroup {value} {
- variable groups
-
- set gIndex [lsearch -exact $groups $value]
- if {$gIndex == -1} {
- set gIndex [llength $groups]
- lappend groups $value
- }
- return $gIndex
-}
-
-proc uni::addPage {info} {
- variable pMap
- variable pages
-
- set pIndex [lsearch -exact $pages $info]
- if {$pIndex == -1} {
- set pIndex [llength $pages]
- lappend pages $info
- }
- lappend pMap $pIndex
- return
-}
-
-proc uni::addPage {map_var pages_var info} {
- variable $map_var
- variable $pages_var
-
- set pIndex [lsearch -exact [set $pages_var] $info]
- if {$pIndex == -1} {
- set pIndex [llength [set $pages_var]]
- lappend $pages_var $info
- }
- lappend $map_var $pIndex
- return
-}
-
-proc uni::load_exclusions {data} {
- variable exclusions
-
- foreach line [split $data \n] {
- if {$line == ""} continue
-
- set items [split $line " "]
-
- if {[lindex $items 0] == "#"} continue
-
- scan [lindex $items 0] %x index
-
- set exclusions($index) ""
- }
-}
-
-proc uni::load_tables {data} {
- variable cclass_map
- variable decomp_map
- variable comp_map
- variable comp_first
- variable comp_second
- variable exclusions
-
- foreach line [split $data \n] {
- if {$line == ""} continue
-
- set items [split $line \;]
-
- scan [lindex $items 0] %x index
- set cclass [lindex $items 3]
- set decomp [lindex $items 5]
-
- set cclass_map($index) $cclass
- #set decomp_map($index) $cclass
-
- if {$decomp != ""} {
- if {[string index [lindex $decomp 0] 0] == "<"} {
- set decomp1 [lreplace $decomp 0 0]
- set decomp {}
- foreach ch $decomp1 {
- scan $ch %x ch
- lappend decomp $ch
- }
- set decomp_map($index) $decomp
- } else {
- switch -- [llength $decomp] {
- 1 {
- scan $decomp %x ch
- set decomp_map($index) $ch
- }
- 2 {
- scan $decomp "%x %x" ch1 ch2
- set decomp [list $ch1 $ch2]
- set decomp_map($index) $decomp
- # hackish
- if {(![info exists cclass_map($ch1)] || \
- $cclass_map($ch1) == 0) && \
- ![info exists exclusions($index)]} {
- if {[info exists comp_first($ch1)]} {
- incr comp_first($ch1)
- } else {
- set comp_first($ch1) 1
- }
- if {[info exists comp_second($ch2)]} {
- incr comp_second($ch2)
- } else {
- set comp_second($ch2) 1
- }
- set comp_map($decomp) $index
- } else {
- puts "Excluded $index"
- }
- }
- default {
- puts "Bad canonical decomposition: $line"
- }
- }
- }
-
- #puts "[format 0x%0.4x $index]\t$cclass\t$decomp_map($index)"
- }
- }
- #puts [array get comp_first]
- #puts [array get comp_second]
-}
-
-proc uni::buildTables {} {
- variable cclass_shift
- variable decomp_shift
- variable comp_shift
-
- variable cclass_map
- variable cclass_pmap {}
- variable cclass_pages {}
- variable decomp_map
- variable decomp_pmap {}
- variable decomp_pages {}
- variable decomp_list {}
- variable comp_map
- variable comp_pmap {}
- variable comp_pages {}
- variable comp_first
- variable comp_second
- variable comp_first_list {}
- variable comp_second_list {}
- variable comp_x_list {}
- variable comp_y_list {}
- variable comp_both_map {}
-
- set cclass_info {}
- set decomp_info {}
- set comp_info {}
-
- set cclass_mask [expr {(1 << $cclass_shift) - 1}]
- set decomp_mask [expr {(1 << $decomp_shift) - 1}]
- set comp_mask [expr {(1 << $comp_shift) - 1}]
-
- foreach comp [array names comp_map] {
- set ch1 [lindex $comp 0]
- if {[info exists comp_first($ch1)] && $comp_first($ch1) > 0 && \
- [info exists comp_second($ch1)] && $comp_second($ch1) > 0} {
- if {[lsearch -exact $comp_x_list $ch1] < 0} {
- set i [llength $comp_x_list]
- lappend comp_x_list $ch1
- set comp_info_map($ch1) $i
- lappend comp_y_list $ch1
- set comp_info_map($ch1) $i
- puts "There should be no symbols which appears on"
- puts "both first and second place in composition"
- exit
- }
- }
- }
-
- foreach comp [array names comp_map] {
- set ch1 [lindex $comp 0]
- set ch2 [lindex $comp 1]
-
- if {$comp_first($ch1) == 1 && ![info exists comp_second($ch1)]} {
- set i [llength $comp_first_list]
- lappend comp_first_list [list $ch2 $comp_map($comp)]
- set comp_info_map($ch1) [expr {$i | (1 << 16)}]
- } elseif {$comp_second($ch2) == 1 && ![info exists comp_first($ch2)]} {
- set i [llength $comp_second_list]
- lappend comp_second_list [list $ch1 $comp_map($comp)]
- set comp_info_map($ch2) [expr {$i | (1 << 16) | (1 << 17)}]
- } else {
- if {[lsearch -exact $comp_x_list $ch1] < 0} {
- set i [llength $comp_x_list]
- lappend comp_x_list $ch1
- set comp_info_map($ch1) $i
- }
- if {[lsearch -exact $comp_y_list $ch2] < 0} {
- set i [llength $comp_y_list]
- lappend comp_y_list $ch2
- set comp_info_map($ch2) [expr {$i | (1 << 17)}]
- }
- }
- }
-
- set next 0
-
- for {set i 0} {$i <= 0x10ffff} {incr i} {
- #set gIndex [getGroup [getValue $i]]
-
- set cclass_offset [expr {$i & $cclass_mask}]
-
- if {[info exists cclass_map($i)]} {
- set cclass $cclass_map($i)
- } else {
- set cclass 0
- }
- lappend cclass_info $cclass
-
- if {$cclass_offset == $cclass_mask} {
- addPage cclass_pmap cclass_pages $cclass_info
- set cclass_info {}
- }
-
-
- set decomp_offset [expr {$i & $decomp_mask}]
-
- if {[info exists decomp_map($i)]} {
- set decomp $decomp_map($i)
- set b 1
- while {$b} {
- set b 0
- for {set j 0} {$j < [llength $decomp]} {incr j} {
- if {[info exists \
- decomp_map([set ch1 [lindex $decomp $j]])]} {
- #puts -$decomp
- set decomp [eval [list lreplace $decomp $j $j] \
- $decomp_map($ch1)]
- #puts +$decomp
- set b 1
- }
- }
- }
-
- if {[info exists decomp_used($decomp)]} {
- lappend decomp_info $decomp_used($decomp)
- } else {
- set val [expr {([llength $decomp] << 16) + \
- [llength $decomp_list]}]
- #set val [expr {[llength $decomp_list]}]
- lappend decomp_info $val
- set decomp_used($decomp) $val
- #puts "$val $decomp"
- foreach d $decomp {
- lappend decomp_list $d
- }
- }
- } else {
- lappend decomp_info -1
- }
-
- if {$decomp_offset == $decomp_mask} {
- addPage decomp_pmap decomp_pages $decomp_info
- set decomp_info {}
- }
-
-
- set comp_offset [expr {$i & $comp_mask}]
-
- if {[info exists comp_info_map($i)]} {
- set comp $comp_info_map($i)
- } else {
- set comp -1
- }
- lappend comp_info $comp
-
- if {$comp_offset == $comp_mask} {
- addPage comp_pmap comp_pages $comp_info
- set comp_info {}
- }
- }
-
- #puts [array get decomp_map]
- #puts $decomp_list
-
- return
-}
-
-proc uni::main {} {
- global argc argv0 argv
- variable cclass_shift
- variable cclass_pmap
- variable cclass_pages
- variable decomp_shift
- variable decomp_pmap
- variable decomp_pages
- variable decomp_list
- variable comp_shift
- variable comp_map
- variable comp_pmap
- variable comp_pages
- variable comp_first_list
- variable comp_second_list
- variable comp_x_list
- variable comp_y_list
- variable pages
- variable groups {}
- variable titleCount
-
- if {$argc != 3} {
- puts stderr "\nusage: $argv0 <datafile> <exclusionsfile> <outdir>\n"
- exit 1
- }
- set f [open [lindex $argv 1] r]
- set data [read $f]
- close $f
-
- load_exclusions $data
-
- set f [open [lindex $argv 0] r]
- set data [read $f]
- close $f
-
- load_tables $data
- buildTables
- #puts "X = [llength $pMap] Y= [llength $pages] A= [llength $groups]"
- #set size [expr {[llength $pMap] + [llength $pages]*(1<<$shift)}]
- #puts "shift = 6, space = $size"
- #puts "title case count = $titleCount"
-
- set f [open [file join [lindex $argv 2] uni_norm.c] w]
- fconfigure $f -translation lf
- puts $f "/*
- * uni_norm.c --
- *
- * Declarations of Unicode character information tables. This file is
- * automatically generated by the uni_parse2.tcl script. Do not
- * modify this file by hand.
- *
- * Copyright (c) 1998 by Scriptics Corporation.
- * All rights reserved.
- *
- * Modified for ejabberd by Alexey Shchepin
- *
- * RCS: @(#) \$Id\$
- */
-
-/*
- * A 16-bit Unicode character is split into two parts in order to index
- * into the following tables. The lower CCLASS_OFFSET_BITS comprise an offset
- * into a page of characters. The upper bits comprise the page number.
- */
-
-#define CCLASS_OFFSET_BITS $cclass_shift
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters. Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char cclassPageMap\[\] = {"
- set line " "
- set last [expr {[llength $cclass_pmap] - 1}]
- for {set i 0} {$i <= $last} {incr i} {
- append line [lindex $cclass_pmap $i]
- if {$i != $last} {
- append line ", "
- }
- if {[string length $line] > 70} {
- puts $f $line
- set line " "
- }
- }
- puts $f $line
- puts $f "};
-
-/*
- * The cclassGroupMap is indexed by combining the alternate page number with
- * the page offset and returns a combining class number.
- */
-
-static unsigned char cclassGroupMap\[\] = {"
- set line " "
- set lasti [expr {[llength $cclass_pages] - 1}]
- for {set i 0} {$i <= $lasti} {incr i} {
- set page [lindex $cclass_pages $i]
- set lastj [expr {[llength $page] - 1}]
- for {set j 0} {$j <= $lastj} {incr j} {
- append line [lindex $page $j]
- if {$j != $lastj || $i != $lasti} {
- append line ", "
- }
- if {[string length $line] > 70} {
- puts $f $line
- set line " "
- }
- }
- }
- puts $f $line
- puts $f "};
-
-#define GetUniCharCClass(ch) (cclassGroupMap\[(cclassPageMap\[(((int)(ch)) & 0x1fffff) >> CCLASS_OFFSET_BITS\] << CCLASS_OFFSET_BITS) | ((ch) & ((1 << CCLASS_OFFSET_BITS)-1))\])
-
-
-#define DECOMP_OFFSET_BITS $decomp_shift
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters. Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char decompPageMap\[\] = {"
- set line " "
- set last [expr {[llength $decomp_pmap] - 1}]
- for {set i 0} {$i <= $last} {incr i} {
- append line [lindex $decomp_pmap $i]
- if {$i != $last} {
- append line ", "
- }
- if {[string length $line] > 70} {
- puts $f $line
- set line " "
- }
- }
- puts $f $line
- puts $f "};
-
-/*
- * The decompGroupMap is indexed by combining the alternate page number with
- * the page offset and returns a group number that identifies a length and
- * shift of decomposition sequence in decompList
- */
-
-static int decompGroupMap\[\] = {"
- set line " "
- set lasti [expr {[llength $decomp_pages] - 1}]
- for {set i 0} {$i <= $lasti} {incr i} {
- set page [lindex $decomp_pages $i]
- set lastj [expr {[llength $page] - 1}]
- for {set j 0} {$j <= $lastj} {incr j} {
- append line [lindex $page $j]
- if {$j != $lastj || $i != $lasti} {
- append line ", "
- }
- if {[string length $line] > 70} {
- puts $f $line
- set line " "
- }
- }
- }
- puts $f $line
- puts $f "};
-
-/*
- * List of decomposition sequences
- */
-
-static int decompList\[\] = {"
- set line " "
- set last [expr {[llength $decomp_list] - 1}]
- for {set i 0} {$i <= $last} {incr i} {
- set val [lindex $decomp_list $i]
-
- append line [format "%d" $val]
- if {$i != $last} {
- append line ", "
- }
- if {[string length $line] > 70} {
- puts $f $line
- set line " "
- }
- }
- puts $f $line
- puts $f "};
-
-
-/*
- * This macro extracts the information about a character from the
- * Unicode character tables.
- */
-
-#define GetUniCharDecompInfo(ch) (decompGroupMap\[(decompPageMap\[(((int)(ch)) & 0x1fffff) >> DECOMP_OFFSET_BITS\] << DECOMP_OFFSET_BITS) | ((ch) & ((1 << DECOMP_OFFSET_BITS)-1))\])
-
-#define GetDecompShift(info) ((info) & 0xffff)
-#define GetDecompLen(info) ((info) >> 16)
-
-
-#define COMP_OFFSET_BITS $comp_shift
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters. Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char compPageMap\[\] = {"
- set line " "
- set last [expr {[llength $comp_pmap] - 1}]
- for {set i 0} {$i <= $last} {incr i} {
- append line [lindex $comp_pmap $i]
- if {$i != $last} {
- append line ", "
- }
- if {[string length $line] > 70} {
- puts $f $line
- set line " "
- }
- }
- puts $f $line
- puts $f "};
-
-/*
- * The groupMap is indexed by combining the alternate page number with
- * the page offset and returns a group number that identifies a unique
- * set of character attributes.
- */
-
-static int compGroupMap\[\] = {"
- set line " "
- set lasti [expr {[llength $comp_pages] - 1}]
- for {set i 0} {$i <= $lasti} {incr i} {
- set page [lindex $comp_pages $i]
- set lastj [expr {[llength $page] - 1}]
- for {set j 0} {$j <= $lastj} {incr j} {
- append line [lindex $page $j]
- if {$j != $lastj || $i != $lasti} {
- append line ", "
- }
- if {[string length $line] > 70} {
- puts $f $line
- set line " "
- }
- }
- }
- puts $f $line
- puts $f "};
-
-/*
- * Lists of compositions for characters that appears only in one composition
- */
-
-static int compFirstList\[\]\[2\] = {"
- set line " "
- set last [expr {[llength $comp_first_list] - 1}]
- for {set i 0} {$i <= $last} {incr i} {
- set val [lindex $comp_first_list $i]
-
- append line [format "{%d, %d}" [lindex $val 0] [lindex $val 1]]
- if {$i != $last} {
- append line ", "
- }
- if {[string length $line] > 60} {
- puts $f $line
- set line " "
- }
- }
- puts $f $line
- puts $f "};
-
-static int compSecondList\[\]\[2\] = {"
- set line " "
- set last [expr {[llength $comp_second_list] - 1}]
- for {set i 0} {$i <= $last} {incr i} {
- set val [lindex $comp_second_list $i]
-
- append line [format "{%d, %d}" [lindex $val 0] [lindex $val 1]]
- if {$i != $last} {
- append line ", "
- }
- if {[string length $line] > 60} {
- puts $f $line
- set line " "
- }
- }
- puts $f $line
- puts $f "};
-
-/*
- * Compositions matrix
- */
-
-static int compBothList\[[llength $comp_x_list]\]\[[llength $comp_y_list]\] = {"
- set lastx [expr {[llength $comp_x_list] - 1}]
- set lasty [expr {[llength $comp_y_list] - 1}]
- for {set i 0} {$i <= $lastx} {incr i} {
- puts $f " \{"
- set line " "
- for {set j 0} {$j <= $lasty} {incr j} {
- set comp [list [lindex $comp_x_list $i] [lindex $comp_y_list $j]]
- if {[info exists comp_map($comp)]} {
- set val $comp_map($comp)
- } else {
- set val 0
- }
-
- append line [format "%d" $val]
- if {$j != $lasty} {
- append line ", "
- }
- if {[string length $line] > 70} {
- puts $f $line
- set line " "
- }
- }
- puts $f $line
- if {$j != $lasty} {
- puts $f " \},"
- } else {
- puts $f " \}"
- }
- }
- puts $f "};
-
-
-#define GetUniCharCompInfo(ch) (compGroupMap\[(compPageMap\[(((int)(ch)) & 0x1fffff) >> COMP_OFFSET_BITS\] << COMP_OFFSET_BITS) | ((ch) & ((1 << COMP_OFFSET_BITS)-1))\])
-
-#define CompSingleMask (1 << 16)
-#define CompMask ((1 << 16) - 1)
-#define CompSecondMask (1 << 17)
-"
-
- close $f
-}
-
-uni::main
-
-return
diff --git a/ejabberd-1.1.2/src/tls/Makefile.in b/ejabberd-1.1.2/src/tls/Makefile.in
deleted file mode 100644
index 4b32fd84d..000000000
--- a/ejabberd-1.1.2/src/tls/Makefile.in
+++ /dev/null
@@ -1,45 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@ @SSL_CFLAGS@ @ERLANG_CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@ @SSL_LIBS@ @ERLANG_LIBS@
-
-ifeq ($(shell uname),Darwin)
-DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
-else
-# Assume Linux-style dynamic library flags
-DYNAMIC_LIB_CFLAGS = -fpic -shared
-endif
-
-SUBDIRS =
-
-ERLSHLIBS = ../tls_drv.so
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-OBJS = \
- $(OUTDIR)/tls.beam
-
-all: $(OBJS) $(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) -Wall $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \
- $(subst ../,,$(subst .so,.c,$@)) $(LIBS) \
- -o $@ -fpic $(DYNAMIC_LIB_CFLAGS)
-
-clean:
- rm -f $(OBJS) $(ERLSHLIBS)
-
-distclean: clean
- rm -f Makefile
-
-TAGS:
- etags *.erl
diff --git a/ejabberd-1.1.2/src/tls/Makefile.win32 b/ejabberd-1.1.2/src/tls/Makefile.win32
deleted file mode 100644
index 414c1c06f..000000000
--- a/ejabberd-1.1.2/src/tls/Makefile.win32
+++ /dev/null
@@ -1,37 +0,0 @@
-
-include ..\Makefile.inc
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-
-OBJS = \
- $(OUTDIR)\tls.beam
-
-SOURCE = tls_drv.c
-OBJECT = tls_drv.o
-DLL = $(OUTDIR)\tls_drv.dll
-
-ALL : $(DLL) $(OBJS)
-
-CLEAN :
- -@erase $(DLL)
- -@erase $(OUTDIR)\tls_drv.exp
- -@erase $(OUTDIR)\tls_drv.lib
- -@erase $(OBJECT)
- -@erase $(OBJS)
-
-$(OUTDIR)\tls.beam : tls.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) tls.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"$(OPENSSL_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" "$(OPENSSL_DIR)\lib\VC\ssleay32.lib" "$(OPENSSL_DIR)\lib\VC\libeay32.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/ejabberd-1.1.2/src/tls/tls.erl b/ejabberd-1.1.2/src/tls/tls.erl
deleted file mode 100644
index 7c7d07bad..000000000
--- a/ejabberd-1.1.2/src/tls/tls.erl
+++ /dev/null
@@ -1,261 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : tls.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Interface to openssl
-%%% Created : 24 Jul 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(tls).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_server).
-
--export([start/0, start_link/0,
- tcp_to_tls/2, tls_to_tcp/1,
- send/2,
- recv/2, recv/3, recv_data/2,
- setopts/2,
- controlling_process/2,
- close/1,
- get_peer_certificate/1,
- get_verify_result/1,
- test/0]).
-
-%% Internal exports, call-back functions.
--export([init/1,
- handle_call/3,
- handle_cast/2,
- handle_info/2,
- code_change/3,
- terminate/2]).
-
--define(SET_CERTIFICATE_FILE_ACCEPT, 1).
--define(SET_CERTIFICATE_FILE_CONNECT, 2).
--define(SET_ENCRYPTED_INPUT, 3).
--define(SET_DECRYPTED_OUTPUT, 4).
--define(GET_ENCRYPTED_OUTPUT, 5).
--define(GET_DECRYPTED_INPUT, 6).
--define(GET_PEER_CERTIFICATE, 7).
--define(GET_VERIFY_RESULT, 8).
-
--record(tlssock, {tcpsock, tlsport}).
-
-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(), tls_drv) of
- ok -> ok;
- {error, already_loaded} -> ok
- end,
- Port = open_port({spawn, tls_drv}, [binary]),
- Res = port_control(Port, ?SET_CERTIFICATE_FILE_ACCEPT, "./ssl.pem" ++ [0]),
- case Res of
- <<0>> ->
- %ets:new(iconv_table, [set, public, named_table]),
- %ets:insert(iconv_table, {port, Port}),
- {ok, Port};
- <<1, Error/binary>> ->
- {error, binary_to_list(Error)}
- end.
-
-
-%%% --------------------------------------------------------
-%%% 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.
-
-
-tcp_to_tls(TCPSocket, Options) ->
- case lists:keysearch(certfile, 1, Options) of
- {value, {certfile, CertFile}} ->
- case erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv) of
- ok -> ok;
- {error, already_loaded} -> ok
- end,
- Port = open_port({spawn, tls_drv}, [binary]),
- Command = case lists:member(connect, Options) of
- true ->
- ?SET_CERTIFICATE_FILE_CONNECT;
- false ->
- ?SET_CERTIFICATE_FILE_ACCEPT
- end,
- case port_control(Port, Command, CertFile ++ [0]) of
- <<0>> ->
- {ok, #tlssock{tcpsock = TCPSocket, tlsport = Port}};
- <<1, Error/binary>> ->
- {error, binary_to_list(Error)}
- end;
- false ->
- {error, no_certfile}
- end.
-
-tls_to_tcp(#tlssock{tcpsock = TCPSocket, tlsport = Port}) ->
- port_close(Port),
- TCPSocket.
-
-recv(Socket, Length) ->
- recv(Socket, Length, infinity).
-recv(#tlssock{tcpsock = TCPSocket} = TLSSock,
- Length, Timeout) ->
- case gen_tcp:recv(TCPSocket, Length, Timeout) of
- {ok, Packet} ->
- recv_data(TLSSock, Packet);
- {error, _Reason} = Error ->
- Error
- end.
-
-recv_data(#tlssock{tcpsock = TCPSocket, tlsport = Port}, Packet) ->
- case port_control(Port, ?SET_ENCRYPTED_INPUT, Packet) of
- <<0>> ->
- case port_control(Port, ?GET_DECRYPTED_INPUT, []) of
- <<0, In/binary>> ->
- case port_control(Port, ?GET_ENCRYPTED_OUTPUT, []) of
- <<0, Out/binary>> ->
- case gen_tcp:send(TCPSocket, Out) of
- ok ->
- %io:format("IN: ~p~n", [{TCPSocket, binary_to_list(In)}]),
- {ok, In};
- Error ->
- Error
- end;
- <<1, Error/binary>> ->
- {error, binary_to_list(Error)}
- end;
- <<1, Error/binary>> ->
- {error, binary_to_list(Error)}
- end;
- <<1, Error/binary>> ->
- {error, binary_to_list(Error)}
- end.
-
-send(#tlssock{tcpsock = TCPSocket, tlsport = Port}, Packet) ->
- case port_control(Port, ?SET_DECRYPTED_OUTPUT, Packet) of
- <<0>> ->
- %io:format("OUT: ~p~n", [{TCPSocket, lists:flatten(Packet)}]),
- case port_control(Port, ?GET_ENCRYPTED_OUTPUT, []) of
- <<0, Out/binary>> ->
- gen_tcp:send(TCPSocket, Out);
- <<1, Error/binary>> ->
- {error, binary_to_list(Error)}
- end;
- <<1, Error/binary>> ->
- {error, binary_to_list(Error)};
- <<2>> -> % Dirty hack
- receive
- {timeout, _Timer, _} ->
- {error, timeout}
- after 100 ->
- send(#tlssock{tcpsock = TCPSocket, tlsport = Port}, Packet)
- end
- end.
-
-
-setopts(#tlssock{tcpsock = TCPSocket}, Opts) ->
- inet:setopts(TCPSocket, Opts).
-
-controlling_process(#tlssock{tcpsock = TCPSocket}, Pid) ->
- gen_tcp:controlling_process(TCPSocket, Pid).
-
-close(#tlssock{tcpsock = TCPSocket, tlsport = Port}) ->
- gen_tcp:close(TCPSocket),
- port_close(Port).
-
-get_peer_certificate(#tlssock{tlsport = Port}) ->
- case port_control(Port, ?GET_PEER_CERTIFICATE, []) of
- <<0, BCert/binary>> ->
- case catch ssl_pkix:decode_cert(BCert, [pkix]) of
- {ok, Cert} ->
- {ok, Cert};
- _ ->
- error
- end;
- <<1>> ->
- error
- end.
-
-get_verify_result(#tlssock{tlsport = Port}) ->
- <<Res>> = port_control(Port, ?GET_VERIFY_RESULT, []),
- Res.
-
-
-test() ->
- case erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv) of
- ok -> ok;
- {error, already_loaded} -> ok
- end,
- Port = open_port({spawn, tls_drv}, [binary]),
- io:format("open_port: ~p~n", [Port]),
- PCRes = port_control(Port, ?SET_CERTIFICATE_FILE_ACCEPT,
- "./ssl.pem" ++ [0]),
- io:format("port_control: ~p~n", [PCRes]),
- {ok, ListenSocket} = gen_tcp:listen(1234, [binary,
- {packet, 0},
- {active, true},
- {reuseaddr, true},
- {nodelay, true}]),
- io:format("listen: ~p~n", [ListenSocket]),
- {ok, Socket} = gen_tcp:accept(ListenSocket),
- io:format("accept: ~p~n", [Socket]),
- loop(Port, Socket).
-
-
-loop(Port, Socket) ->
- receive
- {tcp, Socket, Data} ->
- %io:format("read: ~p~n", [Data]),
- Res = port_control(Port, ?SET_ENCRYPTED_INPUT, Data),
- io:format("SET_ENCRYPTED_INPUT: ~p~n", [Res]),
-
- DIRes = port_control(Port, ?GET_DECRYPTED_INPUT, Data),
- io:format("GET_DECRYPTED_INPUT: ~p~n", [DIRes]),
- case DIRes of
- <<0, In/binary>> ->
- io:format("input: ~s~n", [binary_to_list(In)]);
- <<1, DIError/binary>> ->
- io:format("GET_DECRYPTED_INPUT error: ~p~n", [binary_to_list(DIError)])
- end,
-
- EORes = port_control(Port, ?GET_ENCRYPTED_OUTPUT, Data),
- io:format("GET_ENCRYPTED_OUTPUT: ~p~n", [EORes]),
- case EORes of
- <<0, Out/binary>> ->
- gen_tcp:send(Socket, Out);
- <<1, EOError/binary>> ->
- io:format("GET_ENCRYPTED_OUTPUT error: ~p~n", [binary_to_list(EOError)])
- end,
-
-
- loop(Port, Socket);
- Msg ->
- io:format("receive: ~p~n", [Msg]),
- loop(Port, Socket)
- end.
-
-
diff --git a/ejabberd-1.1.2/src/tls/tls_drv.c b/ejabberd-1.1.2/src/tls/tls_drv.c
deleted file mode 100644
index 5d3530360..000000000
--- a/ejabberd-1.1.2/src/tls/tls_drv.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* $Id$ */
-
-#include <stdio.h>
-#include <string.h>
-#include <erl_driver.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-
-
-#define BUF_SIZE 1024
-
-typedef struct {
- ErlDrvPort port;
- SSL_CTX *ctx;
- BIO *bio_read;
- BIO *bio_write;
- SSL *ssl;
-} tls_data;
-
-
-static ErlDrvData tls_drv_start(ErlDrvPort port, char *buff)
-{
- tls_data *d = (tls_data *)driver_alloc(sizeof(tls_data));
- d->port = port;
- d->ctx = NULL;
- d->bio_read = NULL;
- d->bio_write = NULL;
- d->ssl = NULL;
-
- set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
-
- return (ErlDrvData)d;
-}
-
-static void tls_drv_stop(ErlDrvData handle)
-{
- tls_data *d = (tls_data *)handle;
-
- if (d->ssl != NULL)
- SSL_free(d->ssl);
-
- if (d->ctx != NULL)
- SSL_CTX_free(d->ctx);
-
- driver_free((char *)handle);
-}
-
-
-static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
-{
- return 1;
-}
-
-#define SET_CERTIFICATE_FILE_ACCEPT 1
-#define SET_CERTIFICATE_FILE_CONNECT 2
-#define SET_ENCRYPTED_INPUT 3
-#define SET_DECRYPTED_OUTPUT 4
-#define GET_ENCRYPTED_OUTPUT 5
-#define GET_DECRYPTED_INPUT 6
-#define GET_PEER_CERTIFICATE 7
-#define GET_VERIFY_RESULT 8
-
-
-#define die_unless(cond, errstr) \
- if (!(cond)) \
- { \
- int errstrlen = strlen(errstr); \
- unsigned long error_code = ERR_get_error(); \
- char *error_string = error_code ? \
- ERR_error_string(error_code, NULL) : \
- NULL; \
- int error_string_length = error_string ? \
- strlen(error_string) : 0; \
- if (error_code) \
- rlen = errstrlen + error_string_length + 3; \
- else \
- rlen = errstrlen + 1; \
- b = driver_alloc_binary(rlen); \
- b->orig_bytes[0] = 1; \
- strncpy(b->orig_bytes + 1, errstr, errstrlen); \
- if (error_code) { \
- strncpy(b->orig_bytes + 1 + errstrlen, \
- ": ", 2); \
- strncpy(b->orig_bytes + 3 + errstrlen, \
- error_string, error_string_length); \
- } \
- *rbuf = (char *)b; \
- return rlen; \
- }
-
-
-static int tls_drv_control(ErlDrvData handle,
- unsigned int command,
- char *buf, int len,
- char **rbuf, int rlen)
-{
- tls_data *d = (tls_data *)handle;
- int res;
- int size;
- ErlDrvBinary *b;
- X509 *cert;
-
- ERR_clear_error();
- switch (command)
- {
- case SET_CERTIFICATE_FILE_ACCEPT:
- case SET_CERTIFICATE_FILE_CONNECT:
- d->ctx = SSL_CTX_new(SSLv23_method());
- die_unless(d->ctx, "SSL_CTX_new failed");
-
- res = SSL_CTX_use_certificate_file(d->ctx, buf, SSL_FILETYPE_PEM);
- die_unless(res > 0, "SSL_CTX_use_certificate_file failed");
-
- res = SSL_CTX_use_PrivateKey_file(d->ctx, buf, SSL_FILETYPE_PEM);
- die_unless(res > 0, "SSL_CTX_use_PrivateKey_file failed");
-
- res = SSL_CTX_check_private_key(d->ctx);
- die_unless(res > 0, "SSL_CTX_check_private_key failed");
-
- SSL_CTX_set_default_verify_paths(d->ctx);
-
- if (command == SET_CERTIFICATE_FILE_ACCEPT)
- {
- SSL_CTX_set_verify(d->ctx,
- SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
- verify_callback);
- }
-
- d->ssl = SSL_new(d->ctx);
- die_unless(d->ssl, "SSL_new failed");
-
- d->bio_read = BIO_new(BIO_s_mem());
- d->bio_write = BIO_new(BIO_s_mem());
-
- SSL_set_bio(d->ssl, d->bio_read, d->bio_write);
-
- if (command == SET_CERTIFICATE_FILE_ACCEPT)
- SSL_set_accept_state(d->ssl);
- else
- SSL_set_connect_state(d->ssl);
- break;
- case SET_ENCRYPTED_INPUT:
- die_unless(d->ssl, "SSL not initialized");
- BIO_write(d->bio_read, buf, len);
- break;
- case SET_DECRYPTED_OUTPUT:
- die_unless(d->ssl, "SSL not initialized");
- res = SSL_write(d->ssl, buf, len);
- if (res <= 0)
- {
- res = SSL_get_error(d->ssl, res);
- if (res == SSL_ERROR_WANT_READ || res == SSL_ERROR_WANT_WRITE)
- {
- b = driver_alloc_binary(1);
- b->orig_bytes[0] = 2;
- *rbuf = (char *)b;
- return 1;
- } else {
- die_unless(0, "SSL_write failed");
- }
- }
- break;
- case GET_ENCRYPTED_OUTPUT:
- die_unless(d->ssl, "SSL not initialized");
- size = BUF_SIZE + 1;
- rlen = 1;
- b = driver_alloc_binary(size);
- b->orig_bytes[0] = 0;
- while ((res = BIO_read(d->bio_write,
- b->orig_bytes + rlen, BUF_SIZE)) > 0)
- {
- //printf("%d bytes of encrypted data read from state machine\r\n", res);
-
- rlen += res;
- size += BUF_SIZE;
- b = driver_realloc_binary(b, size);
- }
- b = driver_realloc_binary(b, rlen);
- *rbuf = (char *)b;
- return rlen;
- case GET_DECRYPTED_INPUT:
- if (!SSL_is_init_finished(d->ssl))
- {
- res = SSL_do_handshake(d->ssl);
- if (res <= 0)
- die_unless(SSL_get_error(d->ssl, res) == SSL_ERROR_WANT_READ,
- "SSL_do_handshake failed");
- } else {
- size = BUF_SIZE + 1;
- rlen = 1;
- b = driver_alloc_binary(size);
- b->orig_bytes[0] = 0;
-
- while ((res = SSL_read(d->ssl,
- b->orig_bytes + rlen, BUF_SIZE)) > 0)
- {
- //printf("%d bytes of decrypted data read from state machine\r\n",res);
- rlen += res;
- size += BUF_SIZE;
- b = driver_realloc_binary(b, size);
- }
-
- if (res < 0)
- {
- int err = SSL_get_error(d->ssl, res);
-
- if (err == SSL_ERROR_WANT_READ)
- {
- //printf("SSL_read wants more data\r\n");
- //return 0;
- }
- // TODO
- }
- b = driver_realloc_binary(b, rlen);
- *rbuf = (char *)b;
- return rlen;
- }
- break;
- case GET_PEER_CERTIFICATE:
- cert = SSL_get_peer_certificate(d->ssl);
- if (cert == NULL)
- {
- b = driver_alloc_binary(1);
- b->orig_bytes[0] = 1;
- *rbuf = (char *)b;
- return 1;
- } else {
- unsigned char *tmp_buf;
- rlen = i2d_X509(cert, NULL);
- if (rlen >= 0)
- {
- rlen++;
- b = driver_alloc_binary(rlen);
- b->orig_bytes[0] = 0;
- tmp_buf = &b->orig_bytes[1];
- i2d_X509(cert, &tmp_buf);
- X509_free(cert);
- *rbuf = (char *)b;
- return rlen;
- } else
- X509_free(cert);
- }
- break;
- case GET_VERIFY_RESULT:
- b = driver_alloc_binary(1);
- b->orig_bytes[0] = SSL_get_verify_result(d->ssl);
- *rbuf = (char *)b;
- return 1;
- break;
- }
-
- b = driver_alloc_binary(1);
- b->orig_bytes[0] = 0;
- *rbuf = (char *)b;
- return 1;
-}
-
-
-ErlDrvEntry tls_driver_entry = {
- NULL, /* F_PTR init, N/A */
- tls_drv_start, /* L_PTR start, called when port is opened */
- tls_drv_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 */
- "tls_drv", /* char *driver_name, the argument to open_port */
- NULL, /* F_PTR finish, called when unloaded */
- NULL, /* handle */
- tls_drv_control, /* F_PTR control, port_command callback */
- NULL, /* F_PTR timeout, reserved */
- NULL /* F_PTR outputv, reserved */
-};
-
-DRIVER_INIT(tls_drv) /* must match name in driver_entry */
-{
- OpenSSL_add_ssl_algorithms();
- SSL_load_error_strings();
- return &tls_driver_entry;
-}
-
-
diff --git a/ejabberd-1.1.2/src/translate.erl b/ejabberd-1.1.2/src/translate.erl
deleted file mode 100644
index a6cc8c146..000000000
--- a/ejabberd-1.1.2/src/translate.erl
+++ /dev/null
@@ -1,145 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : translate.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 6 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(translate).
--author('alexey@sevcom.net').
-
--export([start/0,
- load_dir/1,
- load_file/2,
- translate/2]).
-
--include("ejabberd.hrl").
-
-start() ->
- ets:new(translations, [named_table, public]),
- Dir =
- case os:getenv("EJABBERD_MSGS_PATH") of
- false ->
- case code:priv_dir(ejabberd) of
- {error, _} ->
- ?MSGS_DIR;
- Path ->
- filename:join([Path, "msgs"])
- end;
- Path ->
- Path
- end,
- load_dir(Dir),
- ok.
-
-load_dir(Dir) ->
- case file:list_dir(Dir) of
- {ok, Files} ->
- MsgFiles = lists:filter(
- fun(FN) ->
- case string:len(FN) > 4 of
- true ->
- string:substr(
- FN,
- string:len(FN) - 3) == ".msg";
- _ ->
- false
- end
- end, Files),
- lists:foreach(
- fun(FN) ->
- L = ascii_tolower(
- string:substr(FN, 1, string:len(FN) - 4)),
- load_file(L, Dir ++ "/" ++ FN)
- end, MsgFiles),
- ok;
- {error, Reason} ->
- ?ERROR_MSG("~p", [Reason])
- end.
-
-load_file(Lang, File) ->
- case file:consult(File) of
- {ok, Terms} ->
- lists:foreach(fun({Orig, Trans}) ->
- Trans1 = case Trans of
- "" ->
- Orig;
- _ ->
- Trans
- end,
- ets:insert(translations,
- {{Lang, Orig}, Trans1})
- end, Terms);
- {error, Reason} ->
- exit(file:format_error(Reason))
- end.
-
-translate(Lang, Msg) ->
- LLang = ascii_tolower(Lang),
- case ets:lookup(translations, {LLang, Msg}) of
- [{_, Trans}] ->
- Trans;
- _ ->
- ShortLang = case string:tokens(LLang, "-") of
- [] ->
- LLang;
- [SL | _] ->
- SL
- end,
- case ShortLang of
- "en" ->
- Msg;
- LLang ->
- translate(Msg);
- _ ->
- case ets:lookup(translations, {ShortLang, Msg}) of
- [{_, Trans}] ->
- Trans;
- _ ->
- translate(Msg)
- end
- end
- end.
-
-translate(Msg) ->
- case ?MYLANG of
- undefined ->
- Msg;
- "en" ->
- Msg;
- Lang ->
- LLang = ascii_tolower(Lang),
- case ets:lookup(translations, {LLang, Msg}) of
- [{_, Trans}] ->
- Trans;
- _ ->
- ShortLang = case string:tokens(LLang, "-") of
- [] ->
- LLang;
- [SL | _] ->
- SL
- end,
- case ShortLang of
- "en" ->
- Msg;
- Lang ->
- Msg;
- _ ->
- case ets:lookup(translations, {ShortLang, Msg}) of
- [{_, Trans}] ->
- Trans;
- _ ->
- Msg
- end
- end
- end
- end.
-
-ascii_tolower([C | Cs]) when C >= $A, C =< $Z ->
- [C + ($a - $A) | ascii_tolower(Cs)];
-ascii_tolower([C | Cs]) ->
- [C | ascii_tolower(Cs)];
-ascii_tolower([]) ->
- [].
-
diff --git a/ejabberd-1.1.2/src/web/Makefile.in b/ejabberd-1.1.2/src/web/Makefile.in
deleted file mode 100644
index 2656504e8..000000000
--- a/ejabberd-1.1.2/src/web/Makefile.in
+++ /dev/null
@@ -1,34 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@ @ERLANG_CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@ @ERLANG_LIBS@
-
-SUBDIRS =
-
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-OBJS = \
- $(OUTDIR)/ejabberd_http.beam \
- $(OUTDIR)/ejabberd_web.beam \
- $(OUTDIR)/ejabberd_web_admin.beam \
- $(OUTDIR)/ejabberd_http_poll.beam
-
-all: $(OBJS)
-
-$(OUTDIR)/%.beam: %.erl ejabberd_http.hrl
- @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-
-clean:
- rm -f $(OBJS)
-
-distclean: clean
- rm -f Makefile
-
-TAGS:
- etags *.erl
-
diff --git a/ejabberd-1.1.2/src/web/Makefile.win32 b/ejabberd-1.1.2/src/web/Makefile.win32
deleted file mode 100644
index 70d2e7cd7..000000000
--- a/ejabberd-1.1.2/src/web/Makefile.win32
+++ /dev/null
@@ -1,28 +0,0 @@
-
-include ..\Makefile.inc
-
-OUTDIR = ..
-EFLAGS = -I .. -pz ..
-
-OBJS = \
- $(OUTDIR)\ejabberd_http.beam \
- $(OUTDIR)\ejabberd_web.beam \
- $(OUTDIR)\ejabberd_web_admin.beam \
- $(OUTDIR)\ejabberd_http_poll.beam
-
-ALL : $(OBJS)
-
-CLEAN :
- -@erase $(OBJS)
-
-$(OUTDIR)\ejabberd_http.beam : ejabberd_http.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_http.erl
-
-$(OUTDIR)\ejabberd_web.beam : ejabberd_web.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_web.erl
-
-$(OUTDIR)\ejabberd_web_admin.beam : ejabberd_web_admin.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_web_admin.erl
-
-$(OUTDIR)\ejabberd_http_poll.beam : ejabberd_http_poll.erl
- erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_http_poll.erl
diff --git a/ejabberd-1.1.2/src/web/ejabberd_http.erl b/ejabberd-1.1.2/src/web/ejabberd_http.erl
deleted file mode 100644
index 5113f1afe..000000000
--- a/ejabberd-1.1.2/src/web/ejabberd_http.erl
+++ /dev/null
@@ -1,882 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_http.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 27 Feb 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_http).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
-%% External exports
--export([start/2,
- start_link/2,
- become_controller/1,
- receive_headers/1,
- url_encode/1]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include("ejabberd_http.hrl").
-
--record(state, {sockmod,
- socket,
- request_method,
- request_version,
- request_path,
- request_auth,
- request_keepalive,
- request_content_length,
- request_lang = "en",
- use_http_poll = false,
- use_web_admin = false,
- end_of_request = false,
- trail = ""
- }).
-
-
--define(XHTML_DOCTYPE,
- "<?xml version='1.0'?>\n"
- "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
- "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n").
-
--define(HTML_DOCTYPE,
- "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
- "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n").
-
-
-start(SockData, Opts) ->
- supervisor:start_child(ejabberd_http_sup, [SockData, Opts]).
-
-start_link({SockMod, Socket}, Opts) ->
- TLSEnabled = lists:member(tls, Opts),
- TLSOpts = lists:filter(fun({certfile, _}) -> true;
- (_) -> false
- end, Opts),
- {SockMod1, Socket1} =
- if
- TLSEnabled ->
- inet:setopts(Socket, [{recbuf, 8192}]),
- {ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
- {tls, TLSSocket};
- true ->
- {SockMod, Socket}
- end,
- case SockMod1 of
- gen_tcp ->
- inet:setopts(Socket1, [{packet, http}, {recbuf, 8192}]);
- _ ->
- ok
- end,
- UseHTTPPoll = lists:member(http_poll, Opts),
- UseWebAdmin = lists:member(web_admin, Opts),
- ?DEBUG("S: ~p~n", [{UseHTTPPoll, UseWebAdmin}]),
- ?INFO_MSG("started: ~p", [{SockMod1, Socket1}]),
- {ok, proc_lib:spawn_link(ejabberd_http,
- receive_headers,
- [#state{sockmod = SockMod1,
- socket = Socket1,
- use_http_poll = UseHTTPPoll,
- use_web_admin = UseWebAdmin}])}.
-
-
-become_controller(_Pid) ->
- ok.
-
-send_text(State, Text) ->
- (State#state.sockmod):send(State#state.socket, Text).
-
-
-receive_headers(State) ->
- SockMod = State#state.sockmod,
- Socket = State#state.socket,
- Data = SockMod:recv(Socket, 0, 300000),
- case State#state.sockmod of
- gen_tcp ->
- NewState = process_header(State, Data),
- case NewState#state.end_of_request of
- true ->
- ok;
- _ ->
- receive_headers(NewState)
- end;
- _ ->
- case Data of
- {ok, Binary} ->
- {Request, Trail} = parse_request(
- State,
- State#state.trail ++ binary_to_list(Binary)),
- State1 = State#state{trail = Trail},
- NewState = lists:foldl(
- fun(D, S) ->
- case S#state.end_of_request of
- true ->
- S;
- _ ->
- process_header(S, D)
- end
- end, State1, Request),
- case NewState#state.end_of_request of
- true ->
- ok;
- _ ->
- receive_headers(NewState)
- end;
- _ ->
- ok
- end
- end.
-
-process_header(State, Data) ->
- SockMod = State#state.sockmod,
- Socket = State#state.socket,
- case Data of
- {ok, {http_request, Method, Uri, Version}} ->
- KeepAlive = case Version of
- {1, 1} ->
- true;
- _ ->
- false
- end,
- Path = case Uri of
- {absoluteURI, _Scheme, _Host, _Port, P} -> {abs_path, P};
- _ -> Uri
- end,
- State#state{request_method = Method,
- request_version = Version,
- request_path = Path,
- request_keepalive = KeepAlive};
- {ok, {http_header, _, 'Connection', _, Conn}} ->
- KeepAlive1 = case jlib:tolower(Conn) of
- "keep-alive" ->
- true;
- "close" ->
- false;
- _ ->
- State#state.request_keepalive
- end,
- State#state{request_keepalive = KeepAlive1};
- {ok, {http_header, _, 'Authorization', _, Auth}} ->
- State#state{request_auth = parse_auth(Auth)};
- {ok, {http_header, _, 'Content-Length', _, SLen}} ->
- case catch list_to_integer(SLen) of
- Len when is_integer(Len) ->
- State#state{request_content_length = Len};
- _ ->
- State
- end;
- {ok, {http_header, _, 'Accept-Language', _, Langs}} ->
- State#state{request_lang = parse_lang(Langs)};
- {ok, {http_header, _, _, _, _}} ->
- State;
- {ok, http_eoh} ->
- ?INFO_MSG("(~w) http query: ~w ~s~n",
- [State#state.socket,
- State#state.request_method,
- element(2, State#state.request_path)]),
- Out = process_request(State),
- send_text(State, Out),
- case State#state.request_keepalive of
- true ->
- case SockMod of
- gen_tcp ->
- inet:setopts(Socket, [{packet, http}]);
- _ ->
- ok
- end,
- #state{sockmod = SockMod,
- socket = Socket,
- use_http_poll = State#state.use_http_poll,
- use_web_admin = State#state.use_web_admin};
- _ ->
- #state{end_of_request = true}
- end;
- {error, _Reason} ->
- #state{end_of_request = true};
- _ ->
- #state{end_of_request = true}
- end.
-
-process_request(#state{request_method = 'GET',
- request_path = {abs_path, Path},
- request_auth = Auth,
- request_lang = Lang,
- use_http_poll = UseHTTPPoll,
- use_web_admin = UseWebAdmin} = State) ->
- case (catch url_decode_q_split(Path)) of
- {'EXIT', _} ->
- process_request(false);
- {NPath, Query} ->
- LQuery = case (catch parse_urlencoded(Query)) of
- {'EXIT', _Reason} ->
- [];
- LQ ->
- LQ
- end,
- LPath = string:tokens(NPath, "/"),
- Request = #request{method = 'GET',
- path = LPath,
- q = LQuery,
- auth = Auth,
- lang = Lang},
- case ejabberd_web:process_get({UseHTTPPoll, UseWebAdmin},
- Request) of
- El when element(1, El) == xmlelement ->
- make_xhtml_output(State, 200, [], El);
- {Status, Headers, El} when
- element(1, El) == xmlelement ->
- make_xhtml_output(State, Status, Headers, El);
- Text when is_list(Text) ->
- make_text_output(State, 200, [], Text);
- {Status, Headers, Text} when
- is_list(Text) ->
- make_text_output(State, Status, Headers, Text)
- end
- end;
-
-process_request(#state{request_method = 'POST',
- request_path = {abs_path, Path},
- request_auth = Auth,
- request_content_length = Len,
- request_lang = Lang,
- sockmod = SockMod,
- socket = Socket,
- use_http_poll = UseHTTPPoll,
- use_web_admin = UseWebAdmin} = State)
- when is_integer(Len) ->
- case SockMod of
- gen_tcp ->
- inet:setopts(Socket, [{packet, 0}]);
- _ ->
- ok
- end,
- Data = recv_data(State, Len),
- ?DEBUG("client data: ~p~n", [Data]),
- case (catch url_decode_q_split(Path)) of
- {'EXIT', _} ->
- process_request(false);
- {NPath, Query} ->
- LPath = string:tokens(NPath, "/"),
- LQuery = case (catch parse_urlencoded(Data)) of
- {'EXIT', _Reason} ->
- [];
- LQ ->
- LQ
- end,
- Request = #request{method = 'POST',
- path = LPath,
- q = LQuery,
- auth = Auth,
- data = Data,
- lang = Lang},
- case ejabberd_web:process_get({UseHTTPPoll, UseWebAdmin},
- Request) of
- El when element(1, El) == xmlelement ->
- make_xhtml_output(State, 200, [], El);
- {Status, Headers, El} when
- element(1, El) == xmlelement ->
- make_xhtml_output(State, Status, Headers, El);
- Text when is_list(Text) ->
- make_text_output(State, 200, [], Text);
- {Status, Headers, Text} when is_list(Text) ->
- make_text_output(State, Status, Headers, Text)
- end
- end;
-
-process_request(State) ->
- make_xhtml_output(State,
- 400,
- [],
- ejabberd_web:make_xhtml([{xmlelement, "h1", [],
- [{xmlcdata, "400 Bad Request"}]}])).
-
-
-recv_data(State, Len) ->
- recv_data(State, Len, []).
-
-recv_data(State, 0, Acc) ->
- binary_to_list(list_to_binary(Acc));
-recv_data(State, Len, Acc) ->
- case State#state.trail of
- [] ->
- case (State#state.sockmod):recv(State#state.socket, Len, 300000) of
- {ok, Data} ->
- recv_data(State, Len - size(Data), [Acc | Data]);
- _ ->
- ""
- end;
- _ ->
- Trail = State#state.trail,
- recv_data(State#state{trail = ""}, Len - length(Trail), [Acc | Trail])
- end.
-
-
-make_xhtml_output(State, Status, Headers, XHTML) ->
- Data = case lists:member(html, Headers) of
- true ->
- list_to_binary([?HTML_DOCTYPE,
- xml:element_to_string(XHTML)]);
- _ ->
- list_to_binary([?XHTML_DOCTYPE,
- xml:element_to_string(XHTML)])
- end,
- Headers1 = case lists:keysearch("Content-Type", 1, Headers) of
- {value, _} ->
- [{"Content-Length", integer_to_list(size(Data))} |
- Headers];
- _ ->
- [{"Content-Type", "text/html; charset=utf-8"},
- {"Content-Length", integer_to_list(size(Data))} |
- Headers]
- end,
- HeadersOut = case {State#state.request_version,
- State#state.request_keepalive} of
- {{1, 1}, true} -> Headers1;
- {_, true} ->
- [{"Connection", "keep-alive"} | Headers1];
- {_, false} ->
- % not required for http versions < 1.1
- % but would make no harm
- [{"Connection", "close"} | Headers1]
- end,
-
- Version = case State#state.request_version of
- {1, 1} -> "HTTP/1.1 ";
- _ -> "HTTP/1.0 "
- end,
-
- H = lists:map(fun({Attr, Val}) ->
- [Attr, ": ", Val, "\r\n"];
- (_) ->
- []
- end, HeadersOut),
- SL = [Version, integer_to_list(Status), " ",
- code_to_phrase(Status), "\r\n"],
- [SL, H, "\r\n", Data].
-
-make_text_output(State, Status, Headers, Text) ->
- Data = list_to_binary(Text),
- Headers1 = case lists:keysearch("Content-Type", 1, Headers) of
- {value, _} ->
- [{"Content-Length", integer_to_list(size(Data))} |
- Headers];
- _ ->
- [{"Content-Type", "text/html; charset=utf-8"},
- {"Content-Length", integer_to_list(size(Data))} |
- Headers]
- end,
-
- HeadersOut = case {State#state.request_version,
- State#state.request_keepalive} of
- {{1, 1}, true} -> Headers1;
- {_, true} ->
- [{"Connection", "keep-alive"} | Headers1];
- {_, false} ->
- % not required for http versions < 1.1
- % but would make no harm
- [{"Connection", "close"} | Headers1]
- end,
-
- Version = case State#state.request_version of
- {1, 1} -> "HTTP/1.1 ";
- _ -> "HTTP/1.0 "
- end,
-
- H = lists:map(fun({Attr, Val}) ->
- [Attr, ": ", Val, "\r\n"]
- end, HeadersOut),
- SL = [Version, integer_to_list(Status), " ",
- code_to_phrase(Status), "\r\n"],
- [SL, H, "\r\n", Data].
-
-
-parse_lang(Langs) ->
- case string:tokens(Langs, ",; ") of
- [First | _] ->
- First;
- [] ->
- "en"
- end.
-
-
-
-% Code below is taken (with some modifications) from the yaws webserver, which
-% is distributed under the folowing license:
-%
-% This software (the yaws webserver) is free software.
-% Parts of this software is Copyright (c) Claes Wikstrom <klacke@hyber.org>
-% Any use or misuse of the source code is hereby freely allowed.
-%
-% 1. Redistributions of source code must retain the above copyright
-% notice as well as this list of conditions.
-%
-% 2. Redistributions in binary form must reproduce the above copyright
-% notice as well as this list of conditions.
-
-
-%% url decode the path and return {Path, QueryPart}
-
-url_decode_q_split(Path) ->
- url_decode_q_split(Path, []).
-
-url_decode_q_split([$%, $C, $2, $%, Hi, Lo | Tail], Ack) ->
- Hex = hex_to_integer([Hi, Lo]),
- url_decode_q_split(Tail, [Hex|Ack]);
-url_decode_q_split([$%, $C, $3, $%, Hi, Lo | Tail], Ack) when Hi > $9 ->
- Hex = hex_to_integer([Hi+4, Lo]),
- url_decode_q_split(Tail, [Hex|Ack]);
-url_decode_q_split([$%, $C, $3, $%, Hi, Lo | Tail], Ack) when Hi < $A ->
- Hex = hex_to_integer([Hi+4+7, Lo]),
- url_decode_q_split(Tail, [Hex|Ack]);
-url_decode_q_split([$%, Hi, Lo | Tail], Ack) ->
- Hex = hex_to_integer([Hi, Lo]),
- url_decode_q_split(Tail, [Hex|Ack]);
-url_decode_q_split([$?|T], Ack) ->
- %% Don't decode the query string here, that is parsed separately.
- {path_norm_reverse(Ack), T};
-url_decode_q_split([H|T], Ack) ->
- url_decode_q_split(T, [H|Ack]);
-url_decode_q_split([], Ack) ->
- {path_norm_reverse(Ack), []}.
-
-path_norm_reverse("/" ++ T) -> start_dir(0, "/", T);
-path_norm_reverse( T) -> start_dir(0, "", T).
-
-start_dir(N, Path, ".." ) -> rest_dir(N, Path, "");
-start_dir(N, Path, "/" ++ T ) -> start_dir(N , Path, T);
-start_dir(N, Path, "./" ++ T ) -> start_dir(N , Path, T);
-start_dir(N, Path, "../" ++ T ) -> start_dir(N + 1, Path, T);
-start_dir(N, Path, T ) -> rest_dir (N , Path, T).
-
-rest_dir (_N, Path, [] ) -> case Path of
- [] -> "/";
- _ -> Path
- end;
-rest_dir (0, Path, [ $/ | T ] ) -> start_dir(0 , [ $/ | Path ], T);
-rest_dir (N, Path, [ $/ | T ] ) -> start_dir(N - 1, Path , T);
-rest_dir (0, Path, [ H | T ] ) -> rest_dir (0 , [ H | Path ], T);
-rest_dir (N, Path, [ _H | T ] ) -> rest_dir (N , Path , T).
-
-
-%% hex_to_integer
-
-
-hex_to_integer(Hex) ->
- case catch erlang:list_to_integer(Hex, 16) of
- {'EXIT', _} ->
- old_hex_to_integer(Hex);
- X ->
- X
- end.
-
-
-old_hex_to_integer(Hex) ->
- DEHEX = fun (H) when H >= $a, H =< $f -> H - $a + 10;
- (H) when H >= $A, H =< $F -> H - $A + 10;
- (H) when H >= $0, H =< $9 -> H - $0
- end,
- lists:foldl(fun(E, Acc) -> Acc*16+DEHEX(E) end, 0, Hex).
-
-code_to_phrase(100) -> "Continue";
-code_to_phrase(101) -> "Switching Protocols ";
-code_to_phrase(200) -> "OK";
-code_to_phrase(201) -> "Created";
-code_to_phrase(202) -> "Accepted";
-code_to_phrase(203) -> "Non-Authoritative Information";
-code_to_phrase(204) -> "No Content";
-code_to_phrase(205) -> "Reset Content";
-code_to_phrase(206) -> "Partial Content";
-code_to_phrase(300) -> "Multiple Choices";
-code_to_phrase(301) -> "Moved Permanently";
-code_to_phrase(302) -> "Found";
-code_to_phrase(303) -> "See Other";
-code_to_phrase(304) -> "Not Modified";
-code_to_phrase(305) -> "Use Proxy";
-code_to_phrase(306) -> "(Unused)";
-code_to_phrase(307) -> "Temporary Redirect";
-code_to_phrase(400) -> "Bad Request";
-code_to_phrase(401) -> "Unauthorized";
-code_to_phrase(402) -> "Payment Required";
-code_to_phrase(403) -> "Forbidden";
-code_to_phrase(404) -> "Not Found";
-code_to_phrase(405) -> "Method Not Allowed";
-code_to_phrase(406) -> "Not Acceptable";
-code_to_phrase(407) -> "Proxy Authentication Required";
-code_to_phrase(408) -> "Request Timeout";
-code_to_phrase(409) -> "Conflict";
-code_to_phrase(410) -> "Gone";
-code_to_phrase(411) -> "Length Required";
-code_to_phrase(412) -> "Precondition Failed";
-code_to_phrase(413) -> "Request Entity Too Large";
-code_to_phrase(414) -> "Request-URI Too Long";
-code_to_phrase(415) -> "Unsupported Media Type";
-code_to_phrase(416) -> "Requested Range Not Satisfiable";
-code_to_phrase(417) -> "Expectation Failed";
-code_to_phrase(500) -> "Internal Server Error";
-code_to_phrase(501) -> "Not Implemented";
-code_to_phrase(502) -> "Bad Gateway";
-code_to_phrase(503) -> "Service Unavailable";
-code_to_phrase(504) -> "Gateway Timeout";
-code_to_phrase(505) -> "HTTP Version Not Supported".
-
-
-parse_auth(Orig = "Basic " ++ Auth64) ->
- case decode_base64(Auth64) of
- {error, _Err} ->
- undefined;
- Auth ->
- case string:tokens(Auth, ":") of
- [User, Pass] ->
- {User, Pass};
- _ ->
- undefined
- end
- end;
-parse_auth(_) ->
- undefined.
-
-
-
-decode_base64([]) ->
- [];
-decode_base64([Sextet1,Sextet2,$=,$=|Rest]) ->
- Bits2x6=
- (d(Sextet1) bsl 18) bor
- (d(Sextet2) bsl 12),
- Octet1=Bits2x6 bsr 16,
- [Octet1|decode_base64(Rest)];
-decode_base64([Sextet1,Sextet2,Sextet3,$=|Rest]) ->
- Bits3x6=
- (d(Sextet1) bsl 18) bor
- (d(Sextet2) bsl 12) bor
- (d(Sextet3) bsl 6),
- Octet1=Bits3x6 bsr 16,
- Octet2=(Bits3x6 bsr 8) band 16#ff,
- [Octet1,Octet2|decode_base64(Rest)];
-decode_base64([Sextet1,Sextet2,Sextet3,Sextet4|Rest]) ->
- Bits4x6=
- (d(Sextet1) bsl 18) bor
- (d(Sextet2) bsl 12) bor
- (d(Sextet3) bsl 6) bor
- d(Sextet4),
- Octet1=Bits4x6 bsr 16,
- Octet2=(Bits4x6 bsr 8) band 16#ff,
- Octet3=Bits4x6 band 16#ff,
- [Octet1,Octet2,Octet3|decode_base64(Rest)];
-decode_base64(_CatchAll) ->
- {error, bad_base64}.
-
-d(X) when X >= $A, X =<$Z ->
- X-65;
-d(X) when X >= $a, X =<$z ->
- X-71;
-d(X) when X >= $0, X =<$9 ->
- X+4;
-d($+) -> 62;
-d($/) -> 63;
-d(_) -> 63.
-
-
-parse_urlencoded(S) ->
- parse_urlencoded(S, nokey, [], key).
-
-parse_urlencoded([$%, Hi, Lo | Tail], Last, Cur, State) ->
- Hex = hex_to_integer([Hi, Lo]),
- parse_urlencoded(Tail, Last, [Hex | Cur], State);
-
-parse_urlencoded([$& | Tail], _Last, Cur, key) ->
- [{lists:reverse(Cur), ""} |
- parse_urlencoded(Tail, nokey, [], key)]; %% cont keymode
-
-parse_urlencoded([$& | Tail], Last, Cur, value) ->
- V = {Last, lists:reverse(Cur)},
- [V | parse_urlencoded(Tail, nokey, [], key)];
-
-parse_urlencoded([$+ | Tail], Last, Cur, State) ->
- parse_urlencoded(Tail, Last, [$\s | Cur], State);
-
-parse_urlencoded([$= | Tail], _Last, Cur, key) ->
- parse_urlencoded(Tail, lists:reverse(Cur), [], value); %% change mode
-
-parse_urlencoded([H | Tail], Last, Cur, State) ->
- parse_urlencoded(Tail, Last, [H|Cur], State);
-
-parse_urlencoded([], Last, Cur, _State) ->
- [{Last, lists:reverse(Cur)}];
-
-parse_urlencoded(undefined, _, _, _) ->
- [].
-
-
-url_encode([H|T]) ->
- if
- H >= $a, $z >= H ->
- [H|url_encode(T)];
- H >= $A, $Z >= H ->
- [H|url_encode(T)];
- H >= $0, $9 >= H ->
- [H|url_encode(T)];
- H == $_; H == $.; H == $-; H == $/; H == $: -> % FIXME: more..
- [H|url_encode(T)];
- true ->
- case integer_to_hex(H) of
- [X, Y] ->
- [$%, X, Y | url_encode(T)];
- [X] ->
- [$%, $0, X | url_encode(T)]
- end
- end;
-
-url_encode([]) ->
- [].
-
-integer_to_hex(I) ->
- case catch erlang:integer_to_list(I, 16) of
- {'EXIT', _} ->
- old_integer_to_hex(I);
- Int ->
- Int
- end.
-
-
-old_integer_to_hex(I) when I<10 ->
- integer_to_list(I);
-old_integer_to_hex(I) when I<16 ->
- [I-10+$A];
-old_integer_to_hex(I) when I>=16 ->
- N = trunc(I/16),
- old_integer_to_hex(N) ++ old_integer_to_hex(I rem 16).
-
-
-% The following code is mostly taken from yaws_ssl.erl
-
-parse_request(State, Data) ->
- case Data of
- [] ->
- {[], []};
- _ ->
- ?DEBUG("GOT ssl data ~p~n", [Data]),
- {R, Trail} = case State#state.request_method of
- undefined ->
- {R1, Trail1} = get_req(Data),
- ?DEBUG("Parsed request ~p~n", [R1]),
- {[R1], Trail1};
- _ ->
- {[], Data}
- end,
- {H, Trail2} = get_headers(Trail),
- {R ++ H, Trail2}
- end.
-
-get_req("\r\n\r\n" ++ _) ->
- bad_request;
-get_req("\r\n" ++ Data) ->
- get_req(Data);
-get_req(Data) ->
- {FirstLine, Trail} = lists:splitwith(fun not_eol/1, Data),
- R = parse_req(FirstLine),
- {R, Trail}.
-
-
-not_eol($\r)->
- false;
-not_eol($\n) ->
- false;
-not_eol(_) ->
- true.
-
-
-get_word(Line)->
- {Word, T} = lists:splitwith(fun(X)-> X /= $\ end, Line),
- {Word, lists:dropwhile(fun(X) -> X == $\ end, T)}.
-
-
-parse_req(Line) ->
- {MethodStr, L1} = get_word(Line),
- ?DEBUG("Method: ~p~n", [MethodStr]),
- case L1 of
- [] ->
- bad_request;
- _ ->
- {URI, L2} = get_word(L1),
- {VersionStr, L3} = get_word(L2),
- ?DEBUG("URI: ~p~nVersion: ~p~nL3: ~p~n",
- [URI, VersionStr, L3]),
- case L3 of
- [] ->
- Method = case MethodStr of
- "GET" -> 'GET';
- "POST" -> 'POST';
- "HEAD" -> 'HEAD';
- "OPTIONS" -> 'OPTIONS';
- "TRACE" -> 'TRACE';
- "PUT" -> 'PUT';
- "DELETE" -> 'DELETE';
- S -> S
- end,
- Path = case URI of
- "*" ->
- % Is this correct?
- "*";
- _ ->
- case string:str(URI, "://") of
- 0 ->
- % Relative URI
- % ex: /index.html
- {abs_path, URI};
- N ->
- % Absolute URI
- % ex: http://localhost/index.html
-
- % Remove scheme
- % ex: URI2 = localhost/index.html
- URI2 = string:substr(URI, N + 3),
- % Look for the start of the path
- % (or the lack of a path thereof)
- case string:chr(URI2, $/) of
- 0 -> {abs_path, "/"};
- M -> {abs_path,
- string:substr(URI2, M + 1)}
- end
- end
- end,
- case VersionStr of
- [] ->
- {ok, {http_request, Method, Path, {0,9}}};
- "HTTP/1.0" ->
- {ok, {http_request, Method, Path, {1,0}}};
- "HTTP/1.1" ->
- {ok, {http_request, Method, Path, {1,1}}};
- _ ->
- bad_request
- end;
- _ ->
- bad_request
- end
- end.
-
-
-get_headers(Tail) ->
- get_headers([], Tail).
-
-get_headers(H, Tail) ->
- case get_line(Tail) of
- {incomplete, Tail2} ->
- {H, Tail2};
- {line, Line, Tail2} ->
- get_headers(H ++ parse_line(Line), Tail2);
- {lastline, Line, Tail2} ->
- {H ++ parse_line(Line) ++ [{ok, http_eoh}], Tail2}
- end.
-
-
-parse_line("Connection:" ++ Con) ->
- [{ok, {http_header, undefined, 'Connection', undefined, strip_spaces(Con)}}];
-parse_line("Host:" ++ Con) ->
- [{ok, {http_header, undefined, 'Host', undefined, strip_spaces(Con)}}];
-parse_line("Accept:" ++ Con) ->
- [{ok, {http_header, undefined, 'Accept', undefined, strip_spaces(Con)}}];
-parse_line("If-Modified-Since:" ++ Con) ->
- [{ok, {http_header, undefined, 'If-Modified-Since', undefined, strip_spaces(Con)}}];
-parse_line("If-Match:" ++ Con) ->
- [{ok, {http_header, undefined, 'If-Match', undefined, strip_spaces(Con)}}];
-parse_line("If-None-Match:" ++ Con) ->
- [{ok, {http_header, undefined, 'If-None-Match', undefined, strip_spaces(Con)}}];
-parse_line("If-Range:" ++ Con) ->
- [{ok, {http_header, undefined, 'If-Range', undefined, strip_spaces(Con)}}];
-parse_line("If-Unmodified-Since:" ++ Con) ->
- [{ok, {http_header, undefined, 'If-Unmodified-Since', undefined, strip_spaces(Con)}}];
-parse_line("Range:" ++ Con) ->
- [{ok, {http_header, undefined, 'Range', undefined, strip_spaces(Con)}}];
-parse_line("User-Agent:" ++ Con) ->
- [{ok, {http_header, undefined, 'User-Agent', undefined, strip_spaces(Con)}}];
-parse_line("Accept-Ranges:" ++ Con) ->
- [{ok, {http_header, undefined, 'Accept-Ranges', undefined, strip_spaces(Con)}}];
-parse_line("Authorization:" ++ Con) ->
- [{ok, {http_header, undefined, 'Authorization', undefined, strip_spaces(Con)}}];
-parse_line("Keep-Alive:" ++ Con) ->
- [{ok, {http_header, undefined, 'Keep-Alive', undefined, strip_spaces(Con)}}];
-parse_line("Referer:" ++ Con) ->
- [{ok, {http_header, undefined, 'Referer', undefined, strip_spaces(Con)}}];
-parse_line("Content-type:"++Con) ->
- [{ok, {http_header, undefined, 'Content-Type', undefined, strip_spaces(Con)}}];
-parse_line("Content-Type:"++Con) ->
- [{ok, {http_header, undefined, 'Content-Type', undefined, strip_spaces(Con)}}];
-parse_line("Content-Length:"++Con) ->
- [{ok, {http_header, undefined, 'Content-Length', undefined, strip_spaces(Con)}}];
-parse_line("Content-length:"++Con) ->
- [{ok, {http_header, undefined, 'Content-Length', undefined, strip_spaces(Con)}}];
-parse_line("Cookie:"++Con) ->
- [{ok, {http_header, undefined, 'Cookie', undefined, strip_spaces(Con)}}];
-parse_line("Accept-Language:"++Con) ->
- [{ok, {http_header, undefined, 'Accept-Language', undefined, strip_spaces(Con)}}];
-parse_line("Accept-Encoding:"++Con) ->
- [{ok, {http_header, undefined, 'Accept-Encoding', undefined, strip_spaces(Con)}}];
-parse_line(S) ->
- case lists:splitwith(fun(C)->C /= $: end, S) of
- {Name, [$:|Val]} ->
- [{ok, {http_header, undefined, Name, undefined, strip_spaces(Val)}}];
- _ ->
- []
- end.
-
-
-is_space($\s) ->
- true;
-is_space($\r) ->
- true;
-is_space($\n) ->
- true;
-is_space($\t) ->
- true;
-is_space(_) ->
- false.
-
-
-strip_spaces(String) ->
- strip_spaces(String, both).
-
-strip_spaces(String, left) ->
- drop_spaces(String);
-strip_spaces(String, right) ->
- lists:reverse(drop_spaces(lists:reverse(String)));
-strip_spaces(String, both) ->
- strip_spaces(drop_spaces(String), right).
-
-drop_spaces([]) ->
- [];
-drop_spaces(YS=[X|XS]) ->
- case is_space(X) of
- true ->
- drop_spaces(XS);
- false ->
- YS
- end.
-
-is_nb_space(X) ->
- lists:member(X, [$\s, $\t]).
-
-
-% ret: {line, Line, Trail} | {lastline, Line, Trail}
-
-get_line(L) ->
- get_line(L, []).
-get_line("\r\n\r\n" ++ Tail, Cur) ->
- {lastline, lists:reverse(Cur), Tail};
-get_line("\r\n" ++ Tail, Cur) ->
- case Tail of
- [] ->
- {incomplete, lists:reverse(Cur) ++ "\r\n"};
- _ ->
- case is_nb_space(hd(Tail)) of
- true -> %% multiline ... continue
- get_line(Tail, [$\n, $\r | Cur]);
- false ->
- {line, lists:reverse(Cur), Tail}
- end
- end;
-get_line([H|T], Cur) ->
- get_line(T, [H|Cur]).
-
diff --git a/ejabberd-1.1.2/src/web/ejabberd_http.hrl b/ejabberd-1.1.2/src/web/ejabberd_http.hrl
deleted file mode 100644
index 62041fed3..000000000
--- a/ejabberd-1.1.2/src/web/ejabberd_http.hrl
+++ /dev/null
@@ -1,18 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_http.hrl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 4 Mar 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--record(request, {method,
- path,
- q = [],
- us,
- auth,
- lang = "",
- data = ""
- }).
-
-
diff --git a/ejabberd-1.1.2/src/web/ejabberd_http_poll.erl b/ejabberd-1.1.2/src/web/ejabberd_http_poll.erl
deleted file mode 100644
index dcd041235..000000000
--- a/ejabberd-1.1.2/src/web/ejabberd_http_poll.erl
+++ /dev/null
@@ -1,380 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_http_poll.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : HTTP Polling support (JEP-0025)
-%%% Created : 4 Mar 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_http_poll).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--behaviour(gen_fsm).
-
-%% External exports
--export([start_link/2,
- init/1,
- handle_event/3,
- handle_sync_event/4,
- code_change/4,
- handle_info/3,
- terminate/3,
- send/2,
- setopts/2,
- controlling_process/2,
- close/1,
- process_request/1]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include("ejabberd_http.hrl").
-
--record(http_poll, {id, pid}).
-
--record(state, {id,
- key,
- output = "",
- input = "",
- waiting_input = false, %% {ReceiverPid, Tag}
- last_receiver,
- timer}).
-
-%-define(DBGFSM, true).
-
--ifdef(DBGFSM).
--define(FSMOPTS, [{debug, [trace]}]).
--else.
--define(FSMOPTS, []).
--endif.
-
--define(HTTP_POLL_TIMEOUT, 300000).
--define(CT, {"Content-Type", "text/xml; charset=utf-8"}).
--define(BAD_REQUEST, [?CT, {"Set-Cookie", "ID=-3:0; expires=-1"}]).
-
-
-%%%----------------------------------------------------------------------
-%%% API
-%%%----------------------------------------------------------------------
-start(ID, Key) ->
- mnesia:create_table(http_poll,
- [{ram_copies, [node()]},
- {attributes, record_info(fields, http_poll)}]),
- supervisor:start_child(ejabberd_http_poll_sup, [ID, Key]).
-
-start_link(ID, Key) ->
- gen_fsm:start_link(?MODULE, [ID, Key], ?FSMOPTS).
-
-send({http_poll, FsmRef}, Packet) ->
- gen_fsm:sync_send_all_state_event(FsmRef, {send, Packet}).
-
-setopts({http_poll, FsmRef}, Opts) ->
- case lists:member({active, once}, Opts) of
- true ->
- gen_fsm:sync_send_all_state_event(FsmRef, activate);
- _ ->
- ok
- end.
-
-controlling_process(_Socket, _Pid) ->
- ok.
-
-close({http_poll, FsmRef}) ->
- catch gen_fsm:sync_send_all_state_event(FsmRef, close).
-
-
-process_request(#request{path = [],
- data = Data} = Request) ->
- case catch parse_request(Data) of
- {ok, ID1, Key, NewKey, Packet} ->
- ID = if
- (ID1 == "0") or (ID1 == "mobile") ->
- NewID = sha:sha(term_to_binary({now(), make_ref()})),
- {ok, Pid} = start(NewID, ""),
- mnesia:transaction(
- fun() ->
- mnesia:write(#http_poll{id = NewID,
- pid = Pid})
- end),
- NewID;
- true ->
- ID1
- end,
- case http_put(ID, Key, NewKey, Packet) of
- {error, not_exists} ->
- {200, ?BAD_REQUEST, ""};
- {error, bad_key} ->
- {200, ?BAD_REQUEST, ""};
- ok ->
- receive
- after 100 -> ok
- end,
- case http_get(ID) of
- {error, not_exists} ->
- {200, [?BAD_REQUEST], ""};
- {ok, OutPacket} ->
- if
- ID == ID1 ->
- Cookie = "ID=" ++ ID ++ "; expires=-1",
- {200, [?CT, {"Set-Cookie", Cookie}],
- OutPacket};
- ID1 == "mobile" ->
- {200, [?CT], [ID, $\n, OutPacket]};
- true ->
- Cookie = "ID=" ++ ID ++ "; expires=-1",
- {200, [?CT, {"Set-Cookie", Cookie}],
- OutPacket}
- end
- end
- end;
- _ ->
- {200, [?CT, {"Set-Cookie", "ID=-2:0; expires=-1"}], ""}
- end;
-process_request(_Request) ->
- {400, [], {xmlelement, "h1", [],
- [{xmlcdata, "400 Bad Request"}]}}.
-
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_fsm
-%%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, StateName, StateData} |
-%% {ok, StateName, StateData, Timeout} |
-%% ignore |
-%% {stop, StopReason}
-%%----------------------------------------------------------------------
-init([ID, Key]) ->
- ?INFO_MSG("started: ~p", [{ID, Key}]),
- Opts = [], % TODO
- {ok, C2SPid} = ejabberd_c2s:start({?MODULE, {http_poll, self()}}, Opts),
- ejabberd_c2s:become_controller(C2SPid),
- Timer = erlang:start_timer(?HTTP_POLL_TIMEOUT, self(), []),
- {ok, loop, #state{id = ID,
- key = Key,
- timer = Timer}}.
-
-%%----------------------------------------------------------------------
-%% Func: StateName/2
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-
-
-%%----------------------------------------------------------------------
-%% 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({send, Packet}, From, StateName, StateData) ->
- Output = StateData#state.output ++ [lists:flatten(Packet)],
- Reply = ok,
- {reply, Reply, StateName, StateData#state{output = Output}};
-
-handle_sync_event(activate, From, StateName, StateData) ->
- case StateData#state.input of
- "" ->
- {reply, ok, StateName, StateData#state{waiting_input = From}};
- Input ->
- {Receiver, _Tag} = From,
- Receiver ! {tcp, {http_poll, self()}, list_to_binary(Input)},
- {reply, ok, StateName, StateData#state{input = "",
- waiting_input = false,
- last_receiver = From
- }}
- end;
-
-handle_sync_event(stop, From, StateName, StateData) ->
- Reply = ok,
- {stop, normal, Reply, StateData};
-
-handle_sync_event({http_put, Key, NewKey, Packet},
- From, StateName, StateData) ->
- Allow = case StateData#state.key of
- "" ->
- true;
- OldKey ->
- NextKey = jlib:encode_base64(
- binary_to_list(crypto:sha(Key))),
- if
- OldKey == NextKey ->
- true;
- true ->
- false
- end
- end,
- if
- Allow ->
- case StateData#state.waiting_input of
- false ->
- Input = [StateData#state.input|Packet],
- Reply = ok,
- {reply, Reply, StateName, StateData#state{input = Input,
- key = NewKey}};
- {Receiver, _Tag} ->
- Receiver ! {tcp, {http_poll, self()},
- list_to_binary(Packet)},
- cancel_timer(StateData#state.timer),
- Timer = erlang:start_timer(?HTTP_POLL_TIMEOUT, self(), []),
- Reply = ok,
- {reply, Reply, StateName,
- StateData#state{waiting_input = false,
- last_receiver = Receiver,
- key = NewKey,
- timer = Timer}}
- end;
- true ->
- Reply = {error, bad_key},
- {reply, Reply, StateName, StateData}
- end;
-
-handle_sync_event(http_get, From, StateName, StateData) ->
- Reply = {ok, StateData#state.output},
- {reply, Reply, StateName, StateData#state{output = ""}};
-
-handle_sync_event(Event, From, StateName, StateData) ->
- Reply = ok,
- {reply, Reply, StateName, StateData}.
-
-code_change(OldVsn, StateName, StateData, Extra) ->
- {ok, StateName, StateData}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/3
-%% Returns: {next_state, NextStateName, NextStateData} |
-%% {next_state, NextStateName, NextStateData, Timeout} |
-%% {stop, Reason, NewStateData}
-%%----------------------------------------------------------------------
-handle_info({timeout, Timer, _}, StateName,
- #state{timer = Timer} = StateData) ->
- {stop, normal, StateData};
-
-handle_info(_, StateName, StateData) ->
- {next_state, StateName, StateData}.
-
-%%----------------------------------------------------------------------
-%% Func: terminate/3
-%% Purpose: Shutdown the fsm
-%% Returns: any
-%%----------------------------------------------------------------------
-terminate(Reason, StateName, StateData) ->
- mnesia:transaction(
- fun() ->
- mnesia:delete({http_poll, StateData#state.id})
- end),
- case StateData#state.waiting_input of
- false ->
- %% We are testing this case due to "socket activation": If we pass
- %% here and the "socket" is not ready to receive, the tcp_closed
- %% will be lost.
- case StateData#state.last_receiver of
- undefined -> ok;
- Receiver ->
- Receiver ! {tcp_closed, {http_poll, self()}}
- end;
- {Receiver, _Tag} ->
- Receiver ! {tcp_closed, {http_poll, self()}}
- end,
- resend_messages(StateData#state.output),
- ok.
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-
-
-http_put(ID, Key, NewKey, Packet) ->
- case mnesia:dirty_read({http_poll, ID}) of
- [] ->
- {error, not_exists};
- [#http_poll{pid = FsmRef}] ->
- gen_fsm:sync_send_all_state_event(
- FsmRef, {http_put, Key, NewKey, Packet})
- end.
-
-http_get(ID) ->
- case mnesia:dirty_read({http_poll, ID}) of
- [] ->
- {error, not_exists};
- [#http_poll{pid = FsmRef}] ->
- gen_fsm:sync_send_all_state_event(FsmRef, http_get)
- end.
-
-
-parse_request(Data) ->
- Comma = string:chr(Data, $,),
- Header = lists:sublist(Data, Comma - 1),
- Packet = lists:nthtail(Comma, Data),
- {ID, Key, NewKey} =
- case string:tokens(Header, ";") of
- [ID1] ->
- {ID1, "", ""};
- [ID1, Key1] ->
- {ID1, Key1, Key1};
- [ID1, Key1, NewKey1] ->
- {ID1, Key1, NewKey1}
- end,
- {ok, ID, Key, NewKey, Packet}.
-
-
-cancel_timer(Timer) ->
- erlang:cancel_timer(Timer),
- receive
- {timeout, Timer, _} ->
- ok
- after 0 ->
- ok
- end.
-
-%% Resend the polled messages
-resend_messages(Messages) ->
- lists:foreach(fun(Packet) ->
- resend_message(Packet)
- end, Messages).
-
-%% This function is used to resend messages that have been polled but not
-%% delivered.
-resend_message(Packet) ->
- ParsedPacket = xml_stream:parse_element(Packet),
- From = get_jid("from", ParsedPacket),
- To = get_jid("to", ParsedPacket),
- io:format("MREMOND: Resend ~p ~p ~p~n",[From,To, ParsedPacket]),
- ejabberd_router:route(From, To, ParsedPacket).
-
-%% Type can be "from" or "to"
-%% Parsed packet is a parsed Jabber packet.
-get_jid(Type, ParsedPacket) ->
- case xml:get_tag_attr(Type, ParsedPacket) of
- {value, StringJid} ->
- jlib:string_to_jid(StringJid);
- false ->
- jlib:make_jid("","","")
- end.
diff --git a/ejabberd-1.1.2/src/web/ejabberd_web.erl b/ejabberd-1.1.2/src/web/ejabberd_web.erl
deleted file mode 100644
index 143fbf407..000000000
--- a/ejabberd-1.1.2/src/web/ejabberd_web.erl
+++ /dev/null
@@ -1,145 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_web.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
-%%% Created : 28 Feb 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(ejabberd_web).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
-%% External exports
--export([make_xhtml/1,
- process_get/2]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include("ejabberd_http.hrl").
-
-
-make_xhtml(Els) ->
- {xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"},
- {"xml:lang", "en"},
- {"lang", "en"}],
- [{xmlelement, "head", [],
- [{xmlelement, "meta", [{"http-equiv", "Content-Type"},
- {"content", "text/html; charset=utf-8"}], []}]},
- {xmlelement, "body", [], Els}
- ]}.
-
-
--define(X(Name), {xmlelement, Name, [], []}).
--define(XA(Name, Attrs), {xmlelement, Name, Attrs, []}).
--define(XE(Name, Els), {xmlelement, Name, [], Els}).
--define(XAE(Name, Attrs, Els), {xmlelement, Name, Attrs, Els}).
--define(C(Text), {xmlcdata, Text}).
--define(XC(Name, Text), ?XE(Name, [?C(Text)])).
--define(XAC(Name, Attrs, Text), ?XAE(Name, Attrs, [?C(Text)])).
-
--define(LI(Els), ?XE("li", Els)).
--define(A(URL, Els), ?XAE("a", [{"href", URL}], Els)).
--define(AC(URL, Text), ?A(URL, [?C(Text)])).
--define(P, ?X("p")).
--define(BR, ?X("br")).
--define(INPUT(Type, Name, Value),
- ?XA("input", [{"type", Type},
- {"name", Name},
- {"value", Value}])).
-
-
-process_get({_, true},
- #request{auth = Auth,
- path = ["admin", "server", SHost | RPath],
- q = Query,
- lang = Lang} = Request) ->
- Host = jlib:nameprep(SHost),
- case lists:member(Host, ?MYHOSTS) of
- true ->
- US = case Auth of
- {SJID, P} ->
- case jlib:string_to_jid(SJID) of
- error ->
- unauthorized;
- #jid{user = U, server = S} ->
- case ejabberd_auth:check_password(U, S, P) of
- true ->
- {U, S};
- false ->
- unauthorized
- end
- end;
- _ ->
- unauthorized
- end,
- case US of
- {User, Server} ->
- case acl:match_rule(
- Host, configure, jlib:make_jid(User, Server, "")) of
- deny ->
- {401, [], make_xhtml([?XC("h1", "Not Allowed")])};
- allow ->
- ejabberd_web_admin:process_admin(
- Host, Request#request{path = RPath,
- us = US})
- end;
- unauthorized ->
- {401,
- [{"WWW-Authenticate", "basic realm=\"ejabberd\""}],
- ejabberd_web:make_xhtml([{xmlelement, "h1", [],
- [{xmlcdata, "401 Unauthorized"}]}])}
- end;
- false ->
- {404, [], make_xhtml([?XC("h1", "Not found")])}
- end;
-
-process_get({_, true},
- #request{auth = Auth,
- path = ["admin" | RPath],
- q = Query,
- lang = Lang} = Request) ->
- US = case Auth of
- {SJID, P} ->
- case jlib:string_to_jid(SJID) of
- error ->
- unauthorized;
- #jid{user = U, server = S} ->
- case ejabberd_auth:check_password(U, S, P) of
- true ->
- {U, S};
- false ->
- unauthorized
- end
- end;
- _ ->
- unauthorized
- end,
- case US of
- {User, Server} ->
- case acl:match_rule(
- global, configure, jlib:make_jid(User, Server, "")) of
- deny ->
- {401, [], make_xhtml([?XC("h1", "Not Allowed")])};
- allow ->
- ejabberd_web_admin:process_admin(
- global, Request#request{path = RPath,
- us = US})
- end;
- unauthorized ->
- {401,
- [{"WWW-Authenticate", "basic realm=\"ejabberd\""}],
- ejabberd_web:make_xhtml([{xmlelement, "h1", [],
- [{xmlcdata, "401 Unauthorized"}]}])}
- end;
-
-process_get({true, _},
- #request{path = ["http-poll" | RPath],
- q = _Query,
- lang = _Lang} = Request) ->
- ejabberd_http_poll:process_request(Request#request{path = RPath});
-
-process_get(_, _Request) ->
- {404, [], make_xhtml([?XC("h1", "Not found")])}.
-
-
diff --git a/ejabberd-1.1.2/src/web/ejabberd_web_admin.erl b/ejabberd-1.1.2/src/web/ejabberd_web_admin.erl
deleted file mode 100644
index 1c03e50e1..000000000
--- a/ejabberd-1.1.2/src/web/ejabberd_web_admin.erl
+++ /dev/null
@@ -1,2653 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : ejabberd_web_admin.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Administration web interface
-%%% Created : 9 Apr 2004 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-%%% Copyright (c) 2004-2006 Alexey Shchepin
-%%% Copyright (c) 2004-2006 Process One
-%%%----------------------------------------------------------------------
-
--module(ejabberd_web_admin).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
-%% External exports
--export([process_admin/2,
- list_users/4,
- list_users_in_diapason/4]).
-
--include("ejabberd.hrl").
--include("jlib.hrl").
--include("ejabberd_http.hrl").
-
--define(X(Name), {xmlelement, Name, [], []}).
--define(XA(Name, Attrs), {xmlelement, Name, Attrs, []}).
--define(XE(Name, Els), {xmlelement, Name, [], Els}).
--define(XAE(Name, Attrs, Els), {xmlelement, Name, Attrs, Els}).
--define(C(Text), {xmlcdata, Text}).
--define(XC(Name, Text), ?XE(Name, [?C(Text)])).
--define(XAC(Name, Attrs, Text), ?XAE(Name, Attrs, [?C(Text)])).
-
--define(T(Text), translate:translate(Lang, Text)).
--define(CT(Text), ?C(?T(Text))).
--define(XCT(Name, Text), ?XC(Name, ?T(Text))).
--define(XACT(Name, Attrs, Text), ?XAC(Name, Attrs, ?T(Text))).
-
-
--define(LI(Els), ?XE("li", Els)).
--define(A(URL, Els), ?XAE("a", [{"href", URL}], Els)).
--define(AC(URL, Text), ?A(URL, [?C(Text)])).
--define(ACT(URL, Text), ?AC(URL, ?T(Text))).
--define(P, ?X("p")).
--define(BR, ?X("br")).
--define(INPUT(Type, Name, Value),
- ?XA("input", [{"type", Type},
- {"name", Name},
- {"value", Value}])).
--define(INPUTT(Type, Name, Value), ?INPUT(Type, Name, ?T(Value))).
--define(INPUTS(Type, Name, Value, Size),
- ?XA("input", [{"type", Type},
- {"name", Name},
- {"value", Value},
- {"size", Size}])).
--define(INPUTST(Type, Name, Value, Size), ?INPUT(Type, Name, ?T(Value), Size)).
-
-make_xhtml(Els, global, Lang) ->
- {200, [html],
- {xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"},
- {"xml:lang", Lang},
- {"lang", Lang}],
- [{xmlelement, "head", [],
- [?XCT("title", "ejabberd Web Interface"),
- {xmlelement, "meta", [{"http-equiv", "Content-Type"},
- {"content", "text/html; charset=utf-8"}], []},
- {xmlelement, "link", [{"href", "/admin/style.css"},
- {"type", "text/css"},
- {"rel", "stylesheet"}], []}]},
- ?XE("body",
- [?XAE("div",
- [{"id", "container"}],
- [?XAE("div",
- [{"id", "header"}],
- [?XE("h1",
- [?ACT("/admin/", "Administration")]
- )]),
- ?XAE("div",
- [{"id", "navigation"}],
- [?XE("ul",
- [?LI([?ACT("/admin/acls/", "Access Control Lists")]),
- ?LI([?ACT("/admin/access/", "Access Rules")]),
- ?LI([?ACT("/admin/vhosts/", "Virtual Hosts")]),
- ?LI([?ACT("/admin/nodes/", "Nodes")]),
- ?LI([?ACT("/admin/stats/", "Statistics")])
- ]
- )]),
- ?XAE("div",
- [{"id", "content"}],
- Els),
- ?XAE("div",
- [{"id", "clearcopyright"}],
- [{xmlcdata, ""}])]),
- ?XAE("div",
- [{"id", "copyrightouter"}],
- [?XAE("div",
- [{"id", "copyright"}],
- [?XCT("p",
- "ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One")
- ])])])
- ]}};
-
-make_xhtml(Els, Host, Lang) ->
- Base = "/admin/server/" ++ Host ++ "/",
- {200, [html],
- {xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"},
- {"xml:lang", Lang},
- {"lang", Lang}],
- [{xmlelement, "head", [],
- [?XCT("title", "ejabberd Web Interface"),
- {xmlelement, "meta", [{"http-equiv", "Content-Type"},
- {"content", "text/html; charset=utf-8"}], []},
- {xmlelement, "link", [{"href", Base ++ "style.css"},
- {"type", "text/css"},
- {"rel", "stylesheet"}], []}]},
- ?XE("body",
- [?XAE("div",
- [{"id", "container"}],
- [?XAE("div",
- [{"id", "header"}],
- [?XE("h1",
- [?ACT(Base, "Administration")]
- )]),
- ?XAE("div",
- [{"id", "navigation"}],
- [?XE("ul",
- [?LI([?ACT(Base ++ "acls/", "Access Control Lists")]),
- ?LI([?ACT(Base ++ "access/", "Access Rules")]),
- ?LI([?ACT(Base ++ "users/", "Users")]),
- ?LI([?ACT(Base ++ "online-users/", "Online Users")]),
- ?LI([?ACT(Base ++ "last-activity/", "Last Activity")]),
- ?LI([?ACT(Base ++ "nodes/", "Nodes")]),
- ?LI([?ACT(Base ++ "stats/", "Statistics")])
- ] ++
- case lists:member(mod_shared_roster,
- gen_mod:loaded_modules(Host)) of
- true ->
- [?LI([?ACT(Base ++ "shared-roster/", "Shared Roster")])];
- false ->
- []
- end
- )]),
- ?XAE("div",
- [{"id", "content"}],
- Els),
- ?XAE("div",
- [{"id", "clearcopyright"}],
- [{xmlcdata, ""}])]),
- ?XAE("div",
- [{"id", "copyrightouter"}],
- [?XAE("div",
- [{"id", "copyright"}],
- [?XCT("p",
- "ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One")
- ])])])
- ]}}.
-
-css(Host) ->
- Base = case Host of
- global ->
- "/admin/";
- _ ->
- "/admin/server/" ++ Host ++ "/"
- end,
- "
-html,body {
- background: white;
- margin: 0;
- padding: 0;
- height: 100%;
-}
-
-#container {
- padding: 0;
- margin: 0;
- min-height: 100%;
- height: 100%;
- margin-bottom: -30px;
-}
-
-html>body #container {
- height: auto;
-}
-
-#header h1 {
- width: 100%;
- height: 55px;
- padding: 0;
- margin: 0;
- background: transparent url(\"" ++ Base ++ "logo-fill.png\");
-}
-
-#header h1 a {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 55px;
- padding: 0;
- margin: 0;
- background: transparent url(\"" ++ Base ++ "logo.png\") no-repeat;
- display: block;
- text-indent: -700em;
-}
-
-#clearcopyright {
- display: block;
- width: 100%;
- height: 30px;
-}
-
-#copyrightouter {
- display: table;
- width: 100%;
- height: 30px;
-}
-
-#copyright {
- display: table-cell;
- vertical-align: bottom;
- width: 100%;
- height: 30px;
-}
-
-#copyright p {
- margin-left: 0;
- margin-right: 0;
- margin-top: 5px;
- margin-bottom: 0;
- padding-left: 0;
- padding-right: 0;
- padding-top: 1px;
- padding-bottom: 1px;
- width: 100%;
- color: #ffffff;
- background-color: #fe8a00;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 7pt;
- font-weight: bold;
- text-align: center;
-}
-
-#navigation ul {
- position: absolute;
- top: 54px;
- left: 0;
- padding: 0 1px 1px 1px;
- margin: 0;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 8pt;
- font-weight: bold;
- background: #d47911;
- width: 13em;
-}
-
-#navigation ul li {
- list-style: none;
- margin: 0;
- text-align: left;
- display: inline;
-}
-
-#navigation ul li a {
- margin: 0;
- display: block;
- padding: 3px 6px 3px 9px;
- border-left: 1em solid #ffc78c;
- border-top: 1px solid #d47911;
- background: #ffe3c9;
- text-decoration: none;
-}
-
-#navigation ul li a:link {
- color: #844;
-}
-
-#navigation ul li a:visited {
- color: #766;
-}
-
-#navigation ul li a:hover {
- border-color: #fc8800;
- color: #FFF;
- background: #332;
-}
-
-#lastactivity li {
- font-weight: bold;
- border: 1px solid #d6760e;
- background-color: #fff2e8;
- padding: 2px;
- margin-bottom: -1px;
-}
-
-td.copy {
- color: #ffffff;
- background-color: #fe8a00;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 7pt;
- font-weight: bold;
- text-align: center;
-}
-
-input {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 10pt;
- border: 1px solid #d6760e;
- color: #723202;
- background-color: #fff2e8;
- vertical-align: middle;
- margin-bottom: 0px;
- padding: 0.1em;
-}
-
-input[type=submit] {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 8pt;
- font-weight: bold;
- color: #ffffff;
- background-color: #fe8a00;
- border: 1px solid #d6760e;
-}
-
-textarea {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 10pt;
- border: 1px solid #d6760e;
- color: #723202;
- background-color: #fff2e8;
- vertical-align: middle;
- margin-top: 7px;
- margin-bottom: 5px;
- padding: 0.1em;
-}
-
-select {
- border: 1px solid #d6760e;
- color: #723202;
- background-color: #fff2e8;
- vertical-align: middle;
- margin-bottom: 0px;
- padding: 0.1em;
-}
-
-thead {
- color: #000000;
- background-color: #ffffff;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 10pt;
- font-weight: bold;
-}
-
-tr.head {
- color: #ffffff;
- background-color: #3b547a;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 9pt;
- font-weight: bold;
- text-align: center;
-}
-
-tr.oddraw {
- color: #412c75;
- background-color: #ccd4df;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 9pt;
- font-weight: normal;
- text-align: center;
-}
-
-tr.evenraw {
- color: #412c75;
- background-color: #dbe0e8;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 9pt;
- font-weight: normal;
- text-align: center;
-}
-
-td.leftheader {
- color: #412c75;
- background-color: #ccccc1;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 9pt;
- font-weight: bold;
- padding-left: 5px;
- padding-top: 2px;
- padding-bottom: 2px;
- margin-top: 0px;
- margin-bottom: 0px;
-}
-
-td.leftcontent {
- color: #000044;
- background-color: #e6e6df;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 7pt;
- font-weight: normal;
- padding-left: 5px;
- padding-right: 5px;
- padding-top: 2px;
- padding-bottom: 2px;
- margin-top: 0px;
- margin-bottom: 0px;
-}
-
-td.rightcontent {
- color: #000044;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 10pt;
- font-weight: normal;
- text-align: justify;
- padding-left: 10px;
- padding-right: 10px;
- padding-bottom: 5px;
-}
-
-
-h1 {
- color: #000044;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 14pt;
- font-weight: bold;
- text-align: center;
- padding-top: 2px;
- padding-bottom: 2px;
- margin-top: 0px;
- margin-bottom: 0px;
-}
-
-h2 {
- color: #000044;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 12pt;
- font-weight: bold;
- text-align: center;
- padding-top: 2px;
- padding-bottom: 2px;
- margin-top: 0px;
- margin-bottom: 0px;
-}
-
-h3 {
- color: #000044;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 10pt;
- font-weight: bold;
- text-align: left;
- padding-top: 20px;
- padding-bottom: 2px;
- margin-top: 0px;
- margin-bottom: 0px;
-}
-
-#content a:link {
- color: #990000;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 10pt;
- font-weight: bold;
- text-decoration: underline;
-}
-#content a:visited {
- color: #990000;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 10pt;
- font-weight: bold;
- text-decoration: underline;
-}
-#content a:hover {
- color: #cc6600;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 10pt;
- font-weight: bold;
- text-decoration: underline;
-}
-
-
-#content ul li {
- list-style-type: disc;
- font-size: 10pt;
- /*font-size: 7pt;*/
- padding-left: 10px;
-}
-
-#content li.big {
- font-size: 10pt;
-}
-
-#content {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 10pt;
- padding-left: 13em;
- padding-top: 5px;
-}
-
-*.alignright {
- text-align: right;
-}
-
-".
-
-logo() ->
- jlib:decode_base64(
- "iVBORw0KGgoAAAANSUhEUgAAAVcAAAA3CAMAAACPbPnEAAAAYFBMVEX///8C"
- "AgJyMgL+vm7Wdg7+igL+/v7+slb+qkb+4sr+ojP+nir+lhr+1qb+khL+wnb+"
- "wn7+zpb+jgb+yoz+xo7+tmL+pj7+mib+jg7+5sb+rlL+rkr+mh7+tl7+2q7+"
- "umpJ0uikAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIA"
- "AAsSAdLdfvwAAAAHdElNRQfUBAUJBhWzc9qJAAABQ0lEQVR42u2bXU/CQBBF"
- "UUZFURAU5Ev4//+S3Ow+tFl3s6adtE3Oebghzc4DJ/Nw04WZgQczexJkz4lX"
- "vOKVxKuXV6APTCFXAq94xSte8ermFYbrA6+ilemZRxGz+fxBxMydL0/Vz5an"
- "vkUrPfb1IPCKV7ziFa9uXsG/DzyLPz7ndjS3tc3tSbcwPdl9tmYq3dHmk9x3"
- "r8mtiM11KfCKV7ziFa9uXmEc7wf+u6+5TtlXf62fKu9rl3wX9ibsLPCKV7zi"
- "Fa9uXmF87wf67aBT6a+hp4bOehFxU0/CbgKveMUrXvHq5hXG+vuBcpss75zH"
- "/VZ5X7vcb4W7q5A/wvbCXoTNhX0JvOIVr3jFq5tX4P8Fw2V6g7UQ9itsLeKm"
- "fgi84hWveMWrm1egDwyX6Q3WTtinsI2wq7CjwCte8YpXvLp5BQ/utIiGbwh9"
- "RAEAAAAASUVORK5CYII=").
-
-logo_fill() ->
- jlib:decode_base64(
- "iVBORw0KGgoAAAANSUhEUgAAAAYAAAA3BAMAAADdxCZzAAAAHlBMVEXWdg7+"
- "igL+jg7+khL+nir+rkr+umr+yoz+1qb+5sbOf9L8AAAACXBIWXMAAA9hAAAP"
- "YQGoP6dpAAAAQUlEQVQI12XDSxHAIBAFQT6BJEcsYAELWMACFtYCFnAL7zxd"
- "1c5dvhSU2BpKqBXl6R0ljYGS50R5zVC+tVD+vfE6YyUexE9x7g4AAAAASUVO"
- "RK5CYII=").
-
-process_admin(global,
- #request{us = US,
- path = [],
- q = Query,
- lang = Lang} = Request) ->
- make_xhtml([?XCT("h1", "Administration"),
- ?XE("ul",
- [?LI([?ACT("/admin/acls/", "Access Control Lists"), ?C(" "),
- ?ACT("/admin/acls-raw/", "(Raw)")]),
- ?LI([?ACT("/admin/access/", "Access Rules"), ?C(" "),
- ?ACT("/admin/access-raw/", "(Raw)")]),
- ?LI([?ACT("/admin/vhosts/", "Virtual Hosts")]),
- ?LI([?ACT("/admin/nodes/", "Nodes")]),
- ?LI([?ACT("/admin/stats/", "Statistics")])
- ]
- )
- ], global, Lang);
-
-process_admin(Host,
- #request{us = US,
- path = [],
- q = Query,
- lang = Lang} = Request) ->
- Base = "/admin/server/" ++ Host ++ "/",
- make_xhtml([?XCT("h1", "Administration"),
- ?XE("ul",
- [?LI([?ACT(Base ++ "acls/", "Access Control Lists"), ?C(" "),
- ?ACT(Base ++ "acls-raw/", "(Raw)")]),
- ?LI([?ACT(Base ++ "access/", "Access Rules"), ?C(" "),
- ?ACT(Base ++ "access-raw/", "(Raw)")]),
- ?LI([?ACT(Base ++ "users/", "Users")]),
- ?LI([?ACT(Base ++ "online-users/", "Online Users")]),
- ?LI([?ACT(Base ++ "last-activity/", "Last Activity")]),
- ?LI([?ACT(Base ++ "nodes/", "Nodes")]),
- ?LI([?ACT(Base ++ "stats/", "Statistics")])
- ] ++
- case lists:member(mod_shared_roster,
- gen_mod:loaded_modules(Host)) of
- true ->
- [?LI([?ACT(Base ++ "shared-roster/", "Shared Roster")])];
- false ->
- []
- end
- )
- ], Host, Lang);
-
-process_admin(Host,
- #request{us = US,
- path = ["style.css"],
- q = Query,
- lang = Lang} = Request) ->
- {200, [{"Content-Type", "text/css"}], css(Host)};
-
-process_admin(Host,
- #request{us = US,
- path = ["logo.png"],
- q = Query,
- lang = Lang} = Request) ->
- {200, [{"Content-Type", "image/png"}], logo()};
-
-process_admin(Host,
- #request{us = US,
- path = ["logo-fill.png"],
- q = Query,
- lang = Lang} = Request) ->
- {200, [{"Content-Type", "image/png"}], logo_fill()};
-
-process_admin(Host,
- #request{us = US,
- path = ["acls-raw"],
- q = Query,
- lang = Lang} = Request) ->
- Res = case lists:keysearch("acls", 1, Query) of
- {value, {_, String}} ->
- case erl_scan:string(String) of
- {ok, Tokens, _} ->
- case erl_parse:parse_term(Tokens) of
- {ok, NewACLs} ->
- case acl:add_list(Host, NewACLs, true) of
- ok ->
- ok;
- _ ->
- error
- end;
- _ ->
- error
- end;
- _ ->
- error
- end;
- _ ->
- nothing
- end,
- ACLs = lists:flatten(
- io_lib:format(
- "~p.", [lists:keysort(
- 2, ets:select(acl, [{{acl, {'$1', Host}, '$2'},
- [], [{{acl, '$1', '$2'}}]}]))])),
- make_xhtml([?XCT("h1", "Access Control Lists")] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [?XAC("textarea", [{"name", "acls"},
- {"rows", "16"},
- {"cols", "80"}],
- ACLs),
- ?BR,
- ?INPUTT("submit", "submit", "Submit")
- ])
- ], Host, Lang);
-
-process_admin(Host,
- #request{method = Method,
- us = US,
- path = ["acls"],
- q = Query,
- lang = Lang} = Request) ->
- ?INFO_MSG("query: ~p", [Query]),
- Res = case Method of
- 'POST' ->
- case catch acl_parse_query(Host, Query) of
- {'EXIT', _} ->
- error;
- NewACLs ->
- ?INFO_MSG("NewACLs at ~s: ~p", [Host, NewACLs]),
- case acl:add_list(Host, NewACLs, true) of
- ok ->
- ?INFO_MSG("NewACLs: ok", []),
- ok;
- _ ->
- error
- end
- end;
- _ ->
- nothing
- end,
- ACLs = lists:keysort(
- 2, ets:select(acl, [{{acl, {'$1', Host}, '$2'},
- [], [{{acl, '$1', '$2'}}]}])),
- make_xhtml([?XCT("h1", "Access Control Lists")] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XE("p", [?ACT("../acls-raw/", "Raw")])] ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [acls_to_xhtml(ACLs),
- ?BR,
- ?INPUTT("submit", "delete", "Delete Selected"),
- ?C(" "),
- ?INPUTT("submit", "submit", "Submit")
- ])
- ], Host, Lang);
-
-process_admin(Host,
- #request{us = US,
- path = ["access-raw"],
- q = Query,
- lang = Lang} = Request) ->
- SetAccess =
- fun(Rs) ->
- mnesia:transaction(
- fun() ->
- Os = mnesia:select(
- config,
- [{{config, {access, '$1', Host}, '$2'},
- [],
- ['$_']}]),
- lists:foreach(fun(O) ->
- mnesia:delete_object(O)
- end, Os),
- lists:foreach(
- fun({access, Name, Rules}) ->
- mnesia:write({config,
- {access, Name, Host},
- Rules})
- end, Rs)
- end)
- end,
- Res = case lists:keysearch("access", 1, Query) of
- {value, {_, String}} ->
- case erl_scan:string(String) of
- {ok, Tokens, _} ->
- case erl_parse:parse_term(Tokens) of
- {ok, Rs} ->
- case SetAccess(Rs) of
- {atomic, _} ->
- ok;
- _ ->
- error
- end;
- _ ->
- error
- end;
- _ ->
- error
- end;
- _ ->
- nothing
- end,
- Access =
- lists:flatten(
- io_lib:format(
- "~p.", [ets:select(config,
- [{{config, {access, '$1', Host}, '$2'},
- [],
- [{{access, '$1', '$2'}}]}])])),
- make_xhtml([?XCT("h1", "Access Rules")] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [?XAC("textarea", [{"name", "access"},
- {"rows", "16"},
- {"cols", "80"}],
- Access),
- ?BR,
- ?INPUTT("submit", "submit", "Submit")
- ])
- ], Host, Lang);
-
-process_admin(Host,
- #request{method = Method,
- us = US,
- path = ["access"],
- q = Query,
- lang = Lang} = Request) ->
- ?INFO_MSG("query: ~p", [Query]),
- Res = case Method of
- 'POST' ->
- case catch access_parse_query(Host, Query) of
- {'EXIT', _} ->
- error;
- ok ->
- ok
- end;
- _ ->
- nothing
- end,
- AccessRules =
- ets:select(config,
- [{{config, {access, '$1', Host}, '$2'},
- [],
- [{{access, '$1', '$2'}}]}]),
- make_xhtml([?XCT("h1", "Access Rules")] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XE("p", [?ACT("../access-raw/", "Raw")])] ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [access_rules_to_xhtml(AccessRules, Lang),
- ?BR,
- ?INPUTT("submit", "delete", "Delete Selected")
- ])
- ], Host, Lang);
-
-process_admin(Host,
- #request{method = Method,
- us = US,
- path = ["access", SName],
- q = Query,
- lang = Lang} = Request) ->
- ?INFO_MSG("query: ~p", [Query]),
- Name = list_to_atom(SName),
- Res = case lists:keysearch("rules", 1, Query) of
- {value, {_, String}} ->
- case parse_access_rule(String) of
- {ok, Rs} ->
- ejabberd_config:add_global_option(
- {access, Name, Host}, Rs),
- ok;
- _ ->
- error
- end;
- _ ->
- nothing
- end,
- Rules = case ejabberd_config:get_global_option({access, Name, Host}) of
- undefined ->
- [];
- Rs1 ->
- Rs1
- end,
- make_xhtml([?XC("h1",
- io_lib:format(?T("~s access rule configuration"), [SName]))] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [access_rule_to_xhtml(Rules),
- ?BR,
- ?INPUTT("submit", "submit", "Submit")
- ])
- ], Host, Lang);
-
-process_admin(global,
- #request{us = US,
- path = ["vhosts"],
- q = Query,
- lang = Lang} = Request) ->
- Res = list_vhosts(Lang),
- make_xhtml([?XCT("h1", "ejabberd virtual hosts")] ++ Res, global, Lang);
-
-process_admin(Host,
- #request{us = US,
- path = ["users"],
- q = Query,
- lang = Lang} = Request) when is_list(Host) ->
- Res = list_users(Host, Query, Lang, fun url_func/1),
- make_xhtml([?XCT("h1", "Users")] ++ Res, Host, Lang);
-
-process_admin(Host,
- #request{us = US,
- path = ["users", Diap],
- q = Query,
- lang = Lang} = Request) when is_list(Host) ->
- Res = list_users_in_diapason(Host, Diap, Lang, fun url_func/1),
- make_xhtml([?XCT("h1", "Users")] ++ Res, Host, Lang);
-
-process_admin(Host,
- #request{us = US,
- path = ["online-users"],
- q = Query,
- lang = Lang} = Request) when is_list(Host) ->
- Res = list_online_users(Host, Lang),
- make_xhtml([?XCT("h1", "Online Users")] ++ Res, Host, Lang);
-
-process_admin(Host,
- #request{method = Method,
- us = US,
- path = ["last-activity"],
- q = Query,
- lang = Lang} = Request) when is_list(Host) ->
- ?INFO_MSG("query: ~p", [Query]),
- Month = case lists:keysearch("period", 1, Query) of
- {value, {_, Val}} ->
- Val;
- _ ->
- "month"
- end,
- Res = case lists:keysearch("ordinary", 1, Query) of
- {value, {_, _}} ->
- list_last_activity(Host, Lang, false, Month);
- _ ->
- list_last_activity(Host, Lang, true, Month)
- end,
- make_xhtml([?XCT("h1", "Users Last Activity")] ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [?CT("Period: "),
- ?XAE("select", [{"name", "period"}],
- lists:map(
- fun({O, V}) ->
- Sel = if
- O == Month -> [{"selected", "selected"}];
- true -> []
- end,
- ?XAC("option",
- Sel ++ [{"value", O}], V)
- end, [{"month", ?T("Last month")},
- {"year", ?T("Last year")},
- {"all", ?T("All activity")}])),
- ?C(" "),
- ?INPUTT("submit", "ordinary", "Show Ordinary Table"),
- ?C(" "),
- ?INPUTT("submit", "integral", "Show Integral Table")
- ])] ++
- Res, Host, Lang);
-
-process_admin(Host,
- #request{us = US,
- path = ["stats"],
- q = Query,
- lang = Lang} = Request) ->
- Res = get_stats(Host, Lang),
- make_xhtml([?XCT("h1", "Statistics")] ++ Res, Host, Lang);
-
-process_admin(Host,
- #request{us = US,
- path = ["user", U],
- q = Query,
- lang = Lang} = Request) ->
- Res = user_info(U, Host, Query, Lang),
- make_xhtml(Res, Host, Lang);
-
-process_admin(Host,
- #request{us = US,
- path = ["user", U, "queue"],
- q = Query,
- lang = Lang} = Request) ->
- Res = user_queue(U, Host, Query, Lang),
- make_xhtml(Res, Host, Lang);
-
-process_admin(Host,
- #request{us = US,
- path = ["user", U, "roster"],
- q = Query,
- lang = Lang} = Request) ->
- Res = user_roster(U, Host, Query, Lang, true),
- make_xhtml(Res, Host, Lang);
-
-process_admin(Host,
- #request{us = US,
- path = ["nodes"],
- q = Query,
- lang = Lang} = Request) ->
- Res = get_nodes(Lang),
- make_xhtml(Res, Host, Lang);
-
-process_admin(Host,
- #request{us = US,
- path = ["node", SNode | NPath],
- q = Query,
- lang = Lang} = Request) ->
- case search_running_node(SNode) of
- false ->
- make_xhtml([?XCT("h1", "Node not found")], Host, Lang);
- Node ->
- Res = get_node(Host, Node, NPath, Query, Lang),
- make_xhtml(Res, Host, Lang)
- end;
-
-process_admin(Host,
- #request{us = US,
- path = ["shared-roster"],
- q = Query,
- lang = Lang} = Request) ->
- Res = list_shared_roster_groups(Host, Query, Lang),
- make_xhtml(Res, Host, Lang);
-
-process_admin(Host,
- #request{us = US,
- path = ["shared-roster", Group],
- q = Query,
- lang = Lang} = Request) ->
- Res = shared_roster_group(Host, Group, Query, Lang),
- make_xhtml(Res, Host, Lang);
-
-process_admin(Host,
- #request{lang = Lang}) ->
- setelement(1, make_xhtml([?XC("h1", "Not Found")], Host, Lang), 404).
-
-
-
-acls_to_xhtml(ACLs) ->
- ?XAE("table", [],
- [?XE("tbody",
- lists:map(
- fun({acl, Name, Spec} = ACL) ->
- SName = atom_to_list(Name),
- ID = term_to_id(ACL),
- ?XE("tr",
- [?XE("td", [?INPUT("checkbox", "selected", ID)]),
- ?XC("td", SName)] ++
- acl_spec_to_xhtml(ID, Spec)
- )
- end, ACLs) ++
- [?XE("tr",
- [?X("td"),
- ?XE("td", [?INPUT("text", "namenew", "")])
- ] ++
- acl_spec_to_xhtml("new", {user, ""})
- )]
- )]).
-
--define(ACLINPUT(Text), ?XE("td", [?INPUT("text", "value" ++ ID, Text)])).
-
-acl_spec_to_text({user, U}) ->
- {user, U};
-
-acl_spec_to_text({server, S}) ->
- {server, S};
-
-acl_spec_to_text({user, U, S}) ->
- {user_server, U ++ "@" ++ S};
-
-acl_spec_to_text(Spec) ->
- {raw, term_to_string(Spec)}.
-
-acl_spec_to_xhtml(ID, Spec) ->
- {Type, Str} = acl_spec_to_text(Spec),
- [acl_spec_select(ID, Type), ?ACLINPUT(Str)].
-
-acl_spec_select(ID, Opt) ->
- ?XE("td",
- [?XAE("select", [{"name", "type" ++ ID}],
- lists:map(
- fun(O) ->
- Sel = if
- O == Opt -> [{"selected", "selected"}];
- true -> []
- end,
- ?XAC("option",
- Sel ++ [{"value", atom_to_list(O)}],
- atom_to_list(O))
- end, [user, server, user_server, raw]))]).
-
-
-term_to_string(T) ->
- lists:flatten(io_lib:format("~1000000p", [T])).
-
-term_to_id(T) ->
- jlib:encode_base64(binary_to_list(term_to_binary(T))).
-
-
-acl_parse_query(Host, Query) ->
- ACLs = ets:select(acl, [{{acl, {'$1', Host}, '$2'},
- [], [{{acl, '$1', '$2'}}]}]),
- case lists:keysearch("submit", 1, Query) of
- {value, _} ->
- acl_parse_submit(ACLs, Query);
- _ ->
- case lists:keysearch("delete", 1, Query) of
- {value, _} ->
- acl_parse_delete(ACLs, Query)
- end
- end.
-
-acl_parse_submit(ACLs, Query) ->
- NewACLs =
- lists:map(
- fun({acl, Name, Spec} = ACL) ->
- SName = atom_to_list(Name),
- ID = term_to_id(ACL),
- case {lists:keysearch("type" ++ ID, 1, Query),
- lists:keysearch("value" ++ ID, 1, Query)} of
- {{value, {_, T}}, {value, {_, V}}} ->
- {Type, Str} = acl_spec_to_text(Spec),
- case {atom_to_list(Type), Str} of
- {T, V} ->
- ACL;
- _ ->
- NewSpec = string_to_spec(T, V),
- {acl, Name, NewSpec}
- end;
- _ ->
- ACL
- end
- end, ACLs),
- NewACL = case {lists:keysearch("namenew", 1, Query),
- lists:keysearch("typenew", 1, Query),
- lists:keysearch("valuenew", 1, Query)} of
- {{value, {_, ""}}, _, _} ->
- [];
- {{value, {_, N}}, {value, {_, T}}, {value, {_, V}}} ->
- NewName = list_to_atom(N),
- NewSpec = string_to_spec(T, V),
- [{acl, NewName, NewSpec}];
- _ ->
- []
- end,
- NewACLs ++ NewACL.
-
-string_to_spec("user", Val) ->
- {user, Val};
-string_to_spec("server", Val) ->
- {server, Val};
-string_to_spec("user_server", Val) ->
- #jid{luser = U, lserver = S, resource = ""} = jlib:string_to_jid(Val),
- {user, U, S};
-string_to_spec("raw", Val) ->
- {ok, Tokens, _} = erl_scan:string(Val ++ "."),
- {ok, NewSpec} = erl_parse:parse_term(Tokens),
- NewSpec.
-
-
-acl_parse_delete(ACLs, Query) ->
- NewACLs =
- lists:filter(
- fun({acl, Name, Spec} = ACL) ->
- ID = term_to_id(ACL),
- not lists:member({"selected", ID}, Query)
- end, ACLs),
- NewACLs.
-
-
-access_rules_to_xhtml(AccessRules, Lang) ->
- ?XAE("table", [],
- [?XE("tbody",
- lists:map(
- fun({access, Name, Rules} = Access) ->
- SName = atom_to_list(Name),
- ID = term_to_id(Access),
- ?XE("tr",
- [?XE("td", [?INPUT("checkbox", "selected", ID)]),
- ?XE("td", [?AC(SName ++ "/", SName)]),
- ?XC("td", term_to_string(Rules))
- ]
- )
- end, AccessRules) ++
- [?XE("tr",
- [?X("td"),
- ?XE("td", [?INPUT("text", "namenew", "")]),
- ?XE("td", [?INPUTT("submit", "addnew", "Add New")])
- ]
- )]
- )]).
-
-access_parse_query(Host, Query) ->
- AccessRules =
- ets:select(config,
- [{{config, {access, '$1', Host}, '$2'},
- [],
- [{{access, '$1', '$2'}}]}]),
- case lists:keysearch("addnew", 1, Query) of
- {value, _} ->
- access_parse_addnew(AccessRules, Host, Query);
- _ ->
- case lists:keysearch("delete", 1, Query) of
- {value, _} ->
- access_parse_delete(AccessRules, Host, Query)
- end
- end.
-
-access_parse_addnew(AccessRules, Host, Query) ->
- case lists:keysearch("namenew", 1, Query) of
- {value, {_, String}} when String /= "" ->
- Name = list_to_atom(String),
- ejabberd_config:add_global_option({access, Name, Host}, []),
- ok
- end.
-
-access_parse_delete(AccessRules, Host, Query) ->
- lists:foreach(
- fun({access, Name, _Rules} = AccessRule) ->
- ID = term_to_id(AccessRule),
- case lists:member({"selected", ID}, Query) of
- true ->
- mnesia:transaction(
- fun() ->
- mnesia:delete({config, {access, Name, Host}})
- end);
- _ ->
- ok
- end
- end, AccessRules),
- ok.
-
-
-
-
-access_rule_to_xhtml(Rules) ->
- Text = lists:flatmap(
- fun({Access, ACL} = Rule) ->
- SAccess = atom_to_list(Access),
- SACL = atom_to_list(ACL),
- SAccess ++ "\t" ++ SACL ++ "\n"
- end, Rules),
- ?XAC("textarea", [{"name", "rules"},
- {"rows", "16"},
- {"cols", "80"}],
- Text).
-
-parse_access_rule(Text) ->
- Strings = string:tokens(Text, "\r\n"),
- case catch lists:flatmap(
- fun(String) ->
- case string:tokens(String, "\s\t") of
- [Access, ACL] ->
- [{list_to_atom(Access), list_to_atom(ACL)}];
- [] ->
- []
- end
- end, Strings) of
- {'EXIT', _Reason} ->
- error;
- Rs ->
- {ok, Rs}
- end.
-
-
-list_vhosts(Lang) ->
- Hosts = ?MYHOSTS,
- SHosts = lists:sort(Hosts),
- [?XE("table",
- [?XE("thead",
- [?XE("tr",
- [?XCT("td", "Host"),
- ?XCT("td", "Registered Users"),
- ?XCT("td", "Online Users")
- ])]),
- ?XE("tbody",
- lists:map(
- fun(Host) ->
- OnlineUsers =
- length(ejabberd_sm:get_vh_session_list(Host)),
- RegisteredUsers =
- length(ejabberd_auth:get_vh_registered_users(Host)),
- ?XE("tr",
- [?XE("td", [?AC("../server/" ++ Host ++ "/", Host)]),
- ?XC("td", integer_to_list(RegisteredUsers)),
- ?XC("td", integer_to_list(OnlineUsers))
- ])
- end, SHosts)
- )])].
-
-
-list_users(Host, Query, Lang, URLFunc) ->
- Res = list_users_parse_query(Query, Host),
- Users = ejabberd_auth:get_vh_registered_users(Host),
- SUsers = lists:sort([{S, U} || {U, S} <- Users]),
- FUsers =
- case length(SUsers) of
- N when N =< 100 ->
- [list_given_users(SUsers, "../", Lang, URLFunc)];
- N ->
- NParts = trunc(math:sqrt(N * 0.618)) + 1,
- M = trunc(N / NParts) + 1,
- lists:flatmap(
- fun(K) ->
- L = K + M - 1,
- Node = integer_to_list(K) ++ "-" ++ integer_to_list(L),
- Last = if L < N -> su_to_list(lists:nth(L, SUsers));
- true -> su_to_list(lists:last(SUsers))
- end,
- Name =
- su_to_list(lists:nth(K, SUsers)) ++
- [$\s, 226, 128, 148, $\s] ++
- Last,
- [?AC(URLFunc({user_diapason, K, L}), Name), ?BR]
- end, lists:seq(1, N, M))
- end,
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [?XE("table",
- [?XE("tr",
- [?XC("td", ?T("User") ++ ":"),
- ?XE("td", [?INPUT("text", "newusername", "")]),
- ?XE("td", [?C([" @ ", Host])])
- ]),
- ?XE("tr",
- [?XC("td", ?T("Password") ++ ":"),
- ?XE("td", [?INPUT("password", "newuserpassword", "")]),
- ?X("td")
- ]),
- ?XE("tr",
- [?X("td"),
- ?XAE("td", [{"class", "alignright"}],
- [?INPUTT("submit", "addnewuser", "Add User")]),
- ?X("td")
- ])]),
- ?P] ++
- FUsers)].
-
-%% Parse user creation query and try register:
-list_users_parse_query(Query, Host) ->
- case lists:keysearch("addnewuser", 1, Query) of
- {value, _} ->
- {value, {_, Username}} =
- lists:keysearch("newusername", 1, Query),
- {value, {_, Password}} =
- lists:keysearch("newuserpassword", 1, Query),
- case jlib:string_to_jid(Username++"@"++Host) of
- error ->
- error;
- #jid{user = User, server = Server} ->
- case ejabberd_auth:try_register(User, Server, Password) of
- {error, _Reason} ->
- error;
- _ ->
- ok
- end
- end;
- false ->
- nothing
- end.
-
-
-list_users_in_diapason(Host, Diap, Lang, URLFunc) ->
- Users = ejabberd_auth:get_vh_registered_users(Host),
- SUsers = lists:sort([{S, U} || {U, S} <- Users]),
- {ok, [S1, S2]} = regexp:split(Diap, "-"),
- N1 = list_to_integer(S1),
- N2 = list_to_integer(S2),
- Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
- [list_given_users(Sub, "../../", Lang, URLFunc)].
-
-list_given_users(Users, Prefix, Lang, URLFunc) ->
- ?XE("table",
- [?XE("thead",
- [?XE("tr",
- [?XCT("td", "User"),
- ?XCT("td", "Offline Messages"),
- ?XCT("td", "Last Activity")])]),
- ?XE("tbody",
- lists:map(
- fun(SU = {Server, User}) ->
- US = {User, Server},
- QueueLen = length(mnesia:dirty_read({offline_msg, US})),
- FQueueLen = [?AC(URLFunc({users_queue, Prefix,
- User, Server}),
- integer_to_list(QueueLen))],
- FLast =
- case ejabberd_sm:get_user_resources(User, Server) of
- [] ->
- case mnesia:dirty_read({last_activity, US}) of
- [] ->
- ?T("Never");
- [E] ->
- Shift = element(3, E),
- TimeStamp = {Shift div 1000000,
- Shift rem 1000000,
- 0},
- {{Year, Month, Day}, {Hour, Minute, Second}} =
- calendar:now_to_local_time(TimeStamp),
- lists:flatten(
- io_lib:format(
- "~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w",
- [Year, Month, Day, Hour, Minute, Second]))
- end;
- _ ->
- ?T("Online")
- end,
- ?XE("tr",
- [?XE("td",
- [?AC(URLFunc({user, Prefix,
- ejabberd_http:url_encode(User),
- Server}),
- us_to_list(US))]),
- ?XE("td", FQueueLen),
- ?XC("td", FLast)])
- end, Users)
- )]).
-
-us_to_list({User, Server}) ->
- jlib:jid_to_string({User, Server, ""}).
-
-su_to_list({Server, User}) ->
- jlib:jid_to_string({User, Server, ""}).
-
-
-get_stats(global, Lang) ->
- OnlineUsers = mnesia:table_info(presence, size),
- AuthUsers = mnesia:table_info(session, size),
- RegisteredUsers = mnesia:table_info(passwd, size),
- S2SConns = ejabberd_s2s:dirty_get_connections(),
- S2SConnections = length(S2SConns),
- S2SServers = length(lists:usort([element(2, C) || C <- S2SConns])),
- [?XAE("table", [],
- [?XE("tbody",
- [?XE("tr", [?XCT("td", "Registered Users:"),
- ?XC("td", integer_to_list(RegisteredUsers))]),
- ?XE("tr", [?XCT("td", "Authenticated Users:"),
- ?XC("td", integer_to_list(AuthUsers))]),
- ?XE("tr", [?XCT("td", "Online Users:"),
- ?XC("td", integer_to_list(OnlineUsers))]),
- ?XE("tr", [?XCT("td", "Outgoing s2s Connections:"),
- ?XC("td", integer_to_list(S2SConnections))]),
- ?XE("tr", [?XCT("td", "Outgoing s2s Servers:"),
- ?XC("td", integer_to_list(S2SServers))])
- ])
- ])];
-
-get_stats(Host, Lang) ->
- OnlineUsers = length(ejabberd_sm:get_vh_session_list(Host)),
- RegisteredUsers = length(ejabberd_auth:get_vh_registered_users(Host)),
- [?XAE("table", [],
- [?XE("tbody",
- [?XE("tr", [?XCT("td", "Registered Users:"),
- ?XC("td", integer_to_list(RegisteredUsers))]),
- ?XE("tr", [?XCT("td", "Online Users:"),
- ?XC("td", integer_to_list(OnlineUsers))])
- ])
- ])].
-
-
-list_online_users(Host, _Lang) ->
- Users = [{S, U} || {U, S, R} <- ejabberd_sm:get_vh_session_list(Host)],
- SUsers = lists:usort(Users),
- lists:flatmap(
- fun({S, U} = SU) ->
- [?AC("../user/" ++ ejabberd_http:url_encode(U) ++ "/",
- su_to_list(SU)),
- ?BR]
- end, SUsers).
-
-user_info(User, Server, Query, Lang) ->
- US = {jlib:nodeprep(User), jlib:nameprep(Server)},
- Res = user_parse_query(User, Server, Query),
- Resources = ejabberd_sm:get_user_resources(User, Server),
- FResources =
- case Resources of
- [] ->
- [?CT("None")];
- _ ->
- [?XE("ul",
- lists:map(fun(R) ->
- ?LI([?C(R)])
- end, lists:sort(Resources)))]
- end,
- Password = ejabberd_auth:get_password_s(User, Server),
- FPassword = [?INPUT("password", "password", Password), ?C(" "),
- ?INPUTT("submit", "chpassword", "Change Password")],
- QueueLen = length(mnesia:dirty_read({offline_msg, US})),
- FQueueLen = [?AC("queue/",
- integer_to_list(QueueLen))],
- [?XC("h1", ?T("User ") ++ us_to_list(US))] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [?XCT("h3", "Connected Resources:")] ++ FResources ++
- [?XCT("h3", "Password:")] ++ FPassword ++
- [?XCT("h3", "Offline Messages:")] ++ FQueueLen ++
- [?XE("h3", [?ACT("roster/", "Roster")])] ++
- [?BR, ?INPUTT("submit", "removeuser", "Remove User")])].
-
-
-user_parse_query(User, Server, Query) ->
- case lists:keysearch("chpassword", 1, Query) of
- {value, _} ->
- case lists:keysearch("password", 1, Query) of
- {value, {_, undefined}} ->
- error;
- {value, {_, Password}} ->
- ejabberd_auth:set_password(User, Server, Password),
- ok;
- _ ->
- error
- end;
- _ ->
- case lists:keysearch("removeuser", 1, Query) of
- {value, _} ->
- ejabberd_auth:remove_user(User, Server),
- ok;
- false ->
- nothing
- end
- end.
-
-
-user_queue(User, Server, Query, Lang) ->
- US = {jlib:nodeprep(User), jlib:nameprep(Server)},
- Res = user_queue_parse_query(US, Query),
- Msgs = lists:keysort(3, mnesia:dirty_read({offline_msg, US})),
- FMsgs =
- lists:map(
- fun({offline_msg, _US, TimeStamp, _Expire, From, To,
- {xmlelement, Name, Attrs, Els}} = Msg) ->
- ID = jlib:encode_base64(binary_to_list(term_to_binary(Msg))),
- {{Year, Month, Day}, {Hour, Minute, Second}} =
- calendar:now_to_local_time(TimeStamp),
- Time = lists:flatten(
- io_lib:format(
- "~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w",
- [Year, Month, Day, Hour, Minute, Second])),
- SFrom = jlib:jid_to_string(From),
- STo = jlib:jid_to_string(To),
- Attrs2 = jlib:replace_from_to_attrs(SFrom, STo, Attrs),
- Packet = jlib:remove_attr(
- "jeai-id", {xmlelement, Name, Attrs2, Els}),
- FPacket = pretty_print(Packet),
- ?XE("tr",
- [?XAE("td", [{"class", "valign"}], [?INPUT("checkbox", "selected", ID)]),
- ?XAC("td", [{"class", "valign"}], Time),
- ?XAC("td", [{"class", "valign"}], SFrom),
- ?XAC("td", [{"class", "valign"}], STo),
- ?XAE("td", [{"class", "valign"}], [?XC("pre", FPacket)])]
- )
- end, Msgs),
- [?XC("h1", io_lib:format(?T("~s's Offline Messages Queue"),
- [us_to_list(US)]))] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [?XE("table",
- [?XE("thead",
- [?XE("tr",
- [?X("td"),
- ?XCT("td", "Time"),
- ?XCT("td", "From"),
- ?XCT("td", "To"),
- ?XCT("td", "Packet")
- ])]),
- ?XE("tbody",
- if
- FMsgs == [] ->
- [?XE("tr",
- [?XAC("td", [{"colspan", "4"}], " ")]
- )];
- true ->
- FMsgs
- end
- )]),
- ?BR,
- ?INPUTT("submit", "delete", "Delete Selected")
- ])].
-
-user_queue_parse_query(US, Query) ->
- case lists:keysearch("delete", 1, Query) of
- {value, _} ->
- Msgs = lists:keysort(3, mnesia:dirty_read({offline_msg, US})),
- F = fun() ->
- lists:foreach(
- fun(Msg) ->
- ID = jlib:encode_base64(
- binary_to_list(term_to_binary(Msg))),
- case lists:member({"selected", ID}, Query) of
- true ->
- mnesia:delete_object(Msg);
- false ->
- ok
- end
- end, Msgs)
- end,
- mnesia:transaction(F),
- ok;
- false ->
- nothing
- end.
-
-
-
--record(roster, {usj,
- us,
- jid,
- name = "",
- subscription = none,
- ask = none,
- groups = [],
- xattrs = [],
- xs = []}).
-
-ask_to_pending(subscribe) -> out;
-ask_to_pending(unsubscribe) -> none;
-ask_to_pending(Ask) -> Ask.
-
-
-user_roster(User, Server, Query, Lang, Admin) ->
- US = {jlib:nodeprep(User), jlib:nameprep(Server)},
- Items1 = mnesia:dirty_index_read(roster, US, #roster.us),
- Res = user_roster_parse_query(User, Server, Items1, Query, Admin),
- Items = mnesia:dirty_index_read(roster, US, #roster.us),
- SItems = lists:sort(Items),
- FItems =
- case SItems of
- [] ->
- [?CT("None")];
- _ ->
- [?XE("table",
- [?XE("thead",
- [?XE("tr",
- [?XCT("td", "Jabber ID"),
- ?XCT("td", "Nickname"),
- ?XCT("td", "Subscription"),
- ?XCT("td", "Pending"),
- ?XCT("td", "Groups")
- ])]),
- ?XE("tbody",
- lists:map(
- fun(R) ->
- Groups =
- lists:flatmap(
- fun(Group) ->
- [?C(Group), ?BR]
- end, R#roster.groups),
- Pending = ask_to_pending(R#roster.ask),
- ?XE("tr",
- [?XAC("td", [{"class", "valign"}],
- jlib:jid_to_string(R#roster.jid)),
- ?XAC("td", [{"class", "valign"}],
- R#roster.name),
- ?XAC("td", [{"class", "valign"}],
- atom_to_list(R#roster.subscription)),
- ?XAC("td", [{"class", "valign"}],
- atom_to_list(Pending)),
- ?XAE("td", [{"class", "valign"}], Groups),
- if
- Pending == in ->
- ?XAE("td", [{"class", "valign"}],
- [?INPUTT("submit",
- "validate" ++
- term_to_id(R#roster.jid),
- "Validate")]);
- true ->
- ?X("td")
- end,
- ?XAE("td", [{"class", "valign"}],
- [?INPUTT("submit",
- "remove" ++
- term_to_id(R#roster.jid),
- "Remove")])])
- end, SItems))])]
- end,
- [?XC("h1", ?T("Roster of ") ++ us_to_list(US))] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- FItems ++
- [?P,
- ?INPUT("text", "newjid", ""), ?C(" "),
- ?INPUTT("submit", "addjid", "Add Jabber ID")
- ])].
-
-user_roster_parse_query(User, Server, Items, Query, Admin) ->
- case lists:keysearch("addjid", 1, Query) of
- {value, _} ->
- case lists:keysearch("newjid", 1, Query) of
- {value, {_, undefined}} ->
- error;
- {value, {_, SJID}} ->
- case jlib:string_to_jid(SJID) of
- JID when is_record(JID, jid) ->
- user_roster_subscribe_jid(User, Server, JID),
- ok;
- error ->
- error
- end;
- false ->
- error
- end;
- false ->
- case catch user_roster_item_parse_query(
- User, Server, Items, Query) of
- submitted ->
- ok;
- {'EXIT', _Reason} ->
- error;
- _ ->
- nothing
- end
- end.
-
-
-user_roster_subscribe_jid(User, Server, JID) ->
- mod_roster:out_subscription(User, Server, JID, subscribe),
- UJID = jlib:make_jid(User, Server, ""),
- ejabberd_router:route(
- UJID, JID, {xmlelement, "presence", [{"type", "subscribe"}], []}).
-
-user_roster_item_parse_query(User, Server, Items, Query) ->
- lists:foreach(
- fun(R) ->
- JID = R#roster.jid,
- case lists:keysearch(
- "validate" ++ term_to_id(JID), 1, Query) of
- {value, _} ->
- JID1 = jlib:make_jid(JID),
- mod_roster:out_subscription(
- User, Server, JID1, subscribed),
- UJID = jlib:make_jid(User, Server, ""),
- ejabberd_router:route(
- UJID, JID1, {xmlelement, "presence",
- [{"type", "subscribed"}], []}),
- throw(submitted);
- false ->
- case lists:keysearch(
- "remove" ++ term_to_id(JID), 1, Query) of
- {value, _} ->
- UJID = jlib:make_jid(User, Server, ""),
- mod_roster:process_iq(
- UJID, UJID,
- #iq{type = set,
- sub_el = {xmlelement, "query",
- [{"xmlns", ?NS_ROSTER}],
- [{xmlelement, "item",
- [{"jid", jlib:jid_to_string(JID)},
- {"subscription", "remove"}],
- []}]}}),
- throw(submitted);
- false ->
- ok
- end
-
- end
- end, Items),
- nothing.
-
-
-list_last_activity(Host, Lang, Integral, Period) ->
- {MegaSecs, Secs, _MicroSecs} = now(),
- TimeStamp = MegaSecs * 1000000 + Secs,
- case Period of
- "all" ->
- TS = 0,
- Days = infinity;
- "year" ->
- TS = TimeStamp - 366 * 86400,
- Days = 366;
- _ ->
- TS = TimeStamp - 31 * 86400,
- Days = 31
- end,
- case catch mnesia:dirty_select(
- last_activity, [{{last_activity, {'_', Host}, '$1', '_'},
- [{'>', '$1', TS}],
- [{'trunc', {'/',
- {'-', TimeStamp, '$1'},
- 86400}}]}]) of
- {'EXIT', _Reason} ->
- [];
- Vals ->
- Hist = histogram(Vals, Integral),
- if
- Hist == [] ->
- [?CT("No Data")];
- true ->
- Left = if
- Days == infinity ->
- 0;
- true ->
- Days - length(Hist)
- end,
- Tail = if
- Integral ->
- lists:duplicate(Left, lists:last(Hist));
- true ->
- lists:duplicate(Left, 0)
- end,
- Max = lists:max(Hist),
- [?XAE("ol",
- [{"id", "lastactivity"}, {"start", "0"}],
- [?XAE("li",
- [{"style",
- "width:" ++ integer_to_list(
- trunc(90 * V / Max)) ++ "%;"}],
- [{xmlcdata, integer_to_list(V)}])
- || V <- Hist ++ Tail])]
- end
- end.
-
-histogram(Values, Integral) ->
- histogram(lists:sort(Values), Integral, 0, 0, []).
-
-histogram([H | T], Integral, Current, Count, Hist) when Current == H ->
- histogram(T, Integral, Current, Count + 1, Hist);
-
-histogram([H | _] = Values, Integral, Current, Count, Hist) when Current < H ->
- if
- Integral ->
- histogram(Values, Integral, Current + 1, Count, [Count | Hist]);
- true ->
- histogram(Values, Integral, Current + 1, 0, [Count | Hist])
- end;
-
-histogram([], _Integral, _Current, Count, Hist) ->
- if
- Count > 0 ->
- lists:reverse([Count | Hist]);
- true ->
- lists:reverse(Hist)
- end.
-
-
-get_nodes(Lang) ->
- RunningNodes = mnesia:system_info(running_db_nodes),
- StoppedNodes = lists:usort(mnesia:system_info(db_nodes) ++
- mnesia:system_info(extra_db_nodes)) --
- RunningNodes,
- FRN = if
- RunningNodes == [] ->
- ?CT("None");
- true ->
- ?XE("ul",
- lists:map(
- fun(N) ->
- S = atom_to_list(N),
- ?LI([?AC("../node/" ++ S ++ "/", S)])
- end, lists:sort(RunningNodes)))
- end,
- FSN = if
- StoppedNodes == [] ->
- ?CT("None");
- true ->
- ?XE("ul",
- lists:map(
- fun(N) ->
- S = atom_to_list(N),
- ?LI([?C(S)])
- end, lists:sort(StoppedNodes)))
- end,
- [?XCT("h1", "Nodes"),
- ?XCT("h3", "Running Nodes"),
- FRN,
- ?XCT("h3", "Stopped Nodes"),
- FSN].
-
-search_running_node(SNode) ->
- search_running_node(SNode, mnesia:system_info(running_db_nodes)).
-
-search_running_node(_, []) ->
- false;
-search_running_node(SNode, [Node | Nodes]) ->
- case atom_to_list(Node) of
- SNode ->
- Node;
- _ ->
- search_running_node(SNode, Nodes)
- end.
-
-get_node(global, Node, [], Query, Lang) ->
- Res = node_parse_query(Node, Query),
- [?XC("h1", ?T("Node ") ++ atom_to_list(Node))] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XE("ul",
- [?LI([?ACT("db/", "Database")]),
- ?LI([?ACT("backup/", "Backup")]),
- ?LI([?ACT("ports/", "Listened Ports")]),
- ?LI([?ACT("stats/", "Statistics")]),
- ?LI([?ACT("update/", "Update")])
- ]),
- ?XAE("form", [{"action", ""}, {"method", "post"}],
- [?INPUTT("submit", "restart", "Restart"),
- ?C(" "),
- ?INPUTT("submit", "stop", "Stop")])
- ];
-
-get_node(Host, Node, [], Query, Lang) ->
- [?XC("h1", ?T("Node ") ++ atom_to_list(Node)),
- ?XE("ul",
- [?LI([?ACT("modules/", "Modules")])])
- ];
-
-get_node(global, Node, ["db"], Query, Lang) ->
- case rpc:call(Node, mnesia, system_info, [tables]) of
- {badrpc, _Reason} ->
- [?XCT("h1", "RPC Call Error")];
- Tables ->
- Res = node_db_parse_query(Node, Tables, Query),
- STables = lists:sort(Tables),
- Rows = lists:map(
- fun(Table) ->
- STable = atom_to_list(Table),
- TInfo =
- case rpc:call(Node,
- mnesia,
- table_info,
- [Table, all]) of
- {badrpc, _} ->
- [];
- I ->
- I
- end,
- {Type, Size, Memory} =
- case {lists:keysearch(storage_type, 1, TInfo),
- lists:keysearch(size, 1, TInfo),
- lists:keysearch(memory, 1, TInfo)} of
- {{value, {storage_type, T}},
- {value, {size, S}},
- {value, {memory, M}}} ->
- {T, S, M};
- _ ->
- {unknown, 0, 0}
- end,
- ?XE("tr",
- [?XC("td", STable),
- ?XE("td", [db_storage_select(
- STable, Type, Lang)]),
- ?XAC("td", [{"class", "alignright"}],
- integer_to_list(Size)),
- ?XAC("td", [{"class", "alignright"}],
- integer_to_list(Memory))
- ])
- end, STables),
- [?XC("h1", ?T("Database Tables at ") ++ atom_to_list(Node))] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [?XAE("table", [],
- [?XE("thead",
- [?XE("tr",
- [?XCT("td", "Name"),
- ?XCT("td", "Storage Type"),
- ?XCT("td", "Size"),
- ?XCT("td", "Memory")
- ])]),
- ?XE("tbody",
- Rows ++
- [?XE("tr",
- [?XAE("td", [{"colspan", "4"},
- {"class", "alignright"}],
- [?INPUTT("submit", "submit",
- "Submit")])
- ])]
- )])])]
- end;
-
-get_node(global, Node, ["backup"], Query, Lang) ->
- Res = node_backup_parse_query(Node, Query),
- [?XC("h1", ?T("Backup of ") ++ atom_to_list(Node)),
- ?XCT("p", "Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately."),
- ?XAE("form", [{"action", ""}, {"method", "post"}],
- [?XAE("table", [],
- [?XE("tbody",
- [?XE("tr",
- [?XCT("td", "Store binary backup:"),
- ?XE("td", [?INPUT("text", "storepath",
- "ejabberd.backup")]),
- ?XE("td", [?INPUTT("submit", "store",
- "OK")])
- ]),
- ?XE("tr",
- [?XCT("td", "Restore binary backup immediately:"),
- ?XE("td", [?INPUT("text", "restorepath",
- "ejabberd.backup")]),
- ?XE("td", [?INPUTT("submit", "restore",
- "OK")])
- ]),
- ?XE("tr",
- [?XCT("td",
- "Restore binary backup after next ejabberd restart (requires less memory):"),
- ?XE("td", [?INPUT("text", "fallbackpath",
- "ejabberd.backup")]),
- ?XE("td", [?INPUTT("submit", "fallback",
- "OK")])
- ]),
- ?XE("tr",
- [?XCT("td", "Store plain text backup:"),
- ?XE("td", [?INPUT("text", "dumppath",
- "ejabberd.dump")]),
- ?XE("td", [?INPUTT("submit", "dump",
- "OK")])
- ]),
- ?XE("tr",
- [?XCT("td", "Restore plain text backup immediately:"),
- ?XE("td", [?INPUT("text", "loadpath",
- "ejabberd.dump")]),
- ?XE("td", [?INPUTT("submit", "load",
- "OK")])
- ])
- ])
- ])])];
-
-get_node(global, Node, ["ports"], Query, Lang) ->
- Ports = rpc:call(Node, ejabberd_config, get_local_option, [listen]),
- Res = case catch node_ports_parse_query(Node, Ports, Query) of
- submitted ->
- ok;
- {'EXIT', _Reason} ->
- error;
- _ ->
- nothing
- end,
- NewPorts = lists:sort(
- rpc:call(Node, ejabberd_config, get_local_option, [listen])),
- [?XC("h1", ?T("Listened Ports at ") ++ atom_to_list(Node))] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [node_ports_to_xhtml(NewPorts, Lang)])
- ];
-
-get_node(Host, Node, ["modules"], Query, Lang) when is_list(Host) ->
- Modules = rpc:call(Node, gen_mod, loaded_modules_with_opts, [Host]),
- Res = case catch node_modules_parse_query(Host, Node, Modules, Query) of
- submitted ->
- ok;
- {'EXIT', Reason} ->
- ?INFO_MSG("~p~n", [Reason]),
- error;
- _ ->
- nothing
- end,
- NewModules = lists:sort(
- rpc:call(Node, gen_mod, loaded_modules_with_opts, [Host])),
- [?XC("h1", ?T("Modules at ") ++ atom_to_list(Node))] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [node_modules_to_xhtml(NewModules, Lang)])
- ];
-
-get_node(global, Node, ["stats"], Query, Lang) ->
- UpTime = rpc:call(Node, erlang, statistics, [wall_clock]),
- UpTimeS = io_lib:format("~.3f", [element(1, UpTime)/1000]),
- CPUTime = rpc:call(Node, erlang, statistics, [runtime]),
- CPUTimeS = io_lib:format("~.3f", [element(1, CPUTime)/1000]),
- Users = length(
- rpc:call(Node, ejabberd_sm, dirty_get_my_sessions_list, [])),
- TransactionsCommited =
- rpc:call(Node, mnesia, system_info, [transaction_commits]),
- TransactionsAborted =
- rpc:call(Node, mnesia, system_info, [transaction_failures]),
- TransactionsRestarted =
- rpc:call(Node, mnesia, system_info, [transaction_restarts]),
- TransactionsLogged =
- rpc:call(Node, mnesia, system_info, [transaction_log_writes]),
-
- [?XC("h1", io_lib:format(?T("Statistics of ~p"), [Node])),
- ?XAE("table", [],
- [?XE("tbody",
- [?XE("tr", [?XCT("td", "Uptime:"),
- ?XAC("td", [{"class", "alignright"}],
- UpTimeS)]),
- ?XE("tr", [?XCT("td", "CPU Time:"),
- ?XAC("td", [{"class", "alignright"}],
- CPUTimeS)]),
- ?XE("tr", [?XCT("td", "Authenticated Users:"),
- ?XAC("td", [{"class", "alignright"}],
- integer_to_list(Users))]),
- ?XE("tr", [?XCT("td", "Transactions Commited:"),
- ?XAC("td", [{"class", "alignright"}],
- integer_to_list(TransactionsCommited))]),
- ?XE("tr", [?XCT("td", "Transactions Aborted:"),
- ?XAC("td", [{"class", "alignright"}],
- integer_to_list(TransactionsAborted))]),
- ?XE("tr", [?XCT("td", "Transactions Restarted:"),
- ?XAC("td", [{"class", "alignright"}],
- integer_to_list(TransactionsRestarted))]),
- ?XE("tr", [?XCT("td", "Transactions Logged:"),
- ?XAC("td", [{"class", "alignright"}],
- integer_to_list(TransactionsLogged))])
- ])
- ])];
-
-get_node(global, Node, ["update"], Query, Lang) ->
- rpc:call(Node, code, purge, [ejabberd_update]),
- Res = node_update_parse_query(Node, Query),
- rpc:call(Node, code, load_file, [ejabberd_update]),
- {ok, Dir, UpdatedBeams, Script, LowLevelScript, Check} =
- rpc:call(Node, ejabberd_update, update_info, []),
- Mods =
- case UpdatedBeams of
- [] ->
- ?CT("None");
- _ ->
- ?XE("ul",
- [?LI([?C(atom_to_list(Beam))]) ||
- Beam <- UpdatedBeams])
- end,
- FmtScript = ?XC("pre", io_lib:format("~p", [Script])),
- FmtLowLevelScript = ?XC("pre", io_lib:format("~p", [LowLevelScript])),
- [?XC("h1", ?T("Update ") ++ atom_to_list(Node))] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [?INPUTT("submit", "update", "Update"),
- ?XCT("h2", "Update plan"),
- ?XCT("h3", "Updated modules"), Mods,
- ?XCT("h3", "Update script"), FmtScript,
- ?XCT("h3", "Low level update script"), FmtLowLevelScript,
- ?XCT("h3", "Script check"), ?C(atom_to_list(Check))])
- ];
-
-get_node(Host, Node, NPath, Query, Lang) ->
- [?XCT("h1", "Not Found")].
-
-
-node_parse_query(Node, Query) ->
- case lists:keysearch("restart", 1, Query) of
- {value, _} ->
- case rpc:call(Node, init, restart, []) of
- {badrpc, _Reason} ->
- error;
- _ ->
- ok
- end;
- _ ->
- case lists:keysearch("stop", 1, Query) of
- {value, _} ->
- case rpc:call(Node, init, stop, []) of
- {badrpc, _Reason} ->
- error;
- _ ->
- ok
- end;
- _ ->
- nothing
- end
- end.
-
-
-db_storage_select(ID, Opt, Lang) ->
- ?XAE("select", [{"name", "table" ++ ID}],
- lists:map(
- fun({O, Desc}) ->
- Sel = if
- O == Opt -> [{"selected", "selected"}];
- true -> []
- end,
- ?XACT("option",
- Sel ++ [{"value", atom_to_list(O)}],
- Desc)
- end, [{ram_copies, "RAM copy"},
- {disc_copies, "RAM and disc copy"},
- {disc_only_copies, "Disc only copy"},
- {unknown, "Remote copy"}])).
-
-node_db_parse_query(Node, Tables, Query) ->
- lists:foreach(
- fun(Table) ->
- STable = atom_to_list(Table),
- case lists:keysearch("table" ++ STable, 1, Query) of
- {value, {_, SType}} ->
- Type = case SType of
- "unknown" -> unknown;
- "ram_copies" -> ram_copies;
- "disc_copies" -> disc_copies;
- "disc_only_copies" -> disc_only_copies;
- _ -> false
- end,
- if
- Type == false ->
- ok;
- Type == unknown ->
- mnesia:del_table_copy(Table, Node);
- true ->
- case mnesia:add_table_copy(Table, Node, Type) of
- {aborted, _} ->
- mnesia:change_table_copy_type(
- Table, Node, Type);
- _ ->
- ok
- end
- end;
- _ ->
- ok
- end
- end, Tables),
- ok.
-
-node_backup_parse_query(Node, Query) ->
- lists:foldl(
- fun(Action, nothing) ->
- case lists:keysearch(Action, 1, Query) of
- {value, _} ->
- case lists:keysearch(Action ++ "path", 1, Query) of
- {value, {_, Path}} ->
- Res =
- case Action of
- "store" ->
- rpc:call(Node, mnesia,
- backup, [Path]);
- "restore" ->
- rpc:call(Node, ejabberd_admin,
- restore, [Path]);
- "fallback" ->
- rpc:call(Node, mnesia,
- install_fallback, [Path]);
- "dump" ->
- rpc:call(Node, mnesia,
- dump_to_textfile, [Path]);
- "load" ->
- rpc:call(Node, mnesia,
- load_textfile, [Path])
- end,
- case Res of
- {error, _Reason} ->
- error;
- {badrpc, _Reason} ->
- error;
- _ ->
- ok
- end;
- _ ->
- error
- end;
- _ ->
- nothing
- end;
- (_Action, Res) ->
- Res
- end, nothing, ["store", "restore", "fallback", "dump", "load"]).
-
-
-node_ports_to_xhtml(Ports, Lang) ->
- ?XAE("table", [],
- [?XE("thead",
- [?XE("tr",
- [?XCT("td", "Port"),
- ?XCT("td", "Module"),
- ?XCT("td", "Options")
- ])]),
- ?XE("tbody",
- lists:map(
- fun({Port, Module, Opts} = E) ->
- SPort = integer_to_list(Port),
- SModule = atom_to_list(Module),
- ID = term_to_id(E),
- ?XE("tr",
- [?XC("td", SPort),
- ?XE("td", [?INPUT("text", "module" ++ SPort,
- SModule)]),
- ?XE("td", [?INPUTS("text", "opts" ++ SPort,
- term_to_string(Opts), "40")]),
- ?XE("td", [?INPUTT("submit", "add" ++ SPort,
- "Update")]),
- ?XE("td", [?INPUTT("submit", "delete" ++ SPort,
- "Delete")])
- ]
- )
- end, Ports) ++
- [?XE("tr",
- [?XE("td", [?INPUTS("text", "portnew", "", "6")]),
- ?XE("td", [?INPUT("text", "modulenew", "")]),
- ?XE("td", [?INPUTS("text", "optsnew", "", "40")]),
- ?XAE("td", [{"colspan", "2"}],
- [?INPUTT("submit", "addnew", "Add New")])
- ]
- )]
- )]).
-
-
-node_ports_parse_query(Node, Ports, Query) ->
- lists:foreach(
- fun({Port, _Module1, _Opts1}) ->
- SPort = integer_to_list(Port),
- case lists:keysearch("add" ++ SPort, 1, Query) of
- {value, _} ->
- {{value, {_, SModule}}, {value, {_, SOpts}}} =
- {lists:keysearch("module" ++ SPort, 1, Query),
- lists:keysearch("opts" ++ SPort, 1, Query)},
- Module = list_to_atom(SModule),
- {ok, Tokens, _} = erl_scan:string(SOpts ++ "."),
- {ok, Opts} = erl_parse:parse_term(Tokens),
- rpc:call(Node, ejabberd_listener, delete_listener, [Port]),
- rpc:call(Node, ejabberd_listener, add_listener, [Port, Module, Opts]),
- throw(submitted);
- _ ->
- case lists:keysearch("delete" ++ SPort, 1, Query) of
- {value, _} ->
- rpc:call(Node, ejabberd_listener, delete_listener, [Port]),
- throw(submitted);
- _ ->
- ok
- end
- end
- end, Ports),
- case lists:keysearch("addnew", 1, Query) of
- {value, _} ->
- {{value, {_, SPort}},
- {value, {_, SModule}},
- {value, {_, SOpts}}} =
- {lists:keysearch("portnew", 1, Query),
- lists:keysearch("modulenew", 1, Query),
- lists:keysearch("optsnew", 1, Query)},
- Port = list_to_integer(SPort),
- Module = list_to_atom(SModule),
- {ok, Tokens, _} = erl_scan:string(SOpts ++ "."),
- {ok, Opts} = erl_parse:parse_term(Tokens),
- rpc:call(Node, ejabberd_listener, add_listener, [Port, Module, Opts]),
- throw(submitted);
- _ ->
- ok
- end.
-
-node_modules_to_xhtml(Modules, Lang) ->
- ?XAE("table", [],
- [?XE("thead",
- [?XE("tr",
- [?XCT("td", "Module"),
- ?XCT("td", "Options")
- ])]),
- ?XE("tbody",
- lists:map(
- fun({Module, Opts} = E) ->
- SModule = atom_to_list(Module),
- ID = term_to_id(E),
- ?XE("tr",
- [?XC("td", SModule),
- ?XE("td", [?INPUTS("text", "opts" ++ SModule,
- term_to_string(Opts), "40")]),
- ?XE("td", [?INPUTT("submit", "restart" ++ SModule,
- "Restart")]),
- ?XE("td", [?INPUTT("submit", "stop" ++ SModule,
- "Stop")])
- ]
- )
- end, Modules) ++
- [?XE("tr",
- [?XE("td", [?INPUT("text", "modulenew", "")]),
- ?XE("td", [?INPUTS("text", "optsnew", "", "40")]),
- ?XAE("td", [{"colspan", "2"}],
- [?INPUTT("submit", "start", "Start")])
- ]
- )]
- )]).
-
-node_modules_parse_query(Host, Node, Modules, Query) ->
- lists:foreach(
- fun({Module, _Opts1}) ->
- SModule = atom_to_list(Module),
- case lists:keysearch("restart" ++ SModule, 1, Query) of
- {value, _} ->
- {value, {_, SOpts}} =
- lists:keysearch("opts" ++ SModule, 1, Query),
- {ok, Tokens, _} = erl_scan:string(SOpts ++ "."),
- {ok, Opts} = erl_parse:parse_term(Tokens),
- rpc:call(Node, gen_mod, stop_module, [Host, Module]),
- rpc:call(Node, gen_mod, start_module, [Host, Module, Opts]),
- throw(submitted);
- _ ->
- case lists:keysearch("stop" ++ SModule, 1, Query) of
- {value, _} ->
- rpc:call(Node, gen_mod, stop_module, [Host, Module]),
- throw(submitted);
- _ ->
- ok
- end
- end
- end, Modules),
- case lists:keysearch("start", 1, Query) of
- {value, _} ->
- {{value, {_, SModule}},
- {value, {_, SOpts}}} =
- {lists:keysearch("modulenew", 1, Query),
- lists:keysearch("optsnew", 1, Query)},
- Module = list_to_atom(SModule),
- {ok, Tokens, _} = erl_scan:string(SOpts ++ "."),
- {ok, Opts} = erl_parse:parse_term(Tokens),
- rpc:call(Node, gen_mod, start_module, [Host, Module, Opts]),
- throw(submitted);
- _ ->
- ok
- end.
-
-
-node_update_parse_query(Node, Query) ->
- case lists:keysearch("update", 1, Query) of
- {value, _} ->
- case rpc:call(Node, ejabberd_update, update, []) of
- {ok, _} ->
- ok;
- {error, Error} ->
- ?ERROR_MSG("~p~n", [Error]);
- {badrpc, Error} ->
- ?ERROR_MSG("~p~n", [Error])
- end;
- _ ->
- nothing
- end.
-
-
-pretty_print(El) ->
- lists:flatten(pretty_print(El, "")).
-
-pretty_print({xmlcdata, CData}, Prefix) ->
- [Prefix, CData, $\n];
-pretty_print({xmlelement, Name, Attrs, Els}, Prefix) ->
- [Prefix, $<, Name,
- case Attrs of
- [] ->
- [];
- [{Attr, Val} | RestAttrs] ->
- AttrPrefix = [Prefix,
- string:copies(" ", length(Name) + 2)],
- [$\s, Attr, $=, $', xml:crypt(Val), $' |
- lists:map(fun({Attr1, Val1}) ->
- [$\n, AttrPrefix,
- Attr1, $=, $', xml:crypt(Val1), $']
- end, RestAttrs)]
- end,
- if
- Els == [] ->
- "/>\n";
- true ->
- OnlyCData = lists:all(fun({xmlcdata, _}) -> true;
- ({xmlelement, _, _, _}) -> false
- end, Els),
- if
- OnlyCData ->
- [$>,
- xml:get_cdata(Els),
- $<, $/, Name, $>, $\n
- ];
- true ->
- [$>, $\n,
- lists:map(fun(E) ->
- pretty_print(E, [Prefix, " "])
- end, Els),
- Prefix, $<, $/, Name, $>, $\n
- ]
- end
- end].
-
-
-list_shared_roster_groups(Host, Query, Lang) ->
- Res = list_sr_groups_parse_query(Host, Query),
- SRGroups = mod_shared_roster:list_groups(Host),
- FGroups =
- ?XAE("table", [],
- [?XE("tbody",
- lists:map(
- fun(Group) ->
- ?XE("tr",
- [?XE("td", [?INPUT("checkbox", "selected",
- Group)]),
- ?XE("td", [?AC(Group ++ "/", Group)])
- ]
- )
- end, lists:sort(SRGroups)) ++
- [?XE("tr",
- [?X("td"),
- ?XE("td", [?INPUT("text", "namenew", "")]),
- ?XE("td", [?INPUTT("submit", "addnew", "Add New")])
- ]
- )]
- )]),
- [?XC("h1", ?T("Shared Roster Groups"))] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [FGroups,
- ?BR,
- ?INPUTT("submit", "delete", "Delete Selected")
- ])
- ].
-
-list_sr_groups_parse_query(Host, Query) ->
- case lists:keysearch("addnew", 1, Query) of
- {value, _} ->
- list_sr_groups_parse_addnew(Host, Query);
- _ ->
- case lists:keysearch("delete", 1, Query) of
- {value, _} ->
- list_sr_groups_parse_delete(Host, Query);
- _ ->
- nothing
- end
- end.
-
-list_sr_groups_parse_addnew(Host, Query) ->
- case lists:keysearch("namenew", 1, Query) of
- {value, {_, Group}} when Group /= "" ->
- mod_shared_roster:create_group(Host, Group),
- ok;
- _ ->
- error
- end.
-
-list_sr_groups_parse_delete(Host, Query) ->
- SRGroups = mod_shared_roster:list_groups(Host),
- lists:foreach(
- fun(Group) ->
- case lists:member({"selected", Group}, Query) of
- true ->
- mod_shared_roster:delete_group(Host, Group);
- _ ->
- ok
- end
- end, SRGroups),
- ok.
-
-
-shared_roster_group(Host, Group, Query, Lang) ->
- Res = shared_roster_group_parse_query(Host, Group, Query),
- GroupOpts = mod_shared_roster:get_group_opts(Host, Group),
- Name = get_opt(GroupOpts, name, ""),
- Description = get_opt(GroupOpts, description, ""),
- AllUsers = get_opt(GroupOpts, all_users, false),
- Disabled = false,
- DisplayedGroups = get_opt(GroupOpts, displayed_groups, []),
- Members = mod_shared_roster:get_group_explicit_users(Host, Group),
- FMembers =
- if
- AllUsers ->
- "@all@\n";
- true ->
- []
- end ++ [[us_to_list(Member), $\n] || Member <- Members],
- FDisplayedGroups = [[DG, $\n] || DG <- DisplayedGroups],
- FGroup =
- ?XAE("table", [],
- [?XE("tbody",
- [?XE("tr",
- [?XCT("td", "Name:"),
- ?XE("td", [?INPUT("text", "name", Name)])
- ]
- ),
- ?XE("tr",
- [?XCT("td", "Description:"),
- ?XE("td", [?XAC("textarea", [{"name", "description"},
- {"rows", "3"},
- {"cols", "20"}],
- Description)])
- ]
- ),
- ?XE("tr",
- [?XCT("td", "Members:"),
- ?XE("td", [?XAC("textarea", [{"name", "members"},
- {"rows", "3"},
- {"cols", "20"}],
- FMembers)])
- ]
- ),
- ?XE("tr",
- [?XCT("td", "Displayed Groups:"),
- ?XE("td", [?XAC("textarea", [{"name", "dispgroups"},
- {"rows", "3"},
- {"cols", "20"}],
- FDisplayedGroups)])
- ]
- )]
- )]),
- [?XC("h1", ?T("Shared Roster Groups"))] ++
- [?XC("h2", ?T("Group ") ++ Group)] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- [FGroup,
- ?BR,
- ?INPUTT("submit", "submit", "Submit")
- ])
- ].
-
-shared_roster_group_parse_query(Host, Group, Query) ->
- case lists:keysearch("submit", 1, Query) of
- {value, _} ->
- {value, {_, Name}} = lists:keysearch("name", 1, Query),
- {value, {_, Description}} = lists:keysearch("description", 1, Query),
- {value, {_, SMembers}} = lists:keysearch("members", 1, Query),
- {value, {_, SDispGroups}} = lists:keysearch("dispgroups", 1, Query),
- NameOpt =
- if
- Name == "" -> [];
- true -> [{name, Name}]
- end,
- DescriptionOpt =
- if
- Description == "" -> [];
- true -> [{description, Description}]
- end,
- DispGroups = string:tokens(SDispGroups, "\r\n"),
- DispGroupsOpt =
- if
- DispGroups == [] -> [];
- true -> [{displayed_groups, DispGroups}]
- end,
-
- OldMembers = mod_shared_roster:get_group_explicit_users(
- Host, Group),
- SJIDs = string:tokens(SMembers, ", \r\n"),
- NewMembers =
- lists:foldl(
- fun(_SJID, error) -> error;
- (SJID, USs) ->
- case SJID of
- "@all@" ->
- USs;
- _ ->
- case jlib:string_to_jid(SJID) of
- JID when is_record(JID, jid) ->
- [{JID#jid.luser, JID#jid.lserver} | USs];
- error ->
- error
- end
- end
- end, [], SJIDs),
- AllUsersOpt =
- case lists:member("@all@", SJIDs) of
- true -> [{all_users, true}];
- false -> []
- end,
-
- mod_shared_roster:set_group_opts(
- Host, Group,
- NameOpt ++ DispGroupsOpt ++ DescriptionOpt ++ AllUsersOpt),
-
- if
- NewMembers == error -> error;
- true ->
- AddedMembers = NewMembers -- OldMembers,
- RemovedMembers = OldMembers -- NewMembers,
- lists:foreach(
- fun(US) ->
- mod_shared_roster:remove_user_from_group(
- Host, US, Group)
- end, RemovedMembers),
- lists:foreach(
- fun(US) ->
- mod_shared_roster:add_user_to_group(
- Host, US, Group)
- end, AddedMembers),
- ok
- end;
- _ ->
- nothing
- end.
-
-
-get_opt(Opts, Opt, Default) ->
- case lists:keysearch(Opt, 1, Opts) of
- {value, {_, Val}} ->
- Val;
- false ->
- Default
- end.
-
-
-url_func({user_diapason, From, To}) ->
- integer_to_list(From) ++ "-" ++ integer_to_list(To) ++ "/";
-url_func({users_queue, Prefix, User, Server}) ->
- Prefix ++ "user/" ++ User ++ "/queue/";
-url_func({user, Prefix, User, Server}) ->
- Prefix ++ "user/" ++ User ++ "/".
-
diff --git a/ejabberd-1.1.2/src/win32/CheckReqs.ini b/ejabberd-1.1.2/src/win32/CheckReqs.ini
deleted file mode 100644
index 35875f82d..000000000
--- a/ejabberd-1.1.2/src/win32/CheckReqs.ini
+++ /dev/null
@@ -1,20 +0,0 @@
-[Settings]
-NumFields=2
-
-[Field 1]
-Type=label
-Left=0
-Right=-1
-Top=10
-Bottom=70
-Text="Erlang OTP R10B-7 (version 5.4.9) or newer is required to install Ejabberd.\r\n\r\nIt is not found on your computer.\r\n\r\nPlease install Erlang OTP R10B-7 or newer before installing Ejabberd.\r\n\r\nIts installer can be downloaded from"
-
-[Field 2]
-Type=link
-Left=0
-Right=-1
-Top=74
-Bottom=88
-State=http://www.erlang.org/download.html
-Text=http://www.erlang.org/download.html
-
diff --git a/ejabberd-1.1.2/src/win32/CheckReqs1.ini b/ejabberd-1.1.2/src/win32/CheckReqs1.ini
deleted file mode 100644
index 76b8a9009..000000000
--- a/ejabberd-1.1.2/src/win32/CheckReqs1.ini
+++ /dev/null
@@ -1,28 +0,0 @@
-[Settings]
-NumFields=3
-
-[Field 1]
-Type=label
-Left=0
-Right=-1
-Top=10
-Bottom=70
-Text="OpenSLL 0.9.7i or newer is not found on your computer.\r\n\r\nTo use SSL and TLS encryption you need an SSL certificate. You can create a selfsigned certificate with OpenSSL.\r\n\r\nOpenSLL installer can be downloaded from"
-
-[Field 2]
-Type=link
-Left=0
-Right=-1
-Top=74
-Bottom=88
-State=http://www.slproweb.com/products/Win32OpenSSL.html
-Text=http://www.slproweb.com/products/Win32OpenSSL.html
-
-[Field 3]
-Type=label
-Left=0
-Right=-1
-Top=93
-Bottom=-10
-Text="If you want to continue installing Ejabberd anyway, click Next."
-
diff --git a/ejabberd-1.1.2/src/win32/CheckReqs1H.ini b/ejabberd-1.1.2/src/win32/CheckReqs1H.ini
deleted file mode 100644
index 36076640d..000000000
--- a/ejabberd-1.1.2/src/win32/CheckReqs1H.ini
+++ /dev/null
@@ -1,29 +0,0 @@
-[Settings]
-NumFields=3
-
-[Field 1]
-Type=label
-Left=0
-Right=-1
-Top=10
-Bottom=70
-Text="OpenSLL 0.9.7i or newer is not found on your computer.\r\n\r\nTo use SSL and TLS encryption you need an SSL certificate. You can create a selfsigned certificate with OpenSSL.\r\n\r\nOpenSLL installer can be downloaded from"
-
-[Field 2]
-Type=link
-Left=0
-Right=-1
-Top=74
-Bottom=88
-State=http://www.slproweb.com/products/Win32OpenSSL.html
-Text=http://www.slproweb.com/products/Win32OpenSSL.html
-
-[Field 3]
-Type=checkbox
-Left=0
-Right=-1
-Top=93
-Bottom=105
-Text="I want to continue installing Ejabberd anyway"
-State=0
-Flags=NOTIFY
diff --git a/ejabberd-1.1.2/src/win32/CheckService.ini b/ejabberd-1.1.2/src/win32/CheckService.ini
deleted file mode 100644
index 764832469..000000000
--- a/ejabberd-1.1.2/src/win32/CheckService.ini
+++ /dev/null
@@ -1,19 +0,0 @@
-[Settings]
-NumFields=2
-
-[Field 1]
-Type=label
-Left=0
-Right=-1
-Top=10
-Bottom=50
-Text="You are installing Ejabberd as Administrator.\r\n\r\nEjabberd will be installed as a Windows service."
-
-[Field 2]
-Type=checkbox
-Left=0
-Right=-1
-Top=50
-Bottom=62
-Text="Configure ejabberd service to start automatically"
-State=1
diff --git a/ejabberd-1.1.2/src/win32/CheckUser.ini b/ejabberd-1.1.2/src/win32/CheckUser.ini
deleted file mode 100644
index 3352d69d2..000000000
--- a/ejabberd-1.1.2/src/win32/CheckUser.ini
+++ /dev/null
@@ -1,11 +0,0 @@
-[Settings]
-NumFields=1
-
-[Field 1]
-Type=label
-Left=0
-Right=-1
-Top=10
-Bottom=-10
-Text="Administrator privileges are recommended for Ejabberd install.\r\n\r\nOtherwise installing Ejabberd as a service will be impossible.\r\n\r\nIf you want to continue installing Ejabberd anyway, click Next."
-
diff --git a/ejabberd-1.1.2/src/win32/CheckUserH.ini b/ejabberd-1.1.2/src/win32/CheckUserH.ini
deleted file mode 100644
index 741bada22..000000000
--- a/ejabberd-1.1.2/src/win32/CheckUserH.ini
+++ /dev/null
@@ -1,20 +0,0 @@
-[Settings]
-NumFields=2
-
-[Field 1]
-Type=label
-Left=0
-Right=-1
-Top=10
-Bottom=50
-Text="Administrator privileges are recommended for Ejabberd install.\r\n\r\nOtherwise installing Ejabberd as a service will be impossible."
-
-[Field 2]
-Type=checkbox
-Left=0
-Right=-1
-Top=50
-Bottom=62
-Text="I want to continue installing Ejabberd anyway"
-State=0
-Flags=NOTIFY
diff --git a/ejabberd-1.1.2/src/win32/ejabberd.cfg b/ejabberd-1.1.2/src/win32/ejabberd.cfg
deleted file mode 100644
index 7ba191be0..000000000
--- a/ejabberd-1.1.2/src/win32/ejabberd.cfg
+++ /dev/null
@@ -1,167 +0,0 @@
-% $Id$
-
-%override_acls.
-
-
-% Users that have admin access. Add line like one of the following after you
-% will be successfully registered on server to get admin access:
-%{acl, admin, {user, "aleksey"}}.
-%{acl, admin, {user, "ermine"}}.
-
-% Blocked users:
-%{acl, blocked, {user, "test"}}.
-
-% Local users:
-{acl, local, {user_regexp, ""}}.
-
-% Another examples of ACLs:
-%{acl, jabberorg, {server, "jabber.org"}}.
-%{acl, aleksey, {user, "aleksey", "jabber.ru"}}.
-%{acl, test, {user_regexp, "^test"}}.
-%{acl, test, {user_glob, "test*"}}.
-
-
-% Only admins can use configuration interface:
-{access, configure, [{allow, admin}]}.
-
-% Every username can be registered via in-band registration:
-{access, register, [{allow, all}]}.
-
-% After successful registration user will get message with following subject
-% and body:
-{welcome_message,
- {"Welcome!",
- "Welcome to Jabber Service. "
- "For information about Jabber visit http://jabber.org"}}.
-% Replace them with 'none' if you don't want to send such message:
-%{welcome_message, none}.
-
-% List of people who will get notifications about registered users
-%{registration_watchers, ["admin1@localhost",
-% "admin2@localhost"]}.
-
-% Only admins can send announcement messages:
-{access, announce, [{allow, admin}]}.
-
-
-% Only non-blocked users can use c2s connections:
-{access, c2s, [{deny, blocked},
- {allow, all}]}.
-
-% Set shaper with name "normal" to limit traffic speed to 1000B/s
-{shaper, normal, {maxrate, 1000}}.
-
-% Set shaper with name "fast" to limit traffic speed to 50000B/s
-{shaper, fast, {maxrate, 50000}}.
-
-% For all users except admins used "normal" shaper
-{access, c2s_shaper, [{none, admin},
- {normal, all}]}.
-
-% For all S2S connections used "fast" shaper
-{access, s2s_shaper, [{fast, all}]}.
-
-% Admins of this server are also admins of MUC service:
-{access, muc_admin, [{allow, admin}]}.
-
-% All users are allowed to use MUC service:
-{access, muc, [{allow, all}]}.
-
-% This rule allows access only for local users:
-{access, local, [{allow, local}]}.
-
-
-% Authentification method. If you want to use internal user base, then use
-% this line:
-{auth_method, internal}.
-
-% For LDAP authentification use these lines instead of above one:
-%{auth_method, ldap}.
-%{ldap_servers, ["localhost"]}. % List of LDAP servers
-%{ldap_uidattr, "uid"}. % LDAP attribute that holds user ID
-%{ldap_base, "dc=example,dc=com"}. % Base of LDAP directory
-%{ldap_rootdn, "dc=example,dc=com"}. % LDAP manager
-%{ldap_password, "******"}. % Password to LDAP manager
-
-% For authentification via external script use the following:
-%{auth_method, external}.
-%{extauth_program, "/path/to/authentification/script"}.
-
-% For authentification via ODBC use the following:
-%{auth_method, odbc}.
-%{odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}.
-
-
-% Host name(s):
-{hosts, ["localhost"]}.
-
-% Default language:
-{language, "en"}.
-
-% Listened ports:
-{listen,
- [
- {5222, ejabberd_c2s, [{access, c2s},
- {shaper, c2s_shaper}]},
-
-% To create selfsigned certificate run the following command from the
-% command prompt:
-%
-% openssl req -new -x509 -days 365 -nodes -out ejabberd.pem -keyout ejabberd.pem
-%
-% and answer the questions.
-% {5222, ejabberd_c2s, [{access, c2s},
-% starttls, {certfile, "./ejabberd.pem"},
-% {shaper, c2s_shaper}]},
-
-% When using SSL/TLS ssl option is not recommended (it requires patching
-% erlang ssl application). Use tls option instead (as shown below).
-% {5223, ejabberd_c2s, [{access, c2s},
-% tls, {certfile, "./ejabberd.pem"},
-% {shaper, c2s_shaper}]},
-
- {5269, ejabberd_s2s_in, [{shaper, s2s_shaper}]},
-
-% {5555, ejabberd_service, [{access, all},
-% {host, "icq.localhost", [{password, "secret"}]}]},
-
- {5280, ejabberd_http, [http_poll, web_admin]}
- ]}.
-
-% If SRV lookup fails, then port 5269 is used to communicate with remote server
-{outgoing_s2s_port, 5269}.
-
-
-% Used modules:
-{modules,
- [
- {mod_register, [{access, register}]},
- {mod_roster, []},
- {mod_shared_roster, []},
- {mod_privacy, []},
- {mod_configure, []},
- {mod_disco, []},
- {mod_stats, []},
- {mod_vcard, []},
- {mod_offline, []},
- {mod_announce, [{access, announce}]},
- {mod_private, []},
- {mod_irc, []},
-% Default options for mod_muc:
-% host: "conference." ++ ?MYNAME
-% access: all
-% access_create: all
-% access_admin: none (only room creator has owner privileges)
- {mod_muc, [{access, muc},
- {access_create, muc},
- {access_admin, muc_admin}]},
- {mod_pubsub, []},
- {mod_time, []},
- {mod_last, []},
- {mod_version, []}
- ]}.
-
-
-% Local Variables:
-% mode: erlang
-% End:
diff --git a/ejabberd-1.1.2/src/win32/ejabberd.ico b/ejabberd-1.1.2/src/win32/ejabberd.ico
deleted file mode 100644
index 0a572d7f4..000000000
--- a/ejabberd-1.1.2/src/win32/ejabberd.ico
+++ /dev/null
Binary files differ
diff --git a/ejabberd-1.1.2/src/win32/ejabberd.nsi b/ejabberd-1.1.2/src/win32/ejabberd.nsi
deleted file mode 100644
index 8c828bda8..000000000
--- a/ejabberd-1.1.2/src/win32/ejabberd.nsi
+++ /dev/null
@@ -1,770 +0,0 @@
-; NSIS Modern User Interface
-; Ejabberd installation script
-
-;--------------------------------
-;Include Modern UI
-
- !include "MUI.nsh"
- !include "ejabberd.nsh" ; All release specific parameters come from this
-
-;--------------------------------
-;General
-
- ;Name and file
- !define PRODUCT "Ejabberd"
- Name ${PRODUCT}
- OutFile "${OUTFILEDIR}\${PRODUCT}-${VERSION}.exe"
- ShowInstDetails show
- ShowUninstDetails show
-
- !define MUI_ICON "ejabberd.ico"
- !define MUI_UNICON "ejabberd.ico"
- !define MUI_HEADERIMAGE
- !define MUI_HEADERIMAGE_BITMAP "ejabberd_header.bmp"
- !define MUI_WELCOMEFINISHPAGE_BITMAP "ejabberd_intro.bmp"
-
-
-;--------------------------------
-;Configuration
-
- SetCompressor lzma
-
-;--------------------------------
-;Reserve Files
-
- ReserveFile "ejabberd.ico"
- ReserveFile "ejabberd.ico"
- ReserveFile "ejabberd_header.bmp"
- ReserveFile "ejabberd_intro.bmp"
- !ifdef HACKED_INSTALLOPTIONS
- ReserveFile "CheckUserH.ini"
- ReserveFile "CheckReqs1H.ini"
- !else
- ReserveFile "CheckUser.ini"
- ReserveFile "CheckReqs1.ini"
- !endif
- ReserveFile "CheckReqs.ini"
- ReserveFile "CheckService.ini"
- !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
-
-;--------------------------------
-;Variables
-
- Var MUI_TEMP
- Var STARTMENU_FOLDER
- Var ADMIN
- Var ENABLE_SERVICE
- Var ERLANG_PATH
- Var ERLANG_VERSION
- Var REQUIRED_ERLANG_VERSION
- Var OPENSSL_PATH
- Var OPENSSL_VERSION
- Var REQUIRED_OPENSSL_VERSION
- Var ERLSRV
-
-;----------------------------------------------------------
-;.onInit uses UserInfo plugin, so it's as high as possible
-
-Function .onInit
-
- StrCpy $REQUIRED_ERLANG_VERSION "5.4.9"
- StrCpy $REQUIRED_OPENSSL_VERSION "0.9.7c"
-
- ;Default installation folder
- StrCpy $INSTDIR "$PROGRAMFILES\${PRODUCT}"
-
- ;Get installation folder from registry if available
- ClearErrors
- ReadRegStr $0 HKLM "SOFTWARE\${PRODUCT}" ""
- IfErrors 0 copydir
- ReadRegStr $0 HKCU "SOFTWARE\${PRODUCT}" ""
- IfErrors skipdir
- copydir:
- StrCpy $INSTDIR "$0"
-
- skipdir:
- ;Extract InstallOptions INI files
- !ifdef HACKED_INSTALLOPTIONS
- !insertmacro MUI_INSTALLOPTIONS_EXTRACT "CheckUserH.ini"
- !insertmacro MUI_INSTALLOPTIONS_EXTRACT "CheckReqs1H.ini"
- !else
- !insertmacro MUI_INSTALLOPTIONS_EXTRACT "CheckUser.ini"
- !insertmacro MUI_INSTALLOPTIONS_EXTRACT "CheckReqs1.ini"
- !endif
- !insertmacro MUI_INSTALLOPTIONS_EXTRACT "CheckReqs.ini"
- !insertmacro MUI_INSTALLOPTIONS_EXTRACT "CheckService.ini"
-
- ClearErrors
- UserInfo::GetName
- IfErrors admin
- Pop $0
- UserInfo::GetAccountType
- Pop $1
- StrCmp $1 "Admin" admin user
-
- admin:
- StrCpy $ADMIN 1
- Goto skip
-
- user:
- StrCpy $ADMIN 0
-
- skip:
-
-FunctionEnd
-
-;--------------------------------
-;Interface Settings
-
- !define MUI_ABORTWARNING
-
-;--------------------------------
-;Installer/Uninstaller pages
-
- !insertmacro MUI_PAGE_WELCOME
- !insertmacro MUI_PAGE_LICENSE "..\..\COPYING"
- Page custom CheckReqs LeaveCheckReqs
- Page custom CheckReqs1 LeaveCheckReqs1
- Page custom CheckUser LeaveCheckUser
- Page custom CheckService LeaveCheckService
- ;!insertmacro MUI_PAGE_COMPONENTS
- !insertmacro MUI_PAGE_DIRECTORY
-
- !insertmacro MUI_PAGE_STARTMENU ${PRODUCT} $STARTMENU_FOLDER
-
- !insertmacro MUI_PAGE_INSTFILES
-
- !insertmacro MUI_UNPAGE_WELCOME
- !insertmacro MUI_UNPAGE_CONFIRM
- !insertmacro MUI_UNPAGE_INSTFILES
-
-;--------------------------------
-;Languages
-
- !insertmacro MUI_LANGUAGE "English"
-
-;--------------------------------
-;Language Strings
-
-;Description
-
- LangString DESC_SecEjabberd ${LANG_ENGLISH} "Erlang jabber server."
-
-;--------------------------------
-;Installer Sections
-
-Section "Ejabberd" SecEjabberd
-SectionIn 1 RO
-
- SetOutPath "$INSTDIR"
- File /r "${TESTDIR}\doc"
- File /r "${TESTDIR}\ebin"
- File /r "${TESTDIR}\msgs"
- File /r "${TESTDIR}\win32"
- File "${TESTDIR}\*.dll"
- File "${TESTDIR}\inetrc"
- File /oname=ejabberd.cfg.example "${TESTDIR}\ejabberd.cfg"
- SetOverwrite off
- File "${TESTDIR}\ejabberd.cfg"
- SetOverwrite on
- ;File /r "${TESTDIR}\src"
- CreateDirectory "$INSTDIR\log"
-
-;The startmenu stuff
- !insertmacro MUI_STARTMENU_WRITE_BEGIN ${PRODUCT}
-
- ;Create shortcuts
- StrCpy $0 "$SMPROGRAMS\$STARTMENU_FOLDER"
- CreateDirectory "$0"
- CreateShortCut "$0\Start Ejabberd.lnk" "$ERLANG_PATH\bin\werl.exe" \
- '-sname ejabberd -pa ebin \
- -env EJABBERD_LOG_PATH log/ejabberd.log \
- -s ejabberd -kernel inetrc \"./inetrc\" -mnesia dir \"spool\" \
- -sasl sasl_error_logger {file,\"log/sasl.log\"}' \
- $INSTDIR\win32\ejabberd.ico
- CreateShortCut "$0\Edit Config.lnk" "%SystemRoot%\system32\notepad.exe" \
- "$INSTDIR\ejabberd.cfg"
- CreateShortCut "$0\Read Docs.lnk" "$INSTDIR\doc\guide.html"
- CreateShortCut "$0\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
-
- !insertmacro MUI_STARTMENU_WRITE_END
-
-;Create Windows service
- StrCmp $ADMIN 1 0 skipservice
-
- StrCpy $ERLSRV ""
- Push $ERLANG_PATH
- Push erlsrv.exe
- GetFunctionAddress $0 FFCallback
- Push $0
- Call FindFiles
-
- StrCmp $ERLSRV "" skipservice
-
- nsExec::Exec '"$ERLSRV" list ejabberd'
- Pop $0
- StrCmp $0 "error" skipservice
- StrCmp $0 "0" 0 installsrv
-
- nsExec::ExecToLog '"$ERLSRV" remove ejabberd'
- Pop $0
-
- installsrv:
- nsExec::ExecToLog '"$ERLSRV" add ejabberd -stopaction "init:stop()." \
- -onfail restart -workdir "$INSTDIR" \
- -args "-s ejabberd -pa ebin \
- -kernel inetrc \\\"./inetrc\\\" \
- -env EJABBERD_LOG_PATH log/ejabberd.log \
- -sasl sasl_error_logger {file,\\\"log/sasl.log\\\"} \
- -mnesia dir \\\"spool\\\"" -d'
- Pop $0
-
- StrCmp $ENABLE_SERVICE 0 0 skipservice
- nsExec::ExecToLog '"$ERLSRV" disable ejabberd'
- Pop $0
-
- skipservice:
-
- ;Create uninstaller
- WriteUninstaller "$INSTDIR\Uninstall.exe"
-
- StrCpy $1 "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT}"
- StrCmp $ADMIN 1 admin2
-
- WriteRegStr HKCU "Software\${PRODUCT}" "" "$INSTDIR"
- WriteRegStr HKCU "$1" "DisplayName" "${PRODUCT} ${VERSION}"
- WriteRegStr HKCU "$1" "UninstallString" "$INSTDIR\Uninstall.exe"
- WriteRegDWORD HKCU "$1" "NoModify" 1
- WriteRegDWORD HKCU "$1" "NoRepair" 1
- Goto done2
-
- admin2:
- WriteRegStr HKLM "Software\${PRODUCT}" "" "$INSTDIR"
- WriteRegStr HKLM "Software\${PRODUCT}" "Erlsrv" "$ERLSRV"
- WriteRegStr HKLM "$1" "DisplayName" "${PRODUCT} ${VERSION}"
- WriteRegStr HKLM "$1" "UninstallString" "$INSTDIR\Uninstall.exe"
- WriteRegDWORD HKLM "$1" "NoModify" 1
- WriteRegDWORD HKLM "$1" "NoRepair" 1
-
- done2:
-
-SectionEnd ; SecEjabberd
-
-Function FFCallback
-
- Exch $0
- StrCpy $ERLSRV $0
- Pop $0
- Push "stop"
-
-FunctionEnd
-
-;--------------------------------
-;Descriptions
-
- !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
- !insertmacro MUI_DESCRIPTION_TEXT ${SecEjabberd} $(DESC_SecEjabberd)
- !insertmacro MUI_FUNCTION_DESCRIPTION_END
-
-;--------------------------------
-;Uninstaller Section
-
-Section "Uninstall"
-
- ClearErrors
- UserInfo::GetName
- IfErrors admin
- Pop $0
- UserInfo::GetAccountType
- Pop $1
- StrCmp $1 "Admin" admin
-
- StrCpy $ADMIN 0
- Goto skipservice
-
- admin:
- StrCpy $ADMIN 1
- ReadRegStr $ERLSRV HKLM "Software\${PRODUCT}" "Erlsrv"
-
- nsExec::Exec '"$ERLSRV" list ejabberd'
- Pop $0
- StrCmp $0 "error" skipservice
- StrCmp $0 "0" 0 skipservice
-
- nsExec::ExecToLog '"$ERLSRV" remove ejabberd'
- Pop $0
-
- skipservice:
- RMDir /r "$INSTDIR\doc"
- RMDir /r "$INSTDIR\ebin"
- RMDir /r "$INSTDIR\msgs"
- RMDir /r "$INSTDIR\win32"
- ;RMDir /r "$INSTDIR\src"
- RMDir /r "$INSTDIR\log"
- Delete "$INSTDIR\*.dll"
- Delete "$INSTDIR\inetrc"
- Delete "$INSTDIR\ejabberd.cfg.example"
- Delete "$INSTDIR\Uninstall.exe"
- RMDir "$INSTDIR"
-
- !insertmacro MUI_STARTMENU_GETFOLDER ${PRODUCT} $MUI_TEMP
-
- Delete "$SMPROGRAMS\$MUI_TEMP\Start Ejabberd.lnk"
- Delete "$SMPROGRAMS\$MUI_TEMP\Edit Config.lnk"
- Delete "$SMPROGRAMS\$MUI_TEMP\Read Docs.lnk"
- Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
-
- ;Delete empty start menu parent diretories
- StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"
-
- startMenuDeleteLoop:
- RMDir $MUI_TEMP
- GetFullPathName $MUI_TEMP "$MUI_TEMP\.."
-
- IfErrors startMenuDeleteLoopDone
-
- StrCmp $MUI_TEMP $SMPROGRAMS startMenuDeleteLoopDone startMenuDeleteLoop
- startMenuDeleteLoopDone:
-
- StrCpy $1 "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT}"
- StrCmp $ADMIN 1 admin1
- DeleteRegKey HKCU "Software\${PRODUCT}"
- DeleteRegKey HKCU $1
- Goto done
- admin1:
- DeleteRegKey HKLM "Software\${PRODUCT}"
- DeleteRegKey HKLM $1
-
- done:
-
-SectionEnd
-
-LangString TEXT_CU_TITLE ${LANG_ENGLISH} "Checking User Privileges"
-LangString TEXT_CU_SUBTITLE ${LANG_ENGLISH} "Checking user privileged required to install Ejabberd."
-
-Function CheckUser
-
- StrCmp $ADMIN 1 0 showpage
- Abort
-
- showpage:
- !insertmacro MUI_HEADER_TEXT $(TEXT_CU_TITLE) $(TEXT_CU_SUBTITLE)
-
- !ifdef HACKED_INSTALLOPTIONS
- !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "CheckUserH.ini"
- !insertmacro MUI_INSTALLOPTIONS_READ $0 "CheckUserH.ini" "Field 2" "State"
- GetDlgItem $1 $HWNDPARENT 1
- EnableWindow $1 $0
- !else
- !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "CheckUser.ini"
- !endif
-
- !insertmacro MUI_INSTALLOPTIONS_SHOW
-
-FunctionEnd
-
-Function LeaveCheckUser
-
- !ifdef HACKED_INSTALLOPTIONS
- !insertmacro MUI_INSTALLOPTIONS_READ $0 "CheckUserH.ini" "Settings" "State"
- StrCmp $0 0 validate ;Next button?
- StrCmp $0 2 checkbox ;checkbox?
- Abort ;Return to the page
-
- checkbox:
- !insertmacro MUI_INSTALLOPTIONS_READ $0 "CheckUserH.ini" "Field 2" "State"
- GetDlgItem $1 $HWNDPARENT 1
- EnableWindow $1 $0
- Abort
-
- validate:
- !endif
-
-FunctionEnd
-
-LangString TEXT_CU_TITLE ${LANG_ENGLISH} "Configuring Ejabberd Service"
-LangString TEXT_CU_SUBTITLE ${LANG_ENGLISH} "Configuring Ejabberd Service."
-
-Function CheckService
-
- StrCmp $ADMIN 0 0 showpage
- Abort
-
- showpage:
- !insertmacro MUI_HEADER_TEXT $(TEXT_CU_TITLE) $(TEXT_CU_SUBTITLE)
-
- !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "CheckService.ini"
-
- !insertmacro MUI_INSTALLOPTIONS_SHOW
-
-FunctionEnd
-
-Function LeaveCheckService
-
- !insertmacro MUI_INSTALLOPTIONS_READ $0 "CheckService.ini" "Field 2" "State"
- StrCmp $0 0 0 autostart
- StrCpy $ENABLE_SERVICE 0
- Goto endfun
-
- autostart:
- StrCpy $ENABLE_SERVICE 1
-
- endfun:
-
-FunctionEnd
-
-LangString TEXT_CR_TITLE ${LANG_ENGLISH} "Unsatisfied Requirements"
-LangString TEXT_CR_SUBTITLE ${LANG_ENGLISH} "Unsatisfied Ejabberd requirements found."
-
-Function CheckReqs
-
- Push "HKLM"
- Call FindErlang
- Pop $ERLANG_PATH
- Pop $ERLANG_VERSION
- StrCmp $ERLANG_PATH "" 0 abort
- Push "HKCU"
- Call FindErlang
- Pop $ERLANG_PATH
- Pop $ERLANG_VERSION
- StrCmp $ERLANG_PATH "" 0 abort
-
- !insertmacro MUI_HEADER_TEXT $(TEXT_CR_TITLE) $(TEXT_CR_SUBTITLE)
-
- !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "CheckReqs.ini"
- GetDlgItem $R0 $HWNDPARENT 1
- EnableWindow $R0 0
-
-
- !insertmacro MUI_INSTALLOPTIONS_SHOW
-
- abort:
- Abort
-
-FunctionEnd
-
-Function LeaveCheckReqs
-
- Abort
-
-FunctionEnd
-
-Function CheckReqs1
-
- Push "HKLM"
- Call FindOpenSSL
- Pop $OPENSSL_PATH
- Pop $OPENSSL_VERSION
- StrCmp $OPENSSL_PATH "" 0 abort
- Push "HKCU"
- Call FindOpenSSL
- Pop $OPENSSL_PATH
- Pop $OPENSSL_VERSION
- StrCmp $OPENSSL_PATH "" 0 abort
-
- !insertmacro MUI_HEADER_TEXT $(TEXT_CR_TITLE) $(TEXT_CR_SUBTITLE)
-
- !ifdef HACKED_INSTALLOPTIONS
- !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "CheckReqs1H.ini"
- !insertmacro MUI_INSTALLOPTIONS_READ $0 "CheckReqs1H.ini" "Field 3" "State"
- GetDlgItem $1 $HWNDPARENT 1
- EnableWindow $1 $0
- !else
- !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "CheckReqs1.ini"
- !endif
-
- !insertmacro MUI_INSTALLOPTIONS_SHOW
-
- abort:
- Abort
-
-FunctionEnd
-
-Function LeaveCheckReqs1
-
- !ifdef HACKED_INSTALLOPTIONS
- !insertmacro MUI_INSTALLOPTIONS_READ $0 "CheckReqs1H.ini" "Settings" "State"
- StrCmp $0 0 validate ;Next button?
- StrCmp $0 3 checkbox ;checkbox?
- Abort ;Return to the page
-
- checkbox:
- !insertmacro MUI_INSTALLOPTIONS_READ $0 "CheckReqs1H.ini" "Field 3" "State"
- GetDlgItem $1 $HWNDPARENT 1
- EnableWindow $1 $0
- Abort
-
- validate:
- !endif
-
-FunctionEnd
-
-Function FindErlang
-
- Exch $R0
- Push $R1
- Push $R2
- Push $R3
- Push $R4
- Push $R5
-
- StrCpy $R1 0
- StrCpy $R2 "SOFTWARE\Ericsson\Erlang"
-
- loop:
- StrCmp $R0 HKLM h1
- EnumRegKey $R3 HKCU $R2 $R1
- Goto l1
- h1:
- EnumRegKey $R3 HKLM $R2 $R1
- l1:
- IntOp $R1 $R1 + 1
- StrCmp $R3 "" endloop
- ClearErrors
- StrCmp $R0 HKLM h2
- ReadRegStr $R4 HKCU "$R2\$R3" ""
- Goto l2
- h2:
- ReadRegStr $R4 HKLM "$R2\$R3" ""
- l2:
- IfFileExists "$R4\bin\erl.exe" 0 loop
- Push $REQUIRED_ERLANG_VERSION
- Push $R3
- Call CompareVersions
- Pop $R5
- StrCmp $R5 1 get
- Goto loop
-
- endloop:
- StrCpy $R4 ""
-
- get:
- StrCpy $R0 $R4
- StrCpy $R1 $R3
-
- Pop $R5
- Pop $R4
- Pop $R3
- Pop $R2
- Exch $R1
- Exch
- Exch $R0
-
-FunctionEnd
-
-Function FindOpenSSL
-
- Exch $R0
- Push $R1
- Push $R2
- Push $R3
- Push $R4
- Push $R5
-
- StrCpy $R1 0
- StrCpy $R2 "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\OpenSSL_is1"
-
- StrCmp $R0 HKLM h1
- ReadRegStr $R3 HKCU "$R2" "DisplayName"
- ReadRegStr $R4 HKCU "$R2" "Inno Setup: App Path"
- Goto l1
- h1:
- ReadRegStr $R3 HKLM "$R2" "DisplayName"
- ReadRegStr $R4 HKLM "$R2" "Inno Setup: App Path"
- l1:
-
- IfFileExists "$R4\bin\openssl.exe" 0 notfound
- Goto get
- ; TODO check version
- ;Push $REQUIRED_OPENSSL_VERSION
- ;Push $R3
- ;Call CompareVersions
- ;Pop $R5
- ;StrCmp $R5 1 get
-
- notfound:
- StrCpy $R4 ""
-
- get:
- StrCpy $R0 $R4
- StrCpy $R1 $R3
-
- Pop $R5
- Pop $R4
- Pop $R3
- Pop $R2
- Exch $R1
- Exch
- Exch $R0
-
-FunctionEnd
-
-;----------------------------------------------------------------------
-; CompareVersions
-; input:
-; top of stack = existing version
-; top of stack-1 = needed version
-; output:
-; top of stack = 1 if current version => neded version, else 0
-; version is a string in format "xx.xx.xx.xx" (number of interger sections
-; can be different in needed and existing versions)
-
-Function CompareVersions
- ; stack: existing ver | needed ver
- Exch $R0
- Exch
- Exch $R1
- ; stack: $R1|$R0
-
- Push $R1
- Push $R0
- ; stack: e|n|$R1|$R0
-
- ClearErrors
- loop:
- IfErrors VersionNotFound
- Strcmp $R0 "" VersionTestEnd
-
- Call ParseVersion
- Pop $R0
- Exch
-
- Call ParseVersion
- Pop $R1
- Exch
-
- IntCmp $R1 $R0 +1 VersionOk VersionNotFound
- Pop $R0
- Push $R0
-
- goto loop
-
- VersionTestEnd:
- Pop $R0
- Pop $R1
- Push $R1
- Push $R0
- StrCmp $R0 $R1 VersionOk VersionNotFound
-
- VersionNotFound:
- StrCpy $R0 "0"
- Goto end
-
- VersionOk:
- StrCpy $R0 "1"
-end:
- ; stack: e|n|$R1|$R0
- Exch $R0
- Pop $R0
- Exch $R0
- ; stack: res|$R1|$R0
- Exch
- ; stack: $R1|res|$R0
- Pop $R1
- ; stack: res|$R0
- Exch
- Pop $R0
- ; stack: res
-FunctionEnd
-
-;-----------------------------------------------------------------------
-; ParseVersion
-; input:
-; top of stack = version string ("xx.xx.xx.xx")
-; output:
-; top of stack = first number in version ("xx")
-; top of stack-1 = rest of the version string ("xx.xx.xx")
-Function ParseVersion
- Exch $R1 ; version
- Push $R2
- Push $R3
-
- StrCpy $R2 1
- loop:
- StrCpy $R3 $R1 1 $R2
- StrCmp $R3 "." loopend
- StrLen $R3 $R1
- IntCmp $R3 $R2 loopend loopend
- IntOp $R2 $R2 + 1
- Goto loop
- loopend:
- Push $R1
- StrCpy $R1 $R1 $R2
- Exch $R1
-
- StrLen $R3 $R1
- IntOp $R3 $R3 - $R2
- IntOp $R2 $R2 + 1
- StrCpy $R1 $R1 $R3 $R2
-
- Push $R1
-
- Exch 2
- Pop $R3
-
- Exch 2
- Pop $R2
-
- Exch 2
- Pop $R1
-FunctionEnd
-
-Function FindFiles
-
- Exch $R5 # callback function
- Exch
- Exch $R4 # file name
- Exch 2
- Exch $R0 # directory
- Push $R1
- Push $R2
- Push $R3
- Push $R6
-
- Push $R0 # first dir to search
-
- StrCpy $R3 1
-
- nextDir:
- Pop $R0
- IntOp $R3 $R3 - 1
- ClearErrors
- FindFirst $R1 $R2 "$R0\*.*"
- nextFile:
- StrCmp $R2 "." gotoNextFile
- StrCmp $R2 ".." gotoNextFile
-
- StrCmp $R2 $R4 0 isDir
- Push "$R0\$R2"
- Call $R5
- Pop $R6
- StrCmp $R6 "stop" 0 isDir
- loop:
- StrCmp $R3 0 done
- Pop $R0
- IntOp $R3 $R3 - 1
- Goto loop
-
- isDir:
- IfFileExists "$R0\$R2\*.*" 0 gotoNextFile
- IntOp $R3 $R3 + 1
- Push "$R0\$R2"
-
- gotoNextFile:
- FindNext $R1 $R2
- IfErrors 0 nextFile
-
- done:
- FindClose $R1
- StrCmp $R3 0 0 nextDir
-
- Pop $R6
- Pop $R3
- Pop $R2
- Pop $R1
- Pop $R0
- Pop $R5
- Pop $R4
-
-FunctionEnd
-
diff --git a/ejabberd-1.1.2/src/win32/ejabberd_header.bmp b/ejabberd-1.1.2/src/win32/ejabberd_header.bmp
deleted file mode 100644
index 14d70ddee..000000000
--- a/ejabberd-1.1.2/src/win32/ejabberd_header.bmp
+++ /dev/null
Binary files differ
diff --git a/ejabberd-1.1.2/src/win32/ejabberd_intro.bmp b/ejabberd-1.1.2/src/win32/ejabberd_intro.bmp
deleted file mode 100644
index 7b37b0780..000000000
--- a/ejabberd-1.1.2/src/win32/ejabberd_intro.bmp
+++ /dev/null
Binary files differ
diff --git a/ejabberd-1.1.2/src/win32/inetrc b/ejabberd-1.1.2/src/win32/inetrc
deleted file mode 100644
index 49b18c2eb..000000000
--- a/ejabberd-1.1.2/src/win32/inetrc
+++ /dev/null
@@ -1 +0,0 @@
-{registry, win32}.
diff --git a/ejabberd-1.1.2/src/xml.erl b/ejabberd-1.1.2/src/xml.erl
deleted file mode 100644
index 888618867..000000000
--- a/ejabberd-1.1.2/src/xml.erl
+++ /dev/null
@@ -1,233 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : xml.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : XML utils
-%%% Created : 20 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(xml).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([element_to_string/1,
- crypt/1,
- remove_cdata/1,
- get_cdata/1, get_tag_cdata/1,
- get_attr/2, get_attr_s/2,
- get_tag_attr/2, get_tag_attr_s/2,
- get_subtag/2,
- get_path_s/2,
- replace_tag_attr/3]).
-
-%element_to_string(El) ->
-% case El of
-% {xmlelement, Name, Attrs, Els} ->
-% if length(Els) > 0 ->
-% "<" ++ Name ++ attrs_to_string(Attrs) ++ ">" ++
-% lists:append(
-% lists:map(fun(E) -> element_to_string(E) end, Els))
-% ++ "</" ++ Name ++ ">";
-% true ->
-% "<" ++ Name ++ attrs_to_string(Attrs) ++ "/>"
-% end;
-% {xmlcdata, CData} -> crypt(CData)
-% end.
-%
-%
-%attrs_to_string(Attrs) ->
-% lists:append(lists:map(fun(A) -> attr_to_string(A) end, Attrs)).
-%
-%attr_to_string({Name, Value}) ->
-% " " ++ crypt(Name) ++ "='" ++ crypt(Value) ++ "'".
-
-
-%element_to_string2(El) ->
-% lists:flatten(element_to_string21(El)).
-%
-%element_to_string21(El) ->
-% case El of
-% {xmlelement, Name, Attrs, Els} ->
-% if length(Els) > 0 ->
-% [[$< | Name], attrs_to_list(Attrs), ">",
-% lists:map(fun(E) -> element_to_string21(E) end, Els),
-% "</", Name, ">"];
-% true ->
-% ["<", Name, attrs_to_list(Attrs), "/>"]
-% end;
-% {xmlcdata, CData} -> crypt(CData)
-% end.
-%
-%attrs_to_list(Attrs) ->
-% lists:map(fun(A) -> attr_to_list(A) end, Attrs).
-%
-%attr_to_list({Name, Value}) ->
-% [" ", crypt(Name), "='", crypt(Value), "'"].
-
-element_to_string(El) ->
- case El of
- {xmlelement, Name, Attrs, Els} ->
- if
- Els /= [] ->
- [$<, Name, attrs_to_list(Attrs), $>,
- [element_to_string(E) || E <- Els],
- $<, $/, Name, $>];
- true ->
- [$<, Name, attrs_to_list(Attrs), $/, $>]
- end;
- {xmlcdata, CData} ->
- crypt(CData)
- end.
-
-attrs_to_list(Attrs) ->
- [attr_to_list(A) || A <- Attrs].
-
-attr_to_list({Name, Value}) ->
- [$\s, crypt(Name), $=, $', crypt(Value), $'].
-
-
-
-%crypt(S) ->
-% lists:reverse(crypt(S, "")).
-%
-%crypt([$& | S], R) ->
-% crypt(S, [$;, $p, $m, $a, $& | R]);
-%crypt([$< | S], R) ->
-% crypt(S, [$;, $t, $l, $& | R]);
-%crypt([$> | S], R) ->
-% crypt(S, [$;, $t, $g, $& | R]);
-%crypt([$" | S], R) ->
-% crypt(S, [$;, $t, $o, $u, $q, $& | R]);
-%crypt([$' | S], R) ->
-% crypt(S, [$;, $s, $o, $p, $a, $& | R]);
-%crypt([C | S], R) ->
-% crypt(S, [C | R]);
-%crypt([], R) ->
-% R.
-
-crypt(S) when is_list(S) ->
- [case C of
- $& -> "&amp;";
- $< -> "&lt;";
- $> -> "&gt;";
- $" -> "&quot;";
- $' -> "&apos;";
- _ -> C
- end || C <- S];
-crypt(S) when is_binary(S) ->
- crypt(binary_to_list(S)).
-
-%crypt1(S) ->
-% lists:flatten([case C of
-% $& -> "&amp;";
-% $< -> "&lt;";
-% $> -> "&gt;";
-% $" -> "&quot;";
-% $' -> "&apos;";
-% _ -> C
-% end || C <- S]).
-
-%crypt([$& | S]) ->
-% [$&, $a, $m, $p, $; | crypt(S)];
-%crypt([$< | S]) ->
-% [$&, $l, $t, $; | crypt(S)];
-%crypt([$> | S]) ->
-% [$&, $g, $t, $; | crypt(S)];
-%crypt([$" | S]) ->
-% [$&, $q, $u, $o, $t, $; | crypt(S)];
-%crypt([$' | S]) ->
-% [$&, $a, $p, $o, $s, $; | crypt(S)];
-%crypt([C | S]) ->
-% [C | crypt(S)];
-%crypt([]) ->
-% [].
-
-
-
-remove_cdata_p({xmlelement, Name, Attrs, Els}) -> true;
-remove_cdata_p(_) -> false.
-
-remove_cdata(L) -> [E || E <- L, remove_cdata_p(E)].
-
-
-%remove_cdata(L) ->
-% lists:reverse(remove_cdata(L, [])).
-%
-%remove_cdata([{xmlelement, Name, Attrs, Els} | L], R) ->
-% remove_cdata(L, [{xmlelement, Name, Attrs, Els} | R]);
-%remove_cdata([{xmlcdata, CData} | L], R) ->
-% remove_cdata(L, R);
-%remove_cdata([], R) ->
-% R.
-
-get_cdata(L) ->
- binary_to_list(list_to_binary(get_cdata(L, ""))).
-
-get_cdata([{xmlcdata, CData} | L], S) ->
- get_cdata(L, [S, CData]);
-get_cdata([_ | L], S) ->
- get_cdata(L, S);
-get_cdata([], S) ->
- S.
-
-get_tag_cdata({xmlelement, Name, Attrs, Els}) ->
- get_cdata(Els).
-
-get_attr(AttrName, Attrs) ->
- case lists:keysearch(AttrName, 1, Attrs) of
- {value, {_, Val}} ->
- {value, Val};
- _ ->
- false
- end.
-
-get_attr_s(AttrName, Attrs) ->
- case lists:keysearch(AttrName, 1, Attrs) of
- {value, {_, Val}} ->
- Val;
- _ ->
- ""
- end.
-
-get_tag_attr(AttrName, {xmlelement, Name, Attrs, Els}) ->
- get_attr(AttrName, Attrs).
-
-get_tag_attr_s(AttrName, {xmlelement, Name, Attrs, Els}) ->
- get_attr_s(AttrName, Attrs).
-
-
-get_subtag({xmlelement, _, _, Els}, Name) ->
- get_subtag1(Els, Name).
-
-get_subtag1([El | Els], Name) ->
- case El of
- {xmlelement, Name, _, _} ->
- El;
- _ ->
- get_subtag1(Els, Name)
- end;
-get_subtag1([], _) ->
- false.
-
-
-get_path_s(El, []) ->
- El;
-get_path_s(El, [{elem, Name} | Path]) ->
- case get_subtag(El, Name) of
- false ->
- "";
- SubEl ->
- get_path_s(SubEl, Path)
- end;
-get_path_s(El, [{attr, Name}]) ->
- get_tag_attr_s(Name, El);
-get_path_s(El, [cdata]) ->
- get_tag_cdata(El).
-
-
-replace_tag_attr(Attr, Value, {xmlelement, Name, Attrs, Els}) ->
- Attrs1 = lists:keydelete(Attr, 1, Attrs),
- Attrs2 = [{Attr, Value} | Attrs1],
- {xmlelement, Name, Attrs2, Els}.
-
-
diff --git a/ejabberd-1.1.2/src/xml_stream.erl b/ejabberd-1.1.2/src/xml_stream.erl
deleted file mode 100644
index c923b6ae7..000000000
--- a/ejabberd-1.1.2/src/xml_stream.erl
+++ /dev/null
@@ -1,164 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File : xml_stream.erl
-%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose : Parse XML streams
-%%% Created : 17 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
-%%% Id : $Id$
-%%%----------------------------------------------------------------------
-
--module(xml_stream).
--author('alexey@sevcom.net').
--vsn('$Revision$ ').
-
--export([new/1,
- new/2,
- parse/2,
- close/1,
- parse_element/1]).
-
--define(XML_START, 0).
--define(XML_END, 1).
--define(XML_CDATA, 2).
--define(XML_ERROR, 3).
-
--define(PARSE_COMMAND, 0).
--define(PARSE_FINAL_COMMAND, 1).
-
--record(xml_stream_state, {callback_pid, port, stack, size, maxsize}).
-
-process_data(CallbackPid, Stack, Data) ->
- case Data of
- {?XML_START, {Name, Attrs}} ->
- if
- Stack == [] ->
- catch gen_fsm:send_event(CallbackPid,
- {xmlstreamstart, Name, Attrs});
- true ->
- ok
- end,
- [{xmlelement, Name, Attrs, []} | Stack];
- {?XML_END, EndName} ->
- case Stack of
- [{xmlelement, Name, Attrs, Els} | Tail] ->
- NewEl = {xmlelement, Name, Attrs, lists:reverse(Els)},
- case Tail of
- [] ->
- catch gen_fsm:send_event(CallbackPid,
- {xmlstreamend, EndName}),
- Tail;
- [_] ->
- catch gen_fsm:send_event(CallbackPid,
- {xmlstreamelement, NewEl}),
- Tail;
- [{xmlelement, Name1, Attrs1, Els1} | Tail1] ->
- [{xmlelement, Name1, Attrs1, [NewEl | Els1]} |
- Tail1]
- end
- end;
- {?XML_CDATA, CData} ->
- case Stack of
- [El] ->
- [El];
- [{xmlelement, Name, Attrs, Els} | Tail] ->
- [{xmlelement, Name, Attrs, [{xmlcdata, CData} | Els]} |
- Tail];
- [] -> []
- end;
- {?XML_ERROR, Err} ->
- catch gen_fsm:send_event(CallbackPid, {xmlstreamerror, Err})
- end.
-
-
-new(CallbackPid) ->
- new(CallbackPid, infinity).
-
-new(CallbackPid, MaxSize) ->
- Port = open_port({spawn, expat_erl}, [binary]),
- #xml_stream_state{callback_pid = CallbackPid,
- port = Port,
- stack = [],
- size = 0,
- maxsize = MaxSize}.
-
-
-parse(#xml_stream_state{callback_pid = CallbackPid,
- port = Port,
- stack = Stack,
- size = Size,
- maxsize = MaxSize} = State, Str) ->
- StrSize = if
- is_list(Str) -> length(Str);
- is_binary(Str) -> size(Str)
- end,
- Res = port_control(Port, ?PARSE_COMMAND, Str),
- {NewStack, NewSize} =
- lists:foldl(
- fun(Data, {St, Sz}) ->
- NewSt = process_data(CallbackPid, St, Data),
- case NewSt of
- [_] -> {NewSt, 0};
- _ -> {NewSt, Sz}
- end
- end, {Stack, Size + StrSize}, binary_to_term(Res)),
- if
- NewSize > MaxSize ->
- catch gen_fsm:send_event(CallbackPid,
- {xmlstreamerror, "XML stanza is too big"});
- true ->
- ok
- end,
- State#xml_stream_state{stack = NewStack, size = NewSize}.
-
-close(#xml_stream_state{port = Port}) ->
- port_close(Port).
-
-
-parse_element(Str) ->
- Port = open_port({spawn, expat_erl}, [binary]),
- Res = port_control(Port, ?PARSE_FINAL_COMMAND, Str),
- port_close(Port),
- process_element_events(binary_to_term(Res)).
-
-process_element_events(Events) ->
- process_element_events(Events, []).
-
-process_element_events([], _Stack) ->
- {error, parse_error};
-process_element_events([Event | Events], Stack) ->
- case Event of
- {?XML_START, {Name, Attrs}} ->
- process_element_events(
- Events, [{xmlelement, Name, Attrs, []} | Stack]);
- {?XML_END, _EndName} ->
- case Stack of
- [{xmlelement, Name, Attrs, Els} | Tail] ->
- NewEl = {xmlelement, Name, Attrs, lists:reverse(Els)},
- case Tail of
- [] ->
- if
- Events == [] ->
- NewEl;
- true ->
- {error, parse_error}
- end;
- [{xmlelement, Name1, Attrs1, Els1} | Tail1] ->
- process_element_events(
- Events,
- [{xmlelement, Name1, Attrs1, [NewEl | Els1]} |
- Tail1])
- end
- end;
- {?XML_CDATA, CData} ->
- case Stack of
- [{xmlelement, Name, Attrs, Els} | Tail] ->
- process_element_events(
- Events,
- [{xmlelement, Name, Attrs, [{xmlcdata, CData} | Els]} |
- Tail]);
- [] ->
- process_element_events(Events, [])
- end;
- {?XML_ERROR, Err} ->
- {error, Err}
- end.
-
diff --git a/ejabberd-1.1.2/tools/ejabberdctl b/ejabberd-1.1.2/tools/ejabberdctl
deleted file mode 100755
index 48294cae9..000000000
--- a/ejabberd-1.1.2/tools/ejabberdctl
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-exec erl -noinput -sname ejabberdctl -s ejabberd_ctl -extra $@
-