#!/bin/sh
# WARNING: This file was auto-generated. Do not edit!
# 
# $Id: svps.in,v 1.23 2024-10-24 18:06:23+05:30 Cprogrammer Exp mbhangui $
#

do_days()
{
	secs=$1
	if [ $mday -eq 1 ] ; then
		tstr=$(printf '%2d days, %02d hrs, %02d mins, %02d secs\n' $((secs/86400)) $((secs%86400/3600)) $((secs%3600/60)) $((secs%60)))
	else
		tstr=$(printf '%7d secs' $secs)
	fi
}

get_mod()
{
	SYSTEM=$(uname -s)
	case "$SYSTEM" in
		Darwin|FreeBSD)
		mod=$(stat -f "%m" $1)
		;;
		*)
		if [ -f /etc/alpine-release ] ; then
			mod=$(stat -c "%Y" $1)
		else
			mod=$(stat --printf="%Y\n" $1)
		fi
	esac
}

do_svscan()
{
	now=$(date +%s)
	words=$(ps axu|head -1|wc -w)
	words=$(expr $words - 1)

	t=$(expr $max - $svscan_length)
	printf "============ %-"$t"s     state uptime ===== pid/spid ==\n" "svscan"
	ps axu|grep root|grep "sbin/svscan"|grep -Ev "grep|multilog|supervise" | while read line
	do
		set $line
		pid=$2
		if [ -s ${12}/.svscan/variables/DISABLE_RUN ] ; then
			t=$(cat /proc/$pid/cmdline |tr '\0' '\n'|tail -n +2)
			get_mod $t/.svscan.pid
		else
			get_mod $pidfile
		fi
		diff=$(expr $now - $mod)
		do_days $diff
		shift $words
		printf "%-"$max"s up   %s  pid %7d\n" "$*" "$tstr" $pid
	done
}

doit()
{
	svpid=$1
	svdir=$2
	option=$3

	t=$(expr $max - $svscan_length)
	case "$option" in
		all|main)
		echo
		printf "============ %-"$t"s     state uptime ===== pid/spid ==\n" $svdir

		grep -w down /tmp/svps.$$ | grep -E -v "normally down|want down" | sort -n -k3 | grep -v "/log" | while read line
		do
			set $line
			name=`echo $1|cut -d: -f1`
			secs=$3
			do_days $secs
			if [ "$5" = "normally" ] ; then
				printf "%-"$max"s down %s spid %7d\n" $name "$tstr" $8
			elif [ "$5" = "want" ] ; then
				printf "%-"$max"s down %s spid %7d\n" $name "$tstr" $8
			else
				printf "%-"$max"s down %s spid %7d\n" $name "$tstr" $6
			fi
			if [ $? -ne 0 ] ; then
				break
			fi
		done

		grep -Ew wait /tmp/svps.$$ | sort -n -k3 | grep -v "/log" | while read line
		do
			set $line
			name=`echo $1|cut -d: -f1`
			secs=$3
			do_days $secs
			if [ $# -eq 9 ] ; then
				printf "%-"$max"s wait %s  pid %7d remaining %7d seconds\n" $name "$tstr" $6 $8
			else
				printf "%-"$max"s wait %s  pid %7d\n" $name "$tstr" $6
			fi
			if [ $? -ne 0 ] ; then
				break
			fi
		done

		grep -Ew "up" /tmp/svps.$$ | grep -E -v "normally up|want up" | sort -n -k3 | grep -v "/log" | while read line
		do
			set $line
			name=`echo $1|cut -d: -f1`
			secs=$3
			do_days $secs
			if [ "$5" = "normally" ] ; then
				printf "%-"$max"s up   %s  pid %7d\n" $name "$tstr" $8
			elif [ "$5" = "want" ] ; then
				printf "%-"$max"s up   %s  pid %7d\n" $name "$tstr" $8
			else
				printf "%-"$max"s up   %s  pid %7d\n" $name "$tstr" $6
			fi
			if [ $? -ne 0 ] ; then
				break
			fi
		done
		;;
	esac

	case "$option" in
		all|logs)
		echo
		printf "============ %-"$t"s     state uptime ===== pid/spid ==\n" ".svscan/log"
		set $(grep "/service/\.svscan/log" /tmp/svps.$$)
		name=`echo $1|cut -d: -f1`
		secs=$3
		do_days $secs
		printf "%-"$max"s up   %s  pid %7d\n" $name "$tstr" $6
		echo
		printf "==== logs == %-"$t"s     state uptime ===== pid/spid ==\n" $svdir
		grep -E "/service/.*/log" /tmp/svps.$$ | sort -n -k3 | grep -v "\.svscan" | while read line
		do
			set $line
			name=`echo $1|cut -d: -f1`
			secs=$3
			do_days $secs
			printf "%-"$max"s up   %s  pid %7d\n" $name "$tstr" $6
			if [ $? -ne 0 ] ; then
				break
			fi
		done
		;;
	esac
}

