#!/bin/sh -e
# See http://jdebp.uk./FGA/slashpackage.html
if test \! -d package || test \! -d source
then
	echo "You are not in the right directory." 1>&2
	exit 100
fi
if test \! -d build
then
	echo "You have not prepared the build area." 1>&2
	exit 100
fi

export CDPATH=

# Atomically update the release directories ./command, ./library, ./include, and so forth.
# The build and release directories need not be on the same disc volume.
# And the files released must not be potentially overwritable and truncatable by the compiler/linker during subsequent builds.
# But released files can be links to other released files, of course.
install -d -m 0755 command manual config guide guide/services guide/commands guide/commands/html guide/convert

# ##############################################################################
# Build all of the ...{new} files in ./command, ./manual, and ./guide.
# Symbolic links in place of subdirectories to fool the man(1) command
for directory in en_GB.UTF-8 en.UTF-8
do
	rm -f -- manual/"${directory}"{new}
	ln -f -s -- . manual/"${directory}"{new}
done
# Main guide pages
cat package/guidepages |
while read -r i
do
	rm -f -- guide/"$i".html{new}
	install -m 0444 -p -- build/"$i".html guide/"$i".html{new}
done
for i in COPYING guide.css
do
	rm -f -- guide/"$i"{new}
	install -m 0444 -p -- build/"$i" guide/"$i"{new}
done
for i in docbook-xml.css
do
	rm -f -- guide/"$i"{new}
	install -m 0444 -p -- build/"$i" guide/commands/"$i"{new}
done
for section in 1 2 3 4 5 6 7 8 9
do
	if test 1 = "${section}" || test 8 = "${section}"
	then
		# All of the commands that have executables
		test -r package/commands${section} && cat package/commands${section} |
		while read -r i
		do
			rm -f -- command/"$i"{new}
			if objdump -f build/"$i" >/dev/null 2>&1
			then
				install -m 0755 -p -- build/"$i" command/"$i"{new}
				strip -p -- command/"$i"{new}
				chmod a-w command/"$i"{new}
			else
				install -m 0555 -p -- build/"$i" command/"$i"{new}
			fi
		done
		# All of the aliases for other executables
		test -r package/aliases${section} && cat package/aliases${section} |
		while read -r command alias
		do
			rm -f -- command/"${alias}"{new}
			ln -f -- command/"${command}"{new} command/"${alias}"{new}
		done
	fi
	# All of the commands that have their own manual and guide pages
	(
		test -r package/commands${section} && cat package/commands${section}
		test -r package/extra-manpages${section} && cat package/extra-manpages${section}
	) |
	while read -r i
	do
		install -d -m 0755 -- manual/man${section} manual/docbook${section}
		rm -f -- manual/man${section}/"$i".${section}{new}
		install -m 0444 -p -- build/"$i".${section} manual/man${section}/"$i".${section}{new}
		rm -f -- manual/docbook${section}/"$i".xml{new}
		install -m 0444 -p -- build/"$i".xml manual/docbook${section}/"$i".xml{new}
		rm -f -- guide/commands/html/"$i".html{new}
		install -m 0444 -p -- build/slashdoc/"$i".html guide/commands/html/"$i".html{new}
		rm -f -- guide/commands/"$i".xml{new}
		ln -f -- manual/docbook${section}/"$i".xml{new} guide/commands/"$i".xml{new}
	done
	# Aliased manual and guide pages
	test -r package/aliases${section} && cat package/aliases${section} |
	while read -r command alias
	do
		test -r package/commands${section} && grep -q -- "^${alias}\$" package/commands${section} && continue
		test -r package/extra-manpages${section} && grep -q -- "^${alias}\$" package/extra-manpages${section} && continue
		rm -f -- manual/man${section}/"${alias}".${section}{new}
		ln -f -- manual/man${section}/"${command}".${section}{new} manual/man${section}/"${alias}".${section}{new}
		rm -f -- manual/docbook${section}/"${alias}".xml{new}
		ln -f -- manual/docbook${section}/"${command}".xml{new} manual/docbook${section}/"${alias}".xml{new}
		rm -f -- guide/commands/html/"${alias}".html{new}
		ln -f -- guide/commands/html/"${command}".html{new} guide/commands/html/"${alias}".html{new}
		rm -f -- guide/commands/"${alias}".xml{new}
		ln -f -- guide/commands/"${command}".xml{new} guide/commands/"${alias}".xml{new}
	done
done

# ##############################################################################
# Rename the ...{new} files in ./command, ./manual, and ./guide.
# Symbolic links in place of subdirectories to fool the man(1) command
for directory in en_GB.UTF-8 en.UTF-8
do
	test -e manual/"${directory}" && mv -f -- manual/"${directory}" manual/"${directory}"{old}
	mv -f -- manual/"${directory}"{new} manual/"${directory}"
	rm -f -- manual/"${directory}"{old}
