diff options
Diffstat (limited to 'ejabberdctl.template')
-rwxr-xr-x | ejabberdctl.template | 251 |
1 files changed, 141 insertions, 110 deletions
diff --git a/ejabberdctl.template b/ejabberdctl.template index 6c131ace0..6b06226ac 100755 --- a/ejabberdctl.template +++ b/ejabberdctl.template @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # define default configuration POLL=true @@ -15,9 +15,7 @@ ERL={{erl}} IEX={{bindir}}/iex EPMD={{bindir}}/epmd INSTALLUSER={{installuser}} - -# Compatibility in ZSH -#setopt shwordsplit 2>/dev/null +ERL_LIBS={{libdir}} # check the proper system user is used if defined if [ "$INSTALLUSER" != "" ] ; then @@ -33,30 +31,31 @@ if [ "$INSTALLUSER" != "" ] ; then fi done if [ `id -g` -eq `id -g $INSTALLUSER` ] ; then - EXEC_CMD="sh -c" + EXEC_CMD="bash -c" fi if [ "$EXEC_CMD" = "false" ] ; then echo "This command can only be run by root or the user $INSTALLUSER" >&2 exit 4 fi else - EXEC_CMD="sh -c" + EXEC_CMD="bash -c" fi # parse command line parameters -ARGS="" +declare -a ARGS=() while [ $# -ne 0 ] ; do - PARAM=$1 + PARAM="$1" shift case $PARAM in --) break ;; + --no-timeout) EJABBERD_NO_TIMEOUT="--no-timeout" ;; --node) ERLANG_NODE_ARG=$1 ; shift ;; --config-dir) ETC_DIR="$1" ; shift ;; --config) EJABBERD_CONFIG_PATH="$1" ; shift ;; --ctl-config) EJABBERDCTL_CONFIG_PATH="$1" ; shift ;; --logs) LOGS_DIR="$1" ; shift ;; --spool) SPOOL_DIR="$1" ; shift ;; - *) ARGS="$ARGS $PARAM" ;; + *) ARGS=("${ARGS[@]}" "$PARAM") ;; esac done @@ -90,24 +89,14 @@ if [ "{{release}}" != "true" ] ; then if [ "$EJABBERDDIR" = "" ] ; then EJABBERDDIR={{libdir}}/ejabberd fi - if [ "$EJABBERD_EBIN_PATH" = "" ] ; then - EJABBERD_EBIN_PATH=$EJABBERDDIR/ebin - fi if [ "$EJABBERD_PRIV_PATH" = "" ] ; then EJABBERD_PRIV_PATH=$EJABBERDDIR/priv fi if [ "$EJABBERD_BIN_PATH" = "" ] ; then EJABBERD_BIN_PATH=$EJABBERD_PRIV_PATH/bin fi - if [ "$EJABBERD_SO_PATH" = "" ] ; then - EJABBERD_SO_PATH=$EJABBERD_PRIV_PATH/lib - fi - if [ "$EJABBERD_MSGS_PATH" = "" ] ; then - EJABBERD_MSGS_PATH=$EJABBERD_PRIV_PATH/msgs - fi fi EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log -SASL_LOG_PATH=$LOGS_DIR/erlang.log DATETIME=`date "+%Y%m%d-%H%M%S"` ERL_CRASH_DUMP=$LOGS_DIR/erl_crash_$DATETIME.dump ERL_INETRC=$ETC_DIR/inetrc @@ -115,7 +104,6 @@ ERL_INETRC=$ETC_DIR/inetrc # define mnesia options MNESIA_OPTS="-mnesia dir \"\\\"$SPOOL_DIR\\\"\" $MNESIA_OPTIONS" # define erl parameters -ERL_OPTIONS=$(echo $ERL_OPTIONS | sed 's/ /\\ /g') ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS" KERNEL_OPTS="" if [ "$FIREWALL_WINDOW" != "" ] ; then @@ -158,9 +146,7 @@ cd $SPOOL_DIR # export global variables export EJABBERD_CONFIG_PATH -export EJABBERD_MSGS_PATH export EJABBERD_LOG_PATH -export EJABBERD_SO_PATH export EJABBERD_BIN_PATH export EJABBERD_DOC_PATH export EJABBERD_PID_PATH @@ -170,21 +156,43 @@ export ERL_INETRC export ERL_MAX_PORTS export ERL_MAX_ETS_TABLES export CONTRIB_MODULES_PATH +export CONTRIB_MODULES_CONF_DIR +export ERL_LIBS + +shell_escape_str() +{ + if test $# -eq 0; then + printf '"" ' + else + shell_escape "$@" + fi +} + +shell_escape() +{ + local RES=() + for i in "$@"; do + if test -z "$i"; then + printf '"" ' + else + printf '%q ' "$i" + fi + done +} # start server start() { check_start - $EXEC_CMD "$ERL \ - $NAME $ERLANG_NODE \ - -noinput -detached \ - -pa $EJABBERD_EBIN_PATH \ - $MNESIA_OPTS \ - $KERNEL_OPTS \ - $EJABBERD_OPTS \ - -s ejabberd \ - -sasl sasl_error_logger \\{file,\\\"$SASL_LOG_PATH\\\"\\} \ - $ERLANG_OPTS $ARGS \"$@\"" + CMD="`shell_escape \"$ERL\" \"$NAME\" \"$ERLANG_NODE\"` \ + -noinput -detached \ + $MNESIA_OPTS \ + $KERNEL_OPTS \ + $EJABBERD_OPTS \ + -s ejabberd \ + $ERLANG_OPTS \ + `shell_escape \"${ARGS[@]}\" \"$@\"`" + $EXEC_CMD "$CMD" } # attach to server @@ -192,12 +200,13 @@ debug() { debugwarning TTY=`tty | sed -e 's/.*\///g'` - $EXEC_CMD "$ERL \ - $NAME debug-${TTY}-${ERLANG_NODE} \ - -remsh $ERLANG_NODE \ - -hidden \ - $KERNEL_OPTS \ - $ERLANG_OPTS $ARGS \"$@\"" + CMD="`shell_escape \"$ERL\" \"$NAME\" \"debug-${TTY}-${ERLANG_NODE}\"` \ + -remsh $ERLANG_NODE \ + -hidden \ + $KERNEL_OPTS \ + $ERLANG_OPTS \ + `shell_escape \"${ARGS[@]}\" \"$@\"`" + $EXEC_CMD "$CMD" } # attach to server using Elixir @@ -206,49 +215,60 @@ iexdebug() debugwarning TTY=`tty | sed -e 's/.*\///g'` # Elixir shell is hidden as default - $EXEC_CMD "$IEX \ - $IEXNAME debug-${TTY}-${ERLANG_NODE} \ - --remsh $ERLANG_NODE \ - --erl \"$KERNEL_OPTS\" \ - --erl \"$ERLANG_OPTS\" --erl \"$ARGS\" --erl \"$@\"" + CMD="`shell_escape \"$IEX\" \"$IEXNAME\" \"debug-${TTY}-${ERLANG_NODE}\"` \ + -remsh $ERLANG_NODE \ + --erl `shell_escape \"$KERNEL_OPTS\"` \ + --erl `shell_escape \"$ERLANG_OPTS\"` \ + --erl `shell_escape \"${ARGS[@]}\"` \ + --erl `shell_escape_str \"$@\"`" + $EXEC_CMD "$CMD" } # start interactive server live() { livewarning - $EXEC_CMD "$ERL \ - $NAME $ERLANG_NODE \ - -pa $EJABBERD_EBIN_PATH \ - $MNESIA_OPTS \ - $KERNEL_OPTS \ - $EJABBERD_OPTS \ - -s ejabberd \ - $ERLANG_OPTS $ARGS \"$@\"" + CMD="`shell_escape \"$ERL\" \"$NAME\" \"${ERLANG_NODE}\"` \ + $MNESIA_OPTS \ + $KERNEL_OPTS \ + $EJABBERD_OPTS \ + -s ejabberd \ + $ERLANG_OPTS \ + `shell_escape \"${ARGS[@]}\" \"$@\"`" + $EXEC_CMD "$CMD" } # start interactive server with Elixir iexlive() { livewarning - $EXEC_CMD "$IEX \ - $IEXNAME $ERLANG_NODE \ - -pa $EJABBERD_EBIN_PATH \ - --erl \"-mnesia dir \\\"$SPOOL_DIR\\\"\" \ - --erl \"$KERNEL_OPTS\" \ - --erl \"$EJABBERD_OPTS\" \ - --app ejabberd \ - --erl \"$ERLANG_OPTS\" --erl $ARGS --erl \"$@\"" + echo $@ + CMD="`shell_escape \"$IEX\" \"$IEXNAME\" \"${ERLANG_NODE}\"` \ + --erl \"-mnesia dir \\\"$SPOOL_DIR\\\"\" \ + --erl \"`shell_escape \"$KERNEL_OPTS\"`\" \ + --erl \"`shell_escape \"$EJABBERD_OPTS\"`\" \ + --app ejabberd \ + --erl `shell_escape \"$ERLANG_OPTS\"` \ + --erl `shell_escape \"${ARGS[@]}\"` \ + --erl `shell_escape_str \"$@\"`" + $EXEC_CMD "$CMD" } -etop() +# start server in the foreground +foreground() { - $EXEC_CMD "$ERL \ - $NAME debug-${TTY}-${ERLANG_NODE} \ - -hidden -s etop -s erlang halt -output text -node $ERLANG_NODE" + check_start + CMD="`shell_escape \"$ERL\" \"$NAME\" \"$ERLANG_NODE\"` \ + -noinput \ + $MNESIA_OPTS \ + $KERNEL_OPTS \ + $EJABBERD_OPTS \ + -s ejabberd \ + $ERLANG_OPTS \ + `shell_escape \"${ARGS[@]}\" \"$@\"`" + $EXEC_CMD "$CMD" } -# TODO: refactor debug warning and livewarning debugwarning() { if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then @@ -270,7 +290,7 @@ debugwarning() echo "Press return to continue" read foo echo "" - fi + fi } livewarning() @@ -297,16 +317,42 @@ livewarning() fi } -# TODO: Make iex command display only if ejabberd Elixir support has been enabled +etop() +{ + TTY=`tty | sed -e 's/.*\///g'` + $EXEC_CMD "$ERL \ + $NAME debug-${TTY}-${ERLANG_NODE} \ + -hidden -s etop -s erlang halt -output text -node $ERLANG_NODE" +} + +ping() +{ + TTY=`tty | sed -e 's/.*\///g'` + if [ "$1" = "${1%.*}" ] ; then + PING_NAME="-sname" + PING_NODE=$(hostname -s) + else + PING_NAME="-name" + PING_NODE=$(hostname) + fi + $EXEC_CMD "$ERL \ + $PING_NAME ping-${TTY}@${PING_NODE} \ + -hidden \ + $KERNEL_OPTS $ERLANG_OPTS \ + -eval 'io:format(\"~p~n\",[net_adm:ping('\"'\"'$1'\"'\"')])' \ + -s erlang halt -output text -noinput" +} + help() { echo "" echo "Commands to start an ejabberd node:" - echo " start Start an ejabberd node in server mode" - echo " debug Attach an interactive Erlang shell to a running ejabberd node" - echo " iexdebug Attach an interactive Elixir shell to a running ejabberd node" - echo " live Start an ejabberd node in live (interactive) mode" - echo " iexlive Start an ejabberd node in live (interactive) mode, within an Elixir shell" + echo " start Start an ejabberd node in server mode" + echo " debug Attach an interactive Erlang shell to a running ejabberd node" + echo " iexdebug Attach an interactive Elixir shell to a running ejabberd node" + echo " live Start an ejabberd node in live (interactive) mode" + echo " iexlive Start an ejabberd node in live (interactive) mode, within an Elixir shell" + echo " foreground Start an ejabberd node in server mode (attached)" echo "" echo "Optional parameters when starting an ejabberd node:" echo " --config-dir dir Config ejabberd: $ETC_DIR" @@ -321,26 +367,24 @@ help() # common control function ctl() { - COMMAND=$@ - # Control number of connections identifiers # using flock if available. Expects a linux-style # flock that can lock a file descriptor. MAXCONNID=100 CONNLOCKDIR={{localstatedir}}/lock/ejabberdctl - FLOCK='/usr/bin/flock' + FLOCK=/usr/bin/flock if [ ! -x "$FLOCK" ] || [ ! -d "$CONNLOCKDIR" ] ; then - JOT='/usr/bin/jot' + JOT=/usr/bin/jot if [ ! -x "$JOT" ] ; then # no flock or jot, simply invoke ctlexec() CTL_CONN="ctl-${ERLANG_NODE}" - ctlexec $CTL_CONN $COMMAND + ctlexec $CTL_CONN "$@" result=$? else # no flock, but at least there is jot RAND=`jot -r 1 0 $MAXCONNID` CTL_CONN="ctl-${RAND}-${ERLANG_NODE}" - ctlexec $CTL_CONN $COMMAND + ctlexec $CTL_CONN "$@" result=$? fi else @@ -350,12 +394,12 @@ ctl() # concurrent invocations using a bound # number of atoms for N in `seq 1 $MAXCONNID`; do - CTL_CONN="ejabberdctl-$N" + CTL_CONN="ctl-$N-${ERLANG_NODE}" CTL_LOCKFILE="$CONNLOCKDIR/$CTL_CONN" ( exec 8>"$CTL_LOCKFILE" if flock --nb 8; then - ctlexec $CTL_CONN $COMMAND + ctlexec $CTL_CONN "$@" ssresult=$? # segregate from possible flock exit(1) ssresult=`expr $ssresult \* 10` @@ -397,20 +441,17 @@ ctl() ctlexec() { CONN_NAME=$1; shift - COMMAND=$@ - $EXEC_CMD "$ERL \ - $NAME ${CONN_NAME} \ - -noinput \ - -hidden \ - -pa $EJABBERD_EBIN_PATH \ - $KERNEL_OPTS \ - -s ejabberd_ctl -extra $ERLANG_NODE $COMMAND" + CMD="`shell_escape \"$ERL\" \"$NAME\" \"$CONN_NAME\"` \ + -noinput -hidden $KERNEL_OPTS -s ejabberd_ctl \ + -extra `shell_escape \"$ERLANG_NODE\"` $EJABBERD_NO_TIMEOUT \ + `shell_escape \"$@\"`" + $EXEC_CMD "$CMD" } # stop epmd if there is no other running node stop_epmd() { - $EPMD -names 2>/dev/null | grep -q name || epmd -kill >/dev/null + $EPMD -names 2>/dev/null | grep -q name || $EPMD -kill >/dev/null } # make sure node not already running and node name unregistered @@ -433,16 +474,6 @@ check_start() } } -# cluster setup -join_cluster() -{ - $EJABBERD_BIN_PATH/joincluster $* -} -leave_cluster() -{ - $EJABBERD_BIN_PATH/leavecluster $* -} - # allow sync calls wait_for_status() { @@ -464,16 +495,16 @@ wait_for_status() } # main handler -case $ARGS in - ' start') start;; - ' debug') debug;; - ' iexdebug') iexdebug;; - ' live') live;; - ' iexlive') iexlive;; - ' etop') etop;; - ' started') wait_for_status 0 30 2;; # wait 30x2s before timeout - ' stopped') wait_for_status 3 15 2 && stop_epmd;; # wait 15x2s before timeout - ' join_cluster'*) join_cluster ${ARGS# join_cluster};; - ' leave_cluster'*) leave_cluster ${ARGS# leave_cluster};; - *) ctl $ARGS;; +case "${ARGS[0]}" in + 'start') start;; + 'debug') debug;; + 'iexdebug') iexdebug;; + 'live') live;; + 'iexlive') iexlive;; + 'foreground') foreground;; + 'ping'*) ping ${ARGS# ping};; + 'etop') etop;; + 'started') wait_for_status 0 30 2;; # wait 30x2s before timeout + 'stopped') wait_for_status 3 15 2 && stop_epmd;; # wait 15x2s before timeout + *) ctl "${ARGS[@]}";; esac |