stop_all()
{
	flag=0
	for i in $sv_dirs
	do
		for j in $i/*
		do
			if [ -d $j ] ; then
  				/usr/bin/svstat $j >/dev/null
				if [ $? -eq 0 ] ; then
					mkdir -p /var/tmp/$j
					if [ $? -ne 0 ] ; then
						continue
					fi
					[ $flag -eq 0 ] && echo "Stopping all running services"
					flag=1
					/usr/bin/svc -d $j
					if [ $? -eq 0 ] ; then
						touch /var/tmp/$j/down
					fi
				fi
			fi
		done
	done
	[ $flag -eq 0 ] && echo "No running services found" 1>&2
}

resume_all()
{
	flag=0
	for i in $sv_dirs
	do
		for j in $i/*
		do
			if [ -f /var/tmp/$j/down ] ; then
				[ $flag -eq 0 ] && echo "Starting all stopped services"
				flag=1
				/usr/bin/svc -u $j
				/bin/rm -rf /var/tmp/$j
			fi
		done
	done
	[ $flag -eq 0 ] && echo "No stopped services found" 1>&2
}

if [ -z "$PAGER" ] ; then
	if [ -x /usr/bin/less ] ; then
		PAGER=/usr/bin/less
	elif [ -x /usr/bin/more ] ; then
		PAGER=/usr/bin/more
	fi
fi
option=main
mday=0
while test $# -gt 0; do
    case "$1" in
    -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
	;;
    *) optarg=
	;;
    esac

    case "$1" in
    -a|--all)
	option=all
    ;;
	-h|--hup)
	option=hup
	;;
	-t|--term)
	option=term
	;;
    -m|--main)
	option=main
    ;;
    -l|--logs)
	option=logs
    ;;
    -n|--no-pager)
	PAGER=""
    ;;
	-d|--days)
	mday=1
	;;
	-s|--stop)
	option=stop
	;;
	-r|--resume)
	option=resume
	;;
    *)
    echo "invalid option [$1]" 1>&2
	echo "usage: svps [-a|--all | -m|--main | -h|--hup | -t|--term | -n|--no-pager] |"
	echo "  [-d|--days -s|--stop | -r|--resume | -l|--logs]" 1>&2
    read key
	exit 1
    ;;
    esac

    shift
done

ID=$(id -u)

if [ $ID -ne 0 ] ; then
  echo "You are not root" 1>&2
  exit 1
fi
if [ -d /run/svscan ] ; then
	pidfile=/run/svscan/.svscan.pid
	rundir=/run
elif [ -d /var/run/svscan ] ; then
	pidfile=/var/run/svscan/.svscan.pid
	rundir=/var/run
else
	pidfile=/service/.svscan.pid
	rundir=/service
fi
if [ -f $pidfile ] ; then
	svpid=$(sed -n '$p' $pidfile)
else
	svpid=$(pgrep -fn /usr/sbin/svscan)
	if [ -z "$svpid" ] ; then
		echo "svscan not running: $pidfile: No such file or directory" 1>&2
		exit 1
	fi
	t=$(cat /proc/$svpid/cmdline |tr '\0' '\n'|tail -n +2)
	pidfile=$t/.svscan.pid
fi

ps axu|grep root|grep "sbin/svscan"|grep -Ev "grep|multilog|supervise" > /tmp/svps.$$
max=0
while read line
do
	set $line
	len=$(echo ${11} ${12} | wc -c)
	if [ $len -gt $max ] ; then
		max=$len
	fi
	svscan_length=$(echo ${11} | wc -c)
	if [ -z "$sv_dirs" ] ; then
		sv_dirs=${12}
	else
		sv_dirs="$sv_dirs ${12}"
	fi
done < /tmp/svps.$$

case "$option" in
	stop)
	stop_all
	exit 0
	;;
	resume)
	resume_all
	exit 0
	;;
	hup)
	if [ ! -f $pidfile ] ; then
		echo "$pidfile: No such file or directory" 1>&2
		exit 1
	else
		echo "Sending HUP to svscan with PID $svpid"
		kill -1 $svpid
		if [ $? -ne 0 ] ; then
			echo "Failed to send HUP signal to pid $svpid" 1>&2
		fi
	fi
	exit 0
	;;
	term)
	if [ ! -f $pidfile ] ; then
		echo "$pidfile: No such file or directory" 1>&2
		exit 1
	else
		echo "Sending TERM to svscan with PID $svpid"
		kill -TERM $svpid
		if [ $? -ne 0 ] ; then
			echo "Failed to send HUP signal to pid $svpid" 1>&2
		fi
	fi
	exit 0
	;;
esac

(
for i in $sv_dirs
do
	/usr/bin/svstat $i/* $i/*/log $i/.svscan/log
done
) > /tmp/svps_tmp.$$ 2>/tmp/svpserr.$$
status=$?
if [ $status -ne 0 ] ; then
	if [ -s /tmp/svpserr.$$ ] ; then
		cat /tmp/svpserr.$$
	fi
	/bin/rm -f /tmp/svpserr.$$ /tmp/svps_tmp.$$
	exit $status
