#!/bin/bash
#
# Init file for the ARC gridftp server
#
# chkconfig: 2345 75 25
# description: ARC gridftpd
#
# config: /etc/sysconfig/nordugrid
# config: /etc/sysconfig/gridftpd
# config: /usr/etc/arc.conf
# config: /etc/arc.conf

### BEGIN INIT INFO
# Provides:          arc-gridftpd
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: ARC gridftpd
# Description:       ARC gridftp server
### END INIT INFO

# source function library
if [ -f /etc/init.d/functions ]; then
    . /etc/init.d/functions
    log_success_msg() {
	echo -n "$@"
	success "$@"
	echo
    }
    log_warning_msg() {
	echo -n "$@"
	warning "$@"
	echo
    }
    log_failure_msg() {
	echo -n "$@"
	failure "$@"
	echo
    }
elif [ -f /lib/lsb/init-functions ]; then
    . /lib/lsb/init-functions
else
    echo "Error: Cannot source neither init.d nor lsb functions"
    exit 1
fi

add_library_path() {
    location="$1"
    if [ ! "x$location" = "x" ] ; then
	if [ ! "$location" = "/usr" ] ; then
	    libdir="$location/lib"
	    libdir64="$location/lib64"
	    if [ -d "$libdir64" ] ; then
		if [ "x$LD_LIBRARY_PATH" = "x" ]; then
		    LD_LIBRARY_PATH="$libdir64"
		else
		    LD_LIBRARY_PATH="$libdir64:$LD_LIBRARY_PATH"
		fi
	    fi
	    if [ -d "$libdir" ] ; then
		if [ "x$LD_LIBRARY_PATH" = "x" ]; then
		    LD_LIBRARY_PATH="$libdir"
		else
		    LD_LIBRARY_PATH="$libdir:$LD_LIBRARY_PATH"
		fi
	    fi
	fi
    fi
}

prog=gridftpd
RUN=yes

# sysconfig files
if [ -r /etc/sysconfig/nordugrid ]; then
    . /etc/sysconfig/nordugrid
elif [ -r /etc/default/nordugrid ]; then
    . /etc/default/nordugrid
fi
if [ -r /etc/sysconfig/arc-${prog} ]; then
    . /etc/sysconfig/arc-${prog}
elif [ -r /etc/default/arc-${prog} ]; then
    . /etc/default/arc-${prog}
fi

if [ "$RUN" != "yes" ] ; then
    log_warning_msg "arc-${prog} disabled, please adjust the configuration to your"
    log_warning_msg "needs and then set RUN to 'yes' in /etc/default/arc-${prog} to enable it."
    exit 0
fi

# GLOBUS_LOCATION
GLOBUS_LOCATION=${GLOBUS_LOCATION:-/usr}
if [ ! -d "$GLOBUS_LOCATION" ]; then
    log_failure_msg "GLOBUS_LOCATION ($GLOBUS_LOCATION) not found"
    exit 1
fi
export GLOBUS_LOCATION

# ARC_LOCATION
ARC_LOCATION=${ARC_LOCATION:-/usr}
if [ ! -d "$ARC_LOCATION" ]; then
    log_failure_msg "ARC_LOCATION ($ARC_LOCATION) not found"
    exit 1
fi
export ARC_LOCATION

readorigconfigvar() {
    value=`$ARC_LOCATION/lib/arc/arcconfig-parser --config "$1" -b "$3" -o "$2" 2>/dev/null`
    if [ "$?" = '0' ] ; then
        echo "$value"
        exit 0
    else
        exit 1
    fi
}

readconfigvar() {
    fname="$1"
    optname="$2"
    blocks=""
    while [ ! -z "$3" ] ; do
        blocks="$blocks -b $3"
        shift
    done
    value=`$ARC_LOCATION/lib/arc/arcconfig-parser --runconfig "$fname" --load $blocks -o "$optname" 2>/dev/null`
    if [ "$?" = '0' ] ; then
        echo "$value"
        exit 0
    else
        exit 1
    fi
}

check_cert() {
  X509_USER_CERT=`readconfigvar "$ARC_RUNTIME_CONFIG" x509_host_cert gridftpd common`
  X509_USER_KEY=`readconfigvar "$ARC_RUNTIME_CONFIG" x509_host_key gridftpd common`
  if [ ! -f "$X509_USER_CERT" ] ; then
    log_failure_msg "Host certificate not found"
    exit 1
  fi
  if [ ! -f "$X509_USER_KEY" ] ; then
    log_failure_msg "Host key not found"
    exit 1
  fi
  # check permissions on key
  perms=`stat -L -c %a "$X509_USER_KEY"`
  if [ "$perms" != "600" ] && [ "$perms" != "400" ] ; then
    log_failure_msg "Host key must be readable only by user"
    exit 1
  fi
}

# ARC_CONFIG
if [ "x$ARC_CONFIG" = "x" ]; then
    if [ -r $ARC_LOCATION/etc/arc.conf ]; then
	ARC_CONFIG=$ARC_LOCATION/etc/arc.conf
    elif [ -r /etc/arc.conf ]; then
	ARC_CONFIG=/etc/arc.conf
    fi
fi

if [ ! -r "$ARC_CONFIG" ]; then
    log_failure_msg "ARC configuration not found (usually /etc/arc.conf)"
    exit 1
