-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgeoblocker-bash-common
597 lines (489 loc) · 19.9 KB
/
geoblocker-bash-common
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
#!/bin/bash
# shellcheck disable=SC2034
# geoblocker-bash-common
# Common functions and variables for geoblocker-bash suite
# This script does nothing if called directly. It is sourced from other scripts.
### Functions
round_up_to_power2() {
# rounds the input number up to the next high power of 2
echo "\
if($1==0) x=0 else \
x=l($1)/l(2); \
scale=0; \
y=2^((x+1)/1); \
if($1==y/2 && $1!=1) \
print $1 \
else \
print y"\
| bc -l
}
get_file_size() {
# outputs file size in bytes for a given file
# works regardless (?) of how 'ls' is implemented
set -o pipefail
# shellcheck disable=SC2015,SC2012
[ -f "$1" ] && ls -dnL -- "$1" | awk '{print $5;exit}' || { echo ""; return 1; }
set +0 pipefail
# previous implementation, also works. but the above looks nicer and probably slightly faster
# # this is very touchy! so don't touch it.
# # this line is to catch the error code
# ls -ln "$1" &>/dev/null; rv=$?
# # shellcheck disable=SC2207
# ( IFS=$' \t'; set -f; ls_output=( $(ls -ln "$1" 2>/dev/null) ); printf "%s" "${ls_output[4]}" )
# return "$rv"
}
call_script() {
# calls antother script and makes sure that the config file cache resets on exit
# the reasons for this function:
# 1) for debug
# 2) to minimize config file reads. the only feasible way to do this is to cache the config file contents in a variable.
# bash doesn't allow to propagate changes made to a variable by a daughter script back to the parent script.
# so we need to track when the daughter script exits, and then reset the parent script's $config_var.
# once $config_var gets reset, getconfig() function will know that it needs to re-read the config file.
# uncomment for debug
# local arguments=("$@")
# debugprint "\033[1;33mStarted *call_script* with args: $(for arg in "${arguments[@]}"; do printf "%s" "'$arg' "; done)\033[0m"
local script_to_call="$1"
shift
# call the daughter script, then reset the $config_file var to force re-read of the config file next time getconfig() gets called
[[ -n "$script_to_call" ]] && { bash "$script_to_call" "$@"; rv=$?; export config_var=""; } || rv=1
set_script_names
debugexitmsg
return $rv
}
set_script_names(){
# sets some strings we use for debug
# shellcheck disable=SC2154
me_base="$(basename "$me")"
export me_short="${me_base//${suite_name}-/}"
export me_short_cap="${me_short^^}"
}
check_deps(){
# tests commands specified in arguments and complains if something's missing (by echo'ing it out in the end and setting return value to 1)
# if an argument contains '|' then tests for all alternatives and only if all are missing, complains
# check for bash >= 4.0
bash_v="${BASH_VERSINFO[0]}.${BASH_VERSINFO[1]}"
requiredver="4.0"
if [ "$(printf '%s\n' "$requiredver" "$bash_v" | sort -V | head -n1)" != "$requiredver" ]; then
echo "Error: missing dependency: 'bash v${requiredver}' or higher is required but 'bash v$bash_v' is installed." >&2
echo
exit 1
fi
local missing_deps=""
local err=0
IFS_OLD="$IFS"
IFS="${IFS_OLD}|"
# implicitly loops over arguments
for dep; do
# process 'or' statements received as 'command_1|command_2...|command_n'
if [[ "$dep" = *'|'* ]]; then
local test_alt_cnt=0
local err_alt_cnt=0
local alt_dep_list=""
local deps_alt="$dep"
# process all |-delimited alternatives
for dep_alt in $deps_alt; do
(( test_alt_cnt++ ))
! command -v "$dep" &> /dev/null && (( err_alt_cnt++ ))
[[ -z "$alt_dep_list" ]] && alt_dep_list="'$dep_alt'" || alt_dep_list="$alt_dep_list or '$dep_alt'"
done
if [[ "$err_alt_cnt" -ge "$test_alt_cnt" ]]; then
[[ -z "$missing_deps" ]] && missing_deps="$alt_dep_list" || missing_deps="${missing_deps}, $alt_dep_list"
(( err++ ))
fi
else
if ! command -v "$dep" &> /dev/null; then
[[ -z "$missing_deps" ]] && missing_deps="'$dep'" || missing_deps="${missing_deps}, '$dep'"
(( err++ ))
fi
fi
done
IFS="$IFS_OLD"
[[ "$err" -gt 0 ]] && { echo "$missing_deps"; return 1; } || return 0
}
echolog() {
# outputs arguments to stdout and writes them to syslog
# if one of the arguments is "-err" then redirect output to stderr
local msg_args1=() msg_args2=() arg msg_is_err first_el new_line
# check for "-err" option in arguments
for arg in "$@"; do
[[ "$arg" = "-err" ]] && msg_is_err="true" || msg_args1+=( "$arg" )
done
#check for '\n' in the biginning of the line and strip it if it's there
first_el="${msg_args1[0]}"
if [[ "${first_el:0:2}" = '\n' ]]; then new_line=$'\n'; msg_args1[0]="${first_el:2}"; fi
# check for "-noecho" option in arguments
for arg in "${msg_args1[@]}"; do
[[ "$arg" = "-noecho" ]] && noecho="true" || msg_args2+=( "$arg" )
done
if [[ -n "${msg_args2[*]}" ]]; then
# loop through arguments and print them to stderr and to the syslog
# "$nolog" is set as environment variable (used in *manage and *install scripts)
for arg in "${msg_args2[@]}"; do
if [[ ! "$noecho" ]]; then
[[ "$msg_is_err" ]] && echo -e "${new_line}$me_short: $arg" 1>&2 || echo -e "${new_line}$me_short: $arg"
fi
[[ ! "$nolog" ]] && logger -t "$me" "$(echo -e "$arg" | sed -e 's/\x1b\[[0-9;]*m//g')"
done
fi
}
debugprint() {
# prints a debug message
[[ "$debugmode" ]] && echo -e "\n Debug: ${me_short}: $*" >&2
}
debugentermsg() {
args="$(for arg in "${arguments[@]}"; do printf "%s" "'$arg' "; done)"
debugprint "\033[1;33mStarted *${me_short_cap}* with args: ${args}\033[0m"
}
debugexitmsg() {
[[ -n "$me_short_cap" ]] && debugprint "\033[1;33mBack to *$me_short_cap*...\033[0m"
}
die() {
# if first arg is a number, assume it's the exit code
if [[ "$1" =~ ^[0-9]+$ ]]; then rv="$1"; shift; else rv="1"; fi
die_args=()
# check for "-nolog" option in arguments
for die_arg in "$@"; do
[[ "$die_arg" = "-nolog" ]] && nolog="true" || die_args+=( "$die_arg" )
done
if [[ -n "${die_args[*]}" ]]; then
echo >&2
# loop through arguments and print them to stderr and to the syslog
# "$nolog" is set either when calling die() or as environment variable (used in *manage and *install scripts)
for arg in "${die_args[@]}"; do
echo -e "$yellow$me_short$no_color: $arg" >&2
# shellcheck disable=SC2001
arg_nocolors="$(sed $'s/\e\\[[0-9;:]*[a-zA-Z]//g' <<< "$arg")"
[[ ! "$nolog" ]] && logger -t "$me" "$arg_nocolors"
done
fi
echo >&2
exit "$rv"
}
getconfig() {
# reads a field named $1 from the config file $conf_file (or from file $2 if specified)
# outputs the resulting field
# if $conf_file=$2 then re-uses its value in order to minimiza file reads
# returns 0 if successful, 1 if missing arguments, 2 if key is not present in the config file
local key_conf="$1"
local target_file="${2:-$conf_file}"
[[ -z "$key_conf" || -z "$target_file" ]] && return 1
local conf=""
# re-use existing $config_var (if it's set) to minimize file reads, unless an unusual target file is specified
if [[ "$target_file" = "$conf_file" ]]; then
if [[ -n "$config_var" ]]; then
conf="$config_var"
elif [[ -s "$target_file" ]]; then
conf="$(<"$target_file")" || return 1
else return 1
fi
else
if [[ -s "$target_file" ]]; then
conf="$(<"$target_file")" || return 1
else return 1
fi
fi
local conf_line=""
conf_line="$(grep "$key_conf=" <<< "$conf" 2>/dev/null)" || return 2
local value_conf="${conf_line//$key_conf=}"
printf "%s" "$value_conf"
#[[ -z "$2" ]] && debugprint "getconfig: key - '$key_conf', value - '$value_conf'"
return 0
}
getstatus() {
# utilizes getconfig() but intended for reading status from status files
# 1st argument is path to the status file
# rest of the arguments are passed as is to setconfig()
target_file="$1"
shift 1
local rv=0
[[ -n "$target_file" ]] && { status_value="$(getconfig "$*" "$target_file")"; rv=$?; } || rv=1
printf "%s" "$status_value"
return $rv
}
setconfig() {
# Accepts key=value pairs and writes them to (or replaces in) config file specified in global variable $conf_file
# if one of the value pairs is "target_file=[file]" then writes to $file instead
# returns 0 if successful, 1 if not
# # uncomment for debug
# local arguments=("$@")
# # shellcheck disable=SC2155
# local args="$(for arg in "${arguments[@]}"; do printf "%s" "'$arg' "; done)"
# debugprint "\033[1;33mStarted *setconfig* with args: ${args}\033[0m"
### Parse arguments into associative array
declare -A arguments_arr
# loop through arguments
for argument_conf in "$@"; do
# read each line into a separate lines_arr element (needed in case an argument contains multiple lines)
readarray -t lines_arr <<< "$argument_conf"
for line in "${lines_arr[@]}"; do
# only process the line if it contains '='
if [[ "$line" == *'='* ]]; then
key_conf="$(cut -f1 -d= <<< "$line")"
key_length=${#key_conf}
value_conf="${line:$key_length+1}"
if [[ "$key_conf" = "target_file" ]]; then
arguments_target_file="$value_conf"
else
[[ -n "$key_conf" ]] && arguments_arr["$key_conf"]="$(trim_spaces "$value_conf")"
fi
fi
done
done
target_file="${arguments_target_file:-$conf_file}"
# Check that $target_file variable is not empty
[[ -z "$target_file" ]] && { die "*common: setconfig: '\$target_file' variable is not set!"; }
# create the config file if it doesn't exist
if [[ ! -f "$target_file" ]]; then
touch "$target_file" || { die "*common: setconfig: could not create target_file '$target_file'"; }
fi
# read config file into variable
config_var="$(<"$target_file")" || { die "*common: setconfig: could not read target_file '$target_file'"; }
for key_conf in "${!arguments_arr[@]}"; do
value_conf="${arguments_arr[$key_conf]}"
# remove corresponding config line if it exists
config_var="$(awk "!/$key_conf/" <<< "$config_var")"
# add updated config line
config_var="$key_conf=${value_conf}"$'\n'"$config_var"
done
# write modified config file
echo -e "$config_var" > "$target_file" || { die "*common: setconfig: Error: could not write to file '$target_file'!"; }
return 0
}
setstatus() {
# utilizes setconfig() but intended for writing status to status files
# 1st argument is path to the status file
# rest of the arguments are passed as is to setconfig()
target_file="$1"
shift 1
local rv=0
[[ -n "$target_file" ]] && { setconfig "target_file=$target_file" "${@}"; rv=$?; } || rv=1
return $rv
}
trim_spaces() {
set -f
# shellcheck disable=SC2048,2086
set -- $* # no quotes on purpose
local IFS_OLD="$IFS"
IFS=$' \t\n'
local trimmed_strings="$*"
set +f
IFS="$IFS_OLD"
printf "%s" "$trimmed_strings"
}
sanitize_string() {
# 1) replaces tabs with spaces in the input string
# 2) trims leading, trailing, and extra in-between whitespaces
# 3) replaces new lines (if any) with spaces
# 4) sorts and removes duplicates
local input_str="$*"
local input_space_sep="${input_str//$'\t'/ }" # replace tabs with spaces
# shellcheck disable=SC2155
local input_sorted="$(printf "%s" "${input_space_sep// /$'\n'}" | sort -ibu)" # replace spaces with newlines -> sort and remove duplicates
local sorted_str="${input_sorted//$'\n'/ }" # replace newlines with spaces
printf "%s" "$(trim_spaces "$sorted_str")" # trim extra spaces and print out
}
find_lists_intersection() {
# finds duplicates-free intersection between space-delimited fields in input strings $1 and $2,
# and outputs the intersection as a string
local list1=""; local list2=""; local intersect_str=""
# convert space-separated lists to newline-separated sorted lists
list1="$(printf "%s\n" "${1// /$'\n'}" | sort -u)"
list2="$(printf "%s\n" "${2// /$'\n'}" | sort -u)"
# piping into comm is not allowed so using the "<()" constructions
# result is space separated intersection list
intersect_str="$(comm -12 <(printf "%s" "$list1") <(printf "%s" "$list2"))"
printf "%s" "$(trim_spaces "$intersect_str")"
}
find_lists_difference() {
# finds space-delimited fields that exist in strings $1 or $2 but not both
# and outputs the difference as a string
local list1=""; local list2=""; local diff_list=""
# convert space-separated lists to newline-separated sorted lists
list1="$(printf "%s\n" "${1// /$'\n'}" | sort -u)"
list2="$(printf "%s\n" "${2// /$'\n'}" | sort -u)"
# can't pipe into comm so using the "<()" constructions
# result is space separated difference list
diff_list="$(comm -3 <(printf "%s\n" "$list1") <(printf "%s\n" "$list2"))"
printf "%s" "$(trim_spaces "$diff_list")"
}
subtract_list_a_from_b() {
# removes all space-delimited fields found in string $1 from string $2, outputs the result as a string
local list1=""; local list2=""
# convert space-separated lists to newline-separated sorted lists
list1="$(printf "%s\n" "${1// /$'\n'}" | sort -u)"
list2="$(printf "%s\n" "${2// /$'\n'}" | sort -u)"
# can't pipe into comm so using the "<()" constructions
# result is space separated difference list
diff_list="$(comm -13 <(printf "%s\n" "$list1") <(printf "%s\n" "$list2"))"
printf "%s" "$(trim_spaces "$diff_list")"
}
merge_lists() {
# merges string lists then sanitizes the list by removing extra white spaces and replacing \n with " "
merged_list="$*"
result_list="$(trim_spaces "$merged_list")"
printf "%s" "$result_list"
}
check_lists_coherency() {
# checks whether current ipsets and iptables rules match ones in the config file
debugprint "Verifying config coherency..."
# check for a valid list type
# shellcheck disable=SC2154
[[ "$list_type" != "whitelist" && "$list_type" != "blacklist" ]] && die "Error: Unrecognized list type '$list_type'!"
# initialize variables
unexpected_lists=""; missing_lists=""
config_lists="$(getconfig "Lists")" || die "Error: Couldn't read value for Lists from the config file."
# shellcheck disable=SC2119
active_lists="$(find_active_lists)" || return 1
# debugprint "active_lists: '$active_lists'"
# debugprint "config_lists: '$config_lists'"
# reflect discrepancies in global variables $unexpected_lists and $missing_lists
unexpected_lists="$(subtract_list_a_from_b "$config_lists" "$active_lists")"
missing_lists="$(subtract_list_a_from_b "$active_lists" "$config_lists")"
lists_difference="$(find_lists_difference "$active_lists" "$config_lists")"
if [[ -z "$lists_difference" ]]; then
debugprint "Successfully verified config coherency."
return 0
else
debugprint "Failed to verify config coherency."
return 1
fi
}
# shellcheck disable=SC2120
find_active_lists() {
# checks current ipsets and iptables rules for geoblocker
# returns a list of active ip lists
# if $1 is "all" then returns all lists even when there is a difference between ipset lists and iptables rules lists
local ipset_lists ipv4rules_lists ipv6rules_lists iprules_lists lists_intersection lists_difference lists_merged rule_type
case "$list_type" in
whitelist) rule_type="ACCEPT" ;;
blacklist) rule_type="DROP" ;;
*) die "Error: unexpected list type '$list_type'!"
esac
ipset_lists="$(ipset list -n | grep "$suite_name" | grep -o '.......$' | tr '\n' ' ' | awk '{$1=$1};1')"
ipv4rules_lists="$(iptables -vL | awk -v s="${suite_name}_" -v p="$rule_type" '($0!~s||$0!~p) {next} {gsub (s,"")} \
$0~p {for(i=1; i<=NF; i++) if($(i-1)~/^match-set$/) print $i}' | awk -v RS= '{gsub (/'"$\n"'/," ")} 1')"
ipv6rules_lists="$(ip6tables -vL | awk -v s="${suite_name}_" -v p="$rule_type" '($0!~s||$0!~p) {next} {gsub (s,"")} \
$0~p {for(i=1; i<=NF; i++) if($(i-1)~/^match-set$/) print $i}' | awk -v RS= '{gsub (/'"$\n"'/," ")} 1')"
iprules_lists="$(merge_lists "$ipv4rules_lists" "$ipv6rules_lists")"
lists_intersection="$(find_lists_intersection "$ipset_lists" "$iprules_lists")"
lists_difference="$(find_lists_difference "$ipset_lists" "$iprules_lists")"
lists_merged="$(merge_lists "$ipset_lists" "$iprules_lists")"
if [[ "$1" = "all" ]]; then
printf "%s" "$lists_merged"
else
printf "%s" "$lists_intersection"
fi
# shellcheck disable=SC2015
[[ -z "$lists_difference" ]] && return 0 || { ipsets_incoherent="true"; return 1; }
}
# this can't be used from a sourced script because it'll return the path to the sourced script and not to the caller
# leaving it in for reference
#get_script_dir () {
# SOURCE=${BASH_SOURCE[0]}
# while [ -L "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
# DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
# SOURCE=$(readlink "$SOURCE")
# [[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE
# # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
# done
# DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
# echo "$DIR"
#}
sanitize_args() {
# trims extra whitespaces, discards empty arguments
arguments=()
for arg in "$@"; do
# trim leading and trailing whitespaces
arg="$(trim_spaces "$arg")"
# add to array while discarding empty arguments
[[ -n "$arg" ]] && arguments+=("$arg")
done
}
validate_ccode(){
# validates country code in $1 against cca2.list
# country code must be in upper case
# optional $2 may contain path to cca2.list
# returns 0 if validation successful, 2 if not, 1 if cca2 list read from file is empty
# to fetch country codes online:
# cca2_list="$($fetch_command https://restcountries.com/v3.1/all?fields=cca2 2>/dev/null | jq -r '.[].cca2' 2>/dev/null)"
# command to xz-compress, convert to base64 and store in a variable:
# test="$(xz < cca2.list | base64 -w0)"
# resulting data:
# /Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4ALtARZdACCQ/UPERPp2ctP2iu+JpKwGwSps8/P8vQpb++GbAHflYA/3wP85V0OjxJaaNZsVRJRqecZIAsmd4IrGOeRgvY6uEjolGV2zY9K8k5F0wSk6L1dLgzEMHfD4UQci+0cuzbW7E4xay6wAt8stj/jfzyZkleZn+cXkEDlVEVTp7GkvCoIpRwlSZlT7a4U6PxoBXpMp5MjYXVVy0qbxDF3nxapo4SLpqR91levUQCW7c+s+Okj26gs/apehIjcOXpYpEmtwRrd6V4uXSyTeOovlskC0lsLWiF+DB2px9ylIq0Kw9gb6PBZ2d4hdDpoL5W/u3a8o20ehjquxJXUa+z4LzZpcZ7TMa6HiPQxIOx+cLeG7U1vBdw2gAAAAt7gTVpGW1WQAAbIC7gUAACPB/N6xxGf7AgAAAAAEWVo=
# this can be embedded in a script and decoded with the command:
# test2="$(base64 -d <<< "$test" | xz -d)"
# but for now, we are using a dedicated uncompressed file
cca2_path="${2:-"$conf_dir/cca2.list"}"
local rv=0
local checked_ccode=""
# shellcheck disable=SC2155
local ccode_list="$(<"$cca2_path")"
[[ -z "$ccode_list" ]] && { echo "Error: \$ccode_list variable is empty. Perhaps cca2.list is missing?" >&2; return 1; } # if the list variable is empty, revert the installation
checked_ccode="$(grep -x "$1" <<< "$ccode_list" 2>/dev/null)"; rv=$?
[[ "$rv" -eq 0 && -n "$checked_ccode" ]] && return 0 || return 2
}
detect_init() {
# init process is pid 1
INIT="$(ls -l /proc/1/exe)"
if [[ $INIT == *"upstart"* ]]; then
SYSTEMINITDAEMON=upstart
elif [[ $INIT == *"initctl"* ]]; then
SYSTEMINITDAEMON=sysvinit
elif [[ $INIT == *"systemd"* ]]; then
SYSTEMINITDAEMON=systemd
elif [[ $INIT == *"busybox"* ]]; then
SYSTEMINITDAEMON=busybox
elif [[ $INIT == *"procd"* ]]; then
SYSTEMINITDAEMON=procd
elif [[ $INIT == *"/sbin/init"* ]]; then
INIT="$(/sbin/init --version)"
if [[ $INIT == *"upstart"* ]]; then
SYSTEMINITDAEMON=upstart
elif [[ $INIT == *"systemd"* ]]; then
SYSTEMINITDAEMON=systemd
fi
else
SYSTEMINITDAEMON=unknown
fi
echo "$SYSTEMINITDAEMON"
}
check_cron() {
local rv=0
# check the init system
init_system="$(detect_init)"
case "$init_system" in
systemd )
# check if cron service is enabled
(systemctl is-enabled cron.service) &>/dev/null; rv=$? ;;
* )
# check for cron or crond in running processes
if ! pidof cron &>/dev/null && ! pidof crond &>/dev/null; then rv=1; else rv=0; fi ;;
esac
return "$rv"
}
set_script_names
### Checks
# check for common deps
missing_deps="$(check_deps bash tr cut sort wc awk sed grep comm logger bc)" || die "Error: missing dependencies: $missing_deps."
# check for curl
command -v "curl" &> /dev/null && curl_exists="true"
# check for wget
command -v "wget" &> /dev/null && wget_exists="true"
[[ "$curl_exists" || "$wget_exists" ]] || die "Missing dependencies: Neither curl nor wget found."
### Variables
# colors
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[1;33m'
purple='\033[0;35m'
no_color='\033[0m'
conf_dir="/etc/${suite_name}"
conf_file="${conf_dir}/${suite_name}.conf"
# global variables to get coherency check results from check_lists_coherency()
unexpected_lists=""
missing_lists=""
ipsets_incoherent=""
### Main
arguments=("$@")
return 0