#!/bin/sh

# /usr/bin/wrap_editors
#
# Author: Alexander Kriegisch (user 'kriegaex' at ip-phone-forum.de)
#
# Generic editor wrapper script for "special" files in
#   - /var/flash (Fritz!Box config files in character devices)
#   - /var/tmp/flash and /var/mod/etc/conf (Freetz config files)
#
# This script replaces good old nvi/mvi as well as nmcedit and should work as
# a replacement for any other n*/m* script as long as you create symbolic
# links with the right names pointing to this script. Examples:
#   - /usr/bin/nvi   -> wrap_editors
#   - /usr/bin/mnano -> wrap_editors
#   - /any/path/xfoo -> /usr/bin/wrap_editors
#
# It might be a good idea to stick to the old n*/m* naming scheme for the
# symbolic links you create, but it is not technically necessary, because this
# script uses the path of the file to be edited to decide whether is should
# work in "/var/flash mode" or in "Freetz mode". The only important thing is
# that the script discards the first character of the symbolic link name, i.e.
# if the link is named "xfoo", the script tries to call an editor named "foo".
# The target editor must be in the current PATH, so the script can find it
# via "which foo".


# Function for calling the target editor, handling the result and permitting
# some user interaction. Parameters:
#   $1 - editor base name (NOT full path, otherwise we get problems with $tmp)
#   $2 - file to be edited (full or relative path)
#
# If you want to disable the "are you sure do you want to save" question, do
# the following:
#   echo 0 > /tmp/flash/ask_save
#   modsave
# To re-enable the question, call
#   rm -f /tmp/flash/ask_save
#   modsave

edit_file()
{
	local tmp="/var/$1.tmp"
	cat $2 > $tmp
	$1 $tmp
	local exitval=$?
	if [ $exitval -ne 0 ]; then
		rm -f $tmp
		echo "editor session aborted" >&2
		exit $exitval
	fi
	local save="y"
	if cmp -s "$tmp" "$2" 2> /dev/null; then
		echo "aborted - file '$2' not changed"
		rm -f $tmp
		return 1
	fi
	if [ "$(head -n1 /tmp/flash/ask_save 2>/dev/null)" != "0" ]; then
		echo -n "Are you sure you want to save the changes made? (y/n) "
		read -n 1 -s save
		echo
	fi
	if [ "$save" == "y" ]; then
		cat $tmp > $2
		echo "done - file '$2' saved"
		exitval=0
	else
		echo "aborted - file '$2' not saved"
		exitval=1
	fi
	rm -f $tmp
	return $exitval
}


# Determine editor
local editor_base=$(basename $0)
if [ "$editor_base" == "wrap_editors" ]; then
	echo "error: don't call 'wrap_editors' directly, but via symlink" >&2
	exit 1
fi
editor_base=$(echo "$editor_base" | sed 's/^.//')
local editor=$(which $editor_base)
if [ ! -x "$editor" ]; then
	echo "error: editor '$editor_base' not found or not executable" >&2
	exit 1
fi

# Verify name of file to be edited
if [ -z "$1" ] ; then
	echo "usage: $0 <config-filename>" >&2
	exit 1
fi
if [ ! -w "$1" ] ; then
	echo "error: file '$1' must exist and be writeable" >&2
	exit 1
fi

# Determine editing mode (TFFS file or Freetz config)
local dir="$(dirname "$1")"
local base="$(basename "$1")"
case "$(realpath "$dir")/" in
	/var/flash/)
		edit_file $editor_base $1
		;;
	/var/tmp/flash/*)
		if edit_file $editor_base $1; then
			/usr/bin/modsave flash
		fi
		;;
	/var/mod/etc/conf/*)
		local pkg="${base%.cfg}"
		local cfg="/mod/etc/default.$pkg/$pkg.cfg"
		if [ ! -r $cfg ]; then
			echo "error: file '$cfg' not found or not readable" >&2
			exit 1
		fi
		if edit_file $editor_base $1; then
			/usr/bin/modconf save $pkg
			/usr/bin/modsave flash
		fi
		;;
	*)
		echo "error: use only with files in /var/flash, /var/mod/etc/conf or /var/tmp/flash" >&2
		exit 1
		;;
esac
