#!/bin/bash
# config-scripts/src/share/sys/functions.sh
# 
#  Copyright: ©2007–2012, Güralp Systems Ltd.
#  Author: Laurence Withers <lwithers@guralp.com>
#  Author: Bob Dunlop <rdunlop@guralp.com>
#  License: GPLv3
#

CFGROOT=
CONFIGDIR="${CFGROOT}/etc"
CONFDIR="${CONFIGDIR}/conf.d"
CONFDIR2="${CONFIGDIR}/conf.local"
NETCONFDIR="${CONFIGDIR}/network"
INITDIR="${CONFIGDIR}/init.d"
INITDIR2="${CONFIGDIR}/init.local"
SERVDIR="/usr/share/config-base/services"
TMPDIR="/tmp"

declare -i gcs_errors=0
declare gcs_error_msg_set=n

# With the advent of multi-user support we need to take care to preserve or
# setup group write permissions on files.

# Only block global write by default.
umask 002

group_move_file() {
    local src=$1
    local dst=$2
    local grp=$3
    local mod=$4

    if [ -e $dst ]
    then
        diff $src $dst > /dev/null || cat $src > $dst
        [ -n "$grp" ] && chgrp $grp $dst > /dev/null 2>&1
        [ -n "$mod" ] && chmod $mod $dst > /dev/null 2>&1
        rm -f $src
    else
        mv $src $dst
        chgrp ${grp:-conf} $dst > /dev/null 2>&1
        chmod ${mod:-0664} $dst > /dev/null 2>&1
    fi
}

group_mkdir() {
    local dst=$1
    local grp=$2
    local mod=$3

    if [ -d $dst ]
    then
        [ -n "$grp" ] && chgrp $grp $dst > /dev/null 2>&1
        [ -n "$mod" ] && chmod $mod $dst > /dev/null 2>&1
    else
        mkdir -p -m ${mod:- 775} $dst
        chgrp ${grp:-conf} $dst > /dev/null 2>&1
    fi
}


# Variable and error output

# Use this in place of a direct echo incase we change quoting/escaping
gcs_var() {
    echo "$1=\"$2\""
}

# Add a named error
gcs_err() {
    local name=$1
    shift

    echo "error_${name}=\"$*\""
    (( gcs_errors++ ))
    [ "${name}" = "msg" ] && gcs_error_msg_set=y
}

# Add an error text but without adding it to the error total (a warning)
gcs_warn() {
    local name=$1
    shift

    echo "error_${name}=\"$*\""
    [ "${name}" = "msg" ] && gcs_error_msg_set=y
}


# Variable input and processing

# Read variable list from stdin and save to a file
gcs_read_vars() {
    VARFILE=$(mktemp $TMPDIR/gcsvars.XXXXXX)

    cat > $VARFILE

    # Load the variables into our environment (safe now the config engine
    # is checking them)
    source $VARFILE
}

gcs_get_var() {
    eval echo "\$$1"
}


# Check a config file exists, creating it if it doesn't
gcs_ensure_cfgfile_exists() {
    local file="$1"
    local grp="${2:-conf}"
    local mod="${3:- 0664}"

    if [ ! -e "$file" ]
    then
        group_mkdir $(dirname "$file") $grp 2775
        echo "# File created by Guralp Configuration System $(date)" \
                                    > "$file"
        chgrp $grp "$file" > /dev/null 2>&1
        chmod $mod "$file" > /dev/null 2>&1
    fi
}


# Read/write variables in format "name=value", possibly with quotes
gcs_get_varf() {
    gcs_rwvar gcs_get_varf "$1" "$2"
}

gcs_set_varf() {
    local name=$1
    local file=$2
    local value="$3"

    gcs_ensure_cfgfile_exists "$file"
    gcs_rwvar gcs_set_varf "$name" "$file" "$value"
}


# Read/write variables in format "name: value"
gcs_get_cvarf() {
    gcs_rwvar gcs_get_cvarf "$1" "$2"
}

gcs_set_cvarf() {
    local name=$1
    local file=$2
    local value="$3"

    gcs_ensure_cfgfile_exists "$file"
    gcs_rwvar gcs_set_cvarf "$name" "$file" "$value"
}


# Read/write variables in libgslutil's cffile format
gcs_get_varcf() {
    gcs_rwvar gcs_get_varcf "$1" "$2" 2>/dev/null
}

gcs_set_varcf() {
    local name=$1
    local file=$2
    local value="$3"

    gcs_ensure_cfgfile_exists "$file"
    gcs_rwvar gcs_set_varcf "$name" "$file" "$value"
}

# Common action when reading config. Get a value from the standard config file
# and emit it.  Unwind call to gcs_get_varcf() and gcs_var()
gcs_var_o() {
    local name="$1"
    local val
    
    if [ -r "$CFGFILE" ]
    then
	val="$(gcs_rwvar gcs_get_varcf "$name" "$CFGFILE")"
	[ -n "$val" ] && echo "o_${name}=\"$val\""
    fi
}


# Read/write variables in libgslutil's cffile2 format
gcs_get_varcf2() {
    gcs_rwvar gcs_get_varcf2 "$1" "$2" "$3" 2>/dev/null
}

gcs_set_varcf2() {
    local name=$1
    local file=$2
    local value="$3"
    local section="$4"

    gcs_ensure_cfgfile_exists "$file"
    gcs_rwvar gcs_set_varcf2 "$name" "$file" "$value" "$section"
}

# cf2 varient of gcs_var_o()
gcs_var_o2() {
    local name="$1"
    local section="$2"
    local val
    
    if [ -r "$CFGFILE" ]
    then
	val="$(gcs_rwvar gcs_get_varcf2 "$name" "$CFGFILE" "$section")"
	[ -n "$section" ] && name="${section}_$name"
	[ -n "$val" ] && echo "o_${name}=\"$val\""
    fi
}

gcs_list_varcf2() {
    local file=$1
    local section="$2"

    gcs_ensure_cfgfile_exists "$file"
    gcs_rwvar gcs_list_varcf2 "$file" "$section"
}

gcs_list_varcf2_sections() {
    local file="$1"

    gcs_ensure_cfgfile_exists "$file"
    gcs_rwvar gcs_list_varcf2_sections "$file"
}

gcs_clear_varcf2_section() {
    local file=$1
    local section="$2"

    gcs_ensure_cfgfile_exists "$file"
    gcs_rwvar gcs_clear_varcf2_section "$file" "$section"
}


# Read/write variables in format "keyword value"
gcs_get_varw() {
    gcs_rwvar gcs_get_varw "$1" "$2" 2>/dev/null
}

gcs_set_varw() {
    local name=$1
    local file=$2
    local value="$3"

    gcs_ensure_cfgfile_exists "$file"
    gcs_rwvar gcs_set_varw "$name" "$file" "$value"
}


# All done. Cleanup
gcs_cleanup() {
    [ -n "$VARFILE" ] && rm -f $VARFILE

    if (( gcs_errors > 0 ))
    then
        if [ "$gcs_error_msg_set" = "n" ]
        then
            gcs_err msg "$gcs_errors errors found"
        fi
    fi
}


# Check if a table has at least one entry
check_table_not_empty() {
    local table=$1
    local field=$2
    local err="$3"
    local -i i rows
    local v

    v="new_${table}_rows"
    rows=${!v}

    for (( i = 0 ; i < rows ; i++ ))
    do
	v="new_$field$i"
	[ -n "${!v}" ] && return 0
    done
    gcs_err "$table" "$err"
}


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