#!/bin/bash
#  Copyright: ©2010, Güralp Systems Ltd.
#  Author: Laurence Withers
#  License: GPLv3
#
#  Fix up socket and state directory ownership for multi-user systems. Such
#  ownership needs to be set in the configuration file. Socket owners are
#  generally going to be set to e.g. group "data" mode 0660, which will allow
#  any user in the "data" group to connect.
#
#  We need to modify any existing (.local) configuration files which do not have
#  the group set correctly.
#

# Only run once
[ -n "${POST_UPGRADE_CACHE}" ] && touch "${POST_UPGRADE_CACHE}/`basename $0`"

# pull in gcs rwvar stuff
. "/usr/share/config-base/scripts/functions.sh"



# fix_cf2()
#  Fix the socket group and permissions in a gslutil cf2 configuration file.
fix_cf2() {
    group="$1"
    mode="$2"
    glob="$3"
    var_prefix="$4"
    var_optgroup="$5"

    for cfg in ${glob}
    do
        [ -f "${cfg}" ] || continue
        [ "${cfg/.ctl.local}" == "${cfg}" ] || continue
        if [ "$(gcs_get_varcf2 "${var_prefix}group" "${cfg}" "${var_optgroup}")" != "${group}" ]
        then
            echo " * Updating socket permissions in ${cfg}"
            gcs_set_varcf2 "${var_prefix}group" "${cfg}" "${group}" "${var_optgroup}"
            gcs_set_varcf2 "${var_prefix}mode" "${cfg}" "${mode}" "${var_optgroup}"
        fi
    done
}



# fix_cf()
#  Fix the socket group and permissions in a gslutil configuration file.
fix_cf() {
    group="$1"
    mode="$2"
    glob="$3"
    var_prefix="$4"

    for cfg in ${glob}
    do
        [ -f "${cfg}" ] || continue
        [ "${cfg/.ctl.local}" == "${cfg}" ] || continue
        if [ "$(gcs_get_varcf "${var_prefix}group" "${cfg}")" != "${group}" ]
        then
            echo " * Updating socket permissions in ${cfg}"
            gcs_set_varcf "${var_prefix}group" "${cfg}" "${group}"
            gcs_set_varcf "${var_prefix}mode" "${cfg}" "${mode}"
        fi
    done
}



# socket/directory modes for different types of interface
READ="0666"
CONTROL="0660"
GROUPDIR="02775"
NORMALDIR="0755"



# The fixups to perform
fix_cf  "data"  "${GROUPDIR}"   "/etc/data-in-cd11/*.local"     "clientdb_dir_"
fix_cf  "data"  "${CONTROL}"    "/etc/data-out-cd11/*.local"    "management_socket_"
fix_cf  "data"  "${GROUPDIR}"   "/etc/data-out-cd11/*.local"    "dbdir_"
fix_cf  "data"  "${CONTROL}"    "/etc/gdi-link-rx/*.local"      "peer_control_socket_"
fix_cf  "data"  "${GROUPDIR}"   "/etc/gdi-link-rx/*.local"      "backfill_directory_"
fix_cf  "data"  "${CONTROL}"    "/etc/gdi-link-tx/*.local"      "peer_control_socket_"
fix_cf  "data"  "${GROUPDIR}"   "/etc/gdi-link-tx/*.local"      "backfill_directory_"
fix_cf2 "data"  "${CONTROL}"    "/etc/gdi2cd11/*.local"         "management_socket_"    ""
fix_cf2 "daemon" "${READ}"      "/etc/gdi2gcf/*.local"          "socket_"               ""
fix_cf2 "data"  "${GROUPDIR}"   "/etc/gcf-in-scream/*.local"    "backfill_directory_"   ""
fix_cf2 "daemon" "${READ}"      "/etc/gdi2miniseed/*.local"     "socket_"               ""
fix_cf2 "gpio"  "${NORMALDIR}"  "/etc/envirologd/*.local"       "dir_"                  ""
fix_cf2 "gpio"  "${NORMALDIR}"  "/etc/tamperd/*.local"          "dir_"                  ""



# gdi-base has some more complex fixups
fix_gdi_base_user() {
    local old_socket

    inst="$1"
    change_socket="$2"
    new_socket="$3"
    glob="$4"

    for user_cfg in ${glob}
    do
        [ -f "${user_cfg}" ] || continue
        [ "${user_cfg/.ctl.local}" == "${user_cfg}" ] || continue
        old_socket="$(gcs_get_varcf2 "gdi_socket" "${user_cfg}" "")"
        if [ -z "${old_socket}" ]
        then
            [ "${inst}" == "default" ] && old_socket="${change_socket}"
        fi

        if [ "${old_socket}" == "${change_socket}" ]
        then
            echo "  - used by ${user_cfg}"
            gcs_set_varcf2 "gdi_socket" "${user_cfg}" "${new_socket}" ""
        fi
    done
}

