104 lines
2.3 KiB
Bash
104 lines
2.3 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
if [[ -n ${IPF_STORAGE_SH_LOADED:-} ]]; then
|
|
return 0
|
|
fi
|
|
IPF_STORAGE_SH_LOADED=1
|
|
|
|
: "${IPF_STORAGE_DIR:=/var/lib/iptables-forward}"
|
|
: "${IPF_STORAGE_DB:=${IPF_STORAGE_DIR}/rules.db}"
|
|
: "${IPF_LOCK_FILE:=${IPF_STORAGE_DIR}/.lock}"
|
|
|
|
storage_dir() { printf '%s\n' "${IPF_STORAGE_DIR}"; }
|
|
storage_db_path() { printf '%s\n' "${IPF_STORAGE_DB}"; }
|
|
storage_lock_path() { printf '%s\n' "${IPF_LOCK_FILE}"; }
|
|
|
|
storage_init() {
|
|
mkdir -p "${IPF_STORAGE_DIR}"
|
|
touch "${IPF_STORAGE_DB}" "${IPF_LOCK_FILE}"
|
|
chmod 750 "${IPF_STORAGE_DIR}"
|
|
chmod 640 "${IPF_STORAGE_DB}"
|
|
chmod 600 "${IPF_LOCK_FILE}"
|
|
}
|
|
|
|
storage_with_lock() {
|
|
storage_init
|
|
(
|
|
flock -x 9
|
|
"$@"
|
|
) 9>>"${IPF_LOCK_FILE}"
|
|
}
|
|
|
|
storage_add_unlocked() {
|
|
local line=${1-}
|
|
[[ -n ${line} ]] || return 1
|
|
storage_init
|
|
printf '%s\n' "${line}" >>"${IPF_STORAGE_DB}"
|
|
}
|
|
|
|
storage_add() { storage_with_lock storage_add_unlocked "$@"; }
|
|
|
|
storage_list() {
|
|
[[ -f ${IPF_STORAGE_DB} ]] || return 0
|
|
cat "${IPF_STORAGE_DB}"
|
|
}
|
|
|
|
storage_parse() {
|
|
local line=${1-}
|
|
local key=${2-}
|
|
local part
|
|
IFS='|' read -r -a parts <<<"${line}"
|
|
for part in "${parts[@]}"; do
|
|
if [[ ${part} == "${key}="* ]]; then
|
|
printf '%s\n' "${part#*=}"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
storage_get() {
|
|
local uuid=${1-}
|
|
local line current
|
|
[[ -n ${uuid} ]] || return 1
|
|
while IFS= read -r line || [[ -n ${line} ]]; do
|
|
current=$(storage_parse "${line}" uuid || true)
|
|
if [[ ${current} == "${uuid}" ]]; then
|
|
printf '%s\n' "${line}"
|
|
return 0
|
|
fi
|
|
done < <(storage_list)
|
|
return 1
|
|
}
|
|
|
|
storage_delete_unlocked() {
|
|
local uuid=${1-}
|
|
local tmp found=0 line current
|
|
[[ -n ${uuid} ]] || return 1
|
|
storage_init
|
|
tmp="${IPF_STORAGE_DB}.tmp.$$"
|
|
|
|
: >"${tmp}"
|
|
while IFS= read -r line || [[ -n ${line} ]]; do
|
|
current=$(storage_parse "${line}" uuid || true)
|
|
if [[ ${current} == "${uuid}" ]]; then
|
|
found=1
|
|
continue
|
|
fi
|
|
printf '%s\n' "${line}" >>"${tmp}"
|
|
done <"${IPF_STORAGE_DB}"
|
|
(( found == 1 )) || { rm -f "${tmp}"; return 1; }
|
|
mv "${tmp}" "${IPF_STORAGE_DB}"
|
|
}
|
|
|
|
storage_delete() { storage_with_lock storage_delete_unlocked "$@"; }
|
|
|
|
storage_count() {
|
|
local count=0 line
|
|
while IFS= read -r line || [[ -n ${line} ]]; do
|
|
[[ -n ${line} ]] || continue
|
|
((count += 1))
|
|
done < <(storage_list)
|
|
printf '%s\n' "${count}"
|
|
}
|