File systemd-sysv-convert of Package systemd.8696

#!/bin/bash

if [ "$UID" != "0" ]; then
	echo Need to be root.
	exit 1
fi

declare -A results_runlevel
declare -A results_priority

usage() {
	cat << EOF
usage: systemd-sysv-convert [-h] [--save] [--show] [--apply]
                            SERVICE [SERVICE ...]
EOF
}

help() {
	usage
	cat << EOF
Save and Restore SysV Service Runlevel Information

positional arguments:
  SERVICE	Service names

optional arguments:
  -h, --help	show this help message and exit
  --save	Save SysV runlevel information for one or more services
  --show	Show saved SysV runlevel information for one or more services
  --apply 	Apply saved SysV runlevel information for one or more services
  		to systemd counterparts
EOF
}

find_service() {
	local service
	local rcnd
	declare -i priority

	service=$1
	rcnd=$2
	priority=-1

	for l in $(ls /etc/rc.d/$rcnd/) ; do
		initscript=$(basename $l)
		case $initscript in
		S??$service)		;;
		S??boot.$service)	;;
		*)	continue
		esac

		if [ ${initscript:1:2} -ge 0 -a ${initscript:1:2} -le 99 -a ${initscript:1:2} -ge $priority ]; then
			if [ ${initscript:1:1} == 0 ]; then
				priority=${initscript:2:1}
			else
				priority=${initscript:1:2}
			fi
		fi
	done
	if [ $priority -ge 0 ]; then
		return $priority
	fi
	return 255
}

lookup_database() {
	local services
	local service
	local service_file
	local runlevel
	local priority
	local -i k
	declare -a parsed

	services=$@
	k=0
	results_runlevel=()
	results_priority=()

	while read line ; do
		k+=1
		parsed=($line)
		service=${parsed[0]}
		runlevel=${parsed[1]}
		priority=${parsed[2]}
		if [ $runlevel -lt 2 -o $runlevel -gt 5 ]; then
			echo "Runlevel out of bounds in database line $k. Ignoring" >/dev/stderr
			continue
		fi
		if [ $priority -lt 0 -o $priority -gt 99 ]; then
			echo "Priority out of bounds in database line $k. Ignoring" >/dev/stderr
			continue
		fi

		declare -i found
		found=0
		for s in $services ; do
			if [ $s == $service ]; then
				found=1
				continue
			fi
		done
		if [ $found -eq 0 ]; then
			continue
		fi
		results_runlevel[$service]+=" $runlevel"
		results_priority[$service]+=" $priority"
	done < /var/lib/systemd/sysv-convert/database
}

declare -i fail=0
case "$1" in
	-h|--help)
		help
		exit 0
		;;
	--save)
		shift
		for service in $@ ; do
			if [ ! -r "/etc/init.d/$service" ] && [ ! -r /etc/init.d/boot.$service ]; then
				echo "SysV service $service does not exist, skipping"
				continue
			fi
			for rcnd in rc2.d rc3.d rc4.d rc5.d boot.d; do
				case $rcnd in
				rc*.d)	runlevel=${rcnd:2:1} ;;
				boot.d)	runlevel=3 ;;
				esac

				find_service $service $rcnd
				priority=$?
				if [ $priority -lt 255 ]; then
					echo "$service	$runlevel	$priority" >>/var/lib/systemd/sysv-convert/database
				fi
			done
		done
		;;
	--show)
		shift
		services=$@
		lookup_database $services
		for service in $services; do
  			if [ -z "${results_runlevel[$service]}" ]; then
				echo No information found about service $service found. >/dev/stderr
				let fail++
				continue
			fi
			declare -i count
			count=0
			priority=(${results_priority[$service]})
			for runlevel in ${results_runlevel[$service]}; do
				echo SysV service $service enabled in runlevel $runlevel at priority ${priority[$count]}
				count+=1
			done
		done
		;;
	--apply)
		shift
		services=$@
		for service in $services; do
			if [ ! -f "/lib/systemd/system/$service.service" -a ! -f "/usr/lib/systemd/system/$service.service" ]; then
				echo systemd service $service.service does not exist. >/dev/stderr
				exit 1
			fi
		done

		#
		# The database might no have been created by a previous --save
		# call. This can happen when:
		#
		#  - we're upgrading a package which initially didn't
		#    have any unit file nor sysv init script and now
		#    start shipping one or more unit files (bsc#982303).
		#
		#  - the sysv init service wasn't enabled at all before
		#    being migrated to a native unit file (bsc#982211).
		#
		if [ -e /var/lib/systemd/sysv-convert/database ]; then
			lookup_database $services
			for service in $services; do
				[ -f "/lib/systemd/system/$service.service" ] && service_file="/lib/systemd/system/$service.service"
				[ -f "/usr/lib/systemd/system/$service.service" ] && service_file="/usr/lib/systemd/system/$service.service"

				# If $service is not present in the database,
				# then it simply means that the sysv init
				# service was not enabled at all.
				for runlevel in ${results_runlevel[$service]}; do
					echo ln -sf $service_file /etc/systemd/system/runlevel$runlevel.target.wants/$service.service >/dev/stderr
					mkdir -p "/etc/systemd/system/runlevel$runlevel.target.wants"
					/bin/ln -sf $service_file /etc/systemd/system/runlevel$runlevel.target.wants/$service.service
				done
			done
		fi
		;;
	*)
 		usage
		let fail=2
		;;
esac

exit $fail
openSUSE Build Service is sponsored by