Compare commits

..

1 Commits

Author SHA1 Message Date
Alexey Shchepin 2cfa6730cc Added 0.9 tag
SVN Revision: 320
2005-04-18 23:02:59 +00:00
745 changed files with 46483 additions and 205981 deletions
-1
View File
@@ -1 +0,0 @@
FROM ghcr.io/processone/devcontainer:latest
-7
View File
@@ -1,7 +0,0 @@
{
"name": "ejabberd",
"build": {"dockerfile": "Dockerfile"},
"extensions": ["erlang-ls.erlang-ls"],
"postCreateCommand": ".devcontainer/prepare-container.sh",
"remoteUser": "vscode"
}
-3
View File
@@ -1,3 +0,0 @@
echo "export PATH=/workspaces/ejabberd/_build/relive:$PATH" >>$HOME/.bashrc
echo "COOKIE" >$HOME/.erlang.cookie
chmod 400 $HOME/.erlang.cookie
-46
View File
@@ -1,46 +0,0 @@
.git
.win32
.examples
*.swp
*~
\#*#
.#*
.edts
*.dump
/Makefile
/config.log
/config.status
/config/releases.exs
/configure
/aclocal.m4
/*.cache
/deps/
/.deps-update/
/ebin/
/ejabberd.init
/ejabberd.service
/ejabberdctl
/ejabberdctl.example
/rel/ejabberd/
/rel/overlays/
/src/eldap_filter_yecc.erl
/vars.config
/dialyzer/
/test/*.beam
/test/*.ctc
/logs/
/priv/bin/captcha*sh
/priv/sql
/rel/ejabberd
/_build
/database/
/.rebar
/rebar.lock
/log/
Mnesia.nonode@nohost/
# Binaries created with tools/make-{binaries,installers,packages}:
/ejabberd_*.deb
/ejabberd-*.rpm
/ejabberd-*.run
/ejabberd-*.tar.gz
/.github/container/Dockerfile
-31
View File
@@ -1,31 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
assignees: ''
---
Before creating a ticket, please consider if this should fit the [discussion forum](https://github.com/processone/ejabberd/discussions) better.
## Environment
- ejabberd version: 18.09
- Erlang version: `erl +V`
- OS: Linux (Debian)
- Installed from: source | distro package | official deb/rpm | official binary installer | other
## Configuration (only if needed): grep -Ev '^$|^\s*#' ejabberd.yml
```yaml
loglevel: 4
...
```
## Errors from error.log/crash.log
No errors
## Bug description
Please, give us a precise description (what does not work, what is expected, etc.)
-26
View File
@@ -1,26 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: Kind:Feature
assignees: ''
---
Before creating a ticket, please consider if this should fit the [discussion forum](https://github.com/processone/ejabberd/discussions) better.
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when...
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
-20
View File
@@ -1,20 +0,0 @@
We are open to contributions for ejabberd, as GitHub pull requests (PR).
Here are a few points to consider before submitting your PR. (You can
remove the whole text after reading.)
1. Does this PR address an issue? Please reference it in the PR
description.
2. Have you properly described the proposed change?
3. Please make sure the change is atomic and does only touch the needed
modules. If you have other changes/fixes to provide, please submit
them as separate PRs.
4. If your change or new feature involves storage backends, did you make
sure your change works with all backends?
5. Do you provide tests? How can we check the behavior of the code?
6. Did you consider documentation changes in the
processone/docs.ejabberd.im repository?
-155
View File
@@ -1,155 +0,0 @@
name: 'Manage Database'
inputs:
for:
default: ""
description: 'One or more databases to manage:
mysql, pgsql, redis, mssql'
do:
default: ""
description: 'One or more tasks to do:
install, start, user, create, drop, dump'
dump-suffix:
default: ""
description: 'Suffix to append to the dump file name'
mssql-schema:
default: ""
description: 'SQL schema for the MSSQL database:
singlehost or multihost'
runs:
using: "composite"
steps:
############################################################# Install #####
- if: contains(inputs.for, 'pgsql') && contains(inputs.do, 'install')
shell: sh
run: |
sudo sed -i 's/yes/no/g' /etc/initramfs-tools/update-initramfs.conf
sudo rm -f /var/lib/man-db/auto-update || echo ok
sudo apt-get -q update
sudo apt-get -q -y install postgresql
- if: contains(inputs.for, 'redis') && contains(inputs.do, 'install')
shell: sh
run: |
sudo sed -i 's/yes/no/g' /etc/initramfs-tools/update-initramfs.conf
sudo rm -f /var/lib/man-db/auto-update || echo ok
sudo apt-get -q update
sudo apt-get -q -y install redis-server
- if: contains(inputs.for, 'mssql') && contains(inputs.do, 'install')
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: tdsodbc
- if: contains(inputs.for, 'mssql') && contains(inputs.do, 'install')
shell: sh
run: |
docker run -d -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=ejabberd_Test1" \
-v $(pwd)/test/docker/db/mssql/initdb/initdb_mssql.sql:/initdb_mssql.sql:ro \
-v $(pwd)/sql/mssql.sql:/mssql.sql:ro \
-v $(pwd)/sql/mssql.new.sql:/mssql.new.sql:ro \
-p 1433:1433 --name ejabberd-mssql \
"mcr.microsoft.com/mssql/server:2019-latest"
sleep 10
docker exec ejabberd-mssql /opt/mssql-tools18/bin/sqlcmd \
-C -U SA -P ejabberd_Test1 -S localhost -i /initdb_mssql.sql
- if: contains(inputs.for, 'mssql') && contains(inputs.do, 'install')
&& inputs.mssql-schema == 'singlehost'
shell: sh
run: |
docker exec ejabberd-mssql /opt/mssql-tools18/bin/sqlcmd \
-C -U SA -P ejabberd_Test1 -S localhost -d ejabberd_test \
-i /mssql.sql
- if: contains(inputs.for, 'mssql') && contains(inputs.do, 'install')
&& inputs.mssql-schema == 'multihost'
shell: sh
run: |
docker exec ejabberd-mssql /opt/mssql-tools18/bin/sqlcmd \
-C -U SA -P ejabberd_Test1 -S localhost -d ejabberd_test \
-i /mssql.new.sql
############################################################### Start #####
- if: contains(inputs.for, 'mysql') && contains(inputs.do, 'start')
shell: sh
run: |
sudo systemctl start mysql.service
- if: contains(inputs.for, 'pgsql') && contains(inputs.do, 'start')
shell: sh
run: |
sudo systemctl start postgresql.service
pg_isready
################################################################ User #####
- if: contains(inputs.for, 'mysql') && contains(inputs.do, 'user')
shell: sh
run: |
mysql -u root -proot -e "CREATE USER 'ejabberd_test'@'localhost'
IDENTIFIED BY 'ejabberd_test';"
- if: contains(inputs.for, 'pgsql') && contains(inputs.do, 'user')
shell: sh
run: |
sudo -u postgres psql -c "CREATE USER ejabberd_test
WITH PASSWORD 'ejabberd_test';"
################################################################ Dump #####
- if: contains(inputs.for, 'mysql') && contains(inputs.do, 'dump')
shell: sh
run: |
sudo mysqldump -u root -proot ejabberd_test \
> mysql-${{ inputs.dump-suffix }}.sql
- if: contains(inputs.for, 'pgsql') && contains(inputs.do, 'dump')
shell: sh
run: |
sudo -u postgres pg_dump ejabberd_test \
> pgsql-${{ inputs.dump-suffix }}.sql
################################################################ Drop #####
- if: contains(inputs.for, 'mysql') && contains(inputs.do, 'drop')
shell: sh
run: |
mysql -u root -proot -e "DROP DATABASE ejabberd_test;"
- if: contains(inputs.for, 'pgsql') && contains(inputs.do, 'drop')
shell: sh
run: |
sudo -u postgres psql -c "DROP DATABASE ejabberd_test;"
############################################################## Create #####
- if: contains(inputs.for, 'mysql') && contains(inputs.do, 'create')
shell: sh
run: |
mysql -u root -proot -e "CREATE DATABASE ejabberd_test;"
mysql -u root -proot -e "GRANT ALL ON ejabberd_test.*
TO 'ejabberd_test'@'localhost';"
- if: contains(inputs.for, 'pgsql') && contains(inputs.do, 'create')
shell: sh
run: |
sudo -u postgres psql -c "CREATE DATABASE ejabberd_test;"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES
ON DATABASE ejabberd_test TO ejabberd_test;"
sudo -u postgres psql -c "GRANT ALL ON SCHEMA public TO ejabberd_test;"
sudo -u postgres psql -c "ALTER DATABASE ejabberd_test
OWNER TO ejabberd_test;"
sudo -u postgres psql ejabberd_test -c "GRANT ALL PRIVILEGES ON ALL
TABLES IN SCHEMA public
TO ejabberd_test;"
sudo -u postgres psql ejabberd_test -c "GRANT ALL PRIVILEGES ON ALL
SEQUENCES IN SCHEMA public
TO ejabberd_test;"
-195
View File
@@ -1,195 +0,0 @@
name: 'Manage ejabberd'
inputs:
for:
default: ""
description: 'Release method, one of:
prod, dev, install, run, deb'
do:
default: ""
description: 'One or more tasks to perform:
deploy, no_acme, no_tls,
start, register, update_sql, stop,
check, logs'
username:
default: "user1"
description: 'Username part of the account JID'
host:
default: "localhost"
description: 'Host part of the account JID'
tool:
default: "rebar3"
description: 'Build tool to use:
rebar or rebar3 (only relevant to make rebar2)'
rel_name_vsn:
default: ""
description: 'Base name of installer files'
configure:
default: ""
description: 'Options to append to ./configure'
runs:
using: "composite"
steps:
- name: Path Definitions
id: path
shell: bash
run: |
case ${{ inputs.for }} in
'prod')
BASE="_build/prod/rel/ejabberd"
echo "conf=$BASE/conf" >> $GITHUB_OUTPUT
echo "logs=$BASE/logs" >> $GITHUB_OUTPUT
echo "ectl=$BASE/bin/ejabberdctl" >> $GITHUB_OUTPUT
;;
'dev')
BASE="_build/dev/rel/ejabberd"
echo "conf=$BASE/conf" >> $GITHUB_OUTPUT
echo "logs=$BASE/logs" >> $GITHUB_OUTPUT
echo "ectl=$BASE/bin/ejabberdctl" >> $GITHUB_OUTPUT
;;
'install')
BASE="/tmp/ejabberd"
echo "conf=$BASE/etc/ejabberd" >> $GITHUB_OUTPUT
echo "logs=$BASE/var/log/ejabberd" >> $GITHUB_OUTPUT
echo "ectl=$BASE/sbin/ejabberdctl" >> $GITHUB_OUTPUT
;;
'deb')
BASE="/opt/ejabberd"
echo "base=$BASE" >> $GITHUB_OUTPUT
echo "conf=$BASE/conf" >> $GITHUB_OUTPUT
echo "logs=$BASE/logs" >> $GITHUB_OUTPUT
echo "ectl=sudo /opt/${{ inputs.rel_name_vsn }}/bin/ejabberdctl" >> $GITHUB_OUTPUT
;;
'run')
BASE="$HOME/opt/ejabberd"
echo "base=$BASE" >> $GITHUB_OUTPUT
echo "conf=$BASE/conf" >> $GITHUB_OUTPUT
echo "logs=$BASE/logs" >> $GITHUB_OUTPUT
echo "ectl=$HOME/opt/${{ inputs.rel_name_vsn }}/bin/ejabberdctl" >> $GITHUB_OUTPUT
;;
esac
############################################################# Compile #####
- if: contains(inputs.do, 'compile')
shell: sh
run: |
TOOL=${{ inputs.tool }}
[ "${TOOL%3}" = "rebar" ] && TOOL="./$TOOL"
./autogen.sh
./configure --with-rebar=$TOOL \
--prefix=/tmp/ejabberd \
--enable-all ${{ inputs.configure }}
sed -i 's|, syntax_tools||g' src/ejabberd.app.src.script
REBAR_PROFILE=test make
############################################################## Deploy #####
- if: contains(inputs.do, 'deploy') &&
inputs.for == 'prod' && inputs.tool == 'rebar'
shell: sh
run: |
mkdir -p _build/prod && ln -s `pwd`/rel/ _build/prod/rel
- if: contains(inputs.do, 'deploy') &&
inputs.for == 'dev' && inputs.tool == 'rebar'
shell: sh
run: |
mkdir -p _build/dev && ln -s `pwd`/rel/ _build/dev/rel
- if: contains(inputs.do, 'deploy') &&
(inputs.for == 'prod' ||
inputs.for == 'dev' ||
inputs.for == 'install')
shell: sh
run: |
make ${{ inputs.for }}
- if: contains(inputs.do, 'deploy') &&
inputs.for == 'deb'
shell: sh
run: |
sudo dpkg -i $(ls -1 *.deb)
- if: contains(inputs.do, 'deploy') &&
inputs.for == 'run'
shell: sh
run: |
./$(ls -1 *.run)
################################################################ ACME #####
- if: contains(inputs.do, 'no_acme')
shell: sh
run: |
sed -i 's/loglevel/acme:\n auto: false\nloglevel/g' \
${{ steps.path.outputs.conf }}/ejabberd.yml
################################################################# TLS #####
- if: contains(inputs.do, 'no_tls') &&
inputs.for == 'dev'
shell: sh
run: |
sed -i 's/starttls_required: true/starttls_required: false/g' \
${{ steps.path.outputs.conf }}/ejabberd.yml
############################################################### Start #####
- if: contains(inputs.do, 'start')
shell: sh
run: |
${{ steps.path.outputs.ectl }} start
${{ steps.path.outputs.ectl }} started
############################################################ Register #####
- if: contains(inputs.do, 'register')
shell: sh
run: |
${{ steps.path.outputs.ectl }} \
register ${{ inputs.username }} ${{ inputs.host }} s0mePass
${{ steps.path.outputs.ectl }} \
registered_users ${{ inputs.host }} >> registered.log
grep -q '${{ inputs.username }}' registered.log
########################################################### UpdateSQL #####
- if: contains(inputs.do, 'update_sql')
shell: sh
run: |
${{ steps.path.outputs.ectl }} \
update_sql
################################################################ Stop #####
- if: contains(inputs.do, 'stop')
shell: sh
run: |
${{ steps.path.outputs.ectl }} stop
${{ steps.path.outputs.ectl }} stopped
############################################################### Check #####
- if: contains(inputs.do, 'check')
shell: sh
run: |
grep -q 'is started' ${{ steps.path.outputs.logs }}/ejabberd.log
grep -q 'is stopped' ${{ steps.path.outputs.logs }}/ejabberd.log
test $(find ${{ steps.path.outputs.logs }}/ -empty -name error.log)
################################################################ Logs #####
- if: contains(inputs.do, 'logs') || failure()
shell: sh
run: |
SUDO=sudo
[ "${{ inputs.for }}" = "deb" ] || SUDO=""
echo "::group::View ejabberd.log"
$SUDO cat ${{ steps.path.outputs.logs }}/ejabberd.log
echo "::endgroup::"
echo "::group::View error.log"
$SUDO cat ${{ steps.path.outputs.logs }}/error.log
echo "::endgroup::"
-208
View File
@@ -1,208 +0,0 @@
#' Define default build variables
ARG OTP_VSN='28.4.1.0'
ARG ELIXIR_VSN='1.19.5'
ARG UID='9000'
ARG USER='ejabberd'
ARG HOME="opt/$USER"
ARG BUILD_DIR="/$USER"
ARG VERSION='master'
################################################################################
#' Compile ejabberdapi
FROM docker.io/golang:1.25-alpine AS api
RUN go install -v \
github.com/processone/ejabberd-api/cmd/ejabberd@master \
&& mv bin/ejabberd bin/ejabberdapi
################################################################################
#' build and install ejabberd directly from source
FROM docker.io/erlang:${OTP_VSN}-alpine AS ejabberd
RUN apk -U add --no-cache \
ca-certificates \
autoconf \
automake \
bash \
build-base \
curl \
expat-dev \
file \
gd-dev \
git \
jpeg-dev \
libpng-dev \
libwebp-dev \
linux-pam-dev \
npm \
openssl-dev \
sqlite-dev \
yaml-dev \
zlib-dev
ARG ELIXIR_VSN
RUN wget -O - https://github.com/elixir-lang/elixir/archive/v$ELIXIR_VSN.tar.gz \
| tar -xzf -
WORKDIR /elixir-$ELIXIR_VSN
ENV ERL_FLAGS="+JPperf true"
RUN make install clean
RUN mix local.hex --force \
&& mix local.rebar --force
ARG BUILD_DIR
COPY / $BUILD_DIR/
WORKDIR $BUILD_DIR
RUN mv .github/container/ejabberdctl.template . \
&& mv .github/container/ejabberd.yml.example . \
&& ./autogen.sh \
&& ./configure --with-rebar=mix --enable-all \
&& make deps \
&& make prod
WORKDIR /rootfs
ARG VERSION
ARG HOME
RUN mkdir -p $HOME $HOME-$VERSION \
&& cp -r $BUILD_DIR/_build/prod/rel/ejabberd/* $HOME-$VERSION \
&& mv $HOME-$VERSION/conf $HOME/conf
RUN cp -p $BUILD_DIR/tools/captcha*.sh $HOME-$VERSION/lib
RUN find "$HOME-$VERSION/bin" -name 'ejabberd' -delete \
&& find "$HOME-$VERSION/releases" -name 'COOKIE' -delete
RUN wget -O "$HOME/conf/cacert.pem" 'https://curl.se/ca/cacert.pem'
#' Prepare ejabberd for runtime
RUN apk -U add --no-cache \
git \
libcap \
openssl
RUN mkdir -p usr/local/bin $HOME/conf $HOME/database $HOME/logs $HOME/upload
COPY --from=api /go/bin/ejabberdapi usr/local/bin/
RUN if [ ! -d $HOME/.ejabberd-modules ]; \
then \
if [ -d $BUILD_DIR/.ejabberd-modules ]; \
then cp -r $BUILD_DIR/.ejabberd-modules $HOME; \
else git clone https://github.com/processone/ejabberd-contrib --depth 1 \
$HOME/.ejabberd-modules/sources/ejabberd-contrib; \
fi \
fi
RUN export PEM=$HOME/conf/server.pem \
&& openssl req -x509 \
-batch \
-nodes \
-newkey rsa:4096 \
-keyout $PEM \
-out $PEM \
-days 3650 \
-subj "/CN=localhost"
RUN sed -i 's|^#CTL_OVER_HTTP=|CTL_OVER_HTTP=../|' "$HOME/conf/ejabberdctl.cfg"
RUN home_root_dir=$(echo $HOME | sed 's|\(.*\)/.*|\1 |') \
&& setcap 'cap_net_bind_service=+ep' $(find $home_root_dir -name beam.smp) \
&& echo -e \
"#!/bin/sh \
\n[ -z \$ERLANG_NODE_ARG ] && export ERLANG_NODE_ARG=ejabberd@localhost \
\nexport EMA=\"\$EJABBERD_MACRO_ADMIN\" \
\nexport HOST=\"\${EJABBERD_MACRO_HOST:-localhost}\" \
\nif [ -n \"\$EMA\" ] \
\nthen \
\n if [ \"\$EMA\" != \"\${EMA%%@*}\" ] \
\n then \
\n export USERNAME=\"\${EMA%%@*}\" \
\n export HOST=\"\${EMA##*@}\" \
\n else \
\n export USERNAME=\"\$EMA\" \
\n export SHOW_WARNING=\"true\" \
\n fi \
\nelif [ -n \"\$REGISTER_ADMIN_PASSWORD\" ] \
\nthen \
\n export USERNAME=\"admin\" \
\nelse \
\n export USERNAME=\"\$(od -A n -N 8 -t x8 /dev/urandom)\" \
\nfi \
\nexport EJABBERD_MACRO_ADMIN=\"\$USERNAME@\$HOST\" \
\n[ -n \"\$SHOW_WARNING\" ] && echo \"WARNING: The EJABBERD_MACRO_ADMIN environment variable was set to '\$EMA', but it should include the host... I'll overwrite it to become '\$EJABBERD_MACRO_ADMIN'.\" \
\n[ -n \"\$CTL_ON_CREATE\" ] && export SEPARATOR=\";\" \
\n[ -n \"\$REGISTER_ADMIN_PASSWORD\" ] && export CTL_ON_CREATE=\"register \${EJABBERD_MACRO_ADMIN%%@*} \${EJABBERD_MACRO_ADMIN##*@} \$REGISTER_ADMIN_PASSWORD \$SEPARATOR \$CTL_ON_CREATE\" \
\nexport CONFIG_DIR=/$HOME/conf \
\nexport LOGS_DIR=/$HOME/logs \
\nexport SPOOL_DIR=/$HOME/database \
\nexec /$(find $home_root_dir -name ejabberdctl) \"\$@\"" \
> usr/local/bin/ejabberdctl \
&& chmod +x usr/local/bin/* \
&& scanelf --needed --nobanner --format '%n#p' --recursive $home_root_dir \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e $home_root_dir" $1 " ]") == 0 { next } { print "so:" $1 }' \
| sed -e "s|so:libc.so|so:libc.musl-$(uname -m).so.1|" \
> /tmp/runDeps
ARG UID
RUN chown -R $UID:$UID $HOME
RUN cp /rootfs/$HOME-$VERSION/lib/captcha*.sh usr/local/bin/
RUN mkdir $HOME/sql \
&& find /rootfs/$HOME-$VERSION/lib/ -name *.sql -exec cp {} $HOME/sql \; -exec cp {} $HOME/database \;
################################################################################
#' Remove erlang/OTP & rebar3
FROM docker.io/erlang:${OTP_VSN}-alpine AS runtime
RUN apk del .erlang-rundeps \
&& rm -f $(which rebar3) \
&& find /usr -type d -name 'erlang' -exec rm -rf {} + \
&& find /usr -type l -exec test ! -e {} \; -delete
#' Update alpine, finalize runtime environment
COPY --from=ejabberd /tmp/runDeps /tmp/runDeps
RUN apk -U upgrade --available --no-cache \
&& apk add --no-cache \
$(cat /tmp/runDeps) \
so:libcap.so.2 \
so:libtdsodbc.so \
curl \
tini \
&& rm /tmp/runDeps
ARG USER
ARG UID
ARG HOME
RUN addgroup $USER -g $UID \
&& adduser -s /sbin/nologin -D -u $UID -h /$HOME -G $USER $USER
RUN ln -fs /usr/local/bin/ /opt/ejabberd/bin
RUN rm -rf /home \
&& ln -fs /opt /home
################################################################################
#' Build together production image
FROM scratch
ARG USER
ARG HOME
COPY --from=runtime / /
COPY --from=ejabberd /rootfs /
HEALTHCHECK \
--interval=1m \
--timeout=5s \
--start-period=5s \
--retries=10 \
CMD ejabberdctl status
WORKDIR /$HOME
USER $USER
VOLUME ["/$HOME"]
EXPOSE 1880 1883 4369-4399 5210 5222 5269 5280 5443 5478 7777 50000-50099
ENTRYPOINT ["/sbin/tini","--","ejabberdctl"]
CMD ["foreground"]
@@ -1,294 +0,0 @@
@echo off
::
:: ejabberd container installer for Windows
:: -------------------------------------
:: v0.4
::
:: This batch script downloads an ejabberd container image
:: and setups a docker container to run ejabberd.
::
:: 1. Download and install Docker:
::
:: If you use Windows 10, download Docker Desktop from:
:: https://www.docker.com/
::
:: If you use Windows 7 or 8, download Docker Toolbox from:
:: https://github.com/docker/toolbox/releases
:: After installation, run Docker Quickstart Installer
::
::
:: 2. Edit those options:
:: Directory where your ejabberd deployment files will be installed
:: (configuration, database, logs, ...)
::
:: In Windows 10 you can configure the path:
set INSTALL_DIR_WINDOWS10=C:\ejabberd
:: In older Windows, not configurable, it will be installed in:
:: C:\Users\%USERNAME%\ejabberd
:: Please enter the desired ejabberd domain name.
:: The domain is the visible attribute that is added to the username
:: to form the Jabber Identifier (for example: user@example.net).
:: This computer must be known on the network with this address name.
:: You can later add more in conf/ejabberd.yml
set HOST=localhost
:: Please enter the administrator username for the current
:: ejabberd installation. A Jabber account with this username
:: will be created and granted administrative privileges.
:: Don't use blankspaces in the username.
set USER=admin
:: Please provide a password for that new administrator account
set PASSWORD=
:: By default this downloads 'latest' ejabberd version,
:: but you can set a specific version, for example '22.05'
:: or the bleeding edge 'master'. See available tags in
:: https://github.com/processone/ejabberd/pkgs/container/ejabberd
set VERSION=latest
:: This tells docker what ports ejabberd will use.
:: You can later configure them in conf/ejabberd.yml
set PORTS=5180 5222 5269 5443
::
:: 3. Now save this script and run it.
::
::
:: 4. When installation is completed:
::
:: If using Windows 10, open Docker Desktop and you can:
::
:: - (>) START the ejabberd container
:: - Enter WebAdmin: click the ([->]) OPEN IN BROWSER button
:: - To try ejabberdctl, click the (>_) CLI button, then: ejabberdctl
:: - ([]) STOP the ejabberd container
::
:: If using an old Windows, open Kitematic and you can:
::
:: - START the ejabberd container
:: - Open your configuration, logs, ... in Settings > Volumes
:: - Enter WebAdmin in Settings > Hostname/Ports > click on the 5180 port
:: - Try ejabberdctl in EXEC, then: ejabberdctl
:: - STOP the ejabberd container
::
:: You can delete the container and create it again running this script,
:: the configuration and database are maintained.
::
::===============================================================
:: Check Windows version
::
::===============================================================
set INSTALL_DIR_DOCKER=c/Users/%USERNAME%/ejabberd
for /f "tokens=4-5 delims=. " %%i in ('ver') do set WVERSION=%%i.%%j
if "%wversion%" == "10.0" (
echo === Preparing paths to install in Windows 10...
set INSTALL_DIR=%INSTALL_DIR_WINDOWS10%
set VC=-v %INSTALL_DIR_WINDOWS10%\conf:/opt/ejabberd/conf
set VD=-v %INSTALL_DIR_WINDOWS10%\database:/opt/ejabberd/database
set VL=-v %INSTALL_DIR_WINDOWS10%\logs:/opt/ejabberd/logs
set VM=-v %INSTALL_DIR_WINDOWS10%\ejabberd-modules:/opt/ejabberd/.ejabberd-modules
set DOCKERDOWNLOAD="First download and install Docker Desktop from https://www.docker.com/"
) else (
echo === Preparing paths to install in Windows older than 10...
set INSTALL_DIR=C:\Users\%USERNAME%\ejabberd
set VC=-v "/%INSTALL_DIR_DOCKER%/conf:/opt/ejabberd/conf"
set VD=-v "/%INSTALL_DIR_DOCKER%/database:/opt/ejabberd/database"
set VL=-v "/%INSTALL_DIR_DOCKER%/logs:/opt/ejabberd/logs"
set VM=-v "/%INSTALL_DIR_DOCKER%/ejabberd-modules:/opt/ejabberd/.ejabberd-modules"
set DOCKERDOWNLOAD="First download and install Docker Toolbox from https://github.com/docker/toolbox/releases"
)
set VOLUMES=%VC% %VD% %VL% %VM%
::===============================================================
:: Check docker is installed
::
::===============================================================
docker version >NUL
if %ERRORLEVEL% NEQ 0 (
echo.
echo === ERROR: It seems docker is not installed!!!
echo.
echo %DOCKERDOWNLOAD%
echo === Then try to run this script again.
echo.
pause
exit 1
)
::===============================================================
:: Check install options are correctly set
::
::===============================================================
if [%PASSWORD%]==[] (
echo.
echo === ERROR: PASSWORD not set!!!
echo.
echo === Please edit this script and set the PASSWORD.
echo === Then try to run this script again.
echo.
pause
exit 1
)
::===============================================================
:: Download Docker image
::
::===============================================================
set IMAGE=ghcr.io/processone/ejabberd:%VERSION%
echo.
echo === Checking if the '%IMAGE%' container image was already downloaded...
docker image history %IMAGE% >NUL
if %ERRORLEVEL% NEQ 0 (
echo === The '%IMAGE%' container image was not downloaded yet.
echo.
echo === Downloading the '%IMAGE%' container image, please wait...
docker pull %IMAGE%
) else (
echo === The '%IMAGE%' container image was already downloaded.
)
::===============================================================
:: Create preliminary container
::
::===============================================================
echo.
echo === Checking if the 'ejabberd' container already exists...
docker container logs ejabberd
if %ERRORLEVEL% EQU 0 (
echo.
echo === The 'ejabberd' container already exists.
echo === Nothing to do, so installation finishes now.
echo === You can go to Docker Desktop and start the 'ejabberd' container.
echo.
pause
exit 1
) else (
echo === The 'ejabberd' container doesn't yet exist,
echo === so let's continue the installation process.
)
echo.
if exist %INSTALL_DIR% (
echo === The INSTALL_DIR %INSTALL_DIR% already exists.
echo === No need to create the preliminary 'ejabberd-pre' image.
) else (
echo === The INSTALL_DIR %INSTALL_DIR% doesn't exist.
echo === Let's create the preliminary 'ejabberd-pre' image.
CALL :create-ejabberd-pre
)
::===============================================================
:: Create final container
::
::===============================================================
echo.
echo === Creating the final 'ejabberd' container using %IMAGE% image...
setlocal EnableDelayedExpansion
set PS=
for %%a in (%PORTS%) do (
set PS=!PS! -p %%a:%%a
)
docker create --name ejabberd --hostname localhost %PS% %VOLUMES% %IMAGE%
echo.
echo === Installation completed.
echo.
pause
EXIT /B %ERRORLEVEL%
::===============================================================
:: Function to create preliminary container
::
::===============================================================
:create-ejabberd-pre
echo.
echo === Creating a preliminary 'ejabberd-pre' container using %IMAGE% image...
docker create --name ejabberd-pre --hostname localhost %IMAGE%
echo.
echo === Now 'ejabberd-pre' will be started.
docker container start ejabberd-pre
echo.
echo === Waiting ejabberd to be running...
set /A timeout = 10
set status=4
goto :while
:statusstart
docker exec -it ejabberd-pre ejabberdctl status
goto :statusend
:while
if %status% GTR 0 (
echo.
timeout /t 1 /nobreak >NUL
set /A timeout = timeout - 1
if %timeout% EQU 0 (
set status=-1
) else (
goto :statusstart
:statusend
set status=%ERRORLEVEL%
)
goto :while
)
echo.
echo === Setting a few options...
docker exec -it ejabberd-pre sed -i "s!- localhost!- %HOST%!g" conf/ejabberd.yml
docker exec -it ejabberd-pre sed -i "s!^acl:!acl:\n admin:\n user:\n - \"%USER%@%HOST%\"!g" conf/ejabberd.yml
docker exec -it ejabberd-pre sed -i "s!5280!5180!g" conf/ejabberd.yml
docker exec -it ejabberd-pre sed -i "s!/admin!/!g" conf/ejabberd.yml
docker exec -it ejabberd-pre ejabberdctl reload_config
echo.
echo === Registering the administrator account...
docker exec -it ejabberd-pre ejabberdctl register %USER% %HOST% %PASSWORD%
docker exec -it ejabberd-pre ejabberdctl stop
echo.
echo === Copying conf, database, logs...
mkdir %INSTALL_DIR%
mkdir %INSTALL_DIR%\conf
mkdir %INSTALL_DIR%\database
mkdir %INSTALL_DIR%\logs
mkdir %INSTALL_DIR%\ejabberd-modules
docker cp ejabberd-pre:/opt/ejabberd/conf/ %INSTALL_DIR%
docker cp ejabberd-pre:/opt/ejabberd/database/ %INSTALL_DIR%
docker cp ejabberd-pre:/opt/ejabberd/logs/ %INSTALL_DIR%
echo.
echo === Deleting the preliminary 'ejabberd-pre' container...
docker stop ejabberd-pre
docker rm ejabberd-pre
EXIT /B 0
-289
View File
@@ -1,289 +0,0 @@
###
### ejabberd configuration file
###
### The parameters used in this configuration file are explained at
###
### https://docs.ejabberd.im/admin/configuration
###
### The configuration file is written in YAML.
### *******************************************************
### ******* !!! WARNING !!! *******
### ******* YAML IS INDENTATION SENSITIVE *******
### ******* MAKE SURE YOU INDENT SECTIONS CORRECTLY *******
### *******************************************************
### Refer to http://en.wikipedia.org/wiki/YAML for the brief description.
###
define_macro:
HOST: localhost
## ADMIN: ... # set by /usr/local/bin/ejabberdctl
PORT_C2S: 5222
PORT_C2S_TLS: 5223
PORT_S2S: 5269
PORT_HTTP_TLS: 5443
PORT_HTTP: 5280
PORT_BROWSER: 1880
PORT_STUN: 5478
PORT_TURN_MIN: 50000
PORT_TURN_MAX: 50099
PORT_MQTT: 1883
PORT_PROXY65: 7777
STARTTLS_REQUIRED: true
hosts:
- HOST
loglevel: info
## If you already have certificates, list them here
# certfiles:
# - /etc/letsencrypt/live/domain.tld/fullchain.pem
# - /etc/letsencrypt/live/domain.tld/privkey.pem
ca_file: /opt/ejabberd/conf/cacert.pem
certfiles:
- /opt/ejabberd/conf/server.pem
listen:
-
port: PORT_C2S
ip: "::"
module: ejabberd_c2s
max_stanza_size: 262144
shaper: c2s_shaper
access: c2s
starttls_required: STARTTLS_REQUIRED
-
port: PORT_C2S_TLS
ip: "::"
module: ejabberd_c2s
max_stanza_size: 262144
shaper: c2s_shaper
access: c2s
tls: true
-
port: PORT_S2S
ip: "::"
module: ejabberd_s2s_in
max_stanza_size: 524288
shaper: s2s_shaper
-
port: PORT_HTTP_TLS
ip: "::"
module: ejabberd_http
tls: true
request_handlers:
/admin: ejabberd_web_admin
/api: mod_http_api
/bosh: mod_bosh
/captcha: ejabberd_captcha
/upload: mod_http_upload
/websocket: ejabberd_http_ws
-
port: PORT_HTTP
ip: "::"
module: ejabberd_http
request_handlers:
/admin: ejabberd_web_admin
/.well-known/acme-challenge: ejabberd_acme
-
port: PORT_BROWSER
ip: "::"
module: ejabberd_http
request_handlers:
/: ejabberd_web_admin
-
port: "unix:../sockets/ctl_over_http.sock"
module: ejabberd_http
unix_socket:
mode: '0600'
request_handlers:
/ctl: ejabberd_ctl
-
port: PORT_STUN
ip: "::"
transport: udp
module: ejabberd_stun
use_turn: true
turn_min_port: PORT_TURN_MIN
turn_max_port: PORT_TURN_MAX
## The server's public IPv4 address:
# turn_ipv4_address: "203.0.113.3"
## The server's public IPv6 address:
# turn_ipv6_address: "2001:db8::3"
-
port: PORT_MQTT
ip: "::"
module: mod_mqtt
backlog: 1000
s2s_use_starttls: optional
acl:
local:
user_regexp: ""
loopback:
ip:
- 127.0.0.0/8
- ::1/128
admin:
user:
- ADMIN
access_rules:
local:
allow: local
c2s:
deny: blocked
allow: all
announce:
allow: admin
configure:
allow: admin
muc_create:
allow: local
pubsub_createnode:
allow: local
trusted_network:
allow: loopback
api_permissions:
"console commands":
from: ejabberd_ctl
who: all
what: "*"
"webadmin commands":
from: ejabberd_web_admin
who: admin
what: "*"
"adhoc commands":
from: mod_adhoc_api
who: admin
what: "*"
"http access":
from: mod_http_api
who:
access:
allow:
- acl: loopback
- acl: admin
oauth:
scope: "ejabberd:admin"
access:
allow:
- acl: loopback
- acl: admin
what:
- "*"
- "!stop"
- "!start"
"public commands":
who:
ip: 127.0.0.1/8
what:
- status
- connected_users_number
shaper:
normal:
rate: 3000
burst_size: 20000
fast: 100000
shaper_rules:
max_user_sessions: 10
max_user_offline_messages:
5000: admin
100: all
c2s_shaper:
none: admin
normal: all
s2s_shaper: fast
modules:
mod_adhoc: {}
mod_adhoc_api: {}
mod_admin_extra: {}
mod_announce:
access: announce
mod_avatar: {}
mod_blocking: {}
mod_bosh: {}
mod_caps: {}
mod_carboncopy: {}
mod_client_state: {}
mod_configure: {}
mod_disco: {}
mod_fail2ban: {}
mod_http_api: {}
mod_http_upload:
put_url: https://@HOST_URL_ENCODE@:5443/upload
custom_headers:
"Access-Control-Allow-Origin": "https://@HOST@"
"Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
"Access-Control-Allow-Headers": "Content-Type"
mod_last: {}
mod_mam:
## Mnesia is limited to 2GB, better to use an SQL backend
## For small servers SQLite is a good fit and is very easy
## to configure. Uncomment this when you have SQL configured:
## db_type: sql
assume_mam_usage: true
default: always
mod_mqtt: {}
mod_muc:
access:
- allow
access_admin:
- allow: admin
access_create: muc_create
access_persistent: muc_create
access_mam:
- allow
default_room_options:
mam: true
mod_muc_admin: {}
mod_offline:
access_max_user_messages: max_user_offline_messages
mod_ping: {}
mod_privacy: {}
mod_private: {}
mod_proxy65:
access: local
max_connections: 5
port: PORT_PROXY65
mod_pubsub:
access_createnode: pubsub_createnode
plugins:
- flat
- pep
force_node_config:
## Avoid buggy clients to make their bookmarks public
storage:bookmarks:
access_model: whitelist
mod_push: {}
mod_push_keepalive: {}
mod_register:
## Only accept registration requests from the "trusted"
## network (see access_rules section above).
## Think twice before enabling registration from any
## address. See the Jabber SPAM Manifesto for details:
## https://github.com/ge0rg/jabber-spam-fighting-manifesto
ip_access: trusted_network
mod_roster:
versioning: true
mod_s2s_bidi: {}
mod_s2s_dialback: {}
mod_shared_roster: {}
mod_stream_mgmt:
resend_on_timeout: if_offline
mod_stun_disco: {}
mod_vcard: {}
mod_vcard_xupdate: {}
mod_version:
show_os: false
### Local Variables:
### mode: yaml
### End:
### vim: set filetype=yaml tabstop=8
-652
View File
@@ -1,652 +0,0 @@
#!/bin/sh
# define default configuration
POLL=true
ERL_MAX_PORTS=32000
ERL_PROCESSES=250000
ERL_MAX_ETS_TABLES=1400
FIREWALL_WINDOW=""
INET_DIST_INTERFACE=""
ERLANG_NODE=ejabberd@localhost
# define default environment variables
[ -z "$SCRIPT" ] && SCRIPT=$0
SCRIPT_DIR="$(cd "$(dirname "$SCRIPT")" && pwd -P)"
# shellcheck disable=SC2034
ERTS_VSN="{{erts_vsn}}"
ERL="{{erl}}"
EPMD="{{epmd}}"
IEX="{{iexpath}}"
COOKIE_FILE="$HOME"/.erlang.cookie
[ -n "$ERLANG_COOKIE" ] && [ ! -f "$COOKIE_FILE" ] && echo "$ERLANG_COOKIE" > "$COOKIE_FILE" && chmod 400 "$COOKIE_FILE"
# check the proper system user is used
case $(id -un) in
"$INSTALLUSER")
EXEC_CMD="as_current_user"
;;
root)
if [ -n "$INSTALLUSER" ] ; then
EXEC_CMD="as_install_user"
else
EXEC_CMD="as_current_user"
echo "WARNING: It is not recommended to run ejabberd as root" >&2
fi
;;
*)
if [ -n "$INSTALLUSER" ] ; then
echo "ERROR: This command can only be run by root or the user $INSTALLUSER" >&2
exit 7
else
EXEC_CMD="as_current_user"
fi
;;
esac
# parse command line parameters
while [ $# -gt 0 ]; do
case $1 in
-n|--node) ERLANG_NODE_ARG=$2; shift 2;;
-s|--spool) SPOOL_DIR=$2; shift 2;;
-l|--logs) LOGS_DIR=$2; shift 2;;
-f|--config) EJABBERD_CONFIG_PATH=$2; shift 2;;
-c|--ctl-config) EJABBERDCTL_CONFIG_PATH=$2; shift 2;;
-d|--config-dir) CONFIG_DIR=$2; shift 2;;
-t|--no-timeout) NO_TIMEOUT="--no-timeout"; shift;;
*) break;;
esac
done
# define ejabberd variables if not already defined from the command line
: "${CONFIG_DIR:="{{config_dir}}"}"
: "${LOGS_DIR:="{{logs_dir}}"}"
: "${EJABBERD_CONFIG_PATH:="$CONFIG_DIR/ejabberd.yml"}"
: "${EJABBERDCTL_CONFIG_PATH:="$CONFIG_DIR/ejabberdctl.cfg"}"
# Allows passing extra Erlang command-line arguments in vm.args file
: "${VMARGS:="$CONFIG_DIR/vm.args"}"
# shellcheck source=ejabberdctl.cfg.example
[ -f "$EJABBERDCTL_CONFIG_PATH" ] && . "$EJABBERDCTL_CONFIG_PATH"
[ -n "$ERLANG_NODE_ARG" ] && ERLANG_NODE="$ERLANG_NODE_ARG"
[ "$ERLANG_NODE" = "${ERLANG_NODE%@*}" ] && ERLANG_NODE="$ERLANG_NODE@$(hostname -s)"
[ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] && S="-s"
: "${SPOOL_DIR:="{{spool_dir}}"}"
: "${EJABBERD_LOG_PATH:="$LOGS_DIR/ejabberd.log"}"
# backward support for old mnesia spool dir path
: "${SPOOL_DIR_OLD:="$SPOOL_DIR/$ERLANG_NODE"}"
[ -r "$SPOOL_DIR_OLD/schema.DAT" ] && [ ! -r "$SPOOL_DIR/schema.DAT" ] && SPOOL_DIR="$SPOOL_DIR_OLD"
# define erl parameters
ERLANG_OPTS="+K $POLL +P $ERL_PROCESSES $ERL_OPTIONS"
if [ -n "$FIREWALL_WINDOW" ] ; then
ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}"
fi
if [ -n "$INET_DIST_INTERFACE" ] ; then
INET_DIST_INTERFACE2=$("$ERL" $ERLANG_OPTS -noshell -eval 'case inet:parse_address("'$INET_DIST_INTERFACE'") of {ok,IP} -> io:format("~p",[IP]); _ -> ok end.' -s erlang halt)
if [ -n "$INET_DIST_INTERFACE2" ] ; then
if [ "$(echo "$INET_DIST_INTERFACE2" | grep -o "," | wc -l)" -eq 7 ] ; then
INET_DIST_INTERFACE2="$INET_DIST_INTERFACE2 -proto_dist inet6_tcp"
fi
ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_use_interface $INET_DIST_INTERFACE2"
fi
fi
[ -n "$ERL_DIST_PORT" ] && ERLANG_OPTS="$ERLANG_OPTS -erl_epmd_port $ERL_DIST_PORT -start_epmd false"
# if vm.args file exists in config directory, pass it to Erlang VM
[ -f "$VMARGS" ] && ERLANG_OPTS="$ERLANG_OPTS -args_file $VMARGS"
ERL_LIBS='{{libdir}}'
ERL_CRASH_DUMP="$LOGS_DIR"/erl_crash_$(date "+%Y%m%d-%H%M%S").dump
ERL_INETRC="$CONFIG_DIR"/inetrc
# define ejabberd parameters
EJABBERD_OPTS="\
$(sed '/^log_rotate_size/!d;s/:[ \t]*\([0-9]\{1,\}\).*/ \1/;s/:[ \t]*\(infinity\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
$(sed '/^log_rotate_count/!d;s/:[ \t]*\([0-9]*\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
$(sed '/^log_burst_limit_count/!d;s/:[ \t]*\([0-9]*\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
$(sed '/^log_burst_limit_window_time/!d;s/:[ \t]*\([0-9]*[a-z]*\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
$EJABBERD_OPTS"
[ -n "$EJABBERD_OPTS" ] && EJABBERD_OPTS="-ejabberd $EJABBERD_OPTS"
EJABBERD_OPTS="-mnesia dir \"$SPOOL_DIR\" $MNESIA_OPTIONS $EJABBERD_OPTS -s ejabberd"
# export global variables
export EJABBERD_CONFIG_PATH
export EJABBERD_LOG_PATH
export EJABBERD_PID_PATH
export ERL_CRASH_DUMP
export ERL_EPMD_ADDRESS
export ERL_DIST_PORT
export ERL_INETRC
export ERL_MAX_PORTS
export ERL_MAX_ETS_TABLES
export CONTRIB_MODULES_PATH
export CONTRIB_MODULES_CONF_DIR
export ERL_LIBS
export SCRIPT_DIR
# Only required for Erlang/OTP 25:
export ERL_FLAGS="$ERL_FLAGS -enable-feature maybe_expr"
set_dist_client()
{
[ -n "$ERL_DIST_PORT" ] && ERLANG_OPTS="$ERLANG_OPTS -dist_listen false"
}
# run command either directly or via su $INSTALLUSER
run_cmd()
{
case $EXEC_CMD in
as_install_user) su -s /bin/sh -c '"$0" "$@"' "$INSTALLUSER" -- "$@" ;;
as_current_user) "$@" ;;
esac
}
exec_cmd()
{
case $EXEC_CMD,$(uname -s) in
as_install_user,OpenBSD)
su -s /bin/sh "$INSTALLUSER" -c 'exec "$0" "$@"' "$@"
;;
as_install_user,NetBSD)
su "$INSTALLUSER" -c 'exec "$0" "$@"' -- "$@"
;;
as_install_user,*)
su -s /bin/sh -c 'exec "$0" "$@"' "$INSTALLUSER" -- "$@"
;;
as_current_user,*)
"$@"
;;
esac
}
run_erl()
{
NODE=$1; shift
run_cmd "$ERL" ${S:--}name "$NODE" $ERLANG_OPTS "$@"
}
exec_erl()
{
NODE=$1; shift
exec_cmd "$ERL" ${S:--}name "$NODE" $ERLANG_OPTS "$@"
}
exec_iex()
{
NODE=$1; shift
exec_cmd "$IEX" -${S:--}name "$NODE" --erl "$ERLANG_OPTS" "$@"
}
# usage
debugwarning()
{
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
echo "--------------------------------------------------------------------"
echo ""
echo "IMPORTANT: we will attempt to attach an INTERACTIVE shell"
echo "to an already running ejabberd node."
echo "If an ERROR is printed, it means the connection was not successful."
echo "You can interact with the ejabberd node if you know how to use it."
echo "Please be extremely cautious with your actions,"
echo "and exit immediately if you are not completely sure."
echo ""
echo "To exit and detach this shell from ejabberd, press:"
echo " control+g and then q"
echo ""
#vt100 echo "Please do NOT use control+c in this debug shell !"
#vt100 echo ""
echo "--------------------------------------------------------------------"
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
echo " EJABBERD_BYPASS_WARNINGS=true"
echo "Press return to continue"
read -r _
echo ""
fi
}
livewarning()
{
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
echo "--------------------------------------------------------------------"
echo ""
echo "IMPORTANT: ejabberd is going to start in LIVE (interactive) mode."
echo "All log messages will be shown in the command shell."
echo "You can interact with the ejabberd node if you know how to use it."
echo "Please be extremely cautious with your actions,"
echo "and exit immediately if you are not completely sure."
echo ""
echo "To stop ejabberd gracefully:"
echo " ejabberd:stop()."
echo "To quit erlang immediately, press:"
echo " control+g and then q"
echo ""
echo "--------------------------------------------------------------------"
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
echo " EJABBERD_BYPASS_WARNINGS=true"
echo "Press return to continue"
read -r _
echo ""
fi
}
check_etop_result()
{
result=$?
if [ $result -eq 1 ] ; then
echo ""
echo "It seems there was some problem running 'ejabberdctl etop'."
echo "Is the error message something like this?"
echo " Failed to load module 'etop' because it cannot be found..."
echo "Then probably ejabberd was compiled with development tools disabled."
echo "To use 'etop', recompile ejabberd with: ./configure --enable-tools"
echo ""
exit $result
fi
}
check_iex_result()
{
result=$?
if [ $result -eq 127 ] ; then
echo ""
echo "It seems there was some problem finding 'iex' binary from Elixir."
echo "Probably ejabberd was compiled with Rebar3 and Elixir disabled, like:"
echo " ./configure"
echo "which is equivalent to:"
echo " ./configure --with-rebar=rebar3 --disable-elixir"
echo "To use 'iex', recompile ejabberd enabling Elixir or using Mix:"
echo " ./configure --enable-elixir"
echo " ./configure --with-rebar=mix"
echo ""
exit $result
fi
}
help()
{
echo ""
echo "Commands to start an ejabberd node:"
echo " start Start in server mode"
echo " foreground Start in server mode (attached)"
echo " foreground-quiet Start in server mode (attached), show only critical messages"
echo " live Start in interactive mode, with Erlang shell"
echo " iexlive Start in interactive mode, with Elixir shell"
echo ""
echo "Commands to interact with a running ejabberd node:"
echo " debug Attach an interactive Erlang shell to a running node"
echo " iexdebug Attach an interactive Elixir shell to a running node"
echo " etop Attach to a running node and start Erlang Top"
echo " ping Send ping to the node, returns pong or pang"
echo " started|stopped Wait for the node to fully start|stop"
echo ""
echo "Optional parameters when starting an ejabberd node:"
echo " --config-dir dir Config ejabberd: $CONFIG_DIR"
echo " --config file Config ejabberd: $EJABBERD_CONFIG_PATH"
echo " --ctl-config file Config ejabberdctl: $EJABBERDCTL_CONFIG_PATH"
echo " --logs dir Directory for logs: $LOGS_DIR"
echo " --spool dir Database spool dir: $SPOOL_DIR"
echo " --node nodename ejabberd node name: $ERLANG_NODE"
echo ""
}
# dynamic node name helper
uid() {
ERTSVERSION="$("$ERL" -version 2>&1 | sed 's|.* \([0-9]*[0-9]\).*|\1|g')"
if [ $ERTSVERSION -lt 11 ] ; then # otp 23.0 includes erts 11.0
# Erlang/OTP lower than 23, which doesn's support dynamic node code
N=1
PF=$(( $$ % 97 ))
while
case $# in
0) NN="${PF}-${N}-${ERLANG_NODE}"
;;
1) NN="${PF}-${N}-${1}-${ERLANG_NODE}"
;;
2) NN="${PF}-${N}-${1}@${2}"
;;
esac
N=$(( N + 1 + ( $$ % 5 ) ))
"$EPMD" -names 2>/dev/null | grep -q " ${NN%@*} "
do :; done
echo $NN
else
# Erlang/OTP 23 or higher: use native dynamic node code
# https://www.erlang.org/patches/otp-23.0#OTP-13812
if [ "$ERLANG_NODE" != "${ERLANG_NODE%.*}" ]; then
echo "undefined@${ERLANG_NODE#*@}"
else
echo "undefined"
fi
fi
}
# stop epmd if there is no other running node
stop_epmd()
{
[ -n "$ERL_DIST_PORT" ] && return
"$EPMD" -names 2>/dev/null | grep -q name || "$EPMD" -kill >/dev/null
}
# make sure node not already running and node name unregistered
# if all ok, ensure runtime directory exists and make it current directory
check_start()
{
ECSIMAGE_DBPATH=$HOME/database/$ERLANG_NODE
[ ! -d "$ECSIMAGE_DBPATH" ] && ln -s $HOME/database $HOME/database/$ERLANG_NODE
[ -n "$ERL_DIST_PORT" ] && {
netstat -nl | grep ":5210" >/dev/null && {
echo "Error: The file ejabberdctl.cfg has configured ERL_DIST_PORT=$ERL_DIST_PORT"
echo " but the port 5210 is already in use."
echo " Stop that program or configure a different ERL_DIST_PORT"
echo ""
netstat -nlp | grep ":5210"
echo ""
}
return
}
"$EPMD" -names 2>/dev/null | grep -q " ${ERLANG_NODE%@*} " && {
pgrep -f "$ERLANG_NODE" >/dev/null && {
echo "ERROR: The ejabberd node '$ERLANG_NODE' is already running."
exit 4
}
pgrep beam >/dev/null && {
echo "ERROR: The ejabberd node '$ERLANG_NODE' is registered,"
echo " but no related beam process has been found."
echo "Shutdown all other erlang nodes, and call 'epmd -kill'."
exit 5
}
"$EPMD" -kill >/dev/null
}
}
post_waiter_fork()
{
(FIRST_RUN=$FIRST_RUN "$0" post_waiter)&
}
post_waiter_waiting()
{
$0 started
[ -n "$FIRST_RUN" ] && [ -n "$CTL_ON_CREATE" ] && (post_waiter_loop $CTL_ON_CREATE)
[ -n "$CTL_ON_START" ] && post_waiter_loop $CTL_ON_START
}
post_waiter_loop()
{
LIST=$@
HEAD=${LIST%% ; *}
TAIL=${LIST#* ; }
HEAD2=${HEAD#\! *}
echo ":> ejabberdctl $HEAD2"
$0 $HEAD2
ctlstatus=$?
if [ $ctlstatus -ne 0 ] ; then
if [ "$HEAD" != "$HEAD2" ] ; then
echo ":> FAILURE in command '$HEAD2' !!! Ignoring result"
else
echo ":> FAILURE in command '$HEAD' !!! Stopping ejabberd..."
$0 halt > /dev/null
exit $ctlstatus
fi
fi
[ "$HEAD" = "$TAIL" ] || post_waiter_loop $TAIL
}
# allow sync calls
wait_status()
{
wait_status_node "$ERLANG_NODE" $1 $2 $3
}
wait_status_node()
{
CONNECT_NODE=$1
shift
# args: status try delay
# return: 0 OK, 1 KO
timeout="$2"
status=4
while [ "$status" -ne "$1" ] ; do
sleep "$3"
timeout=$((timeout - 1))
if [ $timeout -eq 0 ] ; then
status="$1"
else
run_erl "$(uid ctl)" -hidden -noinput \
-eval 'net_kernel:connect_node('"'$CONNECT_NODE'"')' \
-s ejabberd_ctl \
-extra "$CONNECT_NODE" $NO_TIMEOUT status > /dev/null
status="$?"
fi
done
[ $timeout -gt 0 ]
}
exec_other_command()
{
exec_other_command_node $ERLANG_NODE "$@"
}
exec_other_command_node()
{
CONNECT_NODE=$1
shift
if [ -z "$CTL_OVER_HTTP" ] || [ ! -S "$CTL_OVER_HTTP" ] \
|| [ ! -x "$(command -v curl)" ] || [ -z "$1" ] || [ "$1" = "help" ] \
|| [ "$1" = "mnesia_info_ctl" ]|| [ "$1" = "print_sql_schema" ] ; then
run_erl "$(uid ctl)" -hidden -noinput \
-eval 'net_kernel:connect_node('"'$CONNECT_NODE'"')' \
-s ejabberd_ctl \
-extra "$CONNECT_NODE" $NO_TIMEOUT "$@"
result=$?
case $result in
3) help;;
*) :;;
esac
return $result
else
exec_ctl_over_http_socket "$@"
fi
}
exec_ctl_over_http_socket()
{
COMMAND=${1}
CARGS=""
while [ $# -gt 0 ]; do
[ -z "$CARGS" ] && CARGS="[" || CARGS="${CARGS}, "
CARGS="${CARGS}\"$1\""
shift
done
CARGS="${CARGS}]"
TEMPHEADERS=temp-headers.log
curl \
--unix-socket ${CTL_OVER_HTTP} \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "${CARGS}" \
--dump-header ${TEMPHEADERS} \
--no-progress-meter \
"http://localhost/ctl/${COMMAND}"
result=$(sed -n 's/.*status-code: \([0-9]*\).*/\1/p' < $TEMPHEADERS)
rm ${TEMPHEADERS}
case $result in
2|3) exec_other_command help ${COMMAND};;
*) :;;
esac
exit $result
}
# ensure we can change current directory to SPOOL_DIR
[ -f "$SPOOL_DIR/schema.DAT" ] || FIRST_RUN=true
[ -d "$SPOOL_DIR" ] || run_cmd mkdir -p "$SPOOL_DIR"
cd "$SPOOL_DIR" || {
echo "ERROR: can not access directory $SPOOL_DIR"
exit 6
}
printe()
{
printf "\n"
printf "\e[1;40;32m==> %s\e[0m\n" "$1"
}
## Function copied from tools/make-installers
user_agrees()
{
question="$*"
if [ -t 0 ]
then
printe "$question (y/n) [n]"
read -r response
case "$response" in
[Yy]|[Yy][Ee][Ss])
return 0
;;
[Nn]|[Nn][Oo]|'')
return 1
;;
*)
echo 'Please respond with "yes" or "no".'
user_agrees "$question"
;;
esac
else # Assume 'yes' if not running interactively.
return 0
fi
}
mnesia_change()
{
ERLANG_NODE_OLD="$1"
[ "$ERLANG_NODE_OLD" = "" ] \
&& echo "Error: Please provide the old erlang node name, for example:" \
&& echo " ejabberdctl mnesia_change ejabberd@oldmachine" \
&& exit 1
SPOOL_DIR_BACKUP=$SPOOL_DIR/$ERLANG_NODE_OLD-backup/
OLDFILE=$SPOOL_DIR_BACKUP/$ERLANG_NODE_OLD.backup
NEWFILE=$SPOOL_DIR_BACKUP/$ERLANG_NODE.backup
printe "This changes your mnesia database from node name '$ERLANG_NODE_OLD' to '$ERLANG_NODE'"
[ -d "$SPOOL_DIR_BACKUP" ] && printe "WARNING! A backup of old node already exists in $SPOOL_DIR_BACKUP"
if ! user_agrees "Do you want to proceed?"
then
echo 'Operation aborted.'
exit 1
fi
printe "Starting ejabberd with old node name $ERLANG_NODE_OLD ..."
exec_erl "$ERLANG_NODE_OLD" $EJABBERD_OPTS -detached
wait_status_node $ERLANG_NODE_OLD 0 30 2
result=$?
case $result in
1) echo "There was a problem starting ejabberd with the old erlang node name. " \
&& echo "Check for log errors in $EJABBERD_LOG_PATH" \
&& exit $result;;
*) :;;
esac
exec_other_command_node $ERLANG_NODE_OLD "status"
printe "Making backup of old database to file $OLDFILE ..."
mkdir $SPOOL_DIR_BACKUP
exec_other_command_node $ERLANG_NODE_OLD backup "$OLDFILE"
printe "Changing node name in new backup file $NEWFILE ..."
exec_other_command_node $ERLANG_NODE_OLD mnesia_change_nodename "$ERLANG_NODE_OLD" "$ERLANG_NODE" "$OLDFILE" "$NEWFILE"
printe "Stopping old ejabberd..."
exec_other_command_node $ERLANG_NODE_OLD "stop"
wait_status_node $ERLANG_NODE_OLD 3 30 2 && stop_epmd
printe "Moving old mnesia spool files to backup subdirectory $SPOOL_DIR_BACKUP ..."
mv $SPOOL_DIR/*.DAT $SPOOL_DIR_BACKUP
mv $SPOOL_DIR/*.DCD $SPOOL_DIR_BACKUP
mv $SPOOL_DIR/*.LOG $SPOOL_DIR_BACKUP
printe "Starting ejabberd with new node name $ERLANG_NODE ..."
exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -detached
wait_status 0 30 2
exec_other_command "status"
printe "Installing fallback of new mnesia..."
exec_other_command install_fallback "$NEWFILE"
printe "Stopping new ejabberd..."
exec_other_command "stop"
wait_status 3 30 2 && stop_epmd
printe "Finished, now you can start ejabberd normally"
}
# main
case $1 in
start)
check_start
exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -detached
;;
foreground)
check_start
post_waiter_fork
exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -noinput
;;
foreground-quiet)
check_start
exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -noinput -ejabberd quiet true
;;
live)
livewarning
check_start
exec_erl "$ERLANG_NODE" $EJABBERD_OPTS
;;
debug)
debugwarning
set_dist_client
exec_erl "$(uid debug)" -hidden -remsh "$ERLANG_NODE"
;;
etop)
set_dist_client
exec_erl "$(uid top)" -hidden -remsh "$ERLANG_NODE" \
-eval 'net_kernel:connect_node('"'$ERLANG_NODE'"')' \
-s etop \
-output text
check_etop_result
;;
iexdebug)
debugwarning
set_dist_client
exec_iex "$(uid debug)" --remsh "$ERLANG_NODE"
check_iex_result
;;
iexlive)
livewarning
exec_iex "$ERLANG_NODE" --erl "$EJABBERD_OPTS"
check_iex_result
;;
ping)
PEER=${2:-$ERLANG_NODE}
[ "$PEER" = "${PEER%.*}" ] && PS="-s"
set_dist_client
exec_cmd "$ERL" ${PS:--}name "$(uid ping "$(hostname $PS)")" $ERLANG_OPTS \
-noinput -hidden \
-eval 'net_kernel:connect_node('"'$PEER'"')' \
-eval 'io:format("~p~n",[net_adm:ping('"'$PEER'"')])' \
-eval 'halt(case net_adm:ping('"'$PEER'"') of pong -> 0; pang -> 1 end).' \
-output text
;;
started)
set_dist_client
wait_status 0 30 2 # wait 30x2s before timeout
;;
stopped)
set_dist_client
wait_status 3 30 2 && stop_epmd # wait 30x2s before timeout
;;
mnesia_change)
mnesia_change $2
;;
post_waiter)
post_waiter_waiting
;;
*)
set_dist_client
exec_other_command "$@"
;;
esac
-38
View File
@@ -1,38 +0,0 @@
# Configuration for Lock Threads - https://github.com/dessant/lock-threads
# Number of days of inactivity before a closed issue or pull request is locked
daysUntilLock: 365
# Skip issues and pull requests created before a given timestamp. Timestamp must
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
skipCreatedBefore: false
# Issues and pull requests with these labels will be ignored. Set to `[]` to disable
exemptLabels: []
# Label to add before locking, such as `outdated`. Set to `false` to disable
lockLabel: false
# Comment to post before locking. Set to `false` to disable
lockComment: >
This thread has been automatically locked since there has not been
any recent activity after it was closed. Please open a new issue for
related bugs.
# Assign `resolved` as the reason for locking. Set to `false` to disable
setLockReason: true
# Limit to only `issues` or `pulls`
# only: issues
# Optionally, specify configuration settings just for `issues` or `pulls`
# issues:
# exemptLabels:
# - help-wanted
# lockLabel: outdated
# pulls:
# daysUntilLock: 30
# Repository to extend settings from
# _extends: repo
-417
View File
@@ -1,417 +0,0 @@
name: CI
on:
push:
paths-ignore:
- '.devcontainer/**'
- 'lib/**'
- 'man/**'
- 'priv/**'
- '**.md'
pull_request:
paths-ignore:
- '.devcontainer/**'
- 'lib/**'
- 'man/**'
- 'priv/**'
- '**.md'
env:
DEV: _build/dev/rel/ejabberd
jobs:
############################################################### Compile #####
compile:
runs-on: ubuntu-24.04-arm
strategy:
matrix:
otp: ['28']
steps:
- uses: actions/checkout@v6
- uses: erlef/setup-beam@v1
with:
otp-version: ${{ matrix.otp }}
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libexpat1-dev libgd-dev libpam0g-dev
libsqlite3-dev libwebp-dev libyaml-dev
- name: Cache rebar3
uses: actions/cache@v5
with:
path: |
~/.cache/rebar3/
_build/default/lib/
key: ci-${{ matrix.otp }}-${{hashFiles('rebar.*')}}
- name: Compile
uses: ./.github/actions/manage-ejabberd
with:
for: prod
do: compile
tool: rebar3
configure: --disable-elixir
- name: Compress compiled.tar
run: |
tar -cvf /tmp/compiled.tar .
- uses: actions/upload-artifact@v6
with:
name: compiled-${{ matrix.otp }}
path: /tmp/compiled.tar
retention-days: 1
########################################################## Static Tests #####
static:
needs: compile
runs-on: ubuntu-24.04-arm
strategy:
matrix:
otp: ['28']
steps:
- uses: erlef/setup-beam@v1
with:
otp-version: ${{ matrix.otp }}
- uses: actions/download-artifact@v7
with:
name: compiled-${{ matrix.otp }}
- run: tar -xf compiled.tar
- name: Test shell scripts
run: |
shellcheck ejabberd.init.template
shellcheck -x ejabberdctl.template
shellcheck .vscode/relive.sh
shellcheck rel/setup-dev.sh
shellcheck rel/setup-relive.sh
shellcheck test/ejabberd_SUITE_data/gencerts.sh
shellcheck tools/captcha.sh
shellcheck tools/emacs-indent.sh
shellcheck tools/generate-doap.sh
shellcheck tools/prepare-tr.sh
shellcheck tools/rebar3-format.sh
- run: make hooks
- run: make options
- run: make xref
- run: make dialyzer
- run: make testeunit
- run: make elvis
if: matrix.otp > '25'
- run: make install -s
######################################################### Dynamic Tests #####
dynamic:
needs: compile
runs-on: ubuntu-24.04-arm
strategy:
matrix:
otp: ['28']
steps:
- uses: erlef/setup-beam@v1
with:
otp-version: ${{ matrix.otp }}
- uses: awalsh128/cache-apt-pkgs-action@latest
if: matrix.otp < '28'
with:
packages: libexpat1-dev libgd-dev libpam0g-dev
libsqlite3-dev libwebp-dev libyaml-dev
- uses: actions/download-artifact@v7
with:
name: compiled-${{ matrix.otp }}
- run: tar -xf compiled.tar
- name: Check production release
uses: ./.github/actions/manage-ejabberd
with:
for: prod
do: deploy, start, stop, check
- name: Start development release
uses: ./.github/actions/manage-ejabberd
with:
for: dev
do: deploy, no_tls, start, register
username: user123
- name: Run XMPP Interoperability Tests against CI server
if: matrix.otp == '28'
continue-on-error: true
uses: XMPP-Interop-Testing/xmpp-interop-tests-action@v1.7.2
with:
domain: 'localhost'
adminAccountUsername: 'user123'
adminAccountPassword: 's0mePass'
disabledSpecifications: RFC6121,XEP-0030,XEP-0045,XEP-0054,XEP-0060,
XEP-0080,XEP-0115,XEP-0118,XEP-0215,XEP-0347,
XEP-0363,XEP-0384,XEP-0421
- name: Stop development release
if: always()
uses: ./.github/actions/manage-ejabberd
with:
for: dev
do: stop, check
- name: View production logs
if: always()
uses: ./.github/actions/manage-ejabberd
with:
for: prod
do: logs
- name: View development logs
if: always()
uses: ./.github/actions/manage-ejabberd
with:
for: dev
do: logs
##################################################### Common Test Suite #####
ct:
needs: compile
runs-on: ubuntu-24.04-arm
strategy:
matrix:
otp: ['28']
backend: [agnostic, extauth, ldap, mnesia, mysql, pgsql, redis, sqlite]
schema: [single, multi]
exclude:
- backend: agnostic
schema: single
- backend: extauth
schema: single
- backend: ldap
schema: single
- backend: mnesia
schema: single
- backend: redis
schema: single
steps:
- uses: erlef/setup-beam@v1
with:
otp-version: ${{ matrix.otp }}
- uses: actions/download-artifact@v7
with:
name: compiled-${{ matrix.otp }}
- run: tar -xf compiled.tar
- name: Prepare database
uses: ./.github/actions/manage-database
with:
for: ${{ matrix.backend }}
do: install, start, user, create
- name: Setup multihost SQL schema
if: matrix.schema == 'multi'
run: |
sed -i 's|multihost_schema, false|multihost_schema, true|g' \
test/suite.erl
- name: Run tests
id: ct
run: CT_BACKENDS=${{ matrix.backend }} make test
- name: Send to coveralls
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
DIAGNOSTIC=1 ./rebar3 as test coveralls send
- name: Check results
if: always() && (steps.ct.outcome != 'skipped')
id: ctresults
run: |
[[ -d _build ]] && ln -s _build/test/logs/last/ logs || true
ln `find logs/ -name suite.log` logs/suite.log
grep 'TEST COMPLETE' logs/suite.log
grep -q 'TEST COMPLETE,.* 0 failed' logs/suite.log
test $(find logs/ -empty -name error.log)
- name: View logs
if: always()
run: |
echo "::group::ejabberd.log"
find logs/ -name ejabberd.log -exec cat '{}' ';'
echo "::endgroup::"
echo "::group::error.log"
find logs/ -name error.log -exec cat '{}' ';'
echo "::endgroup::"
echo "::group::exunit.log"
find logs/ -name exunit.log -exec cat '{}' ';'
echo "::endgroup::"
echo "::group::suite.log (only failures)"
cat logs/suite.log | awk \
'BEGIN{RS="\n=case";FS="\n"} /=result\s*failed/ {print "=case" $0}'
echo "::endgroup::"
echo "::group::suite.log (complete)"
cat logs/suite.log
echo "::endgroup::"
- name: Upload CT logs
if: failure()
uses: actions/upload-artifact@v6
with:
name: ct-logs-${{ matrix.otp }}-${{ matrix.backend }}-${{ matrix.schema }}
path: _build/test/logs
retention-days: 14
############################################################# Coveralls #####
cover:
needs: ct
runs-on: ubuntu-24.04-arm
steps:
- name: Finish parallel upload to coveralls
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
curl -v -k https://coveralls.io/webhook \
--header "Content-Type: application/json" \
--data '{"repo_name":"$GITHUB_REPOSITORY",
"repo_token":"$GITHUB_TOKEN",
"payload":{"build_num":$GITHUB_RUN_ID,
"status":"done"}}'
################################################################ Schema #####
schema:
needs: compile
runs-on: ubuntu-24.04-arm
strategy:
matrix:
otp: ['28']
steps:
- uses: erlef/setup-beam@v1
with:
otp-version: ${{ matrix.otp }}
- uses: actions/download-artifact@v7
with:
name: compiled-${{ matrix.otp }}
- run: tar -xf compiled.tar
###################################### multi-changed ##
- name: Prepare databases
uses: ./.github/actions/manage-database
with:
for: mysql, pgsql
do: install, start, user, create
- name: Prepare configuration
run: |
CT_BACKENDS=mysql,pgsql ./rebar3 ct \
--suite=test/ejabberd_SUITE --group=configtest_single
make dev
cp test/ejabberd_SUITE_data/ejabberd.yml ${{ env.DEV }}/conf/
cp _build/test/logs/last/*.yml ${{ env.DEV }}/database/
echo "define_macro: [CONFIGTEST_CONFIG: {modules: {mod_muc: {}}}]" \
> ${{ env.DEV }}/database/configtest.yml
cp _build/test/logs/last/*.pem ${{ env.DEV }}/conf/
cp _build/test/logs/last/*.pem ${{ env.DEV }}/database/
- name: Run ejabberd
uses: ./.github/actions/manage-ejabberd
with:
for: dev
do: start, update_sql, stop, check, logs
username: user2
- name: Dump multihost databases
uses: ./.github/actions/manage-database
with:
for: mysql, pgsql
do: dump
dump-suffix: multi-changed
######################################### multi-auto ##
- name: Prepare databases
uses: ./.github/actions/manage-database
with:
for: mysql, pgsql
do: drop, create
- name: Configure multihost schema
run: |
sed -i 's|MULTIHOST_SCHEMA|true|g' ${{ env.DEV }}/conf/ejabberd.yml
- name: Run ejabberd for multihost
uses: ./.github/actions/manage-ejabberd
with:
for: dev
do: start, stop, check, logs
username: user2
- name: Dump multihost databases
uses: ./.github/actions/manage-database
with:
for: mysql, pgsql
do: dump
dump-suffix: multi-auto
############################################ compare ##
- name: View SQL schemas (mysql)
run: |
perl test/ejabberd_SUITE_data/sql_sort.pl \
<mysql-multi-auto.sql >mysql-multi2.sql
perl test/ejabberd_SUITE_data/sql_sort.pl \
<mysql-multi-changed.sql >mysql-changed2.sql
echo "::group::differences multi-auto > multi-changed"
diff -u mysql-multi2.sql mysql-changed2.sql || echo ok
echo "::endgroup::"
echo "::group::multi-auto.sql"
cat mysql-multi-auto.sql
echo "::endgroup::"
echo "::group::multi-changed.sql"
cat mysql-multi-changed.sql
echo "::endgroup::"
- name: View SQL schemas (pgsql)
run: |
perl test/ejabberd_SUITE_data/sql_sort.pl \
<pgsql-multi-auto.sql >pgsql-multi2.sql
perl test/ejabberd_SUITE_data/sql_sort.pl \
<pgsql-multi-changed.sql >pgsql-changed2.sql
echo "::group::differences (multi-auto > multi-changed)"
diff -u pgsql-multi2.sql pgsql-changed2.sql || echo ok
echo "::endgroup::"
echo "::group::multi-auto.sql"
cat pgsql-multi-auto.sql
echo "::endgroup::"
echo "::group::multi-changed.sql"
cat pgsql-multi-changed.sql
echo "::endgroup::"
- name: View ejabberd logs
if: always()
uses: ./.github/actions/manage-ejabberd
with:
for: dev
do: logs
-119
View File
@@ -1,119 +0,0 @@
name: Container
on:
push:
paths-ignore:
- '.devcontainer/**'
- 'lib/**'
- 'man/**'
- 'priv/**'
- '**.md'
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-24.04${{ matrix.suffix }}
strategy:
matrix:
platform: [amd64, arm64]
include:
- platform: amd64
suffix:
- platform: arm64
suffix: -arm
permissions:
packages: write
steps:
- name: Check out repository code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Checkout ejabberd-contrib
uses: actions/checkout@v6
with:
repository: processone/ejabberd-contrib
path: .ejabberd-modules/sources/ejabberd-contrib
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get git describe
id: gitdescribe
run: echo "ver=$(git describe --tags)" >> $GITHUB_OUTPUT
- uses: docker/metadata-action@v5
id: meta
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: suffix=--${{ matrix.platform }}
labels: |
org.opencontainers.image.revision=${{ steps.gitdescribe.outputs.ver }}
org.opencontainers.image.licenses=GPL-2.0
org.opencontainers.image.vendor=ProcessOne
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
build-args: |
VERSION=${{ steps.gitdescribe.outputs.ver }}
cache-from: type=gha
cache-to: type=gha,mode=max
context: .
file: .github/container/Dockerfile
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/${{ matrix.platform }}
push: true
tags: ${{ steps.meta.outputs.tags }}
merge:
needs: [build]
runs-on: ubuntu-24.04
outputs:
image-uri: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.merge.outputs.digest }}
steps:
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v5
id: meta-amd
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: suffix=--amd64
- uses: docker/metadata-action@v5
id: meta-arm
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: suffix=--arm64
- uses: docker/metadata-action@v5
id: meta-result
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- uses: int128/docker-manifest-create-action@v2
id: merge
with:
index-annotations: ${{ steps.metadata.outputs.labels }}
tags: ${{ steps.meta-result.outputs.tags }}
sources: |
${{ steps.meta-amd.outputs.tags }}
${{ steps.meta-arm.outputs.tags }}
#- uses: dataaxiom/ghcr-cleanup-action@v1
# with:
# dry-run: true
# delete-tags: '*--a??64'
# delete-untagged: true
# delete-ghost-images: true
# delete-partial-images: true
# delete-orphaned-images: true
-109
View File
@@ -1,109 +0,0 @@
name: Installers
on:
push:
paths-ignore:
- '.devcontainer/**'
- 'lib/**'
- 'man/**'
- 'priv/**'
- '**.md'
pull_request:
paths-ignore:
- '.devcontainer/**'
- 'lib/**'
- 'man/**'
- 'priv/**'
- '**.md'
jobs:
binaries:
runs-on: ubuntu-22.04${{ matrix.suffix }}
strategy:
matrix:
platform: [amd64, arm64]
include:
- platform: amd64
suffix:
- platform: arm64
suffix: -arm
steps:
- name: Check out repository code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cache build directory
uses: actions/cache@v5
with:
path: ~/build/
key: installers-ubuntu-22.04-${{runner.arch}}-${{hashFiles('tools/make-binaries')}}
- name: Install prerequisites
run: |
sudo apt-get -qq update
sudo apt-get -qq install makeself
# https://github.com/crosstool-ng/crosstool-ng/blob/master/testing/docker/ubuntu21.10/Dockerfile
sudo apt-get -qq install build-essential autoconf bison flex gawk
sudo apt-get -qq install help2man libncurses5-dev libtool libtool-bin
sudo apt-get -qq install python3-dev texinfo unzip
- name: Install FPM
run: |
gem install --no-document --user-install fpm
echo $HOME/.local/share/gem/ruby/*/bin >> $GITHUB_PATH
- name: Build binary archives
run: CHECK_DEPS=false tools/make-binaries
- name: Build DEB and RPM packages
run: tools/make-packages
- name: Build installers
run: tools/make-installers
- run: echo "rel_name_vsn=$(ls *.run | sed 's/-1-linux.*//g')" >> $GITHUB_OUTPUT
id: vsn
- name: Test RUN
uses: ./.github/actions/manage-ejabberd
with:
for: run
do: deploy, no_acme, start, register, stop, check, logs
username: user1
host: $(hostname --fqdn)
rel_name_vsn: ${{ steps.vsn.outputs.rel_name_vsn }}
- name: Test DEB
uses: ./.github/actions/manage-ejabberd
with:
for: deb
do: deploy, register, stop, logs
username: user1
host: $(hostname --fqdn)
rel_name_vsn: ${{ steps.vsn.outputs.rel_name_vsn }}
- name: Collect packages
run: |
mkdir ejabberd-packages
mv ejabberd_*.deb ejabberd-*.rpm ejabberd-*.run ejabberd-packages
- name: Upload packages
uses: actions/upload-artifact@v6
with:
name: ejabberd-packages-${{ matrix.platform }}
#
# Appending the wildcard character ("*") is a trick to make
# "ejabberd-packages" the root directory of the uploaded ZIP file:
#
# https://github.com/actions/upload-artifact#upload-using-multiple-paths-and-exclusions
#
path: ejabberd-packages*
retention-days: 14
release:
name: Release
needs: [binaries]
runs-on: ubuntu-22.04
if: github.ref_type == 'tag'
steps:
- name: Download packages
uses: actions/download-artifact@v7
with:
merge-multiple: true
- name: Draft Release
uses: softprops/action-gh-release@v2
with:
draft: true
files: ejabberd-packages/*
-270
View File
@@ -1,270 +0,0 @@
name: Runtime
on:
push:
paths:
- '*'
- '!*.md'
- '.github/workflows/runtime.yml'
- 'checkouts/**'
- 'config/**'
- 'lib/**'
- 'm4/**'
- 'plugins/**'
- 'rel/**'
pull_request:
paths:
- '*'
- '!*.md'
- '.github/workflows/runtime.yml'
- 'checkouts/**'
- 'config/**'
- 'lib/**'
- 'm4/**'
- 'plugins/**'
- 'rel/**'
jobs:
################################################################ Rebars #####
rebars:
runs-on: ubuntu-24.04-arm
strategy:
matrix:
otp: ['25', '26', '27', '28', '29']
rebar: ['rebar', 'rebar3']
exclude:
- otp: '27'
rebar: 'rebar'
- otp: '28'
rebar: 'rebar'
- otp: '29'
rebar: 'rebar'
container:
image: public.ecr.aws/docker/library/erlang:${{ matrix.otp }}
steps:
- uses: actions/checkout@v6
- name: Prepare libraries
run: |
apt-get -qq update
apt-get -q -y install libexpat1-dev libgd-dev libpam0g-dev \
libsqlite3-dev libwebp-dev libyaml-dev
- name: Cache rebar3
if: matrix.rebar == 'rebar3'
uses: actions/cache@v5
with:
path: |
~/.cache/rebar3/
_build/default/lib/
key: runtime-${{ matrix.otp }}-${{matrix.rebar}}-${{hashFiles('rebar.*')}}
- name: Compile
uses: ./.github/actions/manage-ejabberd
with:
for: prod
do: compile
tool: ${{ matrix.rebar }}
configure: --disable-elixir
- run: make hooks
- run: make options
- run: make xref
- run: make dialyzer
- run: make elvis
if: matrix.otp > '25' && matrix.rebar == 'rebar3'
- name: Production
uses: ./.github/actions/manage-ejabberd
with:
for: prod
do: deploy, start, register, stop, check, logs
tool: ${{ matrix.rebar }}
username: user1
- name: Development
uses: ./.github/actions/manage-ejabberd
with:
for: dev
do: deploy, start, register, stop, check, logs
tool: ${{ matrix.rebar }}
username: user2
- name: Installed
uses: ./.github/actions/manage-ejabberd
with:
for: install
do: deploy, start, register, stop, check, logs
tool: ${{ matrix.rebar }}
username: user3
####################################################### Rebar3 + Elixir #####
rebar3-elixir:
runs-on: ubuntu-24.04-arm
strategy:
matrix:
elixir: ['1.14', '1.18', '1.19']
container:
image: public.ecr.aws/docker/library/elixir:${{ matrix.elixir }}
steps:
- uses: actions/checkout@v6
- name: Prepare libraries
run: |
apt-get -qq update
apt-get -q -y install libexpat1-dev libgd-dev libpam0g-dev \
libsqlite3-dev libwebp-dev libyaml-dev
- name: Enable Module.Example and an Elixir dependency
run: |
sed -i "s|^modules:|modules:\n 'Ejabberd.Module.Example': {}|g" \
ejabberd.yml.example
cat ejabberd.yml.example
sed -i 's|^{deps, \[\(.*\)|{deps, [{decimal, ".*", {git, "https://github.com/ericmj/decimal", {branch, "main"}}},\n \1|g' rebar.config
cat rebar.config
- name: Cache hex.pm
uses: actions/cache@v5
with:
path: |
~/.cache/rebar3/
key: runtime-${{matrix.elixir}}-${{hashFiles('rebar.*')}}
- name: Install Hex and Rebar3 manually on older Elixir
if: matrix.elixir < '1.15'
run: |
mix local.hex --force
mix local.rebar --force
- name: Compile
uses: ./.github/actions/manage-ejabberd
with:
for: prod
do: compile
tool: ./rebar3
- name: Test scripts, deps, eunit
run: |
make scripts deps
./rebar3 eunit --verbose
- run: make hooks
- run: make options
- run: make xref
#- run: make dialyzer
- run: make elvis
if: matrix.otp > '25'
- name: Production
uses: ./.github/actions/manage-ejabberd
with:
for: prod
do: deploy, start, register, stop, check, logs
username: user1
- name: Release
uses: ./.github/actions/manage-ejabberd
with:
for: dev
do: deploy, start, register, stop, check, logs
username: user2
- name: Installed
uses: ./.github/actions/manage-ejabberd
with:
for: install
do: deploy, start, register, stop, check, logs
username: user3
################################################################### Mix #####
mix:
runs-on: ubuntu-24.04-arm
strategy:
matrix:
elixir: ['1.14', '1.18', '1.19']
container:
image: public.ecr.aws/docker/library/elixir:${{ matrix.elixir }}
steps:
- uses: actions/checkout@v6
- name: Prepare libraries
run: |
apt-get -qq update
apt-get -q -y install libexpat1-dev libgd-dev libpam0g-dev \
libsqlite3-dev libwebp-dev libyaml-dev
- name: Remove Elixir matchers
run: |
echo "::remove-matcher owner=elixir-mixCompileWarning::"
echo "::remove-matcher owner=elixir-credoOutputDefault::"
echo "::remove-matcher owner=elixir-mixCompileError::"
echo "::remove-matcher owner=elixir-mixTestFailure::"
echo "::remove-matcher owner=elixir-dialyzerOutputDefault::"
- name: Enable Module.Example and an Elixir dependency
run: |
sed -i "s|^modules:|modules:\n 'Ejabberd.Module.Example': {}|g" \
ejabberd.yml.example
cat ejabberd.yml.example
sed -i 's|^{deps, \(.*\)|{deps, \1\n {decimal, ".*", {git, "https://github.com/ericmj/decimal", {branch, "main"}}}, |g' rebar.config
cat rebar.config
- name: Cache hex.pm
uses: actions/cache@v5
with:
path: |
~/.hex/
key: runtime-${{matrix.elixir}}-${{hashFiles('mix.*')}}
- name: Install Hex and Rebar3 manually on older Elixir
if: matrix.elixir < '1.15'
run: |
mix local.hex --force
mix local.rebar --force
- name: Compile
uses: ./.github/actions/manage-ejabberd
with:
for: prod
do: compile
tool: mix
- run: make hooks
- run: make options
- run: make xref
- run: make dialyzer
- run: make elvis
if: matrix.otp > '25'
- run: make edoc
- name: Production
uses: ./.github/actions/manage-ejabberd
with:
for: prod
do: deploy, start, register, stop, check, logs
username: user1
- name: Development
uses: ./.github/actions/manage-ejabberd
with:
for: dev
do: deploy, start, register, stop, check, logs
username: user2
- name: Installed
uses: ./.github/actions/manage-ejabberd
with:
for: install
do: deploy, start, register, stop, check, logs
username: user3
-177
View File
@@ -1,177 +0,0 @@
name: Weekly
on:
schedule:
- cron: '30 9 * * 0'
jobs:
############################################################### Compile #####
test:
runs-on: ubuntu-24.04-arm
strategy:
matrix:
otp: ['25', '26', '27', '28', '29.0-rc1']
steps:
- uses: actions/checkout@v6
- uses: erlef/setup-beam@v1
with:
otp-version: ${{ matrix.otp }}
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libexpat1-dev libgd-dev libpam0g-dev
libsqlite3-dev libwebp-dev libyaml-dev
- name: Compile
uses: ./.github/actions/manage-ejabberd
with:
for: prod
do: compile
tool: rebar3
configure: --disable-elixir --disable-mssql
########################################################## Static Tests #####
- name: Test shell scripts
run: |
shellcheck ejabberd.init.template
shellcheck -x ejabberdctl.template
shellcheck .vscode/relive.sh
shellcheck rel/setup-dev.sh
shellcheck rel/setup-relive.sh
shellcheck test/ejabberd_SUITE_data/gencerts.sh
shellcheck tools/captcha.sh
shellcheck tools/emacs-indent.sh
shellcheck tools/generate-doap.sh
shellcheck tools/prepare-tr.sh
shellcheck tools/rebar3-format.sh
- run: make hooks
- run: make options
- run: make xref
- run: make dialyzer
- run: make testeunit
- run: make elvis
if: matrix.otp > '25'
- run: make install -s
######################################################### Dynamic Tests #####
- name: Check production release
uses: ./.github/actions/manage-ejabberd
with:
for: prod
do: deploy, start, stop, check
- name: Start development release
uses: ./.github/actions/manage-ejabberd
with:
for: dev
do: deploy, no_tls, start, register
username: user123
- name: Stop development release
if: always()
uses: ./.github/actions/manage-ejabberd
with:
for: dev
do: stop, check
- name: View production logs
if: always()
uses: ./.github/actions/manage-ejabberd
with:
for: prod
do: logs
- name: View development logs
if: always()
uses: ./.github/actions/manage-ejabberd
with:
for: dev
do: logs
##################################################### Common Test Suite #####
- name: Prepare database
uses: ./.github/actions/manage-database
with:
for: mysql, pgsql, redis
do: install, start, user, create
- name: Setup multihost SQL schema
run: |
sed -i 's|new_schema, false|new_schema, true|g' test/suite.erl
- name: Run tests
id: ct
run: make test
- name: Send to coveralls
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
DIAGNOSTIC=1 ./rebar3 as test coveralls send
- name: Check results
if: always() && (steps.ct.outcome != 'skipped')
id: ctresults
run: |
[[ -d _build ]] && ln -s _build/test/logs/last/ logs || true
ln `find logs/ -name suite.log` logs/suite.log
grep 'TEST COMPLETE' logs/suite.log
grep -q 'TEST COMPLETE,.* 0 failed' logs/suite.log
test $(find logs/ -empty -name error.log)
- name: View logs
if: always()
run: |
echo "::group::ejabberd.log"
find logs/ -name ejabberd.log -exec cat '{}' ';'
echo "::endgroup::"
echo "::group::error.log"
find logs/ -name error.log -exec cat '{}' ';'
echo "::endgroup::"
echo "::group::exunit.log"
find logs/ -name exunit.log -exec cat '{}' ';'
echo "::endgroup::"
echo "::group::suite.log (only failures)"
cat logs/suite.log | awk \
'BEGIN{RS="\n=case";FS="\n"} /=result\s*failed/ {print "=case" $0}'
echo "::endgroup::"
echo "::group::suite.log (complete)"
cat logs/suite.log
echo "::endgroup::"
- name: Upload CT logs
if: failure()
uses: actions/upload-artifact@v6
with:
name: ct-logs-${{ matrix.otp }}
path: _build/test/logs
retention-days: 14
############################################################# Coveralls #####
cover:
needs: test
if: always()
runs-on: ubuntu-24.04-arm
steps:
- name: Finish parallel upload to coveralls
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
curl -v -k https://coveralls.io/webhook \
--header "Content-Type: application/json" \
--data '{"repo_name":"$GITHUB_REPOSITORY",
"repo_token":"$GITHUB_TOKEN",
"payload":{"build_num":$GITHUB_RUN_ID,
"status":"done"}}'
-52
View File
@@ -1,52 +0,0 @@
#
# You can add personal rules in your file .git/info/exclude
*.swp
*~
\#*#
.#*
.edts
.tool-versions
*.dump
/Makefile
/doc
/config.log
/config.status
/config/releases.exs
/configure
/aclocal.m4
/*.cache
/deps/
/.deps-update/
/.ejabberd-modules/
/ebin/
/ejabberd.init
/ejabberd.service
/ejabberdctl
/ejabberdctl.example
/rel/ejabberd/
/rel/overlays/
/src/eldap_filter_yecc.erl
/vars.config
/dialyzer/
/test/*.beam
/test/*.ctc
/logs/
/priv/bin/captcha*sh
/priv/sql
/rel/ejabberd
/recompile.log
/_build
/database/
/.rebar
/log/
Mnesia.nonode@nohost/
/TAGS
/tags
# Binaries created with tools/make-{binaries,installers,packages}:
/ejabberd_*.deb
/ejabberd-*.rpm
/ejabberd-*.run
/ejabberd-*.tar.gz
/priv/mod_invites/static/bootstrap/
/priv/mod_invites/static/jquery/
/node_modules/
-4
View File
@@ -1,4 +0,0 @@
disable=SC2016,SC2086,SC2089,SC2090
external-sources=true
source=ejabberdctl.cfg.example
shell=sh
-5
View File
@@ -1,5 +0,0 @@
{
"recommendations": [
"erlang-ls.erlang-ls"
]
}
-66
View File
@@ -1,66 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Relive (Vim)",
"type": "erlang",
"request": "launch",
"runinterminal": [
"./rebar3", "shell",
"--apps", "ejabberd",
"--config", "rel/relive.config",
"--script", "rel/relive.escript",
"--name", "ejabberd@localhost",
"--setcookie", "COOKIE"
],
"projectnode": "ejabberd@localhost",
"cookie": "COOKIE",
"timeout": 900,
"cwd": "."
},
{
"name": "Relive (VSCode)",
"type": "erlang",
"request": "launch",
"runinterminal": [
".vscode/relive.sh"
],
"projectnode": "ejabberd@localhost",
"cookie": "COOKIE",
"timeout": 300,
"cwd": "${workspaceRoot}"
},
{
"name": "Relive (alternate)",
"type": "erlang",
"request": "launch",
"runinterminal": [
"./rebar3", "shell",
"--apps", "ejabberd",
"--config", "rel/relive.config",
"--script", "rel/relive.escript",
"--name", "ejabberd@localhost",
"--setcookie", "COOKIE"
],
"projectnode": "ejabberd@localhost",
"cookie": "COOKIE",
"timeout": 300,
"cwd": "${workspaceRoot}"
},
{
"name": "Attach",
"type": "erlang",
"request": "attach",
"runinterminal": [
"./rebar3", "shell",
"--sname", "clean@localhost",
"--setcookie", "COOKIE",
"--start-clean"
],
"projectnode": "ejabberd@localhost",
"cookie": "COOKIE",
"timeout": 300,
"cwd": "${workspaceRoot}"
}
]
}
-6
View File
@@ -1,6 +0,0 @@
[ ! -f Makefile ] \
&& ./autogen.sh \
&& ./configure --with-rebar=rebar3 \
&& make
make relive
-13
View File
@@ -1,13 +0,0 @@
{
"editor.tabSize": 8,
"remote.portsAttributes": {
"1883": {"label": "MQTT", "onAutoForward": "silent"},
"4369": {"label": "EPMD", "onAutoForward": "silent"},
"5222": {"label": "XMPP C2S", "onAutoForward": "silent"},
"5223": {"label": "XMPP C2S (legacy)", "onAutoForward": "silent"},
"5269": {"label": "XMPP S2S", "onAutoForward": "silent"},
"5280": {"label": "HTTP", "onAutoForward": "silent"},
"5443": {"label": "HTTPS", "onAutoForward": "silent"},
"7777": {"label": "XMPP SOCKS5 (proxy65)", "onAutoForward": "silent"}
}
}
-1926
View File
File diff suppressed because it is too large Load Diff
-61
View File
@@ -1,61 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Guidelines for Respectful and Efficient Communication on Issues, Discussions, and PRs
To ensure that our maintainers can efficiently manage issues and provide timely updates, we kindly ask that all comments on GitHub tickets remain relevant to the topic of the issue. Please avoid posting comments solely to ping maintainers or ask for updates. If you need information on the status of an issue, consider the following:
- **Check the Issue Timeline:** Review the existing comments and updates on the issue before posting.
- **Use Reactions:** If you want to show that you are interested in an issue, use GitHub's reaction feature (e.g., thumbs up) instead of commenting.
- **Be Patient:** Understand that maintainers may be working on multiple tasks and will provide updates as soon as possible.
Additionally, please be aware that:
- **User Responses:** Users who report issues may no longer be using the software, may have switched to other projects, or may simply be busy. It is their right not to respond to follow-up questions or comments.
- **Maintainer Priorities:** Maintainers have the right to define their own priorities and schedule. They will address issues based on their availability and the project's needs.
By following these guidelines, you help us maintain a productive and respectful environment for everyone involved.
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at the email address: conduct AT process-one.net. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [https://contributor-covenant.org/version/1/4][version]
[homepage]: https://www.contributor-covenant.org/
[version]: https://www.contributor-covenant.org/version/1/4/
-126
View File
@@ -1,126 +0,0 @@
Compile and Install ejabberd
============================
This document explains how to compile and install ejabberd
from source code.
For a more detailed explanation, please check the
ejabberd Docs: [Source Code Installation][docs-source].
[docs-source]: https://docs.ejabberd.im/admin/install/source/
Requirements
------------
To compile ejabberd you need:
- GNU Make
- GCC
- Libexpat ≥ 1.95
- Libyaml ≥ 0.1.4
- Erlang/OTP ≥ 25.0
- OpenSSL ≥ 1.0.0
Other optional libraries are:
- Zlib ≥ 1.2.3, for Stream Compression support (XEP-0138)
- PAM library, for Pluggable Authentication Modules (PAM)
- ImageMagick's Convert program and Ghostscript fonts, for CAPTCHA
challenges
- Elixir ≥ 1.14.0, for Elixir support
If your system splits packages in libraries and development headers,
install the development packages too.
Download Source Code
--------------------
There are several ways to obtain the ejabberd source code:
- Source code archive from [ProcessOne Downloads][p1dl]
- Source code package from [ejabberd GitHub Releases][ghr]
- Latest development code from [ejabberd Git repository][gitrepo]
[p1dl]: https://www.process-one.net/download/ejabberd/
[ghr]: https://github.com/processone/ejabberd/releases
[gitrepo]: https://github.com/processone/ejabberd
Compile
-------
The general instructions to compile ejabberd are:
./configure
make
If the source code doesn't contain a `configure` script,
first of all install `autoconf` and run this to generate it:
./autogen.sh
To configure the compilation, features, install paths...
./configure --help
The build tool automatically downloads and compiles the
erlang libraries that [ejabberd depends on][docs-repo].
[docs-repo]: https://docs.ejabberd.im/developer/repositories/
Install in the System
---------------------
To install ejabberd in the system, run this with system administrator rights (root user):
sudo make install
This will:
- Install the configuration files in `/etc/ejabberd/`
- Install ejabberd binary, header and runtime files in `/lib/ejabberd/`
- Install the administration script: `/sbin/ejabberdctl`
- Install ejabberd documentation in `/share/doc/ejabberd/`
- Create a spool directory: `/var/lib/ejabberd/`
- Create a directory for log files: `/var/log/ejabberd/`
Build an OTP Release
--------------------
Instead of installing ejabberd in the system, you can build an OTP release
that includes all necessary to run ejabberd in a subdirectory:
./configure
make prod
Check the full list of targets:
make help
Start ejabberd
--------------
You can use the `ejabberdctl` command line administration script to
start and stop ejabberd. Some examples, depending on your installation method:
- When installed in the system:
```
ejabberdctl start
/sbin/ejabberdctl start
```
- When built an OTP production release:
```
_build/prod/rel/ejabberd/bin/ejabberdctl start
_build/prod/rel/ejabberd/bin/ejabberdctl live
```
- Start interactively without installing or building OTP release:
```
make relive
```
-1136
View File
File diff suppressed because it is too large Load Diff
-149
View File
@@ -1,149 +0,0 @@
# Contributing to ejabberd
We'd love for you to contribute to our source code and to make ejabberd even better than it is
today! Here are the guidelines we'd like you to follow:
* [Code of Conduct](#code-of-conduct)
* [Questions and Problems](#questions-bugs-features)
* [Issues and Bugs](#found-an-issue-or-bug)
* [Feature Requests](#missing-a-feature)
* [Issue Submission Guidelines](#issue-submission-guidelines)
* [Pull Request Submission Guidelines](#pull-request-submission-guidelines)
* [Signing the CLA](#signing-the-contributor-license-agreement-cla)
## Code of Conduct
Help us keep ejabberd community open-minded and inclusive. Please read and follow our [Code of Conduct][coc].
## Questions, Bugs, Features
### Got a Question or Problem?
Do not open issues for general support questions as we want to keep GitHub issues for bug reports
and feature requests. You've got much better chances of getting your question answered on dedicated
support platforms, the best being [Stack Overflow][stackoverflow].
Stack Overflow is a much better place to ask questions since:
* there are thousands of people willing to help on Stack Overflow
* questions and answers stay available for public viewing so your question / answer might help
someone else
* Stack Overflow's voting system assures that the best answers are prominently visible.
To save your and our time, we will systematically close all issues that are requests for general
support and redirect people to the section you are reading right now.
Other channels for support are:
* ejabberd XMPP room: [ejabberd@conference.process-one.net][muc]
* [ejabberd Mailing List][list]
### Found an Issue or Bug?
If you find a bug in the source code, you can help us by submitting an issue to our
[GitHub Repository][github]. Even better, you can submit a Pull Request with a fix.
### Missing a Feature?
You can request a new feature by submitting an issue to our [GitHub Repository][github-issues].
If you would like to implement a new feature then consider what kind of change it is:
* **Major Changes** that you wish to contribute to the project should be discussed first in an
[GitHub issue][github-issues] that clearly outlines the changes and benefits of the feature.
* **Small Changes** can directly be crafted and submitted to the [GitHub Repository][github]
as a Pull Request. See the section about [Pull Request Submission Guidelines](#pull-request-submission-guidelines).
## Issue Submission Guidelines
Before you submit your issue search the archive, maybe your question was already answered.
If your issue appears to be a bug, and hasn't been reported, open a new issue. Help us to maximize
the effort we can spend fixing issues and adding new features, by not reporting duplicate issues.
The "[new issue][github-new-issue]" form contains a number of prompts that you should fill out to
make it easier to understand and categorize the issue.
## Pull Request Submission Guidelines
By submitting a pull request for a code or doc contribution, you need to have the right
to grant your contribution's copyright license to ProcessOne. Please check [ProcessOne CLA][cla]
for details.
Before you submit your pull request consider the following guidelines:
* Search [GitHub][github-pr] for an open or closed Pull Request
that relates to your submission. You don't want to duplicate effort.
* Create the [development environment][developer-setup]
* Make your changes in a new git branch:
```shell
git checkout -b my-fix-branch master
```
* Test your changes and, if relevant, expand the automated test suite.
* Create your patch commit, including appropriate test cases.
* If the changes affect public APIs, change or add relevant [documentation][doc-repo].
* Commit your changes using a descriptive commit message.
```shell
git commit -a
```
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
* Push your branch to GitHub:
```shell
git push origin my-fix-branch
```
* In GitHub, send a pull request to `ejabberd:master`. This will trigger the automated testing.
We will also notify you if you have not yet signed the [contribution agreement][cla].
* If you find that the tests have failed, look into the logs to find out
if your changes caused test failures, the commit message was malformed etc. If you find that the
tests failed or times out for unrelated reasons, you can ping a team member so that the build can be
restarted.
* If we suggest changes, then:
* Make the required updates.
* Test your changes and test cases.
* Commit your changes to your branch (e.g. `my-fix-branch`).
* Push the changes to your GitHub repository (this will update your Pull Request).
You can also amend the initial commits and force push them to the branch.
```shell
git rebase master -i
git push origin my-fix-branch -f
```
This is generally easier to follow, but separate commits are useful if the Pull Request contains
iterations that might be interesting to see side-by-side.
That's it! Thank you for your contribution!
## Signing the Contributor License Agreement (CLA)
Upon submitting a Pull Request, we will ask you to sign our CLA if you haven't done
so before. It's a quick process, we promise, and you will be able to do it all online
Here's a link to the [ProcessOne Contribution License Agreement][cla].
This is part of the legal framework of the open-source ecosystem that adds some red tape,
but protects both the contributor and the company / foundation behind the project. It also
gives us the option to relicense the code with a more permissive license in the future.
[coc]: https://github.com/processone/ejabberd/blob/master/CODE_OF_CONDUCT.md
[stackoverflow]: https://stackoverflow.com/questions/tagged/ejabberd?sort=newest
[list]: https://web.archive.org/web/20230319174915/http://lists.jabber.ru/mailman/listinfo/ejabberd
[muc]: xmpp:ejabberd@conference.process-one.net
[github]: https://github.com/processone/ejabberd
[github-issues]: https://github.com/processone/ejabberd/issues
[github-new-issue]: https://github.com/processone/ejabberd/issues/new
[github-pr]: https://github.com/processone/ejabberd/pulls
[doc-repo]: https://github.com/processone/docs.ejabberd.im
[developer-setup]: https://docs.ejabberd.im/developer/
[cla]: https://cla.process-one.net/
-38
View File
@@ -1,38 +0,0 @@
# Contributors
We would like to thanks official ejabberd source code contributors:
- Sergey Abramyan
- Badlop
- Ludovic Bocquet
- Emilio Bustos
- Thiago Camargo
- Juan Pablo Carlino
- Paweł Chmielowski
- Gabriel Gatu
- Tsukasa Hamano
- Konstantinos Kallas
- Evgeny Khramtsov
- Ben Langfeld
- Peter Lemenkov
- Anna Mukharram
- Johan Oudinet
- Pablo Polvorin
- Mickaël Rémond
- Matthias Rieber
- Rafael Roemhild
- Christophe Romain
- Jérôme Sautret
- Sonny Scroggin
- Alexey Shchepin
- Shelley Shyan
- Stefan Strigler
- Radoslaw Szymczyszyn
- Stu Tomlinson
- Christian Ulrich
- Holger Weiß
Please, if you think we are missing your contribution, do not hesitate to contact us at ProcessOne.
In case you do not want to appear in this list, please, let us know as well.
Thanks !
+5 -5
View File
@@ -4,8 +4,8 @@ with the OpenSSL library and distribute the resulting binary.
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -306,9 +306,9 @@ the "copyright" line and a pointer to where the full notice is found.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
+1849
View File
File diff suppressed because it is too large Load Diff
-756
View File
@@ -1,756 +0,0 @@
#.
#' definitions
#
# Only required for Erlang/OTP 25
MAYBE=ERL_FLAGS="-enable-feature maybe_expr"
ESCRIPT = @ESCRIPT@
REBAR = $(MAYBE) @rebar@ # rebar|rebar3|mix binary (or path to binary)
REBAR3 = @REBAR3@ # path to rebar3 binary
MIX = @rebar@
AWK = @AWK@
INSTALL = @INSTALL@
MKDIR_P = @MKDIR_P@
SED = @SED@
ERL = @ERL@
EPMD = @EPMD@
IEX = @IEX@
INSTALLUSER=@INSTALLUSER@
INSTALLGROUP=@INSTALLGROUP@
REBAR_ENABLE_ELIXIR = @elixir@
prefix = @prefix@
exec_prefix = @exec_prefix@
DESTDIR =
# /etc/ejabberd/
ETCDIR = @sysconfdir@/ejabberd
# /bin/
BINDIR = @bindir@
# /sbin/
SBINDIR = @sbindir@
# /lib/
LIBDIR = @libdir@
# /lib/ejabberd/
EJABBERDDIR = @libdir@/ejabberd
# /share/doc/ejabberd
PACKAGE_TARNAME = @PACKAGE_TARNAME@
datarootdir = @datarootdir@
DOCDIR = @docdir@
# /share/doc/man/man5
MANDIR = @mandir@/man5
# /usr/lib/ejabberd/ebin/
BEAMDIR = $(EJABBERDDIR)/ebin
# /usr/lib/ejabberd/include/
INCLUDEDIR = $(EJABBERDDIR)/include
# /usr/lib/ejabberd/priv/
PRIVDIR = $(EJABBERDDIR)/priv
# /usr/lib/ejabberd/priv/bin
PBINDIR = $(PRIVDIR)/bin
# /usr/lib/ejabberd/priv/lib
SODIR = $(PRIVDIR)/lib
# /usr/lib/ejabberd/priv/msgs
MSGSDIR = $(PRIVDIR)/msgs
# /usr/lib/ejabberd/priv/css
CSSDIR = $(PRIVDIR)/css
# /usr/lib/ejabberd/priv/img
IMGDIR = $(PRIVDIR)/img
# /usr/lib/ejabberd/priv/js
JSDIR = $(PRIVDIR)/js
# /usr/lib/ejabberd/priv/sql
SQLDIR = $(PRIVDIR)/sql
# /usr/lib/ejabberd/priv/lua
LUADIR = $(PRIVDIR)/lua
# /var/lib/ejabberd/
SPOOLDIR = @localstatedir@/lib/ejabberd
# /var/log/ejabberd/
LOGDIR = @localstatedir@/log/ejabberd
#.
#' install user
#
# if no user was enabled, don't set privileges or ownership
ifeq ($(INSTALLUSER),)
O_USER=
G_USER=
CHOWN_COMMAND=echo
CHOWN_OUTPUT=/dev/null
INIT_USER=root
else
O_USER=-o $(INSTALLUSER)
G_USER=-g $(INSTALLUSER)
CHOWN_COMMAND=chown
CHOWN_OUTPUT=&1
INIT_USER=$(INSTALLUSER)
endif
# if no group was enabled, don't set privileges or ownership
ifneq ($(INSTALLGROUP),)
G_USER=-g $(INSTALLGROUP)
endif
#.
#' rebar / rebar3 / mix
#
ifeq "$(notdir $(MIX))" "mix"
REBAR_VER:=6
REBAR_VER_318:=0
else
REBAR_VER:=$(shell $(REBAR) --version | $(AWK) -F '[ .]' '/rebar / {print $$2}')
REBAR_VER_318:=$(shell $(REBAR) --version | $(AWK) -F '[ .]' '/rebar / {print ($$2 == 3 && $$3 >= 18 ? 1 : 0)}')
endif
ifeq "$(REBAR_VER)" "6"
REBAR=$(MAYBE) $(MIX)
SKIPDEPS=
LISTDEPS=deps.tree
UPDATEDEPS=deps.update
DEPSPATTERN="s/.*─ \([a-z0-9_]*\) .*/\1/p;"
DEPSBASE=_build
DEPSDIR=$(DEPSBASE)/dev/lib
GET_DEPS= deps.get
CONFIGURE_DEPS=(cd deps/eimp; ./configure)
EBINDIR=$(DEPSDIR)/ejabberd/ebin
XREFOPTIONS=graph
EDOCPRE=MIX_ENV=edoc
EDOCTASK=docs --proglang erlang
CLEANARG=--deps
ELIXIR_LIBDIR_RAW=$(shell elixir -e "IO.puts(:filename.dirname(:code.lib_dir(:elixir)))" -e ":erlang.halt")
ELIXIR_LIBDIR=":$(ELIXIR_LIBDIR_RAW)"
REBARREL=MIX_ENV=prod $(REBAR) release --overwrite
REBARDEV=MIX_ENV=dev $(REBAR) release --overwrite
RELIVECMD=$(ESCRIPT) rel/relive.escript && MIX_ENV=dev RELIVE=true $(MAYBE) $(IEX) --name ejabberd@localhost -S mix run
RELIVECTLCMD=$(ESCRIPT) rel/relive.escript ctl && _build/relivectl/ejabberdctl live
REL_LIB_DIR = _build/dev/rel/ejabberd/lib
COPY_REL_TARGET = dev
GET_DEPS_TRANSLATIONS=MIX_ENV=translations $(REBAR) $(GET_DEPS)
DEPSDIR_TRANSLATIONS=deps
else
ifeq ($(REBAR_ENABLE_ELIXIR),true)
ELIXIR_LIBDIR_RAW=$(shell elixir -e "IO.puts(:filename.dirname(:code.lib_dir(:elixir)))" -e ":erlang.halt")
ELIXIR_LIBDIR=":$(ELIXIR_LIBDIR_RAW)"
EXPLICIT_ELIXIR_COMPILE=MIX_ENV=default mix compile.elixir
EXPLICIT_ELIXIR_COMPILE_DEV=MIX_ENV=dev mix compile.elixir
PREPARE_ELIXIR_SCRIPTS=$(MKDIR_P) rel/overlays; cp $(ELIXIR_LIBDIR_RAW)/../bin/iex rel/overlays/; cp $(ELIXIR_LIBDIR_RAW)/../bin/elixir rel/overlays/; sed -i 's|ERTS_BIN=$$|ERTS_BIN=$$SCRIPT_PATH/../../erts-{{erts_vsn}}/bin/|' rel/overlays/elixir
endif
ifeq "$(REBAR_VER)" "3"
SKIPDEPS=
LISTDEPS=tree
ifeq "$(REBAR_VER_318)" "1"
UPDATEDEPS=upgrade --all
else
UPDATEDEPS=upgrade
endif
DEPSPATTERN="s/ (.*//; /^ / s/.* \([a-z0-9_]*\).*/\1/p;"
DEPSBASE=_build
DEPSDIR=$(DEPSBASE)/default/lib
GET_DEPS= get-deps
CONFIGURE_DEPS=$(REBAR) configure-deps
EBINDIR=$(DEPSDIR)/ejabberd/ebin
XREFOPTIONS=
CLEANARG=--all
REBARREL=$(REBAR) as prod tar
REBARDEV=$(REBAR) as dev release
RELIVECMD=$(REBAR) as dev relive
RELIVECTLCMD=$(ESCRIPT) rel/relive.escript ctl && _build/relivectl/ejabberdctl live
REL_LIB_DIR = _build/dev/rel/ejabberd/lib
COPY_REL_TARGET = dev
GET_DEPS_TRANSLATIONS=$(REBAR) as translations $(GET_DEPS)
DEPSDIR_TRANSLATIONS=_build/translations/lib
else
SKIPDEPS=skip_deps=true
LISTDEPS=-q list-deps
UPDATEDEPS=update-deps
DEPSPATTERN="/ TAG / s/ .*// p; / REV / s/ .*// p; / BRANCH / s/ .*// p;"
DEPSBASE=deps
DEPSDIR=$(DEPSBASE)
GET_DEPS= get-deps
CONFIGURE_DEPS=$(REBAR) configure-deps
EBINDIR=ebin
XREFOPTIONS=
CLEANARG=
REBARREL=$(REBAR) generate
REBARDEV=@echo "Rebar2 detected... dev not supported.\
\nTry: make prod, or: ./configure --with-rebar=rebar3 ; make dev"
RELIVECMD=@echo "Rebar2 detected... relive not supported.\
\nTry: ./configure --with-rebar=rebar3 ; make relive"
RELIVECTLCMD=@echo "Rebar2 detected... relivectl not supported.\
\nTry: ./configure --with-rebar=rebar3 ; make relivectl"
REL_LIB_DIR = rel/ejabberd/lib
COPY_REL_TARGET = rel
endif
endif
#.
#' main targets
#
all: scripts deps src
deps: $(DEPSDIR)/.got invites-deps
$(DEPSDIR)/.got:
rm -rf $(DEPSDIR)/.got
rm -rf $(DEPSDIR)/.built
$(MKDIR_P) $(DEPSDIR)
$(REBAR) $(GET_DEPS) && :> $(DEPSDIR)/.got
$(CONFIGURE_DEPS)
$(DEPSDIR)/.built: $(DEPSDIR)/.got
$(REBAR) compile && :> $(DEPSDIR)/.built
ifeq (, $(shell which npm))
INSTALL_INVITES_DEPS=tools/dl_invites_page_deps.sh priv/mod_invites/static
else
INSTALL_INVITES_DEPS=npm install
endif
invites-deps: priv/mod_invites/static/bootstrap/ priv/mod_invites/static/jquery/
priv/mod_invites/static/bootstrap/:
$(INSTALL_INVITES_DEPS)
priv/mod_invites/static/jquery/:
$(INSTALL_INVITES_DEPS)
src: $(DEPSDIR)/.built
$(REBAR) $(SKIPDEPS) compile
$(EXPLICIT_ELIXIR_COMPILE)
update:
rm -rf $(DEPSDIR)/.got
rm -rf $(DEPSDIR)/.built
$(REBAR) $(UPDATEDEPS) && :> $(DEPSDIR)/.got
$(CONFIGURE_DEPS)
xref: src
$(REBAR) $(SKIPDEPS) xref $(XREFOPTIONS)
hooks: src
tools/hook_deps.sh $(EBINDIR)
options: src
tools/opt_types.sh ejabberd_option $(EBINDIR)
translations:
$(GET_DEPS_TRANSLATIONS)
tools/prepare-tr.sh $(DEPSDIR_TRANSLATIONS)
doap:
tools/generate-doap.sh
#.
#' edoc
#
edoc: edoc_files edoc_compile
$(EDOCPRE) $(REBAR) $(EDOCTASK)
edoc_compile: deps
$(EDOCPRE) $(REBAR) compile
edoc_files: _build/edoc/docs.md _build/edoc/logo.png
_build/edoc/docs.md: edoc_compile
echo "For much more detailed and complete ejabberd documentation, " \
"go to the [ejabberd Docs](https://docs.ejabberd.im/) site." \
> _build/edoc/docs.md
_build/edoc/logo.png: edoc_compile
wget https://docs.ejabberd.im/assets/img/footer_logo_e.png -O _build/edoc/logo.png
#.
#' format / indent
#
format:
tools/rebar3-format.sh $(REBAR3)
indent:
tools/emacs-indent.sh
#.
#' copy-files
#
JOIN_PATHS=$(if $(wordlist 2,1000,$(1)),$(firstword $(1))/$(call JOIN_PATHS,$(wordlist 2,1000,$(1))),$(1))
VERSIONED_DEP=$(if $(DEP_$(1)_VERSION),$(DEP_$(1)_VERSION),$(1))
DEPIX:=$(words $(subst /, ,$(DEPSDIR)))
LIBIX:=$(shell expr "$(DEPIX)" + 2)
ELIXIR_TO_DEST=$(LIBDIR) $(call VERSIONED_DEP,$(word 2,$(1))) $(wordlist 5,1000,$(1))
DEPS_TO_DEST=$(LIBDIR) $(call VERSIONED_DEP,$(word 2,$(1))) $(wordlist 3,1000,$(1))
MAIN_TO_DEST=$(LIBDIR) $(call VERSIONED_DEP,ejabberd) $(1)
TO_DEST_SINGLE=$(if $(subst X$(DEPSBASE)X,,X$(word 1,$(1))X),$(call MAIN_TO_DEST,$(1)),$(if $(subst XlibX,,X$(word $(LIBIX),$(1))X),$(call DEPS_TO_DEST,$(wordlist $(DEPIX),1000,$(1))),$(call ELIXIR_TO_DEST,$(wordlist $(DEPIX),1000,$(1)))))
TO_DEST=$(foreach path,$(1),$(call JOIN_PATHS,$(DESTDIR)$(call TO_DEST_SINGLE,$(subst /, ,$(path)))))
FILTER_DIRS=$(foreach path,$(1),$(if $(wildcard $(path)/*),,$(path)))
FILES_WILDCARD=$(call FILTER_DIRS,$(foreach w,$(1),$(wildcard $(w))))
ifeq ($(MAKECMDGOALS),copy-files-sub)
DEPS:=$(sort $(shell QUIET=1 $(REBAR) $(LISTDEPS) | $(SED) -ne $(DEPSPATTERN) ))
DEPS_FILES=$(call FILES_WILDCARD,$(foreach DEP,$(DEPS),$(DEPSDIR)/$(DEP)/ebin/*.beam $(DEPSDIR)/$(DEP)/ebin/*.app $(DEPSDIR)/$(DEP)/priv/* $(DEPSDIR)/$(DEP)/priv/lib/* $(DEPSDIR)/$(DEP)/priv/bin/* $(DEPSDIR)/$(DEP)/include/*.hrl $(DEPSDIR)/$(DEP)/COPY* $(DEPSDIR)/$(DEP)/LICENSE* $(DEPSDIR)/$(DEP)/lib/*/ebin/*.beam $(DEPSDIR)/$(DEP)/lib/*/ebin/*.app))
BINARIES=$(DEPSDIR)/epam/priv/bin/epam $(DEPSDIR)/eimp/priv/bin/eimp $(DEPSDIR)/fs/priv/mac_listener
DEPS_FILES_FILTERED=$(filter-out $(BINARIES) $(DEPSDIR)/elixir/ebin/elixir.app,$(DEPS_FILES))
DEPS_DIRS=$(sort $(DEPSDIR)/ $(foreach DEP,$(DEPS),$(DEPSDIR)/$(DEP)/) $(dir $(DEPS_FILES)))
MAIN_FILES=$(filter-out %/configure.beam,$(call FILES_WILDCARD,$(EBINDIR)/*.beam $(EBINDIR)/*.app priv/msgs/*.msg priv/css/*.css priv/img/*.png priv/js/*.js priv/lib/* priv/mod_invites/* priv/mod_invites/static/* priv/mod_invites/static/bootstrap/css/bootstrap.min.css priv/mod_invites/static/bootstrap/js/bootstrap.min.js priv/mod_invites/static/jquery/jquery.min.js \
priv/mod_invites/static/logos/* include/*.hrl COPYING))
MAIN_DIRS=$(sort $(dir $(MAIN_FILES)) priv/bin priv/sql priv/lua priv/mod_invites)
define DEP_VERSION_template
DEP_$(1)_VERSION:=$(shell $(SED) -e '/vsn/!d;s/.*, *"/$(1)-/;s/".*//' $(2) 2>/dev/null)
endef
DELETE_TARGET_SO=$(if $(subst X.soX,,X$(suffix $(1))X),,rm -f $(call TO_DEST,$(1));)
$(foreach DEP,$(DEPS),$(eval $(call DEP_VERSION_template,$(DEP),$(DEPSDIR)/$(DEP)/ebin/$(DEP).app)))
$(eval $(call DEP_VERSION_template,ejabberd,$(EBINDIR)/ejabberd.app))
define COPY_template
$(call TO_DEST,$(1)): $(1) $(call TO_DEST,$(dir $(1))) ; $(call DELETE_TARGET_SO, $(1)) $$(INSTALL) -m 644 $(1) $(call TO_DEST,$(1))
endef
define COPY_BINARY_template
$(call TO_DEST,$(1)): $(1) $(call TO_DEST,$(dir $(1))) ; rm -f $(call TO_DEST,$(1)); $$(INSTALL) -m 755 $$(O_USER) $(1) $(call TO_DEST,$(1))
endef
$(foreach file,$(DEPS_FILES_FILTERED) $(MAIN_FILES),$(eval $(call COPY_template,$(file))))
$(foreach file,$(BINARIES),$(eval $(call COPY_BINARY_template,$(file))))
$(sort $(call TO_DEST,$(MAIN_DIRS) $(DEPS_DIRS))):
$(INSTALL) -d $@
$(call TO_DEST,priv/sql/lite.sql): sql/lite.sql $(call TO_DEST,priv/sql)
$(INSTALL) -m 644 $< $@
$(call TO_DEST,priv/sql/lite.new.sql): sql/lite.new.sql $(call TO_DEST,priv/sql)
$(INSTALL) -m 644 $< $@
$(call TO_DEST,priv/bin/captcha.sh): tools/captcha.sh $(call TO_DEST,priv/bin)
$(INSTALL) -m 755 $(O_USER) $< $@
$(call TO_DEST,priv/lua/redis_sm.lua): priv/lua/redis_sm.lua $(call TO_DEST,priv/lua)
$(INSTALL) -m 644 $< $@
ifeq (@sqlite@,true)
SQLITE_FILES = priv/sql/lite.sql priv/sql/lite.new.sql
endif
ifeq (@redis@,true)
REDIS_FILES = priv/lua/redis_sm.lua
endif
copy-files-sub2: $(call TO_DEST,$(DEPS_FILES) $(MAIN_FILES) priv/bin/captcha.sh $(SQLITE_FILES) $(REDIS_FILES))
.PHONY: $(call TO_DEST,$(DEPS_FILES) $(MAIN_DIRS) $(DEPS_DIRS))
endif
copy-files:
$(MAKE) copy-files-sub
copy-files-sub: copy-files-sub2
#.
#' copy-files-rel
#
copy-files-rel: $(COPY_REL_TARGET)
#
# Libraries
(cd $(REL_LIB_DIR) && find . -follow -type f ! -executable -exec $(INSTALL) -vDm 640 $(G_USER) {} $(DESTDIR)$(LIBDIR)/{} \;)
#
# *.so:
(cd $(REL_LIB_DIR) && find . -follow -type f -executable -name *.so -exec $(INSTALL) -vDm 640 $(G_USER) {} $(DESTDIR)$(LIBDIR)/{} \;)
#
# Executable files
(cd $(REL_LIB_DIR) && find . -follow -type f -executable ! -name *.so -exec $(INSTALL) -vDm 550 $(G_USER) {} $(DESTDIR)$(LIBDIR)/{} \;)
#.
#' uninstall-librel
#
uninstall-librel:
(cd $(REL_LIB_DIR) && find . -follow -type f -exec rm -fv -v $(DESTDIR)$(LIBDIR)/{} \;)
(cd $(REL_LIB_DIR) && find . -follow -depth -type d -exec rm -dv -v $(DESTDIR)$(LIBDIR)/{} \;)
#.
#' relive
#
relive:
$(EXPLICIT_ELIXIR_COMPILE_DEV)
$(RELIVECMD)
relivectl:
$(EXPLICIT_ELIXIR_COMPILE_DEV)
$(RELIVECTLCMD)
relivelibdir=$(shell pwd)/$(DEPSDIR)
relivebase=$(shell pwd)/$(DEPSBASE)
#.
#' scripts
#
# Used for ejabberdctl.relive and ejabberdctl.relivectl
ejabberdctl.re%:
$(SED) -e "s*{{installuser}}*${INSTALLUSER}*g" \
-e "s*{{config_dir}}*${relivebase}/re${*}/conf*g" \
-e "s*{{logs_dir}}*${relivebase}/re${*}/logs*g" \
-e "s*{{spool_dir}}*${relivebase}/re${*}/database*g" \
-e "s*{{bindir}}*${BINDIR}*g" \
-e "s*{{libdir}}*${relivelibdir}${ELIXIR_LIBDIR}*g" \
-e "s*ERTS_VSN*# ERTS_VSN*g" \
-e "s*{{iexpath}}*${IEX}*g" \
-e "s*{{erl}}*${ERL}*g" \
-e "s*{{epmd}}*${EPMD}*g" ejabberdctl.template \
> ejabberdctl.re${*}
ejabberd.init:
$(SED) -e "s*@ctlscriptpath@*$(SBINDIR)*g" \
-e "s*@installuser@*$(INIT_USER)*g" ejabberd.init.template \
> ejabberd.init
chmod 755 ejabberd.init
ejabberd.service:
$(SED) -e "s*@ctlscriptpath@*$(SBINDIR)*g" \
-e "s*@installuser@*$(INIT_USER)*g" ejabberd.service.template \
> ejabberd.service
chmod 644 ejabberd.service
ejabberdctl.example: vars.config
$(SED) -e "s*{{installuser}}*${INSTALLUSER}*g" \
-e "s*{{config_dir}}*${ETCDIR}*g" \
-e "s*{{logs_dir}}*${LOGDIR}*g" \
-e "s*{{spool_dir}}*${SPOOLDIR}*g" \
-e "s*{{bindir}}*${BINDIR}*g" \
-e "s*{{libdir}}*${LIBDIR}${ELIXIR_LIBDIR}*g" \
-e "s*ERTS_VSN*# ERTS_VSN*g" \
-e "s*{{iexpath}}*${IEX}*g" \
-e "s*{{erl}}*${ERL}*g" \
-e "s*{{epmd}}*${EPMD}*g" ejabberdctl.template \
> ejabberdctl.example
scripts: ejabberd.init ejabberd.service ejabberdctl.example
#.
#' install
#
install: copy-files install-main
install-rel: copy-files-rel install-main
install-main:
#
# Configuration files
$(INSTALL) -d -m 750 $(G_USER) $(DESTDIR)$(ETCDIR)
[ -f $(DESTDIR)$(ETCDIR)/ejabberd.yml ] \
&& $(INSTALL) -b -m 640 $(G_USER) ejabberd.yml.example $(DESTDIR)$(ETCDIR)/ejabberd.yml-new \
|| $(INSTALL) -b -m 640 $(G_USER) ejabberd.yml.example $(DESTDIR)$(ETCDIR)/ejabberd.yml
[ -f $(DESTDIR)$(ETCDIR)/ejabberdctl.cfg ] \
&& $(INSTALL) -b -m 640 $(G_USER) ejabberdctl.cfg.example $(DESTDIR)$(ETCDIR)/ejabberdctl.cfg-new \
|| $(INSTALL) -b -m 640 $(G_USER) ejabberdctl.cfg.example $(DESTDIR)$(ETCDIR)/ejabberdctl.cfg
$(INSTALL) -b -m 644 $(G_USER) inetrc $(DESTDIR)$(ETCDIR)/inetrc
#
# Administration script
[ -d $(DESTDIR)$(SBINDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(SBINDIR)
$(INSTALL) -m 550 $(G_USER) ejabberdctl.example $(DESTDIR)$(SBINDIR)/ejabberdctl
# Elixir binaries
[ -d $(DESTDIR)$(BINDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR)
[ -f $(DEPSDIR)/elixir/bin/iex ] && $(INSTALL) -m 550 $(G_USER) $(DEPSDIR)/elixir/bin/iex $(DESTDIR)$(BINDIR)/iex || true
[ -f $(DEPSDIR)/elixir/bin/elixir ] && $(INSTALL) -m 550 $(G_USER) $(DEPSDIR)/elixir/bin/elixir $(DESTDIR)$(BINDIR)/elixir || true
[ -f $(DEPSDIR)/elixir/bin/mix ] && $(INSTALL) -m 550 $(G_USER) $(DEPSDIR)/elixir/bin/mix $(DESTDIR)$(BINDIR)/mix || true
#
# Spool directory
$(INSTALL) -d -m 750 $(O_USER) $(DESTDIR)$(SPOOLDIR)
$(CHOWN_COMMAND) -R $(INSTALLUSER) $(DESTDIR)$(SPOOLDIR) >$(CHOWN_OUTPUT)
chmod -R 750 $(DESTDIR)$(SPOOLDIR)
#
# Log directory
$(INSTALL) -d -m 750 $(O_USER) $(DESTDIR)$(LOGDIR)
$(CHOWN_COMMAND) -R $(INSTALLUSER) $(DESTDIR)$(LOGDIR) >$(CHOWN_OUTPUT)
chmod -R 750 $(DESTDIR)$(LOGDIR)
#
# Documentation
$(INSTALL) -d $(DESTDIR)$(MANDIR)
$(INSTALL) -d $(DESTDIR)$(DOCDIR)
[ -f man/ejabberd.yml.5 ] \
&& $(INSTALL) -m 644 man/ejabberd.yml.5 $(DESTDIR)$(MANDIR) \
|| echo "Man page not included in sources"
$(INSTALL) -m 644 COPYING $(DESTDIR)$(DOCDIR)
#.
#' uninstall
#
uninstall: uninstall-binary
uninstall-rel: uninstall-binary uninstall-librel
uninstall-binary:
rm -f $(DESTDIR)$(SBINDIR)/ejabberdctl
rm -f $(DESTDIR)$(BINDIR)/iex
rm -f $(DESTDIR)$(BINDIR)/elixir
rm -f $(DESTDIR)$(BINDIR)/mix
rm -fr $(DESTDIR)$(DOCDIR)
rm -f $(DESTDIR)$(BEAMDIR)/*.beam
rm -f $(DESTDIR)$(BEAMDIR)/*.app
rm -fr $(DESTDIR)$(BEAMDIR)
rm -f $(DESTDIR)$(INCLUDEDIR)/*.hrl
rm -fr $(DESTDIR)$(INCLUDEDIR)
rm -fr $(DESTDIR)$(PBINDIR)
rm -f $(DESTDIR)$(SODIR)/*.so
rm -fr $(DESTDIR)$(SODIR)
rm -f $(DESTDIR)$(MSGSDIR)/*.msg
rm -fr $(DESTDIR)$(MSGSDIR)
rm -f $(DESTDIR)$(CSSDIR)/*.css
rm -fr $(DESTDIR)$(CSSDIR)
rm -f $(DESTDIR)$(IMGDIR)/*.png
rm -fr $(DESTDIR)$(IMGDIR)
rm -f $(DESTDIR)$(JSDIR)/*.js
rm -fr $(DESTDIR)$(JSDIR)
rm -f $(DESTDIR)$(SQLDIR)/*.sql
rm -fr $(DESTDIR)$(SQLDIR)
rm -fr $(DESTDIR)$(LUADIR)/*.lua
rm -fr $(DESTDIR)$(LUADIR)
rm -fr $(DESTDIR)$(PRIVDIR)
rm -fr $(DESTDIR)$(EJABBERDDIR)
rm -f $(DESTDIR)$(MANDIR)/ejabberd.yml.5
uninstall-all: uninstall-binary
rm -rf $(DESTDIR)$(ETCDIR)
rm -rf $(DESTDIR)$(EJABBERDDIR)
rm -rf $(DESTDIR)$(SPOOLDIR)
rm -rf $(DESTDIR)$(LOGDIR)
#.
#' clean
#
clean:
rm -rf $(DEPSDIR)/.got
rm -rf $(DEPSDIR)/.built
rm -rf test/*.beam
rm -f rebar.lock
rm -f ejabberdctl.example ejabberd.init ejabberd.service
rm -rf priv/mod_invites/static/{jquery,bootstrap4}
$(REBAR) clean $(CLEANARG)
clean-rel:
rm -rf rel/ejabberd
distclean: clean clean-rel
rm -f aclocal.m4
rm -f config.status
rm -f config.log
rm -rf autom4te.cache
rm -rf $(EBINDIR)
rm -rf $(DEPSBASE)
rm -rf deps
rm -f Makefile
rm -f vars.config
#.
#' releases
#
rel: prod
prod:
$(PREPARE_ELIXIR_SCRIPTS)
$(REBARREL)
DEV_CONFIG = _build/dev/rel/ejabberd/conf/ejabberd.yml
dev $(DEV_CONFIG):
$(PREPARE_ELIXIR_SCRIPTS)
$(REBARDEV)
#.
#' tags
#
TAGS:
etags src/*.erl
#.
#' makefile
#
Makefile: Makefile.in
#.
#' dialyzer
#
ifeq "$(REBAR_VER)" "6" # Mix
dialyzer:
MIX_ENV=test $(REBAR) dialyzer
else
ifeq "$(REBAR_VER)" "3" # Rebar3
dialyzer:
$(REBAR) dialyzer
else # Rebar2
deps := $(wildcard $(DEPSDIR)/*/ebin)
dialyzer/erlang.plt:
@$(MKDIR_P) dialyzer
@dialyzer --build_plt --output_plt dialyzer/erlang.plt \
-o dialyzer/erlang.log --apps kernel stdlib sasl crypto \
public_key ssl mnesia inets odbc compiler erts \
os_mon asn1 syntax_tools; \
status=$$? ; if [ $$status -ne 2 ]; then exit $$status; else exit 0; fi
dialyzer/deps.plt:
@$(MKDIR_P) dialyzer
@dialyzer --build_plt --output_plt dialyzer/deps.plt \
-o dialyzer/deps.log $(deps); \
status=$$? ; if [ $$status -ne 2 ]; then exit $$status; else exit 0; fi
dialyzer/ejabberd.plt:
@$(MKDIR_P) dialyzer
@dialyzer --build_plt --output_plt dialyzer/ejabberd.plt \
-o dialyzer/ejabberd.log ebin; \
status=$$? ; if [ $$status -ne 2 ]; then exit $$status; else exit 0; fi
erlang_plt: dialyzer/erlang.plt
@dialyzer --plt dialyzer/erlang.plt --check_plt -o dialyzer/erlang.log; \
status=$$? ; if [ $$status -ne 2 ]; then exit $$status; else exit 0; fi
deps_plt: dialyzer/deps.plt
@dialyzer --plt dialyzer/deps.plt --check_plt -o dialyzer/deps.log; \
status=$$? ; if [ $$status -ne 2 ]; then exit $$status; else exit 0; fi
ejabberd_plt: dialyzer/ejabberd.plt
@dialyzer --plt dialyzer/ejabberd.plt --check_plt -o dialyzer/ejabberd.log; \
status=$$? ; if [ $$status -ne 2 ]; then exit $$status; else exit 0; fi
dialyzer: erlang_plt deps_plt ejabberd_plt
@dialyzer --plts dialyzer/*.plt --no_check_plt \
--get_warnings -o dialyzer/error.log ebin; \
status=$$? ; if [ $$status -ne 2 ]; then exit $$status; else exit 0; fi
endif
endif
#.
#' elvis
#
elvis:
$(REBAR) lint
#.
#' test
#
test:
@echo "************************** NOTICE ***************************************"
@cat test/README
@echo "*************************************************************************"
@cd priv && ln -sf ../sql
$(REBAR) $(SKIPDEPS) ct
.PHONY: test-%
define test-group-target
test-$1:
$(REBAR) $(SKIPDEPS) ct --suite=test/ejabberd_SUITE --group=$1
endef
ifneq ($(filter test-%,$(MAKECMDGOALS)),)
group_to_test := $(patsubst test-%,%,$(filter test-%,$(MAKECMDGOALS)))
$(eval $(call test-group-target,$(group_to_test)))
endif
testeunit:
$(REBAR) $(SKIPDEPS) eunit --verbose
#.
#' phony
#
.PHONY: src edoc dialyzer Makefile TAGS clean clean-rel distclean prod rel \
install uninstall uninstall-binary uninstall-all translations deps test testeunit \
all dev doap help install-rel relive scripts uninstall-rel update \
erlang_plt deps_plt ejabberd_plt xref hooks options format indent
#.
#' help
#
help:
@echo ""
@echo " [all] "
@echo " scripts Prepare ejabberd start scripts"
@echo " deps Get and configure dependencies"
@echo " src Compile dependencies and ejabberd"
@echo " update Update dependencies source code"
@echo " clean Clean binary files"
@echo " distclean Clean completely the development files"
@echo ""
@echo " install Install ejabberd to /usr/local"
@echo " install-rel Install ejabberd to /usr/local (using release)"
@echo " uninstall Uninstall ejabberd (buggy)"
@echo " uninstall-rel Uninstall ejabberd (using release)"
@echo " uninstall-all Uninstall also configuration, logs, mnesia... (buggy)"
@echo ""
@echo " prod Build a production release"
@echo " dev Build a development release"
@echo " relive Start live using rebar3/mix tools"
@echo " relivectl Start live using ejabberdctl script"
@echo ""
@echo " doap Generate DOAP file"
@echo " edoc Generate EDoc documentation [mix]"
@echo " options Generate ejabberd_option.erl"
@echo " translations Extract translation files"
@echo " TAGS Generate tags file for text editors"
@echo ""
@echo " format Format source code using rebar3_format"
@echo " indent Indent source code using erlang-mode [emacs]"
@echo ""
@echo " dialyzer Run Dialyzer static analyzer"
@echo " elvis Run Elvis source code style reviewer [rebar3]"
@echo " hooks Run hooks validator"
@echo " test Run Common Tests suite [rebar3]"
@echo " testeunit Run EUnit suite [rebar3]"
@echo " test-<group> Run Common Test suite for specific group only [rebar3]"
@echo " xref Run cross reference analysis [rebar3]"
#.
#'
# vim: foldmarker=#',#. foldmethod=marker:
-136
View File
@@ -1,136 +0,0 @@
<p align="center">
<img src="https://www.process-one.net/wp-content/uploads/2022/05/ejabberd-logo-rounded-index.png">
</p>
<p align="center">
<a href="https://github.com/processone/ejabberd/tags" alt="GitHub tag (latest SemVer)">
<img src="https://img.shields.io/github/v/tag/processone/ejabberd?sort=semver&logo=embarcadero&label=&color=3fb0d2&logoWidth=20" /></a>
<a href="https://hex.pm/packages/ejabberd" alt="Hex version">
<img src="https://img.shields.io/hexpm/v/ejabberd.svg" /></a>
<a href="https://formulae.brew.sh/formula/ejabberd" alt="homebrew version">
<img src="https://img.shields.io/homebrew/v/ejabberd" /></a>
<a href="https://hub.docker.com/r/ejabberd/ecs/" alt="Docker Image Version (latest semver)">
<img src="https://img.shields.io/docker/v/ejabberd/ecs?label=ecs&logo=docker" /></a>
<a href="https://github.com/processone/ejabberd/pkgs/container/ejabberd" alt="GitHub Container">
<img src="https://img.shields.io/github/v/tag/processone/ejabberd?label=ejabberd&sort=semver&logo=docker" /></a>
<br />
<a href="https://github.com/processone/ejabberd/actions/workflows/ci.yml" alt="CI">
<img src="https://github.com/processone/ejabberd/actions/workflows/ci.yml/badge.svg" /></a>
<a href="https://coveralls.io/github/processone/ejabberd?branch=master" alt="Coverage Status">
<img src="https://coveralls.io/repos/github/processone/ejabberd/badge.svg?branch=master" /></a>
<a href="https://hosted.weblate.org/projects/ejabberd/ejabberd-po/" alt="Translation status">
<img src="https://hosted.weblate.org/widgets/ejabberd/-/ejabberd-po/svg-badge.svg" /></a>
<a href="https://docs.ejabberd.im/" alt="ejabberd Docs">
<img src="https://img.shields.io/github/v/tag/processone/docs.ejabberd.im?sort=semver&logo=&label=docs&logoWidth=0" /></a>
</p>
[ejabberd][im] is an open-source,
robust, scalable and extensible realtime platform built using [Erlang/OTP][erlang],
that includes [XMPP][xmpp] Server, [MQTT][mqtt] Broker and [SIP][sip] Service.
Check the features in [ejabberd.im][im], [ejabberd Docs][features],
[ejabberd at ProcessOne][p1home], and the list of [supported protocols in ProcessOne][xeps]
and [XMPP.org][xmppej].
Installation
------------
There are several ways to install ejabberd:
- Source code: compile yourself, see [COMPILE](COMPILE.md)
- Installers:
- [ProcessOne Download Page][p1download] or [GitHub Releases][releases] for releases.
- [GitHub Actions](https://github.com/processone/ejabberd/actions/workflows/installers.yml) for master branch (`run`/`deb`/`rpm` for `x64` and `arm64`)
- Docker Containers:
- `ecs` container image: [Docker Hub][hubecs] and [Github Packages][packagesecs], see [ecs README][docker-ecs-readme] (for `x64`)
- `ejabberd` container image: [Github Packages][packages] for releases and master branch, see [CONTAINER](CONTAINER.md) (for `x64` and `arm64`)
- Using your [Operating System package][osp]
- Using the [Homebrew][homebrew] package manager
More info can be found in the `Installation` part of [ejabberd Docs](https://docs.ejabberd.im/admin/install/).
Documentation
-------------
Please check the [ejabberd Docs][docs] website.
When compiling from source code, you can get some help with:
./configure --help
make help
Once ejabberd is installed, try:
ejabberdctl help
man ejabberd.yml
Development
-----------
Bug reports and features are tracked using [GitHub Issues][issues],
please check [CONTRIBUTING](CONTRIBUTING.md) for details.
Translations can be improved online [using Weblate][weblate]
or in your local machine as explained in [Localization][localization].
Documentation for developers is available in [ejabberd docs: Developers][docs-dev].
There are nightly builds of ejabberd, both for `master` branch and for Pull Requests:
- Installers: go to [GitHub Actions: Installers](https://github.com/processone/ejabberd/actions/workflows/installers.yml), open the most recent commit, on the bottom of that commit page, download the `ejabberd-packages.zip` artifact.
- `ejabberd` container image: go to [ejabberd Github Packages][packages]
Security reports or concerns should preferably be reported privately,
please send an email to the address: contact at process-one dot net
or some other method from [ProcessOne Contact][p1contact].
For commercial offering and support, including [ejabberd Business Edition][p1home]
and [Fluux (ejabberd in the Cloud)][fluux], please check [ProcessOne ejabberd page][p1home].
Security
--------
For information on how to report security vulnerabilities, please refer to the [SECURITY.md](SECURITY.md) file. It contains guidelines on how to report vulnerabilities privately and securely, ensuring that any issues are addressed in a timely and confidential manner.
Community
---------
There are several places to get in touch with other ejabberd developers and administrators:
- ejabberd XMPP chatroom: [ejabberd@conference.process-one.net][muc]
- [GitHub Discussions][discussions]
- [Stack Overflow][stackoverflow]
License
-------
- ejabberd is released under the __GNU General Public License v2__ (see [COPYING](COPYING))
- [ejabberd translations](https://github.com/processone/ejabberd-po/) under __MIT License__.
[discussions]: https://github.com/processone/ejabberd/discussions
[docker-ecs-readme]: https://github.com/processone/docker-ejabberd/tree/master/ecs#readme
[docs-dev]: https://docs.ejabberd.im/developer/
[docs]: https://docs.ejabberd.im
[erlang]: https://www.erlang.org/
[features]: https://docs.ejabberd.im/admin/introduction/
[fluux]: https://fluux.io/
[homebrew]: https://docs.ejabberd.im/admin/install/homebrew/
[hubecs]: https://hub.docker.com/r/ejabberd/ecs/
[im]: https://www.ejabberd.im/
[issues]: https://github.com/processone/ejabberd/issues
[localization]: https://docs.ejabberd.im/developer/extending-ejabberd/localization/
[mqtt]: https://mqtt.org/
[muc]: xmpp:ejabberd@conference.process-one.net
[osp]: https://docs.ejabberd.im/admin/install/os-package/
[p1contact]: https://www.process-one.net/contact/
[p1download]: https://www.process-one.net/download/ejabberd/
[p1home]: https://www.process-one.net/ejabberd/
[packages]: https://github.com/processone/ejabberd/pkgs/container/ejabberd
[packagesecs]: https://github.com/processone/docker-ejabberd/pkgs/container/ecs
[releases]: https://github.com/processone/ejabberd/releases
[sip]: https://en.wikipedia.org/wiki/Session_Initiation_Protocol
[stackoverflow]: https://stackoverflow.com/questions/tagged/ejabberd?sort=newest
[weblate]: https://hosted.weblate.org/projects/ejabberd/ejabberd-po/
[xeps]: https://www.process-one.net/ejabberd-features/
[xmpp]: https://xmpp.org/
[xmppej]: https://xmpp.org/software/servers/ejabberd/
-45
View File
@@ -1,45 +0,0 @@
# Security Policy
## Supported Versions
We recommend that all users always use the latest version of ejabberd.
To ensure the best experience and security, upgrade to the latest version available on [this repo](https://github.com/processone/ejabberd).
## Reporting a Vulnerability
### Private Reporting
**Preferred Method**: Use GitHub's private vulnerability reporting system by clicking the "Report a Vulnerability" button in the [Security tab of this repository](https://github.com/processone/ejabberd/security). This ensures your report is securely transmitted and tracked.
**Alternative**: If you cannot use the GitHub system, send an email to **`contact@process-one.net`** with the following details:
- A clear description of the vulnerability.
- Steps to reproduce the issue.
- Any potential impact or exploitation scenarios.
### Response Time
We aim to acknowledge receipt of your report within 72 hours. You can expect regular updates on the status of your report.
### Resolution
If the vulnerability is confirmed, we will work on a patch or mitigation strategy.
We will notify you once the issue is resolved and coordinate a public disclosure if needed.
### Acknowledgements
We value and appreciate the contributions of security researchers and community members.
If you wish, we are happy to acknowledge your efforts publicly by listing your name (or alias) below in this document.
Please let us know if you would like to be recognized when reporting the vulnerability.
## Public Discussion
For general inquiries or discussions about the projects security, feel free to chat with us here:
- XMPP room: `ejabberd@conference.process-one.net`
- [GitHub Discussions](https://github.com/processone/ejabberd/discussions)
However, please note that if the issue is **critical** or potentially exploitable, **do not share it publicly**. Instead, we strongly recommend you contact the maintainers directly via the private reporting methods outlined above to ensure a secure and timely response.
Thank you for helping us improve the security of ejabberd!
+21
View File
@@ -0,0 +1,21 @@
admin tool
mod_muc logging
admin interface
users management
statistics about each user
statistics about each connection
node management
node restart/shutdown
statistics about memory usage
S2S:
rewrite S2S key validation
check "id" attributes in db:verify packets
more correctly work with SRV DNS records (priority, weight, etc...)
TLS
make roster set to work in one transaction
add traffic shapers to c2s connection before authentification
more traffic shapers
SNMP
-2
View File
@@ -1,2 +0,0 @@
{erl_opts, [debug_info]}.
{deps, []}.
@@ -1,9 +0,0 @@
{application, configure_deps,
[{description, "A rebar3 plugin to explicitly run configure on dependencies"},
{vsn, "0.0.1"},
{registered, []},
{applications, [kernel, stdlib]},
{env,[]},
{modules, []},
{links, []}
]}.
@@ -1,8 +0,0 @@
-module(configure_deps).
-export([init/1]).
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
init(State) ->
{ok, State1} = configure_deps_prv:init(State),
{ok, State1}.
@@ -1,54 +0,0 @@
-module(configure_deps_prv).
-export([init/1, do/1, format_error/1]).
-define(PROVIDER, 'configure-deps').
-define(DEPS, [install_deps]).
%% ===================================================================
%% Public API
%% ===================================================================
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
init(State) ->
Provider = providers:create([
{namespace, default},
{name, ?PROVIDER}, % The 'user friendly' name of the task
{module, ?MODULE}, % The module implementation of the task
{bare, true}, % The task can be run by the user, always true
{deps, ?DEPS}, % The list of dependencies
{example, "rebar3 configure-deps"}, % How to use the plugin
{opts, []}, % list of options understood by the plugin
{short_desc, "Explicitly run ./configure for dependencies"},
{desc, "A rebar plugin to allow explicitly running ./configure on dependencies. Useful if dependencies might change prior to compilation when configure is run."}
]),
{ok, rebar_state:add_provider(State, Provider)}.
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) ->
Apps = rebar_state:project_apps(State) ++ lists:usort(rebar_state:all_deps(State)),
lists:foreach(fun do_app/1, Apps),
{ok, State}.
exec_configure({'configure-deps', Cmd}, Dir) ->
rebar_utils:sh(Cmd, [{cd, Dir}, {use_stdout, true}]);
exec_configure(_, Acc) -> Acc.
parse_pre_hooks({pre_hooks, PreHooks}, Acc) ->
lists:foldl(fun exec_configure/2, Acc, PreHooks);
parse_pre_hooks(_, Acc) -> Acc.
parse_additions({add, App, Additions}, {MyApp, Dir}) when App == MyApp ->
lists:foldl(fun parse_pre_hooks/2, Dir, Additions),
{MyApp, Dir};
parse_additions(_, Acc) -> Acc.
do_app(App) ->
Dir = rebar_app_info:dir(App),
Opts = rebar_app_info:opts(App),
Overrides = rebar_opts:get(Opts, overrides),
lists:foldl(fun parse_additions/2, {binary_to_atom(rebar_app_info:name(App), utf8), Dir}, Overrides).
-spec format_error(any()) -> iolist().
format_error(Reason) ->
io_lib:format("~p", [Reason]).
-3
View File
@@ -1,3 +0,0 @@
# generate a new autoconf
aclocal -I m4
autoconf -f
-164
View File
@@ -1,164 +0,0 @@
defmodule Ejabberd.ConfigFile do
use Ejabberd.Config
def start do
[loglevel: 4,
log_rotate_size: 10485760,
log_rotate_count: 1,
auth_method: :internal,
max_fsm_queue: 1000,
language: "en",
allow_contrib_modules: true,
hosts: ["localhost"],
shaper: shaper(),
acl: acl(),
access: access()]
end
defp shaper do
[normal: 1000,
fast: 50000,
max_fsm_queue: 1000]
end
defp acl do
[local:
[user_regexp: "", loopback: [ip: "127.0.0.0/8"]]]
end
defp access do
[max_user_sessions: [all: 10],
max_user_offline_messages: [admin: 5000, all: 100],
local: [local: :allow],
c2s: [blocked: :deny, all: :allow],
c2s_shaper: [admin: :none, all: :normal],
s2s_shaper: [all: :fast],
announce: [admin: :allow],
configure: [admin: :allow],
muc_admin: [admin: :allow],
muc_create: [local: :allow],
muc: [all: :allow],
pubsub_createnode: [local: :allow],
register: [all: :allow],
trusted_network: [loopback: :allow]]
end
listen :ejabberd_c2s do
@opts [
port: 5222,
max_stanza_size: 65536,
shaper: :c2s_shaper,
access: :c2s]
end
listen :ejabberd_s2s_in do
@opts [port: 5269]
end
listen :ejabberd_http do
@opts [
port: 5280,
web_admin: true,
http_bind: true,
captcha: true]
end
module :mod_adhoc do
end
module :mod_announce do
@opts [access: :announce]
end
module :mod_blocking do
end
module :mod_caps do
end
module :mod_carboncopy do
end
module :mod_client_state do
@opts [
queue_chat_states: true,
queue_presence: false]
end
module :mod_configure do
end
module :mod_disco do
end
module :mod_http_bind do
end
module :mod_last do
end
module :mod_muc do
@opts [
access: :muc,
access_create: :muc_create,
access_persistent: :muc_create,
access_admin: :muc_admin]
end
module :mod_offline do
@opts [access_max_user_messages: :max_user_offline_messages]
end
module :mod_ping do
end
module :mod_privacy do
end
module :mod_private do
end
module :mod_pubsub do
@opts [
access_createnode: :pubsub_createnode,
ignore_pep_from_offline: true,
last_item_cache: true,
plugins: ["flat", "hometree", "pep"]]
end
module :mod_register do
@opts [welcome_message: [
subject: "Welcome!",
body: "Hi.\nWelcome to this XMPP server"
],
ip_access: :trusted_network,
access: :register]
end
module :mod_roster do
end
module :mod_shared_roster do
end
module :mod_stats do
end
module :mod_time do
end
module :mod_version do
end
# Example of how to define a hook, called when the event
# specified is triggered.
#
# @event: Name of the event
# @opts: Params are optional. Available: :host and :priority.
# If missing, defaults are used. (host: :global | priority: 50)
# @callback Could be an anonymous function or a callback from a module,
# use the &ModuleName.function/arity format for that.
hook :register_user, [host: "localhost"], fn(user, server) ->
info("User registered: #{user} on #{server}")
end
end
-15
View File
@@ -1,15 +0,0 @@
import Config
rootdefault = case System.get_env("RELIVE", "false") do
"true" -> "_build/relive"
"false" -> ""
end
rootpath = System.get_env("RELEASE_ROOT", rootdefault)
config :ejabberd,
file: Path.join(rootpath, "conf/ejabberd.yml"),
log_path: Path.join(rootpath, "logs/ejabberd.log")
config :mnesia,
dir: Path.join(rootpath, "database/")
config :exsync,
reload_callback: {:ejabberd_admin, :update, []}
-375
View File
@@ -1,375 +0,0 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT(ejabberd, m4_esyscmd([echo `git describe --tags 2>/dev/null || echo 26.03` | sed 's/-g.*//;s/-/./' | tr -d '\012']), [ejabberd@process-one.net], [ejabberd])
AC_ARG_WITH(min-erlang,
AS_HELP_STRING([--with-min-erlang=version],[set minimal required erlang version, default to OTP25]),
[if test "X$withval" = "X"; then
REQUIRE_ERLANG_MIN="13.0 (Erlang/OTP 25.0)"
else
REQUIRE_ERLANG_MIN="$withval"
fi
], [REQUIRE_ERLANG_MIN="13.0 (Erlang/OTP 25.0)"])
REQUIRE_ERLANG_MAX="100.0.0 (No Max)"
AC_CONFIG_MACRO_DIR([m4])
# Checks for programs.
AC_PROG_MAKE_SET
AC_PROG_AWK
AC_PROG_INSTALL
AC_PROG_MKDIR_P
AC_PROG_SED
if test "x$GCC" = "xyes"; then
CFLAGS="$CFLAGS -Wall"
fi
# Checks Erlang runtime and compiler
AC_ARG_WITH(erlang,
AS_HELP_STRING([--with-erlang=dir],[search for erlang in dir]),
[if test "$withval" = "yes" -o "$withval" = "no" -o "X$with_erlang" = "X"; then
extra_erl_path=""
else
extra_erl_path="$with_erlang:$with_erlang/bin:"
fi
])
AC_ARG_WITH(rebar,
AS_HELP_STRING([--with-rebar=bin],[use as build tool the rebar/rebar3/mix binary specified]),
[if test "$withval" = "yes" -o "$withval" = "no" -o "X$with_rebar" = "X"; then
rebar="rebar3"
else
rebar="$with_rebar"
fi
], [rebar="unconfigured"])
AC_PATH_TOOL(ERL, erl, , [${extra_erl_path}$PATH])
AC_PATH_TOOL(ERLC, erlc, , [${extra_erl_path}$PATH])
AC_PATH_TOOL(EPMD, epmd, , [${extra_erl_path}$PATH])
AC_PATH_TOOL(REBAR, rebar, , [${extra_erl_path}$PATH])
AC_PATH_TOOL(REBAR3, rebar3, , [${extra_erl_path}$PATH])
AC_PATH_TOOL(ELIXIR, elixir, , [${extra_erl_path}$PATH])
AC_PATH_TOOL(IEX, iex, , [${extra_erl_path}$PATH])
AC_PATH_TOOL(MIX, mix, , [${extra_erl_path}$PATH])
if test "$rebar" = unconfigured; then
if test "x$ELIXIR" = "x" -o "x$IEX" = "x" -o "x$MIX" = "x"; then
if test "x$REBAR3" = "x"; then
rebar="rebar3"
else
rebar=$REBAR3
fi
else
rebar=$MIX
fi
fi
if test "x$rebar" = "xrebar" -a "x$REBAR" = "x" ; then
rebar="./rebar"
fi
if test "x$rebar" = "xrebar3" -a "x$REBAR3" = "x" ; then
rebar="./rebar3"
fi
AC_ERLANG_NEED_ERL
AC_ERLANG_NEED_ERLC
# Checks and sets ERLANG_ROOT_DIR and ERLANG_LIB_DIR variable
AC_ERLANG_SUBST_ROOT_DIR
# AC_ERLANG_SUBST_LIB_DIR
#locating escript
AC_PATH_PROG([ESCRIPT], [escript], [], [$ERLANG_ROOT_DIR/bin])
#locating make
AC_CHECK_PROG([MAKE], [make], [make], [])
if test "x$ESCRIPT" = "x"; then
AC_MSG_ERROR(['escript' was not found])
fi
if test "x$MAKE" = "x"; then
AC_MSG_ERROR(['make' was not found])
fi
# Change default prefix
AC_PREFIX_DEFAULT(/usr/local)
AC_CONFIG_FILES([Makefile
vars.config])
AC_ARG_ENABLE(all,
[AS_HELP_STRING([--enable-all],[same as --enable-odbc --enable-mssql --enable-mysql --enable-pgsql --enable-sqlite --enable-pam --enable-zlib --enable-redis --enable-elixir --enable-stun --enable-sip --enable-debug --enable-lua --enable-tools (useful for Dialyzer checks, default: no)])],
[case "${enableval}" in
yes) odbc=true mssql=true mysql=true pgsql=true sqlite=true pam=true zlib=true redis=true elixir=true stun=true sip=true debug=true lua=true tools=true ;;
no) odbc=false mssql=false mysql=false pgsql=false sqlite=false pam=false zlib=false redis=false elixir=false stun=false sip=false debug=false lua=false tools=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
esac],[])
AC_ARG_ENABLE(debug,
[AS_HELP_STRING([--enable-debug],[enable debug information (default: yes)])],
[case "${enableval}" in
yes) debug=true ;;
no) debug=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
esac],[if test "x$debug" = "x"; then debug=true; fi])
AC_ARG_ENABLE(elixir,
[AS_HELP_STRING([--enable-elixir],[enable Elixir support in Rebar3 (default: no)])],
[case "${enableval}" in
yes) elixir=true ;;
no) elixir=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-elixir) ;;
esac],[if test "x$elixir" = "x"; then elixir=false; fi])
AC_ARG_ENABLE(erlang-version-check,
[AS_HELP_STRING([--enable-erlang-version-check],[Check Erlang/OTP version (default: yes)])])
case "$enable_erlang_version_check" in
yes|'')
ERLANG_VERSION_CHECK([$REQUIRE_ERLANG_MIN],[$REQUIRE_ERLANG_MAX])
;;
no)
ERLANG_VERSION_CHECK([$REQUIRE_ERLANG_MIN],[$REQUIRE_ERLANG_MAX],[warn])
;;
esac
AC_ARG_ENABLE(full_xml,
[AS_HELP_STRING([--enable-full-xml],[use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])],
[case "${enableval}" in
yes) full_xml=true ;;
no) full_xml=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-full-xml) ;;
esac],[full_xml=false])
ENABLEGROUP=""
AC_ARG_ENABLE(group,
[AS_HELP_STRING([--enable-group[[=GROUP]]], [specify the group of the account defined in --enable-user (default: no)])],
[case "${enableval}" in
yes) ENABLEGROUP=`groups |head -n 1` ;;
no) ENABLEGROUP="" ;;
*) ENABLEGROUP=$enableval
esac],
[])
if test "$ENABLEGROUP" != ""; then
echo "allow this system group to start ejabberd: $ENABLEGROUP"
AC_SUBST([INSTALLGROUP], [$ENABLEGROUP])
fi
AC_ARG_ENABLE(latest_deps,
[AS_HELP_STRING([--enable-latest-deps],[makes rebar use latest commits for dependencies instead of tagged versions (default: no)])],
[case "${enableval}" in
yes) latest_deps=true ;;
no) latest_deps=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-latest-deps) ;;
esac],[if test "x$latest_deps" = "x"; then latest_deps=false; fi])
AC_ARG_ENABLE(lua,
[AS_HELP_STRING([--enable-lua],[enable Lua support, to import from Prosody (default: no)])],
[case "${enableval}" in
yes) lua=true ;;
no) lua=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-lua) ;;
esac],[if test "x$lua" = "x"; then lua=false; fi])
AC_ARG_ENABLE(mssql,
[AS_HELP_STRING([--enable-mssql],[use Microsoft SQL Server database (default: no, requires --enable-odbc)])],
[case "${enableval}" in
yes) mssql=true ;;
no) mssql=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-mssql) ;;
esac],[if test "x$mssql" = "x"; then mssql=false; fi])
AC_ARG_ENABLE(mysql,
[AS_HELP_STRING([--enable-mysql],[enable MySQL support (default: no)])],
[case "${enableval}" in
yes) mysql=true ;;
no) mysql=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-mysql) ;;
esac],[if test "x$mysql" = "x"; then mysql=false; fi])
AC_ARG_ENABLE(new_sql_schema,
[AS_HELP_STRING([--enable-new-sql-schema],[obsolete, use --enable-multihost-sql-schema instead (default: no)])],
[case "${enableval}" in
yes) multihost_sql_schema=true ;;
no) multihost_sql_schema=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-new-sql-schema) ;;
esac],[multihost_sql_schema=false])
AC_ARG_ENABLE(multihost_sql_schema,
[AS_HELP_STRING([--enable-multihost-sql-schema],[use multihost SQL schema by default (default: no)])],
[case "${enableval}" in
yes) multihost_sql_schema=true ;;
no) multihost_sql_schema=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-multihost-sql-schema) ;;
esac],[multihost_sql_schema=false])
AC_ARG_ENABLE(odbc,
[AS_HELP_STRING([--enable-odbc],[enable pure ODBC support (default: no)])],
[case "${enableval}" in
yes) odbc=true ;;
no) odbc=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-odbc) ;;
esac],[if test "x$odbc" = "x"; then odbc=false; fi])
AC_ARG_ENABLE(pam,
[AS_HELP_STRING([--enable-pam],[enable PAM support (default: no)])],
[case "${enableval}" in
yes) pam=true ;;
no) pam=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-pam) ;;
esac],[if test "x$pam" = "x"; then pam=false; fi])
AC_ARG_ENABLE(pgsql,
[AS_HELP_STRING([--enable-pgsql],[enable PostgreSQL support (default: no)])],
[case "${enableval}" in
yes) pgsql=true ;;
no) pgsql=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-pgsql) ;;
esac],[if test "x$pgsql" = "x"; then pgsql=false; fi])
AC_ARG_ENABLE(redis,
[AS_HELP_STRING([--enable-redis],[enable Redis support (default: no)])],
[case "${enableval}" in
yes) redis=true ;;
no) redis=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-redis) ;;
esac],[if test "x$redis" = "x"; then redis=false; fi])
AC_ARG_ENABLE(roster_gateway_workaround,
[AS_HELP_STRING([--enable-roster-gateway-workaround],[turn on workaround for processing gateway subscriptions (default: no)])],
[case "${enableval}" in
yes) roster_gateway_workaround=true ;;
no) roster_gateway_workaround=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-roster-gateway-workaround) ;;
esac],[roster_gateway_workaround=false])
AC_ARG_ENABLE(sip,
[AS_HELP_STRING([--enable-sip],[enable SIP support (default: no)])],
[case "${enableval}" in
yes) sip=true ;;
no) sip=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-sip) ;;
esac],[if test "x$sip" = "x"; then sip=false; fi])
AC_ARG_ENABLE(sqlite,
[AS_HELP_STRING([--enable-sqlite],[enable SQLite support (default: no)])],
[case "${enableval}" in
yes) sqlite=true ;;
no) sqlite=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-sqlite) ;;
esac],[if test "x$sqlite" = "x"; then sqlite=false; fi])
AC_ARG_ENABLE(stun,
[AS_HELP_STRING([--enable-stun],[enable STUN/TURN support (default: yes)])],
[case "${enableval}" in
yes) stun=true ;;
no) stun=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-stun) ;;
esac],[if test "x$stun" = "x"; then stun=true; fi])
AC_ARG_ENABLE(system_deps,
[AS_HELP_STRING([--enable-system-deps],[makes rebar use locally installed dependencies instead of downloading them (default: no)])],
[case "${enableval}" in
yes) system_deps=true ;;
no) system_deps=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-system-deps) ;;
esac],[if test "x$system_deps" = "x"; then system_deps=false; fi])
AC_ARG_ENABLE(tools,
[AS_HELP_STRING([--enable-tools],[include debugging/development tools (default: no)])],
[case "${enableval}" in
yes) tools=true ;;
no) tools=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-tools) ;;
esac],[if test "x$tools" = "x"; then tools=false; fi])
ENABLEUSER=""
AC_ARG_ENABLE(user,
[AS_HELP_STRING([--enable-user[[=USER]]], [allow this system user to start ejabberd (default: no)])],
[case "${enableval}" in
yes) ENABLEUSER=`whoami` ;;
no) ENABLEUSER="" ;;
*) ENABLEUSER=$enableval
esac],
[])
if test "$ENABLEUSER" != ""; then
echo "allow this system user to start ejabberd: $ENABLEUSER"
AC_SUBST([INSTALLUSER], [$ENABLEUSER])
fi
AC_ARG_ENABLE(zlib,
[AS_HELP_STRING([--enable-zlib],[enable Stream Compression (XEP-0138) using zlib (default: yes)])],
[case "${enableval}" in
yes) zlib=true ;;
no) zlib=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-zlib) ;;
esac],[if test "x$zlib" = "x"; then zlib=true; fi])
case "`uname`" in
"Darwin")
# Darwin (macos) erlang-sqlite is built using amalgamated lib, so no external dependency
;;
*)
if test "$sqlite" = "true"; then
AX_LIB_SQLITE3([3.6.19])
if test "x$SQLITE3_VERSION" = "x"; then
AC_MSG_ERROR(SQLite3 library >= 3.6.19 was not found)
fi
fi
;;
esac
AC_MSG_RESULT([build tool to use (change using --with-rebar): $rebar])
AC_SUBST(roster_gateway_workaround)
AC_SUBST(multihost_sql_schema)
AC_SUBST(full_xml)
AC_SUBST(odbc)
AC_SUBST(mssql)
AC_SUBST(mysql)
AC_SUBST(pgsql)
AC_SUBST(sqlite)
AC_SUBST(pam)
AC_SUBST(zlib)
AC_SUBST(rebar)
AC_SUBST(redis)
AC_SUBST(elixir)
AC_SUBST(stun)
AC_SUBST(sip)
AC_SUBST(debug)
AC_SUBST(lua)
AC_SUBST(tools)
AC_SUBST(latest_deps)
AC_SUBST(system_deps)
AC_SUBST(CFLAGS)
AC_SUBST(CPPFLAGS)
AC_SUBST(LDFLAGS)
AC_OUTPUT
AS_CASE([$rebar],
[*rebar3], [
deps=""
AS_IF([test "x$stun" = "xfalse"], [deps="stun,$deps"])
AS_IF([test "x$sqlite" = "xfalse"], [deps="sqlite3,$deps"])
AS_IF([test "x$pgsql" = "xfalse"], [deps="p1_pgsql,$deps"])
AS_IF([test "x$mysql" = "xfalse"], [deps="p1_mysql,$deps"])
AS_IF([test "x$zlib" = "xfalse"], [deps="ezlib,$deps"])
AS_IF([test "x$sip" = "xfalse"], [deps="esip,$deps"])
AS_IF([test "x$redis" = "xfalse"], [deps="eredis,$deps"])
AS_IF([test "x$pam" = "xfalse"], [deps="epam,$deps"])
AS_IF([test "x$deps" = "x"], [],
[AC_MSG_NOTICE([unlocking disabled rebar3 dependencies: $deps])
$rebar unlock "$deps"])
deps=""
ERLANG_VERSION=m4_esyscmd([erl -noinput -noshell -eval 'erlang:display(list_to_integer(erlang:system_info(otp_release))), halt().'])
AS_IF([test "$ERLANG_VERSION" -le "26"], [deps="jose,$deps"])
AS_IF([test "$ERLANG_VERSION" -ge "27"], [deps="jiffy,$deps"])
AS_IF([test "x$deps" = "x"], [],
[AC_MSG_NOTICE([unlocking rebar3 dependencies for old Erlang/OTP: $deps])
$rebar unlock "$deps"])
])
-5
View File
@@ -1,5 +0,0 @@
{level, details}.
{incl_dirs, ["src", "ebin"]}.
{excl_mods, [eldap, 'ELDAPv3']}.
{export, "logs/all.coverdata"}.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

