# This is shell script, sourced by uWSGI init.d script . /usr/share/uwsgi/init/snippets . /usr/share/uwsgi/init/specific_daemon do_command() { local COMMAND="$1" shift local ERRORS=0 # If command is given with arguments, i.e. 'start smth smth_else' if [ -n "$1" ]; then [ "x$VERBOSE" != "xno" ] && log_progress_msg "->" # Iterate over given configuration file specifications and: # * either print notice that conforming conffile wasn't found (if it # wasn't) # * or execute given command with conforming conffile local CONFSPEC_PATH="" for CONFSPEC in "$@"; do CONFSPEC_RELPATH="$(relative_path_to_conffile_with_spec "$CONFSPEC")" if [ -z "${CONFSPEC_RELPATH}" ]; then log_progress_not_found "$CONFSPEC" else do_with_given_specific_daemon "$COMMAND" "$CONFSPEC_RELPATH" ERRORS="$(expr "$ERRORS" + "$?")" fi done [ "$ERRORS" -eq 0 ] && log_progress_done return "$ERRORS" fi # Do not start daemon if it was disabled. if [ "x$COMMAND" = "xstart" -a "x$RUN_AT_STARTUP" != "xyes" ]; then [ "x$VERBOSE" != "xno" ] && log_progress_msg "(disabled; see /etc/default/${NAME})" return 2 fi local SOME_CONF_WAS_FOUND=no local UWSGI_APPS_CONFDIRS="$(ls -1d ${UWSGI_APPS_CONFDIR_GLOB})" # This construction is needed for supporting configuration file names with # spaces or control characters. # # See http://www.dwheeler.com/essays/filenames-in-shell.html (paragraph #4). # # Predefined delimeters are resetted to null character (by changing IFS and # setting -d option of 'read' command) and then: # * 'find -print0' command is used for finding all available confnames # * 'while ... read' loop is used for iterating over found confnames # # Also process substitution is used, so that variables changed inside 'while' # loop will retain their values after exiting from loop. # # By default 'find' command use emacs-style regexps. Emacs-style regexp # processor with given regexp doesn't matches to file names with newline # character. Posix-style regexp processor is working good. # # With executing 'sed' over found paths, relative configuration file # paths are extracted from full paths provided with 'find' output. # Firstly, common directory path (UWSGI_CONFDIR) is stripped from 'find' # output. Secondly, all directories (except the first) and file extensions # are stripped from result of first substitution. # # For example: list of found paths # '/etc/uwsgi/apps-enabled/site.ini\0/etc/uwsgi/apps-enabled/dir/site2.ini' # is transformed by sed into 'apps-enabled/site\0apps-enabled/site2'. while IFS="" read -r -d "" RELATIVE_CONFPATH <&4 ; do if [ "x$SOME_CONF_WAS_FOUND" = "xno" -a "x$VERBOSE" != "xno" ]; then log_progress_msg "->" fi SOME_CONF_WAS_FOUND=yes do_with_given_specific_daemon "$COMMAND" "$RELATIVE_CONFPATH" ERRORS="$(expr "$ERRORS" + "$?")" done 4< <(find "$UWSGI_APPS_CONFDIRS" \ -regextype posix-basic \ -iregex ".*\.${UWSGI_CONFFILE_TYPES_REGEXP}\$" -a -xtype f \ -print0 \ | sed -e "s:\(^\|\x0\)${UWSGI_CONFDIR}/:\1:g" \ -e "s:\([^\x0/]\+\)\([^\x0]\+\)\?/\([^/\x0]\+\)\.${UWSGI_CONFFILE_TYPES_REGEXP}\x0:\1/\3\x0:g" \ | sort --zero-terminated --unique \ ) if [ "x$VERBOSE" != "xno" ]; then if [ "x$SOME_CONF_WAS_FOUND" = "xno" ]; then log_progress_msg "(omitted; missing conffile(s) in ${UWSGI_APPS_CONFDIR_GLOB})" elif [ "$ERRORS" -eq 0 ]; then log_progress_done fi fi return "$ERRORS" } do_with_given_specific_daemon() { local COMMAND="$1" shift local RELATIVE_CONFPATH="$@" local ERRORS=0 case "$COMMAND" in start) do_start_specific_daemon "$RELATIVE_CONFPATH" ;; stop) do_stop_specific_daemon "$RELATIVE_CONFPATH" ;; force-reload) do_force_reload_specific_daemon "$RELATIVE_CONFPATH" ;; reload|*) do_reload_specific_daemon "$RELATIVE_CONFPATH" ;; esac case "$?" in 0) log_progress_ok "$RELATIVE_CONFPATH" ;; 1) log_progress_skip "$RELATIVE_CONFPATH" ;; *) log_progress_error "$RELATIVE_CONFPATH" ERRORS=1 ;; esac return "$ERRORS" } # Print progress notification about successful command execution. log_progress_ok() { local RELATIVE_CONFPATH="$@" local CONFNAME="" [ "x$VERBOSE" = "xno" ] && return if [ "x$PRINT_CONFNAMES_IN_INITD_SCRIPT_OUTPUT" != "xno" ]; then CONFNAME="$(make_confname_for_progress_log "$RELATIVE_CONFPATH")" log_progress_msg "$CONFNAME" else log_progress_msg '.' fi } # Print progress notification about skipped command execution. # # It is printed, for example, when 'start' command was issued, but specific # daemon is already started. Or when 'stop' command was issued, but specific # daemon isn't runned yet. log_progress_skip() { local RELATIVE_CONFPATH="$@" local CONFNAME="" [ "x$VERBOSE" = "xno" ] && return if [ "x$PRINT_CONFNAMES_IN_INITD_SCRIPT_OUTPUT" != "xno" ]; then CONFNAME="$(make_confname_for_progress_log "$RELATIVE_CONFPATH")" log_progress_msg "(${CONFNAME})" else log_progress_msg "." fi } # Print progress notification about missing configuration file with given # name. log_progress_not_found() { local RELATIVE_CONFPATH="$@" local CONFNAME="" [ "x$VERBOSE" = "xno" ] && return if [ "x$PRINT_CONFNAMES_IN_INITD_SCRIPT_OUTPUT" != "xno" ]; then CONFNAME="$(make_confname_for_progress_log "$RELATIVE_CONFPATH")" fi log_progress_msg "${CONFNAME}?" } # Print progress notification about failed command execution. log_progress_error() { local RELATIVE_CONFPATH="$@" local CONFNAME="" [ "x$VERBOSE" = "xno" ] && return if [ "x$PRINT_CONFNAMES_IN_INITD_SCRIPT_OUTPUT" != "xno" ]; then CONFNAME="$(make_confname_for_progress_log "$RELATIVE_CONFPATH")" fi log_progress_msg "${CONFNAME}!" } log_progress_done() { log_progress_msg "done" } make_confname_for_progress_log() { local RELATIVE_CONFPATH="$@" local CONFNAMESPACE="$(extract_confnamespace "$RELATIVE_CONFPATH")" local CONFNAME="$(extract_confname "$RELATIVE_CONFPATH")" echo "$(sanitize_confname "${CONFNAMESPACE}/${CONFNAME}")" } # Sanitize configuration file name for printing it in terminal. sanitize_confname() { local CONFNAME="$@" # In sanitizing: # * all control ASCII characters are replaced with '?' character # * confname with spaces is surrounded by single quotes. CONFNAME="$(echo -n "$CONFNAME" | tr '[\001-\037\177]' '?')" case "$CONFNAME" in *[[:space:]]*) echo "'$CONFNAME'" ;; *) echo "$CONFNAME" ;; esac }