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
#!/bin/sh
usage() {
printf %s "\
pa-urn
commands:
[c]lose [file] - Archive password store into file.
[o]pen [file] - Extract file into password store.
"
}
create_tar() {
if command -v pax >/dev/null 2>&1; then
pax -x ustar -w "./$1"
else
tar c "./$1"
fi
}
extract_tar() {
if command -v pax >/dev/null 2>&1; then
pax -r
else
tar x
fi
}
die() {
printf '%s: %s.\n' "$(basename "$0")" "$1" >&2
exit 1
}
set -o pipefail
age=$(command -v age || command -v rage) ||
die "age not found, install per https://age-encryption.org"
basedir=${XDG_DATA_HOME:=$HOME/.local/share}/pa
: "${PA_DIR:=$basedir/passwords}"
dir=$(realpath "$PA_DIR") ||
die "couldn't get path to password directory"
name=$(basename "$dir")
if [ "$2" ]; then
urn=$(realpath -- "$2") ||
die "couldn't get path to file '$2'"
else
urn=$(pwd)/$name.tar.age ||
die "couldn't get working directory"
fi
cd "$(dirname "$dir")" ||
die "couldn't change to parent of password directory"
case $1 in
c*)
{ create_tar "$name" | $age -R "$basedir/recipients" -o "$urn"; } &&
printf '%s\n' "store has been archived into $urn"
;;
o*)
[ -f "$urn" ] ||
die "file '$urn' doesn't exist"
{ $age --decrypt -i "$basedir/identities" "$urn" | extract_tar; } &&
printf '%s\n' "file has been extracted into $PA_DIR"
;;
*) usage ;;
esac