#!/usr/bin/env bash

# --- utility functions ---

write() {

    local filename="$1"

    local directory=`dirname "$filename"`
    mkdirectory "$directory"
    if [ "x$?" != "x0" ] ; then
        ERROR=$?
        echo "Can not create directory $directory" >&2
        return $ERROR
    fi

    # Check target file can be replaced
    if [ -f "$filename" ] ; then
        if [ ! -w "$filename" -o ! -r "$filename" ] ; then
            echo "Can not read/write to $filename" >&2
            return 100
        fi
    fi

    # Put new content into temporary file
    local tmpfile=`mktemp "$filename".XXXXXX`
    if [ "x$?" != "x0" -o ! -w "$tmpfile" ] ; then
        echo "Can not create temporary file $tmpfile" >&2
        return 101
    fi

    cat > "$tmpfile"
    if [ "x$?" != "x0" ] ; then
        echo "Error writing to $tmpfile" >&2
        rm -f "$tmpfile"
        return 101
    fi

    # Check that new file is not empty
    if [ ! -s "$tmpfile" ] ; then
        echo "No or empty input supplied on utility's standard input stream!" >&2
        rm -f "$tmpfile"
        return 101
    fi

    # Remove existing target file
    if [ -f "$filename" ] ; then
        rm -f "$filename"
        if [ "x$?" != "x0" ] ; then
            echo "Can not remove existing file $filename" >&2
            rm -f "$tmpfile"
            return 100
        fi
    fi

    # Commit changes to target file (disable interactivity in mv)
    mv -f "$tmpfile" "$filename"
    if [ "x$?" != "x0" ] ; then
        ERROR=$?
        rm -f "$tmpfile"
        return $ERROR
    fi

    # Correct owner & permissions
    chown "$FILE_OWNERGROUP" "$filename" && chmod "$FILE_PERMS" "$filename"

    return $?
}

mklink() {
    local filename="$1"
    local directory=`dirname "$filename"`

    if ! [ -d "$directory" -a -f "$filename" ]; then
        echo "Path $filename doesn't exist"
        return 100
    fi

    # Create convenience symlink to last written config
    local fname=`basename "$filename"`
    local lnkname="last_${fname#*_}"
    if ! echo "${fname%%_*}" | grep -q '[^0-9.]' 2>/dev/null ; then
        pushd "$directory"
        if [ ! -f "$lnkname" -o -L "$lnkname" ] ; then
            rm -f "$lnkname" && ln -s "$fname" "$lnkname"
            ERROR=$?
        else
            echo "Refusing to create symlink '$directory/$lnkname': file with the same name already exists"
            ERROR=101
        fi
        popd
    else
        echo "Refusing to create symlink: unexpected file name format"
        ERROR=101
    fi

    return $ERROR
}

mkdirectory() {

    local path="$1"

    if [ -d "$path" ] ; then
        return 0
    fi

    if [ -e "$path" ] ; then
        echo "File $path already exists" >&2
        return 100
    fi

    mkdir "$path"
    if [ "x$?" != "x0" ] ; then
        ERROR=$?
        return $ERROR
    fi

    chmod "$DIR_PERMS" "$path"
    if [ "x$?" != "x0" ] ; then
        ERROR=$?
        return $ERROR
    fi
    chown "$DIR_OWNERGROUP" "$path"
    if [ "x$?" != "x0" ] ; then
        ERROR=$?
        return $ERROR
    fi

    return $?
}

check() {
    local id file
    while read data; do
        if [ "x$data" != "x" ]; then
            id=${data%%:*};
            file=${data#*:};
            if [ ! -f $file ]; then
                echo "$id:File '$file' not found";
            fi
        fi
    done
    return 0
}

#!/usr/bin/env bash

usage() {
    cat << EOH

Usage: $0 [options]

 Helper utility to manage Apache configuration files

OPTIONS:
 -t      - Test current configuration of web server.
 -d dir  - Create directory.
 -w file - Write content from stdin to the specified file.
 -l file - Switch or create 'last_*' symlink to the specified file.
 -c      - Read configuration files list from stdin and check their
           their presence. Each line should be like '<id>:<filepath>'.

EOH
}

set_params()
{
    DIR_OWNERGROUP="wwwrun":"psacln"
    DIR_PERMS=770
    FILE_OWNERGROUP="root":"www"
    FILE_PERMS=640
}

# --- script ---

if [ $# -eq 0 ] ; then
    usage
    exit 0
fi

getopts "td:w:l:c" OPTION

set_params

ERROR=0
case $OPTION in
    t)
        [ ! -e "/etc/apache2/envvars" ] || source /etc/apache2/envvars
        /etc/init.d/apache2 test
        ERROR=$?
        ;;
    d)
        mkdirectory "$OPTARG"
        ERROR=$?
        ;;
    w)
        write "$OPTARG"
        ERROR=$?
        ;;
    l)
        mklink "$OPTARG"
        ERROR=$?
        ;;
    c)
        check
        ERROR=$?
        ;;
    *)
        usage
        ERROR=1
        ;;
esac

exit $ERROR

#
# Helper utility for file operations with Apache's configuration files.
#
