]> git.ipfire.org Git - people/ms/network.git/blob - functions.util
Remove sorting algorithm implemented in shell code.
[people/ms/network.git] / functions.util
1 #!/bin/bash
2 ###############################################################################
3 # #
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2010 Michael Tremer & Christian Schmidt #
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
22 # Print a pretty error message
23 function error() {
24 echo -e " ${COLOUR_ERROR}ERROR${COLOUR_NORMAL} : $@" >&2
25 }
26
27 function error_log() {
28 log ERROR "$@"
29 }
30
31 # Print a pretty warn message
32 function warning() {
33 echo -e " ${COLOUR_WARN}WARNING${COLOUR_NORMAL}: $@" >&2
34 }
35
36 function warning_log() {
37 log WARNING "$@"
38 }
39
40 function listsort() {
41 local i
42 for i in $@; do
43 echo "${1}"
44 done | sort | tr '\n' ' '
45 }
46
47 function listmatch() {
48 local match=${1}
49 shift
50
51 assert isset match
52
53 local i
54 for i in $@; do
55 [ "${match}" = "${i}" ] && return ${EXIT_OK}
56 done
57
58 return ${EXIT_ERROR}
59 }
60
61 function listlength() {
62 local length=0
63
64 local i
65 for i in $@; do
66 length=$(( ${length} + 1 ))
67 done
68
69 echo "${length}"
70 }
71
72 function config_read() {
73 local config_file=${1}
74
75 log DEBUG "Reading configuration: ${config_file}"
76
77 if [ -e "${config_file}" ]; then
78 . ${config_file}
79 config_check
80 fi
81 }
82
83 function config_write() {
84 local config_file=${1}
85 shift
86
87 # Check if all values to be written are sane
88 config_check
89
90 log DEBUG "Writing configuration file ${config_file}."
91
92 > ${config_file}
93
94 local param
95 for param in $(listsort $@); do
96 echo "${param}=\"${!param}\"" >> ${config_file}
97 done
98 }
99
100 function config_print() {
101 local param
102
103 for param in $(listsort $@); do
104 printf "%-16s = %s\n" "${param}" "${!param}"
105 done
106 }
107
108 function config_check() {
109 # If there is a function defined that is called __check
110 # we call that function
111 [ -n "$(type -t _check)" ] && _check
112 }
113
114 function config_hostname() {
115 local hostname=${1}
116
117 if [ -n "${hostname}" ]; then
118 echo "${hostname}" > ${CONFIG_HOSTNAME}
119 else
120 echo "$(<${CONFIG_HOSTNAME})"
121 fi
122 }
123
124 function network_config_set() {
125 while [ $# -gt 0 ]; do
126 case "${1}" in
127 *=*)
128 log INFO "Setting configuration option '${1}'".
129 eval ${1}
130 ;;
131 *)
132 warning "Invalid parameter given: ${1}"
133 ;;
134 esac
135 shift
136 done
137
138 # Write configuration to disk
139 network_config_write
140 }
141
142 function network_config_read() {
143 # Save state of DEBUG and restore it later.
144 local debug=${DEBUG}
145
146 config_read ${CONFIG_FILE}
147
148 if [ -n "${debug}" ]; then
149 DEBUG=${debug}
150 fi
151 }
152
153 function network_config_write() {
154 config_write ${CONFIG_FILE} ${CONFIG_FILE_PARAMS}
155 }
156
157 function network_config_print() {
158 config_print ${CONFIG_FILE_PARAMS}
159 }
160
161 # Speedup function to avoid a call of the basename binary
162 function basename() {
163 echo "${1##*/}"
164 }
165
166 function enabled() {
167 local param=${1}
168
169 [ "${!param}" = "yes" ] || [ "${!param}" = "on" ] || [ "${!param}" = "1" ]
170 }
171
172 function mac_generate() {
173 local mac=()
174 for i in $(seq 0 5); do
175 mac[i]="$(uuid)"
176 mac[i]="0x${mac[i]:0:2}"
177 done
178
179 # Remove multicast bit
180 # and set address is software assigned
181 # XXX must doublecheck if this works
182 mac[0]=$((mac[0] & 0xfe))
183 mac[0]=$((mac[0] | 0x02))
184
185 local output
186 for i in ${mac[*]}; do
187 if [ -n "${output}" ]; then
188 output="${output}:"
189 fi
190
191 output="${output}$(printf "%02x" ${i})"
192 done
193
194 # Check if output is valid
195 assert mac_is_valid ${output}
196
197 echo ${output}
198 }
199
200 function mac_format() {
201 local mac=${1}
202
203 local output
204
205 if [ "${#mac}" = "12" ]; then
206 # Add colons (:) to mac address
207 output=${mac:0:2}
208 local i
209 for i in 2 4 6 8 10; do
210 output="${output}:${mac:${i}:2}"
211 done
212 fi
213
214 assert mac_is_valid ${output}
215
216 echo "${output}"
217 }
218
219 function mac_is_valid() {
220 local mac=${1}
221
222 [[ ${mac} =~ ^([0-9a-f]{2}\:){5}[0-9a-f]{2}$ ]]
223 }
224
225 function uuid() {
226 echo $(</proc/sys/kernel/random/uuid)
227 }
228
229 function isset() {
230 local var=${1}
231
232 [ -n "${!var}" ]
233 }
234
235 # XXX Nearly same as listmatch
236 function isoneof() {
237 local var=${!1}
238 shift
239
240 for i in $@; do
241 [ "${var}" = "${i}" ] && return ${EXIT_OK}
242 done
243
244 return ${EXIT_ERROR}
245 }
246
247 function isbool() {
248 local var=${1}
249
250 isoneof ${var} 0 1 no yes on off
251 }
252
253 function isinteger() {
254 local var=${!1}
255
256 [[ ${var} =~ ^[0-9]+$ ]]
257 }
258
259 function ismac() {
260 local mac=${!1}
261
262 mac_is_valid ${mac}
263 }
264
265 function backtrace() {
266 local start=1
267
268 echo # Empty line
269 error_log "Backtrace (most recent call in first line):"
270
271 local i
272 for i in $(seq ${start} ${#BASH_SOURCE[*]}); do
273 [ -z "${FUNCNAME[${i}]}" ] && continue
274 [ "${FUNCNAME[${i}]}" == "main" ] && continue
275
276 error_log " $(printf "%20s" "'${FUNCNAME[${i}]}'") called from ${BASH_SOURCE[$(( ${i} + 1 ))]}:${BASH_LINENO[${i}]}"
277 done
278 }
279
280 function assert() {
281 local assertion="$@"
282
283 if ! ${assertion}; then
284 error_log "Assertion '${assertion}' failed."
285 backtrace
286 exit ${EXIT_ERROR}
287 fi
288
289 return ${EXIT_OK}
290 }
291
292 function exec_cmd() {
293 local cmd=$@
294
295 log DEBUG "Running command: ${cmd}"
296
297 DEBUG=${DEBUG} \
298 LOG_DISABLE_STDOUT="${LOG_DISABLE_STDOUT}" \
299 LOG_FACILITY="${LOG_FACILITY}" \
300 ${SHELL} ${cmd}
301 local ret=$?
302
303 #log DEBUG "Returned with code '${ret}'"
304
305 if [ ${ret} -eq ${EXIT_ERROR_ASSERT} ]; then
306 error_log "Stopping parent process due to assertion error in child process: ${cmd}"
307 exit ${EXIT_ERROR_ASSERT}
308 fi
309
310 return ${ret}
311 }
312
313 function cmd() {
314 local cmd=$@
315
316 log DEBUG "Running command: ${cmd}"
317
318 ${cmd}
319 local ret=$?
320
321 log DEBUG "Returned with code '${ret}'"
322
323 return ${ret}
324 }
325
326 function uppercase() {
327 local input
328 read input
329 echo "${input^^}"
330 }
331
332 function lowercase() {
333 local input
334 read input
335 echo "${input,,}"
336 }
337
338 function seq() {
339 if [ $# -eq 2 ]; then
340 eval echo {${1}..${2}}
341 elif [ $# -eq 3 ]; then
342 eval echo {${1}..${3}..${2}}
343 fi
344 }
345
346 function beautify_time() {
347 local value=${1}
348
349 local unit
350 local limit
351 for unit in s m h d w; do
352 case "${unit}" in
353 s|m|h)
354 limit=60
355 ;;
356 d)
357 limit=24
358 ;;
359 w)
360 limit=7
361 ;;
362 esac
363
364 [ ${value} -lt ${limit} ] && break
365
366 value=$(( ${value} / ${limit} ))
367 done
368
369 echo "${value}${unit}"
370 }
371
372 function beautify_bytes() {
373 local value=${1}
374
375 local unit
376 local limit=1024
377 for unit in B k M G T; do
378 [ ${value} -lt ${limit} ] && break
379 value=$(( ${value} / ${limit} ))
380 done
381
382 echo "${value}${unit}"
383 }
384
385 function module_load() {
386 local module=${1}
387
388 if ! grep -q "^${module}" /proc/modules; then
389 log DEBUG "Loading module '${module}'."
390 modprobe ${module}
391 fi
392 }
393
394 function binary_exists() {
395 local binary=${1}
396
397 if [ -n "$(type -p ${binary})" ]; then
398 return ${EXIT_OK}
399 fi
400
401 return ${EXIT_ERROR}
402 }
403
404 function process_kill() {
405 local process=${1}
406
407 if ! isinteger process; then
408 process=$(pidof ${process})
409 fi
410
411 local pid
412 local sig
413 for pid in ${process}; do
414 for sig in 15 9; do
415 [ -d "/proc/${pid}" ] || break
416
417 kill -${sig} ${pid}
418 sleep 1
419 done
420 done
421 }
422
423 function dec() {
424 local hex=${1}
425
426 if [ "${hex:0:2}" != "0x" ]; then
427 hex="0x${hex}"
428 fi
429
430 printf "%d\n" "${hex}"
431 }
432
433 function network_is_running() {
434 # Check, if the network service is running.
435 service_is_active network
436 }