done
# Main guide pages
cat package/guidepages |
while read -r i
do
	mv -f -- guide/"$i".html{new} guide/"$i".html
done
for i in COPYING guide.css commands/docbook-xml.css
do
	mv -f -- guide/"$i"{new} guide/"$i"
done
for section in 1 2 3 4 5 6 7 8 9
do
	if test 1 = "${section}" || test 8 = "${section}"
	then
		# All of the commands that have executables and all of their aliases
		(
			test -r package/commands${section} && cat package/commands${section}
			test -r package/aliases${section} && awk '{print $2;}' package/aliases${section}
		) |
		while read -r i
		do
			mv -f -- command/"$i"{new} command/"$i"
		done
	fi
	# All of the commands that have their own manual and guide pages
	(
		test -r package/commands${section} && cat package/commands${section}
		test -r package/extra-manpages${section} && cat package/extra-manpages${section}
	) |
	while read -r i
	do
		mv -f -- manual/man${section}/"$i".${section}{new} manual/man${section}/"$i".${section}
		mv -f -- manual/docbook${section}/"$i".xml{new} manual/docbook${section}/"$i".xml
		mv -f -- guide/commands/html/"$i".html{new} guide/commands/html/"$i".html
		mv -f -- guide/commands/"$i".xml{new} guide/commands/"$i".xml
	done
	# Aliased manual and guide pages
	test -r package/aliases${section} && cat package/aliases${section} |
	while read -r command alias
	do
		test -r package/commands${section} && grep -q -- "^${alias}\$" package/commands${section} && continue
		test -r package/extra-manpages${section} && grep -q -- "^${alias}\$" package/extra-manpages${section} && continue
		mv -f -- manual/man${section}/"${alias}".${section}{new} manual/man${section}/"${alias}".${section}
		mv -f -- manual/docbook${section}/"${alias}".xml{new} manual/docbook${section}/"${alias}".xml
		mv -f -- guide/commands/html/"${alias}".html{new} guide/commands/html/"${alias}".html
		mv -f -- guide/commands/"${alias}".xml{new} guide/commands/"${alias}".xml
	done
done

# ##############################################################################
# Build all of the {new} directories in ./config.
rm -rf -- config/targets{new} config/services{new}
install -d -m 0755 config/targets{new} config/services{new}
while read -r i
do
	( cd build/targets/ && pax -r -w $i ../../config/targets{new}/ )
done < package/standard-targets
while read -r i
do
	( cd build/services/ && pax -r -w mount@$i fsck@$i ../../config/services{new}/ )
done < package/common-mounts
(
	cat package/common-etc-services 
	case "`uname`" in
	Linux)		cat package/linux-etc-services ;;
	OpenBSD)	cat package/bsd-etc-services ;;
	FreeBSD)	cat package/bsd-etc-services package/freebsd-etc-services ;;
	NetBSD)		cat package/bsd-etc-services package/netbsd-etc-services ;;
	*BSD)		cat package/bsd-etc-services ;;
	esac
) |
while read -r i
do
	( cd build/services/ && pax -r -w $i ../../config/services{new}/ )
done
(
	cat package/common-services package/common-sockets package/common-timers package/common-ttys 
	case "`uname`" in
	Linux)		cat package/linux-services package/linux-sockets package/linux-timers package/linux-ttys ;;
	OpenBSD)	cat package/bsd-services package/bsd-sockets package/openbsd-services package/openbsd-timers package/openbsd-ttys ;;
	NetBSD)		cat package/bsd-services package/bsd-sockets package/netbsd-services package/netbsd-timers package/netbsd-ttys ;;
	FreeBSD)	cat package/bsd-services package/bsd-sockets package/freebsd-services package/freebsd-timers package/freebsd-ttys ;;
	*BSD)		cat package/bsd-services package/bsd-sockets ;;
	esac
) |
while read -r i
do
	case "$i" in
		*-log)	
			( cd build/services/ && pax -r -w $i ../../config/services{new}/ )
			;;
		*)	
			( cd build/services/ && pax -r -w $i cyclog@$i ../../config/services{new}/ )
			;;
	esac
done
(
	cat package/common-service-aliases 
	case "`uname`" in
	Linux) cat package/linux-service-aliases ;;
	OpenBSD) cat package/openbsd-service-aliases ;;
	FreeBSD) cat package/freebsd-service-aliases ;;
	NetBSD) cat package/netbsd-service-aliases ;;
	*BSD) cat package/bsd-service-aliases ;;
	esac
) |
while read -r service alias
do
	ln -s "${service}" config/services{new}/"${alias}"
	case "${alias}" in
		*-log)	
			;;
		*)	
			ln -s cyclog@"${service}" config/services{new}/cyclog@"${alias}"
			;;
	esac
