X-Git-Url: https://git.plutz.net/?a=blobdiff_plain;f=storage.sh;h=a8484b0514891fe3e7d6f3cfdbb55fba655cb61a;hb=e3e5c0d0a56dc4de4f7f9e0133e93b2360365eea;hp=d84f0c26d6529ddbbf5555de53902e96b23eedc5;hpb=0d6196d34eed576738a7ca4f4f40f240503b1d96;p=cgilite diff --git a/storage.sh b/storage.sh index d84f0c2..a8484b0 100755 --- a/storage.sh +++ b/storage.sh @@ -29,18 +29,18 @@ LOCK(){ lock="${1}.lock" timeout="${2-20}" if [ \! -w "${lock%/*}" ] || [ -e "$lock" -a \! -d "$lock" ]; then - printf 'Impossible to get lock: %s\n' "$lock" >&2 + debug "Impossible to get lock: $lock" return 1 fi while ! mkdir "$lock" 2>&-; do block="$(cat "$lock/pid" || printf 1)" if ! { ps -eo pid |grep -qwF "$block"; }; then - printf 'Overriding stale lock: %s\n' "$lock" >&2 + debug "Overriding stale lock: $lock" break fi if [ $timeout -le 0 ]; then - printf 'Timeout while trying to get lock: %s\n' "$lock" >&2 + debug "Timeout while trying to get lock: $lock" return 1 fi timeout=$((timeout - 1)) @@ -56,13 +56,13 @@ RELEASE(){ if [ "$(cat "$lock/pid")" = "$$" ]; then rm "$lock/pid" if ! rmdir "$lock"; then - printf 'Cannot remove tainted lock: %s\n' "$lock" >&2 + debug "Cannot remove tainted lock: $lock" printf '%i\n' $$ >"${lock}/pid" return 1 fi return 0 else - printf 'Refusing to release foreign lock: %s\n' "$lock" >&2 + debug "Refusing to release foreign lock: $lock" return 1 fi } @@ -91,7 +91,7 @@ STRING(){ " "*) out="${out}\\t"; in="${in# }" ;; +*) out="${out}\\+"; in="${in#+}" ;; " "*) out="${out}+"; in="${in# }" ;; - *) out="${out}${in%%[\\${CR}${BR} + ]*}"; in="${in#${in%%[\\${BR}${CR} + ]*}}" ;; + *) out="${out}${in%%[\\${CR}${BR} + ]*}"; in="${in#"${in%%[\\${BR}${CR} + ]*}"}" ;; esac; done printf '%s' "$out" } @@ -122,8 +122,100 @@ UNSTRING(){ \\+) out="${out}+"; in="${in#\\+}" ;; +*) out="${out} "; in="${in#+}" ;; \\*) in="${in#\\}" ;; - *) out="${out}${in%%[\\+]*}"; in="${in#${in%%[\\+]*}}" ;; + *) out="${out}${in%%[\\+]*}"; in="${in#"${in%%[\\+]*}"}" ;; esac; done printf '%s' "$out" } +DBM() { + local file="$1" cmd="$2" + local k v key value + shift 2; + + case "$cmd" in + check|contains) + key="$(STRING "$1")" + while read -r k v; do if [ "$k" = "$key" ]; then + return 0 + fi; done <"$file" 2>&- + return 1 + ;; + get) + key="$(STRING "$1")" + while read -r k v; do if [ "$k" = "$key" ]; then + UNSTRING "$v" + return 0 + fi; done <"$file" 2>&- + return 1 + ;; + set|store) + key="$(STRING "$1")" value="$(STRING "$2")" + LOCK "$file" || return 1 + { while read -r k v; do + [ "$k" = "$key" ] || printf '%s\t%s\n' "$k" "$v" + done <"$file" 2>&- + printf '%s\t%s\n' "$key" "$value" + } >"${file}.$$.tmp" + mv "${file}.$$.tmp" "${file}" + RELEASE "$file" + return 0 + ;; + add|insert) + k="$1" key="$(STRING "$1")" value="$(STRING "$2")" + LOCK "$file" || return 1 + if DBM "$file" check "$k"; then + RELEASE "$file" + return 1 + else + printf '%s\t%s\n' "$key" "$value" >>"${file}" + RELEASE "$file" + return 0 + fi + ;; + update|replace) + k="$1" key="$(STRING "$1")" value="$(STRING "$2")" + LOCK "$file" || return 1 + if ! DBM check "$k"; then + RELEASE "$file" + return 1 + fi + { while read -r k v; do + [ "$k" = "$key" ] \ + && printf '%s\t%s\n' "$key" "$value" \ + || printf '%s\t%s\n' "$k" "$v" + done <"$file" 2>&- + } >"${file}.$$.tmp" + mv "${file}.$$.tmp" "${file}" + RELEASE "$file" + return 0 + ;; + append) + key="$(STRING "$1")" value="$(STRING "$2")" + LOCK "$file" || return 1 + if ! DBM check "$1"; then + RELEASE "$file" + return 1 + fi + { while read -r k v; do + [ "$k" = "$key" ] \ + && printf '%s\t%s\n' "$key" "$v$value" \ + || printf '%s\t%s\n' "$k" "$v" + done <"$file" 2>&- + } >"${file}.$$.tmp" + mv "${file}.$$.tmp" "${file}" + RELEASE "$file" + return 0 + ;; + delete|remove) + key="$(STRING "$1")" + LOCK "$file" || return 1 + { while read -r k v; do + [ "$k" = "$key" ] || printf '%s\t%s\n' "$k" "$v" + done <"$file" 2>&- + } >"${file}.$$.tmp" + mv "${file}.$$.tmp" "${file}" + RELEASE "$file" + return 0 + ;; + esac +}