+364
View File
@@ -0,0 +1,364 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD><TITLE>Ejabberd Developers Guide</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=ISO8859-1">
<META name="GENERATOR" content="hevea 1.06">
</HEAD>
<BODY >
<!--HEVEA command line is: /usr/bin/hevea -charset ISO8859-1 dev.tex -->
<!--HTMLHEAD-->
<!--ENDHTML-->
<!--PREFIX <ARG ></ARG>-->
<!--CUT DEF section 1 -->
<H1 ALIGN=center>Ejabberd Developers Guide</H1>
<H3 ALIGN=center>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>
<H3 ALIGN=center>September 10, 2003</H3><DIV ALIGN=center>
<IMG SRC="logo.png">
</DIV><BR>
<BR>
<!--TOC section Table of Contents-->
<H2>Table of Contents</H2><!--SEC END -->
<UL><LI>
<A HREF="#htoc1">1&nbsp;&nbsp;Introduction</A>
<UL><LI>
<A HREF="#htoc2">1.1&nbsp;&nbsp;How it works</A>
<UL><LI>
<A HREF="#htoc3">1.1.1&nbsp;&nbsp;Router</A>
<LI><A HREF="#htoc4">1.1.2&nbsp;&nbsp;Local Router</A>
<LI><A HREF="#htoc5">1.1.3&nbsp;&nbsp;Session Manager</A>
<LI><A HREF="#htoc6">1.1.4&nbsp;&nbsp;S2S Manager</A>
</UL>
</UL>
<LI><A HREF="#htoc7">2&nbsp;&nbsp;XML representation</A>
<LI><A HREF="#htoc8">3&nbsp;&nbsp;Module <TT>xml</TT></A>
<LI><A HREF="#htoc9">4&nbsp;&nbsp;<TT>ejabberd</TT> modules</A>
<UL><LI>
<A HREF="#htoc10">4.1&nbsp;&nbsp;<CODE>gen_mod</CODE> behaviour</A>
<LI><A HREF="#htoc11">4.2&nbsp;&nbsp;Module <CODE>gen_iq_handler</CODE></A>
<LI><A HREF="#htoc12">4.3&nbsp;&nbsp;Services</A>
</UL>
</UL>
<!--TOC section Introduction-->
<H2><A NAME="htoc1">1</A>&nbsp;&nbsp;Introduction</H2><!--SEC END -->
<A NAME="sec:intro"></A>
<TT>ejabberd</TT> is a Free and Open Source fault-tolerant distributed Jabber
server. It is writen mostly in Erlang.<BR>
<BR>
The main features of <TT>ejabberd</TT> is:
<UL><LI>
Works on most of popular platforms: *nix (tested on Linux and FreeBSD)
and Win32
<LI>Distributed: You can run <TT>ejabberd</TT> on a cluster of machines and all of
them will serve one Jabber domain.
<LI>Fault-tolerance: You can setup an <TT>ejabberd</TT> cluster so that all the
information required for a properly working service will be stored
permanently on more than one node. This means that if one of the nodes
crashes, then the others will continue working without disruption.
You can also add or replace more nodes ``on the fly''.
<LI>Built-in <A HREF="http://www.jabber.org/jeps/jep-0045.html">Multi-User
Chat</A> service
<LI>Built-in IRC transport
<LI>Built-in
<A HREF="http://www.jabber.org/jeps/jep-0060.html">Publish-Subscribe</A>
service
<LI>Built-in Jabber Users Directory service based on users vCards
<LI>Support for
<A HREF="http://www.jabber.org/jeps/jep-0030.html">JEP-0030</A>
(Service Discovery).
<LI>Support for
<A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A>
(Statistics Gathering).
<LI>Support for <TT>xml:lang</TT> attribute in many XML elements
</UL>
<!--TOC subsection How it works-->
<H3><A NAME="htoc2">1.1</A>&nbsp;&nbsp;How it works</H3><!--SEC END -->
<A NAME="sec:howitworks"></A>
A Jabber domain is served by one or more <TT>ejabberd</TT> nodes. These nodes can
be run on different machines that are connected via a network. They all must
have the ability to connect to port 4369 of all another nodes, and must have
the same magic cookie (see Erlang/OTP documentation, in other words the file
<TT>~ejabberd/.erlang.cookie</TT> must be the same on all nodes). This is
needed because all nodes exchange information about connected users, S2S
connections, registered services, etc...<BR>
<BR>
Each <TT>ejabberd</TT> node have following modules:
<UL><LI>
router;
<LI>local router.
<LI>session manager;
<LI>S2S manager;
</UL>
<!--TOC subsubsection Router-->
<H4><A NAME="htoc3">1.1.1</A>&nbsp;&nbsp;Router</H4><!--SEC END -->
This module is the main router of Jabber packets on each node. It routes
them based on their destinations domains. It has two tables: local and global
routes. First, domain of packet destination searched in local table, and if it
found, then the packet is routed to appropriate process. If no, then it
searches in global table, and is routed to the appropriate <TT>ejabberd</TT> node or
process. If it does not exists in either tables, then it sent to the S2S
manager.<BR>
<BR>
<!--TOC subsubsection Local Router-->
<H4><A NAME="htoc4">1.1.2</A>&nbsp;&nbsp;Local Router</H4><!--SEC END -->
This module routes packets which have a destination domain equal to this server
name. If destination JID has a non-empty user part, then it routed to the
session manager, else it is processed depending on it's content.<BR>
<BR>
<!--TOC subsubsection Session Manager-->
<H4><A NAME="htoc5">1.1.3</A>&nbsp;&nbsp;Session Manager</H4><!--SEC END -->
This module routes packets to local users. It searches for what user resource
packet must be sended via presence table. If this resource is connected to
this node, it is routed to C2S process, if it connected via another node, then
the packet is sent to session manager on that node.<BR>
<BR>
<!--TOC subsubsection S2S Manager-->
<H4><A NAME="htoc6">1.1.4</A>&nbsp;&nbsp;S2S Manager</H4><!--SEC END -->
This module routes packets to other Jabber servers. First, it checks if an
open S2S connection from the domain of the packet source to the domain of
packet destination already exists. If it is open on another node, then it
routes the packet to S2S manager on that node, if it is open on this node, then
it is routed to the process that serves this connection, and if a connection
does not exist, then it is opened and registered.<BR>
<BR>
<!--TOC section XML representation-->
<H2><A NAME="htoc7">2</A>&nbsp;&nbsp;XML representation</H2><!--SEC END -->
<A NAME="sec:xmlrepr"></A>
Each XML stanza represented as following tuple:
<PRE>
XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
Name = string()
Attrs = [Attr]
Attr = {Key, Val}
Key = string()
Val = string()
ElementOrCDATA = XMLElement | CDATA
CDATA = {xmlcdata, string()}
</PRE>E.&nbsp;g. this stanza:
<PRE>
&lt;message to='test@conference.e.localhost' type='groupchat'&gt;
&lt;body&gt;test&lt;/body&gt;
&lt;/message&gt;
</PRE>represented as following structure:
<PRE>
{xmlelement, "message",
[{"to", "test@conference.e.localhost"},
{"type", "groupchat"}],
[{xmlelement, "body",
[],
[{xmlcdata, "test"}]}]}}
</PRE>
<!--TOC section Module <TT>xml</TT>-->
<H2><A NAME="htoc8">3</A>&nbsp;&nbsp;Module <TT>xml</TT></H2><!--SEC END -->
<A NAME="sec:xmlmod"></A>
<DL COMPACT=compact><DT>
<CODE><B>element_to_string(El) -&gt; string()</B></CODE><DD>
<PRE>
El = XMLElement
</PRE>Returns string representation of XML stanza <TT>El</TT>.<BR>
<BR>
<DT><CODE><B>crypt(S) -&gt; string()</B></CODE><DD>
<PRE>
S = string()
</PRE>Returns string which correspond to <TT>S</TT> with encoded XML special
characters.<BR>
<BR>
<DT><CODE><B>remove_cdata(ECList) -&gt; EList</B></CODE><DD>
<PRE>
ECList = [ElementOrCDATA]
EList = [XMLElement]
</PRE><TT>EList</TT> is a list of all non-CDATA elements of ECList.<BR>
<BR>
<DT><CODE><B>get_path_s(El, Path) -&gt; Res</B></CODE><DD>
<PRE>
El = XMLElement
Path = [PathItem]
PathItem = PathElem | PathAttr | PathCDATA
PathElem = {elem, Name}
PathAttr = {attr, Name}
PathCDATA = cdata
Name = string()
Res = string() | XMLElement
</PRE>If <TT>Path</TT> is empty, then returns <TT>El</TT>. Else sequentially
consider elements of <TT>Path</TT>. Each element is one of:
<DL COMPACT=compact><DT>
<CODE><B>{elem, Name}</B></CODE><DD> <TT>Name</TT> is name of subelement of
<TT>El</TT>, if such element exists, then this element considered in
following steps, else returns empty string.
<DT><CODE><B>{attr, Name}</B></CODE><DD> If <TT>El</TT> have attribute <TT>Name</TT>, then
returns value of this attribute, else returns empty string.
<DT><CODE><B>cdata</B></CODE><DD> Returns CDATA of <TT>El</TT>.
</DL><BR>
<BR>
<DT><B>TODO:</B><DD>
<PRE>
get_cdata/1, get_tag_cdata/1
get_attr/2, get_attr_s/2
get_tag_attr/2, get_tag_attr_s/2
get_subtag/2
</PRE></DL>
<!--TOC section <TT>ejabberd</TT> modules-->
<H2><A NAME="htoc9">4</A>&nbsp;&nbsp;<TT>ejabberd</TT> modules</H2><!--SEC END -->
<A NAME="sec:emods"></A>
<!--TOC subsection <CODE>gen_mod</CODE> behaviour-->
<H3><A NAME="htoc10">4.1</A>&nbsp;&nbsp;<CODE>gen_mod</CODE> behaviour</H3><!--SEC END -->
<A NAME="sec:genmod"></A>
TBD<BR>
<BR>
<!--TOC subsection Module <CODE>gen_iq_handler</CODE>-->
<H3><A NAME="htoc11">4.2</A>&nbsp;&nbsp;Module <CODE>gen_iq_handler</CODE></H3><!--SEC END -->
<A NAME="sec:geniqhandl"></A>
The module <CODE>gen_iq_handler</CODE> allows to easily write handlers for IQ packets
of particular XML namespaces that addressed to server or to users bare JIDs.<BR>
<BR>
In this module the following functions are defined:
<DL COMPACT=compact><DT>
<CODE><B>add_iq_handler(Component, NS, Module, Function, Type)</B></CODE><DD>
<PRE>
Component = Module = Function = atom()
NS = string()
Type = no_queue | one_queue | parallel
</PRE>Registers function <CODE>Module:Function</CODE> as handler for IQ packets that
contain child of namespace <CODE>NS</CODE> in <CODE>Component</CODE>. Queueing
discipline is <CODE>Type</CODE>. There are at least two components defined:
<DL COMPACT=compact><DT>
<CODE><B>ejabberd_local</B></CODE><DD> Handles packets that addressed to server JID;
<DT><CODE><B>ejabberd_sm</B></CODE><DD> Handles packets that addressed to users bare JIDs.
</DL>
<DT><CODE><B>remove_iq_handler(Component, NS)</B></CODE><DD>
<PRE>
Component = atom()
NS = string()
</PRE>Removes IQ handler for namespace <CODE>NS</CODE> from <CODE>Component</CODE>.
</DL>
Handler function must have the following type:
<DL COMPACT=compact><DT>
<CODE><B>Module:Function(From, To, IQ)</B></CODE><DD>
<PRE>
From = To = jid()
</PRE></DL>
<PRE>
-module(mod_cputime).
-behaviour(gen_mod).
-export([start/1,
stop/0,
process_local_iq/3]).
-include("ejabberd.hrl").
-include("jlib.hrl").
-define(NS_CPUTIME, "ejabberd:cputime").
start(Opts) -&gt;
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_CPUTIME,
?MODULE, process_local_iq, IQDisc).
stop() -&gt;
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_CPUTIME).
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -&gt;
case Type of
set -&gt;
{iq, ID, error, XMLNS,
[SubEl, ?ERR_NOT_ALLOWED]};
get -&gt;
CPUTime = element(1, erlang:statistics(runtime))/1000,
SCPUTime = lists:flatten(io_lib:format("~.3f", CPUTime)),
{iq, ID, result, XMLNS,
[{xmlelement, "query",
[{"xmlns", ?NS_CPUTIME}],
[{xmlelement, "cputime", [], [{xmlcdata, SCPUTime}]}]}]}
end.
</PRE>
<!--TOC subsection Services-->
<H3><A NAME="htoc12">4.3</A>&nbsp;&nbsp;Services</H3><!--SEC END -->
<A NAME="sec:services"></A>
TBD<BR>
<BR>
TODO: use <CODE>proc_lib</CODE>
<PRE>
-module(mod_echo).
-behaviour(gen_mod).
-export([start/1, init/1, stop/0]).
-include("ejabberd.hrl").
-include("jlib.hrl").
start(Opts) -&gt;
Host = gen_mod:get_opt(host, Opts, "echo." ++ ?MYNAME),
register(ejabberd_mod_echo, spawn(?MODULE, init, [Host])).
init(Host) -&gt;
ejabberd_router:register_local_route(Host),
loop(Host).
loop(Host) -&gt;
receive
{route, From, To, Packet} -&gt;
ejabberd_router:route(To, From, Packet),
loop(Host);
stop -&gt;
ejabberd_router:unregister_local_route(Host),
ok;
_ -&gt;
loop(Host)
end.
stop() -&gt;
ejabberd_mod_echo ! stop,
ok.
</PRE>
<!--HTMLFOOT-->
<!--ENDHTML-->
<!--FOOTER-->
<HR SIZE=2>
<BLOCKQUOTE><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>
+378
View File
@@ -0,0 +1,378 @@
\documentclass[10pt]{article}
\usepackage{graphics}
\usepackage{hevea}
\usepackage{verbatim}
\newcommand{\logoscale}{0.7}
\newcommand{\imgscale}{0.58}
\newcommand{\insimg}[1]{\insscaleimg{\imgscale}{#1}}
\newcommand{\insscaleimg}[2]{
\imgsrc{#2}{}
\begin{latexonly}
\scalebox{#1}{\includegraphics{#2}}
\end{latexonly}
}
\newcommand{\ns}[1]{\texttt{#1}}
\newcommand{\ejabberd}{\texttt{ejabberd}}
\newcommand{\Jabber}{Jabber}
\newcommand{\modregister}{\texttt{mod\_register}}
\newcommand{\modroster}{\texttt{mod\_roster}}
\newcommand{\modconfigure}{\texttt{mod\_configure}}
\newcommand{\moddisco}{\texttt{mod\_disco}}
\newcommand{\modstats}{\texttt{mod\_stats}}
\newcommand{\modvcard}{\texttt{mod\_vcard}}
\newcommand{\modoffline}{\texttt{mod\_offline}}
\newcommand{\modecho}{\texttt{mod\_echo}}
\newcommand{\modprivate}{\texttt{mod\_private}}
\newcommand{\modtime}{\texttt{mod\_time}}
\newcommand{\modversion}{\texttt{mod\_version}}
c
%\setcounter{tocdepth}{3}
\title{Ejabberd Developers Guide}
\author{Alexey Shchepin \\
\ahrefurl{mailto:alexey@sevcom.net} \\
\ahrefurl{xmpp:aleksey@jabber.ru}}
\date{September 10, 2003}
\begin{document}
\begin{titlepage}
\maketitle{}
{\centering
\insscaleimg{\logoscale}{logo.png}
\par
}
\end{titlepage}
%\newpage
\tableofcontents{}
\newpage
\section{Introduction}
\label{sec:intro}
\ejabberd{} is a Free and Open Source fault-tolerant distributed \Jabber{}
server. It is writen mostly in Erlang.
The main features of \ejabberd{} is:
\begin{itemize}
\item Works on most of popular platforms: *nix (tested on Linux and FreeBSD)
and Win32
\item Distributed: You can run \ejabberd{} on a cluster of machines and all of
them will serve one Jabber domain.
\item Fault-tolerance: You can setup an \ejabberd{} cluster so that all the
information required for a properly working service will be stored
permanently on more than one node. This means that if one of the nodes
crashes, then the others will continue working without disruption.
You can also add or replace more nodes ``on the fly''.
\item Built-in \footahref{http://www.jabber.org/jeps/jep-0045.html}{Multi-User
Chat} service
\item Built-in IRC transport
\item Built-in
\footahref{http://www.jabber.org/jeps/jep-0060.html}{Publish-Subscribe}
service
\item Built-in Jabber Users Directory service based on users vCards
\item Support for
\footahref{http://www.jabber.org/jeps/jep-0030.html}{JEP-0030}
(Service Discovery).
\item Support for
\footahref{http://www.jabber.org/jeps/jep-0039.html}{JEP-0039}
(Statistics Gathering).
\item Support for \ns{xml:lang} attribute in many XML elements
\end{itemize}
\subsection{How it works}
\label{sec:howitworks}
A \Jabber{} domain is served by one or more \ejabberd{} nodes. These nodes can
be run on different machines that are connected via a network. They all must
have the ability to connect to port 4369 of all another nodes, and must have
the same magic cookie (see Erlang/OTP documentation, in other words the file
\texttt{\~{}ejabberd/.erlang.cookie} must be the same on all nodes). This is
needed because all nodes exchange information about connected users, S2S
connections, registered services, etc\ldots
Each \ejabberd{} node have following modules:
\begin{itemize}
\item router;
\item local router.
\item session manager;
\item S2S manager;
\end{itemize}
\subsubsection{Router}
This module is the main router of \Jabber{} packets on each node. It routes
them based on their destinations domains. It has two tables: local and global
routes. First, domain of packet destination searched in local table, and if it
found, then the packet is routed to appropriate process. If no, then it
searches in global table, and is routed to the appropriate \ejabberd{} node or
process. If it does not exists in either tables, then it sent to the S2S
manager.
\subsubsection{Local Router}
This module routes packets which have a destination domain equal to this server
name. If destination JID has a non-empty user part, then it routed to the
session manager, else it is processed depending on it's content.
\subsubsection{Session Manager}
This module routes packets to local users. It searches for what user resource
packet must be sended via presence table. If this resource is connected to
this node, it is routed to C2S process, if it connected via another node, then
the packet is sent to session manager on that node.
\subsubsection{S2S Manager}
This module routes packets to other \Jabber{} servers. First, it checks if an
open S2S connection from the domain of the packet source to the domain of
packet destination already exists. If it is open on another node, then it
routes the packet to S2S manager on that node, if it is open on this node, then
it is routed to the process that serves this connection, and if a connection
does not exist, then it is opened and registered.
\section{XML representation}
\label{sec:xmlrepr}
Each XML stanza represented as following tuple:
\begin{verbatim}
XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
Name = string()
Attrs = [Attr]
Attr = {Key, Val}
Key = string()
Val = string()
ElementOrCDATA = XMLElement | CDATA
CDATA = {xmlcdata, string()}
\end{verbatim}
E.\,g. this stanza:
\begin{verbatim}
<message to='test@conference.e.localhost' type='groupchat'>
<body>test</body>
</message>
\end{verbatim}
represented as following structure:
\begin{verbatim}
{xmlelement, "message",
[{"to", "test@conference.e.localhost"},
{"type", "groupchat"}],
[{xmlelement, "body",
[],
[{xmlcdata, "test"}]}]}}
\end{verbatim}
\section{Module \texttt{xml}}
\label{sec:xmlmod}
\begin{description}
\item[\verb|element_to_string(El) -> string()|]
\begin{verbatim}
El = XMLElement
\end{verbatim}
Returns string representation of XML stanza \texttt{El}.
\item[\verb|crypt(S) -> string()|]
\begin{verbatim}
S = string()
\end{verbatim}
Returns string which correspond to \texttt{S} with encoded XML special
characters.
\item[\verb|remove_cdata(ECList) -> EList|]
\begin{verbatim}
ECList = [ElementOrCDATA]
EList = [XMLElement]
\end{verbatim}
\texttt{EList} is a list of all non-CDATA elements of ECList.
\item[\verb|get_path_s(El, Path) -> Res|]
\begin{verbatim}
El = XMLElement
Path = [PathItem]
PathItem = PathElem | PathAttr | PathCDATA
PathElem = {elem, Name}
PathAttr = {attr, Name}
PathCDATA = cdata
Name = string()
Res = string() | XMLElement
\end{verbatim}
If \texttt{Path} is empty, then returns \texttt{El}. Else sequentially
consider elements of \texttt{Path}. Each element is one of:
\begin{description}
\item[\verb|{elem, Name}|] \texttt{Name} is name of subelement of
\texttt{El}, if such element exists, then this element considered in
following steps, else returns empty string.
\item[\verb|{attr, Name}|] If \texttt{El} have attribute \texttt{Name}, then
returns value of this attribute, else returns empty string.
\item[\verb|cdata|] Returns CDATA of \texttt{El}.
\end{description}
\item[TODO:]
\begin{verbatim}
get_cdata/1, get_tag_cdata/1
get_attr/2, get_attr_s/2
get_tag_attr/2, get_tag_attr_s/2
get_subtag/2
\end{verbatim}
\end{description}
\section{\ejabberd{} modules}
\label{sec:emods}
\subsection{\verb|gen_mod| behaviour}
\label{sec:genmod}
TBD
\subsection{Module \verb|gen_iq_handler|}
\label{sec:geniqhandl}
The module \verb|gen_iq_handler| allows to easily write handlers for IQ packets
of particular XML namespaces that addressed to server or to users bare JIDs.
In this module the following functions are defined:
\begin{description}
\item[\verb|add_iq_handler(Component, NS, Module, Function, Type)|]
\begin{verbatim}
Component = Module = Function = atom()
NS = string()
Type = no_queue | one_queue | parallel
\end{verbatim}
Registers function \verb|Module:Function| as handler for IQ packets that
contain child of namespace \verb|NS| in \verb|Component|. Queueing
discipline is \verb|Type|. There are at least two components defined:
\begin{description}
\item[\verb|ejabberd_local|] Handles packets that addressed to server JID;
\item[\verb|ejabberd_sm|] Handles packets that addressed to users bare JIDs.
\end{description}
\item[\verb|remove_iq_handler(Component, NS)|]
\begin{verbatim}
Component = atom()
NS = string()
\end{verbatim}
Removes IQ handler for namespace \verb|NS| from \verb|Component|.
\end{description}
Handler function must have the following type:
\begin{description}
\item[\verb|Module:Function(From, To, IQ)|]
\begin{verbatim}
From = To = jid()
\end{verbatim}
\end{description}
\begin{verbatim}
-module(mod_cputime).
-behaviour(gen_mod).
-export([start/1,
stop/0,
process_local_iq/3]).
-include("ejabberd.hrl").
-include("jlib.hrl").
-define(NS_CPUTIME, "ejabberd:cputime").
start(Opts) ->
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_CPUTIME,
?MODULE, process_local_iq, IQDisc).
stop() ->
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_CPUTIME).
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
case Type of
set ->
{iq, ID, error, XMLNS,
[SubEl, ?ERR_NOT_ALLOWED]};
get ->
CPUTime = element(1, erlang:statistics(runtime))/1000,
SCPUTime = lists:flatten(io_lib:format("~.3f", CPUTime)),
{iq, ID, result, XMLNS,
[{xmlelement, "query",
[{"xmlns", ?NS_CPUTIME}],
[{xmlelement, "cputime", [], [{xmlcdata, SCPUTime}]}]}]}
end.
\end{verbatim}
\subsection{Services}
\label{sec:services}
TBD
TODO: use \verb|proc_lib|
\begin{verbatim}
-module(mod_echo).
-behaviour(gen_mod).
-export([start/1, init/1, stop/0]).
-include("ejabberd.hrl").
-include("jlib.hrl").
start(Opts) ->
Host = gen_mod:get_opt(host, Opts, "echo." ++ ?MYNAME),
register(ejabberd_mod_echo, spawn(?MODULE, init, [Host])).
init(Host) ->
ejabberd_router:register_local_route(Host),
loop(Host).
loop(Host) ->
receive
{route, From, To, Packet} ->
ejabberd_router:route(To, From, Packet),
loop(Host);
stop ->
ejabberd_router:unregister_local_route(Host),
ok;
_ ->
loop(Host)
end.
stop() ->
ejabberd_mod_echo ! stop,
ok.
\end{verbatim}
\end{document}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

+105
View File
@@ -0,0 +1,105 @@
digraph messages {
//concentrate=true;
subgraph clusterclients {
client1 [shape = box];
client2 [shape = box];
client3 [shape = box];
style = dashed;
label = "Clients";
}
subgraph clusternode1 {
subgraph clusterc2s1 {
c2s11;
c2s12;
style = invis;
}
subgraph clusterservices1 {
service11;
service12;
service13;
style = invis;
}
//subgraph clusters2s1 {
//s2s11;
//s2s12;
//style = invis;
//}
c2s11 -> auth1;
c2s12 -> auth1;
auth1 -> c2s11;
auth1 -> c2s12;
c2s11 -> sm1;
c2s11 -> router1;
c2s12 -> sm1;
c2s12 -> router1;
router1 -> local1;
router1 -> service11;
router1 -> service12;
router1 -> service13;
router1 -> s2s11;
router1 -> s2s12;
service11 -> router1;
service12 -> router1;
service13 -> router1;
s2s11 -> router1;
s2s12 -> router1;
local1 -> sm1;
sm1 -> c2s11;
sm1 -> c2s12;
style = dashed;
label = "Node1";
}
subgraph clusternode2 {
c2s2 -> auth2;
auth2 -> c2s2;
c2s2 -> sm2;
c2s2 -> router2;
router2 -> local2;
router2 -> service21;
router2 -> s2s21;
service21 -> router2;
s2s21 -> router2;
local2 -> sm2;
sm2 -> c2s2;
style = dashed;
label = "Node2";
}
subgraph clusterservers {
server1 [shape = box];
server2 [shape = box];
server3 [shape = box];
style = dashed;
label = "Servers";
}
client1 -> c2s11;
client2 -> c2s12;
client3 -> c2s2;
c2s11 -> client1 [constraint=false];
c2s12 -> client2 [constraint=false];
c2s2 -> client3 [constraint=false];
s2s11 -> server1 [minlen = 2];
s2s12 -> server2 [minlen = 2];
s2s21 -> server3 [minlen = 2];
server1 -> s2s11 [constraint=false];
server2 -> s2s12 [constraint=false];
server3 -> s2s21 [constraint=false];
router1 -> router2;
router2 -> router1;
sm1 -> sm2;
sm2 -> sm1;
label = "Data Flows";
}
+1354
View File
File diff suppressed because it is too large Load Diff
+1316
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

+88
View File
@@ -0,0 +1,88 @@
Release notes
ejabberd 0.9
This document describes the major new features of and changes to
ejabberd 0.9, compared to latest public release ejabber 0.7.5.
For more detailed information, please refer to ejabberd User
Guide.
Virtual Hosting
ejabberd now can host several domain on the same instance.
This option is enabled by using:
{hosts, ["erlang-projects.org", "erlang-fr.org"]}.
instead of the previous host directive.
Note that you are now using a list of hosts. The main one should
be the first listed. See migration section further in this release
note for details.
Shared Roster
Shared roster is a new feature that allow the ejabberd
administrator to add jabber user that will be present in the
roster of every users on the server.
Shared roster are enabled by adding:
{mod_shared_roster, []}
at the end of your module list in your ejabberd.cfg file.
PostgreSQL (ODBC) support
This feature is experimental and not yet properly documented. This
feature is released for testing purpose.
You need to have Erlang/OTP R10 to compile with ODBC on various
flavour of *nix. You should use Erlang/OTP R10B-4, as this task
has became easier with this release. It comes already build in
Erlang/OTP Microsoft Windows binary.
PostgreSQL support is enabled by using the following module in
ejabberd.cfg instead of their standard counterpart:
mod_last_odbc.erl
mod_offline_odbc.erl
mod_roster_odbc.erl
The database schema is located in the src/odbc/pq.sql file.
Look at the src/ejabberd.cfg.example file for more information on
how to configure ejabberd with odbc support. You can get support
on how to configure ejabberd with a relational database.
Migration from ejabberd 0.7.5
Migration is pretty straightforward as Mnesia database schema
conversions is handled automatically. Remember however that you
must backup your ejabberd database before migration.
Here are the following steps to proceed:
1. Stop your instance of ejabberd.
2. In ejabberd.cfg, define the host lists. Change the host
directive to the hosts one:
Before:
{host, "erlang-projects.org"}.
After:
{hosts, ["erlang-projects.org", "erlang-fr.org"]}.
Note that when you restart the server the existing users will be
affected to the first virtual host, so the order is important. You
should keep the previous hostname as the first virtual host.
3. Restart ejabberd.
Bugfixes
This release contains several bugfixes and architectural changes.
Please refer to the Changelog file supplied with this release for
details of all improvements in the ejabberd code.
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

-876
View File
@@ -1,876 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://usefulinc.com/ns/doap#"
xmlns:xmpp="https://linkmauve.fr/ns/xmpp-doap#"
xmlns:schema="https://schema.org/">
<Project>
<name>ejabberd</name>
<shortdesc>XMPP Server with MQTT Broker and SIP Service</shortdesc>
<description>Robust, Ubiquitous and Massively Scalable Messaging Platform (XMPP Server, MQTT Broker, SIP Service)</description>
<created>2002-11-16</created>
<os>BSD</os>
<os>Linux</os>
<os>macOS</os>
<os>Windows</os>
<programming-langauge>Erlang</programming-langauge>
<programming-langauge>C</programming-langauge>
<category rdf:resource="https://linkmauve.fr/ns/xmpp-doap#category-jabber"/>
<category rdf:resource="https://linkmauve.fr/ns/xmpp-doap#category-server"/>
<category rdf:resource="https://linkmauve.fr/ns/xmpp-doap#category-xmpp"/>
<homepage rdf:resource="https://www.ejabberd.im"/>
<download-page rdf:resource="https://www.process-one.net/download/ejabberd/"/>
<download-mirror rdf:resource="https://github.com/processone/ejabberd/tags"/>
<license rdf:resource="https://raw.githubusercontent.com/processone/ejabberd/master/COPYING"/>
<schema:logo rdf:resource="https://docs.ejabberd.im/assets/img/footer_logo_e@2x.png"/>
<bug-database rdf:resource="https://github.com/processone/ejabberd/issues"/>
<support-forum rdf:resource="xmpp:ejabberd@conference.process-one.net?join"/>
<repository>
<GitRepository>
<location rdf:resource="https://github.com/processone/ejabberd.git"/>
<browse rdf:resource="https://github.com/processone/ejabberd"/>
</GitRepository>
</repository>
<implements rdf:resource="https://www.rfc-editor.org/info/rfc3261"/>
<implements rdf:resource="https://www.rfc-editor.org/info/rfc3920"/>
<implements rdf:resource="https://www.rfc-editor.org/info/rfc3921"/>
<implements rdf:resource="https://www.rfc-editor.org/info/rfc5766"/>
<implements rdf:resource="https://www.rfc-editor.org/info/rfc5802"/>
<implements rdf:resource="https://www.rfc-editor.org/info/rfc6120"/>
<implements rdf:resource="https://www.rfc-editor.org/info/rfc6121"/>
<implements rdf:resource="https://www.rfc-editor.org/info/rfc6122"/>
<implements rdf:resource="https://www.rfc-editor.org/info/rfc6455"/>
<implements rdf:resource="https://www.rfc-editor.org/info/rfc7395"/>
<implements rdf:resource="https://www.rfc-editor.org/info/rfc7590"/>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0004.html"/>
<xmpp:version>2.13.2</xmpp:version>
<xmpp:since>0.5.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note></xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0012.html"/>
<xmpp:version>2.0</xmpp:version>
<xmpp:since>0.5.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_last</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0013.html"/>
<xmpp:version>1.3</xmpp:version>
<xmpp:since>16.02</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_offline</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0016.html"/>
<xmpp:version>1.7</xmpp:version>
<xmpp:since>0.5.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_privacy</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0022.html"/>
<xmpp:version>1.4</xmpp:version>
<xmpp:since>0.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_offline</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0023.html"/>
<xmpp:version>1.3</xmpp:version>
<xmpp:since>0.7.5</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_offline</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0030.html"/>
<xmpp:version>2.5.0</xmpp:version>
<xmpp:since>0.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_disco</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0033.html"/>
<xmpp:version>1.1</xmpp:version>
<xmpp:since>15.04</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_multicast</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0039.html"/>
<xmpp:version>0.6.0</xmpp:version>
<xmpp:since>0.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_stats</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0045.html"/>
<xmpp:version>1.35.3</xmpp:version>
<xmpp:since>0.5.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_muc</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0048.html"/>
<xmpp:version>1.2</xmpp:version>
<xmpp:since>0.5.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_pubsub</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0049.html"/>
<xmpp:version>1.2</xmpp:version>
<xmpp:since>0.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_private</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0050.html"/>
<xmpp:version>1.3.0</xmpp:version>
<xmpp:since>1.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_adhoc</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0054.html"/>
<xmpp:version>1.3.0</xmpp:version>
<xmpp:since>0.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_vcard</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0055.html"/>
<xmpp:version>1.3</xmpp:version>
<xmpp:since>0.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_vcard</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0059.html"/>
<xmpp:version>1.0</xmpp:version>
<xmpp:since>2.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note></xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0060.html"/>
<xmpp:version>1.14</xmpp:version>
<xmpp:since>0.5.0</xmpp:since>
<xmpp:status>partial</xmpp:status>
<xmpp:note>mod_pubsub</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0065.html"/>
<xmpp:version>1.8.2</xmpp:version>
<xmpp:since>2.0.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_proxy65</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0077.html"/>
<xmpp:version>2.4</xmpp:version>
<xmpp:since>0.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_register</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0078.html"/>
<xmpp:version>2.5</xmpp:version>
<xmpp:since>17.03</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_legacy_auth</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0082.html"/>
<xmpp:version>1.1.1</xmpp:version>
<xmpp:since>2.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note></xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0085.html"/>
<xmpp:version>2.1</xmpp:version>
<xmpp:since>2.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_client_state</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0086.html"/>
<xmpp:version>1.0</xmpp:version>
<xmpp:since>0.5.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note></xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0092.html"/>
<xmpp:version>1.1</xmpp:version>
<xmpp:since>0.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_version</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0106.html"/>
<xmpp:version>1.1.1</xmpp:version>
<xmpp:since>0.5.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note></xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0114.html"/>
<xmpp:version>1.6</xmpp:version>
<xmpp:since>0.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>ejabberd_service</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0115.html"/>
<xmpp:version>1.6.0</xmpp:version>
<xmpp:since>2.1.4</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_caps</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0124.html"/>
<xmpp:version>1.11.2</xmpp:version>
<xmpp:since>16.12</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>ejabberd_bosh</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0133.html"/>
<xmpp:version>1.3.1</xmpp:version>
<xmpp:since>13.10</xmpp:since>
<xmpp:status>partial</xmpp:status>
<xmpp:note>mod_configure</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0138.html"/>
<xmpp:version>2.1</xmpp:version>
<xmpp:since>1.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>ejabberd_c2s</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0153.html"/>
<xmpp:version>1.1.1</xmpp:version>
<xmpp:since>17.09</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_vcard</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0156.html"/>
<xmpp:version>1.4.0</xmpp:version>
<xmpp:since>22.05</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_host_meta</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0157.html"/>
<xmpp:version>1.1.1</xmpp:version>
<xmpp:since>2.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_disco</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0158.html"/>
<xmpp:version>1.0.1</xmpp:version>
<xmpp:since>2.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>ejabberd_captcha</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0160.html"/>
<xmpp:version>1.0.1</xmpp:version>
<xmpp:since>16.01</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_offline</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0163.html"/>
<xmpp:version>1.2.2</xmpp:version>
<xmpp:since>2.0.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_pubsub</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0170.html"/>
<xmpp:version>1.0</xmpp:version>
<xmpp:since>17.12</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note></xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0175.html"/>
<xmpp:version>1.2</xmpp:version>
<xmpp:since>1.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>ejabberd_auth_anonymous</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0178.html"/>
<xmpp:version>1.2</xmpp:version>
<xmpp:since>17.03</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note></xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0185.html"/>
<xmpp:version>1.0</xmpp:version>
<xmpp:since>17.03</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_s2s_dialback</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0191.html"/>
<xmpp:version>1.3</xmpp:version>
<xmpp:since>2.1.7</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_blocking</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0198.html"/>
<xmpp:version>1.5.2</xmpp:version>
<xmpp:since>14.05</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_stream_mgmt</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0199.html"/>
<xmpp:version>2.0.1</xmpp:version>
<xmpp:since>2.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_ping</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0202.html"/>
<xmpp:version>2.0</xmpp:version>
<xmpp:since>2.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_time</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0203.html"/>
<xmpp:version>2.0</xmpp:version>
<xmpp:since>2.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_offline</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0205.html"/>
<xmpp:version>1.0.2</xmpp:version>
<xmpp:since>1.1.2</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note></xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0206.html"/>
<xmpp:version>1.4</xmpp:version>
<xmpp:since>16.12</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>ejabberd_bosh</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0215.html"/>
<xmpp:version>1.0.0</xmpp:version>
<xmpp:since>20.04</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_stun_disco</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0220.html"/>
<xmpp:version>1.1.1</xmpp:version>
<xmpp:since>17.03</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_s2s_dialback</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0223.html"/>
<xmpp:version>1.1.1</xmpp:version>
<xmpp:since>2.0.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_pubsub</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0227.html"/>
<xmpp:version>1.1</xmpp:version>
<xmpp:since>2.1.0</xmpp:since>
<xmpp:status>partial</xmpp:status>
<xmpp:note>ejabberd_piefxis</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0231.html"/>
<xmpp:version>1.1</xmpp:version>
<xmpp:since>2.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>ejabberd_captcha</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0237.html"/>
<xmpp:version>1.3</xmpp:version>
<xmpp:since>2.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_roster</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0248.html"/>
<xmpp:version>0.2</xmpp:version>
<xmpp:since>2.1.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_pubsub</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0249.html"/>
<xmpp:version>1.2</xmpp:version>
<xmpp:since>0.5.0</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_muc</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0279.html"/>
<xmpp:version>0.2</xmpp:version>
<xmpp:since>2.1.3</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_sic</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0280.html"/>
<xmpp:version>1.0.1</xmpp:version>
<xmpp:since>13.06</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_carboncopy</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0288.html"/>
<xmpp:version>1.0.1</xmpp:version>
<xmpp:since>24.10</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_s2s_bidi</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0313.html"/>
<xmpp:version>0.6.1</xmpp:version>
<xmpp:since>15.06</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_mam</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0317.html"/>
<xmpp:version>0.3.1</xmpp:version>
<xmpp:since>21.12</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_muc_room, 0.3.1 since 25.10</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0328.html"/>
<xmpp:version>0.1</xmpp:version>
<xmpp:since>19.09</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_jidprep</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0334.html"/>
<xmpp:version>1.0.0</xmpp:version>
<xmpp:since>16.01</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_mam, mod_muc_log, mod_offline</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0352.html"/>
<xmpp:version>0.1</xmpp:version>
<xmpp:since>14.12</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_client_state</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0355.html"/>
<xmpp:version>0.4.1</xmpp:version>
<xmpp:since>16.09</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_delegation</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0356.html"/>
<xmpp:version>0.4.1</xmpp:version>
<xmpp:since>24.10</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_privilege</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0357.html"/>
<xmpp:version>0.4.1</xmpp:version>
<xmpp:since>17.08</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_push</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0359.html"/>
<xmpp:version>0.7.0</xmpp:version>
<xmpp:since>15.09</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_mam</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0363.html"/>
<xmpp:version>0.3.0</xmpp:version>
<xmpp:since>15.10</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_http_upload</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0368.html"/>
<xmpp:version>1.1.0</xmpp:version>
<xmpp:since>17.09</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note></xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0369.html"/>
<xmpp:version>0.14.1</xmpp:version>
<xmpp:since>16.03</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_mix</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0379.html"/>
<xmpp:version>0.3.3</xmpp:version>
<xmpp:since>26.01</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_invites</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0384.html"/>
<xmpp:version>0.9.0</xmpp:version>
<xmpp:since>21.12</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>node_pep</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0386.html"/>
<xmpp:version>0.3.0</xmpp:version>
<xmpp:since>24.02</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note></xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0388.html"/>
<xmpp:version>1.0.4</xmpp:version>
<xmpp:since>24.02</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note></xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0398.html"/>
<xmpp:version>1.0.0</xmpp:version>
<xmpp:since>18.03</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_avatar</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0401.html"/>
<xmpp:version>0.5.0</xmpp:version>
<xmpp:since>26.01</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_invites</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0402.html"/>
<xmpp:version>1.2.0</xmpp:version>
<xmpp:since>23.10</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_private</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0405.html"/>
<xmpp:version>0.3.0</xmpp:version>
<xmpp:since>19.02</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_mix_pam</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0410.html"/>
<xmpp:version>1.1.0</xmpp:version>
<xmpp:since>18.12</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_muc_room</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0411.html"/>
<xmpp:version>1.1.0</xmpp:version>
<xmpp:since>18.12</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_private</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0421.html"/>
<xmpp:version>1.0.1</xmpp:version>
<xmpp:since>23.10</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_muc</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0424.html"/>
<xmpp:version>0.4.2</xmpp:version>
<xmpp:since>24.02</xmpp:since>
<xmpp:status>partial</xmpp:status>
<xmpp:note>mod_mam, Tombstones not implemented</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0425.html"/>
<xmpp:version>0.3.0</xmpp:version>
<xmpp:since>24.06</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_mam</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0431.html"/>
<xmpp:version>0.2.0</xmpp:version>
<xmpp:since>24.12</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_mam</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0440.html"/>
<xmpp:version>1.0.0</xmpp:version>
<xmpp:since>24.02</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note></xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0441.html"/>
<xmpp:version>0.2.0</xmpp:version>
<xmpp:since>15.06</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_mam</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0445.html"/>
<xmpp:version>0.2.0</xmpp:version>
<xmpp:since>26.01</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_invites</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0474.html"/>
<xmpp:version>0.5.0</xmpp:version>
<xmpp:since>24.02</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>, 0.4.0 since 25.03</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0480.html"/>
<xmpp:version>0.2.0</xmpp:version>
<xmpp:since>24.10</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_scram_upgrade</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0484.html"/>
<xmpp:version>0.2.0</xmpp:version>
<xmpp:since>24.12</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_auth_fast</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0485.html"/>
<xmpp:version>1.0.0</xmpp:version>
<xmpp:since>25.07</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_pubsub_serverinfo</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0486.html"/>
<xmpp:version>0.1.0</xmpp:version>
<xmpp:since>24.07</xmpp:since>
<xmpp:status>complete</xmpp:status>
<xmpp:note>mod_muc</xmpp:note>
</xmpp:SupportedXep>
</implements>
</Project>
</rdf:RDF>
-63
View File
@@ -1,63 +0,0 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: ejabberd
# Required-Start: $remote_fs $network $named $time
# Required-Stop: $remote_fs $network $named $time
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts ejabberd XMPP server
# Description: Starts ejabberd XMPP server, an XMPP
# compliant server written in Erlang.
### END INIT INFO
# chkconfig: 2345 90 10
# description: ejabberd XMPP server
set -o errexit
DIR=@ctlscriptpath@
CTL="$DIR"/ejabberdctl
USER=@installuser@
test -x "$CTL" || {
echo "ERROR: ejabberd not found: $DIR"
exit 1
}
getent passwd "$USER" >/dev/null || {
echo "ERROR: System user not found: $USER"
exit 2
}
export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
case "$1" in
start)
test -x "$CTL" || exit 0
echo "Starting ejabberd..."
su - $USER -c "$CTL start"
su - $USER -c "$CTL started"
echo "done."
;;
stop)
test -x "$CTL" || exit 0
echo "Stopping ejabberd..."
su - $USER -c "$CTL stop"
su - $USER -c "$CTL stopped"
echo "done."
;;
status)
test -x "$CTL" || exit 0
echo "Getting ejabberd status..."
su - $USER -c "$CTL status"
;;
force-reload|restart)
"$0" stop
"$0" start
;;
*)
echo "Usage: $0 {start|stop|restart|force-reload|status}"
exit 1
esac
exit 0
-21
View File
@@ -1,21 +0,0 @@
[Unit]
Description=XMPP Server
After=network.target
[Service]
Type=notify
User=@installuser@
Group=@installuser@
LimitNOFILE=65536
Restart=on-failure
RestartSec=5
ExecStart=@ctlscriptpath@/ejabberdctl foreground
ExecStop=/bin/sh -c '@ctlscriptpath@/ejabberdctl stop && @ctlscriptpath@/ejabberdctl stopped'
ExecReload=@ctlscriptpath@/ejabberdctl reload_config
NotifyAccess=all
PrivateDevices=true
AmbientCapabilities=CAP_NET_BIND_SERVICE
TimeoutSec=300
[Install]
WantedBy=multi-user.target
-250
View File
@@ -1,250 +0,0 @@
###
### ejabberd configuration file
###
### The parameters used in this configuration file are explained at
###
### https://docs.ejabberd.im/admin/configuration
###
### The configuration file is written in YAML.
### *******************************************************
### ******* !!! WARNING !!! *******
### ******* YAML IS INDENTATION SENSITIVE *******
### ******* MAKE SURE YOU INDENT SECTIONS CORRECTLY *******
### *******************************************************
### Refer to http://en.wikipedia.org/wiki/YAML for the brief description.
###
hosts:
- localhost
loglevel: info
## If you already have certificates, list them here
# certfiles:
# - /etc/letsencrypt/live/domain.tld/fullchain.pem
# - /etc/letsencrypt/live/domain.tld/privkey.pem
listen:
-
port: 5222
ip: "::"
module: ejabberd_c2s
max_stanza_size: 262144
shaper: c2s_shaper
access: c2s
starttls_required: true
-
port: 5223
ip: "::"
module: ejabberd_c2s
max_stanza_size: 262144
shaper: c2s_shaper
access: c2s
tls: true
-
port: 5269
ip: "::"
module: ejabberd_s2s_in
max_stanza_size: 524288
shaper: s2s_shaper
-
port: 5443
ip: "::"
module: ejabberd_http
tls: true
request_handlers:
/admin: ejabberd_web_admin
/api: mod_http_api
/bosh: mod_bosh
/captcha: ejabberd_captcha
/upload: mod_http_upload
/ws: ejabberd_http_ws
-
port: 5280
ip: "::"
module: ejabberd_http
request_handlers:
/admin: ejabberd_web_admin
/.well-known/acme-challenge: ejabberd_acme
-
port: 5478
ip: "::"
transport: udp
module: ejabberd_stun
use_turn: true
## The server's public IPv4 address:
# turn_ipv4_address: "203.0.113.3"
## The server's public IPv6 address:
# turn_ipv6_address: "2001:db8::3"
-
port: 1883
ip: "::"
module: mod_mqtt
backlog: 1000
s2s_use_starttls: optional
acl:
local:
user_regexp: ""
loopback:
ip:
- 127.0.0.0/8
- ::1/128
access_rules:
local:
allow: local
c2s:
deny: blocked
allow: all
announce:
allow: admin
configure:
allow: admin
muc_create:
allow: local
pubsub_createnode:
allow: local
trusted_network:
allow: loopback
api_permissions:
"console commands":
from: ejabberd_ctl
who: all
what: "*"
"webadmin commands":
from: ejabberd_web_admin
who: admin
what: "*"
"adhoc commands":
from: mod_adhoc_api
who: admin
what: "*"
"http access":
from: mod_http_api
who:
access:
allow:
- acl: loopback
- acl: admin
oauth:
scope: "ejabberd:admin"
access:
allow:
- acl: loopback
- acl: admin
what:
- "*"
- "!stop"
- "!start"
"public commands":
who:
ip: 127.0.0.1/8
what:
- status
- connected_users_number
shaper:
normal:
rate: 3000
burst_size: 20000
fast: 100000
shaper_rules:
max_user_sessions: 10
max_user_offline_messages:
5000: admin
100: all
c2s_shaper:
none: admin
normal: all
s2s_shaper: fast
modules:
mod_adhoc: {}
mod_adhoc_api: {}
mod_admin_extra: {}
mod_announce:
access: announce
mod_avatar: {}
mod_blocking: {}
mod_bosh: {}
mod_caps: {}
mod_carboncopy: {}
mod_client_state: {}
mod_configure: {}
mod_disco: {}
mod_fail2ban: {}
mod_http_api: {}
mod_http_upload:
put_url: https://@HOST_URL_ENCODE@:5443/upload
custom_headers:
"Access-Control-Allow-Origin": "https://@HOST@"
"Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
"Access-Control-Allow-Headers": "Content-Type"
mod_last: {}
mod_mam:
## Mnesia is limited to 2GB, better to use an SQL backend
## For small servers SQLite is a good fit and is very easy
## to configure. Uncomment this when you have SQL configured:
## db_type: sql
assume_mam_usage: true
default: always
mod_mqtt: {}
mod_muc:
access:
- allow
access_admin:
- allow: admin
access_create: muc_create
access_persistent: muc_create
access_mam:
- allow
default_room_options:
mam: true
mod_muc_admin: {}
mod_offline:
access_max_user_messages: max_user_offline_messages
mod_ping: {}
mod_privacy: {}
mod_private: {}
mod_proxy65:
access: local
max_connections: 5
mod_pubsub:
access_createnode: pubsub_createnode
plugins:
- flat
- pep
force_node_config:
## Avoid buggy clients to make their bookmarks public
storage:bookmarks:
access_model: whitelist
mod_push: {}
mod_push_keepalive: {}
mod_register:
## Only accept registration requests from the "trusted"
## network (see access_rules section above).
## Think twice before enabling registration from any
## address. See the Jabber SPAM Manifesto for details:
## https://github.com/ge0rg/jabber-spam-fighting-manifesto
ip_access: trusted_network
mod_roster:
versioning: true
mod_s2s_bidi: {}
mod_s2s_dialback: {}
mod_shared_roster: {}
mod_stream_mgmt:
resend_on_timeout: if_offline
mod_stun_disco: {}
mod_vcard: {}
mod_vcard_xupdate: {}
mod_version:
show_os: false
### Local Variables:
### mode: yaml
### End:
### vim: set filetype=yaml tabstop=8
-214
View File
@@ -1,214 +0,0 @@
#
# In this file you can configure options that are passed by ejabberdctl
# to the erlang runtime system when starting ejabberd
#
#' POLL: Kernel polling ([true|false])
#
# The kernel polling option requires support in the kernel.
# Additionally, you need to enable this feature while compiling Erlang.
#
# Default: true
#
#POLL=true
#.
#' ERL_MAX_PORTS: Maximum number of simultaneously open Erlang ports
#
# ejabberd consumes two or three ports for every connection, either
# from a client or from another XMPP server. So take this into
# account when setting this limit.
#
# Default: 65536 (or 8196 on Windows)
# Maximum: 268435456
#
#ERL_MAX_PORTS=65536
#.
#' INET_DIST_INTERFACE: IP address where this Erlang node listens other nodes
#
# This communication is used by ejabberdctl command line tool,
# and in a cluster of several ejabberd nodes.
#
# Default: 0.0.0.0
#
#INET_DIST_INTERFACE=127.0.0.1
#.
#' ERL_DIST_PORT: Port number for Erlang distribution
#
# For Erlang distribution, clustering and ejabberdctl usage, the
# Erlang VM listens in a random TCP port number, and the Erlang Port
# Mapper Daemon (EPMD) is spawned and used to determine this port
# number.
#
# ERL_DIST_PORT can define this port number. In that case, EPMD is
# not spawned during ejabberd startup, and ERL_EPMD_ADDRESS is
# ignored. ERL_DIST_PORT must be set to the same port number during
# ejabberd startup and when calling ejabberdctl. This feature
# requires at least Erlang/OTP 23.1.
#
# Default: not defined
#
#ERL_DIST_PORT=5210
#.
#' FIREWALL_WINDOW: Range of allowed ports to pass through a firewall
#
# If ejabberd is configured to run in cluster, and a firewall is blocking ports,
# it's possible to make Erlang use a defined range of port (instead of dynamic
# ports) for node communication.
#
# Default: not defined
# Example: 4200-4210
#
#FIREWALL_WINDOW=
#.
#' ERL_EPMD_ADDRESS: IP addresses where EPMD listens for connections
#
# This environment variable may be set to a comma-separated
# list of IP addresses, in which case the EPMD daemon
# will listen only on the specified address(es) and on the
# loopback address (which is implicitly added to the list if it
# has not been specified). The default behaviour is to listen on
# all available IP addresses.
#
# Default: 0.0.0.0
#
#ERL_EPMD_ADDRESS=127.0.0.1
#.
#' ERL_PROCESSES: Maximum number of Erlang processes
#
# Erlang consumes a lot of lightweight processes. If there is a lot of activity
# on ejabberd so that the maximum number of processes is reached, people will
# experience greater latency times. As these processes are implemented in
# Erlang, and therefore not related to the operating system processes, you do
# not have to worry about allowing a huge number of them.
#
# Default: 262144
# Maximum: 268435456
#
#ERL_PROCESSES=262144
#.
#' ERL_MAX_ETS_TABLES: Maximum number of ETS and Mnesia tables
#
# The number of concurrent ETS and Mnesia tables is limited. When the limit is
# reached, errors will appear in the logs:
# ** Too many db tables **
# You can safely increase this limit when starting ejabberd. It impacts memory
# consumption but the difference will be quite small.
#
# Default: 2053
#
#ERL_MAX_ETS_TABLES=2053
#.
#' ERL_OPTIONS: Additional Erlang options
#
# The next variable allows to specify additional options passed to
# all commands using erlang interpreter. This applies to starting
# ejabberd server itself but also auxiliary commands like for example
# starting debug shell. See erl(1) for list of commands that can be
# used here.
#
# It might be useful to add "-pa /usr/local/lib/ejabberd/ebin" if you
# want to add local modules in this path.
#
# Default: ""
#
#ERL_OPTIONS=""
#.
#' EJABBERD_OPTS: Additional Erlang options to start ejabberd
#
# The next variable allows to specify additional options passed to erlang while
# starting ejabberd. Some useful options are -noshell, -detached, -heart. When
# ejabberd is started from an init.d script options -noshell and -detached are
# added implicitly. See erl(1) for more info.
#
# For example you can use value "-heart -env HEART_BEAT_TIMEOUT 120 -env ERL_CRASH_DUMP_SECONDS 60"
#
# Default: ""
#
#EJABBERD_OPTS=""
#.
#' ERLANG_NODE: Erlang node name
#
# The next variable allows to explicitly specify erlang node for ejabberd
# It can be given in different formats:
# ERLANG_NODE=ejabberd
# Lets erlang add hostname to the node (ejabberd uses short name in this case)
# ERLANG_NODE=ejabberd@hostname
# Erlang uses node name as is (so make sure that hostname is a real
# machine hostname or you'll not be able to control ejabberd)
# ERLANG_NODE=ejabberd@hostname.domainname
# The same as previous, but erlang will use long hostname
# (see erl (1) manual for details)
#
# Default: ejabberd@localhost
#
#ERLANG_NODE=ejabberd@localhost
#.
#' EJABBERD_PID_PATH: ejabberd PID file
#
# Indicate the full path to the ejabberd Process identifier (PID) file.
# If this variable is defined, ejabberd writes the PID file when starts,
# and deletes it when stops.
# Remember to create the directory and grant write permission to ejabberd.
#
# Default: don't write PID file
#
#EJABBERD_PID_PATH=/var/run/ejabberd/ejabberd.pid
#.
#' EJABBERD_CONFIG_PATH: ejabberd configuration file
#
# Specify the full path to the ejabberd configuration file. If the file name has
# yml or yaml extension, it is parsed as a YAML file; otherwise, Erlang syntax is
# expected.
#
# Default: $ETC_DIR/ejabberd.yml
#
#EJABBERD_CONFIG_PATH=/etc/ejabberd/ejabberd.yml
#.
#' CONTRIB_MODULES_PATH: contributed ejabberd modules path
#
# Specify the full path to the contributed ejabberd modules. If the path is not
# defined, ejabberd will use ~/.ejabberd-modules in home of user running ejabberd.
#
# Default: $HOME/.ejabberd-modules
#
#CONTRIB_MODULES_PATH=/opt/ejabberd-modules
#.
#' CONTRIB_MODULES_CONF_DIR: configuration directory for contributed modules
#
# Specify the full path to the configuration directory for contributed ejabberd
# modules. In order to configure a module named mod_foo, a mod_foo.yml file can
# be created in this directory. This file will then be used instead of the
# default configuration file provided with the module.
#
# Default: $CONTRIB_MODULES_PATH/conf
#
#CONTRIB_MODULES_CONF_DIR=/etc/ejabberd/modules
#.
#' CTL_OVER_HTTP: Path to ejabberdctl HTTP listener socket
#
# To speedup ejabberdctl execution time for ejabberd commands,
# you can setup an ejabberd_http listener with ejabberd_ctl handling requests,
# listening in a unix domain socket.
#
# Default: disabled
#
#CTL_OVER_HTTP=sockets/ctl_over_http.sock
#.
#'
# vim: foldmarker=#',#. foldmethod=marker:
-600
View File
@@ -1,600 +0,0 @@
#!/bin/sh
# define default configuration
POLL=true
ERL_MAX_PORTS=32000
ERL_PROCESSES=250000
ERL_MAX_ETS_TABLES=1400
FIREWALL_WINDOW=""
INET_DIST_INTERFACE=""
ERLANG_NODE=ejabberd@localhost
# define default environment variables
[ -z "$SCRIPT" ] && SCRIPT=$0
SCRIPT_DIR="$(cd "$(dirname "$SCRIPT")" && pwd -P)"
# shellcheck disable=SC2034
ERTS_VSN="{{erts_vsn}}"
ERL="{{erl}}"
EPMD="{{epmd}}"
IEX="{{iexpath}}"
INSTALLUSER="{{installuser}}"
# check the proper system user is used
case $(id -un) in
"$INSTALLUSER")
EXEC_CMD="as_current_user"
;;
root)
if [ -n "$INSTALLUSER" ] ; then
EXEC_CMD="as_install_user"
else
EXEC_CMD="as_current_user"
echo "WARNING: It is not recommended to run ejabberd as root" >&2
fi
;;
*)
if [ -n "$INSTALLUSER" ] ; then
echo "ERROR: This command can only be run by root or the user $INSTALLUSER" >&2
exit 7
else
EXEC_CMD="as_current_user"
fi
;;
esac
# parse command line parameters
while [ $# -gt 0 ]; do
case $1 in
-n|--node) ERLANG_NODE_ARG=$2; shift 2;;
-s|--spool) SPOOL_DIR=$2; shift 2;;
-l|--logs) LOGS_DIR=$2; shift 2;;
-f|--config) EJABBERD_CONFIG_PATH=$2; shift 2;;
-c|--ctl-config) EJABBERDCTL_CONFIG_PATH=$2; shift 2;;
-d|--config-dir) CONFIG_DIR=$2; shift 2;;
-t|--no-timeout) NO_TIMEOUT="--no-timeout"; shift;;
*) break;;
esac
done
# define ejabberd variables if not already defined from the command line
: "${CONFIG_DIR:="{{config_dir}}"}"
: "${LOGS_DIR:="{{logs_dir}}"}"
: "${EJABBERD_CONFIG_PATH:="$CONFIG_DIR/ejabberd.yml"}"
: "${EJABBERDCTL_CONFIG_PATH:="$CONFIG_DIR/ejabberdctl.cfg"}"
# Allows passing extra Erlang command-line arguments in vm.args file
: "${VMARGS:="$CONFIG_DIR/vm.args"}"
# shellcheck source=ejabberdctl.cfg.example
[ -f "$EJABBERDCTL_CONFIG_PATH" ] && . "$EJABBERDCTL_CONFIG_PATH"
[ -n "$ERLANG_NODE_ARG" ] && ERLANG_NODE="$ERLANG_NODE_ARG"
[ "$ERLANG_NODE" = "${ERLANG_NODE%@*}" ] && ERLANG_NODE="$ERLANG_NODE@$(hostname -s)"
[ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] && S="-s"
: "${SPOOL_DIR:="{{spool_dir}}"}"
: "${EJABBERD_LOG_PATH:="$LOGS_DIR/ejabberd.log"}"
# backward support for old mnesia spool dir path
: "${SPOOL_DIR_OLD:="$SPOOL_DIR/$ERLANG_NODE"}"
[ -r "$SPOOL_DIR_OLD/schema.DAT" ] && [ ! -r "$SPOOL_DIR/schema.DAT" ] && SPOOL_DIR="$SPOOL_DIR_OLD"
# define erl parameters
ERLANG_OPTS="+K $POLL +P $ERL_PROCESSES $ERL_OPTIONS"
if [ -n "$FIREWALL_WINDOW" ] ; then
ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}"
fi
if [ -n "$INET_DIST_INTERFACE" ] ; then
INET_DIST_INTERFACE2=$("$ERL" $ERLANG_OPTS -noshell -eval 'case inet:parse_address("'$INET_DIST_INTERFACE'") of {ok,IP} -> io:format("~p",[IP]); _ -> ok end.' -s erlang halt)
if [ -n "$INET_DIST_INTERFACE2" ] ; then
if [ "$(echo "$INET_DIST_INTERFACE2" | grep -o "," | wc -l)" -eq 7 ] ; then
INET_DIST_INTERFACE2="$INET_DIST_INTERFACE2 -proto_dist inet6_tcp"
fi
ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_use_interface $INET_DIST_INTERFACE2"
fi
fi
[ -n "$ERL_DIST_PORT" ] && ERLANG_OPTS="$ERLANG_OPTS -erl_epmd_port $ERL_DIST_PORT -start_epmd false"
# if vm.args file exists in config directory, pass it to Erlang VM
[ -f "$VMARGS" ] && ERLANG_OPTS="$ERLANG_OPTS -args_file $VMARGS"
ERL_LIBS='{{libdir}}'
ERL_CRASH_DUMP="$LOGS_DIR"/erl_crash_$(date "+%Y%m%d-%H%M%S").dump
ERL_INETRC="$CONFIG_DIR"/inetrc
# define ejabberd parameters
EJABBERD_OPTS="\
$(sed '/^log_rotate_size/!d;s/:[ \t]*\([0-9]\{1,\}\).*/ \1/;s/:[ \t]*\(infinity\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
$(sed '/^log_rotate_count/!d;s/:[ \t]*\([0-9]*\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
$(sed '/^log_burst_limit_count/!d;s/:[ \t]*\([0-9]*\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
$(sed '/^log_burst_limit_window_time/!d;s/:[ \t]*\([0-9]*[a-z]*\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
$EJABBERD_OPTS"
[ -n "$EJABBERD_OPTS" ] && EJABBERD_OPTS="-ejabberd $EJABBERD_OPTS"
EJABBERD_OPTS="-mnesia dir \"$SPOOL_DIR\" $MNESIA_OPTIONS $EJABBERD_OPTS -s ejabberd"
# export global variables
export EJABBERD_CONFIG_PATH
export EJABBERD_LOG_PATH
export EJABBERD_PID_PATH
export ERL_CRASH_DUMP
export ERL_EPMD_ADDRESS
export ERL_DIST_PORT
export ERL_INETRC
export ERL_MAX_PORTS
export ERL_MAX_ETS_TABLES
export CONTRIB_MODULES_PATH
export CONTRIB_MODULES_CONF_DIR
export ERL_LIBS
export SCRIPT_DIR
# Only required for Erlang/OTP 25:
export ERL_FLAGS="$ERL_FLAGS -enable-feature maybe_expr"
set_dist_client()
{
[ -n "$ERL_DIST_PORT" ] && ERLANG_OPTS="$ERLANG_OPTS -dist_listen false"
}
# run command either directly or via su $INSTALLUSER
exec_cmd()
{
case $EXEC_CMD,$(uname -s) in
as_install_user,OpenBSD)
su -s /bin/sh "$INSTALLUSER" -c 'exec "$0" "$@"' "$@"
;;
as_install_user,NetBSD)
su "$INSTALLUSER" -c 'exec "$0" "$@"' -- "$@"
;;
as_install_user,*)
su -s /bin/sh -c 'exec "$0" "$@"' "$INSTALLUSER" -- "$@"
;;
as_current_user,*)
"$@"
;;
esac
}
exec_erl()
{
NODE=$1; shift
exec_cmd "$ERL" ${S:--}name "$NODE" $ERLANG_OPTS "$@"
}
exec_iex()
{
NODE=$1; shift
exec_cmd "$IEX" -${S:--}name "$NODE" --erl "$ERLANG_OPTS" "$@"
}
# usage
debugwarning()
{
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
echo "--------------------------------------------------------------------"
echo ""
echo "IMPORTANT: we will attempt to attach an INTERACTIVE shell"
echo "to an already running ejabberd node."
echo "If an ERROR is printed, it means the connection was not successful."
echo "You can interact with the ejabberd node if you know how to use it."
echo "Please be extremely cautious with your actions,"
echo "and exit immediately if you are not completely sure."
echo ""
echo "To exit and detach this shell from ejabberd, press:"
echo " control+g and then q"
echo ""
#vt100 echo "Please do NOT use control+c in this debug shell !"
#vt100 echo ""
echo "--------------------------------------------------------------------"
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
echo " EJABBERD_BYPASS_WARNINGS=true"
echo "Press return to continue"
read -r _
echo ""
fi
}
livewarning()
{
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
echo "--------------------------------------------------------------------"
echo ""
echo "IMPORTANT: ejabberd is going to start in LIVE (interactive) mode."
echo "All log messages will be shown in the command shell."
echo "You can interact with the ejabberd node if you know how to use it."
echo "Please be extremely cautious with your actions,"
echo "and exit immediately if you are not completely sure."
echo ""
echo "To stop ejabberd gracefully:"
echo " ejabberd:stop()."
echo "To quit erlang immediately, press:"
echo " control+g and then q"
echo ""
echo "--------------------------------------------------------------------"
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
echo " EJABBERD_BYPASS_WARNINGS=true"
echo "Press return to continue"
read -r _
echo ""
fi
}
check_etop_result()
{
result=$?
if [ $result -eq 1 ] ; then
echo ""
echo "It seems there was some problem running 'ejabberdctl etop'."
echo "Is the error message something like this?"
echo " Failed to load module 'etop' because it cannot be found..."
echo "Then probably ejabberd was compiled with development tools disabled."
echo "To use 'etop', recompile ejabberd with: ./configure --enable-tools"
echo ""
exit $result
fi
}
check_iex_result()
{
result=$?
if [ $result -eq 127 ] ; then
echo ""
echo "It seems there was some problem finding 'iex' binary from Elixir."
echo "Probably ejabberd was compiled with Rebar3 and Elixir disabled, like:"
echo " ./configure"
echo "which is equivalent to:"
echo " ./configure --with-rebar=rebar3 --disable-elixir"
echo "To use 'iex', recompile ejabberd enabling Elixir or using Mix:"
echo " ./configure --enable-elixir"
echo " ./configure --with-rebar=mix"
echo ""
exit $result
fi
}
help()
{
echo ""
echo "Commands to start an ejabberd node:"
echo " start Start in server mode"
echo " foreground Start in server mode (attached)"
echo " foreground-quiet Start in server mode (attached), show only critical messages"
echo " live Start in interactive mode, with Erlang shell"
echo " iexlive Start in interactive mode, with Elixir shell"
echo ""
echo "Commands to interact with a running ejabberd node:"
echo " debug Attach an interactive Erlang shell to a running node"
echo " iexdebug Attach an interactive Elixir shell to a running node"
echo " etop Attach to a running node and start Erlang Top"
echo " ping Send ping to the node, returns pong or pang"
echo " started|stopped Wait for the node to fully start|stop"
echo ""
echo "Optional parameters when starting an ejabberd node:"
echo " --config-dir dir Config ejabberd: $CONFIG_DIR"
echo " --config file Config ejabberd: $EJABBERD_CONFIG_PATH"
echo " --ctl-config file Config ejabberdctl: $EJABBERDCTL_CONFIG_PATH"
echo " --logs dir Directory for logs: $LOGS_DIR"
echo " --spool dir Database spool dir: $SPOOL_DIR"
echo " --node nodename ejabberd node name: $ERLANG_NODE"
echo ""
}
# dynamic node name helper
uid() {
ERTSVERSION="$("$ERL" -version 2>&1 | sed 's|.* \([0-9]*[0-9]\).*|\1|g')"
if [ $ERTSVERSION -lt 11 ] ; then # otp 23.0 includes erts 11.0
# Erlang/OTP lower than 23, which doesn's support dynamic node code
N=1
PF=$(( $$ % 97 ))
while
case $# in
0) NN="${PF}-${N}-${ERLANG_NODE}"
;;
1) NN="${PF}-${N}-${1}-${ERLANG_NODE}"
;;
2) NN="${PF}-${N}-${1}@${2}"
;;
esac
N=$(( N + 1 + ( $$ % 5 ) ))
"$EPMD" -names 2>/dev/null | grep -q " ${NN%@*} "
do :; done
echo $NN
else
# Erlang/OTP 23 or higher: use native dynamic node code
# https://www.erlang.org/patches/otp-23.0#OTP-13812
if [ "$ERLANG_NODE" != "${ERLANG_NODE%.*}" ]; then
echo "undefined@${ERLANG_NODE#*@}"
else
echo "undefined"
fi
fi
}
# stop epmd if there is no other running node
stop_epmd()
{
[ -n "$ERL_DIST_PORT" ] && return
"$EPMD" -names 2>/dev/null | grep -q name || "$EPMD" -kill >/dev/null
}
# make sure node not already running and node name unregistered
# if all ok, ensure runtime directory exists and make it current directory
check_start()
{
[ -n "$ERL_DIST_PORT" ] && {
netstat -nl | grep ":$ERL_DIST_PORT" >/dev/null && {
echo ""
echo "NOTE: The file ejabberdctl.cfg has configured ERL_DIST_PORT=$ERL_DIST_PORT"
echo " and the port 5210 is already in use."
echo " If ejabberd fails to start with listen error eaddrinsuse,"
echo " try configuring in ejabberdctl.cfg a different"
echo " INET_DIST_INTERFACE, or different ERL_DIST_PORT"
echo ""
netstat -nlp 2>/dev/null | grep ":5210"
echo ""
}
return
}
"$EPMD" -names 2>/dev/null | grep -q " ${ERLANG_NODE%@*} " && {
pgrep -f "$ERLANG_NODE" >/dev/null && {
echo "ERROR: The ejabberd node '$ERLANG_NODE' is already running."
exit 4
}
pgrep beam >/dev/null && {
echo "ERROR: The ejabberd node '$ERLANG_NODE' is registered,"
echo " but no related beam process has been found."
echo "Shutdown all other erlang nodes, and call 'epmd -kill'."
exit 5
}
"$EPMD" -kill >/dev/null
}
}
# allow sync calls
wait_status()
{
wait_status_node "$ERLANG_NODE" $1 $2 $3
}
wait_status_node()
{
CONNECT_NODE=$1
shift
# args: status try delay
# return: 0 OK, 1 KO
timeout="$2"
status=4
while [ "$status" -ne "$1" ] ; do
sleep "$3"
timeout=$((timeout - 1))
if [ $timeout -eq 0 ] ; then
status="$1"
else
exec_erl "$(uid ctl)" -hidden -noinput \
-eval 'net_kernel:connect_node('"'$CONNECT_NODE'"')' \
-s ejabberd_ctl \
-extra "$CONNECT_NODE" $NO_TIMEOUT status > /dev/null
status="$?"
fi
done
[ $timeout -gt 0 ]
}
exec_other_command()
{
exec_other_command_node $ERLANG_NODE "$@"
}
exec_other_command_node()
{
CONNECT_NODE=$1
shift
if [ -z "$CTL_OVER_HTTP" ] || [ ! -S "$CTL_OVER_HTTP" ] \
|| [ ! -x "$(command -v curl)" ] || [ -z "$1" ] || [ "$1" = "help" ] \
|| [ "$1" = "mnesia_info_ctl" ]|| [ "$1" = "print_sql_schema" ] ; then
exec_erl "$(uid ctl)" -hidden -noinput \
-eval 'net_kernel:connect_node('"'$CONNECT_NODE'"')' \
-s ejabberd_ctl \
-extra "$CONNECT_NODE" $NO_TIMEOUT "$@"
result=$?
case $result in
3) help;;
*) :;;
esac
return $result
else
exec_ctl_over_http_socket "$@"
fi
}
exec_ctl_over_http_socket()
{
COMMAND=${1}
CARGS=""
while [ $# -gt 0 ]; do
[ -z "$CARGS" ] && CARGS="[" || CARGS="${CARGS}, "
CARGS="${CARGS}\"$1\""
shift
done
CARGS="${CARGS}]"
TEMPHEADERS=temp-headers.log
curl \
--unix-socket ${CTL_OVER_HTTP} \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "${CARGS}" \
--dump-header ${TEMPHEADERS} \
--no-progress-meter \
"http://localhost/ctl/${COMMAND}"
result=$(sed -n 's/.*status-code: \([0-9]*\).*/\1/p' < $TEMPHEADERS)
rm ${TEMPHEADERS}
case $result in
2|3) exec_other_command help ${COMMAND};;
*) :;;
esac
exit $result
}
# ensure we can change current directory to SPOOL_DIR
[ -d "$SPOOL_DIR" ] || exec_cmd mkdir -p "$SPOOL_DIR"
cd "$SPOOL_DIR" || {
echo "ERROR: can not access directory $SPOOL_DIR"
exit 6
}
printe()
{
printf "\n"
printf "\e[1;40;32m==> %s\e[0m\n" "$1"
}
## Function copied from tools/make-installers
user_agrees()
{
question="$*"
if [ -t 0 ]
then
printe "$question (y/n) [n]"
read -r response
case "$response" in
[Yy]|[Yy][Ee][Ss])
return 0
;;
[Nn]|[Nn][Oo]|'')
return 1
;;
*)
echo 'Please respond with "yes" or "no".'
user_agrees "$question"
;;
esac
else # Assume 'yes' if not running interactively.
return 0
fi
}
mnesia_change()
{
ERLANG_NODE_OLD="$1"
[ "$ERLANG_NODE_OLD" = "" ] \
&& echo "Error: Please provide the old erlang node name, for example:" \
&& echo " ejabberdctl mnesia_change ejabberd@oldmachine" \
&& exit 1
SPOOL_DIR_BACKUP=$SPOOL_DIR/$ERLANG_NODE_OLD-backup/
OLDFILE=$SPOOL_DIR_BACKUP/$ERLANG_NODE_OLD.backup
NEWFILE=$SPOOL_DIR_BACKUP/$ERLANG_NODE.backup
printe "This changes your mnesia database from node name '$ERLANG_NODE_OLD' to '$ERLANG_NODE'"
[ -d "$SPOOL_DIR_BACKUP" ] && printe "WARNING! A backup of old node already exists in $SPOOL_DIR_BACKUP"
if ! user_agrees "Do you want to proceed?"
then
echo 'Operation aborted.'
exit 1
fi
printe "Starting ejabberd with old node name $ERLANG_NODE_OLD ..."
exec_erl "$ERLANG_NODE_OLD" $EJABBERD_OPTS -detached
wait_status_node $ERLANG_NODE_OLD 0 30 2
result=$?
case $result in
1) echo "There was a problem starting ejabberd with the old erlang node name. " \
&& echo "Check for log errors in $EJABBERD_LOG_PATH" \
&& exit $result;;
*) :;;
esac
exec_other_command_node $ERLANG_NODE_OLD "status"
printe "Making backup of old database to file $OLDFILE ..."
mkdir $SPOOL_DIR_BACKUP
exec_other_command_node $ERLANG_NODE_OLD backup "$OLDFILE"
printe "Changing node name in new backup file $NEWFILE ..."
exec_other_command_node $ERLANG_NODE_OLD mnesia_change_nodename "$ERLANG_NODE_OLD" "$ERLANG_NODE" "$OLDFILE" "$NEWFILE"
printe "Stopping old ejabberd..."
exec_other_command_node $ERLANG_NODE_OLD "stop"
wait_status_node $ERLANG_NODE_OLD 3 30 2 && stop_epmd
printe "Moving old mnesia spool files to backup subdirectory $SPOOL_DIR_BACKUP ..."
mv $SPOOL_DIR/*.DAT $SPOOL_DIR_BACKUP
mv $SPOOL_DIR/*.DCD $SPOOL_DIR_BACKUP
mv $SPOOL_DIR/*.LOG $SPOOL_DIR_BACKUP
printe "Starting ejabberd with new node name $ERLANG_NODE ..."
exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -detached
wait_status 0 30 2
exec_other_command "status"
printe "Installing fallback of new mnesia..."
exec_other_command install_fallback "$NEWFILE"
printe "Stopping new ejabberd..."
exec_other_command "stop"
wait_status 3 30 2 && stop_epmd
printe "Finished, now you can start ejabberd normally"
}
# main
case $1 in
start)
check_start
exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -detached
;;
foreground)
check_start
exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -noinput
;;
foreground-quiet)
check_start
exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -noinput -ejabberd quiet true
;;
live)
livewarning
check_start
exec_erl "$ERLANG_NODE" $EJABBERD_OPTS
;;
debug)
debugwarning
set_dist_client
exec_erl "$(uid debug)" -hidden -remsh "$ERLANG_NODE"
;;
etop)
set_dist_client
exec_erl "$(uid top)" -hidden -remsh "$ERLANG_NODE" -s etop \
-output text
check_etop_result
;;
iexdebug)
debugwarning
set_dist_client
exec_iex "$(uid debug)" --remsh "$ERLANG_NODE"
check_iex_result
;;
iexlive)
livewarning
exec_iex "$ERLANG_NODE" --erl "$EJABBERD_OPTS"
check_iex_result
;;
ping)
PEER=${2:-$ERLANG_NODE}
[ "$PEER" = "${PEER%.*}" ] && PS="-s"
set_dist_client
exec_cmd "$ERL" ${PS:--}name "$(uid ping "$(hostname $PS)")" $ERLANG_OPTS \
-noinput -hidden \
-eval 'net_kernel:connect_node('"'$PEER'"')' \
-eval 'io:format("~p~n",[net_adm:ping('"'$PEER'"')])' \
-eval 'halt(case net_adm:ping('"'$PEER'"') of pong -> 0; pang -> 1 end).' \
-output text
;;
started)
set_dist_client
wait_status 0 30 2 # wait 30x2s before timeout
;;
stopped)
set_dist_client
wait_status 3 30 2 && stop_epmd # wait 30x2s before timeout
;;
mnesia_change)
mnesia_change $2
;;
*)
set_dist_client
exec_other_command "$@"
;;
esac
-59
View File
@@ -1,59 +0,0 @@
[
{
elvis,
[
{config,
[#{dirs => ["src"],
filter => "*.erl",
ignore => ['ELDAPv3', eldap_filter_yecc],
ruleset => erl_files,
rules => [{elvis_text_style, line_length, #{limit => 1000, skip_comments => false}},
{elvis_text_style, no_tabs, disable},
{elvis_style, atom_naming_convention, disable},
{elvis_style, consistent_variable_casing, disable},
{elvis_style, dont_repeat_yourself, #{min_complexity => 70}},
{elvis_style, export_used_types, disable},
{elvis_style, function_naming_convention, disable},
{elvis_style, god_modules, #{limit => 300}},
{elvis_style, invalid_dynamic_call, disable},
{elvis_style, macro_names, disable},
{elvis_style, max_function_arity, disable}, % #{max_arity => 15}},
{elvis_style, nesting_level, disable},
{elvis_style, no_author, disable},
{elvis_style, no_boolean_in_comparison, disable},
{elvis_style, no_catch_expressions, disable},
{elvis_style, no_debug_call, disable},
{elvis_style, no_if_expression, disable},
{elvis_style, no_import, disable},
{elvis_style, no_nested_try_catch, disable},
{elvis_style, no_operation_on_same_value, disable},
{elvis_style, no_receive_without_timeout, disable},
{elvis_style, no_single_clause_case, disable},
{elvis_style, no_spec_with_records, disable},
{elvis_style, no_throw, disable},
{elvis_style, operator_spaces, disable},
{elvis_style, param_pattern_matching, disable},
{elvis_style, private_data_types, disable},
{elvis_style, variable_naming_convention, disable}
]
},
%#{dirs => ["include"],
% filter => "*.hrl",
% ruleset => hrl_files},
#{dirs => ["."],
filter => "Makefile.in",
ruleset => makefiles,
rules => [{elvis_text_style, line_length, #{limit => 400,
skip_comments => false}},
{elvis_style, dont_repeat_yourself, #{min_complexity => 20}}
]
}
]
}
]
}
].
%% vim: set filetype=erlang tabstop=8:
-29
View File
@@ -1,29 +0,0 @@
#otp_path: "/usr/lib/erlang"
#plt_path: "_build/default/rebar3_24.3.3_plt"
#code_reload:
# node: ejabberd@localhost
apps_dirs:
- "_build/default/lib/*"
deps_dirs:
- "_build/default/lib/*"
include_dirs:
- "_build/default/lib"
- "_build/default/lib/*/include"
- "include"
macros:
- name: OTP_BELOW_27
- name: SIP
- name: STUN
diagnostics:
enabled:
- crossref
disabled:
# - dialyzer
- unused_includes # Otherwise it complains about unused logger.hrl
lenses:
disabled:
- ct-run-test
- function-references
- server-info
- show-behaviour-usages
- suggest-spec
+50
View File
@@ -0,0 +1,50 @@
#!/usr/local/bin/perl
use Unix::Syslog qw(:macros :subs);
my $domain = $ARGV[0] || "example.com";
while(1)
{
# my $rin = '',$rout;
# vec($rin,fileno(STDIN),1) = 1;
# $ein = $rin;
# my $nfound = select($rout=$rin,undef,undef,undef);
my $buf = "";
syslog LOG_INFO,"waiting for packet";
my $nread = sysread STDIN,$buf,2;
do { syslog LOG_INFO,"port closed"; exit; } unless $nread == 2;
my $len = unpack "n",$buf;
my $nread = sysread STDIN,$buf,$len;
my ($op,$user,$password) = split /:/,$buf;
#$user =~ s/\./\//og;
my $jid = "$user\@$domain";
my $result;
syslog(LOG_INFO,"request (%s)", $op);
SWITCH:
{
$op eq 'auth' and do
{
$result = 1;
},last SWITCH;
$op eq 'setpass' and do
{
$result = 1;
},last SWITCH;
$op eq 'isuser' and do
{
# password is null. Return 1 if the user $user\@$domain exitst.
$result = 1;
},last SWITCH;
};
my $out = pack "nn",2,$result ? 1 : 0;
syswrite STDOUT,$out;
}
closelog;
+75
View File
@@ -0,0 +1,75 @@
#!/bin/sh
#
# PROVIDE: ejabberd
# REQUIRE: DAEMON
# KEYWORD: shutdown
#
HOME=/usr/pkg/jabber D=/usr/pkg/jabber/ejabberd export HOME
name="ejabberd"
rcvar=$name
if [ -r /etc/rc.conf ]
then
. /etc/rc.conf
else
eval ${rcvar}=YES
fi
# $flags from environment overrides ${rcvar}_flags
if [ -n "${flags}" ]
then
eval ${rcvar}_flags="${flags}"
fi
checkyesno()
{
eval _value=\$${1}
case $_value in
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) return 0 ;;
[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) return 1 ;;
*)
echo "\$${1} is not set properly."
return 1
;;
esac
}
cmd=${1:-start}
case ${cmd} in
force*)
cmd=${cmd#force}
eval ${rcvar}=YES
;;
esac
if checkyesno ${rcvar}
then
else
exit 0
fi
case ${cmd} in
start)
if [ -x $D/src ]; then
echo "Starting ${name}."
cd $D/src
ERL_MAX_PORTS=32000 export ERL_MAX_PORTS
ulimit -n $ERL_MAX_PORTS
su jabber -c "/usr/pkg/bin/erl -sname ejabberd -s ejabberd -heart -detached -sasl sasl_error_logger '{file, \"ejabberd-sasl.log\"}' &" \
1>/dev/null 2>&1
fi
;;
stop)
echo "rpc:call('ejabberd@`hostname -s`', init, stop, [])." | \
su jabber -c "/usr/pkg/bin/erl -sname ejabberdstop"
;;
restart)
echo "rpc:call('ejabberd@`hostname -s`', init, restart, [])." | \
su jabber -c "/usr/pkg/bin/erl -sname ejabberdrestart"
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
+81
View File
@@ -0,0 +1,81 @@
#!/bin/sh
echo '1. fetch, compile, and install erlang'
if [ ! pkg_info erlang 1>/dev/null 2>&1 ]; then
cd /usr/pkgsrc/lang/erlang
make fetch-list|sh
make
make install
fi
if pkg_info erlang | grep -q erlang-9.1nb1; then
else
echo "erlang-9.1nb1 not installed" 1>&2
exit 1
fi
echo '2. install crypt_drv.so'
if [ ! -d /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib ] ; then
mkdir -p /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib
fi
if [ ! -f /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib/crypto_drv.so ]; then
cp work/otp*/lib/crypto/priv/*/*/crypto_drv.so \
/usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib
fi
echo '3. compile and install elibcrypto.so'
if [ ! -f /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib/elibcrypto.so ]; then
cd /usr/pkgsrc/lang/erlang/work/otp_src_R9B-1/lib/crypto/c_src
ld -r -u CRYPTO_set_mem_functions -u MD5 -u MD5_Init -u MD5_Update \
-u MD5_Final -u SHA1 -u SHA1_Init -u SHA1_Update -u SHA1_Final \
-u des_set_key -u des_ncbc_encrypt -u des_ede3_cbc_encrypt \
-L/usr/lib -lcrypto -o ../priv/obj/i386--netbsdelf/elibcrypto.o
cc -shared \
-L/usr/pkgsrc/lang/erlang/work/otp_src_R9B-1/lib/erl_interface/obj/i386--netbsdelf \
-o ../priv/obj/i386--netbsdelf/elibcrypto.so \
../priv/obj/i386--netbsdelf/elibcrypto.o -L/usr/lib -lcrypto
cp ../priv/obj/i386--netbsdelf/elibcrypto.so \
/usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib
fi
echo '4. compile and install ssl_esock'
if [ ! -f /usr/pkg/lib/erlang/lib/ssl-2.3.5/priv/bin/ssl_esock ]; then
cd /usr/pkg/lib/erlang/lib/ssl-2.3.5/priv/obj/
make
fi
echo '5. initial ejabberd configuration'
cd /usr/pkg/jabber/ejabberd/src
./configure
echo '6. edit ejabberd Makefiles'
for M in Makefile mod_*/Makefile; do
if [ ! -f $M.orig ]; then
mv $M $M.orig
sed -e s%/usr/local%/usr/pkg%g < $M.orig > $M
fi
done
echo '7. compile ejabberd'
gmake
for A in mod_irc mod_muc mod_pubsub; do
(cd $A; gmake)
done
echo ''
echo 'now edit ejabberd.cfg'
echo ''
echo 'to start ejabberd: erl -sname ejabberd -s ejabberd'
+66
View File
@@ -0,0 +1,66 @@
% jabber.dbc.mtview.ca.us
override_acls.
{acl, admin, {user, "mrose", "jabber.dbc.mtview.ca.us"}}.
{access, announce, [{allow, admin},
{deny, all}]}.
{access, c2s, [{deny, blocked},
{allow, all}]}.
{access, c2s_shaper, [{none, admin},
{normal, all}]}.
{access, configure, [{allow, admin},
{deny, all}]}.
{access, disco_admin, [{allow, admin},
{deny, all}]}.
{access, muc_admin, [{allow, admin},
{deny, all}]}.
{access, register, [{deny, all}]}.
{access, s2s_shaper, [{fast, all}]}.
{auth_method, internal}.
{host, "jabber.dbc.mtview.ca.us"}.
{outgoing_s2s_port, 5269}.
{shaper, normal, {maxrate, 1000}}.
{shaper, fast, {maxrate, 50000}}.
{welcome_message, none}.
{listen, [{5222, ejabberd_c2s,
[{access, c2s},
{shaper, c2s_shaper}]},
{5223, ejabberd_c2s,
[{access, c2s},
{shaper, c2s_shaper},
{ssl, [{certfile, "/etc/openssl/certs/ejabberd.pem"}]}]},
{5269, ejabberd_s2s_in,
[{shaper, s2s_shaper}]}]}.
{modules, [
{mod_register, []},
{mod_roster, []},
{mod_privacy, []},
{mod_configure, []},
{mod_disco, []},
{mod_stats, []},
{mod_vcard, []},
{mod_offline, []},
{mod_echo, [{host, "echo.jabber.dbc.mtview.ca.us"}]},
{mod_private, []},
% {mod_irc, []},
{mod_muc, []},
{mod_pubsub, []},
{mod_time, []},
{mod_last, []},
{mod_version, []}
]}.
% Local Variables:
% mode: erlang
% End:
@@ -0,0 +1,77 @@
<!-- aim-transport.xml -->
<jabber>
<!--
You need to add elogger and rlogger entries when using ejabberd.
In this case the transport will do the logging.
-->
<log id='elogger'>
<host/>
<logtype/>
<format>%d: [%t] (%h): %s</format>
<file>/var/log/jabber/aim-transport-error.log</file>
</log>
<log id='rlogger'>
<host/>
<logtype>record</logtype>
<format>%d %h %s</format>
<file>/var/log/jabber/aim-transport-record.log</file>
</log>
<!--
ejabberd do not provide XDB services.
xdb_file.so is loaded in to handle all XDB requests.
-->
<xdb id="xdb">
<host/>
<load>
<xdb_file>/usr/local/lib/jabber/libjabberdxdbfile.so</xdb_file> <!-- This file is part of jabberd-1.4.x. -->
</load>
<xdb_file xmlns="jabber:config:xdb_file">
<spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>
</xdb_file>
</xdb>
<!--
Make sure that all host names here are resolveable via DNS if you
want the transport to be available to the public.
-->
<service id='aim.SERVER.COM'>
<!-- aim-transport configuration. -->
<aimtrans xmlns='jabber:config:aimtrans'>
<vCard>
<FN>AIM/ICQ Transport</FN>
<DESC>This is the AIM/ICQ Transport.</DESC>
<MAIL>EMAIL@ADDRESS.COM</MAIL>
<URL>http://aim-transport.jabberstudio.org/</URL>
</vCard>
<charset>cp1252</charset>
</aimtrans>
<!-- aim-transport module. -->
<load>
<aim_transport>/usr/local/lib/jabber/aim-transport.so</aim_transport>
</load>
</service>
<!--
The settings below have to match the settings you made
in your ejabberd.cfg configuration file.
-->
<service id="icq-linker">
<uplink/>
<connect>
<ip>127.0.0.1</ip>
<port>5233</port>
<secret>SECRET</secret>
</connect>
</service>
<pidfile>/var/run/jabber/aim-transport.pid</pidfile>
</jabber>
+136
View File
@@ -0,0 +1,136 @@
<!-- ile.xml -->
<config>
<jabber>
<server>127.0.0.1</server>
<port>5238</port>
<secret>SECRET</secret>
<service>ile.SERVER.COM</service>
<connectsleep>7</connectsleep> <!-- seconds to wait if we get disconnected -->
<language>en</language>
<vCard>
<FN>I Love Email</FN>
<DESC>With this service you can receive email notifications.
Security warning: Be careful when using this. Your password will travel in clear from your client to your jabber server if you don't use SSL and it will probably travel in clear from the jabber server to your email server. Use with care. This shouldn't be an issue in your Intranet, but it is if you use an ILE installed in a foreign jabber server.</DESC>
<MAIL>EMAIL@ADDRESS.COM</MAIL>
<URL>http://ile.jabberstudio.org/</URL>
</vCard>
</jabber>
<debug>
<file>/var/log/jabber/ile.log</file>
<level>1</level> <!-- man Net::Jabber::Debug -->
</debug>
<mail>
<checkinterval>10</checkinterval> <!-- in minutes -->
<timeout>20</timeout> <!-- timeout for IMAP/POP connection, in seconds -->
</mail>
<files>
<users>/var/spool/jabber/ile.SERVER.COM/users.db</users>
<passwords>/var/spool/jabber/ile.SERVER.COM/passwords.db</passwords>
<hosts>/var/spool/jabber/ile.SERVER.COM/hosts.db</hosts>
<types>/var/spool/jabber/ile.SERVER.COM/types.db</types>
<notifyxa>/var/spool/jabber/ile.SERVER.COM/notifyxa.db</notifyxa>
<notifydnd>/var/spool/jabber/ile.SERVER.COM/notifydnd.db</notifydnd>
<urls>/var/spool/jabber/ile.SERVER.COM/urls.db</urls>
</files>
<form>
<en>
<instructions>Please fill in the fields,according to your email account settings and notification preferences</instructions>
<title>ILE: Email notification service</title>
<email_options>Email account settings</email_options>
<user>Username</user>
<pass>Password</pass>
<host>Hostname</host>
<type>Type</type>
<newmail>You have received NUM email messages since last time I checked, which was CHECKINTERVAL minutes ago.</newmail>
<errorcheck>There was an error while trying to check mail for ACCOUNT.</errorcheck>
<notify_options>Notification Options</notify_options>
<notifyxa>Notify even when Xtended Away (XA)</notifyxa>
<notifydnd>Notify even when Do Not Disturb (DND)</notifydnd>
<webmail_url>Webmail URL</webmail_url>
<webmail_login>Login to ACCOUNT</webmail_login>
<iledesc>ILE: an email notifier component: http://ile.jabberstudio.org</iledesc>
</en>
<es>
<instructions>Por favor, rellene los campos del formulario.</instructions>
<title>ILE: Servicio de notificación de correo</title>
<email_options>Configuración de la cuenta de correo</email_options>
<user>Usuario</user>
<pass>Clave</pass>
<host>Host</host>
<type>Tipo</type>
<newmail>Ha recibido NUM email(s) desde la última comprobación que fue hace CHECKINTERVAL minutos</newmail>
<errorcheck>Ha habido un error en la comprobación del correo para la cuenta ACCOUNT.</errorcheck>
<notify_options>Opciones de notificación</notify_options>
<notifyxa>Notificar incluso si muy ausente (XA)</notifyxa>
<notifydnd>Notificar incluso si no molestar (DND)</notifydnd>
<webmail_url>Webmail URL</webmail_url>
<webmail_login>Leer correo de ACCOUNT</webmail_login>
<iledesc>ILE: un notificador de nuevo email - http://ile.jabberstudio.org</iledesc>
</es>
<ca>
<instructions>Ompli els camps del formulari.</instructions>
<title>ILE: Servei de notificació de nou email</title>
<email_options>Dades del compte de mail</email_options>
<user>Usuari</user>
<pass>Clau</pass>
<host>Host</host>
<type>Tipus</type>
<newmail>Ha rebut NUM email(s) des de la última comprobació que va ser fa CHECKINTERVAL minuts.</newmail>
<errorcheck>S'ha produit un error en la comprobació del correu per al compte ACCOUNT.</errorcheck>
<notify_options>Opcions de notificació</notify_options>
<notifyxa>Notificar si molt absent (XA)</notifyxa>
<notifydnd>Notificar si no molestar (DND)</notifydnd>
<webmail_url>Webmail URL</webmail_url>
<webmail_login>Llegir correu de ACCOUNT</webmail_login>
<iledesc>ILE: un notificador de nou email - http://ile.jabberstudio.org</iledesc>
</ca>
<ro>
<!-- Contributed by Adrian Rappa -->
<instructions>Va rog completati urmatoarele campuri</instructions>
<title>I Love Email: new email notification service</title>
<email_options>Email account settings</email_options>
<user>Nume utilizator</user>
<pass>Parola</pass>
<host>Nume gazda</host>
<type>Tip</type>
<newmail>Ati primit NUM mesaj(e) de la ultima verificare, care a fost acum CHECKINTERVAL minute.</newmail>
<errorcheck>A fost eroare in timp ce incercam sa verific posta pentru ACCOUNT.</errorcheck>
<notify_options>Notification Options</notify_options>
<notifyxa>Notify even when Xtended Away (XA)</notifyxa>
<notifydnd>Notify even when Do Not Disturb (DND)</notifydnd>
<webmail_url>Webmail URL</webmail_url>
<webmail_login>Login to ACCOUNT</webmail_login>
<iledesc>ILE: an email notifier component: http://ile.jabberstudio.org</iledesc>
</ro>
<nl>
<!-- Contributed by Sander Devrieze -->
<instructions>Vul volgende velden in.</instructions>
<title>ILE: Dienst voor e-mailnotificaties</title>
<email_options>Instellingen van e-mailaccount</email_options>
<user>Gebruikersnaam</user>
<pass>Wachtwoord</pass>
<host>Inkomende mailserver</host>
<type>Type verbinding</type>
<newmail>U hebt NUM berichten ontvangen sinds CHECKINTERVAL minuten geleden.</newmail>
<errorcheck>Fout tijdens controle op nieuwe e-mails bij ACCOUNT. ILE zal deze account niet meer opnieuw controleren tot u uw registratiegegevens wijzigt of opnieuw aanmeldt.</errorcheck>
<notify_options>Notificatie-instellingen</notify_options>
<notifyxa>Notificeer ook in de status Niet Beschikbaar (XA)</notifyxa>
<notifydnd>Notificeer ook in de status Niet Storen (DND)</notifydnd>
<webmail_url>URL van webmail</webmail_url>
<webmail_login>Aanmelden op ACCOUNT</webmail_login>
<iledesc>ILE: een dienst om e-mailnotificaties te ontvangen: http://ile.jabberstudio.org</iledesc>
</nl>
</form>
</config>
@@ -0,0 +1,149 @@
<jggtrans>
<service jid="gg.SERVER.COM"/>
<!-- This connects the jabber-gg-transport process to ejabberd. -->
<connect id="gglinker">
<ip>127.0.0.1</ip>
<port>5237</port>
<secret>SECRET</secret>
</connect>
<register>
<!-- This tag contains the message displayed to users at registration time.
You can use <p/> and/or <br/> to break lines. Multiple spaces and newlines
are converted to just one, so formatting of config file doesn't really matter. -->
<instructions>
Fill in your GG number (after "username")
and password to register on the transport.
<p/>To change your information in the GaduGadu directory you need to fill in the other fields.
<p/>To remove registration you need to leave the form blank.
</instructions>
</register>
<search>
<!-- This tag contains the message displayed to users at search time. -->
<instructions>
To search people:<br/>
First fill in surname or family name, nickname, city, birthyear or range of birthyears (eg. 1950-1960)
and gender (you may fill in more fields at once).<br/>
or<br/>
Fill in phone number<br/>
or<br/>
Fill in the GG number of the person you are searching.
</instructions>
</search>
<gateway>
<!-- This is message, that may be displayed to user when adding gg contact. -->
<desc>Please fill in the GaduGadu number of the person you want to add.</desc>
<!-- And this is the prompt for GG number. -->
<prompt>GG Nummer</prompt>
</gateway>
<vCard>
<FN>Gadu-Gadu Transport</FN>
<DESC>This is the Gadu-Gadu Transport.</DESC>
<EMAIL>EMAIL@ADDRESS.COM</EMAIL>
<URL>http://www.jabberstudio.org/projects/jabber-gg-transport/</URL>
</vCard>
<!-- Default user locale (language).
Empty means system locale setting,
no (or commented-out) <default_locale> tag means no translations. -->
<!-- <default_locale>pl_PL</default_locale> -->
<!-- Logger configuration.
You may configure one logger of type "syslog" and/or one of type "file".
You may also not configure logging at all. -->
<log type="syslog" facility="local0"/>
<log type="file">/var/log/jabber/jabber-gg-transport.log</log>
<!-- Uncomment this, if you want proxy to be used for Gadu-Gadu connection. -->
<!--
<proxy>
<ip>127.0.0.1</ip>
<port>8080</port>
</proxy>
-->
<!-- You can change these values according to your needs. -->
<conn_timeout>60</conn_timeout>
<ping_interval>10</ping_interval>
<!-- Gadu-Gadu server doesn't seem to answer pings anymore :-(
So let's give it 10 year :-) -->
<pong_timeout>315360000</pong_timeout>
<!-- This time after disconnection from Gadu-Gadu server the transport
will try to connect again. -->
<reconnect>300</reconnect>
<!-- How long to wait before restart, after jabber server connection is broken
negative value means, that jggtrans should terminate. -->
<restart_timeout>60</restart_timeout>
<!-- Delay between the unavailable presence is received from user and loggin out
from Gadu-Gadu - for nice <presence type="invisible"/> support. -->
<disconnect_delay>5</disconnect_delay>
<!-- list of Gadu-Gadu servers to use.
<hub/> means "use GG hub to find server"
<server/> tag should contain server address and may contain "port"
attribute with port number. When TLS is available (supported by libgadu)
it will be used unless "tls" attribute is set to "no". Please notice,
that not all servers will accept TLS connections.
Servers (including hub) are tried in order as they appear in <servers/>
element.
A reasonable default server list is hardcoded in jggtrans.
-->
<!--
<servers>
<hub/>
<server port="443">217.17.41.90</server>
<server tls="no">217.17.41.85</server>
<server tls="no">217.17.41.88</server>
</servers>
-->
<!-- Spool directory. This is the place, where user info will be stored. -->
<!-- Be careful about permissions - users' Gadu-Gadu passwords are stored there. -->
<spool>/var/spool/jabber/gg.SERVER.COM/</spool>
<!-- Where to store pid file. This tag is optional. -->
<pidfile>/var/run/jabber/jabber-gg-transport.pid</pidfile>
<!-- jid allowed to do some administrative task (eg. discovering online users).
May be used multiple times. -->
<admin>GG_TRANSPORT_ADMIN@SERVER.COM</admin>
<!-- ACL gives detailed access control to the transport. -->
<acl>
<!-- Example entries: -->
<allow who="admin@SERVER.COM" what="iq/query?xmlns=http://jabber.org/protocol/stats"/>
<!-- will allow statistics gathering to admin@SERVER.COM -->
<deny who="*" what="iq/query?xmlns=http://jabber.org/protocol/stats"/>
<!-- will deny statistics gathering for anybody else -->
<!-- <allow who="*@SERVER.COM"/> -->
<!-- will allow anything else to users from "SERVER.COM" -->
<!-- <deny what="iq/query?xmlns=jabber:x:register"/> -->
<!-- will deny registration for all other users -->
<!-- <allow what="presence"/> -->
<!-- allow presence from anybody -->
<!-- <allow what="iq"/> -->
<!-- allow iq from anybody -->
<!-- <allow what="message"/> -->
<!-- allow message from anybody -->
<!-- <deny/> -->
<!-- will deny anything else -->
</acl>
</jggtrans>
+128
View File
@@ -0,0 +1,128 @@
<!-- jit.xml -->
<jabber>
<!--
You need to add elogger and rlogger entries here when using ejabberd.
In this case the transport will do the logging.
-->
<log id='elogger'>
<host/>
<logtype/>
<file>/var/log/jabber/jit-error</file> <!-- WPJabber logs with date. -->
</log>
<log id='rlogger'>
<host/>
<logtype>record</logtype>
<file>/var/log/jabber/jit-record</file> <!-- WPJabber logs with date. -->
</log>
<!--
ejabberd do not provide XDB services.
xdb_file-jit.so (the renamed xdb_file.so from WPJabber) is
loaded in to handle all XDB requests.
Read also the documentation in xdb_file/README from the JIT package.
-->
<xdb id="xdb">
<host/>
<load>
<xdb_file>/usr/local/lib/jabber/xdb_file.so</xdb_file> <!-- The xdb_file.so from WPJabber/JIT. -->
</load>
<xdb_file xmlns="jabber:config:xdb_file">
<spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>
</xdb_file>
</xdb>
<!--
Make sure that all host names here are resolveable via DNS if you
want the transport to be available to the public.
-->
<service id="icq.SERVER.COM">
<!--
Replace SERVER.COM with the same as above to enable sms.
-->
<host>sms.icq.SERVER.COM</host>
<!-- JIT configuration. -->
<icqtrans xmlns="jabber:config:icqtrans">
<sms>
<host>sms.icq.SERVER.COM</host>
<!-- Status of virtual "sms-contacts". -->
<show>away</show>
<status/>
</sms>
<instructions>Fill in your UIN and password.</instructions>
<search>Search ICQ users.</search>
<vCard>
<FN>ICQ Transport (JIT)</FN>
<DESC>This is the Jabber ICQ Transport.</DESC>
<MAIL>EMAIL@ADDRESS.COM</MAIL>
<URL>http://jit.jabberstudio.org/</URL>
</vCard>
<!-- Hashtable for users. -->
<prime>3907</prime>
<!-- Send messages from ICQ as chat to Jabber clients. -->
<chat/>
<!-- Enable this for ICQ web presence. -->
<web/>
<!--
If you don't want jabber:x:data forms
in reg and search uncomment this tag
(Not recomended).
-->
<no_xdata/>
<!--
This tag is necessary when using ejabberd.
In this way JIT will have its own contact list.
-->
<own_roster/>
<!--
When present, this tag will tell JIT not to try to
get the user's roster (which will take a bit of time
to fail in scenarios described above).
-->
<no_jabber_roster/>
<!-- File with stats. -->
<user_count_file>/var/spool/jabber/jit-count</user_count_file>
<!--
Interval beetween checking sessions: ping, messages, acks.
-->
<session_check>5</session_check>
<!-- Reconnect retries. -->
<reconnects>5</reconnects>
<!--
Time in sec when session can be inactive, 0=disabled.
-->
<session_timeout>18000</session_timeout>
<charset>windows-1252</charset>
<server>
<host port="5190">login.icq.com</host>
</server>
</icqtrans>
<!-- JIT module. -->
<load>
<icqtrans>/usr/local/lib/jabber/jit.so</icqtrans>
</load>
</service>
<!--
The settings below have to match the settings you made
in your ejabberd.cfg configuration file.
-->
<service id="icq-linker">
<host>SERVER.COM</host>
<uplink/>
<connect>
<ip>127.0.0.1</ip>
<port>5234</port>
<secret>SECRET</secret>
</connect>
</service>
<pidfile>/var/run/jabber/jit.pid</pidfile>
</jabber>
@@ -0,0 +1,118 @@
<!-- msn-transport.xml -->
<jabber>
<!--
You need to add elogger and rlogger entries here when using ejabberd.
In this case the transport will do the logging.
-->
<log id='elogger'>
<host/>
<logtype/>
<format>%d: [%t] (%h): %s</format>
<file>/var/log/jabber/msn-transport-error.log</file>
</log>
<log id='rlogger'>
<host/>
<logtype>record</logtype>
<format>%d %h %s</format>
<file>/var/log/jabber/msn-transport-record.log</file>
</log>
<!--
ejabberd do not provide XDB services.
xdb_file.so is loaded in to handle all XDB requests.
-->
<xdb id="xdb">
<host/>
<load>
<xdb_file>/usr/local/lib/jabber/libjabberdxdbfile.so</xdb_file>
</load>
<xdb_file xmlns="jabber:config:xdb_file">
<spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>
</xdb_file>
</xdb>
<!--
Make sure that all host names here are resolveable via DNS if you
want the transport to be available to the public.
-->
<service id="msn.SERVER.COM">
<!-- msn-transport configuration. -->
<msntrans xmlns="jabber:config:msntrans">
<instructions>Fill in your MSN account and password (eg: user1@hotmail.com). A nickname is optional.</instructions>
<vCard>
<FN>MSN Transport</FN>
<DESC>This is the MSN Transport.</DESC>
<EMAIL>EMAIL@ADDRESS.COM</EMAIL>
<URL>http://msn-transport.jabberstudio.org/</URL>
</vCard>
<!--
Conference support allows you to create groupchat rooms on the
msn-transport and invite MSN users to join.
-->
<conference id="conference.msn.SERVER.COM">
<!--
This will make MSN transport invite you to a special groupchat
room when more then one user joins a normal one-on-one session.
Joining this room will make MSN transport "switch" the session
into groupchat mode. If you ignore it, MSN transport will
continue to send the messages as one-on-one chats.
-->
<invite>More than one user entered this chat session. Enter this room to switch to groupchat modus.</invite>
<notice>
<join> is available</join>
<leave> has leaved the room</leave>
</notice>
</conference>
<!-- Enable Hotmail inbox notification. -->
<headlines/>
<!--
Enable fancy friendly names
If the user enters a nickname upon registration, and the user has
a status message, their MSN friendly name will be "nickname - status message".
If the user does not enter a nickname on registration, but they do have
a status message, their friendly name will just be their status message.
If the user did enter a nickname on registration, but they have a blank status message,
then their friendly name will just be the registered nickname.
If the user did not enter a nickname on registration, and they have a blank status message,
their nickname will just be the username portion of their JID.
If the above chosen friendly name is too long, then it will be truncated and "..." placed
at the end. MSN only supports friendly names of 128 characters, so this is unavoidable.
If this is disabled, then the registered nick is always sent as the MSN friendly name,
or if that is blank, the username portion of their JID is sent instead.
-->
<fancy_friendly/>
</msntrans>
<!-- msn-transport module. -->
<load>
<msntrans>/usr/local/lib/jabber/msn-transport.so</msntrans>
</load>
</service>
<!--
The settings below have to match the settings you made
in your ejabberd.cfg configuration file.
-->
<service id="msn-linker">
<uplink/>
<connect>
<ip>127.0.0.1</ip>
<port>5235</port>
<secret>SECRET</secret>
</connect>
</service>
<pidfile>/var/run/jabber/msn-transport.pid</pidfile>
</jabber>
@@ -0,0 +1,86 @@
<!-- yahoo-transport-2.xml -->
<jabber>
<!--
You need to add the elogger entry here when using ejabberd.
In this case the transport will do the logging.
-->
<log id='elogger'>
<host/>
<logtype/>
<format>%d: [%t] (%h): %s</format>
<file>/var/log/jabber/yahoo-transport-2-error.log</file>
<stderr/>
</log>
<!--
ejabberd do not provide XDB services.
xdb_file.so is loaded in to handle all XDB requests.
-->
<xdb id="xdb">
<host/>
<load>
<xdb_file>/usr/local/lib/jabber/libjabberdxdbfile.so</xdb_file>
</load>
<xdb_file xmlns="jabber:config:xdb_file">
<spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>
</xdb_file>
</xdb>
<!--
Make sure that all host names here are resolveable via DNS if you
want the transport to be available to the public.
-->
<service id="yahoo.SERVER.COM">
<!-- yahoo-transport-2 configuration. -->
<config xmlns="jabber:config:yahoo">
<vCard>
<NAME>Yahoo! Transport</NAME>
<FN>vCard not implemented in current version</FN>
<DESC>This is the Yahoo! transport.</DESC>
<MAIL>EMAIL@ADDRESS.COM</MAIL>
<URL>http://yahoo-transport-2.jabberstudio.org/</URL>
</vCard>
<instructions>Fill in your YAHOO! Messenger username and password to register on this transport.</instructions>
<server>scs.msg.yahoo.com</server>
<port>5050</port>
<!--
The character map. This provides character set translation from UTF-8
to the indicated character map. See the man page for 'iconv' for available
character maps on your platform. CP1252 is the standard Windows character
set.
-->
<charmap>CP1252</charmap>
<!--
When this element exists, the transport will send new mail notifications as
well as a count of unread messages when the user initially logs in.
-->
<newmail/>
</config>
<!-- yahoo-transport-2 module. -->
<load>
<yahoo_transport>/usr/local/lib/jabber/yahoo-transport-2.so</yahoo_transport>
</load>
</service>
<!--
The settings below have to match the settings you made
in your ejabberd.cfg configuration file.
-->
<service id="yahoo-linker">
<uplink/>
<connect>
<ip>127.0.0.1</ip>
<port>5236</port>
<secret>SECRET</secret>
</connect>
</service>
<pidfile>/var/run/jabber/yahoo-transport-2.pid</pidfile>
</jabber>
+45
View File
@@ -0,0 +1,45 @@
#!/bin/sh
#########################################################
#
# aim-transport -- script to start aim-transport.
#
#########################################################
DAEMON=/usr/local/sbin/jabberd-aim-transport
CONF=/etc/jabber/aim-transport.xml
NAME=jabberd-aim-transport
HOME=/etc/jabber/
USER=ejabberd
#########################################################
if [ "`/usr/bin/whoami`" != "$USER" ]; then
echo "You need to be" $USER "user to run this script."
exit 1
fi
case "$1" in
debug)
test -f $DAEMON -a -f $CONF || exit 0
echo "Starting $NAME in debugging mode."
$DAEMON -D -H $HOME -c $CONF &
;;
start)
test -f $DAEMON -a -f $CONF || exit 0
echo "Starting $NAME."
$DAEMON -H $HOME -c $CONF &
;;
stop)
echo "Stopping $NAME."
killall $NAME &
;;
restart|reload)
$0 stop
sleep 3
$0 start
;;
*)
echo "Usage: $0 {debug|start|stop|restart}"
exit 1
esac
+43
View File
@@ -0,0 +1,43 @@
#!/bin/sh
#########################################################
#
# ile -- script to start ILE.
#
#########################################################
DAEMON=/usr/local/sbin/ile.pl
NAME=ile.pl
CONF=/etc/jabber/ile.xml
USER=ejabberd
#########################################################
if [ "`/usr/bin/whoami`" != "$USER" ]; then
echo "You need to be" $USER "user to run this script."
exit 1
fi
case "$1" in
debug)
echo "Not implemented yet. Starting in normal mode"
$0 start
;;
start)
test -f $DAEMON || exit 0
echo "Starting $NAME."
$DAEMON $CONF &
;;
stop)
echo "Stopping $NAME."
killall $NAME &
;;
restart|reload)
$0 stop
sleep 3
$0 start
;;
*)
echo "Usage: $0 {debug|start|stop|status|restart}"
exit 1
esac
@@ -0,0 +1,47 @@
#!/bin/sh
#########################################################
#
# jabber-gg-transport -- script to start jabber-gg-transport.
#
#########################################################
DAEMON=/usr/local/sbin/jggtrans
CONF=/etc/jabber/jabber-gg-transport.xml
NAME=jggtrans
HOME=/etc/jabber/
USER=ejabberd
#########################################################
if [ "`/usr/bin/whoami`" != "$USER" ]; then
echo "You need to be" $USER "user to run this script."
exit 1
fi
case "$1" in
debug)
test -f $DAEMON -a -f $CONF || exit 0
echo "Starting $NAME in debugging mode."
$DAEMON -D -H $HOME -c $CONF &
;;
start)
test -f $DAEMON -a -f $CONF || exit 0
echo "Starting $NAME."
$DAEMON $CONF &
;;
stop)
echo "Stopping $NAME."
killall $NAME &
rm /var/run/jabber/jabber-gg-transport.pid
;;
restart|reload)
$0 stop
sleep 3
$0 start
;;
*)
echo "Usage: $0 {debug|start|stop|restart}"
exit 1
esac
+45
View File
@@ -0,0 +1,45 @@
#!/bin/sh
#########################################################
#
# jit -- script to start JIT.
#
#########################################################
DAEMON=/usr/local/sbin/wpjabber-jit
CONF=/etc/jabber/jit.xml
NAME=wpjabber-jit
HOME=/etc/jabber/
USER=ejabberd
#########################################################
if [ "`/usr/bin/whoami`" != "$USER" ]; then
echo "You need to be" $USER "user to run this script."
exit 1
fi
case "$1" in
debug)
test -f $DAEMON -a -f $CONF || exit 0
echo "Starting $NAME in debugging mode."
$DAEMON -D -H $HOME -c $CONF &
;;
start)
test -f $DAEMON -a -f $CONF || exit 0
echo "Starting $NAME."
$DAEMON -H $HOME -c $CONF &
;;
stop)
echo "Stopping $NAME."
killall $NAME &
;;
restart|reload)
$0 stop
sleep 3
$0 start
;;
*)
echo "Usage: $0 {debug|start|stop|restart}"
exit 1
esac
+50
View File
@@ -0,0 +1,50 @@
#!/bin/sh
#########################################################
#
# msn-transport -- script to start MSN Transport.
#
#########################################################
DAEMON=/usr/local/sbin/jabberd-msn-transport
CONF=/etc/jabber/msn-transport.xml
NAME=jabberd-msn-transport
HOME=/etc/jabber/
USER=ejabberd
#########################################################
if [ "`/usr/bin/whoami`" != "$USER" ]; then
echo "You need to be" $USER "user to run this script."
exit 1
fi
case "$1" in
strace)
test -f $DAEMON -a -f $CONF || exit 0
echo "Starting $NAME in strace mode."
strace -o /opt/ejabberd/var/log/jabber/strace.log $DAEMON -H $HOME -c $CONF &
;;
debug)
test -f $DAEMON -a -f $CONF || exit 0
echo "Starting $NAME in debugging mode."
$DAEMON -D -H $HOME -c $CONF &
;;
start)
test -f $DAEMON -a -f $CONF || exit 0
echo "Starting $NAME."
$DAEMON -H $HOME -c $CONF &
;;
stop)
echo "Stopping $NAME."
killall $NAME &
;;
restart|reload)
$0 stop
sleep 3
$0 start
;;
*)
echo "Usage: $0 {debug|start|stop|restart}"
exit 1
esac
+45
View File
@@ -0,0 +1,45 @@
#!/bin/sh
##############################################################
#
# yahoo-transport-2 -- script to start Yahoo-transport-2.
#
#############################################################
DAEMON=/usr/local/sbin/jabberd-yahoo-transport-2
CONF=/etc/jabber/yahoo-transport-2.xml
NAME=jabberd-yahoo-transport-2
HOME=/etc/jabber/
USER=ejabberd
#############################################################
if [ "`/usr/bin/whoami`" != "$USER" ]; then
echo "You need to be" $USER "user to run this script."
exit 1
fi
case "$1" in
debug)
test -f $DAEMON -a -f $CONF || exit 0
echo "Starting $NAME in debugging mode."
$DAEMON -D -H $HOME -c $CONF &
;;
start)
test -f $DAEMON -a -f $CONF || exit 0
echo "Starting $NAME."
$DAEMON -H $HOME -c $CONF &
;;
stop)
echo "Stopping $NAME."
killall $NAME &
;;
restart|reload)
$0 stop
sleep 3
$0 start
;;
*)
echo "Usage: $0 {debug|start|stop|restart}"
exit 1
esac
-81
View File
@@ -1,81 +0,0 @@
%% Generated by the Erlang ASN.1 compiler version:2.0.1
%% Purpose: Erlang record definitions for each named and unnamed
%% SEQUENCE and SET, and macro definitions for each value
%% definition,in module ELDAPv3
-record('LDAPMessage',{
messageID, protocolOp, controls = asn1_NOVALUE}).
-record('AttributeValueAssertion',{
attributeDesc, assertionValue}).
-record('Attribute',{
type, vals}).
-record('LDAPResult',{
resultCode, matchedDN, errorMessage, referral = asn1_NOVALUE}).
-record('Control',{
controlType, criticality = asn1_DEFAULT, controlValue = asn1_NOVALUE}).
-record('BindRequest',{
version, name, authentication}).
-record('SaslCredentials',{
mechanism, credentials = asn1_NOVALUE}).
-record('BindResponse',{
resultCode, matchedDN, errorMessage, referral = asn1_NOVALUE, serverSaslCreds = asn1_NOVALUE}).
-record('SearchRequest',{
baseObject, scope, derefAliases, sizeLimit, timeLimit, typesOnly, filter, attributes}).
-record('SubstringFilter',{
type, substrings}).
-record('MatchingRuleAssertion',{
matchingRule = asn1_NOVALUE, type = asn1_NOVALUE, matchValue, dnAttributes = asn1_DEFAULT}).
-record('SearchResultEntry',{
objectName, attributes}).
-record('PartialAttributeList_SEQOF',{
type, vals}).
-record('ModifyRequest',{
object, modification}).
-record('ModifyRequest_modification_SEQOF',{
operation, modification}).
-record('AttributeTypeAndValues',{
type, vals}).
-record('AddRequest',{
entry, attributes}).
-record('AttributeList_SEQOF',{
type, vals}).
-record('ModifyDNRequest',{
entry, newrdn, deleteoldrdn, newSuperior = asn1_NOVALUE}).
-record('CompareRequest',{
entry, ava}).
-record('ExtendedRequest',{
requestName, requestValue = asn1_NOVALUE}).
-record('ExtendedResponse',{
resultCode, matchedDN, errorMessage, referral = asn1_NOVALUE, responseName = asn1_NOVALUE, response = asn1_NOVALUE}).
-record('PasswdModifyRequestValue',{
userIdentity = asn1_NOVALUE, oldPasswd = asn1_NOVALUE, newPasswd = asn1_NOVALUE}).
-record('PasswdModifyResponseValue',{
genPasswd = asn1_NOVALUE}).
-define('maxInt', 2147483647).
-define('passwdModifyOID', [49,46,51,46,54,46,49,46,52,46,49,46,52,50,48,51,46,49,46,49,49,46,49]).
-51
View File
@@ -1,51 +0,0 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2026 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-define(CT_XML,
{<<"Content-Type">>, <<"text/xml; charset=utf-8">>}).
-define(CT_PLAIN,
{<<"Content-Type">>, <<"text/plain">>}).
-define(CT_JSON,
{<<"Content-Type">>, <<"application/json">>}).
-define(AC_ALLOW_ORIGIN,
{<<"Access-Control-Allow-Origin">>, <<"*">>}).
-define(AC_ALLOW_METHODS,
{<<"Access-Control-Allow-Methods">>,
<<"GET, POST, OPTIONS">>}).
-define(AC_ALLOW_HEADERS,
{<<"Access-Control-Allow-Headers">>,
<<"Content-Type">>}).
-define(AC_MAX_AGE,
{<<"Access-Control-Max-Age">>, <<"86400">>}).
-define(OPTIONS_HEADER,
[?CT_PLAIN, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_METHODS,
?AC_ALLOW_HEADERS, ?AC_MAX_AGE]).
-define(HEADER(CType),
[CType, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_HEADERS]).
-define(BOSH_CACHE, bosh_cache).
-22
View File
@@ -1,22 +0,0 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2026 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-record(passwd, {us = {<<"">>, <<"">>} :: {binary(), binary()} | {binary(), binary(), atom()} | '$1',
password = <<"">> :: binary() | scram() | '_'}).
-111
View File
@@ -1,111 +0,0 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2026 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-type aterm() :: {atom(), atype()}.
-type atype() :: integer | string | binary | any | atom |
{tuple, [aterm()]} | {list, aterm()}.
-type rterm() :: {atom(), rtype()}.
-type rtype() :: integer | string | atom | any |
{tuple, [rterm()]} | {list, rterm()} |
rescode | restuple.
%% The 'any' and 'atom' argument types and 'any' result type
%% should only be used by commands with tag 'internal',
%% which are meant to be used only internally in ejabberd,
%% and not called using external frontends.
%% When a command with tag 'async' is called by mod_adhoc_api,
%% it is spawned in a new process for the command execution,
%% and the command immediately returns success.
%% The purpose of a command can either be:
%% - informative: its purpose is to obtain information
%% - modifier: its purpose is to produce some change in the server
%%
%% A modifier command should be designed just to produce its desired side-effect,
%% and its result term should just be success or failure: rescode or restuple.
%%
%% ejabberd_web_admin:make_command/2 considers that commands
%% with result type different than rescode or restuple
%% are commands that can be safely executed automatically
%% to get information and build the web page.
-type oauth_scope() :: atom().
%% ejabberd_commands OAuth ReST ACL definition:
%% Two fields exist that are used to control access on a command from ReST API:
%% 1. Policy
%% If policy is:
%% - restricted: command is not exposed as OAuth Rest API.
%% - admin: Command is allowed for user that have Admin Rest command enabled by access rule: commands_admin_access
%% - user: Command might be called by any server user.
%% - open: Command can be called by anyone.
%%
%% Policy is just used to control who can call the command. A specific additional access rules can be performed, as
%% defined by access option.
%% Access option can be a list of:
%% - {Module, accessName, DefaultValue}: Reference and existing module access to limit who can use the command.
%% - AccessRule name: direct name of the access rule to check in config file.
%% TODO: Access option could be atom command (not a list). In the case, User performing the command, will be added as first parameter
%% to command, so that the command can perform additional check.
-record(ejabberd_commands,
{name :: atom(),
tags = [] :: [atom()] | '_' | '$2',
desc = "" :: string() | '_' | '$3',
longdesc = "" :: string() | '_',
version = 0 :: integer(),
note = "" :: string(),
weight = 1 :: integer(),
module :: atom() | '_',
function :: atom() | '_',
args = [] :: [aterm()] | '_' | '$1' | '$2',
policy = restricted :: open | restricted | admin | user,
%% access is: [accessRuleName] or [{Module, AccessOption, DefaultAccessRuleName}]
access = [] :: [{atom(),atom(),atom()}|atom()],
definer = unknown :: atom(),
result = {res, rescode} :: rterm() | '_' | '$2',
args_rename = [] :: [{atom(),atom()}],
args_desc = none :: none | [string()] | '_',
result_desc = none :: none | string() | '_',
args_example = none :: none | [any()] | '_',
result_example = none :: any()}).
-type ejabberd_commands() :: #ejabberd_commands{name :: atom(),
tags :: [atom()],
desc :: string(),
longdesc :: string(),
version :: integer(),
note :: string(),
weight :: integer(),
module :: atom(),
function :: atom(),
args :: [aterm()],
policy :: open | restricted | admin | user,
access :: [{atom(),atom(),atom()}|atom()],
definer :: atom(),
result :: rterm(),
args_rename :: [{atom(),atom()}],
args_desc :: none | [string()] | '_',
result_desc :: none | string() | '_',
args_example :: none | [any()] | '_',
result_example :: any()
}.
-27
View File
@@ -1,27 +0,0 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2026 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-define(STATUS_SUCCESS, 0).
-define(STATUS_ERROR, 1).
-define(STATUS_USAGE, 2).
-define(STATUS_BADRPC, 3).
-70
View File
@@ -1,70 +0,0 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2026 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-record(serialize_mam_v1, {
serverhost :: binary(),
username :: binary(),
timestamp :: integer(),
peer :: binary(),
type :: chat | groupchat,
nick :: binary(),
origin_id :: binary(),
packet :: binary()
}).
-record(serialize_mam_prefs_v1, {
serverhost :: binary(),
username :: binary(),
default :: atom(),
always :: term(),
never :: term()
}).
-record(serialize_roster_v1, {
serverhost :: binary(),
username :: binary(),
version :: binary() | undefined,
entries :: [{binary(),
binary(),
[binary()],
both | from | to | none,
boolean(),
subscribe | unsubscribe | both | in | out | none,
binary()}]
}).
-record(serialize_auth_v1, {
serverhost :: binary(),
username :: binary(),
passwords :: [binary() | {sha | sha256 | sha512, binary(), binary(), binary(), integer()}]
}).
-record(serialize_muc_room_v1, {
serverhost :: binary(),
name :: binary(),
host :: binary(),
options:: [{atom(), term()}]
}).
-record(serialize_muc_registrations_v1, {
serverhost :: binary(),
host :: binary(),
jid :: binary(),
nick :: binary()
}).
-55
View File
@@ -1,55 +0,0 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2026 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-record(request,
{method :: method(),
path = [] :: [binary()],
raw_path :: binary(),
q = [] :: [{binary() | nokey, binary()}],
us = {<<>>, <<>>} :: {binary(), binary()},
auth :: {binary(), binary()} | {oauth, binary(), []} | undefined | invalid,
lang = <<"">> :: binary(),
data = <<"">> :: binary(),
ip :: {inet:ip_address(), inet:port_number()},
host = <<"">> :: binary(),
port = 5280 :: inet:port_number(),
opts = [] :: list(),
tp = http :: protocol(),
headers = [] :: [{atom() | binary(), binary()}],
length = 0 :: non_neg_integer(),
sockmod :: gen_tcp | fast_tls,
socket :: inet:socket() | fast_tls:tls_socket()}).
-record(ws,
{socket :: inet:socket() | fast_tls:tls_socket(),
sockmod = gen_tcp :: gen_tcp | fast_tls,
ip :: {inet:ip_address(), inet:port_number()},
host = <<"">> :: binary(),
port = 5280 :: inet:port_number(),
path = [] :: [binary()],
headers = [] :: [{atom() | binary(), binary()}],
local_path = [] :: [binary()],
q = [] :: [{binary() | nokey, binary()}],
buf :: binary(),
http_opts = [] :: list()}).
-type method() :: 'GET' | 'HEAD' | 'DELETE' | 'OPTIONS' | 'PUT' | 'POST' | 'TRACE' | 'PATCH'.
-type protocol() :: http | https.
-type http_request() :: #request{}.
-33
View File
@@ -1,33 +0,0 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2026 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-record(oauth_token, {
token = <<"">> :: binary() | '_',
us = {<<"">>, <<"">>} :: {binary(), binary()} | '_',
scope = [] :: [binary()] | '_',
expire :: integer() | '$1' | '_'
}).
-record(oauth_client, {
client_id = <<"">> :: binary() | '_',
client_name = <<"">> :: binary() | '_',
grant_type :: password | implicit | '_',
options :: [any()] | '_'
}).
-8
View File
@@ -1,8 +0,0 @@
-define(ROUTES_CACHE, routes_cache).
-type local_hint() :: integer() | {apply, atom(), atom()}.
-record(route, {domain :: binary(),
server_host :: binary(),
pid :: undefined | pid(),
local_hint :: local_hint() | undefined}).
-36
View File
@@ -1,36 +0,0 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2026 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-ifndef(EJABBERD_SM_HRL).
-define(EJABBERD_SM_HRL, true).
-define(SM_CACHE, sm_cache).
-record(session, {sid, usr, us, priority, info = []}).
-record(session_counter, {vhost, count}).
-type sid() :: {erlang:timestamp(), pid()}.
-type ip() :: {inet:ip_address(), inet:port_number()} | undefined.
-type info() :: [{conn, atom()} | {ip, ip()} | {node, atom()}
| {oor, boolean()} | {auth_module, atom()}
| {num_stanzas_in, non_neg_integer()}
| {atom(), term()}].
-type prio() :: undefined | integer().
-endif.
-70
View File
@@ -1,70 +0,0 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2026 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-define(SQL_MARK, sql__mark_).
-define(SQL(SQL), ?SQL_MARK(SQL)).
-define(SQL_UPSERT_MARK, sql_upsert__mark_).
-define(SQL_UPSERT(Host, Table, Fields),
ejabberd_sql:sql_query(Host, ?SQL_UPSERT_MARK(Table, Fields))).
-define(SQL_UPSERT_T(Table, Fields),
ejabberd_sql:sql_query_t(?SQL_UPSERT_MARK(Table, Fields))).
-define(SQL_INSERT_MARK, sql_insert__mark_).
-define(SQL_INSERT(Table, Fields), ?SQL_INSERT_MARK(Table, Fields)).
-record(sql_query, {hash :: binary(),
format_query :: fun(),
format_res :: fun(),
args :: fun(),
flags :: non_neg_integer(),
loc :: {module(), {pos_integer(), pos_integer()}}}).
-record(sql_escape, {
string :: fun((binary()) -> binary() | atom()),
integer :: fun((integer()) -> binary() | atom()),
boolean :: fun((boolean()) -> binary() | atom()),
timestamp :: fun((calendar:datetime()) -> binary() | atom()),
in_array_string :: fun((binary()) -> binary() | atom()),
like_escape :: fun(() -> binary() | atom())
}).
-record(sql_index, {columns,
unique = false :: boolean(),
meta = #{}}).
-record(sql_column, {name :: binary(),
type,
nullable = false,
default = false,
opts = []}).
-record(sql_table, {name :: binary(),
columns :: [#sql_column{}],
indices = [] :: [#sql_index{}],
post_create}).
-record(sql_schema, {version :: integer(),
tables :: [#sql_table{}],
update = []}).
-record(sql_references, {table :: binary(),
column :: binary()}).
-record(sql_schema_info,
{db_type :: pgsql | mysql | sqlite,
db_version :: any(),
multihost_schema = true :: boolean()}).
-21
View File
@@ -1,21 +0,0 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2026 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-compile([{parse_transform, ejabberd_sql_pt}]).
-include("ejabberd_sql.hrl").
-126
View File
@@ -1,126 +0,0 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2026 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-define(X(Name),
#xmlel{name = Name, attrs = [], children = []}).
-define(XA(Name, Attrs),
#xmlel{name = Name, attrs = Attrs, children = []}).
-define(XE(Name, Els),
#xmlel{name = Name, attrs = [], children = Els}).
-define(XAE(Name, Attrs, Els),
#xmlel{name = Name, attrs = Attrs, children = Els}).
-define(C(Text), {xmlcdata, Text}).
-define(XC(Name, Text), ?XE(Name, [?C(Text)])).
-define(XAC(Name, Attrs, Text),
?XAE(Name, Attrs, [?C(Text)])).
-define(CT(Text), ?C((translate:translate(Lang, Text)))).
-define(XCT(Name, Text), ?XC(Name, (translate:translate(Lang, Text)))).
-define(XACT(Name, Attrs, Text),
?XAC(Name, Attrs, (translate:translate(Lang, Text)))).
-define(LI(Els), ?XE(<<"li">>, Els)).
-define(A(URL, Els),
?XAE(<<"a">>, [{<<"href">>, URL}], Els)).
-define(AC(URL, Text), ?A(URL, [?C(Text)])).
-define(ACT(URL, Text), ?AC(URL, (translate:translate(Lang, Text)))).
-define(P, ?X(<<"p">>)).
-define(BR, ?X(<<"br">>)).
-define(INPUT(Type, Name, Value),
?XA(<<"input">>,
[{<<"type">>, Type}, {<<"name">>, Name},
{<<"value">>, Value}])).
-define(INPUTPH(Type, Name, Value, PlaceHolder),
?XA(<<"input">>,
[{<<"type">>, Type}, {<<"name">>, Name},
{<<"value">>, Value}, {<<"placeholder">>, PlaceHolder}])).
-define(INPUTT(Type, Name, Value),
?INPUT(Type, Name, (translate:translate(Lang, Value)))).
-define(INPUTD(Type, Name, Value),
?XA(<<"input">>,
[{<<"type">>, Type}, {<<"name">>, Name},
{<<"class">>, <<"btn-danger">>}, {<<"value">>, Value}])).
-define(INPUTTD(Type, Name, Value),
?INPUTD(Type, Name, (translate:translate(Lang, Value)))).
-define(INPUTS(Type, Name, Value, Size),
?XA(<<"input">>,
[{<<"type">>, Type}, {<<"name">>, Name},
{<<"value">>, Value}, {<<"size">>, Size}])).
-define(INPUTST(Type, Name, Value, Size),
?INPUT(Type, Name, (translate:translate(Lang, Value)), Size)).
-define(ACLINPUT(Text),
?XE(<<"td">>,
[?INPUT(<<"text">>, <<"value", ID/binary>>, Text)])).
-define(TEXTAREA(Name, Rows, Cols, Value),
?XAC(<<"textarea">>,
[{<<"name">>, Name}, {<<"rows">>, Rows},
{<<"cols">>, Cols}],
Value)).
%% Build an xmlelement for result
-define(XRES(Text),
?XAC(<<"p">>, [{<<"class">>, <<"result">>}], Text)).
-define(DIVRES(Elements),
?XAE(<<"div">>, [{<<"class">>, <<"result">>}], Elements)).
%% Guide Link
-define(XREST(Text), ?XRES((translate:translate(Lang, Text)))).
-define(GL(Ref, Title),
?XAE(<<"div">>, [{<<"class">>, <<"guidelink">>}],
[?XAE(<<"a">>,
[{<<"href">>, <<"https://docs.ejabberd.im/", Ref/binary>>},
{<<"target">>, <<"_blank">>}],
[?C(<<"docs: ", Title/binary>>)])])).
%% h1 with a Guide Link
-define(H1GLraw(Name, Ref, Title),
[?XC(<<"h1">>, Name), ?GL(Ref, Title), ?BR, ?BR]).
-define(H1GL(Name, RefConf, Title),
?H1GLraw(Name, <<"admin/configuration/", RefConf/binary>>, Title)).
-define(ANCHORL(Ref),
?XAE(<<"div">>, [{<<"class">>, <<"anchorlink">>}],
[?XAE(<<"a">>,
[{<<"href">>, <<"#", Ref/binary>>}],
[?C(unicode:characters_to_binary(""))])])).
-79
View File
@@ -1,79 +0,0 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2026 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-define(LDAP_PORT, 389).
-define(LDAPS_PORT, 636).
-type scope() :: baseObject | singleLevel | wholeSubtree.
-record(eldap_search,
{scope = wholeSubtree :: scope(),
base = <<"">> :: binary(),
filter :: eldap:filter() | undefined,
limit = 0 :: non_neg_integer(),
attributes = [] :: [binary()],
types_only = false :: boolean(),
deref_aliases = neverDerefAliases :: neverDerefAliases |
derefInSearching |
derefFindingBaseObj |
derefAlways,
timeout = 0 :: non_neg_integer()}).
-record(eldap_search_result, {entries = [] :: [eldap_entry()],
referrals = [] :: list()}).
-record(eldap_entry, {object_name = <<>> :: binary(),
attributes = [] :: [{binary(), [binary()]}]}).
-type tlsopts() :: [{encrypt, tls | starttls | none} |
{tls_certfile, binary() | undefined} |
{tls_cacertfile, binary() | undefined} |
{tls_depth, non_neg_integer() | undefined} |
{tls_verify, hard | soft | false}].
-record(eldap_config, {servers = [] :: [binary()],
backups = [] :: [binary()],
tls_options = [] :: tlsopts(),
port = ?LDAP_PORT :: inet:port_number(),
dn = <<"">> :: binary(),
password = <<"">> :: binary(),
base = <<"">> :: binary(),
deref_aliases = never :: never | searching |
finding | always}).
-type eldap_config() :: #eldap_config{}.
-type eldap_search() :: #eldap_search{}.
-type eldap_entry() :: #eldap_entry{}.
-define(eldap_config(M, H),
#eldap_config{
servers = M:ldap_servers(H),
backups = M:ldap_backups(H),
tls_options = [{encrypt, M:ldap_encrypt(H)},
{tls_verify, M:ldap_tls_verify(H)},
{tls_certfile, M:ldap_tls_certfile(H)},
{tls_cacertfile, M:ldap_tls_cacertfile(H)},
{tls_depth, M:ldap_tls_depth(H)}],
port = M:ldap_port(H),
dn = M:ldap_rootdn(H),
password = M:ldap_password(H),
base = M:ldap_base(H),
deref_aliases = M:ldap_deref_aliases(H)}).
-49
View File
@@ -1,49 +0,0 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2026 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-define(CT_XML,
{<<"Content-Type">>, <<"text/xml; charset=utf-8">>}).
-define(CT_PLAIN,
{<<"Content-Type">>, <<"text/plain">>}).
-define(AC_ALLOW_ORIGIN,
{<<"Access-Control-Allow-Origin">>, <<"*">>}).
-define(AC_ALLOW_METHODS,
{<<"Access-Control-Allow-Methods">>,
<<"GET, POST, OPTIONS">>}).
-define(AC_ALLOW_HEADERS,
{<<"Access-Control-Allow-Headers">>,
<<"Content-Type">>}).
-define(AC_MAX_AGE,
{<<"Access-Control-Max-Age">>, <<"86400">>}).
-define(NO_CACHE,
{<<"Cache-Control">>, <<"max-age=0, no-cache, no-store">>}).
-define(OPTIONS_HEADER,
[?CT_PLAIN, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_METHODS,
?AC_ALLOW_HEADERS, ?AC_MAX_AGE]).
-define(HEADER,
[?CT_XML, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_HEADERS, ?NO_CACHE]).

Some files were not shown because too many files have changed in this diff Show More