#
# oracleasm-Xshlib - Common shell functions
#


#
# Some basic functions
#


error()
{
    if [ $# -gt 0 ]
    then
        echo >&2 "$@"
    fi
}

die()
{
    error "$@"
    exit 1
}

usage()
{
    die "Usage: $(basename $0) $USAGE"
}


version()
{
    die "$0 version 2.1.8"
}


#
# perm_disk()
# Set the appropriate permissions on a disk.
#
# Returns 0 on success, 1 on error, 2 on already correct
#
perm_disk()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        die "perm_disk(): Requires an argument"
    fi

    DISKNAME="$1"

    OUTPUT="`ls -ld "${DISKNAME}" 2>/dev/null`"
    if [ $? != 0 ]
    then
        return 1
    fi

    OUID="`echo "$OUTPUT" | awk '{print $3}'`"
    OGID="`echo "$OUTPUT" | awk '{print $4}'`"

    if [ "$OUID" = "${ORACLEASM_UID:-root}" -a "$OGID" = "${ORACLEASM_GID:-root}" ]
    then
        return 2
    fi

    chown "${ORACLEASM_UID:-root}:${ORACLEASM_GID:-root}" "$DISKNAME" 2>&3
    if [ $? != 0 ]
    then
        return 1
    fi

    chmod 0660 "$DISKNAME" 2>&3
    if [ $? != 0 ]
    then
        return 1
    fi

    return 0
}

#
# Make a disk name uppercase, because ASM disk labels are all uppercase
# (SQL identifiers)
#
upper_disk()
{
    case "$1" in
    *[^_a-zA-Z0-9]*)
        echo "Disk label \"$1\" contains an invalid character" >&2
        ;;
    *)
        echo "$1" | tr '[a-z]' '[A-Z]'
        ;;
    esac
}


asm_disk_path()
{
    if [ $# -lt 1 ]
    then
        die "asm_disk_path requires an argument"
    fi

    manager="$1"
    name="$2"

    echo "${manager}/disks/$name"
}


# Why is this fake?  Because parsing ls(1) output is fragile
_fake_stat()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        die "fake_stat(): Requires an argument"
    fi

    DISKPATH="$1"
    ls -l "$DISKPATH" 2>/dev/null |
        awk '$5 ~ /[0-9]+,$/{
                 sub(/,$/, "", $5);
                 printf "0x%x 0x%x\n", $5, $6;
             }'
}


get_dev()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        die "get_dev(): Requires an argument"
    fi

    DISKPATH="$1"

    # Must use absolute path to which(1) because RedHat is dumb
    STAT=$(/usr/bin/which stat 2>/dev/null)
    if [ -z "$STAT" ]
    then
        _fake_stat "$DISKPATH"
    else
        $STAT -c '0x%t 0x%T' "$DISKPATH" 2>/dev/null
    fi
}

print_dev()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        die "print_dev(): Requires an argument"
    fi

    MAJOR_MINOR="$(get_dev "$1")"

    # MAJOR_MINOR cannot be quoted, because we want the space
    printf "%d %d" $MAJOR_MINOR
}


#
# Load configuration
#

ORACLEASM_MODNAME="oracleasm"
ORACLEASM_CONFIG_DIR=/etc/sysconfig



if [ -z "$ORACLE_ASMMANAGER" ]
then
    ORACLE_ASMMANAGER="/dev/oracleasm"
fi

if [ "$ORACLE_ASMMANAGER" = "/dev/oracleasm" ]
then
    ORACLEASM_CONFIG_FALLBACK="oracleasm"
else
    ORACLEASM_CONFIG_FALLBACK=
fi

ORACLEASM_CONFIG_FILE="oracleasm-$(echo ${ORACLE_ASMMANAGER} | sed -e 's/\//_/g')"


if [ ! -e "$ORACLEASM_CONFIG_DIR" ]
then
    mkdir -p "$ORACLEASM_CONFIG_DIR" 2>&3
    if [ $? != 0 ]
    then
        die "Unable to access configuration directory"
    fi
fi

ORACLEASM_CONFIG="${ORACLEASM_CONFIG_DIR}/${ORACLEASM_CONFIG_FILE}"
if [ -n "$ORACLEASM_CONFIG_FALLBACK" -a ! -f "${ORACLEASM_CONFIG}" -a \
     -f "${ORACLEASM_CONFIG_DIR}/${ORACLEASM_CONFIG_FALLBACK}" ]
then
    mv "${ORACLEASM_CONFIG_DIR}/${ORACLEASM_CONFIG_FALLBACK}" \
        "${ORACLEASM_CONFIG}" 2>&3
    if [ $? != 0 ]
    then
        die "Unable to update configuration linkage"
    fi

    ln -s "${ORACLEASM_CONFIG_FILE}" \
        "${ORACLEASM_CONFIG_DIR}/${ORACLEASM_CONFIG_FALLBACK}" \
        2>&3
    if [ $? != 0 ]
    then
        die "Unable to update configuration linkage"
    fi
fi

[ -f "${ORACLEASM_CONFIG}" ] && . "${ORACLEASM_CONFIG}"


