#!/bin/sh
#
# $Log: create_service.in,v $
# Revision 1.43  2022-04-30 11:11:16+05:30  Cprogrammer
# removed call to backup in run script
#
# Revision 1.42  2022-02-14 10:07:18+05:30  Cprogrammer
# make fclient run script silent
#
# Revision 1.41  2021-10-09 23:51:40+05:30  Cprogrammer
# play boot sound in fserver script
#
# Revision 1.40  2021-09-24 11:40:29+05:30  Cprogrammer
# create shutdown script to unmount MDrive
#
# Revision 1.39  2021-06-16 19:14:13+05:30  Cprogrammer
# added rsync service
#
# Revision 1.38  2021-06-06 11:04:16+05:30  Cprogrammer
# sleep after backup
#
# Revision 1.37  2021-05-07 13:12:11+05:30  Cprogrammer
# skip updating UPGRADE, INTERVAL env variables
#
# Revision 1.36  2021-05-06 13:34:21+05:30  Cprogrammer
# skip daemontools if clients are connected to fserver service
#
# Revision 1.35  2021-05-05 13:35:32+05:30  Cprogrammer
# added logging statements
#
# Revision 1.34  2021-05-02 19:21:19+05:30  Cprogrammer
# fixed update not getting skipped when no updates available
#
# Revision 1.33  2021-05-02 17:38:49+05:30  Cprogrammer
# fix for atd override.conf
#
# Revision 1.32  2021-05-02 10:06:07+05:30  Cprogrammer
# create env variables for atd service for mail to work using qmail-direct
#
# Revision 1.31  2021-05-01 20:37:40+05:30  Cprogrammer
# refactored code for update service
#
# Revision 1.30  2021-05-01 14:55:28+05:30  Cprogrammer
# create QUEUE_BASE env variable
#
# Revision 1.29  2021-05-01 13:15:37+05:30  Cprogrammer
# reworked service creation for update service
#
# Revision 1.28  2021-04-30 21:37:14+05:30  Cprogrammer
# fixed QMAILQUEUE for root user
#
# Revision 1.27  2021-04-30 12:17:36+05:30  Cprogrammer
# reworked update script
#
# Revision 1.26  2021-04-29 23:05:50+05:30  Cprogrammer
# create Maildir for mail delivery
#
# Revision 1.25  2021-04-27 22:23:40+05:30  Cprogrammer
# do initial sleep of 5 minutes for network to be up
#
# Revision 1.24  2021-04-27 19:07:25+05:30  Cprogrammer
# refactored code to make it smaller
#
# Revision 1.23  2021-04-27 17:35:41+05:30  Cprogrammer
# use at command to run update
#
# Revision 1.22  2021-04-27 15:51:18+05:30  Cprogrammer
# create HOME variable for update service
# removed daemontools from auto-update
#
# Revision 1.21  2021-04-27 13:40:44+05:30  Cprogrammer
# added -q option to apt-get to reduce output
#
# Revision 1.20  2021-04-27 13:36:10+05:30  Cprogrammer
# skip upgrade of pistop when clients are connected to fserver service
#
# Revision 1.19  2021-04-27 12:48:58+05:30  Cprogrammer
# added update service
#
# Revision 1.18  2021-04-14 13:20:10+05:30  Cprogrammer
# fixed .options
#
# Revision 1.17  2021-04-14 09:47:14+05:30  Cprogrammer
# update variables only if changed
#
# Revision 1.16  2021-04-13 18:25:27+05:30  Cprogrammer
# do not overwrite POWER_OFF env variable
#
# Revision 1.15  2021-04-13 18:07:55+05:30  Cprogrammer
# added command line invocation in run header
#
# Revision 1.14  2021-04-13 17:49:38+05:30  Cprogrammer
# create variables/.options file
#
# Revision 1.13  2021-04-13 16:48:02+05:30  Cprogrammer
# fixed home variable
#
# Revision 1.12  2021-04-13 15:29:40+05:30  Cprogrammer
# backup file in fclient service
#
# Revision 1.11  2021-04-01 20:58:31+05:30  Cprogrammer
# do backup using backup script; start mpd of not running
#
# Revision 1.10  2021-04-01 20:52:13+05:30  Cprogrammer
# use absolute path in BACKUP env variable
#
# Revision 1.9  2021-02-25 15:42:57+05:30  Cprogrammer
# use relative path for variables to allow renaming of service directory
#
# Revision 1.8  2021-01-11 22:21:14+05:30  Cprogrammer
# create HOME environment variable
#
# Revision 1.7  2020-08-31 16:40:17+05:30  Cprogrammer
# fixed shutdown script
#
# Revision 1.6  2020-08-31 12:22:40+05:30  Cprogrammer
# added code to do backup during startup in fserver
#
# Revision 1.5  2020-08-29 17:12:50+05:30  Cprogrammer
# fixed shutdown script
#
# Revision 1.4  2020-08-29 16:01:45+05:30  Cprogrammer
# use bash for run file
#
# Revision 1.3  2020-08-28 22:44:00+05:30  Cprogrammer
# create shutdown script for fserver service
#
# Revision 1.2  2020-08-28 22:05:45+05:30  Cprogrammer
# fixed syntax error
#
# Revision 1.1  2020-08-28 17:17:26+05:30  Cprogrammer
# Initial revision
#
#
# $Id: create_service.in,v 1.43 2022-04-30 11:11:16+05:30 Cprogrammer Exp mbhangui $
#