done
(
	cat package/common-target-aliases 
	case "`uname`" in
	Linux) cat package/linux-target-aliases ;;
	OpenBSD) cat package/openbsd-target-aliases ;;
	*BSD) cat package/bsd-target-aliases ;;
	esac
) |
while read -r service alias
do
	ln -s "${service}" config/targets{new}/"${alias}"
done
(
	cat package/common-etc-service-aliases 
	case "`uname`" in
	Linux)	cat package/linux-etc-service-aliases ;;
	*BSD)	cat package/bsd-etc-service-aliases ;;
	esac
) |
while read -r service alias
do
	ln -s "${service}" config/services{new}/"${alias}"
done

# ##############################################################################
# Build all of the {new} files in ./config.
install -d -m 0755 config/presets config/systemd config/systemd/tmpfiles config/systemd/system config/systemd/user config/convert config/convert/kbdmaps config/convert/dbus config/convert/per-user config/convert/per-user/dbus config/convert/termcap config/mewburn-rc.d config/open-rc.d config/openbsd-rc.d config/vt config/devd config/devpubd config/udevd config/zsh config/service-generators config/crontab config/cin-data-tables config/examples
cat package/tmpfiles-snippets |
while read -r i
do
	rm -f -- config/systemd/tmpfiles/"$i"{new}
	install -m 0444 -p -- build/systemd/tmpfiles/"$i" config/systemd/tmpfiles/"$i"{new}
done
cat package/systemd-system-services |
while read -r i
do
	rm -f -- config/systemd/system/"$i"{new}
	install -m 0444 -p -- build/systemd/system/"$i" config/systemd/system/"$i"{new}
done
cat package/systemd-system-overrides |
while read -r i
do
	rm -f -- config/systemd/system/"$i"{new}
	install -d -m 0755 config/systemd/system/"`dirname "$i"`"
	install -m 0444 -p -- build/systemd/system/"$i" config/systemd/system/"$i"{new}
done
cat package/systemd-user-services |
while read -r i
do
	rm -f -- config/systemd/user/"$i"{new}
	install -m 0444 -p -- build/systemd/user/"$i" config/systemd/user/"$i"{new}
done
(
	cat package/common-presets
	case "`uname`" in
	Linux) cat package/linux-presets ;;
	OpenBSD) cat package/openbsd-presets ;;
	*BSD) cat package/bsd-presets ;;
	esac
) |
awk '!x[$0]++' |
while read i
do
	rm -f -- config/presets/"$i"{new}
	install -m 0444 -p -- build/presets/"$i" config/presets/"$i"{new}
done
while read -r i
do
	rm -f -- config/mewburn-rc.d/"$i"{new}
	install -m 0555 -p -- build/mewburn-rc.d/"$i" config/mewburn-rc.d/"$i"{new}
done < package/mewburn-rc-scripts
while read -r i
do
	rm -f -- config/open-rc.d/"$i"{new}
	install -m 0555 -p -- build/open-rc.d/"$i" config/open-rc.d/"$i"{new}
done < package/open-rc-scripts
while read -r i
do
	rm -f -- config/openbsd-rc.d/"$i"{new}
	install -m 0555 -p -- build/openbsd-rc.d/"$i" config/openbsd-rc.d/"$i"{new}
done < package/openbsd-rc-scripts
while read -r i
do
	rm -f -- config/convert/"$i"{new}
	case "$i" in
	*.do)
		install -m 0555 -p -- build/convert/"$i" config/convert/"$i"{new}
		;;
	*)
		install -m 0444 -p -- build/convert/"$i" config/convert/"$i"{new}
		;;
	esac
done < package/conversion-tools
for i in issue.vc
do
	rm -f -- config/vt/"$i"{new}
	install -m 0444 -p -- build/"$i" config/vt/"$i"{new}
done 
for i in _nosh _console_terminal_emulator _system_control
do
	rm -f -- config/zsh/"$i"{new}
	install -m 0444 -p -- build/zsh/"$i" config/zsh/"$i"{new}
done 
for i in generate spin-up spin-down
do
	rm -f -- config/service-generators/"$i"{new}
	install -m 0555 -p -- build/service-generators/"$i" config/service-generators/"$i"{new}
done
for i in cyclog@.service kmod@.service
do
	rm -f -- config/service-generators/"$i"{new}
	install -m 0444 -p -- build/services/"$i" config/service-generators/"$i"{new}
