#! /bin/sh
### BEGIN INIT INFO
# Provides:          gpsd
# Required-Start:    $remote_fs $syslog $network
# Should-Start:      bluetooth dbus udev
# Required-Stop:     $remote_fs $syslog $network
# Should-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# X-Start-Before:    ntp
# Short-Description: GPS (Global Positioning System) daemon start/stop script
# Description:       Start/Stop script for the gpsd service daemon,
#                    which is able to monitor one or more GPS devices
#                    connected to a host computer, making all data on
#                    the location and movements of the sensors available
#                    to be queried on TCP port 2947.
### END INIT INFO


# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin

DESC="GPS (Global Positioning System) daemon"
NAME="gpsd"
DAEMON=/usr/sbin/$NAME
PIDFILE=/var/run/$NAME.pid

. /etc/init.d/functions || exit 1

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

if [ -z "$GPSD_SOCKET" ] && [ -z "$DEVICES" ]; then
	GPSD_SOCKET=/var/run/gpsd.sock
fi

if [ -n "$GPSD_SOCKET" ]; then
	GPSD_OPTIONS="$GPSD_OPTIONS -F $GPSD_SOCKET"
fi

DAEMON_ARGS="$GPSD_OPTIONS $DEVICES"

#
# Function that starts the daemon/service
#
do_start() {
	local status pid

	status=0
	pid=`pidofproc $NAME` || status=$?
	case $status in
	0)
		echo "$DESC already running ($pid)."
		exit 1
		;;
	*)
		echo "Starting $DESC ..."
		exec $DAEMON $DAEMON_ARGS >/dev/null 2>&1 || status=$?
		echo "ERROR: Failed to start $DESC."
		exit $status
		;;
	esac
}

#
# Function that stops the daemon/service
#
do_stop() {
	local pid status

	status=0
	pid=`pidofproc $NAME` || status=$?
	case $status in
	0)
		# Exit when fail to stop, the kill would complain when fail
		kill -s 15 $pid >/dev/null && rm -f $PIDFILE && \
			echo "Stopped $DESC ($pid)." || exit $?
		;;
	*)
		echo "$DESC is not running; none killed." >&2
		;;
	esac

	return $status
}

#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
	local pid status

	status=0
	# If the daemon can reload its configuration without
	# restarting (for example, when it is sent a SIGHUP),
	# then implement that here.
	pid=`pidofproc $NAME` || status=$?
	case $status in
	0)
		echo "Reloading $DESC ..."
		kill -s 1 $pid || exit $?
		;;
	*)
		echo "$DESC is not running; none reloaded." >&2
		;;
	esac
	exit $status
}


#
# Function that shows the daemon/service status
#
status_of_proc () {
	local pid status

	status=0
	# pidof output null when no program is running, so no "2>/dev/null".
	pid=`pidofproc $NAME` || status=$?
	case $status in
	0)
		echo "$DESC is running ($pid)."
		exit 0
		;;
	*)
		echo "$DESC is not running." >&2
		exit $status
		;;
	esac
}

case "$1" in
start)
	do_start
	;;
stop)
	do_stop || exit $?
	;;
status)
	status_of_proc
	;;
restart)
	# Always start the service regardless the status of do_stop
	do_stop
	do_start
	;;
force-reload)
	# Only start the service when do_stop succeeds
	do_stop && do_start
	;;
*)
	echo "Usage: $0 {start|stop|status|restart|force-reload}" >&2
	exit 3
	;;
esac