check_update_if_diff()
{
	val=`cat $1 2>/dev/null`
	if [ ! " $val" = " $2" ] ; then
		echo $2 > $1
	fi
}

add_service()
{
	if [ $# -ne 2 ] ; then
		(
		echo -n "USAGE: create_service --servicedir=path "
		echo -n "--service_name=fclient|fserver|update|rsync --host=host "
		echo -n "--port=port --add-service"
		echo
		) 1>&2
		return 1
	fi
	if [ ! -d $logdir ] ; then
		mkdir -p $logdir
		chown qmaill:nofiles $logdir
	fi
	if [ " $service_name" = " rsync" ] ; then
		service_name="$service_name.875"
	fi
	mkdir -p $servicedir/$service_name/log
	(
		echo "#!/bin/sh"
		echo "exec /usr/bin/setuidgid qmaill \\"
		if [ -f /usr/sbin/multilog ] ; then
			echo "/usr/sbin/multilog t $logdir/$service_name"
		else
			echo "/usr/bin/multilog t $logdir/$service_name"
		fi
	) > $servicedir/$service_name/log/run
	chmod +x $servicedir/$service_name/log/run

	mkdir -p $servicedir/$service_name/variables
	echo "$prog_args" > $servicedir/$service_name/variables/.options
	if [ " $service_name" = " fclient" -o " $service_name" = " fserver" ] ; then
		check_update_if_diff $servicedir/$service_name/variables/HOST       $1
		check_update_if_diff $servicedir/$service_name/variables/PORT       $2
		check_update_if_diff $servicedir/$service_name/variables/TIMEOUT    300
		check_update_if_diff $servicedir/$service_name/variables/MAXDAEMONS 10
		home=$(getent passwd 1000|cut -d: -f6)
		if [ -n "$home" ] ; then
			check_update_if_diff $servicedir/$service_name/variables/HOME $home
		fi
	elif [ " $service_name" = " rsync.875" ] ; then
		check_update_if_diff $servicedir/$service_name/variables/LOCALIP 0
		check_update_if_diff $servicedir/$service_name/variables/MAXDAEMONS 10
		check_update_if_diff $servicedir/$service_name/variables/MAXPERIP 4
		check_update_if_diff $servicedir/$service_name/variables/PORT 875
		check_update_if_diff $servicedir/$service_name/variables/SOFT_MEM 26214400
	elif [ " $service_name" = " update" ] ; then
		if [ ! -f $servicedir/$service_name/variables/UPGRADE ] ; then
			check_update_if_diff $servicedir/$service_name/variables/UPGRADE \
				"ucspi-tcp mpdev libqmail indimail-mini daemontools pistop mpd"
		fi
		if [ ! -f $servicedir/$service_name/variables/INTERVAL ] ; then
			check_update_if_diff $servicedir/$service_name/variables/INTERVAL 21600
		fi
		check_update_if_diff $servicedir/$service_name/variables/DEBIAN_FRONTEND "noninteractive"
		pihome=$(getent passwd 1000|cut -d: -f6)
		piuser=$(getent passwd 1000|cut -d: -f1)
		check_update_if_diff $servicedir/$service_name/variables/HOME    $pihome
		# the at command will use LOGNAME as the mail recipient
		check_update_if_diff $servicedir/$service_name/variables/LOGNAME $piuser
		for i in 1000 root
		do
			home=$(getent passwd $i|cut -d: -f6)
			uid=$(getent passwd $i|cut -d: -f3)
			gid=$(getent passwd $i|cut -d: -f4)
			if [ -z "$home" -o -z "$uid" -o -z "$gid" ] ; then
				echo "unable to get passwd entry for $i" 1>&2
				continue
			fi
			if [ ! -d $home/Malidir ] ; then
				mkdir -p $home/Maildir/new
				mkdir -p $home/Maildir/cur
				mkdir -p $home/Maildir/tmp
				chown -R $uid:$gid $home/Maildir
			fi
			if [ -f /usr/sbin/qmail-direct ] ; then
				flag=0
				if [ ! -d $home/.defaultqueue ] ; then
					flag=1
					mkdir -p $home/.defaultqueue
				fi
				if [ ! -f $home/.defaultqueue/QMAILQUEUE ] ; then
					flag=1
					check_update_if_diff $home/.defaultqueue/QMAILQUEUE "/usr/sbin/qmail-direct"
				fi
				if [ ! -f $home/.defaultqueue/QUEUE_BASE ] ; then
					flag=1
					check_update_if_diff $home/.defaultqueue/QUEUE_BASE $pihome"/Maildir"
				fi
				if [ ! -f $home/.defaultqueue/USER ] ; then
					flag=1
					check_update_if_diff $home/.defaultqueue/USER $piuser
				fi
				if [ $flag -eq 1 ] ; then
					chown -R $uid:$gid $home/.defaultqueue
				fi
			fi
		done
		if [ -f /usr/sbin/qmail-direct -a -d /lib/systemd/system -a ! -d /lib/systemd/system/atd.service.d ] ; then
			mkdir -p /lib/systemd/system/atd.service.d
			(
			echo "[Service]"
			echo "EnvironmentFile=/service/update/variables/.variables"
			) > /lib/systemd/system/atd.service.d/override.conf
			systemctl daemon-reload
		fi
	fi

	# create /service/$service_name/run and /sevice/$service_name/log/run
	if [ " $service_name" = " fclient" ] ; then
		(
		echo "#!/bin/bash"
		echo "# $prog_args"
		echo ""
		echo "exec 2>&1"
		echo 
		echo "HOST=\`cat variables/HOST\`"
		echo "PORT=\`cat variables/PORT\`"
		echo "echo \"Started fclient service\""
		echo "while true"
		echo "do"
		echo "  bash -c \"</dev/tcp/\$HOST/\$PORT\" 2>/dev/null"
		echo "  if [ \$? -eq 0 ] ; then"
		echo "    echo \"connected to \$HOST:\$PORT\""
		echo "    exec /usr/bin/envdir variables sh -c \"\\"
		echo "      exec /usr/bin/tcpclient -v -D -H -R -t \\"
		echo "      \\\$TIMEOUT \\\$HOST \\\$PORT /usr/libexec/pistop/client start 2>&1\""
		echo "  else"
		echo "    sleep 30"
		echo "  fi"
		echo "done"
		) > $servicedir/$service_name/run
		chmod +x $servicedir/$service_name/run
		(
		echo "#!/bin/sh"
		echo "exec /usr/libexec/pistop/client umount"
		) > $servicedir/$service_name/shutdown
		chmod +x $servicedir/$service_name/shutdown
		if [ ! -f $servicedir/$service_name/variables/POWER_OFF ] ; then
			> $servicedir/$service_name/variables/POWER_OFF
		fi
	elif [ " $service_name" = " fserver" ] ; then
		(
		echo "#!/bin/sh"
		echo "# $prog_args"
		echo ""
		echo "exec 2>&1"
		echo ""
		echo "exec /usr/bin/envdir variables sh -c \""
		echo "  /usr/libexec/pistop/backup"
		echo "  if [ -x /var/lib/mpd/MDrive/bin/boot_sound ] ; then"
		echo "    /var/lib/mpd/MDrive/bin/boot_sound >/dev/null 2>&1"
		echo "  fi"
		echo "  systemctl status mpd >/dev/null 2>&1"
		echo "  if [ \$? -eq 0 ] ; then"
		echo "    systemctl start mpd"
		echo "  fi"
		echo ""
		echo "  exec /usr/bin/tcpserver -v -D -H -R -l 0 \\"
		echo "    -c variables/MAXDAEMONS -o -b \\\$MAXDAEMONS \\"
		echo "    -u 0 -g 0 \\\$HOST \\\$PORT \\"
		echo "  /usr/libexec/pistop/server\""
		) > $servicedir/$service_name/run
		chmod +x $servicedir/$service_name/run
		(
		echo "#!/bin/sh"
		echo "killall /usr/libexec/pistop/server"
		echo "exit 0"
		) > $servicedir/$service_name/shutdown
		chmod +x $servicedir/$service_name/shutdown
	elif [ " $service_name" = " rsync.875" ] ; then
		(
		echo "#!/bin/sh"
		echo "# $prog_args"
		echo ""
		echo "exec 2>&1"
		echo
		echo "exec /usr/bin/envdir ./variables sh -c \""
		echo "exec /usr/bin/softlimit -m \\\$SOFT_MEM -o 1024 \\"
		echo "  /usr/bin/tcpserver -v -H -R -l \\\$LOCALIP \\"
		echo "  -c ./variables/MAXDAEMONS -C \\\$MAXPERIP -o -b \\\$MAXDAEMONS \\"
		echo " \\\$LOCALIP \\\$PORT /usr/bin/rsync -v --daemon --no-detach --log-file=/dev/fd/2\""
		) > $servicedir/$service_name/run
		chmod +x $servicedir/$service_name/run
		touch $servicedir/$service_name/down
	elif [ " $service_name" = " update" ] ; then
		if [ -f /etc/debian_version ] ; then
			system="debian"
		elif [ -f /usr/bin/dnf ] ; then
			system="rpm-dnf"
		elif [ -f /usr/bin/yum ] ; then
			system="rpm-yum"
		elif [ -f /usr/bin/zypper ] ; then
			system="rpm-suse"
		else
			system="unknown"
			echo "unsupported system. Did not find apt-get, dnf, yum or zypper" 1>&2
			exit 0
		fi
		(
		echo "#!/bin/sh"
		echo "# $prog_args"
		echo ""
		echo "exec 2>&1"
		echo
		echo "echo \"Check update after 5 minutes\""
		echo "sleep 300"
		echo "if [ -f variables/UPGRADE ] ; then"
		echo "  UPDATE=\$(cat variables/UPGRADE)"
		echo "fi"
		echo "if [ ! -x /usr/bin/at ] ; then"
		echo "  echo \\\"at command not found. Will not upgrade daemontools\\\""
		echo "  UPDATE=\$(cat variables/UPGRADE|sed -e 's{daemontools{{g')"
		echo "fi"
		echo "if [ -d /service/fserver ] ; then"
		echo "  count=\$(ps -ef|grep /usr/libexec/pistop/server|egrep -v \"tcpserver|grep\"|wc -l)"
		echo "  if [ \$count -gt 0 ] ; then"
		echo "    echo \\\"\$count clients already running. Will not upgrade pistop, daemontools\\\""
		echo "    UPDATE=\$(cat variables/UPGRADE|sed -e 's{pistop{{g' -e 's{daemontools{{g')"
		echo "  fi"
		echo "fi"
		echo "exec /usr/bin/envdir variables sh -c \""
		echo "  echo \\\"starting update service\\\""
		echo "  if [ -n \\\"\$UPDATE\\\" ] ; then"
		echo "    echo \\\"checking updates for \$UPDATE\\\""
		case "$system" in
			debian)
		check_update_if_diff $servicedir/$service_name/variables/DEBIAN_FRONTEND "noninteractive"
			echo "    env DEBIAN_FRONTEND=noninteractive apt-get -qy update"
			echo "    list=\\\$(apt list --upgradable \$UPDATE|grep -v List|wc -l)"
			;;
			rpm-dnf)
			echo "    dnf makecache --timer"
			echo "    dnf check-update \$UPDATE >/dev/null 2>&1"
			echo "    if [ \\\$? -ne 100 ] ; then"
			echo "      list=\\\"\\\""
			echo "    else"
			echo "      list=\\\"upgrade\\\""
			echo "    fi"
			;;
			rpm-yum)
			echo "    yum makecache --timer"
			echo "    yum check-update \$UPDATE >/dev/null 2>&1"
			echo "    if [ \\\$? -ne 100 ] ; then"
			echo "      list=\\\"\\\""
			echo "    else"
			echo "      list=\\\"upgrade\\\""
			echo "    fi"
			;;
			rpm-suse)
			echo "    zypper refresh"
			echo "    list=\\\$(zypper list-updates \$UPDATE|grep -v List|wc -l)"
			;;
		esac
		echo "    if [ -z \\\"\\\$list\\\" -o \\\"\\\$list\\\" -eq 0 ] ; then"
		echo "      echo \\\"no upgrade found\\\""
		echo "    elif [ -x /usr/bin/at ] ; then"
		case "$system" in
			debian)
			echo -n "      echo \\\"env DEBIAN_FFRONTEND=noninteractive apt-get "
			echo    "-qy --only-upgrade install \$UPDATE\\\"|at now +1 minute"
			;;
			rpm-dnf)
			echo "      echo \\\"dnf update \$UPDATE\\\"|at now +1 minute"
			;;
			rpm-yum)
			echo "      echo \\\"yum update \$UPDATE\\\"|at now +1 minute"
			;;
			rpm-suse)
			echo "      echo \\\"zypper up \$UPDATE\\\"|at now +1 minute"
			;;
		esac
		echo "    else"
		case "$system" in
			debian)
			echo "      env DEBIAN_FFRONTEND=noninteractive apt-get -qy --only-upgrade install \$UPDATE"
			;;
			rpm-dnf)
			echo "      dnf update \$UPDATE"
			;;
			rpm-yum)
			echo "      yum update \$UPDATE"
			;;
			rpm-suse)
			echo "      zypper up \$UPDATE"
			;;
		esac
		echo "    fi"
		echo "  fi"
		echo "  if [ -n \\\"\\\$INTERVAL\\\" -a \\\$INTERVAL -gt 600 ] ; then"
		echo "    echo \\\"sleeping for \\\$(expr \\\$INTERVAL / 3600) hr\\\""
		echo "    exec sleep \\\$INTERVAL"
		echo "  else"
		echo "    echo \\\"sleeping for 10 min\\\""
		echo "    exec sleep 600"
		echo "  fi"
		echo "\""
	    ) > $servicedir/$service_name/run
		chmod +x $servicedir/$service_name/run
	fi
}