fi

# VOMS_LOCATION
VOMS_LOCATION=${VOMS_LOCATION:-@DEFAULT_VOMS_LOCATION@}

add_library_path "$VOMS_LOCATION"
add_library_path "$GLOBUS_LOCATION"
if [ "x$LD_LIBRARY_PATH" = "x" ]; then
    LD_LIBRARY_PATH=$ARC_LOCATION/lib
else
    LD_LIBRARY_PATH=$ARC_LOCATION/lib:$LD_LIBRARY_PATH
fi
export LD_LIBRARY_PATH

python_site_arch=`python -c 'from distutils import sysconfig; print(sysconfig.get_python_lib(1,0, "'${ARC_LOCATION}'"))'`
if [ "x$PYTHONPATH" = "x" ]; then
    PYTHONPATH=${python_site_arch}
else
    PYTHONPATH=${python_site_arch}:${PYTHONPATH}
fi
export PYTHONPATH

# PID and lock file
PID_FILE=`readorigconfigvar "$ARC_CONFIG" pidfile gridftpd`
if [ "x$PID_FILE" = "x" ]; then
    # Missing default value for pidfile means no service block is present
    log_failure_msg "ARC configuration is missing [gridftpd] block"
    exit 1
fi
ARC_RUNTIME_CONFIG=
LOCKFILE=

if [ `id -u` = 0 ] ; then
    # Debian does not have /var/lock/subsys
    if [ -d /var/lock/subsys ]; then
	LOCKFILE=/var/lock/subsys/$prog
    else
	LOCKFILE=/var/lock/$prog
    fi
else
    LOCKFILE=$HOME/$prog.lock
fi
ARC_RUNTIME_CONFIG=`echo "$PID_FILE" | sed 's#\([^\./]*\)\.[^\./]*$#\1#'`
ARC_RUNTIME_CONFIG="${ARC_RUNTIME_CONFIG}.cfg"


start() {
    CMD="$ARC_LOCATION/sbin/$prog"
    if [ ! -x "$CMD" ]; then
        log_failure_msg "Missing executable"
        exit 1
    fi

    # Pre-process configuration
    $ARC_LOCATION/lib/arc/arcconfig-parser --config "$ARC_CONFIG" --runconfig "$ARC_RUNTIME_CONFIG" --save 2>/dev/null
    if [ ! "$?" = '0' ] ; then
        log_failure_msg "ARC configuration processing failed"
        exit 1
    fi

    CMD="$CMD -c '$ARC_RUNTIME_CONFIG'"
    CMD="$CMD -P '$PID_FILE'"

    LOGFILE=`readconfigvar "$ARC_RUNTIME_CONFIG" logfile gridftpd`
    if [ ! -d `dirname "$LOGFILE"` ]; then
        mkdir -p `dirname "$LOGFILE"`
    fi

    check_cert

    echo -n "Starting $prog: "

    # Check if we are already running
    if [ -f $PID_FILE ]; then
	read pid < $PID_FILE
	if [ "x$pid" != "x" ]; then
	    ps -p "$pid" -o comm 2>/dev/null | grep "^$prog$" 1>/dev/null 2>/dev/null
	    if [ $? -eq 0 ] ; then
		log_success_msg "already running (pid $pid)"
		return 0
	    fi
	fi
	rm -f "$PID_FILE" "$LOCKFILE"
    fi

    eval "$CMD"
    RETVAL=$?

    if [ $RETVAL -eq 0 ]; then
	touch $LOCKFILE
	log_success_msg
    else
	log_failure_msg
    fi
    return $RETVAL
}

stop() {
    echo -n "Stopping $prog: "

    if [ -f "$PID_FILE" ]; then
	read pid < "$PID_FILE"
	if [ ! -z "$pid" ] ; then
	    kill "$pid"
	    RETVAL=$?
	    if [ $RETVAL -eq 0 ]; then
		log_success_msg
	    else
		log_failure_msg
	    fi

	    sleep 1
	    kill -9 "$pid" 1>/dev/null 2>&1
	    rm -f "$PID_FILE" "$LOCKFILE"
	else
	    RETVAL=1
	    log_failure_msg "$prog shutdown - pidfile is empty"
	fi
    else
	RETVAL=0
	log_success_msg "$prog shutdown - already stopped"
    fi
    return $RETVAL
}

status() {
    if [ -f "$PID_FILE" ]; then
	read pid < "$PID_FILE"
	if [ "$pid" != "" ]; then
	    if ps -p "$pid" > /dev/null; then
		echo "$1 (pid $pid) is running..."
		return 0
	    fi
	    echo "$1 stopped but pid file exists"
	    return 1
	fi
    fi
    if [ -f $LOCKFILE ]; then
	echo "$1 stopped but lockfile exists"
	return 2
    fi
    echo "$1 is stopped"
    return 3
}

restart() {
    stop
    start
}

case "$1" in
    start)
	start
	;;
    stop)
	stop
	;;
    status)
	status $prog
	;;
    restart | force-reload)
	restart
	;;
    reload)
	;;
    condrestart | try-restart)
	[ -f $LOCKFILE ] && restart || :
	;;
    *)
	echo "Usage: $0 {start|stop|status|restart|force-reload|reload|condrestart|try-restart}"
	exit 1
	;;
esac

exit $?