for cfg in /etc/gdi-base/*.local
do
    [ -f "${cfg}" ] || continue
    [ "${cfg/.ctl.local}" == "${cfg}" ] || continue

    old_socket="$(gcs_get_varcf "socket_path" "${cfg}")"

    if [ -n "${old_socket}" ]
    then
        inst="$(basename "${cfg}" ".local")"
        echo " * Updating gdi-base sockets in instance ${inst}"
        gcs_set_varcf "socket_path" "${cfg}" ""
        sink_socket_path="/var/run/gdi-base.${inst}.sink"
        gcs_set_varcf "sink_socket_path" "${cfg}" "${sink_socket_path}"
        gcs_set_varcf "sink_socket_mode" "${cfg}" "${READ}"
        source_socket_path="/var/run/gdi-base.${inst}.source"
        gcs_set_varcf "source_socket_path" "${cfg}" "${source_socket_path}"
        gcs_set_varcf "source_socket_mode" "${cfg}" "${CONTROL}"
        gcs_set_varcf "source_socket_group" "${cfg}" "data"
        gcs_set_varcf "metadata_directory_mode" "${cfg}" "02775"
        gcs_set_varcf "metadata_directory_group" "${cfg}" "conf"

        fix_gdi_base_user "${inst}" "${old_socket}" "${sink_socket_path}" \
            "/etc/gdi2cd11/*.local /etc/gdi2gcf/*.local /etc/gdi2miniseed/*.local \
            /etc/gdi-link-tx/*.local /etc/gdi2dbi/*.local \
            /etc/gsms-out/*.local /etc/qscd-out/*.local /etc/win-out/*.local \
            /etc/conf.d/serial/gcf-out-brp/*"

        fix_gdi_base_user "${inst}" "${old_socket}" "${source_socket_path}" \
            "/etc/gcf-in-brp/*.local /etc/gcf-in-scream/*.local \
            /etc/gdi-link-rx/*.local /etc/conf.d/serial/gcf-in-brp/*"
    fi
done



# data-mux-cd11 has some more complex fixups
fix_data_mux_cd11_user() {
    local old_socket

    inst="$1"
    change_socket="$2"
    new_socket="$3"
    glob="$4"

    for user_cfg in ${glob}
    do
        [ -f "${user_cfg}" ] || continue
        [ "${user_cfg/.ctl.local}" == "${user_cfg}" ] || continue
        old_socket="$(gcs_get_varcf2 "mux_path" "${user_cfg}" "")"
        if [ -z "${old_socket}" ]
        then
            [ "${inst}" == "default" ] && old_socket="${change_socket}"
        fi

        if [ "${old_socket}" == "${change_socket}" ]
        then
            echo "  - used by ${user_cfg}"
            gcs_set_varcf2 "mux_path" "${user_cfg}" "${new_socket}" ""
        fi
    done
}

for cfg in /etc/data-mux-cd11/*.local
do
    [ -f "${cfg}" ] || continue
    [ "${cfg/.ctl.local}" == "${cfg}" ] || continue

    old_socket="$(gcs_get_varcf "sockpath" "${cfg}")"

    if [ -n "${old_socket}" ]
    then
        inst="$(basename "${cfg}" ".local")"
        echo " * Updating data-mux-cd11 sockets in instance ${inst}"
        gcs_set_varcf "sockpath" "${cfg}" ""
        sink_socket_path="/var/run/data-mux-cd11.${inst}.sink"
        gcs_set_varcf "sink_socket_path" "${cfg}" "${sink_socket_path}"
        gcs_set_varcf "sink_socket_mode" "${cfg}" "${READ}"
        source_socket_path="/var/run/data-mux-cd11.${inst}.source"
        gcs_set_varcf "source_socket_path" "${cfg}" "${source_socket_path}"
        gcs_set_varcf "source_socket_mode" "${cfg}" "${CONTROL}"
        gcs_set_varcf "source_socket_group" "${cfg}" "data"
        gcs_set_varcf "dbdir_mode" "${cfg}" "02775"
        gcs_set_varcf "dbdir_group" "${cfg}" "data"

        fix_data_mux_cd11_user "${inst}" "${old_socket}" "${sink_socket_path}" \
            "/etc/data-out-cd11/*.local"

        fix_data_mux_cd11_user "${inst}" "${old_socket}" "${source_socket_path}" \
            "/etc/data-in-cd11/*.local /etc/gdi2cd11/*.local"
    fi
done



# control socket naming for gdi-link-[rt]x
for cfg in /etc/gdi-link-*/*.local
do
    [ -f "${cfg}" ] || continue
    [ "${cfg/.ctl.local}" == "${cfg}" ] || continue

    sock="$(gcs_get_varcf "peer_control_socket" "${cfg}")"
    if [ "${sock:20:1}" == "/" ]
    then
        inst="$(basename "${cfg}" ".local")"
        svc="${cfg:5:11}"
        echo " * Updating peer control socket for ${svc} ${inst}"
        gcs_set_varcf "peer_control_socket" "${cfg}" "/var/run/${svc}.${inst}.control"
    fi
done



# vim: ts=4:sw=4:expandtab