else
	grep -Ev "\.\.|^wait until" /tmp/svps_tmp.$$ > /tmp/svps.$$
	/bin/rm -f /tmp/svpserr.$$ /tmp/svps_tmp.$$
fi

while read line
do
	if [ -z "$line" ] ; then
		continue
	fi
	set $line
	len=`echo $1 | cut -d: -f1| wc -c`
	if [ $len -gt $max ] ; then
		max=$len
	fi
done < /tmp/svps.$$

if [ "$option" = "hup" -o "$option" = "term" ] ; then
	PAGER=""
fi

if [ -n "$PAGER" ] ; then
	(
	do_svscan
	ps axu|grep root|grep "sbin/svscan"|grep -Ev "grep|multilog|supervise" | while read line
	do
		set $line
		/usr/bin/svstat ${12}/* ${12}/*/log \
			${12}/.svscan/log 2>/tmp/svpserr.$$ > /tmp/svps_tmp.$$
		grep -Ev "\.\.|^wait until" /tmp/svps_tmp.$$ > /tmp/svps.$$
		/bin/rm -f /tmp/svps_tmp.$$
		doit $2 ${12} $option
	done
	) | $PAGER
else
	do_svscan
	ps axu|grep root|grep "sbin/svscan"|grep -Ev "grep|multilog|supervise" | while read line
	do
		set $line
		/usr/bin/svstat ${12}/* ${12}/*/log \
			${12}/.svscan/log 2>/tmp/svpserr.$$ > /tmp/svps_tmp.$$
		grep -Ev "\.\.|^wait until" /tmp/svps_tmp.$$ > /tmp/svps.$$
		/bin/rm -f /tmp/svps_tmp.$$
		doit $2 ${12} $option
	done
fi

/bin/rm -f /tmp/svps.$$ /tmp/svpserr.$$
#
# $Log: svps.in,v $
# Revision 1.23  2024-10-24 18:06:23+05:30  Cprogrammer
# hide container processes
#
# Revision 1.22  2024-08-29 21:42:46+05:30  Cprogrammer
# use .svscan.pid from service directory of each svscan instance
#
# Revision 1.21  2024-08-14 11:23:27+05:30  Cprogrammer
# fix for pid file not found if svscan is not configured for /service
#
# Revision 1.20  2024-07-01 09:34:06+05:30  Cprogrammer
# added stopall, startall functions
#
# Revision 1.19  2024-06-20 11:07:51+05:30  Cprogrammer
# display services for all svscan instances
#
# Revision 1.18  2023-08-13 09:31:08+05:30  Cprogrammer
# added option to display up/down time in days, hours, mins, secs
#
# Revision 1.17  2023-07-26 22:16:10+05:30  Cprogrammer
# display svscan not running if svscan is not up
#
# Revision 1.16  2023-03-13 17:47:47+05:30  Cprogrammer
# added -t, --term option
#
# Revision 1.15  2022-11-09 20:15:01+05:30  Cprogrammer
# replaced deprecated egrep with grep -E
#
# Revision 1.14  2022-05-24 12:15:48+05:30  Cprogrammer
# fix for alpine linux
#
# revision 1.13  2022-03-18 09:17:35+05:30  cprogrammer
# added -h, hup option to send hup to svscan
#
# revision 1.12  2022-03-06 18:50:50+05:30  cprogrammer
# fix for freebsd (stat command usage)
#
# revision 1.11  2021-07-26 11:31:08+05:30  cprogrammer
# added --no-pager, -n option to disable pager
#
# revision 1.10  2020-11-29 16:26:02+05:30  cprogrammer
# use portable way to use while loop
#
# revision 1.9  2020-11-27 17:30:27+05:30  cprogrammer
# set status variable
#
# Revision 1.8  2020-11-26 23:01:52+05:30  Cprogrammer
# remove PIPESTATUS as it is not portable
#
# Revision 1.7  2020-11-12 11:28:09+05:30  Cprogrammer
# fixed output for normally up and normally down status
#
# Revision 1.6  2020-11-11 18:23:28+05:30  Cprogrammer
# display uptime of svscan
#
# Revision 1.5  2020-11-11 18:05:14+05:30  Cprogrammer
# display error if not running as root
#
# Revision 1.4  2020-11-11 18:01:37+05:30  Cprogrammer
# send output through pager
#
# Revision 1.3  2020-11-10 19:14:47+05:30  Cprogrammer
# display supervise process pid when service is down
#
# Revision 1.2  2020-11-10 16:53:38+05:30  Cprogrammer
# added getopt style options
#
# Revision 1.1  2020-11-09 09:19:58+05:30  Cprogrammer
# Initial revision
#