done
while read -r i
do
	rm -f -- config/service-generators/"$i"{new}
	install -d -m 0755 config/service-generators/"`dirname "$i"`"
	install -m 0444 -p -- build/service-generators/"$i" config/service-generators/"$i"{new}
done < package/service-generators 
for i in no-anacron anacron
do
	rm -f -- config/crontab/crontab.debian."$i"{new}
	install -m 0444 -p -- build/bcron/crontab.debian."$i" config/crontab/crontab.debian."$i"{new}
done 
while read -r i
do
	rm -f -- config/cin-data-tables/"$i"{new}
	install -m 0444 -p -- build/cin-data-tables/"$i" config/cin-data-tables/"$i"{new}
done < package/cin-data-tables
# Plug and Play manager rulesets
while read -r i
do
	rm -f -- config/devd/"$i"{new}
	install -m 0444 -p -- build/devd/"$i" config/devd/"$i"{new}
done < package/devd-rules
while read -r i
do
	rm -f -- config/devpubd/"$i"{new}
	install -m 0555 -p -- build/devpubd/"$i" config/devpubd/"$i"{new}
done < package/devpubd-hooks
while read -r i
do
	rm -f -- config/udevd/"$i"{new}
	install -m 0444 -p -- build/udevd/"$i" config/udevd/"$i"{new}
done < package/udevd-rules
while read -r i
do
	j="`dirname "$i"`"
	install -m 0755 -d -- config/examples/"$j"
done < package/example-files
while read -r i
do
	rm -f -- config/examples/"$i"{new}
	install -p -- build/examples/"$i" config/examples/"$i"{new}
done < package/example-files

# ##############################################################################
# Rename the ...{new} directories and files in ./config.
cat package/tmpfiles-snippets |
while read -r i
do
	mv -f -- config/systemd/tmpfiles/"$i"{new} config/systemd/tmpfiles/"$i"
done 
cat package/systemd-system-services |
while read -r i
do
	mv -f -- config/systemd/system/"$i"{new} config/systemd/system/"$i"
done 
cat package/systemd-system-overrides |
while read -r i
do
	mv -f -- config/systemd/system/"$i"{new} config/systemd/system/"$i"
done
cat package/systemd-user-services |
while read -r i
do
	mv -f -- config/systemd/user/"$i"{new} config/systemd/user/"$i"
done 
(
	cat package/common-presets
	case "`uname`" in
	Linux) cat package/linux-presets ;;
	OpenBSD) cat package/openbsd-presets ;;
	*BSD) cat package/bsd-presets ;;
	esac
) |
awk '!x[$0]++' | while read i
do
	mv -f -- config/presets/"$i"{new} config/presets/"$i"
done 
while read -r i
do
	mv -f -- config/mewburn-rc.d/"$i"{new} config/mewburn-rc.d/"$i"
done < package/mewburn-rc-scripts
while read -r i
do
	mv -f -- config/open-rc.d/"$i"{new} config/open-rc.d/"$i"
done < package/open-rc-scripts
while read -r i
do
	mv -f -- config/openbsd-rc.d/"$i"{new} config/openbsd-rc.d/"$i"
done < package/openbsd-rc-scripts
while read -r i
do
	mv -f -- config/convert/"$i"{new} config/convert/"$i"
done < package/conversion-tools
for i in targets services
do
	test -e config/"$i" && mv -f -- config/"$i" config/"$i"{old}
	mv -f -- config/"$i"{new} config/"$i"
	rm -rf -- config/"$i"{old}
done
for i in issue.vc
do
	mv -f -- config/vt/"$i"{new} config/vt/"$i"
done 
for i in _nosh _console_terminal_emulator _system_control
do
	mv -f -- config/zsh/"$i"{new} config/zsh/"$i"
done 
(
        printf '%s\n' generate cyclog@.service kmod@.service spin-up spin-down
        cat package/service-generators
) |
while read -r i
do
	mv -f -- config/service-generators/"$i"{new} config/service-generators/"$i"
done
for i in no-anacron anacron
do
	mv -f -- config/crontab/crontab.debian."$i"{new} config/crontab/crontab.debian."$i"
done 
while read -r i
do
	mv -f -- config/cin-data-tables/"$i"{new} config/cin-data-tables/"$i"
done < package/cin-data-tables
# Plug and Play manager rulesets
while read -r i
do
	mv -f -- config/devd/"$i"{new} config/devd/"$i"
done < package/devd-rules
while read -r i
do
	mv -f -- config/devpubd/"$i"{new} config/devpubd/"$i"
done < package/devpubd-hooks
while read -r i
do
	mv -f -- config/udevd/"$i"{new} config/udevd/"$i"
done < package/udevd-rules
while read -r i
do
	mv -f -- config/examples/"$i"{new} config/examples/"$i"
done < package/example-files
