[2/7] Add editor functions

Submitted by Jonatan Schlag on June 19, 2017, 7:20 p.m.

Details

Message ID 1497900050-27692-2-git-send-email-jonatan.schlag@ipfire.org
State New
Headers show

Commit Message

Jonatan Schlag June 19, 2017, 7:20 p.m.
Signed-off-by: Jonatan Schlag <jonatan.schlag@ipfire.org>
---
 Makefile.am                    |   1 +
 src/functions/functions.editor | 147 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 148 insertions(+)
 create mode 100644 src/functions/functions.editor

Patch hide | download patch | download mbox

diff --git a/Makefile.am b/Makefile.am
index 108e7a7..477a548 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -120,6 +120,7 @@  dist_network_SCRIPTS = \
 	src/functions/functions.distro \
 	src/functions/functions.dns \
 	src/functions/functions.dummy \
+	src/functions/functions.editor \
 	src/functions/functions.ethernet \
 	src/functions/functions.firewall \
 	src/functions/functions.firewall-policy \
diff --git a/src/functions/functions.editor b/src/functions/functions.editor
new file mode 100644
index 0000000..1ca8159
--- /dev/null
+++ b/src/functions/functions.editor
@@ -0,0 +1,147 @@ 
+#!/bin/bash
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2010  Michael Tremer & Christian Schmidt                      #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+editor_cleanup() {
+	# Cleanup after a file was edited.
+	assert [ $# -eq 2 ]
+	local file=${1}
+	local temp_file=${2}
+
+	unlock_file ${file}
+	rm -f ${temp_file}
+}
+
+editor_find_best() {
+	# Open a file with the best available editor.
+	assert [ $# -eq 1 ]
+
+	local file=${1}
+	local ret
+
+	for editor in ${EDITOR} vim vi; do
+		${editor} "${file}"		
+		ret=${?}
+
+		case "${ret}" in
+			${EXIT_OK})
+				return ${EXIT_OK}
+				;;
+
+			${EXIT_COMMAND_NOT_FOUND})
+				continue
+				;;
+
+			*)
+				return ${ret}
+				;;
+		esac
+	done
+
+	error "Unable to find a working editor"
+
+	return ${EXIT_COMMAND_NOT_FOUND}
+}
+
+editor() {
+	# This function open a file for editing and take care of all preperation and postprocessing
+	assert [ $# -ge 1 ]
+
+	local file=${1}
+	if [ ! -f ${file} ] || [ ! -w ${file} ]; then
+		error "${file} is not valid file or is not writeable"
+		return ${EXIT_ERROR}
+	fi
+	# Maybe we should check if the file is writeable?
+	local check_func=${2}
+
+	# check if the file is locked
+	if [ -f "${file}.lock" ]; then
+		error "Cannot edit ${file} because it is locked"
+		return ${EXIT_ERROR}
+	fi
+	
+	#lock the file
+	if ! lock_file ${file}; then
+		error "Cannot lock file ${file}"
+	fi
+
+	# create a temporary file
+	local temp_file=$(mktemp)
+	
+	if ! [ -f "${temp_file}" ]; then
+		error "Cannot create temporary file"
+	fi
+
+	# copy the content into this temporary file
+	cp -f "${file}" "${temp_file}"
+
+	# edit the file
+	if ! editor_find_best "${temp_file}"; then
+		error "Could not edit ${file}"
+		# cleanup
+		editor_cleanup "${file}" "${temp_file}"
+	fi
+
+	# run the check if we have one
+	if isset check_func && ! editor_check "${check_func}" "${temp_file}"; then
+		return ${EXIT_ERROR}
+	fi
+
+	# copy the changes back
+	cp -f "${temp_file}" "${file}"
+
+	# cleanup
+	editor_cleanup "${file}" "${temp_file}"
+
+}
+
+editor_check() {
+	# Execute the check function to make sure that the changes does not break anything
+	local check_func="${1}"
+	shift
+	
+	# Execute the check function
+	"${check_func}" $@
+	local ret="${?}"
+
+	case "${ret}" in
+		# OK
+		${EXIT_OK}|${EXIT_TRUE})
+			log DEBUG "Check succeeded"
+			return ${EXIT_TRUE}
+			;;
+
+		# Error
+		${EXIT_ERROR}|${EXIT_FALSE})
+			log CRITICAL "Check failed"
+			return ${EXIT_FALSE}
+			;;
+
+		# Command not found
+		${EXIT_COMMAND_NOT_FOUND})
+			log CRITICAL "Check function '${check_func}' was not found"
+			return ${EXIT_FALSE}
+			;;
+	esac
+
+	log CRITICAL "Unhandled exit code for '${check_func}': ${ret}"
+	return ${EXIT_ERROR}
+}