Files
IPTables-Management/lib/storage.sh

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}"
}