#!/bin/bash
#
# Initialization functions for spxmanage
#

# Initializes the location variables, if the argument is non-empty
# it overrides the default raperca service directory
init_dirs() {
    SRVDIR=/srv/raperca
    SHADOWSRVDIR=/srv/.shadow-raperca
    if [ -n "$1" ]; then
        SRVDIR="$1"
        SHADOWSRVDIR="$(dirname "$SRVDIR")"/.shadow-raperca
    fi
    CONTENTDIR="$SRVDIR"/content
    SHADOWCONTENTDIR="$SHADOWSRVDIR"/content
    DEFCONTENTDIR=/usr/share/resources/default/content/default
    INTERFACEDIR="$SRVDIR"/interface
    PUBLICINTERFACEDIR="$INTERFACEDIR"/public
    PROTECTEDINTERFACEDIR="$INTERFACEDIR"/protected
    TMPINTERFACEDIR="$INTERFACEDIR"/tmp
    ASSETSDIR=/usr/share/spxassets
    ASSETSDB="$PROTECTEDINTERFACEDIR"/assets.db
    DAVLOCKDBDIR=/var/cache/spxmanage/dav
    YIIRUNTIME=/var/cache/spxmanage/yii-runtime
    SPOOLDIR=/var/spool/spxmanage
    UIVARDIR=/var/lib/spxmanage/ui
    UIDB="$UIVARDIR"/ui.db
}

# Mounts the shadow dir if not already mounted
mount_shadow_dir() {
    grep -q "^[^[:space:]]\+[[:space:]]\+$SHADOWSRVDIR[[:space:]]\+" \
        /proc/mounts || mount --bind "$SRVDIR" "$SHADOWSRVDIR"
}

# Creates the specified content dir, if not already present
# and sets the permissions correctly
make_content_dir()
{
    [ -n "$1" ] || return
    [ -d "$(dirname "$1")" ] || return
    mkdir -p "$1" && chown root:www-data "$1" && chmod 0775 "$1"
}

# Copies the default content to the list dirs provided as arguments;
# if none provided, or first arg is empty, it defaults to
# "$SHADOWCONTENTDIR" and "$CONTENTDIR".
# The copy is done through the first dir, so if two dirs are effectively
# the same the further copies are a no-op.
copy_default_content() {
    if [ -z "$1" ]; then
        copy_default_content "$SHADOWCONTENTDIR" "$CONTENTDIR"
    else
        local SDIR
        SDIR="$1"
        make_content_dir "$SDIR" && \
            find "$DEFCONTENTDIR" -mindepth 1 -maxdepth 1 -print0 | \
            xargs -0r cp -f -r --target-directory="$SDIR" && \
            find "$SDIR" -mindepth 1 -print0 | xargs -0r chown www-data:www-data
        [ -e "$SDIR"/index.svg ] && touch "$SDIR"/index.svg
        while shift; do
            make_content_dir "$1" && \
            find "$SDIR" -mindepth 1 -maxdepth 1 -print0 | \
                xargs -0r cp -f -r -p --target-directory="$1" 2>/dev/null
            [ -e "$1"/index.svg ] && touch "$1"/index.svg
        done
    fi
}

# Removes the contents of all the directories passed as arguments
clean() {
    # recursively remove all contents of the passed-in dirs
    # this way hidden files are also catched.
    find  "$@" -mindepth 1 -maxdepth 1 -print0 | \
        xargs -0r rm -rf -- 2>/dev/null
}

# Removes all dav_fs tmp files from all the directories passed as
# arguments. dav_fs from Apache httpd 2.4 uses ".davfs.tmp" as prefix
# while SpinetiX patch for Apache httpd 2.2 uses ".davtmp."
clean_dav_tmp() {
    find "$@" -type f \( -name ".davfs.tmp*" -o -name ".davtmp.*" \) -print0 | \
        xargs -0r rm -f --
}

# Cleans the dav lock database
clean_davlockdb() {
    find "$DAVLOCKDBDIR" -type f -print0 | xargs -0r rm -f --
}

# Detects the web server configured restrictions and redirections.
#
# arg1: "yes" if SSL support is enabled on web server
# arg2: the host prefix string from the model resources, or empty if none
# arg3: the device serial number
#
# Sets the following global variables
# NOHTTP: "yes" if plain http is not available over the network
# NOHTTPS: "yes" if secure http (https) is not available over the network
# NODAVHTTP: "yes" if plain http for the DAV port is not available over the network
# HTTPREDIRECT: "yes" if plain http is redirected to https
# HTTPSHOST: the host name to use for https, empty if none or not applicable
# NOHTTPPUBLISH: "yes" if publishing via HTTP is restricted
load_web_server_opts() {
    local enablessl="$1"
    local hostprefix="$2"
    local serialnr="$3"
    local htcert=/etc/apache2/server.crt
    local htspxdefs=/etc/apache2/conf.d/01-spxmanage-defs.conf
    local htspxrundefs=/var/run/spxmanage/httpd-defs.conf

    if egrep -q '^[[:space:]]*Define[[:space:]]+NOSSL_LOCALHOST_ONLY([[:space:]]|$)' "$htspxdefs"; then
        NOHTTP=yes
    else
        NOHTTP=no
    fi
    if [ "$NOHTTP" != "yes" ] && egrep -q '^[[:space:]]*Define[[:space:]]+NOSSL_DAV_PORT_ALLOW_REMOTE([[:space:]]|$)' "$htspxdefs"; then
        NODAVHTTP=no
    else
        NODAVHTTP=yes
    fi
    if [ "$enablessl" != "yes" ] || egrep -q '^[[:space:]]*Define[[:space:]]+SSL_LOCALHOST_ONLY([[:space:]]|$)' "$htspxdefs"; then
        NOHTTPS=yes
    else
        NOHTTPS=no
    fi
    if [ "$NOHTTPS" != "yes" ] && egrep -q '^[[:space:]]*Define[[:space:]]+NOSSL_REDIRECT([[:space:]]|$)' "$htspxdefs"; then
        HTTPREDIRECT=yes
    else
        HTTPREDIRECT=no
    fi
    # Get the preferred server name if HTTPS is enabled to signal it as FQDN 
    if [ "$NOHTTPS" != "yes" ]; then
        HTTPSHOST="$(sed -n -e '/^\s*Define\s\+SSL_SUBJECT_NAME\s/{s/\s*Define\s\+SSL_SUBJECT_NAME\s\+\(\S*\).*/\1/;p;q}' "$htspxdefs")"
        [ "$HTTPSHOST" = "-" ] && HTTPSHOST=
        # If none configured attempt to get it from certificate's subject
        if [ -z "$HTTPSHOST" -a -f "$htcert" ]; then
            HTTPSHOST="$(openssl x509 -subject -noout -nameopt utf8,sep_multiline -in "$htcert" | sed -n -e '/^\s*CN=/{s/^[^=]*=\(\S*\).*/\1/;p;q}')"
        fi
        # Ignore it if it matches that of the auto generated self-signed cert, the Bonjour's
        # service target name is a better bet in this case.
        if [ "$HTTPSHOST" = "$hostprefix""$serialnr" ]; then
            HTTPSHOST=
        fi
    else
        HTTPSHOST=
    fi

    if [ -f "$htspxrundefs" ] && egrep -q '^[[:space:]]*Define[[:space:]]+OnlyUploaderPublish([[:space:]]|$)' "$htspxrundefs"; then
        NOHTTPPUBLISH=yes
    else
        NOHTTPPUBLISH=no
    fi

}
