This function easily lock or unlock a file.
Signed-off-by: Jonatan Schlag jonatan.schlag@ipfire.org --- src/functions/functions.util | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/src/functions/functions.util b/src/functions/functions.util index 4b6f956..23e5a4b 100644 --- a/src/functions/functions.util +++ b/src/functions/functions.util @@ -738,3 +738,17 @@ hex2dec() { dec2hex() { printf "%02x\n" "${1}" } + +lock_file() { + assert [ $# -eq 1 ] + local file=${1} + + touch "${file}.lock" +} + +unlock_file() { + assert [ $# -eq 1 ] + local file=${1} + + rm -f "${file}.lock" +}
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
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} +}
Signed-off-by: Jonatan Schlag jonatan.schlag@ipfire.org --- Makefile.am | 1 + src/functions/functions.description | 181 ++++++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 src/functions/functions.description
diff --git a/Makefile.am b/Makefile.am index 477a548..32e7166 100644 --- a/Makefile.am +++ b/Makefile.am @@ -114,6 +114,7 @@ dist_network_SCRIPTS = \ src/functions/functions.constants \ src/functions/functions.constants-firewall \ src/functions/functions.db \ + src/functions/functions.description \ src/functions/functions.device \ src/functions/functions.dhclient \ src/functions/functions.dhcpd \ diff --git a/src/functions/functions.description b/src/functions/functions.description new file mode 100644 index 0000000..fcf6b51 --- /dev/null +++ b/src/functions/functions.description @@ -0,0 +1,181 @@ +#!/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/. # +# # +############################################################################### + +description_format_filename() { + # Format the filename of a description file for a given zone or port + local type=${1} + local name=${2} + + case ${type} in + zone) + echo "$(zone_dir ${name})/description" + ;; + port) + echo "$(port_dir ${name})/description" + ;; + esac +} + +description_touch_file() { + # If the description file does not exist + # and we have no directory with the given name this function creates the file + local type=${1} + local name=${2} + + local file=$(description_format_filename ${type} ${name}) + + # We use the -e switch here because we want to touch + # when also no directory with this name exist + if ! [ -e ${file} ]; then + touch ${file} + fi + +} +description_title_read() { + # This function reads the title out of a given description file + local file=${1} + assert isset file + + [ -r "${file}" ] || return ${EXIT_ERROR} + + local title + read -r title < ${file} + echo ${title} +} + +description_edit() { + # This function provides a higher level interface special for description files of the editor function. + local type=${1} + local name=${2} + + description_touch_file ${type} ${name} + + local file=$(description_format_filename ${type} ${name}) + editor ${file} "description_check" +} + +description_print() { + # This function prints a given description file. + local type=${1} + local name=${2} + + local file=$(description_format_filename ${type} ${name}) + + if [ ! -r "${file}" ] || [ ! -f "${file}" ]; then + warning "${file} is not readable" + return ${EXIT_ERROR} + fi + + local title=$(description_title_read ${file}) + + cli_headline 1 "Description" + cli_space + cli_print 2 "${title}" + cli_space + # True if we are in the first line + local first_line=true + # True if we get from the second line on, only whitespace or empty lines + local front_white=true + # How many blank lines did we get + local white_counter=0 + + while read line; do + if ${first_line}; then + # We are in the first line and pass they so first_line is now false + first_line=false + continue + fi + # Chekc if the line is blank or contain only whitespace + if ${front_white} && [[ "${line}" =~ ^(|[[:space:]]+)$ ]]; then + # The we do not print them + continue + else + # we have found after the second line which is not blank or contain only white space so + # front_white is false. Now ew print empyt line but only if they are follewd by a non empty line. + front_white=false + if [[ "${line}" == "" ]] || [[ "${line}" =~ ^[[:space:]]$ ]]; then + # If the line is blank or contain only white space we increase the counter. + (( white_counter++ )) + else + # The line is not blank so we print all blank lines till now and print the current line after. + if [ ${white_counter} -gt 0 ]; then + for (( i = 1; i <= ${white_counter}; i += 1 )); do + cli_space + done + # The counter is now zero, because the lines were printed. + white_counter=0 + fi + cli_print 2 "${line}" + fi + fi + done < ${file} + + cli_space +} + +description_cli() { + # Function for the command line interface + local type=${1} + local name=${2} + local action=${3} + shift 3 + + case ${action} in + show) + description_print ${type} ${name} ${@} + ;; + edit) + description_edit ${type} ${name} ${@} + ;; + *) + error "Invalid argument: ${action}" + ;; + esac + +} + +description_check_title() { + # Checks if the title is too long and if so prints a warning + assert [ $# -eq 1 ] + + local title=${1} + local title_length=40 + + # Have to be shorter then ${title_length} + if [ ${#title} -gt ${title_length} ]; then + warning "Title '${title}' is to long. Only titles with ${title_length} or less chracters are allowed" + return ${EXIT_ERROR} + fi + + return ${EXIT_OK} +} + +description_check() { + # Chekc if a description file satisfy our needs. + assert [ $# -eq 1 ] + + local file=${1} + local title=$(description_title_read ${file}) + + description_check_title "${title}" + + return ${EXIT_OK} +}
Signed-off-by: Jonatan Schlag jonatan.schlag@ipfire.org --- src/functions/functions.ports | 7 +++++++ src/functions/functions.zone | 7 +++++++ 2 files changed, 14 insertions(+)
diff --git a/src/functions/functions.ports b/src/functions/functions.ports index db4e365..1c911f1 100644 --- a/src/functions/functions.ports +++ b/src/functions/functions.ports @@ -430,3 +430,10 @@ port_get_color() { local name=${1} color_read "port" ${name} } + +port_get_description_title() { + assert [ $# -eq 1 ] + + local name=${1} + description_title_read $(description_format_filename "port" "${name}") +} diff --git a/src/functions/functions.zone b/src/functions/functions.zone index 058110d..fd13875 100644 --- a/src/functions/functions.zone +++ b/src/functions/functions.zone @@ -1208,3 +1208,10 @@ zone_get_color() { local name=${1} color_read "zone" ${name} } + +zone_get_description_title() { + assert [ $# -eq 1 ] + + local name=${1} + description_title_read $(description_format_filename "zone" "${name}") +}
Signed-off-by: Jonatan Schlag jonatan.schlag@ipfire.org --- src/functions/functions.cli | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/src/functions/functions.cli b/src/functions/functions.cli index 5efd923..1bd99dd 100644 --- a/src/functions/functions.cli +++ b/src/functions/functions.cli @@ -113,6 +113,17 @@ cli_device_headline() { esac cli_print_fmt1 1 "Status" "${status}"
+ # Print the description title of the device. + case "${type}" in + port) + cli_print_fmt1 1 "Description" "$(port_get_description_title ${device})" + ;; + + zone) + cli_print_fmt1 1 "Description" "$(zone_get_description_title ${device})" + ;; + esac + # Print the color of the device. case "${type}" in port)
Signed-off-by: Jonatan Schlag jonatan.schlag@ipfire.org --- src/network | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/src/network b/src/network index ea7f7d6..e2c9db3 100644 --- a/src/network +++ b/src/network @@ -521,6 +521,9 @@ cli_port() { color) color_cli "port" "${port}" $@ ;; + description) + description_cli "port" "${port}" $@ + ;; *) error "Unrecognized argument: ${action}" exit ${EXIT_ERROR} @@ -582,6 +585,9 @@ cli_zone() { color) color_cli "zone" "${zone}" $@ ;; + description) + description_cli "zone" ${zone} $@ + ;; *) error "Unrecognized argument: ${action}" cli_show_man network-zone
Signed-off-by: Jonatan Schlag jonatan.schlag@ipfire.org --- src/bash-completion/network | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/bash-completion/network b/src/bash-completion/network index 091c1cb..f7c58a9 100644 --- a/src/bash-completion/network +++ b/src/bash-completion/network @@ -59,6 +59,16 @@ _network_color() { fi }
+_network_description() { + local words=( $@ ) + + local commands="edit show" + local cmd="$(_network_find_on_cmdline "${commands}")" + if [[ -z "${cmd}" ]]; then + COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) + return 0 + fi +} _network_device() { local words=( $@ )
@@ -258,7 +268,7 @@ _network_port() { _network_port_subcommand() { local words=( $@ )
- local commands="color create down edit identify remove status up" + local commands="color create description down edit identify remove status up" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) @@ -270,6 +280,9 @@ _network_port_subcommand() { color) _network_color ${args} ;; + description) + _network_description ${args} + ;; esac
} @@ -378,7 +391,7 @@ _network_zone_subcommand() {
local words=( $@ )
- local commands="color config disable down edit enable identify port rename status up" + local commands="color config description disable down edit enable identify port rename status up" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) @@ -396,6 +409,9 @@ _network_zone_subcommand() { color) _network_color ${args} ;; + description) + _network_description ${args} + ;; esac }
Hi,
did you not like these?
http://git.ipfire.org/?p=network.git;a=blob;f=src/functions/functions.lock;h...
-Michael
On Mon, 2017-06-19 at 21:20 +0200, Jonatan Schlag wrote:
This function easily lock or unlock a file.
Signed-off-by: Jonatan Schlag jonatan.schlag@ipfire.org
src/functions/functions.util | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/src/functions/functions.util b/src/functions/functions.util index 4b6f956..23e5a4b 100644 --- a/src/functions/functions.util +++ b/src/functions/functions.util @@ -738,3 +738,17 @@ hex2dec() { dec2hex() { printf "%02x\n" "${1}" }
+lock_file() {
- assert [ $# -eq 1 ]
- local file=${1}
- touch "${file}.lock"
+}
+unlock_file() {
- assert [ $# -eq 1 ]
- local file=${1}
- rm -f "${file}.lock"
+}