Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| de080352ca |
@@ -1,365 +1,3 @@
|
||||
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
|
||||
|
||||
+7
-4
@@ -27,13 +27,16 @@ clean:
|
||||
rm -f *.toc
|
||||
|
||||
guide.html: guide.tex
|
||||
hevea -fix -noiso -pedantic guide.tex
|
||||
|
||||
hevea guide.tex
|
||||
hevea guide.tex
|
||||
|
||||
dev.html: dev.tex
|
||||
hevea -fix -noiso -pedantic dev.tex
|
||||
hevea dev.tex
|
||||
hevea dev.tex
|
||||
|
||||
features.html: features.tex
|
||||
hevea -fix -noiso -pedantic features.tex
|
||||
hevea features.tex
|
||||
hevea features.tex
|
||||
|
||||
guide.pdf: guide.tex
|
||||
pdflatex guide.tex
|
||||
|
||||
+62
-50
@@ -4,7 +4,7 @@
|
||||
|
||||
<HEAD>
|
||||
|
||||
<TITLE>Ejabberd 1.1.2 Developers Guide</TITLE>
|
||||
<TITLE>Ejabberd 1.0.0 Developers Guide</TITLE>
|
||||
|
||||
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<META name="GENERATOR" content="hevea 1.08">
|
||||
@@ -22,7 +22,7 @@ BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
|
||||
</HEAD>
|
||||
|
||||
<BODY >
|
||||
<!--HEVEA command line is: hevea -fix -noiso -pedantic dev.tex -->
|
||||
<!--HEVEA command line is: hevea dev.tex -->
|
||||
<!--HTMLHEAD-->
|
||||
<!--ENDHTML-->
|
||||
<!--PREFIX <ARG ></ARG>-->
|
||||
@@ -34,7 +34,7 @@ BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
|
||||
|
||||
<TABLE CLASS="title">
|
||||
<TR><TD>
|
||||
<H1 CLASS="titlemain">Ejabberd 1.1.2 Developers Guide</H1>
|
||||
<H1 CLASS="titlemain">Ejabberd 1.0.0 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>
|
||||
@@ -42,7 +42,7 @@ BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
|
||||
<BR>
|
||||
<DIV CLASS="center">
|
||||
|
||||
<IMG SRC="logo.png" ALT="logo.png">
|
||||
<IMG SRC="logo.png">
|
||||
|
||||
|
||||
<BR>
|
||||
@@ -61,57 +61,56 @@ BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
|
||||
<A HREF="#htoc2">1.1 Key Features</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc3">1.2 Additional Features</A>
|
||||
</UL>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc4">2 How it Works</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc4">2 How it works</A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc5">2.1 Router</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc6">2.2 Local Router</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc7">2.3 Session Manager</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc8">2.4 S2S Manager</A>
|
||||
</UL>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc9">3 XML Representation</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc9">3 XML representation</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc10">4 Module <TT>xml</TT></A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc11">5 Module <TT>xml_stream</TT></A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc12">6 Modules</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc12">6 <TT>ejabberd</TT> modules</A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc13">6.1 Module gen_iq_handler</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc14">6.2 Services</A>
|
||||
<A HREF="#htoc13">6.1 gen_mod behaviour</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc14">6.2 Module gen_iq_handler</A>
|
||||
<LI CLASS="li-toc"><A HREF="#htoc15">6.3 Services</A>
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
<!--TOC section Introduction-->
|
||||
|
||||
<H2 CLASS="section"><A NAME="htoc1">1</A> <A NAME="intro">Introduction</A></H2><!--SEC END -->
|
||||
<H2 CLASS="section"><A NAME="htoc1">1</A> Introduction</H2><!--SEC END -->
|
||||
|
||||
<A NAME="sec:intro"></A>
|
||||
<A NAME="sec:intr"></A>
|
||||
|
||||
<TT>ejabberd</TT> is a free and open source instant messaging server written in <A HREF="http://www.erlang.org/">Erlang</A>.<BR>
|
||||
<TT>ejabberd</TT> is a free (GPL) distributed fault-tolerant Jabber/XMPP server and is mainly 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>
|
||||
<TT>ejabberd</TT> is designed to be a stable, standards compliant, and feature rich Jabber/XMPP server.<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>
|
||||
<TT>ejabberd</TT> is suitable for small servers, whether they need to be scalable or not, as well as extremely big servers.<BR>
|
||||
<BR>
|
||||
<!--TOC subsection Key Features-->
|
||||
|
||||
<H3 CLASS="subsection"><A NAME="htoc2">1.1</A> <A NAME="keyfeatures">Key Features</A></H3><!--SEC END -->
|
||||
<H3 CLASS="subsection"><A NAME="htoc2">1.1</A> Key Features</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>
|
||||
Multiplatform: <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>
|
||||
<LI CLASS="li-itemize">Distributed: You can run <TT>ejabberd</TT> on a cluster of machines and all of them will serve one Jabber domain. 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>
|
||||
<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">Straightforward installers for Windows and Linux.
|
||||
<LI CLASS="li-itemize">Web interface for administration tasks.
|
||||
<LI CLASS="li-itemize">Shared Roster Groups.
|
||||
<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.
|
||||
@@ -119,25 +118,25 @@ Comprehensive documentation.
|
||||
<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.
|
||||
Translated in 11 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.
|
||||
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> <A NAME="addfeatures">Additional Features</A></H3><!--SEC END -->
|
||||
<H3 CLASS="subsection"><A NAME="htoc3">1.2</A> Additional Features</H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:addfeatures"></A>
|
||||
|
||||
Moreover, <TT>ejabberd</TT> comes with a wide range of other state-of-the-art features:
|
||||
Besides common Jabber server features, <TT>ejabberd</TT> comes with a wide range of other features:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Modular
|
||||
Modular: <TT>ejabberd</TT>'s modular architecture allows easy customization:
|
||||
<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.
|
||||
@@ -146,39 +145,42 @@ Load only the modules you want.
|
||||
<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">Obsolete SSL for c2s connections also supported.
|
||||
<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.
|
||||
Native PostgreSQL support.
|
||||
<LI CLASS="li-itemize">Mnesia.
|
||||
<LI CLASS="li-itemize">ODBC data storage support.
|
||||
<LI CLASS="li-itemize">Microsoft SQL Server support.
|
||||
<LI CLASS="li-itemize">ODBC data storage support.
|
||||
</UL>
|
||||
<LI CLASS="li-itemize">Authentication
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
LDAP and ODBC.
|
||||
LDAP.
|
||||
<LI CLASS="li-itemize">External Authentication script.
|
||||
<LI CLASS="li-itemize">Internal Authentication.
|
||||
</UL>
|
||||
<LI CLASS="li-itemize">The ability to interface via external components with networks such as:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
AIM
|
||||
<LI CLASS="li-itemize">ICQ
|
||||
<LI CLASS="li-itemize">MSN
|
||||
</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.
|
||||
IPv6 support both for c2s and s2s connections.
|
||||
<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"><A HREF="http://www.jabber.org/jeps/jep-0045.html">Multi-User Chat</A> module.
|
||||
<LI CLASS="li-itemize">IRC transport.
|
||||
<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0060.html">Publish-Subscribe</A> component.
|
||||
<LI CLASS="li-itemize">Users Directory based on users vCards.
|
||||
<LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A>).
|
||||
</UL>
|
||||
</UL>
|
||||
<!--TOC section How it Works-->
|
||||
<!--TOC section How it works-->
|
||||
|
||||
<H2 CLASS="section"><A NAME="htoc4">2</A> How it Works</H2><!--SEC END -->
|
||||
<H2 CLASS="section"><A NAME="htoc4">2</A> 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
|
||||
@@ -236,9 +238,9 @@ 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-->
|
||||
<!--TOC section XML representation-->
|
||||
|
||||
<H2 CLASS="section"><A NAME="htoc9">3</A> XML Representation</H2><!--SEC END -->
|
||||
<H2 CLASS="section"><A NAME="htoc9">3</A> XML representation</H2><!--SEC END -->
|
||||
|
||||
<A NAME="sec:xmlrepr"></A>
|
||||
Each XML stanza is represented as the following tuple:
|
||||
@@ -326,14 +328,21 @@ Err = term()
|
||||
</PRE>Parses <TT>Str</TT> using XML parser, returns either parsed element or error
|
||||
tuple.
|
||||
</DL>
|
||||
<!--TOC section Modules-->
|
||||
<!--TOC section <TT>ejabberd</TT> modules-->
|
||||
|
||||
<H2 CLASS="section"><A NAME="htoc12">6</A> Modules</H2><!--SEC END -->
|
||||
<H2 CLASS="section"><A NAME="htoc12">6</A> <TT>ejabberd</TT> modules</H2><!--SEC END -->
|
||||
|
||||
<A NAME="sec:emods"></A>
|
||||
<!--TOC subsection gen_mod behaviour-->
|
||||
|
||||
<H3 CLASS="subsection"><A NAME="htoc13">6.1</A> gen_mod behaviour</H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:genmod"></A>
|
||||
TBD<BR>
|
||||
<BR>
|
||||
<!--TOC subsection Module gen_iq_handler-->
|
||||
|
||||
<H3 CLASS="subsection"><A NAME="htoc13">6.1</A> Module gen_iq_handler</H3><!--SEC END -->
|
||||
<H3 CLASS="subsection"><A NAME="htoc14">6.2</A> 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
|
||||
@@ -402,9 +411,12 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
</PRE>
|
||||
<!--TOC subsection Services-->
|
||||
|
||||
<H3 CLASS="subsection"><A NAME="htoc14">6.2</A> Services</H3><!--SEC END -->
|
||||
<H3 CLASS="subsection"><A NAME="htoc15">6.3</A> Services</H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:services"></A>
|
||||
TBD<BR>
|
||||
<BR>
|
||||
TODO: use <CODE>proc_lib</CODE>
|
||||
<PRE CLASS="verbatim">
|
||||
-module(mod_echo).
|
||||
|
||||
|
||||
+9
-16
@@ -29,31 +29,24 @@
|
||||
|
||||
%% 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{\modecho}{\module{mod\_echo}}
|
||||
\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
|
||||
@@ -96,7 +89,7 @@
|
||||
% Input introduction.tex
|
||||
\input{introduction}
|
||||
|
||||
\section{How it Works}
|
||||
\section{How it works}
|
||||
\label{sec:howitworks}
|
||||
|
||||
|
||||
@@ -157,7 +150,7 @@ does not exist, then it is opened and registered.
|
||||
|
||||
|
||||
|
||||
\section{XML Representation}
|
||||
\section{XML representation}
|
||||
\label{sec:xmlrepr}
|
||||
|
||||
Each XML stanza is represented as the following tuple:
|
||||
@@ -261,14 +254,14 @@ Err = term()
|
||||
\end{description}
|
||||
|
||||
|
||||
\section{Modules}
|
||||
\section{\ejabberd{} modules}
|
||||
\label{sec:emods}
|
||||
|
||||
|
||||
%\subsection{gen\_mod behaviour}
|
||||
%\label{sec:genmod}
|
||||
\subsection{gen\_mod behaviour}
|
||||
\label{sec:genmod}
|
||||
|
||||
%TBD
|
||||
TBD
|
||||
|
||||
\subsection{Module gen\_iq\_handler}
|
||||
\label{sec:geniqhandl}
|
||||
@@ -352,10 +345,10 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
\subsection{Services}
|
||||
\label{sec:services}
|
||||
|
||||
%TBD
|
||||
TBD
|
||||
|
||||
|
||||
%TODO: use \verb|proc_lib|
|
||||
TODO: use \verb|proc_lib|
|
||||
\begin{verbatim}
|
||||
-module(mod_echo).
|
||||
|
||||
|
||||
@@ -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 –
|
||||
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. —
|
||||
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. —
|
||||
Peter Saint-André, 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 —
|
||||
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>
|
||||
+8
-10
@@ -9,7 +9,7 @@
|
||||
Feature\ Sheet,pdfauthor=Sander\
|
||||
Devrieze,pdfsubject=ejabberd,pdfkeywords=ejabberd]{hyperref}
|
||||
\usepackage{verbatim}
|
||||
\usepackage{color}
|
||||
\usepackage{xcolor}
|
||||
|
||||
%% Index
|
||||
% Remove the index anchors from the HTML version to save size and bandwith.
|
||||
@@ -49,14 +49,11 @@
|
||||
% 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
|
||||
\newcommand{\new}{\begin{latexonly}\marginpar{\textcolor{red}{\textsc{new}}}\end{latexonly}} % Highlight new features
|
||||
\newcommand{\improved}{\begin{latexonly}\marginpar{\textcolor{orange}{\textsc{improved}}}\end{latexonly}} % Highlight improved features
|
||||
\newcommand{\moreinfo}[1]{} % Hide details
|
||||
\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
|
||||
@@ -70,7 +67,7 @@
|
||||
%% Fancy header
|
||||
\fancyhf{}
|
||||
\pagestyle{fancy}
|
||||
\rhead{\textcolor{ejblue}{The Expandable Jabber Daemon.}}
|
||||
\rhead{\textcolor{ejblue}{The expandable Jabber daemon.}}
|
||||
\renewcommand{\headrule}{{\color{ejblue}%
|
||||
\hrule width\headwidth height\headrulewidth \vskip-\headrulewidth}}
|
||||
\lhead{\setlength{\unitlength}{-6mm}
|
||||
@@ -88,7 +85,7 @@
|
||||
|
||||
\begin{document}
|
||||
|
||||
\label{titlepage}
|
||||
\label{sec:titlepage}
|
||||
\begin{titlepage}
|
||||
\maketitle{}
|
||||
|
||||
@@ -110,9 +107,10 @@
|
||||
% the same identifier".
|
||||
\begin{latexonly}
|
||||
\setcounter{page}{2}
|
||||
\pagecolor{ejgreenwhite}
|
||||
\end{latexonly}
|
||||
|
||||
\pagecolor{ejgreenwhite}
|
||||
|
||||
% Input introduction.tex
|
||||
\input{introduction}
|
||||
|
||||
|
||||
+1091
-1980
File diff suppressed because it is too large
Load Diff
+909
-1696
File diff suppressed because it is too large
Load Diff
+33
-40
@@ -1,31 +1,25 @@
|
||||
\section{\aname{intro}{Introduction}}
|
||||
\label{sec:intro}
|
||||
\section{Introduction}
|
||||
\label{sec:intr}
|
||||
|
||||
\quoting{I just tried out ejabberd and was impressed both by ejabberd itself and the language it is written in, Erlang. ---
|
||||
\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 free (GPL) distributed fault-tolerant \Jabber{}/XMPP server and is mainly written in \footahref{http://www.erlang.org/}{Erlang}.
|
||||
|
||||
\ejabberd{} is a \marking{free and open source} instant messaging server written in \footahref{http://www.erlang.org/}{Erlang}.
|
||||
\ejabberd{} is designed to be a \marking{stable}, \marking{standards compliant}, and \marking{\mbox{feature rich}} \Jabber{}/XMPP server.
|
||||
|
||||
\ejabberd{} is \marking{cross-platform}, distributed, fault-tolerant, and based on open standards to achieve real-time communication.
|
||||
\ejabberd{} is suitable for small servers, whether they need to be scalable or not, as well as extremely big servers.
|
||||
|
||||
\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}
|
||||
%\subsection{Layout with example deployment (title needs a better name)}
|
||||
|
||||
%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}
|
||||
%Some small images of Jabber clients that are known to work greatly with ejabberd. Less text!!!
|
||||
|
||||
%\subsection{\aname{trytoday}{Try It Today}}
|
||||
%\label{sec:trytoday}
|
||||
%\subsection{Try It Today}
|
||||
|
||||
%(Not sure if I will include/finish this section for the next version.)
|
||||
|
||||
@@ -38,42 +32,42 @@ Joeri}
|
||||
%\end{itemize}
|
||||
|
||||
\newpage
|
||||
\subsection{\aname{keyfeatures}{Key Features}}
|
||||
\subsection{Key Features}
|
||||
\label{sec:keyfeatures}
|
||||
\ind{features!key features}
|
||||
|
||||
\quoting{Erlang seems to be tailor-made for writing stable, robust servers. ---
|
||||
\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{Multiplatform:} \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{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 Comprehensive documentation.\moreinfo{ --- You can start in the \footahref{http://ejabberd.jabber.ru/book}{ejabberd Book}.}
|
||||
\item Straightforward installers for Linux, Mac OS X, and Windows.\improved{}\moreinfo{ --- (\footahref{http://ejabberd.jabber.ru/screenshots-linux-installer}{Screenshots}).}
|
||||
\item Web interface for administration tasks.\moreinfo{ --- With HTTPS secure access. \footahref{http://ejabberd.jabber.ru/online-demo-webadmin}{Demo}.}
|
||||
\item Shared Roster Groups.\moreinfo{ --- The administrator can setup a common list of \Jabber{} users for all users on the server. Those users are virtually added to all rosters. They cannot be removed, but can be renamed or moved into different roster groups. Does not require client implementation. Not related to \jepref{0144} (Roster Item Exchange).\footahref{http://ejabberd.jabber.ru/screenshots-shared-roster-groups}{Screenshots})}
|
||||
\item Command line administration tool.\improved{}\moreinfo{ --- Some basic administration tasks can be acomplished using the command line: register/remove users, backup/restore database, amongst others (\footahref{http://ejabberd.jabber.ru/screenshots-administration#ejabberdctl}{Screenshots}).}
|
||||
\item Can integrate with existing authentication mechanisms.
|
||||
\item Capability to send announce messages.
|
||||
\item Capability to send announce messages.\improved{}
|
||||
\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 Translated in 11 languages.\moreinfo{ --- More information is available \footahref{http://ejabberd.jabber.ru/localization}{here}.}
|
||||
\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 Fully XMPP compliant \moreinfo{ --- ejabberd is fully compliant with XMPP Core 1.0 and XMPP IM 1.0. Check the \footahref{http://ejabberd.jabber.ru/protocols}{supported protocols}.}
|
||||
\item XML-based protocol
|
||||
\item \footahref{http://ejabberd.jabber.ru/protocols}{Many JEPs supported}.
|
||||
\end{itemize}
|
||||
|
||||
@@ -81,51 +75,50 @@ Peter Saint-Andr\'e, Executive Director of the Jabber Software Foundation}
|
||||
|
||||
\newpage
|
||||
|
||||
\subsection{\aname{addfeatures}{Additional Features}}
|
||||
\subsection{Additional Features}
|
||||
\label{sec:addfeatures}
|
||||
\ind{features!additional features}
|
||||
|
||||
\quoting{ejabberd is making inroads to solving the "buggy incomplete server" problem ---
|
||||
\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:
|
||||
Besides common \Jabber{} server features, \ejabberd{} comes with a wide range of other features:
|
||||
\begin{itemize}
|
||||
\item Modular
|
||||
\begin{itemize}
|
||||
\item Load only the modules you want.
|
||||
\item Extend \ejabberd{} with your own custom modules.
|
||||
\item Extend \ejabberd{} with your own custom modules.\moreinfo{ --- A list of contributed modules and patches is available on the \footahref{http://ejabberd.jabber.ru/contributions}{contributions page}.}
|
||||
\end{itemize}
|
||||
\item Security
|
||||
\begin{itemize}
|
||||
\item SASL and STARTTLS for c2s and s2s connections.
|
||||
\item SASL and STARTTLS for c2s and s2s connections.\improved{}
|
||||
\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 MySQL support.\new{}
|
||||
\item Native PostgreSQL support.
|
||||
\item Mnesia.
|
||||
\item ODBC data storage support.
|
||||
\item Microsoft SQL Server support.\new{}
|
||||
\item ODBC data storage support. \moreinfo{ --- ODBC requests can be load balanced between several connections.}
|
||||
\end{itemize}
|
||||
\item Authentication
|
||||
\begin{itemize}
|
||||
\item LDAP and ODBC.\improved{}
|
||||
\item LDAP and ODBC. \moreinfo{ --- Accounts can authenticate in a LDAP server.}
|
||||
\item External Authentication script.
|
||||
\item Internal Authentication.
|
||||
\end{itemize}
|
||||
\item Others
|
||||
\begin{itemize}
|
||||
\item Compressing XML streams with Stream Compression (\jepref{0138}).
|
||||
\item Compressing XML streams with Stream Compression (\jepref{0138}).\new{}
|
||||
\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 Support for virtual hosting. \moreinfo{ --- Several \Jabber{} hosts can be hosted on the same \ejabberd{} instance. As simple as adding a new domain name to the list of hosts in the configuration file.}
|
||||
\item \tjepref{0025}{HTTP Polling} service.
|
||||
\item IRC transport.
|
||||
\item IRC transport.\improved{}
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
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 1.1.1 is highly recommanded.
|
||||
|
||||
ejabberd can be downloaded from the Process-one website:
|
||||
http://www.process-one.net/en/projects/ejabberd/
|
||||
|
||||
@@ -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
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
% Define ejabberd version here.
|
||||
\newcommand{\version}{1.1.2}
|
||||
\newcommand{\version}{1.1.1}
|
||||
|
||||
+1
-8
@@ -44,13 +44,6 @@ 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)
|
||||
@@ -77,7 +70,7 @@ $(ERLSHLIBS): %.so: %.c
|
||||
$(subst ../,,$(subst .so,.c,$@)) \
|
||||
$(EXPAT_LIBS) $(EXPAT_CFLAGS) \
|
||||
$(ERLANG_LIBS) $(ERLANG_CFLAGS) \
|
||||
-o $@ $(DYNAMIC_LIB_CFLAGS)
|
||||
-o $@ -fpic -shared
|
||||
|
||||
install: all
|
||||
install -d $(BEAMDIR)
|
||||
|
||||
+1
-7
@@ -171,13 +171,7 @@ match_acl(ACL, JID, Host) ->
|
||||
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
|
||||
is_glob_match(User, UR)
|
||||
end
|
||||
end,
|
||||
ets:lookup(acl, {ACL, global}) ++
|
||||
|
||||
Vendored
+1641
-2450
File diff suppressed because it is too large
Load Diff
+1
-26
@@ -37,7 +37,7 @@ 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)],
|
||||
[ --enable-roster-gateway-workaround Turn on workaround for processing gateway subscriptions],
|
||||
[case "${enableval}" in
|
||||
yes) roster_gateway_workaround=true ;;
|
||||
no) roster_gateway_workaround=false ;;
|
||||
@@ -45,15 +45,6 @@ AC_ARG_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
|
||||
@@ -66,20 +57,4 @@ AC_CONFIG_FILES([Makefile
|
||||
$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
|
||||
|
||||
@@ -46,7 +46,6 @@ start() ->
|
||||
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",
|
||||
@@ -59,7 +58,6 @@ start() ->
|
||||
SSLDir ++
|
||||
StdLibDir ++
|
||||
OpenSSLDir ++
|
||||
DBType ++
|
||||
ExpatDir ++
|
||||
ExpatLib ++
|
||||
ExpatFlag ++
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
{application, ejabberd,
|
||||
[{description, "ejabberd"},
|
||||
{vsn, "1.1.2"},
|
||||
{vsn, "1.0.0"},
|
||||
{modules, [acl,
|
||||
configure,
|
||||
cyrsasl,
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
%{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}]}.
|
||||
@@ -99,9 +97,6 @@
|
||||
% 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
|
||||
@@ -173,7 +168,7 @@
|
||||
{access_admin, muc_admin}]},
|
||||
% {mod_muc_log, []},
|
||||
% {mod_shared_roster, []},
|
||||
{mod_pubsub, [{access_createnode, pubsub_createnode}]},
|
||||
{mod_pubsub, []},
|
||||
{mod_time, []},
|
||||
{mod_last, []},
|
||||
{mod_version, []}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-define(VERSION, "1.1.2").
|
||||
-define(VERSION, "1.1.1").
|
||||
|
||||
%-define(ejabberd_debug, true).
|
||||
%-define(DBGFSM, true).
|
||||
|
||||
@@ -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) -> [].
|
||||
@@ -25,7 +25,6 @@
|
||||
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,
|
||||
@@ -131,14 +130,6 @@ is_user_exists(User, Server) ->
|
||||
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) ->
|
||||
@@ -169,7 +160,6 @@ 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,
|
||||
|
||||
@@ -149,8 +149,7 @@ check_password(User, Server, Password) ->
|
||||
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
|
||||
case ejabberd_auth:is_user_exists(User, Server) of
|
||||
true -> false;
|
||||
false -> login(User, Server)
|
||||
end.
|
||||
|
||||
+62
-299
@@ -10,21 +10,8 @@
|
||||
-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,
|
||||
@@ -42,90 +29,39 @@
|
||||
-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),
|
||||
LDAPServers = ejabberd_config:get_local_option({ldap_servers, Host}),
|
||||
RootDN = ejabberd_config:get_local_option({ldap_rootdn, Host}),
|
||||
Password = ejabberd_config:get_local_option({ldap_password, Host}),
|
||||
eldap:start_link(get_eldap_id(Host, ejabberd),
|
||||
LDAPServers, 389, RootDN, Password),
|
||||
eldap:start_link(get_eldap_id(Host, ejabberd_bind),
|
||||
LDAPServers, 389, RootDN, Password),
|
||||
ejabberd_ctl:register_commands(
|
||||
Host,
|
||||
[{"registered-users", "list all registered users"}],
|
||||
ejabberd_auth, ctl_process_get_registered),
|
||||
{ok, State}.
|
||||
|
||||
-define(REPLY_TIMEOUT, 10000).
|
||||
ok.
|
||||
|
||||
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', _} ->
|
||||
case find_user_dn(User, Server) of
|
||||
false ->
|
||||
false;
|
||||
Result ->
|
||||
Result
|
||||
DN ->
|
||||
LServer = jlib:nameprep(Server),
|
||||
case eldap:bind(get_eldap_id(LServer, ejabberd_bind),
|
||||
DN, Password) of
|
||||
ok ->
|
||||
true;
|
||||
_ ->
|
||||
false
|
||||
end
|
||||
end.
|
||||
|
||||
check_password(User, Server, Password, _StreamID, _Digest) ->
|
||||
@@ -141,13 +77,31 @@ 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
|
||||
LServer = jlib:nameprep(Server),
|
||||
Attr = ejabberd_config:get_local_option({ldap_uidattr, LServer}),
|
||||
Filter = eldap:present(Attr),
|
||||
Base = ejabberd_config:get_local_option({ldap_base, LServer}),
|
||||
case eldap:search(get_eldap_id(LServer, ejabberd),
|
||||
[{base, Base},
|
||||
{filter, Filter},
|
||||
{attributes, [Attr]}]) of
|
||||
#eldap_search_result{entries = Es} ->
|
||||
lists:flatmap(
|
||||
fun(E) ->
|
||||
case lists:keysearch(Attr, 1, E#eldap_entry.attributes) of
|
||||
{value, {_, [U]}} ->
|
||||
case jlib:nodeprep(U) of
|
||||
error ->
|
||||
[];
|
||||
LU ->
|
||||
[{LU, LServer}]
|
||||
end;
|
||||
_ ->
|
||||
[]
|
||||
end
|
||||
end, Es);
|
||||
_ ->
|
||||
[]
|
||||
end.
|
||||
|
||||
get_password(_User, _Server) ->
|
||||
@@ -157,13 +111,11 @@ 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', _} ->
|
||||
case find_user_dn(User, Server) of
|
||||
false ->
|
||||
false;
|
||||
Result ->
|
||||
Result
|
||||
_DN ->
|
||||
true
|
||||
end.
|
||||
|
||||
remove_user(_User, _Server) ->
|
||||
@@ -172,214 +124,25 @@ remove_user(_User, _Server) ->
|
||||
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;
|
||||
find_user_dn(User, Server) ->
|
||||
LServer = jlib:nameprep(Server),
|
||||
Attr = ejabberd_config:get_local_option({ldap_uidattr, LServer}),
|
||||
Filter = eldap:equalityMatch(Attr, User),
|
||||
Base = ejabberd_config:get_local_option({ldap_base, LServer}),
|
||||
case eldap:search(get_eldap_id(LServer, ejabberd),
|
||||
[{base, Base},
|
||||
{filter, Filter},
|
||||
{attributes, []}]) of
|
||||
#eldap_search_result{entries = [E | _]} ->
|
||||
E#eldap_entry.object_name;
|
||||
_ ->
|
||||
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
|
||||
}.
|
||||
get_eldap_id(Host, Name) ->
|
||||
atom_to_list(gen_mod:get_module_proc(Host, Name)).
|
||||
|
||||
+42
-19
@@ -57,8 +57,10 @@ check_password(User, Server, Password) ->
|
||||
false;
|
||||
LUser ->
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
LServer = jlib:nameprep(Server),
|
||||
case catch odbc_queries:get_password(LServer, Username) of
|
||||
case catch ejabberd_odbc:sql_query(
|
||||
jlib:nameprep(Server),
|
||||
["select password from users "
|
||||
"where username='", Username, "';"]) of
|
||||
{selected, ["password"], [{Password}]} ->
|
||||
true;
|
||||
_ ->
|
||||
@@ -72,8 +74,10 @@ check_password(User, Server, Password, StreamID, Digest) ->
|
||||
false;
|
||||
LUser ->
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
LServer = jlib:nameprep(Server),
|
||||
case catch odbc_queries:get_password(LServer, Username) of
|
||||
case catch ejabberd_odbc:sql_query(
|
||||
jlib:nameprep(Server),
|
||||
["select password from users "
|
||||
"where username='", Username, "';"]) of
|
||||
{selected, ["password"], [{Passwd}]} ->
|
||||
DigRes = if
|
||||
Digest /= "" ->
|
||||
@@ -99,7 +103,11 @@ set_password(User, Server, Password) ->
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
Pass = ejabberd_odbc:escape(Password),
|
||||
LServer = jlib:nameprep(Server),
|
||||
catch odbc_queries:set_password_t(LServer, Username, Pass)
|
||||
catch ejabberd_odbc:sql_transaction(
|
||||
LServer,
|
||||
[["delete from users where username='", Username ,"';"],
|
||||
["insert into users(username, password) "
|
||||
"values ('", Username, "', '", Pass, "');"]])
|
||||
end.
|
||||
|
||||
|
||||
@@ -110,8 +118,10 @@ try_register(User, Server, Password) ->
|
||||
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
|
||||
case catch ejabberd_odbc:sql_query(
|
||||
jlib:nameprep(Server),
|
||||
["insert into users(username, password) "
|
||||
"values ('", Username, "', '", Pass, "');"]) of
|
||||
{updated, 1} ->
|
||||
{atomic, ok};
|
||||
_ ->
|
||||
@@ -124,7 +134,9 @@ dirty_get_registered_users() ->
|
||||
|
||||
get_vh_registered_users(Server) ->
|
||||
LServer = jlib:nameprep(Server),
|
||||
case catch odbc_queries:list_users(LServer) of
|
||||
case catch ejabberd_odbc:sql_query(
|
||||
LServer,
|
||||
"select username from users") of
|
||||
{selected, ["username"], Res} ->
|
||||
[{U, LServer} || {U} <- Res];
|
||||
_ ->
|
||||
@@ -137,8 +149,10 @@ get_password(User, Server) ->
|
||||
false;
|
||||
LUser ->
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
LServer = jlib:nameprep(Server),
|
||||
case catch odbc_queries:get_password(LServer, Username) of
|
||||
case catch ejabberd_odbc:sql_query(
|
||||
jlib:nameprep(Server),
|
||||
["select password from users "
|
||||
"where username='", Username, "';"]) of
|
||||
{selected, ["password"], [{Password}]} ->
|
||||
Password;
|
||||
_ ->
|
||||
@@ -152,8 +166,10 @@ get_password_s(User, Server) ->
|
||||
"";
|
||||
LUser ->
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
LServer = jlib:nameprep(Server),
|
||||
case catch odbc_queries:get_password(LServer, Username) of
|
||||
case catch ejabberd_odbc:sql_query(
|
||||
jlib:nameprep(Server),
|
||||
["select password from users "
|
||||
"where username='", Username, "';"]) of
|
||||
{selected, ["password"], [{Password}]} ->
|
||||
Password;
|
||||
_ ->
|
||||
@@ -167,8 +183,10 @@ is_user_exists(User, Server) ->
|
||||
false;
|
||||
LUser ->
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
LServer = jlib:nameprep(Server),
|
||||
case catch odbc_queries:get_password(LServer, Username) of
|
||||
case catch ejabberd_odbc:sql_query(
|
||||
jlib:nameprep(Server),
|
||||
["select password from users "
|
||||
"where username='", Username, "';"]) of
|
||||
{selected, ["password"], [{_Password}]} ->
|
||||
true;
|
||||
_ ->
|
||||
@@ -182,8 +200,9 @@ remove_user(User, Server) ->
|
||||
error;
|
||||
LUser ->
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
LServer = jlib:nameprep(Server),
|
||||
catch odbc_queries:del_user(LServer, Username),
|
||||
catch ejabberd_odbc:sql_query(
|
||||
jlib:nameprep(Server),
|
||||
["delete from users where username='", Username ,"';"]),
|
||||
ejabberd_hooks:run(remove_user, jlib:nameprep(Server),
|
||||
[User, Server])
|
||||
end.
|
||||
@@ -197,8 +216,12 @@ remove_user(User, Server, Password) ->
|
||||
Pass = ejabberd_odbc:escape(Password),
|
||||
LServer = jlib:nameprep(Server),
|
||||
F = fun() ->
|
||||
Result = odbc_queries:del_user_return_password(
|
||||
LServer, Username, Pass),
|
||||
Result = 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, "';"]),
|
||||
case Result of
|
||||
{selected, ["password"], [{Password}]} ->
|
||||
ejabberd_hooks:run(remove_user, jlib:nameprep(Server),
|
||||
@@ -210,6 +233,6 @@ remove_user(User, Server, Password) ->
|
||||
not_allowed
|
||||
end
|
||||
end,
|
||||
{atomic, Result} = odbc_queries:transaction(LServer, F),
|
||||
{atomic, Result } = ejabberd_odbc:transaction(LServer, F),
|
||||
Result
|
||||
end.
|
||||
|
||||
+1
-16
@@ -1109,7 +1109,6 @@ handle_info({route, From, To, Packet}, StateName, 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),
|
||||
@@ -1365,7 +1364,6 @@ presence_update(From, Packet, StateData) ->
|
||||
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
|
||||
@@ -1729,19 +1727,6 @@ resend_offline_messages(#state{user = User,
|
||||
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) ->
|
||||
@@ -1769,7 +1754,7 @@ process_unauthenticated_stanza(StateData, El) ->
|
||||
% 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]},
|
||||
sub_el = [?ERR_FEATURE_NOT_IMPLEMENTED]},
|
||||
Res1 = jlib:replace_from_to(
|
||||
jlib:make_jid("", StateData#state.server, ""),
|
||||
jlib:make_jid("", "", ""),
|
||||
|
||||
+2
-27
@@ -8,7 +8,6 @@
|
||||
|
||||
-module(ejabberd_ctl).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start/0,
|
||||
init/0,
|
||||
@@ -19,7 +18,6 @@
|
||||
unregister_commands/4]).
|
||||
|
||||
-include("ejabberd_ctl.hrl").
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
start() ->
|
||||
case init:get_plain_arguments() of
|
||||
@@ -124,20 +122,12 @@ process(["load", Path]) ->
|
||||
end;
|
||||
|
||||
process(["restore", Path]) ->
|
||||
case ejabberd_admin:restore(Path) of
|
||||
case mnesia:restore(Path, [{default_op, keep_tables}]) 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;
|
||||
|
||||
@@ -175,21 +165,6 @@ 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 ->
|
||||
@@ -232,7 +207,6 @@ print_usage() ->
|
||||
{"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 =
|
||||
@@ -349,3 +323,4 @@ dump_tab(F, T) ->
|
||||
fun() -> mnesia:match_object(T, W, read) end),
|
||||
lists:foreach(
|
||||
fun(Term) -> io:format(F,"~p.~n", [setelement(1, Term, T)]) end, All).
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@ 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,
|
||||
case ejabberd_hooks:run_fold(filter_packet, LOrigDstDomain,
|
||||
{OrigFrom, OrigTo, OrigPacket}, []) of
|
||||
{From, To, Packet} ->
|
||||
LDstDomain = To#jid.lserver,
|
||||
|
||||
+1
-19
@@ -19,9 +19,7 @@
|
||||
get_key/1,
|
||||
try_register/1,
|
||||
remove_connection/1,
|
||||
dirty_get_connections/0,
|
||||
ctl_process/2
|
||||
]).
|
||||
dirty_get_connections/0]).
|
||||
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
@@ -29,7 +27,6 @@
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
-include("ejabberd_ctl.hrl").
|
||||
|
||||
-record(s2s, {fromto, pid, key}).
|
||||
-record(state, {}).
|
||||
@@ -115,10 +112,6 @@ init([]) ->
|
||||
{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{}}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
@@ -247,17 +240,6 @@ find_connection(From, To) ->
|
||||
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] ->
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
-module(ejabberd_s2s_in).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-behaviour(gen_fsm).
|
||||
|
||||
@@ -149,7 +150,7 @@ 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
|
||||
{"jabber:server", "jabber:server:dialback", true} when
|
||||
StateData#state.tls and (not StateData#state.authenticated) ->
|
||||
send_text(StateData, ?STREAM_HEADER(" version='1.0'")),
|
||||
SASL =
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
-module(ejabberd_s2s_out).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-behaviour(gen_fsm).
|
||||
|
||||
@@ -45,7 +46,6 @@
|
||||
tls_enabled = false,
|
||||
tls_options = [],
|
||||
authenticated = false,
|
||||
db_enabled = true,
|
||||
try_auth = true,
|
||||
myname, server, queue,
|
||||
new = false, verify = false,
|
||||
@@ -224,7 +224,12 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
|
||||
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}};
|
||||
?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}};
|
||||
_ ->
|
||||
send_text(StateData, ?INVALID_NAMESPACE_ERR),
|
||||
{stop, normal, StateData}
|
||||
@@ -367,15 +372,8 @@ wait_for_features({xmlstreamelement, El}, StateData) ->
|
||||
{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}}
|
||||
send_db_request(StateData)
|
||||
end;
|
||||
_ ->
|
||||
send_text(StateData,
|
||||
|
||||
+56
-79
@@ -8,6 +8,7 @@
|
||||
|
||||
-module(ejabberd_sm).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
@@ -41,9 +42,6 @@
|
||||
-record(session, {sid, usr, us, priority}).
|
||||
-record(state, {}).
|
||||
|
||||
%% default value for the maximum number of user connections
|
||||
-define(MAX_USER_SESSIONS, infinity).
|
||||
|
||||
%%====================================================================
|
||||
%% API
|
||||
%%====================================================================
|
||||
@@ -65,7 +63,6 @@ route(From, To, Packet) ->
|
||||
|
||||
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]).
|
||||
@@ -180,7 +177,6 @@ init([]) ->
|
||||
{"connected-users-number", "print a number of established sessions"},
|
||||
{"user-resources user server", "print user's connected resources"}],
|
||||
?MODULE, ctl_process),
|
||||
|
||||
{ok, #state{}}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
@@ -274,7 +270,23 @@ set_session(SID, User, Server, Resource, Priority) ->
|
||||
us = US,
|
||||
priority = Priority})
|
||||
end,
|
||||
mnesia:sync_dirty(F).
|
||||
mnesia:sync_dirty(F),
|
||||
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.
|
||||
|
||||
|
||||
clean_table_from_bad_node(Node) ->
|
||||
F = fun() ->
|
||||
@@ -305,35 +317,32 @@ do_route(From, To, Packet) ->
|
||||
{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]),
|
||||
[User, Server, From, subscribe]),
|
||||
true};
|
||||
"subscribed" ->
|
||||
{ejabberd_hooks:run_fold(
|
||||
roster_in_subscription,
|
||||
LServer,
|
||||
false,
|
||||
[User, Server, From, subscribed, ""]),
|
||||
[User, Server, From, subscribed]),
|
||||
true};
|
||||
"unsubscribe" ->
|
||||
{ejabberd_hooks:run_fold(
|
||||
roster_in_subscription,
|
||||
LServer,
|
||||
false,
|
||||
[User, Server, From, unsubscribe, ""]),
|
||||
[User, Server, From, unsubscribe]),
|
||||
true};
|
||||
"unsubscribed" ->
|
||||
{ejabberd_hooks:run_fold(
|
||||
roster_in_subscription,
|
||||
LServer,
|
||||
false,
|
||||
[User, Server, From, unsubscribed, ""]),
|
||||
[User, Server, From, unsubscribed]),
|
||||
true};
|
||||
_ ->
|
||||
{true, false}
|
||||
@@ -342,18 +351,39 @@ do_route(From, To, Packet) ->
|
||||
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);
|
||||
if
|
||||
PResources /= [] ->
|
||||
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 ->
|
||||
if
|
||||
Subsc ->
|
||||
case ejabberd_auth:is_user_exists(
|
||||
LUser, LServer) of
|
||||
true ->
|
||||
ejabberd_hooks:run(
|
||||
offline_subscription_hook,
|
||||
LServer,
|
||||
[From, To, Packet]);
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_SERVICE_UNAVAILABLE),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end;
|
||||
true ->
|
||||
ok
|
||||
end
|
||||
end;
|
||||
true ->
|
||||
ok
|
||||
end;
|
||||
@@ -479,59 +509,6 @@ get_user_present_resources(LUser, LServer) ->
|
||||
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.
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
@@ -555,7 +532,7 @@ process_iq(From, To, Packet) ->
|
||||
From, To, IQ);
|
||||
[] ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_SERVICE_UNAVAILABLE),
|
||||
Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end;
|
||||
reply ->
|
||||
|
||||
@@ -6,13 +6,6 @@ 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
|
||||
@@ -33,7 +26,7 @@ $(OUTDIR)/%.beam: %.erl
|
||||
$(ERLSHLIBS): ../%.so: %.c
|
||||
$(CC) -Wall $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \
|
||||
$(subst ../,,$(subst .so,.c,$@)) $(LIBS) \
|
||||
-o $@ $(DYNAMIC_LIB_CFLAGS)
|
||||
-o $@ -fpic -shared
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(ERLSHLIBS)
|
||||
|
||||
+2
-4
@@ -74,7 +74,7 @@ export_roster(Server, Output) ->
|
||||
" and jid='", SJID, "';"
|
||||
"insert into rosterusers("
|
||||
" username, jid, nick, "
|
||||
" subscription, ask, askmessage, "
|
||||
" subscription, ask, "
|
||||
" server, subscribe, type) "
|
||||
" values ", ItemVals, ";"
|
||||
"delete from rostergroups "
|
||||
@@ -271,8 +271,7 @@ output(LServer, IO, SQL) ->
|
||||
record_to_string(#roster{usj = {User, Server, JID},
|
||||
name = Name,
|
||||
subscription = Subscription,
|
||||
ask = Ask,
|
||||
askmessage = AskMessage}) ->
|
||||
ask = Ask}) ->
|
||||
Username = ejabberd_odbc:escape(User),
|
||||
SJID = ejabberd_odbc:escape(jlib:jid_to_string(JID)),
|
||||
Nick = ejabberd_odbc:escape(Name),
|
||||
@@ -296,7 +295,6 @@ record_to_string(#roster{usj = {User, Server, JID},
|
||||
"'", Nick, "',"
|
||||
"'", SSubscription, "',"
|
||||
"'", SAsk, "',"
|
||||
"'", AskMessage, "',"
|
||||
"'N', '', 'item')"].
|
||||
|
||||
groups_to_string(#roster{usj = {User, Server, JID},
|
||||
|
||||
@@ -12,8 +12,7 @@ OUTDIR = ..
|
||||
EFLAGS = -I .. -pz ..
|
||||
OBJS = \
|
||||
$(OUTDIR)/eldap.beam \
|
||||
$(OUTDIR)/ELDAPv3.beam \
|
||||
$(OUTDIR)/eldap_filter.beam
|
||||
$(OUTDIR)/ELDAPv3.beam
|
||||
|
||||
all: $(OBJS)
|
||||
|
||||
|
||||
@@ -6,8 +6,7 @@ EFLAGS = -I .. -pz ..
|
||||
|
||||
OBJS = \
|
||||
$(OUTDIR)\eldap.beam \
|
||||
$(OUTDIR)\ELDAPv3.beam \
|
||||
$(OUTDIR)\eldap_filter.beam
|
||||
$(OUTDIR)\ELDAPv3.beam
|
||||
|
||||
ALL : $(OBJS)
|
||||
|
||||
|
||||
+1
-1
@@ -808,7 +808,7 @@ polish([], Res, Ref) ->
|
||||
%%-----------------------------------------------------------------------
|
||||
connect_bind(S) ->
|
||||
Host = next_host(S#eldap.host, S#eldap.hosts),
|
||||
TcpOpts = [{packet, asn1}, {active, true}, {keepalive, true}, binary],
|
||||
TcpOpts = [{packet, asn1}, {active, true}, binary],
|
||||
case gen_tcp:connect(Host, S#eldap.port, TcpOpts) of
|
||||
{ok, Socket} ->
|
||||
case bind_request(Socket, S) of
|
||||
|
||||
@@ -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.
|
||||
@@ -181,9 +181,6 @@ string_to_jid1([], "") ->
|
||||
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) ->
|
||||
|
||||
@@ -1126,7 +1126,8 @@ set_form(_Host, ["running nodes", ENode, "backup", "restore"], _Lang, XData) ->
|
||||
false ->
|
||||
{error, ?ERR_BAD_REQUEST};
|
||||
{value, {_, [String]}} ->
|
||||
case rpc:call(Node, ejabberd_admin, restore, [String]) of
|
||||
case rpc:call(Node, mnesia, restore,
|
||||
[String, [{default_op, keep_tables}]]) of
|
||||
{badrpc, _Reason} ->
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, _Reason} ->
|
||||
|
||||
@@ -6,13 +6,6 @@ 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
|
||||
@@ -35,7 +28,7 @@ $(OUTDIR)/%.beam: %.erl
|
||||
$(ERLSHLIBS): ../%.so: %.c
|
||||
$(CC) -Wall $(INCLUDES) $(CFLAGS) $(LDFLAGS) \
|
||||
$(subst ../,,$(subst .so,.c,$@)) $(LIBS) \
|
||||
-o $@ $(DYNAMIC_LIB_CFLAGS)
|
||||
-o $@ -fpic -shared
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(ERLSHLIBS)
|
||||
|
||||
@@ -291,7 +291,7 @@ iq_disco() ->
|
||||
[{xmlelement, "identity",
|
||||
[{"category", "conference"},
|
||||
{"type", "irc"},
|
||||
{"name", "IRC Transport"}], []},
|
||||
{"name", "ejabberd/mod_irc"}], []},
|
||||
{xmlelement, "feature",
|
||||
[{"var", ?NS_MUC}], []},
|
||||
{xmlelement, "feature",
|
||||
|
||||
+12
-4
@@ -95,7 +95,10 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||
|
||||
get_last(IQ, SubEl, LUser, LServer) ->
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
case catch odbc_queries:get_last(LServer, Username) of
|
||||
case catch ejabberd_odbc:sql_query(
|
||||
LServer,
|
||||
["select seconds, state from last "
|
||||
"where username='", Username, "';"]) of
|
||||
{'EXIT', _Reason} ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
|
||||
{selected, ["seconds","state"], []} ->
|
||||
@@ -128,11 +131,16 @@ store_last_info(User, Server, TimeStamp, Status) ->
|
||||
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).
|
||||
|
||||
%% 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, "');"]]).
|
||||
|
||||
remove_user(User, Server) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
odbc_queries:del_last(LServer, Username).
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
["delete from last where username='", Username, "';"]).
|
||||
|
||||
+11
-17
@@ -36,7 +36,7 @@
|
||||
-record(muc_online_room, {name_host, pid}).
|
||||
-record(muc_registered, {us_host, nick}).
|
||||
|
||||
-record(state, {host, server_host, access, history_size}).
|
||||
-record(state, {host, server_host, access}).
|
||||
|
||||
-define(PROCNAME, ejabberd_mod_muc).
|
||||
|
||||
@@ -148,17 +148,14 @@ init([Host, Opts]) ->
|
||||
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),
|
||||
load_permanent_rooms(MyHost, Host, {Access, AccessCreate, AccessAdmin}),
|
||||
{ok, #state{host = MyHost,
|
||||
server_host = Host,
|
||||
access = {Access, AccessCreate, AccessAdmin},
|
||||
history_size = HistorySize}}.
|
||||
access = {Access, AccessCreate, AccessAdmin}}}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
|
||||
@@ -190,9 +187,8 @@ handle_cast(_Msg, State) ->
|
||||
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
|
||||
access = Access} = State) ->
|
||||
case catch do_route(Host, ServerHost, Access, From, To, Packet) of
|
||||
{'EXIT', Reason} ->
|
||||
?ERROR_MSG("~p", [Reason]);
|
||||
_ ->
|
||||
@@ -243,11 +239,11 @@ stop_supervisor(Host) ->
|
||||
supervisor:terminate_child(ejabberd_sup, Proc),
|
||||
supervisor:delete_child(ejabberd_sup, Proc).
|
||||
|
||||
do_route(Host, ServerHost, Access, HistorySize, From, To, Packet) ->
|
||||
do_route(Host, ServerHost, Access, 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);
|
||||
do_route1(Host, ServerHost, Access, From, To, Packet);
|
||||
_ ->
|
||||
{xmlelement, _Name, Attrs, _Els} = Packet,
|
||||
Lang = xml:get_attr_s("xml:lang", Attrs),
|
||||
@@ -258,7 +254,7 @@ do_route(Host, ServerHost, Access, HistorySize, From, To, Packet) ->
|
||||
end.
|
||||
|
||||
|
||||
do_route1(Host, ServerHost, Access, HistorySize, From, To, Packet) ->
|
||||
do_route1(Host, ServerHost, Access, From, To, Packet) ->
|
||||
{_AccessRoute, AccessCreate, AccessAdmin} = Access,
|
||||
{Room, _, Nick} = jlib:jid_tolower(To),
|
||||
{xmlelement, Name, Attrs, _Els} = Packet,
|
||||
@@ -383,8 +379,7 @@ do_route1(Host, ServerHost, Access, HistorySize, From, To, Packet) ->
|
||||
?DEBUG("MUC: open new room '~s'~n", [Room]),
|
||||
{ok, Pid} = mod_muc_room:start(
|
||||
Host, ServerHost, Access,
|
||||
Room, HistorySize, From,
|
||||
Nick),
|
||||
Room, From, Nick),
|
||||
ets:insert(
|
||||
muc_online_room,
|
||||
#muc_online_room{name_host = {Room, Host},
|
||||
@@ -416,7 +411,7 @@ do_route1(Host, ServerHost, Access, HistorySize, From, To, Packet) ->
|
||||
|
||||
|
||||
|
||||
load_permanent_rooms(Host, ServerHost, Access, HistorySize) ->
|
||||
load_permanent_rooms(Host, ServerHost, Access) ->
|
||||
case catch mnesia:dirty_select(
|
||||
muc_room, [{#muc_room{name_host = {'_', Host}, _ = '_'},
|
||||
[],
|
||||
@@ -432,7 +427,6 @@ load_permanent_rooms(Host, ServerHost, Access, HistorySize) ->
|
||||
ServerHost,
|
||||
Access,
|
||||
Room,
|
||||
HistorySize,
|
||||
R#muc_room.opts),
|
||||
ets:insert(
|
||||
muc_online_room,
|
||||
@@ -446,7 +440,7 @@ iq_disco_info() ->
|
||||
[{xmlelement, "identity",
|
||||
[{"category", "conference"},
|
||||
{"type", "text"},
|
||||
{"name", "Chatrooms"}], []},
|
||||
{"name", "ejabberd/mod_muc"}], []},
|
||||
{xmlelement, "feature", [{"var", ?NS_MUC}], []},
|
||||
{xmlelement, "feature", [{"var", ?NS_REGISTER}], []},
|
||||
{xmlelement, "feature", [{"var", ?NS_VCARD}], []}].
|
||||
|
||||
+23
-192
@@ -179,10 +179,10 @@ add_to_log2(text, {Nick, Packet}, Room, Opts, State) ->
|
||||
{false, false} ->
|
||||
ok;
|
||||
{false, SubEl} ->
|
||||
Message = {body, xml:get_tag_cdata(SubEl)},
|
||||
Message = {body, htmlize(xml:get_tag_cdata(SubEl))},
|
||||
add_message_to_log(Nick, Message, Room, Opts, State);
|
||||
{SubEl, _} ->
|
||||
Message = {subject, xml:get_tag_cdata(SubEl)},
|
||||
Message = {subject, htmlize(xml:get_tag_cdata(SubEl))},
|
||||
add_message_to_log(Nick, Message, Room, Opts, State)
|
||||
end;
|
||||
|
||||
@@ -238,24 +238,16 @@ get_timestamp_daydiff(TimeStamp, Daydiff) ->
|
||||
{Date2, HMS}.
|
||||
|
||||
% Try to close the previous day log, if it exists
|
||||
close_previous_log(Fn, Images_dir) ->
|
||||
close_previous_log(Fn) ->
|
||||
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>"),
|
||||
fw(F, "<div class=\"legend\">ejabberd/mod_muc log<span class=\"w3c\"><a href=\"http://validator.w3.org/check?uri=referer\"><img src=\"http://www.w3.org/Icons/valid-xhtml10\" alt=\"Valid XHTML 1.0 Transitional\" height=\"31\" width=\"88\" /></a> <a href=\"http://jigsaw.w3.org/css-validator/\"><img style=\"border:0;width:88px;height:31px\" src=\"http://jigsaw.w3.org/css-validator/images/vcss\" alt=\"Valid CSS!\" /></a></span></div></body></html>"),
|
||||
file:close(F);
|
||||
_ -> ok
|
||||
end.
|
||||
|
||||
add_message_to_log(Nick1, Message, RoomJID, Opts, State) ->
|
||||
Nick = htmlize(Nick1),
|
||||
add_message_to_log(Nick, Message, RoomJID, Opts, State) ->
|
||||
#state{out_dir = OutDir,
|
||||
dir_type = DirType,
|
||||
css_file = CSSFile,
|
||||
@@ -294,14 +286,7 @@ add_message_to_log(Nick1, Message, RoomJID, Opts, State) ->
|
||||
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)
|
||||
close_previous_log(FnYesterday)
|
||||
end,
|
||||
|
||||
% Build message
|
||||
@@ -319,33 +304,33 @@ add_message_to_log(Nick1, Message, RoomJID, Opts, State) ->
|
||||
[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)]);
|
||||
[Nick, ?T("leaves the room"), 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)]);
|
||||
[Nick, ?T("has been kicked"), 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)]);
|
||||
[Nick, ?T("has been banned"), 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)]);
|
||||
[Nick, ?T(" has set the subject to: "), 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)]);
|
||||
[Nick, string:substr(T, 5)]);
|
||||
nomatch ->
|
||||
io_lib:format("<font class=\"mn\"><~s></font> ~s<br/>",
|
||||
[Nick, htmlize(T)])
|
||||
[Nick, T])
|
||||
end
|
||||
end,
|
||||
{Hour, Minute, Second} = Time,
|
||||
@@ -406,160 +391,6 @@ make_dir_rec(Dir) ->
|
||||
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, []).
|
||||
|
||||
@@ -568,19 +399,19 @@ put_header(F, Room, Date, CSSFile, Lang, Hour_offset, Date_prev, Date_next, Top_
|
||||
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]),
|
||||
fw(F, "<title>~s - ~s</title>", [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, "<div class=\"roomtitle\"><a class=\"roomtitle\" href=\"xmpp:~s?join\">~s</a></div>", [Room#room.jid, 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\"><</a> <a class=\"nav\" href=\".\/\">^</a> <a class=\"nav\" href=\"~s\">></a></span></div>", [Date, Date_prev, Date_next]),
|
||||
case {htmlize(Room#room.subject_author), htmlize(Room#room.subject)} of
|
||||
case {Room#room.subject_author, Room#room.subject} of
|
||||
{"", ""} -> ok;
|
||||
{SuA, Su} -> fw(F, "<div class=\"roomsubject\">~s~s~s</div>", [SuA, ?T(" has set the subject to: "), Su])
|
||||
{SuA, Su} -> fw(F, "<div class=\"roomsubject\">~s~s~s</div>", [SuA, ?T(" has set the subject to: "), htmlize(Su)])
|
||||
end,
|
||||
RoomConfig = roomconfig_to_string(Room#room.config, Lang),
|
||||
put_room_config(F, RoomConfig, Lang),
|
||||
@@ -605,7 +436,7 @@ put_header_css(F, false) ->
|
||||
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.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;}"),
|
||||
@@ -654,11 +485,11 @@ htmlize(S1) ->
|
||||
S2_list).
|
||||
|
||||
htmlize2(S1) ->
|
||||
S2 = element(2, regexp:gsub(S1, "\\&", "\\&")),
|
||||
S3 = element(2, regexp:gsub(S2, "<", "\\<")),
|
||||
S4 = element(2, regexp:gsub(S3, ">", "\\>")),
|
||||
S5 = element(2, regexp:gsub(S4, "(http|ftp)://.[^ ]*", "<a href=\"&\">&</a>")),
|
||||
S5.
|
||||
S2 = element(2, regexp:gsub(S1, "<", "\\<")),
|
||||
S3 = element(2, regexp:gsub(S2, ">", "\\>")),
|
||||
S4 = element(2, regexp:gsub(S3, "(http|ftp)://.[^ ]*", "<a href=\"&\">&</a>")),
|
||||
%element(2, regexp:gsub(S4, " ", "\\ ")).
|
||||
S4.
|
||||
|
||||
get_room_info(RoomJID, Opts) ->
|
||||
Title =
|
||||
@@ -713,7 +544,7 @@ roomconfig_to_string(Options, Lang) ->
|
||||
T ->
|
||||
case Opt of
|
||||
password -> "<div class=\"rcoe\">" ++ OptText ++ "</div>";
|
||||
title -> "<div class=\"rcot\">" ++ ?T("Room title") ++ ": \"" ++ htmlize(T) ++ "\"</div>";
|
||||
title -> "<div class=\"rcot\">" ++ ?T("Room title") ++ ": \"" ++ T ++ "\"</div>";
|
||||
_ -> "\"" ++ T ++ "\""
|
||||
end
|
||||
end,
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
|
||||
|
||||
%% External exports
|
||||
-export([start_link/7,
|
||||
start_link/6,
|
||||
start/7,
|
||||
-export([start_link/6,
|
||||
start_link/5,
|
||||
start/6,
|
||||
start/5,
|
||||
route/4]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
@@ -85,22 +85,22 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% API
|
||||
%%%----------------------------------------------------------------------
|
||||
start(Host, ServerHost, Access, Room, HistorySize, Creator, Nick) ->
|
||||
start(Host, ServerHost, Access, Room, Creator, Nick) ->
|
||||
Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_muc_sup),
|
||||
supervisor:start_child(
|
||||
Supervisor, [Host, ServerHost, Access, Room, HistorySize, Creator, Nick]).
|
||||
Supervisor, [Host, ServerHost, Access, Room, Creator, Nick]).
|
||||
|
||||
start(Host, ServerHost, Access, Room, HistorySize, Opts) ->
|
||||
start(Host, ServerHost, Access, Room, Opts) ->
|
||||
Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_muc_sup),
|
||||
supervisor:start_child(
|
||||
Supervisor, [Host, ServerHost, Access, Room, HistorySize, Opts]).
|
||||
Supervisor, [Host, ServerHost, Access, Room, Opts]).
|
||||
|
||||
start_link(Host, ServerHost, Access, Room, HistorySize, Creator, Nick) ->
|
||||
gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, HistorySize, Creator, Nick],
|
||||
start_link(Host, ServerHost, Access, Room, Creator, Nick) ->
|
||||
gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, Creator, Nick],
|
||||
?FSMOPTS).
|
||||
|
||||
start_link(Host, ServerHost, Access, Room, HistorySize, Opts) ->
|
||||
gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, HistorySize, Opts],
|
||||
start_link(Host, ServerHost, Access, Room, Opts) ->
|
||||
gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, Opts],
|
||||
?FSMOPTS).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
@@ -114,22 +114,20 @@ start_link(Host, ServerHost, Access, Room, HistorySize, Opts) ->
|
||||
%% ignore |
|
||||
%% {stop, StopReason}
|
||||
%%----------------------------------------------------------------------
|
||||
init([Host, ServerHost, Access, Room, HistorySize, Creator, _Nick]) ->
|
||||
init([Host, ServerHost, Access, Room, 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]) ->
|
||||
init([Host, ServerHost, Access, Room, 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}.
|
||||
|
||||
@@ -1004,8 +1002,8 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
|
||||
true ->
|
||||
ok
|
||||
end,
|
||||
send_existing_presences(From, NewState),
|
||||
send_new_presence(From, NewState),
|
||||
send_existing_presences(From, NewState),
|
||||
Shift = count_stanza_shift(Nick, Els, NewState),
|
||||
case send_history(From, Shift, NewState) of
|
||||
true ->
|
||||
@@ -1374,10 +1372,6 @@ lqueue_new(Max) ->
|
||||
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
|
||||
@@ -2074,8 +2068,7 @@ process_iq_owner(From, get, Lang, SubEl, StateData) ->
|
||||
end.
|
||||
|
||||
check_allowed_log_change(XEl, StateData, From) ->
|
||||
case lists:keymember("muc#roomconfig_enablelogging", 1,
|
||||
jlib:parse_xdata_submit(XEl)) of
|
||||
case lists:keymember("logging", 1, jlib:parse_xdata_submit(XEl)) of
|
||||
false ->
|
||||
allow;
|
||||
true ->
|
||||
@@ -2110,56 +2103,41 @@ get_config(Lang, StateData, From) ->
|
||||
[{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",
|
||||
"title",
|
||||
Config#config.title),
|
||||
?BOOLXFIELD("Make room persistent",
|
||||
"muc#roomconfig_persistentroom",
|
||||
"persistent",
|
||||
Config#config.persistent),
|
||||
?BOOLXFIELD("Make room public searchable",
|
||||
"muc#roomconfig_publicroom",
|
||||
"public",
|
||||
Config#config.public),
|
||||
?BOOLXFIELD("Make participants list public",
|
||||
"public_list",
|
||||
Config#config.public_list),
|
||||
?BOOLXFIELD("Make room password protected",
|
||||
"muc#roomconfig_passwordprotectedroom",
|
||||
"password_protected",
|
||||
Config#config.password_protected),
|
||||
?PRIVATEXFIELD("Password",
|
||||
"muc#roomconfig_roomsecret",
|
||||
"password",
|
||||
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 semianonymous",
|
||||
"anonymous",
|
||||
Config#config.anonymous),
|
||||
?BOOLXFIELD("Make room members-only",
|
||||
"muc#roomconfig_membersonly",
|
||||
"members_only",
|
||||
Config#config.members_only),
|
||||
?BOOLXFIELD("Make room moderated",
|
||||
"muc#roomconfig_moderatedroom",
|
||||
"moderated",
|
||||
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",
|
||||
"allow_change_subj",
|
||||
Config#config.allow_change_subj),
|
||||
?BOOLXFIELD("Allow users to send private messages",
|
||||
"allow_private_messages",
|
||||
@@ -2168,7 +2146,7 @@ get_config(Lang, StateData, From) ->
|
||||
"allow_query_users",
|
||||
Config#config.allow_query_users),
|
||||
?BOOLXFIELD("Allow users to send invites",
|
||||
"muc#roomconfig_allowinvites",
|
||||
"allow_user_invites",
|
||||
Config#config.allow_user_invites)
|
||||
] ++
|
||||
case mod_muc_log:check_access_log(
|
||||
@@ -2176,7 +2154,7 @@ get_config(Lang, StateData, From) ->
|
||||
allow ->
|
||||
[?BOOLXFIELD(
|
||||
"Enable logging",
|
||||
"muc#roomconfig_enablelogging",
|
||||
"logging",
|
||||
Config#config.logging)];
|
||||
_ -> []
|
||||
end,
|
||||
@@ -2223,48 +2201,36 @@ set_config(XEl, StateData) ->
|
||||
|
||||
set_xoption([], Config) ->
|
||||
Config;
|
||||
set_xoption([{"muc#roomconfig_roomname", [Val]} | Opts], Config) ->
|
||||
set_xoption([{"title", [Val]} | Opts], Config) ->
|
||||
?SET_STRING_XOPT(title, Val);
|
||||
set_xoption([{"muc#roomconfig_changesubject", [Val]} | Opts], Config) ->
|
||||
set_xoption([{"allow_change_subj", [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_xoption([{"public", [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_xoption([{"persistent", [Val]} | Opts], Config) ->
|
||||
?SET_BOOL_XOPT(persistent, Val);
|
||||
set_xoption([{"muc#roomconfig_moderatedroom", [Val]} | Opts], Config) ->
|
||||
set_xoption([{"moderated", [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_xoption([{"members_only", [Val]} | Opts], Config) ->
|
||||
?SET_BOOL_XOPT(members_only, Val);
|
||||
set_xoption([{"muc#roomconfig_allowinvites", [Val]} | Opts], Config) ->
|
||||
set_xoption([{"allow_user_invites", [Val]} | Opts], Config) ->
|
||||
?SET_BOOL_XOPT(allow_user_invites, Val);
|
||||
set_xoption([{"muc#roomconfig_passwordprotectedroom", [Val]} | Opts], Config) ->
|
||||
set_xoption([{"password_protected", [Val]} | Opts], Config) ->
|
||||
?SET_BOOL_XOPT(password_protected, Val);
|
||||
set_xoption([{"muc#roomconfig_roomsecret", [Val]} | Opts], Config) ->
|
||||
set_xoption([{"password", [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_xoption([{"logging", [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}.
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ start(Host, _Opts) ->
|
||||
update_table(),
|
||||
ejabberd_hooks:add(offline_message_hook, Host,
|
||||
?MODULE, store_packet, 50),
|
||||
ejabberd_hooks:add(offline_subscription_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,
|
||||
@@ -81,6 +83,8 @@ receive_all(Msgs) ->
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(offline_message_hook, Host,
|
||||
?MODULE, store_packet, 50),
|
||||
ejabberd_hooks:delete(offline_subscription_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,
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
start(Host, _Opts) ->
|
||||
ejabberd_hooks:add(offline_message_hook, Host,
|
||||
?MODULE, store_packet, 50),
|
||||
ejabberd_hooks:add(offline_subscription_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,
|
||||
@@ -65,9 +67,14 @@ loop(Host) ->
|
||||
ejabberd_odbc:escape(
|
||||
lists:flatten(
|
||||
xml:element_to_string(Packet))),
|
||||
odbc_queries:add_spool_sql(Username, XML)
|
||||
["insert into spool(username, xml) "
|
||||
"values ('", Username, "', '",
|
||||
XML,
|
||||
"');"]
|
||||
end, Msgs),
|
||||
case catch odbc_queries:add_spool(Host, Query) of
|
||||
case catch ejabberd_odbc:sql_transaction(
|
||||
Host,
|
||||
Query) of
|
||||
{'EXIT', Reason} ->
|
||||
?ERROR_MSG("~p~n", [Reason]);
|
||||
_ ->
|
||||
@@ -90,6 +97,8 @@ receive_all(Msgs) ->
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(offline_message_hook, Host,
|
||||
?MODULE, store_packet, 50),
|
||||
ejabberd_hooks:delete(offline_subscription_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,
|
||||
@@ -202,7 +211,15 @@ 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
|
||||
F = fun() ->
|
||||
Result = ejabberd_odbc:sql_query_t(
|
||||
["select username, xml from spool where username='", EUser, "'"
|
||||
" order by seq;"]),
|
||||
ejabberd_odbc:sql_query_t(
|
||||
["delete from spool where username='", EUser, "';"]),
|
||||
Result
|
||||
end,
|
||||
case ejabberd_odbc:sql_transaction(LServer,F) of
|
||||
{atomic, {selected, ["username","xml"], Rs}} ->
|
||||
Ls ++ lists:flatmap(
|
||||
fun({_, XML}) ->
|
||||
@@ -232,5 +249,7 @@ remove_user(User, Server) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
odbc_queries:del_spool_msg(LServer, Username).
|
||||
ejabberd_odbc:sql_query(
|
||||
LServer,
|
||||
["delete from spool where username='", Username, "';"]).
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(state, {host, server_host, access}).
|
||||
-record(state, {host}).
|
||||
|
||||
-define(DICT, dict).
|
||||
-define(MAXITEMS, 20).
|
||||
@@ -122,7 +122,6 @@ init([ServerHost, Opts]) ->
|
||||
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),
|
||||
@@ -134,7 +133,7 @@ init([ServerHost, Opts]) ->
|
||||
end, ServedHosts),
|
||||
ets:new(gen_mod:get_module_proc(Host, pubsub_presence),
|
||||
[set, named_table]),
|
||||
{ok, #state{host = Host, server_host = ServerHost, access = Access}}.
|
||||
{ok, #state{host = Host}}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
|
||||
@@ -163,9 +162,8 @@ handle_cast(_Msg, State) ->
|
||||
%% {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
|
||||
handle_info({route, From, To, Packet}, State) ->
|
||||
case catch do_route(To#jid.lserver, From, To, Packet) of
|
||||
{'EXIT', Reason} ->
|
||||
?ERROR_MSG("~p", [Reason]);
|
||||
_ ->
|
||||
@@ -196,7 +194,7 @@ code_change(_OldVsn, State, _Extra) ->
|
||||
%%--------------------------------------------------------------------
|
||||
%%% Internal functions
|
||||
%%--------------------------------------------------------------------
|
||||
do_route(Host, ServerHost, Access, From, To, Packet) ->
|
||||
do_route(Host, From, To, Packet) ->
|
||||
{xmlelement, Name, Attrs, Els} = Packet,
|
||||
case To of
|
||||
#jid{luser = "", lresource = ""} ->
|
||||
@@ -234,7 +232,7 @@ do_route(Host, ServerHost, Access, From, To, Packet) ->
|
||||
#iq{type = Type, xmlns = ?NS_PUBSUB = XMLNS,
|
||||
sub_el = SubEl} = IQ ->
|
||||
Res =
|
||||
case iq_pubsub(Host, ServerHost, From, Type, SubEl, Access) of
|
||||
case iq_pubsub(Host, From, Type, SubEl) of
|
||||
{result, IQRes} ->
|
||||
jlib:iq_to_xml(
|
||||
IQ#iq{type = result,
|
||||
@@ -318,7 +316,7 @@ iq_disco_info(SNode) ->
|
||||
[{xmlelement, "identity",
|
||||
[{"category", "pubsub"},
|
||||
{"type", "generic"},
|
||||
{"name", "Publish-Subscribe"}], []},
|
||||
{"name", "ejabberd/mod_pubsub"}], []},
|
||||
{xmlelement, "feature", [{"var", ?NS_PUBSUB}], []},
|
||||
{xmlelement, "feature", [{"var", ?NS_PUBSUB_EVENT}], []},
|
||||
{xmlelement, "feature", [{"var", ?NS_PUBSUB_OWNER}], []},
|
||||
@@ -328,50 +326,32 @@ iq_disco_info(SNode) ->
|
||||
[]
|
||||
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,"/"),
|
||||
Node = 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,
|
||||
SubNodes = mnesia:index_read(pubsub_node,
|
||||
{Host, Node},
|
||||
#pubsub_node.host_parent),
|
||||
SubItems = lists:map(fun(#pubsub_node{host_node = {_, N}}) ->
|
||||
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,
|
||||
SN = node_to_string(Node),
|
||||
Items =
|
||||
lists:map(fun(#item{id = Name}) ->
|
||||
{xmlelement, "item",
|
||||
[{"jid", Host},
|
||||
{"node", SN ++ "!" ++ Name},
|
||||
{"name", RealName}], []}
|
||||
{"name", Name}], []}
|
||||
end, Info#nodeinfo.items),
|
||||
SubItems ++ Items;
|
||||
_ ->
|
||||
[]
|
||||
end;
|
||||
SubItems ++ Items;
|
||||
[] ->
|
||||
case Node of
|
||||
[] ->
|
||||
@@ -402,6 +382,8 @@ iq_disco_items(Host, From, SNode) ->
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||
end.
|
||||
|
||||
|
||||
|
||||
iq_get_vcard(Lang) ->
|
||||
[{xmlelement, "FN", [],
|
||||
[{xmlcdata, "ejabberd/mod_pubsub"}]},
|
||||
@@ -415,7 +397,7 @@ iq_get_vcard(Lang) ->
|
||||
"Copyright (c) 2003-2006 Alexey Shchepin")}]}].
|
||||
|
||||
|
||||
iq_pubsub(Host, ServerHost, From, Type, SubEl, Access) ->
|
||||
iq_pubsub(Host, From, Type, SubEl) ->
|
||||
{xmlelement, _, _, SubEls} = SubEl,
|
||||
case xml:remove_cdata(SubEls) of
|
||||
[{xmlelement, Name, Attrs, Els}] ->
|
||||
@@ -423,7 +405,7 @@ iq_pubsub(Host, ServerHost, From, Type, SubEl, Access) ->
|
||||
Node = string:tokens(SNode, "/"),
|
||||
case {Type, Name} of
|
||||
{set, "create"} ->
|
||||
create_new_node(Host, Node, From, ServerHost, Access);
|
||||
create_new_node(Host, Node, From);
|
||||
{set, "publish"} ->
|
||||
case xml:remove_cdata(Els) of
|
||||
[{xmlelement, "item", ItemAttrs, Payload}] ->
|
||||
@@ -502,17 +484,13 @@ iq_pubsub(Host, ServerHost, From, Type, SubEl, Access) ->
|
||||
%% 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),
|
||||
create_new_node(Host, HomeNode, Owner),
|
||||
NewNode = ["home", LOS, LOU, randoms:get_string()],
|
||||
create_new_node(Host, NewNode, Owner, ServerHost, Access);
|
||||
create_new_node(Host, NewNode, Owner);
|
||||
_ ->
|
||||
LOwner = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
|
||||
Parent = lists:sublist(Node, length(Node) - 1),
|
||||
@@ -547,7 +525,7 @@ create_new_node(Host, Node, Owner, ServerHost, Access) ->
|
||||
end
|
||||
end
|
||||
end,
|
||||
case check_create_permission(Host, Node, Owner, ServerHost, Access) of
|
||||
case check_create_permission(Host, Node, Owner) of
|
||||
true ->
|
||||
case mnesia:transaction(F) of
|
||||
{atomic, ok} ->
|
||||
@@ -1074,23 +1052,14 @@ subscription_to_string(Subscription) ->
|
||||
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 ->
|
||||
check_create_permission(Host, Node, Owner) ->
|
||||
if
|
||||
Owner#jid.lserver == Host ->
|
||||
true;
|
||||
true ->
|
||||
#jid{luser = User, lserver = Server} = Owner,
|
||||
case Node of
|
||||
["home", Server, User | _] ->
|
||||
true;
|
||||
_ ->
|
||||
false
|
||||
|
||||
+4
-12
@@ -8,6 +8,7 @@
|
||||
|
||||
-module(mod_register).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
@@ -58,7 +59,7 @@ unauthenticated_iq_register(Acc, _Server, _IQ) ->
|
||||
Acc.
|
||||
|
||||
process_iq(From, To,
|
||||
#iq{type = Type, lang = Lang, sub_el = SubEl, id = ID} = IQ) ->
|
||||
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
UTag = xml:get_subtag(SubEl, "username"),
|
||||
@@ -103,18 +104,9 @@ process_iq(From, To,
|
||||
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)),
|
||||
#jid{user = User, lserver = Server} ->
|
||||
ejabberd_auth:remove_user(User, Server),
|
||||
ignore;
|
||||
IQ#iq{type = result, sub_el = [SubEl]};
|
||||
_ ->
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
|
||||
|
||||
+52
-104
@@ -17,8 +17,7 @@
|
||||
process_local_iq/3,
|
||||
get_user_roster/2,
|
||||
get_subscription_lists/3,
|
||||
get_in_pending_subscriptions/3,
|
||||
in_subscription/6,
|
||||
in_subscription/5,
|
||||
out_subscription/4,
|
||||
set_items/3,
|
||||
remove_user/2,
|
||||
@@ -47,8 +46,6 @@ start(Host, Opts) ->
|
||||
?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).
|
||||
|
||||
@@ -65,8 +62,6 @@ stop(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).
|
||||
|
||||
|
||||
@@ -135,6 +130,8 @@ get_user_roster(Acc, US) ->
|
||||
end.
|
||||
|
||||
|
||||
|
||||
|
||||
item_to_xml(Item) ->
|
||||
Attrs1 = [{"jid", jlib:jid_to_string(Item#roster.jid)}],
|
||||
Attrs2 = case Item#roster.name of
|
||||
@@ -163,11 +160,12 @@ item_to_xml(Item) ->
|
||||
_ ->
|
||||
Attrs3
|
||||
end,
|
||||
Attrs = Attrs4 ++ Item#roster.xattrs,
|
||||
SubEls1 = lists:map(fun(G) ->
|
||||
{xmlelement, "group", [], [{xmlcdata, G}]}
|
||||
end, Item#roster.groups),
|
||||
SubEls = SubEls1 ++ Item#roster.xs,
|
||||
{xmlelement, "item", Attrs4, SubEls}.
|
||||
{xmlelement, "item", Attrs, SubEls}.
|
||||
|
||||
|
||||
process_iq_set(From, To, #iq{sub_el = SubEl} = IQ) ->
|
||||
@@ -195,6 +193,7 @@ process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) ->
|
||||
I#roster{jid = JID,
|
||||
name = "",
|
||||
groups = [],
|
||||
xattrs = [],
|
||||
xs = []}
|
||||
end,
|
||||
Item1 = process_item_attrs(Item, Attrs),
|
||||
@@ -205,11 +204,7 @@ process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) ->
|
||||
_ ->
|
||||
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}
|
||||
{Item, Item2}
|
||||
end,
|
||||
case mnesia:transaction(F) of
|
||||
{atomic, {OldItem, Item}} ->
|
||||
@@ -279,7 +274,9 @@ process_item_attrs(Item, [{Attr, Val} | Attrs]) ->
|
||||
"ask" ->
|
||||
process_item_attrs(Item, Attrs);
|
||||
_ ->
|
||||
process_item_attrs(Item, Attrs)
|
||||
XAttrs = Item#roster.xattrs,
|
||||
process_item_attrs(Item#roster{xattrs = [{Attr, Val} | XAttrs]},
|
||||
Attrs)
|
||||
end;
|
||||
process_item_attrs(Item, []) ->
|
||||
Item.
|
||||
@@ -377,13 +374,13 @@ ask_to_pending(Ask) -> Ask.
|
||||
|
||||
|
||||
|
||||
in_subscription(_, User, Server, JID, Type, Reason) ->
|
||||
process_subscription(in, User, Server, JID, Type, Reason).
|
||||
in_subscription(_, User, Server, JID, Type) ->
|
||||
process_subscription(in, User, Server, JID, Type).
|
||||
|
||||
out_subscription(User, Server, JID, Type) ->
|
||||
process_subscription(out, User, Server, JID, Type, []).
|
||||
process_subscription(out, User, Server, JID, Type).
|
||||
|
||||
process_subscription(Direction, User, Server, JID1, Type, Reason) ->
|
||||
process_subscription(Direction, User, Server, JID1, Type) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
@@ -418,18 +415,12 @@ process_subscription(Direction, User, Server, JID1, Type, Reason) ->
|
||||
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)},
|
||||
ask = Pending},
|
||||
mnesia:write(NewItem),
|
||||
{{push, NewItem}, AutoReply}
|
||||
end
|
||||
@@ -511,7 +502,7 @@ 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, subscribe) -> none;
|
||||
out_state_change(none, out, subscribed) -> none;
|
||||
out_state_change(none, out, unsubscribe) -> {none, none};
|
||||
out_state_change(none, out, unsubscribed) -> none;
|
||||
@@ -639,44 +630,13 @@ process_item_attrs_ws(Item, [{Attr, Val} | Attrs]) ->
|
||||
"ask" ->
|
||||
process_item_attrs_ws(Item, Attrs);
|
||||
_ ->
|
||||
process_item_attrs_ws(Item, Attrs)
|
||||
XAttrs = Item#roster.xattrs,
|
||||
process_item_attrs_ws(Item#roster{xattrs = [{Attr, Val} | XAttrs]},
|
||||
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.
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
@@ -713,54 +673,42 @@ update_table() ->
|
||||
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("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);
|
||||
_ ->
|
||||
?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).
|
||||
|
||||
+1
-1
@@ -13,6 +13,6 @@
|
||||
subscription = none,
|
||||
ask = none,
|
||||
groups = [],
|
||||
askmessage = [],
|
||||
xattrs = [],
|
||||
xs = []}).
|
||||
|
||||
|
||||
+148
-99
@@ -8,6 +8,7 @@
|
||||
|
||||
-module(mod_roster_odbc).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
@@ -16,8 +17,7 @@
|
||||
process_local_iq/3,
|
||||
get_user_roster/2,
|
||||
get_subscription_lists/3,
|
||||
get_in_pending_subscriptions/3,
|
||||
in_subscription/6,
|
||||
in_subscription/5,
|
||||
out_subscription/4,
|
||||
set_items/3,
|
||||
remove_user/2,
|
||||
@@ -41,8 +41,6 @@ start(Host, Opts) ->
|
||||
?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).
|
||||
|
||||
@@ -59,8 +57,6 @@ stop(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).
|
||||
|
||||
|
||||
@@ -122,13 +118,20 @@ process_iq_get(From, To, #iq{sub_el = SubEl} = IQ) ->
|
||||
|
||||
get_user_roster(Acc, {LUser, LServer}) ->
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
case catch odbc_queries:get_roster(LServer, Username) of
|
||||
case catch ejabberd_odbc:sql_query(
|
||||
LServer,
|
||||
["select username, jid, nick, subscription, ask, "
|
||||
"server, subscribe, type from rosterusers "
|
||||
"where username='", Username, "'"]) of
|
||||
{selected, ["username", "jid", "nick", "subscription", "ask",
|
||||
"askmessage", "server", "subscribe", "type"],
|
||||
"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) ->
|
||||
JIDGroups = case catch ejabberd_odbc:sql_query(
|
||||
LServer,
|
||||
["select jid, grp from rostergroups "
|
||||
"where username='", Username, "'"]) of
|
||||
{selected, ["jid","grp"],
|
||||
JGrps} when is_list(JGrps) ->
|
||||
JGrps;
|
||||
_ ->
|
||||
[]
|
||||
@@ -208,8 +211,13 @@ process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) ->
|
||||
F = fun() ->
|
||||
{selected,
|
||||
["username", "jid", "nick", "subscription",
|
||||
"ask", "askmessage", "server", "subscribe", "type"],
|
||||
Res} = odbc_queries:get_roster_by_jid(LServer, Username, SJID),
|
||||
"ask", "server", "subscribe", "type"],
|
||||
Res} =
|
||||
ejabberd_odbc:sql_query_t(
|
||||
["select username, jid, nick, subscription, "
|
||||
"ask, server, subscribe, type from rosterusers "
|
||||
"where username='", Username, "' "
|
||||
"and jid='", SJID, "'"]),
|
||||
Item = case Res of
|
||||
[] ->
|
||||
#roster{usj = {LUser, LServer, LJID},
|
||||
@@ -226,19 +234,42 @@ process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) ->
|
||||
Item2 = process_item_els(Item1, Els),
|
||||
case Item2#roster.subscription of
|
||||
remove ->
|
||||
odbc_queries: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, "';"]);
|
||||
_ ->
|
||||
ItemVals = record_to_string(Item2),
|
||||
ItemGroups = groups_to_string(Item2),
|
||||
odbc_queries: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, "
|
||||
" 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)
|
||||
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}
|
||||
{Item, Item2}
|
||||
end,
|
||||
case odbc_queries:sql_transaction(LServer, F) of
|
||||
case ejabberd_odbc:sql_transaction(LServer, F) of
|
||||
{atomic, {OldItem, Item}} ->
|
||||
push_item(User, LServer, To, Item),
|
||||
case Item#roster.subscription of
|
||||
@@ -370,9 +401,13 @@ 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
|
||||
case catch ejabberd_odbc:sql_query(
|
||||
LServer,
|
||||
["select username, jid, nick, subscription, ask, "
|
||||
"server, subscribe, type from rosterusers "
|
||||
"where username='", Username, "'"]) of
|
||||
{selected, ["username", "jid", "nick", "subscription", "ask",
|
||||
"askmessage", "server", "subscribe", "type"],
|
||||
"server", "subscribe", "type"],
|
||||
Items} when is_list(Items) ->
|
||||
fill_subscription_lists(LServer, Items, [], []);
|
||||
_ ->
|
||||
@@ -401,13 +436,13 @@ ask_to_pending(Ask) -> Ask.
|
||||
|
||||
|
||||
|
||||
in_subscription(_, User, Server, JID, Type, Reason) ->
|
||||
process_subscription(in, User, Server, JID, Type, Reason).
|
||||
in_subscription(_, User, Server, JID, Type) ->
|
||||
process_subscription(in, User, Server, JID, Type).
|
||||
|
||||
out_subscription(User, Server, JID, Type) ->
|
||||
process_subscription(out, User, Server, JID, Type, []).
|
||||
process_subscription(out, User, Server, JID, Type).
|
||||
|
||||
process_subscription(Direction, User, Server, JID1, Type, Reason) ->
|
||||
process_subscription(Direction, User, Server, JID1, Type) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
LJID = jlib:jid_tolower(JID1),
|
||||
@@ -415,14 +450,21 @@ process_subscription(Direction, User, Server, JID1, Type, Reason) ->
|
||||
SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)),
|
||||
F = fun() ->
|
||||
Item =
|
||||
case odbc_queries:get_roster_by_jid(LServer, Username, SJID) of
|
||||
case ejabberd_odbc:sql_query_t(
|
||||
["select username, jid, nick, subscription, ask, "
|
||||
"server, subscribe, type from rosterusers "
|
||||
"where username='", Username, "' "
|
||||
"and jid='", SJID, "';"]) of
|
||||
{selected,
|
||||
["username", "jid", "nick", "subscription", "ask",
|
||||
"askmessage", "server", "subscribe", "type"],
|
||||
"server", "subscribe", "type"],
|
||||
[I]} ->
|
||||
R = raw_to_record(LServer, I),
|
||||
Groups =
|
||||
case odbc_queries:get_roster_groups(LServer, Username, SJID) of
|
||||
case ejabberd_odbc:sql_query_t(
|
||||
["select grp from rostergroups "
|
||||
"where username='", Username, "' "
|
||||
"and jid='", SJID, "';"]) of
|
||||
{selected, ["grp"], JGrps} when is_list(JGrps) ->
|
||||
[JGrp || {JGrp} <- JGrps];
|
||||
_ ->
|
||||
@@ -431,7 +473,7 @@ process_subscription(Direction, User, Server, JID1, Type, Reason) ->
|
||||
R#roster{groups = Groups};
|
||||
{selected,
|
||||
["username", "jid", "nick", "subscription", "ask",
|
||||
"askmessage", "server", "subscribe", "type"],
|
||||
"server", "subscribe", "type"],
|
||||
[]} ->
|
||||
#roster{usj = {LUser, LServer, LJID},
|
||||
us = {LUser, LServer},
|
||||
@@ -455,24 +497,27 @@ process_subscription(Direction, User, Server, JID1, Type, Reason) ->
|
||||
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},
|
||||
ask = Pending},
|
||||
ItemVals = record_to_string(NewItem),
|
||||
odbc_queries: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, "
|
||||
" server, subscribe, type) "
|
||||
" values ", ItemVals, ";"]),
|
||||
{{push, NewItem}, AutoReply}
|
||||
end
|
||||
end,
|
||||
case odbc_queries:sql_transaction(LServer, F) of
|
||||
case ejabberd_odbc:sql_transaction(LServer, F) of
|
||||
{atomic, {Push, AutoReply}} ->
|
||||
case AutoReply of
|
||||
none ->
|
||||
@@ -550,7 +595,7 @@ 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, subscribe) -> none;
|
||||
out_state_change(none, out, subscribed) -> none;
|
||||
out_state_change(none, out, unsubscribe) -> {none, none};
|
||||
out_state_change(none, out, unsubscribed) -> none;
|
||||
@@ -599,7 +644,16 @@ 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),
|
||||
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),
|
||||
ok.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
@@ -608,7 +662,7 @@ set_items(User, Server, SubEl) ->
|
||||
{xmlelement, _Name, _Attrs, Els} = SubEl,
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
catch odbc_queries:transaction(
|
||||
catch ejabberd_odbc:transaction(
|
||||
LServer,
|
||||
lists:map(fun(El) ->
|
||||
process_item_set_t(LUser, LServer, El)
|
||||
@@ -631,11 +685,30 @@ process_item_set_t(LUser, LServer, {xmlelement, _Name, Attrs, Els}) ->
|
||||
Item2 = process_item_els(Item1, Els),
|
||||
case Item2#roster.subscription of
|
||||
remove ->
|
||||
odbc_queries:del_roster_sql(Username, SJID);
|
||||
[["delete from rosterusers "
|
||||
" where username='", Username, "' "
|
||||
" and jid='", SJID, "';"],
|
||||
["delete from rostergroups "
|
||||
" where username='", Username, "' "
|
||||
" and jid='", SJID, "';"]];
|
||||
_ ->
|
||||
ItemVals = record_to_string(Item1),
|
||||
ItemGroups = groups_to_string(Item2),
|
||||
odbc_queries:update_roster_sql(Username, SJID, ItemVals, ItemGroups)
|
||||
[["delete from rosterusers "
|
||||
" where username='", Username, "' "
|
||||
" and jid='", SJID, "';"],
|
||||
["insert into rosterusers("
|
||||
" username, jid, nick, "
|
||||
" subscription, ask, "
|
||||
" server, subscribe, type) "
|
||||
" values ", ItemVals, ";"],
|
||||
["delete from rostergroups "
|
||||
" where username='", Username, "' "
|
||||
" and jid='", SJID, "';"],
|
||||
[["insert into rostergroups("
|
||||
" username, jid, grp) "
|
||||
" values ", ItemGroup, ";"] ||
|
||||
ItemGroup <- ItemGroups]]
|
||||
end
|
||||
end;
|
||||
process_item_set_t(_LUser, _LServer, _) ->
|
||||
@@ -681,39 +754,6 @@ process_item_attrs_ws(Item, [{Attr, Val} | Attrs]) ->
|
||||
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.
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
@@ -723,7 +763,11 @@ get_jid_info(_, User, Server, JID) ->
|
||||
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
|
||||
case catch ejabberd_odbc:sql_query(
|
||||
LServer,
|
||||
["select subscription from rosterusers "
|
||||
"where username='", Username, "' "
|
||||
"and jid='", SJID, "'"]) of
|
||||
{selected, ["subscription"], [{SSubscription}]} ->
|
||||
Subscription = case SSubscription of
|
||||
"B" -> both;
|
||||
@@ -731,7 +775,11 @@ get_jid_info(_, User, Server, JID) ->
|
||||
"F" -> from;
|
||||
_ -> none
|
||||
end,
|
||||
Groups = case catch odbc_queries:get_roster_group_by_jid(LServer, Username, SJID) of
|
||||
Groups = case catch ejabberd_odbc:sql_query(
|
||||
LServer,
|
||||
["select grp from rostergroups "
|
||||
"where username='", Username, "' "
|
||||
"and jid='", SJID, "'"]) of
|
||||
{selected, ["grp"], JGrps} when is_list(JGrps) ->
|
||||
[JGrp || {JGrp} <- JGrps];
|
||||
_ ->
|
||||
@@ -745,7 +793,11 @@ get_jid_info(_, User, Server, JID) ->
|
||||
{none, []};
|
||||
true ->
|
||||
SRJID = ejabberd_odbc:escape(jlib:jid_to_string(LRJID)),
|
||||
case catch odbc_queries:get_subscription(LServer, Username, SRJID) of
|
||||
case catch ejabberd_odbc:sql_query(
|
||||
LServer,
|
||||
["select subscription from rosterusers "
|
||||
"where username='", Username, "' "
|
||||
"and jid='", SRJID, "'"]) of
|
||||
{selected, ["subscription"], [{SSubscription}]} ->
|
||||
Subscription = case SSubscription of
|
||||
"B" -> both;
|
||||
@@ -753,7 +805,11 @@ get_jid_info(_, User, Server, JID) ->
|
||||
"F" -> from;
|
||||
_ -> none
|
||||
end,
|
||||
Groups = case catch odbc_queries:get_rostergroup_by_jid(LServer, Username, SRJID) of
|
||||
Groups = case catch ejabberd_odbc:sql_query(
|
||||
LServer,
|
||||
["select grp from rostergroups "
|
||||
"where username='", Username, "' "
|
||||
"and jid='", SRJID, "'"]) of
|
||||
{selected, ["grp"], JGrps} when is_list(JGrps) ->
|
||||
[JGrp || {JGrp} <- JGrps];
|
||||
_ ->
|
||||
@@ -768,7 +824,7 @@ get_jid_info(_, User, Server, JID) ->
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
raw_to_record(LServer, {User, SJID, Nick, SSubscription, SAsk, SAskMessage,
|
||||
raw_to_record(LServer, {User, SJID, Nick, SSubscription, SAsk,
|
||||
_SServer, _SSubscribe, _SType}) ->
|
||||
case jlib:string_to_jid(SJID) of
|
||||
error ->
|
||||
@@ -794,16 +850,14 @@ raw_to_record(LServer, {User, SJID, Nick, SSubscription, SAsk, SAskMessage,
|
||||
jid = LJID,
|
||||
name = Nick,
|
||||
subscription = Subscription,
|
||||
ask = Ask,
|
||||
askmessage = SAskMessage}
|
||||
ask = Ask}
|
||||
end.
|
||||
|
||||
record_to_string(#roster{us = {User, _Server},
|
||||
jid = JID,
|
||||
name = Name,
|
||||
subscription = Subscription,
|
||||
ask = Ask,
|
||||
askmessage = AskMessage}) ->
|
||||
ask = Ask}) ->
|
||||
Username = ejabberd_odbc:escape(User),
|
||||
SJID = ejabberd_odbc:escape(jlib:jid_to_string(jlib:jid_tolower(JID))),
|
||||
Nick = ejabberd_odbc:escape(Name),
|
||||
@@ -821,26 +875,21 @@ record_to_string(#roster{us = {User, _Server},
|
||||
in -> "I";
|
||||
none -> "N"
|
||||
end,
|
||||
["'", Username, "',"
|
||||
["("
|
||||
"'", Username, "',"
|
||||
"'", SJID, "',"
|
||||
"'", Nick, "',"
|
||||
"'", SSubscription, "',"
|
||||
"'", SAsk, "',"
|
||||
"'", AskMessage, "',"
|
||||
"'N', '', 'item'"].
|
||||
"'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).
|
||||
[["("
|
||||
"'", Username, "',"
|
||||
"'", SJID, "',"
|
||||
"'", ejabberd_odbc:escape(Group), "')"] || Group <- Groups].
|
||||
|
||||
|
||||
+10
-59
@@ -8,6 +8,7 @@
|
||||
|
||||
-module(mod_shared_roster).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision: 24 $ ').
|
||||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
@@ -15,8 +16,7 @@
|
||||
get_user_roster/2,
|
||||
get_subscription_lists/3,
|
||||
get_jid_info/4,
|
||||
process_item/2,
|
||||
in_subscription/6,
|
||||
in_subscription/5,
|
||||
out_subscription/4,
|
||||
list_groups/1,
|
||||
create_group/2,
|
||||
@@ -54,9 +54,7 @@ start(Host, _Opts) ->
|
||||
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).
|
||||
?MODULE, get_jid_info, 70).
|
||||
%ejabberd_hooks:add(remove_user, Host,
|
||||
% ?MODULE, remove_user, 50),
|
||||
|
||||
@@ -70,9 +68,7 @@ stop(Host) ->
|
||||
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).
|
||||
?MODULE, get_jid_info, 70).
|
||||
%ejabberd_hooks:delete(remove_user, Host,
|
||||
% ?MODULE, remove_user, 50),
|
||||
|
||||
@@ -80,22 +76,14 @@ stop(Host) ->
|
||||
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
|
||||
dict:append(User, get_group_name(S, Group), Acc2)
|
||||
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) ->
|
||||
@@ -109,8 +97,6 @@ get_user_roster(Items, US) ->
|
||||
{Item, SRUsers1}
|
||||
end
|
||||
end, SRUsers, Items),
|
||||
|
||||
%% Export items in roster format:
|
||||
SRItems = [#roster{usj = {U, S, {U1, S1, ""}},
|
||||
us = US,
|
||||
jid = {U1, S1, ""},
|
||||
@@ -121,28 +107,6 @@ get_user_roster(Items, US) ->
|
||||
{{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),
|
||||
@@ -184,7 +148,7 @@ get_jid_info({Subscription, Groups}, User, Server, JID) ->
|
||||
{Subscription, Groups}
|
||||
end.
|
||||
|
||||
in_subscription(Acc, User, Server, JID, Type, _Reason) ->
|
||||
in_subscription(Acc, User, Server, JID, Type) ->
|
||||
process_subscription(in, User, Server, JID, Type, Acc).
|
||||
|
||||
out_subscription(User, Server, JID, Type) ->
|
||||
@@ -234,15 +198,8 @@ create_group(Host, Group, Opts) ->
|
||||
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)
|
||||
mnesia:delete({sr_group, {Group, Host}})
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
@@ -261,6 +218,8 @@ set_group_opts(Host, Group, Opts) ->
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
|
||||
|
||||
get_user_groups(US) ->
|
||||
Host = element(2, US),
|
||||
case catch mnesia:dirty_read(sr_user, US) of
|
||||
@@ -331,13 +290,6 @@ get_user_displayed_groups(US) ->
|
||||
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() ->
|
||||
@@ -346,8 +298,7 @@ add_user_to_group(Host, US, Group) ->
|
||||
mnesia:transaction(F).
|
||||
|
||||
remove_user_from_group(Host, US, Group) ->
|
||||
GroupHost = {Group, Host},
|
||||
R = #sr_user{us = US, group_host = GroupHost},
|
||||
R = #sr_user{us = US, group_host = {Group, Host}},
|
||||
F = fun() ->
|
||||
mnesia:delete_object(R)
|
||||
end,
|
||||
|
||||
+342
-554
File diff suppressed because it is too large
Load Diff
-397
@@ -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:
|
||||
+4
-3
@@ -236,6 +236,9 @@
|
||||
{"Group ", "Gruppe "}.
|
||||
{"ejabberd Web Interface", "ejabberd Web Interface"}.
|
||||
|
||||
% mod_vcard_ldap.erl
|
||||
{"Given Name", "Vorname"}.
|
||||
|
||||
% ejabberd_c2s.erl
|
||||
{"Use of STARTTLS required", "Verwendung von STARTTLS erforderlich"}.
|
||||
{"Replaced by new connection", "Durch neue Verbindung ersetzt"}.
|
||||
@@ -349,6 +352,7 @@
|
||||
{"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 semianonymous", "Raum semi-anonym machen"}.
|
||||
{"Make room members-only", "Raum members-only machen"}.
|
||||
{"Make room moderated", "Raum modieriert machen"}.
|
||||
{"Default users as participants", "Standartbenutzer als Teilnehmer"}.
|
||||
@@ -359,9 +363,6 @@
|
||||
{"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
|
||||
|
||||
+3
-4
@@ -135,7 +135,7 @@
|
||||
{"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"}.
|
||||
{"Default users as participants", "Los usuarios on 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"}.
|
||||
@@ -167,11 +167,9 @@
|
||||
{"Invalid role: ~s", "Rol no válido: ~s"}.
|
||||
{"Owner privileges required", "Se requieren privilegios de propietario de la sala"}.
|
||||
{"private, ", "privado"}.
|
||||
{"Make room semianonymous", "Hacer la sala semianónima"}.
|
||||
{"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"}.
|
||||
@@ -322,6 +320,7 @@
|
||||
{"Replaced by new connection", "Reemplazado por una nueva conexión"}.
|
||||
|
||||
% mod_vcard_ldap.erl
|
||||
{"Given Name", "Nombre dado"}.
|
||||
{"Fill in fields to search for any matching Jabber User", "Rellena campos para buscar usuarios Jabber que concuerden"}.
|
||||
|
||||
% mod_adhoc.erl
|
||||
|
||||
+2
-3
@@ -74,6 +74,7 @@
|
||||
|
||||
% src/mod_vcard_ldap.erl
|
||||
{"Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin", "Serveur Jabber Erlang\nCopyright (c) 2002-2006 Alexey Shchepin"}.
|
||||
{"Given Name", "Prénom"}.
|
||||
{"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 "}.
|
||||
@@ -212,6 +213,7 @@
|
||||
{"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 semianonymous", "Rendre le salon semi-anonyme"}.
|
||||
{"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"}.
|
||||
@@ -222,9 +224,6 @@
|
||||
{"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"}.
|
||||
|
||||
+2
-3
@@ -7,6 +7,7 @@
|
||||
{"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"}.
|
||||
{"Given Name", "Voornaam"}.
|
||||
{"Middle Name", "Tussennaam"}.
|
||||
{"Family Name", "Achternaam"}.
|
||||
{"Nickname", "Bijnaam"}.
|
||||
@@ -167,6 +168,7 @@
|
||||
{"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 semianonymous", "Chatruimte gedeeltelijk anoniem maken"}.
|
||||
{"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"}.
|
||||
@@ -178,9 +180,6 @@
|
||||
{"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"}.
|
||||
|
||||
+92
-54
@@ -43,6 +43,7 @@
|
||||
{"Configuration", "Konfiguracja"}.
|
||||
{"Online Users", "Użytkownicy zalogowani"}.
|
||||
{"All Users", "Wszyscy użytkownicy"}.
|
||||
{"Outgoing S2S connections", "Wychodzące połączenia S2S"}.
|
||||
{"To ~s", "Do ~s"}.
|
||||
{"From ~s", "Z ~s"}.
|
||||
{"Running Nodes", "Uruchomione gałęzie"}.
|
||||
@@ -51,10 +52,12 @@
|
||||
{"Access Control Lists", "Lista dostępowa"}.
|
||||
{"Access Rules", "Zasady dostępu"}.
|
||||
{"Remove Users", "Usuń użytkowników"}.
|
||||
{"DB", "DB"}.
|
||||
{"Modules", "Moduły"}.
|
||||
{"Start Modules", "Uruchom moduły"}.
|
||||
{"Stop Modules", "Zatrzymaj moduły"}.
|
||||
{"Backup Management", "Zarządzanie kopiami zapasowymi"}.
|
||||
{"Import users from jabberd1.4 spool files", "Importowanie użytkowników z plikow spoool serwera jabberd1.4"}.
|
||||
{"Backup", "Tworzenie kopii"}.
|
||||
{"Restore", "Odtwarzanie kopii"}.
|
||||
{"Dump to Text File", "Zrzucanie do pliku tekstowego"}.
|
||||
@@ -71,6 +74,7 @@
|
||||
{"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"}.
|
||||
{"Results of search in ", "Wyniki wyszukiwania w "}.
|
||||
|
||||
{"User", "Użytkownik: "}.
|
||||
{"Full Name", "Pełna nazwa: "}.
|
||||
@@ -81,6 +85,7 @@
|
||||
{"Birthday", "Data urodzenia: "}.
|
||||
{"Country", "Państwo: "}.
|
||||
{"City", "Miasto: "}.
|
||||
{"email", "E-Mail: "}.
|
||||
{"Organization Name", "Nazwa organizacji: "}.
|
||||
{"Organization Unit", "Dział: "}.
|
||||
|
||||
@@ -93,6 +98,7 @@
|
||||
"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"}.
|
||||
{"You must fill in field \"nick\" in the form", "Musisz wypełnić pole \"nick\" w formularzu"}.
|
||||
{"Specified nickname is already registered", "Podany nick jest już zarejestrowany"}.
|
||||
|
||||
% mod_muc/mod_muc_room.erl
|
||||
@@ -101,7 +107,25 @@
|
||||
"Potrzebujesz klienta kompatybilnego z x:data aby skonfigurować pokój"}.
|
||||
{"Configuration for ", "Konfiguracja dla "}.
|
||||
{"Room title", "Tytuł pokoju"}.
|
||||
{"Allow users to change subject?", "Zezwolić użytkownikom na zmianę tematu?"}.
|
||||
{"Allow users to query other users?",
|
||||
"Zezwolić użytkownikom na zapraszanie innych użytkowników?"}.
|
||||
{"Allow users to send private messages?",
|
||||
"Zezwolić użytkownikom na wysyłanie prywatnych wiadomości?"}.
|
||||
{"Make room public searchable?", "Uczynić pokój wyszukiwalnym publicznie?"}.
|
||||
{"Make participants list public?", "Uczynic obecnych wyszukiwalnymi publicznie?"}.
|
||||
{"Make room persistent?", "Uczynić pokój trwałym?"}.
|
||||
{"Make room moderated?", "Uczynić pokój moderowanym?"}.
|
||||
{"Default users as members?",
|
||||
"Domyślni użytkownicy jako członkowie?"}.
|
||||
{"Make room members only?",
|
||||
"Uczynić pokój tylko dla członków?"}.
|
||||
{"Allow users to send invites?",
|
||||
"Pozwolić użytkownikom na wysyłanie zaproszeń?"}.
|
||||
{"Make room password protected?", "Czy zabezpieczyć pokój hasłem?"}.
|
||||
{"Password", "Hasło"}.
|
||||
{"Make room anonymous?", "Uczynić pokój anonimowym?"}.
|
||||
{"Enable logging?", "Włączyć logowanie?"}.
|
||||
{"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",
|
||||
@@ -136,10 +160,6 @@
|
||||
{"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",
|
||||
@@ -153,55 +173,91 @@
|
||||
{"Encodings", "Kodowania"}.
|
||||
|
||||
% web/ejabberd_web_admin.erl
|
||||
{"ejabberd administration", "Administracja serwerem Ejabberd"}.
|
||||
{"Users", "Użytkownicy"}.
|
||||
{"Nodes", "Gałęzie"}.
|
||||
{"Statistics", "Statystyki"}.
|
||||
{"(raw)", "(raw)"}.
|
||||
{"submitted", "przesłane"}.
|
||||
{"bad format", "zły format"}.
|
||||
{"raw", "raw"}.
|
||||
{"ejabberd access control lists configuration", "Lista konfiguracyjna dostępu do serwera EJabberd"}.
|
||||
{"Delete Selected", "Usuń zaznaczone"}.
|
||||
{"Submit", "Wprowadź"}.
|
||||
{"ejabberd access rules configuration", "Konfiguracja zasad dostępu do serwera EJabberd"}.
|
||||
{"~s access rule configuration", "~s konfiguracja zasad dostępu"}.
|
||||
{"ejabberd users", "Użytkownicy EJabberd"}.
|
||||
{"ejabberd stats", "Statystyki EJabberd"}.
|
||||
{"Node not found", "Gałąź nie znaleziona"}.
|
||||
{"Add New", "Dodaj nowe"}.
|
||||
{"Registered users", "Zarejestrowani użytkownicy"}.
|
||||
{"Online users", "Użytkownicy online"}.
|
||||
{"Outgoing S2S servers", "Sewery zewnętrzne S2S"}.
|
||||
{"Change Password", "Zmień hasło"}.
|
||||
{"Connected Resources:", "Zasoby podłączone"}.
|
||||
{"Password:", "Hasło:"}.
|
||||
{"None", "Brak"}.
|
||||
{"Node ", "Gałąź "}.
|
||||
{"DB Management", "Zarządzanie bazą danych"}.
|
||||
{"Listened Ports Management", "Zarządzanie portami nasłuchującymi"}.
|
||||
{"Restart", "Restart"}.
|
||||
{"Stop", "Stop"}.
|
||||
{"RPC call error", "Błąd RPC"}.
|
||||
{"DB Tables at ", "Tabele bazy danych "}.
|
||||
{"Name", "Nazwa"}.
|
||||
{"Storage Type", "Typ bazy"}.
|
||||
{"Size", "Wielkość"}.
|
||||
{"Memory", "Pamięć"}.
|
||||
{"Backup Management at ", "Zarządzanie kopiami zapasowymi "}.
|
||||
{"Store a backup in a file", "Zachowaj kopie zapasowa w pliku "}.
|
||||
{"OK", "OK"}.
|
||||
{"Restore a backup from a file", "Odtwórz kopię zapasową z pliku"}.
|
||||
{"Install a database fallback from a file", "Przywróć zapisaną kopię z pliku"}.
|
||||
{"Dump a database in a text file", "Zrzuć bazę danych do pliku tekstowego"}.
|
||||
{"Restore a database from a text file", "Odtwórz bazę danych z pliku tekstowego"}.
|
||||
{"Listened Ports at ", "Porty nasłuchujące "}.
|
||||
{"~p statistics", "~p statystyka"}.
|
||||
{"Uptime", "Uptime"}.
|
||||
{"CPU Time", "Czas procesora"}.
|
||||
{"Transactions commited", "Tarnsakcje rozpoczęte"}.
|
||||
{"Transactions aborted", "Transakcje anulowane"}.
|
||||
{"Transactions restarted", "Transakcje zrestartowane"}.
|
||||
{"Transactions logged", "Transakcje logowane"}.
|
||||
{"Port", "Port"}.
|
||||
{"Module", "Moduł"}.
|
||||
{"Options", "Opcje"}.
|
||||
{"Update", "Aktualizacja"}.
|
||||
{"Delete", "Usuń"}.
|
||||
{"Add User", "Dodaj użytkownika"}.
|
||||
{"Offline messages", "Wiadomości offline"}.
|
||||
{"Last Activity", "Ostatnia aktywność"}.
|
||||
{"Never", "Nigdy"}.
|
||||
{"~s offline messages queue", "~s wiadomości offline w kolejce"}.
|
||||
{"Time", "Czas"}.
|
||||
{"From", "Od"}.
|
||||
{"To", "Do"}.
|
||||
{"Packet", "Pakiet "}.
|
||||
{"Offline messages:", "Wiadomości offline: "}.
|
||||
{"Roster", "Roster "}.
|
||||
{"Nickname", "Nick "}.
|
||||
{"Subscription", "Subskrypcja "}.
|
||||
{"Pending", "Oczekiwanie "}.
|
||||
{"Groups", "Grupy "}.
|
||||
{"Remove", "Usuń "}.
|
||||
{"Add JID", "Dodaj JID "}.
|
||||
{"User ", "Użytkownik "}.
|
||||
{"Roster of ", "Roster "}.
|
||||
{"Shared Roster", "Roster współdzielony"}.
|
||||
{"Online", "Dostępny"}.
|
||||
{"Validate", "Zatwierdź"}.
|
||||
{"Not found", "Nie znaleziony"}.
|
||||
{"Shared roster groups", "Grupy rosterów współdzielonych"}.
|
||||
{"Name:", "Nazwa:"}.
|
||||
{"Description:", "Opis:"}.
|
||||
{"Members:", "Członkowie:"}.
|
||||
{"Displayed Groups:", "Wyświetlane grupy:"}.
|
||||
{"Group ", "Grupa "}.
|
||||
{"Users last activity", "Ostatnia aktywność użytkowników"}.
|
||||
{"Period: ", "Przedział czasu "}.
|
||||
{"Last month", "Ostatni miesiąc"}.
|
||||
{"Last year", "Ostatni rok"}.
|
||||
@@ -209,23 +265,35 @@
|
||||
{"Show Ordinary Table", "Pokaż zwykłą tabelę"}.
|
||||
{"Show Integral Table", "Pokaż tabelę całkowitą"}.
|
||||
{"Start", "Start"}.
|
||||
{"Modules Management", "Zarządzanie modułami"}.
|
||||
{"Modules at ", "Moduły na "}.
|
||||
{"No data", "Brak danych"}.
|
||||
{"Virtual Hosts", "Wirtualne hosty"}.
|
||||
{"ejabberd virtual hosts", "wirtualne hosty ejabberda"}.
|
||||
{"Host", "Host"}.
|
||||
{"ejabberd Web Interface", ""}.
|
||||
|
||||
% 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)", "Wypełnij formularz aby wyszukać pasujących użytkowników Jabbera (dodaj * na koniec pola aby dopasować)"}.
|
||||
{"ejabberd vCard module\nCopyright (c) 2003-2005 Alexey Shchepin", "ejabberd vCard module\nCopyright (c) 2003-2005 Alexey Shchepin"}.
|
||||
{"JID", "JID"}.
|
||||
|
||||
% ejabberd_c2s.erl
|
||||
{"Use of STARTTLS required", "Wymagane użycie STARTTLS"}.
|
||||
{"Replaced by new connection", ""}.
|
||||
|
||||
% mod_configure.erl
|
||||
{"DB Tables Configuration at ", "Konfiguracja tabel bazy dla "}.
|
||||
|
||||
% mod_vcard_ldap.erl
|
||||
{"Given Name", "Nadana nazwa"}.
|
||||
|
||||
% mod_pubsub/mod_pubsub.erl
|
||||
{"ejabberd pub/sub module\nCopyright (c) 2003-2005 Alexey Shchepin", "ejabberd pub/sub module\nCopyright (c) 2003-2005 Alexey Shchepin"}.
|
||||
{[], " "}.
|
||||
{"Node Creator", "Tworzenie gałęzi"}.
|
||||
{"Deliver payloads with event notifications", "Dołącz zawartość publikowanego przedmiotu podczas wysyłania powiadomienia o publikacji"}.
|
||||
{"Deliver payloads with event notifications", "Do?cz zawarto? publikowanego przedmiotu podczas wysy?nia 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"}.
|
||||
@@ -234,23 +302,36 @@
|
||||
{"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"}.
|
||||
{"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 "}.
|
||||
|
||||
% 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", "Użytkownicy zautoryzowani"}.
|
||||
|
||||
% 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.", "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ę"}.
|
||||
{"ejabberd MUC module\nCopyright (c) 2003-2005 Alexey Shchepin", "ejabberd MUC module\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"}.
|
||||
{"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"}.
|
||||
{"ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin", ""}.
|
||||
{"Search Results for ", "Wyniki wyszukiwania dla "}.
|
||||
{"Jabber ID", "Jabber ID"}.
|
||||
{"Jabber ID", ""}.
|
||||
|
||||
% /usr/home/src/ejabberd/ejabberd/src/mod_adhoc.erl
|
||||
{"Commands", "Polecenia"}.
|
||||
@@ -369,7 +450,8 @@
|
||||
{"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 semianonymous", "Utwórz pokój pół-nieznanym"}.
|
||||
{"Make room members-only", "Utwórz pokój tylko dla członków"}.
|
||||
{"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"}.
|
||||
@@ -379,47 +461,3 @@
|
||||
{"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", ""}.
|
||||
|
||||
|
||||
+67
-6
@@ -47,12 +47,15 @@
|
||||
{"Backup", "Salvar cópia de segurança"}.
|
||||
{"Backup Management", "Gestão de copia de segurança"}.
|
||||
{"Configuration", "Configuração"}.
|
||||
{"DB", "BD"}.
|
||||
{"Dump to Text File", "Exportar para arquivo de texto"}.
|
||||
{"From ~s", "De ~s"}.
|
||||
{"Import Directory", "Importar diretório"}.
|
||||
{"Import File", "Importar arquivo"}.
|
||||
{"Import users from jabberd1.4 spool files", "Importar usuários a partir de arquivos da spool do jabberd1.4"}.
|
||||
{"Modules", "Módulos"}.
|
||||
{"Online Users", "Usuários conectados"}.
|
||||
{"Outgoing S2S connections", "Conexões S2S de saída"}.
|
||||
{"Remove Users", "Remover usuários"}.
|
||||
{"Restore", "Restaurar"}.
|
||||
{"Running Nodes", "Nos em execução"}.
|
||||
@@ -71,6 +74,7 @@
|
||||
{"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"}.
|
||||
{"email", "e-mail"}.
|
||||
{"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"}.
|
||||
@@ -81,6 +85,7 @@
|
||||
{"Nickname", "Nick"}.
|
||||
{"Organization Name", "Nome da organização"}.
|
||||
{"Organization Unit", "Unidade da organização"}.
|
||||
{"Results of search in ", "Resultados da busca em "}.
|
||||
{"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"}.
|
||||
@@ -105,11 +110,19 @@
|
||||
{"Whether to allow subscriptions", "Permitir subscrições"}.
|
||||
|
||||
% mod_muc/mod_muc.erl
|
||||
{"Allow users to change subject?", "Permitir aos usuários mudar o tópico?"}.
|
||||
{"Allow users to query other users?", "Permitir aos usuários consultar outros usuários?"}.
|
||||
{"Allow users to send invites?", "Permitir que os usuários enviem convites?"}.
|
||||
{"Allow users to send private messages?", "Permitir que os usuários enviem mensagens privadas?"}.
|
||||
{"Default users as members?", "Os usuários padrão são membros?"}.
|
||||
{"Enable logging?", "Salvar históricos?"}.
|
||||
{"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"}.
|
||||
{"Make room anonymous?", "Tornar a sala anônima?"}.
|
||||
{"Make room password protected?", "Proteger a sala com senha?"}.
|
||||
{"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 "}.
|
||||
@@ -118,11 +131,18 @@
|
||||
{"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 must fill in field \"nick\" in the form", "Deve preencher o campo \"apelido\" no formulário"}.
|
||||
{"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"}.
|
||||
{"Allow users to change subject?", "Permitir aos usuários cambiar o assunto"}.
|
||||
{"Allow users to query other users?", "Permitir aos usuários consultar a outros usuários"}.
|
||||
{"Allow users to send invites?", "Permitir aos usuários enviar convides"}.
|
||||
{"Allow users to send private messages?", "Permitir aos usuários enviar mensagens privados"}.
|
||||
{"Configuration for ", "Configuração para "}.
|
||||
{"Default users as members?", "Os usuários são membros por defeito"}.
|
||||
{"Enable logging?", "Guardar históricos"}.
|
||||
{" has set the subject to: ", " a posto o assunto: "}.
|
||||
{"Improper message type", "Tipo de mensagem incorreto"}.
|
||||
{"Incorrect password", "Senha incorreta"}.
|
||||
@@ -132,6 +152,13 @@
|
||||
{"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"}.
|
||||
{"Make participants list public?", "Fazer pública la lista de participantes"}.
|
||||
{"Make room anonymous?", "Fazer anônima la sala"}.
|
||||
{"Make room members only?", "Fazer la sala solo para membros"}.
|
||||
{"Make room moderated?", "Fazer la sala moderada"}.
|
||||
{"Make room password protected?", "Proteger la sala com senha"}.
|
||||
{"Make room persistent?", "Fazer la sala permanente"}.
|
||||
{"Make room public searchable?", "Fazer a sala publicamente visível"}.
|
||||
{"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"}.
|
||||
@@ -165,57 +192,91 @@
|
||||
|
||||
|
||||
% web/ejabberd_web_admin.erl
|
||||
{"Add JID", "Adicionar JID"}.
|
||||
{"Add New", "Adicionar novo"}.
|
||||
{"Add User", "Adicionar usuário"}.
|
||||
{"All activity", "Toda la atividade"}.
|
||||
{"Backup Management at ", "Gestão de copia de segurança em "}.
|
||||
{"bad format", "mal formato"}.
|
||||
{"Change Password", "Mudar senha"}.
|
||||
{"Connected Resources:", "Recursos conectados:"}.
|
||||
{"CPU Time", "Tempo de processador consumido"}.
|
||||
{"DB Management", "Gestão do BD"}.
|
||||
{"DB Tables at ", "Tabelas do BD em "}.
|
||||
{"Delete", "Eliminar"}.
|
||||
{"Delete Selected", "Remover os selecionados"}.
|
||||
{"Dump a database in a text file", "Exportar uma Base de Dados para um arquivo de texto"}.
|
||||
{"ejabberd access control lists configuration", "Configuração das Listas de Controle de Acesso do ejabberd"}.
|
||||
{"ejabberd access rules configuration", "Configuração de las Regras de Aceso de ejabberd"}.
|
||||
{"ejabberd administration", "Administração de ejabberd"}.
|
||||
{"ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One", "ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One"}.
|
||||
{"ejabberd stats", "Estatísticas de ejabberd"}.
|
||||
{"ejabberd users", "Usuários do ejabberd"}.
|
||||
{"ejabberd virtual hosts", "Maquinas virtuais de ejabberd"}.
|
||||
{"From", "De"}.
|
||||
{"Group ", "Grupo "}.
|
||||
{"Groups", "Grupos"}.
|
||||
{"Host", "Máquina"}.
|
||||
{"Install a database fallback from a file", "Instalar uma recuperação de BD a partir de um arquivo"}.
|
||||
{"JID", "JID"}.
|
||||
{"Last Activity", "Última atividade"}.
|
||||
{"Last month", "Último mês"}.
|
||||
{"Last year", "Último ano"}.
|
||||
{"Listened Ports at ", "Portas de escuta em "}.
|
||||
{"Listened Ports Management", "Gestão dos portas de escuta"}.
|
||||
{"Members:", "Miembros:"}.
|
||||
{"Memory", "Memória"}.
|
||||
{"Module", "Módulo"}.
|
||||
{"Modules at ", "Módulos em "}.
|
||||
{"Modules Management", "Gestão de módulos"}.
|
||||
{"Name:", "Nome:"}.
|
||||
{"Name", "Nome"}.
|
||||
{"Never", "Nunca"}.
|
||||
{"Nickname", "Apelido"}.
|
||||
{"Online", "Conectado"}.
|
||||
{"Online users", "Usuários conectados"}.
|
||||
{"Options", "Opções"}.
|
||||
{"Outgoing S2S servers", "Servidores conectados"}.
|
||||
{"Packet", "Pacote"}.
|
||||
{"Password:", "Senha:"}.
|
||||
{"Pending", "Pendente"}.
|
||||
{"Period: ", "Período: "}.
|
||||
{"Port", "Porta"}.
|
||||
{"~p statistics", "Estatísticas de ~p"}.
|
||||
{"(raw)", "(cru)"}.
|
||||
{"raw", "cru"}.
|
||||
{"Registered users", "Usuários registrados"}.
|
||||
{"Remove", "Borrar"}.
|
||||
{"Restart", "Reiniciar"}.
|
||||
{"Restore a backup from a file", "Recuperar uma cópia de segurança a partir do arquivo"}.
|
||||
{"Restore a database from a text file", "Restaurar uma Base de Dados a partir de um arquivo de texto"}.
|
||||
{"Roster", "Lista de contatos"}.
|
||||
{"Roster of ", "Lista de contatos de "}.
|
||||
{"RPC call error", "Erro em la chamada RPC"}.
|
||||
{"~s access rule configuration", "Configuração da Regra de Acesso ~s"}.
|
||||
{"Shared roster groups", "Grupos compartilhado"}.
|
||||
{"Shared Roster", "Lista de contatos compartilhada"}.
|
||||
{"Show Integral Table", "Mostrar Tabela Integral"}.
|
||||
{"Show Ordinary Table", "Mostrar Tabela Ordinária"}.
|
||||
{"Size", "Tamanho"}.
|
||||
{"~s offline messages queue", "~s cola de mensagens diferidos"}.
|
||||
{"Start", "Iniciar"}.
|
||||
{"Statistics", "Estatísticas"}.
|
||||
{"Stop", "Parar"}.
|
||||
{"Storage Type", "Tipo de armazenamento"}.
|
||||
{"Store a backup in a file", "Armazenar uma cópia de segurança no arquivo"}.
|
||||
{"Submit", "Enviar"}.
|
||||
{"submitted", "enviado"}.
|
||||
{"Subscription", "Subscrição"}.
|
||||
{"Time", "Fecha"}.
|
||||
{"To", "Para"}.
|
||||
|
||||
{"Transactions aborted", "Transações abortadas"}.
|
||||
{"Transactions commited", "Transações realizadas"}.
|
||||
{"Transactions logged", "Transações armazenadas"}.
|
||||
{"Transactions restarted", "Transações reiniciadas"}.
|
||||
{"Update", "Atualizar"}.
|
||||
{"Uptime", "Tempo de funcionamento"}.
|
||||
{"Users last activity", "Última atividades dos usuários"}.
|
||||
{"Users", "Usuários"}.
|
||||
{"User ", "Usuário"}.
|
||||
{"Validate", "Validar"}.
|
||||
@@ -227,7 +288,8 @@
|
||||
|
||||
% mod_vcard_ldap.erl
|
||||
{"Fill in fields to search for any matching Jabber User", "Preencha campos para buscar usuários Jabber que concordem"}.
|
||||
|
||||
{"Given Name", "Nome dado"}.
|
||||
{"JID", "JID"}.
|
||||
|
||||
|
||||
% mod_adhoc.erl
|
||||
@@ -322,6 +384,8 @@
|
||||
{"Description:", "Descrição:"}.
|
||||
{"Displayed Groups:", "Grupos Indicados"}.
|
||||
|
||||
% mod_irc/mod_irc.erl
|
||||
|
||||
% mod_muc/mod_muc_log.erl
|
||||
{"Chatroom configuration modified", "Configuração da sala de bate-papo modificada"}.
|
||||
{"joins the room", "Entrar na sala"}.
|
||||
@@ -360,6 +424,7 @@
|
||||
{"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 semianonymous", "Tornar sala semi-anônima"}.
|
||||
{"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"}.
|
||||
@@ -370,10 +435,6 @@
|
||||
{"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
|
||||
|
||||
+2
-4
@@ -159,7 +159,7 @@
|
||||
"Вы должны заполнить поле \"Псевдоним\" в форме"}.
|
||||
{"Specified nickname is already registered", "Указанный псевдоним уже зарегистрирован"}.
|
||||
|
||||
% mod_muc/mod_muc_log.erl
|
||||
% /home/sergei/src/ejabberd/ejabberd/src/mod_muc/mod_muc_log.erl
|
||||
{"Chatroom configuration modified", "Конфигурация комнаты изменилась"}.
|
||||
{"joins the room", "вошёл(а) в комнату"}.
|
||||
{"leaves the room", "вышел(а) из комнаты"}.
|
||||
@@ -211,9 +211,7 @@
|
||||
"Разрешить пользователям посылать приглашения"}.
|
||||
{"Make room password protected", "Сделать комнату защищённой паролем"}.
|
||||
{"Password", "Пароль"}.
|
||||
{"Present real JIDs to", "Сделать реальные JID участников видимыми"}.
|
||||
{"moderators only", "только модераторам"}.
|
||||
{"anyone", "всем участникам"}.
|
||||
{"Make room semianonymous", "Сделать комнату полуанонимной"}.
|
||||
{"Enable logging", "Включить журналирование"}.
|
||||
{"Only moderators and participants are allowed to change subject in this room",
|
||||
"Только модераторы и участники могут изменять тему в этой комнате"}.
|
||||
|
||||
-463
@@ -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"}.
|
||||
+1
-3
@@ -210,9 +210,7 @@
|
||||
"Дозволити користувачам надсилати запрошення"}.
|
||||
{"Make room password protected", "Зробити кімнату захищеною паролем"}.
|
||||
{"Password", "Пароль"}.
|
||||
{"Present real JIDs to", "Зробити реальні JID учасників видимими"}.
|
||||
{"moderators only", "тільки модераторам"}.
|
||||
{"anyone", "всім учасникам"}.
|
||||
{"Make room semianonymous", "Зробити кімнату напіванонімною"}.
|
||||
{"Enable logging", "Включити журнал роботи"}.
|
||||
{"Only moderators and participants are allowed to change subject in this room",
|
||||
"Тільки модератори та учасники можуть змінювати тему в цій кімнаті"}.
|
||||
|
||||
@@ -13,13 +13,12 @@ OUTDIR = ..
|
||||
EFLAGS = -I .. -pz ..
|
||||
OBJS = \
|
||||
$(OUTDIR)/ejabberd_odbc.beam \
|
||||
$(OUTDIR)/ejabberd_odbc_sup.beam \
|
||||
$(OUTDIR)/odbc_queries.beam
|
||||
$(OUTDIR)/ejabberd_odbc_sup.beam
|
||||
|
||||
all: $(OBJS)
|
||||
|
||||
$(OUTDIR)/%.beam: %.erl
|
||||
@ERLC@ -W $(EFLAGS) -D@db_type@ -o $(OUTDIR) $<
|
||||
@ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
|
||||
|
||||
|
||||
clean:
|
||||
|
||||
@@ -6,8 +6,7 @@ EFLAGS = -I .. -pz ..
|
||||
|
||||
OBJS = \
|
||||
$(OUTDIR)\ejabberd_odbc.beam \
|
||||
$(OUTDIR)\ejabberd_odbc_sup.beam \
|
||||
$(OUTDIR)\odbc_queries.beam
|
||||
$(OUTDIR)\ejabberd_odbc_sup.beam
|
||||
|
||||
ALL : $(OBJS)
|
||||
|
||||
@@ -19,7 +18,3 @@ $(OUTDIR)\ejabberd_odbc.beam : 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
|
||||
|
||||
|
||||
@@ -87,7 +87,16 @@ sql_query_t(Query) ->
|
||||
|
||||
%% Escape character that will confuse an SQL engine
|
||||
escape(S) when is_list(S) ->
|
||||
[odbc_queries:escape(C) || C <- S].
|
||||
[escape(C) || C <- S];
|
||||
escape($\0) -> "\\0";
|
||||
escape($\n) -> "\\n";
|
||||
escape($\t) -> "\\t";
|
||||
escape($\b) -> "\\b";
|
||||
escape($\r) -> "\\r";
|
||||
escape($') -> "\\'";
|
||||
escape($") -> "\\\"";
|
||||
escape($\\) -> "\\\\";
|
||||
escape(C) -> C.
|
||||
|
||||
%% Escape character that will confuse an SQL engine
|
||||
%% Percent and underscore only need to be escaped for pattern matching like
|
||||
@@ -96,7 +105,7 @@ escape_like(S) when is_list(S) ->
|
||||
[escape_like(C) || C <- S];
|
||||
escape_like($%) -> "\\%";
|
||||
escape_like($_) -> "\\_";
|
||||
escape_like(C) -> odbc_queries:escape(C).
|
||||
escape_like(C) -> escape(C).
|
||||
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
@@ -19,7 +19,6 @@ CREATE TABLE rosterusers (
|
||||
nick text,
|
||||
subscription character(1) NOT NULL,
|
||||
ask character(1) NOT NULL,
|
||||
askmessage text,
|
||||
server character(1) NOT NULL,
|
||||
subscribe text,
|
||||
type text
|
||||
@@ -92,5 +91,3 @@ 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;
|
||||
|
||||
@@ -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.
|
||||
+6
-13
@@ -18,7 +18,6 @@ CREATE TABLE rosterusers (
|
||||
nick text,
|
||||
subscription character(1) NOT NULL,
|
||||
ask character(1) NOT NULL,
|
||||
askmessage text,
|
||||
server character(1) NOT NULL,
|
||||
subscribe text,
|
||||
"type" text
|
||||
@@ -37,6 +36,12 @@ CREATE TABLE rostergroups (
|
||||
|
||||
CREATE INDEX pk_rosterg_user_jid ON rostergroups USING btree (username, jid);
|
||||
|
||||
--- To update from previous table definition:
|
||||
-- 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;
|
||||
|
||||
CREATE TABLE spool (
|
||||
username text NOT NULL,
|
||||
@@ -90,15 +95,3 @@ 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;
|
||||
|
||||
@@ -6,13 +6,6 @@ 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
|
||||
@@ -33,7 +26,7 @@ $(OUTDIR)/%.beam: %.erl
|
||||
$(ERLSHLIBS): ../%.so: %.c uni_data.c uni_norm.c
|
||||
gcc -Wall -O2 $(CFLAGS) $(LDFLAGS) $(INCLUDES) \
|
||||
$(subst ../,,$(subst .so,.c,$@)) $(LIBS) \
|
||||
-o $@ $(DYNAMIC_LIB_CFLAGS)
|
||||
-o $@ -fpic -shared
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(ERLSHLIBS)
|
||||
|
||||
+1
-8
@@ -6,13 +6,6 @@ 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
|
||||
@@ -33,7 +26,7 @@ $(OUTDIR)/%.beam: %.erl
|
||||
$(ERLSHLIBS): ../%.so: %.c
|
||||
$(CC) -Wall $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \
|
||||
$(subst ../,,$(subst .so,.c,$@)) $(LIBS) \
|
||||
-o $@ -fpic $(DYNAMIC_LIB_CFLAGS)
|
||||
-o $@ -fpic -shared
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(ERLSHLIBS)
|
||||
|
||||
+2
-19
@@ -64,26 +64,10 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
||||
#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; \
|
||||
rlen = strlen(errstr) + 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); \
|
||||
} \
|
||||
strncpy(b->orig_bytes + 1, errstr, rlen - 1); \
|
||||
*rbuf = (char *)b; \
|
||||
return rlen; \
|
||||
}
|
||||
@@ -100,7 +84,6 @@ static int tls_drv_control(ErlDrvData handle,
|
||||
ErlDrvBinary *b;
|
||||
X509 *cert;
|
||||
|
||||
ERR_clear_error();
|
||||
switch (command)
|
||||
{
|
||||
case SET_CERTIFICATE_FILE_ACCEPT:
|
||||
|
||||
@@ -133,17 +133,13 @@ process_header(State, Data) ->
|
||||
SockMod = State#state.sockmod,
|
||||
Socket = State#state.socket,
|
||||
case Data of
|
||||
{ok, {http_request, Method, Uri, Version}} ->
|
||||
{ok, {http_request, Method, Path, 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,
|
||||
@@ -720,27 +716,10 @@ parse_req(Line) ->
|
||||
"*" ->
|
||||
% 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
|
||||
P ->
|
||||
% FIXME: Handle
|
||||
% absolute URIs
|
||||
{abs_path, P}
|
||||
end,
|
||||
case VersionStr of
|
||||
[] ->
|
||||
|
||||
@@ -36,8 +36,7 @@
|
||||
key,
|
||||
output = "",
|
||||
input = "",
|
||||
waiting_input = false, %% {ReceiverPid, Tag}
|
||||
last_receiver,
|
||||
waiting_input = false,
|
||||
timer}).
|
||||
|
||||
%-define(DBGFSM, true).
|
||||
@@ -195,7 +194,7 @@ handle_event(Event, StateName, StateData) ->
|
||||
%% {stop, Reason, Reply, NewStateData}
|
||||
%%----------------------------------------------------------------------
|
||||
handle_sync_event({send, Packet}, From, StateName, StateData) ->
|
||||
Output = StateData#state.output ++ [lists:flatten(Packet)],
|
||||
Output = [StateData#state.output | Packet],
|
||||
Reply = ok,
|
||||
{reply, Reply, StateName, StateData#state{output = Output}};
|
||||
|
||||
@@ -204,12 +203,9 @@ handle_sync_event(activate, From, StateName, StateData) ->
|
||||
"" ->
|
||||
{reply, ok, StateName, StateData#state{waiting_input = From}};
|
||||
Input ->
|
||||
{Receiver, _Tag} = From,
|
||||
Receiver ! {tcp, {http_poll, self()}, list_to_binary(Input)},
|
||||
From ! {tcp, {http_poll, self()}, list_to_binary(Input)},
|
||||
{reply, ok, StateName, StateData#state{input = "",
|
||||
waiting_input = false,
|
||||
last_receiver = From
|
||||
}}
|
||||
waiting_input = false}}
|
||||
end;
|
||||
|
||||
handle_sync_event(stop, From, StateName, StateData) ->
|
||||
@@ -235,7 +231,7 @@ handle_sync_event({http_put, Key, NewKey, Packet},
|
||||
Allow ->
|
||||
case StateData#state.waiting_input of
|
||||
false ->
|
||||
Input = [StateData#state.input|Packet],
|
||||
Input = [StateData#state.input | Packet],
|
||||
Reply = ok,
|
||||
{reply, Reply, StateName, StateData#state{input = Input,
|
||||
key = NewKey}};
|
||||
@@ -247,7 +243,6 @@ handle_sync_event({http_put, Key, NewKey, Packet},
|
||||
Reply = ok,
|
||||
{reply, Reply, StateName,
|
||||
StateData#state{waiting_input = false,
|
||||
last_receiver = Receiver,
|
||||
key = NewKey,
|
||||
timer = Timer}}
|
||||
end;
|
||||
@@ -292,18 +287,10 @@ terminate(Reason, StateName, StateData) ->
|
||||
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()}}
|
||||
ok;
|
||||
Receiver ->
|
||||
gen_fsm:reply(Receiver, {error, closed})
|
||||
end,
|
||||
resend_messages(StateData#state.output),
|
||||
ok.
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
@@ -354,27 +341,3 @@ cancel_timer(Timer) ->
|
||||
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.
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
%%% Created : 9 Apr 2004 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Copyright (c) 2004-2006 Alexey Shchepin
|
||||
%%% Copyright (c) 2004-2006 Process One
|
||||
%%% Copyright (c) 2004-2005 Alexey Shchepin
|
||||
%%% Copyright (c) 2004-2005 Process One
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(ejabberd_web_admin).
|
||||
@@ -1229,7 +1229,7 @@ list_vhosts(Lang) ->
|
||||
|
||||
|
||||
list_users(Host, Query, Lang, URLFunc) ->
|
||||
Res = list_users_parse_query(Query, Host),
|
||||
Res = list_users_parse_query(Query),
|
||||
Users = ejabberd_auth:get_vh_registered_users(Host),
|
||||
SUsers = lists:sort([{S, U} || {U, S} <- Users]),
|
||||
FUsers =
|
||||
@@ -1262,32 +1262,28 @@ list_users(Host, Query, Lang, URLFunc) ->
|
||||
[?XE("table",
|
||||
[?XE("tr",
|
||||
[?XC("td", ?T("User") ++ ":"),
|
||||
?XE("td", [?INPUT("text", "newusername", "")]),
|
||||
?XE("td", [?C([" @ ", Host])])
|
||||
?XE("td", [?INPUT("text", "newusername", "")])
|
||||
]),
|
||||
?XE("tr",
|
||||
[?XC("td", ?T("Password") ++ ":"),
|
||||
?XE("td", [?INPUT("password", "newuserpassword", "")]),
|
||||
?X("td")
|
||||
?XE("td", [?INPUT("password", "newuserpassword", "")])
|
||||
]),
|
||||
?XE("tr",
|
||||
[?X("td"),
|
||||
?XAE("td", [{"class", "alignright"}],
|
||||
[?INPUTT("submit", "addnewuser", "Add User")]),
|
||||
?X("td")
|
||||
[?INPUTT("submit", "addnewuser", "Add User")])
|
||||
])]),
|
||||
?P] ++
|
||||
FUsers)].
|
||||
|
||||
%% Parse user creation query and try register:
|
||||
list_users_parse_query(Query, Host) ->
|
||||
list_users_parse_query(Query) ->
|
||||
case lists:keysearch("addnewuser", 1, Query) of
|
||||
{value, _} ->
|
||||
{value, {_, Username}} =
|
||||
{value, {_, JIDString}} =
|
||||
lists:keysearch("newusername", 1, Query),
|
||||
{value, {_, Password}} =
|
||||
lists:keysearch("newuserpassword", 1, Query),
|
||||
case jlib:string_to_jid(Username++"@"++Host) of
|
||||
case jlib:string_to_jid(JIDString) of
|
||||
error ->
|
||||
error;
|
||||
#jid{user = User, server = Server} ->
|
||||
@@ -2183,8 +2179,10 @@ node_backup_parse_query(Node, Query) ->
|
||||
rpc:call(Node, mnesia,
|
||||
backup, [Path]);
|
||||
"restore" ->
|
||||
rpc:call(Node, ejabberd_admin,
|
||||
restore, [Path]);
|
||||
rpc:call(Node, mnesia,
|
||||
restore,
|
||||
[Path, [{default_op,
|
||||
keep_tables}]]);
|
||||
"fallback" ->
|
||||
rpc:call(Node, mnesia,
|
||||
install_fallback, [Path]);
|
||||
@@ -2586,7 +2584,7 @@ shared_roster_group_parse_query(Host, Group, Query) ->
|
||||
|
||||
OldMembers = mod_shared_roster:get_group_explicit_users(
|
||||
Host, Group),
|
||||
SJIDs = string:tokens(SMembers, ", \r\n"),
|
||||
SJIDs = string:tokens(SMembers, "\r\n"),
|
||||
NewMembers =
|
||||
lists:foldl(
|
||||
fun(_SJID, error) -> error;
|
||||
|
||||
Reference in New Issue
Block a user