#!/bin/bash # # OUTPUT FUNCTIONS # function echov() { if [ 0$VERBOSITY -ge 1 ]; then echo "$@" fi } function echod() { if [ 0$VERBOSITY -ge 2 ]; then echo "$@" fi } # # CONFIGURATION # # PATH environment variable for running tests if [ -n "$BINARY_PATH" ]; then BP='' for bp in $(echo $BINARY_PATH | sed 's@:@ @'); do if [ -e "$bp" ]; then BP="$BP:$(readlink -f $bp)" else echo "WARNING: $PWD/$bp" does not exist fi done BINARY_PATH="$BP" fi echod "BINARY PATH: $BINARY_PATH" PATH="$BINARY_PATH:/bin/:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin" echod "OVERALL BINARY PATH: $PATH" # used MPM if [ -z "$HTTPD_MPM" ]; then HTTPD_MPM=prefork fi # module PATH if [ -n "$MODULE_PATH" ]; then MP='' for mp in $(echo $MODULE_PATH | sed 's@:@ @'); do if [ -e "$mp" ]; then MP="$MP:$(readlink -f $mp)" else echo "WARNING: $PWD/$mp" does not exist fi done MODULE_PATH="$MP" fi MODULE_PATH="$MODULE_PATH:/usr/lib64/apache2:/usr/lib64/apache2-$HTTPD_MPM:/usr/lib/apache2:/usr/lib/apache2-$HTTPD_MPM" echod "MODULES PATH: $MODULE_PATH" # writeable dir for running the example if [ -z "$RUN_DIR_BASE" ]; then RUN_DIR_BASE=/tmp/apache-rex/ fi # we will pushd to example dir, thus we need # absolute path mkdir -p $RUN_DIR_BASE RUN_DIR_BASE=$(readlink -f $RUN_DIR_BASE) echod "BASE RUN DIR: $RUN_DIR_BASE" # ports where httpd can listen from (start + 6) if [ -z "$HTTP_PORT_START" ]; then HTTP_PORT_START=60080 fi # port where ftp daemon can listen if [ -z "$FTP_PORT" ]; then FTP_PORT=60021 fi # port where fcgi starter can listen if [ -z "$FCGI_PORT" ]; then FCGI_PORT=60009 fi # port where scgi starter can listen if [ -z "$SCGI_PORT" ]; then SCGI_PORT=60004 fi # port where uwsgi daemon can listen if [ -z "$UWSGI_PORT" ]; then UWSGI_PORT=60005 fi # port where second uwsgi daemon can listen if [ -z "$UWSGI_PORT2" ]; then UWSGI_PORT2=60006 fi if [ -z "$OCSP_PORT"]; then OCSP_PORT=60888 fi if [ -z "$PGSQL_PORT"]; then PGSQL_PORT=65432 fi # verbosity of the output: normal=0, verbose=1, debug=2 if [ -z "$VERBOSITY" ]; then VERBOSITY=0 fi if [ -z "$MYSQL_ADMIN" ]; then MYSQL_ADMIN=$USER fi echod # # HELPER FUNCTIONS # function usage() { echo "Run example or examples of httpd configuration." echo echo "$0 \"\"" echo "$0 " echo echo " is a list of examples to be" echo " run (e. g. $0 \"*proxy* 03*\")" echo " is list examples dirs to be run" echo " in that order" } function find_module() { # name can be a regular expression, e. g. php[5,7] name=$1 for mp in $(echo $MODULE_PATH $AREX_RUN_DIR | tr ':' ' '); do if [ -e $mp ]; then find $mp -regextype sed -regex ".*/mod_$name.so" fi done | tail -n 1 } function find_module_symbol() { # name can be a regular expression, e. g. php[5,7] path=$1 name=$2 # \?: exception: php8 have php_module objdump -T $path | grep "[[:space:]]${name}\?_module$" | sed "s:.*\(${name}\?_module\).*:\1:" } function command_exists() { if [ -x $AREX_BINDIR/$1 ]; then return 0 fi return 1 } function register_command() { command_path=$1 command=$2 [ -n "$command_path" ] && ln -sf $command_path $AREX_BINDIR/$command } # # SYSTEM CHECK # function httpd_command() { which httpd-$HTTPD_MPM httpd2-$HTTPD_MPM httpd httpd2 2>/dev/null | head -n 1 } function apxs_command() { which apxs-$HTTPD_MPM apxs2-$HTTPD_MPM apxs apxs2 2>/dev/null | head -n 1 } function objdump_command() { which objdump 2>/dev/null | head -n 1 } function htpasswd_command() { which htpasswd htpasswd2 2>/dev/null | head -n 1 } function htdbm_command() { which htdbm htdbm2 2>/dev/null | head -n 1 } function rotatelogs_command() { which rotatelogs rotatelogs2 2>/dev/null | head -n 1 } function httxt2dbm_command() { which httxt2dbm 2>/dev/null } function check_forensic_command() { which check_forensic 2>/dev/null } function curl_command() { which curl 2>/dev/null } function curl_have_resolve() { { curl --manual || curl --help; } | grep -q '\--resolve' && echo -n 1 || echo -n 0 } function curl_have_cert_status() { { curl --manual || curl --help; } | grep -q '\--cert-status' && echo -n 1 || echo -n 0 } function curl_have_http2() { ldd $(curl_command) | grep -q 'libnghttp2' && echo -n 1 || echo -n 0 } function sed_command() { which sed 2>/dev/null } function sqlite_command() { which sqlite sqlite3 2>/dev/null | head -n 1 } function ps_command() { which ps 2>/dev/null | head -n 1 } function kill_command() { which kill 2>/dev/null | head -n 1 } function gdb_command() { which gdb 2>/dev/null | head -n 1 } function telnet_command() { which telnet 2>/dev/null | head -n 1 } function wget_command() { which wget 2>/dev/null | head -n 1 } function nc_command() { which nc 2>/dev/null } function mysql_install_db_command { which mysql_install_db 2>/dev/null } function mysqld_command { which mysqld 2>/dev/null } function mysqladmin_command { which mysqladmin 2>/dev/null } function mysql_command { which mysql 2>/dev/null } function python_command() { which python3 python 2>/dev/null | head -n 1 } function sysctl_command() { which sysctl 2>/dev/null } function coredumpctl_command() { which coredumpctl 2>/dev/null | head -n 1 } function openssl_command() { which openssl 2>/dev/null } function softhsm2_command() { which softhsm2-util 2>/dev/null } function pkcs11_tool_command() { which pkcs11-tool 2>/dev/null } function nss_pcache_command() { which nss_pcache 2>/dev/null } function lsof_command() { which lsof 2>/dev/null } function vsftpd_command() { which vsftpd 2>/dev/null } function vsftpd_version() { vsftpd -v 0>&1 | sed 's:.*\([0-9]\+\.[0-9]\+\.[0-9]\+\).*:\1:' | tr -d '.' } function uwsgi_command() { which uwsgi 2>/dev/null } UWSGI_PLUGINS_DIRS='/usr/lib64/uwsgi /usr/lib/uwsgi' function uwsgi_plugin() { plugin=$1 ls $UWSGI_PLUGINS_DIRS 2>/dev/null | grep $1 | head -n 1 | sed 's/_plugin.so//' } function openssl_an_engine() { openssl engine | grep -v dynamic | head -n 1 | sed 's:^(\([^()]*\)).*:\1:' } function softhsm2_so() { ls /usr/lib{,64}/pkcs11/libsofthsm2.so /usr/lib{,64}/shofthsm2/libsofthsm2.so 2>/dev/null | head -n 1 } function openssl_have_alpn() { objdump -T $(ldconfig -p | grep 'libssl\.so\.' | sed 's:.* => ::') | grep alpn > /dev/null && echo -n '1' || echo -n '0' } function have_python_tornado() { python -c "help('modules');" | grep tornado > /dev/null && echo -n '1' || echo -n '0' } function have_perl_scgi() { perldoc -l "SCGI" > /dev/null 2>&1 && echo -n '1' || echo -n '0' } function have_python_websocket_client() { python -c "help('modules');" | grep websocket > /dev/null && echo -n '1' || echo -n '0' } function core_pattern() { cat /proc/sys/kernel/core_pattern 2>/dev/null } function have_systemd_coredump() { # check whether: 1. system is configured to dump coredumps into systemd-coredump # 2. coredumpctl command exists and user have enough privileges to gather dumps if sysctl kernel.core_pattern | grep -q 'systemd-coredump' && \ coredumpctl list 2>&1 | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | grep -q 'TIME\|No coredumps found.'; then echo '1' else echo '0' fi } function check_system() { export AREX_BINDIR="$RUN_DIR_BASE/bin" if [ -d $AREX_BINDIR ]; then rm $AREX_BINDIR/* else mkdir $AREX_BINDIR fi # take symlinks created into account export PATH="$AREX_BINDIR:$PATH" echod -n "Checking the system " echod -n '.' HTTPD_COMMAND=$(httpd_command) register_command "$HTTPD_COMMAND" httpd echod -n '.' APXS_COMMAND=$(apxs_command) register_command "$APXS_COMMAND" apxs echod -n '.' OBJDUMP_COMMAND=$(objdump_command) register_command "$OBJDUMP_COMMAND" objdump echod -n '.' HTPASSWD_COMMAND=$(htpasswd_command) register_command "$HTPASSWD_COMMAND" htpasswd echod -n '.' HTDBM_COMMAND=$(htdbm_command) register_command "$HTDBM_COMMAND" htdbm ROTATELOGS_COMMAND=$(rotatelogs_command) register_command "$ROTATELOGS_COMMAND" rotatelogs echod -n '.' HTTXT2DBM_COMMAND=$(httxt2dbm_command) register_command "$HTTXT2DBM_COMMAND" httxt2dbm echod -n '.' CHECK_FORENSIC_COMMAND=$(check_forensic_command) register_command "$CHECK_FORENSIC_COMMAND" check_forensic echod -n '.' CURL_COMMAND=$(curl_command) register_command "$CURL_COMMAND" curl echod -n '.' SQLITE_COMMAND=$(sqlite_command) register_command "$SQLITE_COMMAND" sqlite echod -n '.' PS_COMMAND=$(ps_command) register_command "$PS_COMMAND" ps echod -n '.' KILL_COMMAND=$(kill_command) register_command "$KILL_COMMAND" kill echod -n '.' GDB_COMMAND=$(gdb_command) register_command "$GDB_COMMAND" gdb echod -n '.' TELNET_COMMAND=$(telnet_command) register_command "$TELNET_COMMAND" telnet echod -n '.' WGET_COMMAND=$(wget_command) register_command "$WGET_COMMAND" wget echod -n '.' NC_COMMAND=$(nc_command) register_command "$NC_COMMAND" nc echod -n '.' MYSQL_INSTALL_DB_COMMAND=$(mysql_install_db_command) register_command "$MYSQL_INSTALL_DB_COMMAND" mysql_install_db echod -n '.' MYSQLD_COMMAND=$(mysqld_command) register_command "$MYSQLD_COMMAND" mysqld echod -n '.' MYSQLADMIN_COMMAND=$(mysqladmin_command) register_command "$MYSQLADMIN_COMMAND" mysqladmin echod -n '.' MYSQL_COMMAND=$(mysql_command) register_command "$MYSQL_COMMAND" mysql echod -n '.' PYTHON_COMMAND=$(python_command) register_command "$PYTHON_COMMAND" python echod -n '.' SYSCTL_COMMAND=$(sysctl_command) register_command "$SYSCTL_COMMAND" sysctl echod -n '.' COREDUMPCTL_COMMAND=$(coredumpctl_command) register_command "$COREDUMPCTL_COMMAND" coredumpctl echod -n '.' OPENSSL_COMMAND=$(openssl_command) register_command "$OPENSSL_COMMAND" openssl echod -n '.' SOFTHSM2_COMMAND=$(softhsm2_command) register_command "$SOFTHSM2_COMMAND" softhsm2 echod -n '.' PKCS11_TOOL_COMMAND=$(pkcs11_tool_command) register_command "$PKCS11_TOOL_COMMAND" pkcs11-tool echod -n '.' NSS_PCACHE_COMMAND=$(nss_pcache_command) register_command "$NSS_PCACHE_COMMAND" nss_pcache echod -n '.' LSOF_COMMAND=$(lsof_command) register_command "$LSOF_COMMAND" lsof echod -n '.' VSFTPD_COMMAND=$(vsftpd_command) register_command "$VSFTPD_COMMAND" vsftpd UWSGI_COMMAND=$(uwsgi_command) register_command "$UWSGI_COMMAND" uwsgi echod -n '.' # filter definitions need full path, otherwise # it is expected that sed is in the PATH export AREX_SED_COMMAND=$(sed_command) echod -n '.' # piped logs require full path to rotatelogs export AREX_ROTATELOGS_COMMAND=$ROTATELOGS_COMMAND echod -n '.' export AREX_CURL_HAVE_RESOLVE=$(curl_have_resolve) echod -n '.' export AREX_CURL_HAVE_CERT_STATUS=$(curl_have_cert_status) echod -n '.' export AREX_CURL_HAVE_HTTP2=$(curl_have_http2) echod -n '.' if command_exists openssl; then export AREX_AN_OPENSSL_ENGINE=$(openssl_an_engine) echod -n '.' fi if command_exists openssl; then export AREX_OPENSSL_HAVE_ALPN=$(openssl_have_alpn) echod -n '.' fi if command_exists softhsm2; then export AREX_SOFTHSM2_SO=$(softhsm2_so) fi if command_exists python; then export AREX_HAVE_PYTHON_TORNADO=$(have_python_tornado) echod -n '.' fi export AREX_HAVE_PERL_SCGI=$(have_perl_scgi) echod -n '.' if command_exists python; then export AREX_HAVE_PYTHON_WEBSOCKET_CLIENT=$(have_python_websocket_client) echod -n '.' fi export AREX_CORE_PATTERN=$(core_pattern) echod -n '.' if command_exists coredumpctl; then export AREX_HAVE_SYSTEMD_COREDUMP=$(have_systemd_coredump) fi if command_exists vsftpd; then echod -n '.' export AREX_VSFTPD_VERSION=$(vsftpd_version) fi export AREX_UWSGI_PLUGIN_HTTP=$(uwsgi_plugin http) echod -n '.' export AREX_UWSGI_PLUGIN_PYTHON=$(uwsgi_plugin python) echod -n '.' echod ' done.' echod "httpd command ............................ $HTTPD_COMMAND" echod "apxs command ............................. $APXS_COMMAND" echod "htpasswd command ......................... $HTPASSWD_COMMAND" echod "htdbm command ............................ $HTDBM_COMMAND" echod "rotatelogs command ....................... $AREX_ROTATELOGS_COMMAND" echod "httxt2dbm command ........................ $HTTXT2DBM_COMMAND" echod "check_forensic command ................... $CHECK_FORENSIC_COMMAND" echod "curl command ............................. $CURL_COMMAND" echod "curl have --resolve switch ............... $AREX_CURL_HAVE_RESOLVE" echod "curl have --cert-status switch ........... $AREX_CURL_HAVE_CERT_STATUS" echod "curl have HTTP2 protocol ................. $AREX_CURL_HAVE_HTTP2" echod "sed command .............................. $AREX_SED_COMMAND" echod "sqlite command ........................... $SQLITE_COMMAND" echod "ps command ............................... $PS_COMMAND" echod "kill command ............................. $KILL_COMMAND" echod "gdb command .............................. $GDB_COMMAND" echod "telnet command ........................... $TELNET_COMMAND" echod "wget command ............................. $WGET_COMMAND" echod "nc command ............................... $NC_COMMAND" echod "python command ........................... $PYTHON_COMMAND" echod "sysctl command ........................... $SYSCTL_COMMAND" echod "coredumpctl command ...................... $COREDUMPCTL_COMMAND" echod "openssl command .......................... $OPENSSL_COMMAND" echod "softhsm2 command ......................... $SOFTHSM2_COMMAND" echod "pkcs11-tool command ...................... $PKCS11_TOOL_COMMAND" echod "openssl engine ........................... $AREX_AN_OPENSSL_ENGINE" echod "openssl have alpn support ................ $AREX_OPENSSL_HAVE_ALPN" echod "softhsm2 shared object ................... $AREX_SOFTHSM2_SO" echod "nss_pcache command ....................... $NSS_PCACHE_COMMAND" echod "lsof command ............................. $LSOF_COMMAND" echod "vsftpd command ........................... $VSFTPD_COMMAND" echod "vsftpd version ........................... $AREX_VSFTPD_VERSION" echod "uwsgi command ............................ $UWSGI_COMMAND" echod "uwsgi http plugin ........................ $AREX_UWSGI_PLUGIN_HTTP" echod "uwsgi python plugin ...................... $AREX_UWSGI_PLUGIN_PYTHON" echod "system have python-tornado ............... $AREX_HAVE_PYTHON_TORNADO" echod "system have perl-scgi .................... $AREX_HAVE_PERL_SCGI" echod "system have python-websocket-client ...... $AREX_HAVE_PYTHON_WEBSOCKET_CLIENT" echod "system have systemd coredumps ............ $AREX_HAVE_SYSTEMD_COREDUMP" echod "system core pattern ...................... $AREX_CORE_PATTERN" echod # # following two are neccessary for running examples # if [ -z "$HTTPD_COMMAND" ]; then echo 'fatal: httpd binary not found' >&2 exit 10 fi if [ -z "$OBJDUMP_COMMAND" ]; then echo 'fatal: objdump binary not found' >&2 exit 10 fi if [ -z "$CURL_COMMAND" ]; then echo 'fatal: curl binary not found' >&2 exit 10 fi } # # RUN ENVIRONMENT # function prepare_env() { echod 'Setting environment for running examples.' export AREX_APACHE_VERSION=$(httpd -v | grep 'Server version' | sed 's:.*Apache/\([0-9\.]\+\).*:\1:' | tr '.' ' ' | { read maj min patch; printf "%d%02d%02d" $maj $min $patch;}) echod "httpd version ............................ $AREX_APACHE_VERSION" export AREX_MPM=$HTTPD_MPM echod "httpd MPM ................................ $AREX_MPM" export AREX_PORT=$HTTP_PORT_START echod "httpd will listen on ..................... $AREX_PORT" export AREX_PORT1=$((HTTP_PORT_START+1)) export AREX_PORT2=$((HTTP_PORT_START+2)) export AREX_PORT3=$((HTTP_PORT_START+3)) export AREX_PORT4=$((HTTP_PORT_START+4)) export AREX_PORT5=$((HTTP_PORT_START+5)) export AREX_PORT6=$((HTTP_PORT_START+6)) echod "other available ports ...................."\ "$AREX_PORT1 $AREX_PORT2 $AREX_PORT3 $AREX_PORT4 $AREX_PORT5 $AREX_PORT6" export AREX_FTP_PORT=$FTP_PORT echod "ftp daemon will listen on ................ $AREX_FTP_PORT" export AREX_FCGI_PORT=$FCGI_PORT echod "fcgi daemon will listen on ............... $AREX_FCGI_PORT" export AREX_SCGI_PORT=$SCGI_PORT echod "scgi daemon will listen on ............... $AREX_SCGI_PORT" export AREX_UWSGI_PORT=$UWSGI_PORT echod "uwsgi daemon will listen on .............. $AREX_UWSGI_PORT" export AREX_UWSGI_PORT2=$UWSGI_PORT2 echod "second uwsgi daemon will listen on ....... $AREX_UWSGI_PORT2" export AREX_OCSP_PORT=$OCSP_PORT echod "ocsp responedr daemon will listen on ..... $AREX_OCSP_PORT" export AREX_PGSQL_PORT=$PGSQL_PORT echod "postgress daemon will listen on .......... $AREX_PGSQL_PORT" echod -n "authz_core module present ................ " if [ -n "$(find_module authz_core)" ]; then echod '1' export AREX_ALLOW_FROM_LOCALHOST="Require local" export AREX_DENY_FROM_ALL="Require all denied" export AREX_ALLOW_FROM_ALL="Require all granted" else echod '0' export AREX_ALLOW_FROM_LOCALHOST="Order deny,allow\nDeny from all\nAllow from localhost 127.0.0.1" export AREX_DENY_FROM_ALL="Order deny,allow\nDeny from all" export AREX_ALLOW_FROM_ALL="Order allow,deny\nAllow from all" fi export AREX_USER=$USER echod "httpd user ............................... $AREX_USER" export AREX_GROUP=$(id -gn) echod "httpd user group ......................... $AREX_GROUP" export AREX_MYSQL_ADMIN="$MYSQL_ADMIN" echod "mysql admin .............................. $AREX_MYSQL_ADMIN" echod } function check_open_ports() { echod -n "checking that requested ports are not already opened .. " if ! command_exists lsof; then echod "lsof does not exist, could not check" else lsof -i > $RUN_DIR_BASE/.opened_ports grep -q ":$AREX_PORT (LISTEN)" $RUN_DIR_BASE/.opened_ports && { echo "fatal: $AREX_PORT is already opened"; exit 9; } grep -q ":$AREX_PORT1 (LISTEN)" $RUN_DIR_BASE/.opened_ports && { echo "fatal: $AREX_PORT1 is already opened"; exit 9; } grep -q ":$AREX_PORT2 (LISTEN)" $RUN_DIR_BASE/.opened_ports && { echo "fatal: $AREX_PORT2 is already opened"; exit 9; } grep -q ":$AREX_PORT3 (LISTEN)" $RUN_DIR_BASE/.opened_ports && { echo "fatal: $AREX_PORT3 is already opened"; exit 9; } grep -q ":$AREX_PORT4 (LISTEN)" $RUN_DIR_BASE/.opened_ports && { echo "fatal: $AREX_PORT4 is already opened"; exit 9; } grep -q ":$AREX_PORT5 (LISTEN)" $RUN_DIR_BASE/.opened_ports && { echo "fatal: $AREX_PORT5 is already opened"; exit 9; } grep -q ":$AREX_PORT6 (LISTEN)" $RUN_DIR_BASE/.opened_ports && { echo "fatal: $AREX_PORT6 is already opened"; exit 9; } echod "done" fi echod } # # RUN LOOP (it is possible to run more examples) # function compile_modules() { modules="$(cat MODULES | tr ':' ' ')" module_dir=$AREX_RUN_DIR/my_modules # there is a rule: when for $m mod_$m.c # exist, then we will compile it # and load to httpd for m in $modules; do if [ -e mod_$m.c ]; then mkdir -p $module_dir cp mod_$m.c $module_dir echo -n "Building '$m' module .. " apxs -c $module_dir/mod_$m.c >$module_dir/mod_$m.log 2>&1 if [ ! -e $module_dir/.libs/mod_$m.so ]; then echo "FAILED:" cat $module_dir/mod_$m.log echo fi echo "$module_dir/.libs/mod_$m.so."; echo fi done } function fix_module_name() { name=$1; if [ $HTTPD_MPM == 'prefork' -a $name == 'cgid' ]; then echo -n 'cgi' elif [ $HTTPD_MPM != 'prefork' -a $name == 'cgi' ]; then echo -n 'cgid' else echo -n $name fi } function load_modules() { conf=$1 modules="auth_basic dir authz_host $(cat MODULES | tr ':' ' ')" modules_opt="authz_core" if [ -e MODULES_OPT ]; then modules_opt="$modules_opt $(cat MODULES_OPT | tr ':' ' ')" fi for m in $modules; do m=$(fix_module_name $m) # ensure we have an absolute path module_path=$(readlink -f $(find_module $m)) echov "Will load module $m ($module_path)" module_symbol=$(find_module_symbol $module_path $m) if [ -z "$module_symbol" ]; then echo "fatal: ${m}_module symbol not found in $module_path" exit 8 fi echo "LoadModule ${module_symbol} $module_path" >> $conf done for m in $modules_opt; do m=$(fix_module_name $m) module_path=$(find_module $m) if [ -n "$module_path" ]; then echov "Will load module $m ($module_path)" echo "LoadModule ${m}_module $module_path" >> $conf fi done } function prepare_run() { dir=$1 # prepare config conf=$AREX_RUN_DIR/httpd.conf echo "ServerName test" > $conf echo "User $AREX_USER" >> $conf echo "Group $AREX_GROUP" >> $conf echo "Listen $AREX_PORT" >> $conf echo "PidFile $AREX_RUN_DIR/pid" >> $conf echo "ErrorLog $AREX_RUN_DIR/error_log" >> $conf load_modules $conf if [ $AREX_MPM != 'prefork' ]; then echo "" >> $conf echo " ScriptSock $AREX_RUN_DIR/cgid.sock" >> $conf echo "" >> $conf fi export AREX_DOCUMENT_ROOT=$AREX_RUN_DIR/htdocs echo "DocumentRoot $AREX_DOCUMENT_ROOT" >> $conf echo "DirectoryIndex index.html" >> $conf echo >> $conf echo "### example configuration" >> $conf echo >> $conf if [ -e example.conf.in ]; then cat example.conf.in >> $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_BINDIR@:$AREX_BINDIR:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_RUN_DIR@:$AREX_RUN_DIR:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_USER@:$AREX_USER:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_GROUP@:$AREX_GROUP:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_PORT@:$AREX_PORT:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_PORT1@:$AREX_PORT1:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_PORT2@:$AREX_PORT2:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_PORT3@:$AREX_PORT3:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_PORT4@:$AREX_PORT4:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_PORT5@:$AREX_PORT5:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_PORT6@:$AREX_PORT6:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_DOCUMENT_ROOT@:$AREX_DOCUMENT_ROOT:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_ALLOW_FROM_LOCALHOST@:$AREX_ALLOW_FROM_LOCALHOST:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_DENY_FROM_ALL@:$AREX_DENY_FROM_ALL:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_ALLOW_FROM_ALL@:$AREX_ALLOW_FROM_ALL:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_AN_OPENSSL_ENGINE@:$AREX_AN_OPENSSL_ENGINE:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_FTP_PORT@:$AREX_FTP_PORT:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_FCGI_PORT@:$AREX_FCGI_PORT:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_SCGI_PORT@:$AREX_SCGI_PORT:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_UWSGI_PORT@:$AREX_UWSGI_PORT:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_UWSGI_PORT2@:$AREX_UWSGI_PORT2:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_OCSP_PORT@:$AREX_OCSP_PORT:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_PGSQL_PORT@:$AREX_PGSQL_PORT:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_SED_COMMAND@:$AREX_SED_COMMAND:" $AREX_RUN_DIR/httpd.conf sed -i "s:@AREX_ROTATELOGS_COMMAND@:$AREX_ROTATELOGS_COMMAND:" $AREX_RUN_DIR/httpd.conf else cat example.conf >> $AREX_RUN_DIR/httpd.conf fi # run preparation script of the example if [ -e pre-run.sh ]; then cp pre-run.sh $AREX_RUN_DIR sh $AREX_RUN_DIR/pre-run.sh fi # source $AREX_RUN_DIR/server_environment, which pre-run.sh # can write if [ -e $AREX_RUN_DIR/server_environment ]; then . $AREX_RUN_DIR/server_environment fi # create default DocumentRoot mkdir -p $AREX_RUN_DIR/htdocs # server flags SERVER_FLAGS="" if [ -e SERVERFLAGS ]; then SERVER_FLAGS="$(cat SERVERFLAGS)" fi } function finish_run() { # run cleanup script of the example if [ -e post-run.sh ]; then cp post-run.sh $AREX_RUN_DIR sh $AREX_RUN_DIR/post-run.sh fi } function syntax_check() { syntax_ok=1 httpd -f $AREX_RUN_DIR/httpd.conf $SERVER_FLAGS -t 2>$AREX_RUN_DIR/syntax_check || syntax_ok=0 echo $syntax_ok } function start_apache() { start_ok=1 httpd -f $AREX_RUN_DIR/httpd.conf $SERVER_FLAGS -k start 2>$AREX_RUN_DIR/start_log || start_ok=0 if [ $start_ok -ne 1 ]; then echo '0' return fi # wait for the apache to settle down sleep 2 if [ ! -e $AREX_RUN_DIR/pid ]; then echo '0' return fi echo '1' return } function run() { cp run.sh $AREX_RUN_DIR run_exit_code=0 sh $AREX_RUN_DIR/run.sh 2>&1 || run_exit_code=$? } function stop_apache() { pid=$(cat $AREX_RUN_DIR/pid) kill -TERM $pid sleep 1 if [ -e $AREX_RUN_DIR/pid ]; then kill -KILL -$pid || true sleep 1 if [ -e $AREX_RUN_DIR/pid ]; then echo '0' return fi fi echo '1' } function missing_binaries() { req_binaries="$(cat BINARIES 2>/dev/null)" # check if apxs is needed, too modules="$(cat MODULES | tr ':' ' ')" for m in $modules; do # there is a rule: when for $m mod_$m.c # exist, then we will compile it # (see compile_modules() function) # and load to httpd if [ -e mod_$m.c ]; then req_binaries="$req_binaries apxs" break fi done result="" for b in $req_binaries; do if [ -z "$(which $b 2>/dev/null)" ]; then result="$result$b " fi done echo $result } function missing_modules() { req_modules=$(cat MODULES | tr ':' ' ') result="" for m in $req_modules; do m=$(fix_module_name $m) if [ -z "$(find_module $m)" ]; then result="$result$m " fi done echo $result } run_result=255 function run_example() { dir=$1 n=$2 count=$3 run=$(echo $dir | sed 's:^[0-9]*-::') # run started pushd $dir > /dev/null echo "===========================================================" echo "EXAMPLE $(basename $dir) ($n/$count)" echo cat DESCRIPTION echo "-----------------------------------------------------------" echo AREX_RUN_DIR="$RUN_DIR_BASE/$(basename $dir)" # merge double slashes (// -> /), # essential e. g. for core-DirectoryMatch-* examples AREX_RUN_DIR=$(echo $AREX_RUN_DIR | sed 's://:/:g') export AREX_RUN_DIR # prepare dir to write [ -e $AREX_RUN_DIR ] && rm -r $AREX_RUN_DIR mkdir -p $AREX_RUN_DIR mb=$(missing_binaries) if ! [[ $mb =~ 'apxs' ]]; then compile_modules fi mm=$(missing_modules) if [ -e skip.sh ] && sh skip.sh; then echo 'SKIPPED' head -n 1 skip.sh | sed 's:#::' run_result=1 elif [ -n "$mb" ]; then echo 'SKIPPED' echo "Following utilities are missing: $mb" run_result=1 elif [ -n "$mm" ]; then echo 'SKIPPED' echo "Following modules are missing: $mm" run_result=1 else # prepare the config, dir, run pre-run.sh, etc. prepare_run $dir # check the syntax of the example configuration echo -n 'Checking syntax ... ' syntax_ok="$(syntax_check)" if [ "$syntax_ok" == '1' ]; then echo 'OK.' else echo 'FAILURE.' echo echo 'SKIPPED' cat $AREX_RUN_DIR/syntax_check run_result=1 fi start_ok='0' if [ "$syntax_ok" == '1' ]; then echo -n 'Starting httpd ... ' start_ok=$(start_apache) if [ "$start_ok" == '1' ]; then cat $AREX_RUN_DIR/pid else echo 'SKIPPED' echo 'start_log:' cat $AREX_RUN_DIR/start_log echo 'error_log:' cat $AREX_RUN_DIR/error_log run_result=1 fi fi if [ "$start_ok" == '1' ]; then echov echov 'Running the example' echov echov "+++++++++ $AREX_RUN_DIR/httpd.conf ++++++++++" if [ $VERBOSITY -ge 1 ]; then cat $AREX_RUN_DIR/httpd.conf fi echov "+++++++++ $AREX_RUN_DIR/httpd.conf ++++++++++" echov echov "++++++++++ $AREX_RUN_DIR/run.sh ++++++++++" if [ $VERBOSITY -ge 1 ]; then cat run.sh fi echov "++++++++++ $AREX_RUN_DIR/run.sh ++++++++++" echov echo run echo if [ $run_exit_code == 0 ]; then echo "Example result: PASSED" run_result=0 else echo "Example FAILED (subexample #$run_exit_code):" for log in $AREX_RUN_DIR/error_log*; do echo "++++++++++ $log ++++++++++" cat $log echo "++++++++++ $log ++++++++++" echo done run_result=2 fi echo echo -n 'Stopping httpd ... ' stop_ok=$(stop_apache) if [ $stop_ok == '1' ]; then echo OK. else # should not happen echo FAILURE. fi fi finish_run echo echo "See for details: $AREX_RUN_DIR" fi echo "===========================================================" popd > /dev/null } function run_examples() { dirs=$1 passed="" skipped="" failed="" count=$(echo $dirs | wc -w) n=0 overall_exit_code=0 # iterate over examples for dir in $dirs; do n=$((n+1)) if [ ! -e $dir ]; then echo "error: $dir not found" continue fi if [ ! -d $dir ] || [ ! -e $dir/run.sh ] || [ ! -e $dir/DESCRIPTION ] || [ ! -e $dir/MODULES ] || [ ! -e $dir/example.conf* ]; then echo "warning: $dir does not look like example dir, skipping" continue fi run_example $dir $n $count case $run_result in 0) passed="$passed$dir " ;; 1) skipped="$skipped$dir " [ $overall_exit_code -lt 1 ] && overall_exit_code=1 ;; 2) failed="$failed$dir " [ $overall_exit_code -lt 2 ] && overall_exit_code=2 ;; # should not happen *) echo 'wrong return code from run_example()'; exit 10;; esac done echo echo "SUMMARY" echo "=======" echo "PASSED: $(echo $passed | wc -w)" if [ -n "$passed" ]; then echov "PASSED RUNS: $passed" fi echo "FAILED: $(echo $failed | wc -w)" if [ -n "$failed" ]; then echov "FAILED RUNS: $failed" fi echo "SKIPPED: $(echo $skipped | wc -w)" if [ -n "$skipped" ]; then echov "SKIPPED RUNS: $skipped" fi echo -n "OVERALL RESULT: " case $overall_exit_code in 0) echo "PASS ($(echo $passed | wc -w) OK)" ;; 1) echo "PASS ($(echo $passed | wc -w) OK, $(echo $skipped | wc -w) SKIPPED)" ;; 2) echo "FAIL ($(echo $failed | wc -w) KO, $(echo $skipped | wc -w) SKIPPED)" ;; esac } if [ "$1" == "-h" -o "$1" == "--help" -o "$1" == "" ]; then usage exit 0 elif [ -f "$1" ]; then dirs=$(cat $1 | tr '\n' ' ') else dirs="$@" fi check_system prepare_env check_open_ports run_examples "$dirs" exit $overall_exit_code