del_service()
{
	if [ ! -d $servicedir/$service_name ] ; then
		return 0
	fi
	mv $servicedir/$service_name $servicedir/."$service_name"
	svc -dx $servicedir/."$service_name" $servicedir/."$service_name"/log > /dev/null
	sleep 5
	/bin/rm -rf $servicedir/."$service_name" $servicedir/."$service_name"/log > /dev/null
}

usage()
{
echo "Usage: create_service [OPTIONS]"
echo "create_service --servicedir=dir --service_name=name --host=host --port=port --add-service"
echo "  or"
echo "create_service --servicedir=dir --service_name=name --del-service"
exit $1
}

################################# Main ##################################
if test $# -eq 0; then
	usage 1
fi
ID=$(id -u)
if [ $ID -ne 0 ] ; then
	echo "You are not root" 1>&2
	exit 1
fi
logdir=/var/log/svc
servicedir=/service
prog_args="$0 $*"
RCSID="# \$Id: create_service.in,v 1.43 2022-04-30 11:11:16+05:30 Cprogrammer Exp mbhangui $"
while test $# -gt 0; do
	case "$1" in
	-*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
	;;
	*) optarg=
	;;
	esac

	case "$1" in
	--servicedir=*)
	servicedir=$optarg
	;;
	--service_name=*)
	service_name=$optarg
	if [ " $service_name" != " fclient" -a " $service_name" != " fserver" -a " $service_name" != " update" -a " $service_name" != " rsync" ] ; then
		echo "service_name should be fclient, fserver, rsync or update" 1>&2
	fi
	;;
	--host=*)
	host=$optarg
	;;
	--port=*)
	port=$optarg
	;;

	--add-service)
	if [ -z "$servicedir" -o -z "$service_name" ] ; then
		echo "You must specify servicedir, service_name" 1>&2
		usage 1
	elif [ "$service_name" = "fclient" -o "$service_name" = "fserver" ] ; then
		if [ -z "$port" -o -z "$host" ] ; then
			echo "You must specify port, host for $service_name" 1>&2
			usage 1
		fi
	fi
	add_service "$host" "$port"
	;;
	--del-service)
	del_service
	;;
	*)
	echo "invalid option [$1]"
	read key
	usage 1
	;;
	esac
	shift
done
