]>
Commit | Line | Data |
---|---|---|
e524986c JS |
1 | #!/bin/bash |
2 | ############################################################################### | |
3 | # # | |
4 | # IPFire.org - A linux based firewall # | |
5 | # Copyright (C) 2017 IPFire Network Development Team # | |
6 | # # | |
7 | # This program is free software: you can redistribute it and/or modify # | |
8 | # it under the terms of the GNU General Public License as published by # | |
9 | # the Free Software Foundation, either version 3 of the License, or # | |
10 | # (at your option) any later version. # | |
11 | # # | |
12 | # This program is distributed in the hope that it will be useful, # | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | |
15 | # GNU General Public License for more details. # | |
16 | # # | |
17 | # You should have received a copy of the GNU General Public License # | |
18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | |
19 | # # | |
20 | ############################################################################### | |
21 | ||
e524986c JS |
22 | editor_find_best() { |
23 | # Open a file with the best available editor | |
24 | assert [ $# -eq 1 ] | |
25 | ||
26 | local file=${1} | |
27 | local ret | |
28 | ||
29 | for editor in ${EDITOR} vim vi; do | |
30 | ${editor} "${file}" | |
31 | ret=${?} | |
32 | ||
33 | case "${ret}" in | |
34 | ${EXIT_OK}) | |
35 | return ${EXIT_OK} | |
36 | ;; | |
37 | ||
38 | ${EXIT_COMMAND_NOT_FOUND}) | |
39 | continue | |
40 | ;; | |
41 | ||
42 | *) | |
43 | return ${ret} | |
44 | ;; | |
45 | esac | |
46 | done | |
47 | ||
48 | error "Unable to find a working editor" | |
49 | ||
50 | return ${EXIT_COMMAND_NOT_FOUND} | |
51 | } | |
52 | ||
53 | editor() { | |
d4564f2b MT |
54 | local file="${1}" |
55 | assert isset file | |
e524986c | 56 | |
e524986c JS |
57 | if [ ! -f ${file} ] || [ ! -w ${file} ]; then |
58 | error "${file} is not valid file or is not writeable" | |
59 | return ${EXIT_ERROR} | |
60 | fi | |
61 | ||
d4564f2b MT |
62 | lock "${file}.lock" __editor "$@" |
63 | } | |
e524986c | 64 | |
d4564f2b MT |
65 | __editor() { |
66 | # This function open a file for editing and take care of all preperation and postprocessing | |
67 | assert [ $# -ge 1 ] | |
e524986c | 68 | |
d4564f2b MT |
69 | local file="${1}" |
70 | local check_func="${2}" | |
e524986c JS |
71 | |
72 | # create a temporary file | |
d4564f2b | 73 | local temp_file="$(mktemp)" |
e524986c JS |
74 | |
75 | if ! [ -f "${temp_file}" ]; then | |
76 | error "Cannot create temporary file" | |
77 | fi | |
78 | ||
79 | # copy the content into this temporary file | |
80 | cp -f "${file}" "${temp_file}" | |
81 | ||
82 | # edit the file | |
83 | if ! editor_find_best "${temp_file}"; then | |
84 | error "Could not edit ${file}" | |
d4564f2b MT |
85 | |
86 | # Delete temporary file | |
87 | file_delete "${temp_file}" | |
88 | ||
89 | return ${EXIT_ERROR} | |
e524986c JS |
90 | fi |
91 | ||
92 | # run the check if we have one | |
93 | if isset check_func && ! editor_check "${check_func}" "${temp_file}"; then | |
d4564f2b MT |
94 | # Delete temporary file |
95 | file_delete "${temp_file}" | |
96 | ||
e524986c JS |
97 | return ${EXIT_ERROR} |
98 | fi | |
99 | ||
100 | # copy the changes back | |
101 | cp -f "${temp_file}" "${file}" | |
102 | ||
d4564f2b MT |
103 | # Delete temporary file |
104 | file_delete "${temp_file}" | |
e524986c JS |
105 | } |
106 | ||
107 | editor_check() { | |
108 | # Execute the check function to make sure that the changes does not break anything | |
109 | local check_func="${1}" | |
110 | shift | |
111 | ||
112 | # Execute the check function | |
2212045f | 113 | "${check_func}" "$@" |
e524986c JS |
114 | local ret="${?}" |
115 | ||
116 | case "${ret}" in | |
117 | # OK | |
118 | ${EXIT_OK}|${EXIT_TRUE}) | |
119 | log DEBUG "Check succeeded" | |
120 | return ${EXIT_TRUE} | |
121 | ;; | |
122 | ||
123 | # Error | |
124 | ${EXIT_ERROR}|${EXIT_FALSE}) | |
125 | log CRITICAL "Check failed" | |
126 | return ${EXIT_FALSE} | |
127 | ;; | |
128 | ||
129 | # Command not found | |
130 | ${EXIT_COMMAND_NOT_FOUND}) | |
131 | log CRITICAL "Check function '${check_func}' was not found" | |
132 | return ${EXIT_FALSE} | |
133 | ;; | |
134 | esac | |
135 | ||
136 | log CRITICAL "Unhandled exit code for '${check_func}': ${ret}" | |
137 | return ${EXIT_ERROR} | |
138 | } |