Files
IPTables-Management/lib/storage.sh

134 lines
2.4 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() {
local dir db lock
dir=$(storage_dir)
db=$(storage_db_path)
lock=$(storage_lock_path)
mkdir -p "${dir}"
touch "${db}" "${lock}"
chmod 750 "${dir}"
chmod 640 "${db}"
chmod 600 "${lock}"
}
storage_with_lock() {
local lock
storage_init
lock=$(storage_lock_path)
(
flock -x 9
"$@"
) 9>>"${lock}"
}
storage_add_unlocked() {
local line=${1-}
local db
[[ -n ${line} ]] || return 1
storage_init
db=$(storage_db_path)
printf '%s\n' "${line}" >>"${db}"
}
storage_add() {
storage_with_lock storage_add_unlocked "$@"
}
storage_list() {
local db
db=$(storage_db_path)
[[ -f ${db} ]] || return 0
cat "${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 db tmp found=0 line current
[[ -n ${uuid} ]] || return 1
storage_init
db=$(storage_db_path)
tmp="${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 <"${db}"
if (( found == 0 )); then
rm -f "${tmp}"
return 1
fi
mv "${tmp}" "${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++))
done < <(storage_list)
printf '%s\n' "${count}"
}