summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorroot <root@vps-18a7a2b7.vps.ovh.ca>2024-02-22 09:21:47 -0500
committerroot <root@vps-18a7a2b7.vps.ovh.ca>2024-02-22 09:21:47 -0500
commit2705aa066b152c2583887dc558dd9822506d7362 (patch)
tree54a6bac4fbee3e82be6ba3248669f337ac51f7ff
parent2ab6533b04c4918e2d6c057bf78d5e2f85c7958a (diff)
bash introspection experiments
-rw-r--r--bash/SOURCES.bash113
l---------bash/bootstrap_SOURCES.bash1
-rw-r--r--bash/denominate-function.bash82
3 files changed, 196 insertions, 0 deletions
diff --git a/bash/SOURCES.bash b/bash/SOURCES.bash
new file mode 100644
index 0000000..a274223
--- /dev/null
+++ b/bash/SOURCES.bash
@@ -0,0 +1,113 @@
1#!/bin/bash
2source()
3{
4 if [[ $1 != */* ]] &&
5 (
6 command -v base64_embedded_source__"$1" ||
7 command -v src/"$1"
8 ) >&2 # >/dev/null
9 then
10 rewrite_self \
11 "$1" \
12 src/"$1" \
13 base64_embedded_source__"$1" \
14 "${@:2}"
15 else
16 builtin source "$@"
17 fi
18}
19
20rewrite_self()
21{
22 # TODO: Check if version in src/ updates this version
23 # by checking for its hash in a record kept in the source
24 # file in src/
25 if command -v "$3" >/dev/null
26 then
27 (
28 set +e
29 sha256sum <("$3") >&2
30 sha256sum <(builtin source "$2" "${@:4}" && "$3") >&2
31 )
32 builtin source \
33 <("$3") \
34 "${@:4}"
35 return
36 fi
37 [ -f "$2" -a -r "$2" ] || return
38 declare -n tmpfile=tmpfile${RANDOM}
39 tmpfile=$(mktemp) || return
40 if embed "$1" "$2" > "$tmpfile" &&
41 builtin source "$tmpfile" &&
42 command -v "$3" >/dev/null &&
43 builtin source <("$3") "${@:4}" &&
44 [ -w "$0" ] &&
45 sed \
46 -i~"$(date -Ins)" \
47 -e "1 { r ${tmpfile}"$'\n'" }" \
48 "$0"
49 then
50 local r=0
51 else
52 local r=$?
53 fi
54 rm "$tmpfile"
55 return $r
56}
57
58embed()
59{
60 cat <<.
61base64_embedded_source__${1}()
62{
63 base64 -d <<.
64$(base64 < "$2" && echo .)
65}
66.
67}
68
69print_test_script_for_SOURCES.bash()
70{
71 cat <<.
72#!/bin/bash
73source SOURCES.bash
74source SOURCES.bash
75source rpc.bash
76: base64_embedded_source__rpc.bash
77: base64_embedded_source__dependencies.bash
78BASH_RPC_REMOTE_DEST=localhost \\
79 remote_run_function \\
80 source rpc.bash
81.
82}
83
84setup_test_dir()
85{
86 (
87 set -e
88 mkdir -p test_SOURCES.bash
89 cd test_SOURCES.bash
90 mkdir -p src
91 ln -sf -t src \
92 ../../SOURCES.bash \
93 ../../src/{rpc,dependencies}.bash
94 print_test_script_for_SOURCES.bash > test-SOURCES.bash
95 )
96}
97
98run_test()
99{
100 (
101 set -ex
102 cd test_SOURCES.bash
103 PATH=$PWD/src:$PATH bash test-SOURCES.bash || true
104 PATH=$PWD/src:$PATH bash test-SOURCES.bash
105 )
106}
107
108bootstrap_SOURCES.bash()
109{
110 setup_test_dir && run_test
111}
112
113[ "$0" = 'bootstrap_SOURCES.bash' ] && bootstrap_SOURCES.bash
diff --git a/bash/bootstrap_SOURCES.bash b/bash/bootstrap_SOURCES.bash
new file mode 120000
index 0000000..a0054dd
--- /dev/null
+++ b/bash/bootstrap_SOURCES.bash
@@ -0,0 +1 @@
SOURCES.bash \ No newline at end of file
diff --git a/bash/denominate-function.bash b/bash/denominate-function.bash
new file mode 100644
index 0000000..9e5cb31
--- /dev/null
+++ b/bash/denominate-function.bash
@@ -0,0 +1,82 @@
1#!/bin/bash
2denominate_function()
3{
4 declare -n func_name="$1"
5 local func_output_b64encoded output_hash
6 read -r -d '' \
7 func_output_b64encoded \
8 < <(base64) || [ "${func_output_b64encoded}" ]
9 read output_hash _ \
10 < <(base64 -d <<< "$func_output_b64encoded" | sha256sum)
11 [ ${#output_hash} = 64 ] || return
12 func_name=SHA256_${output_hash:0:32}
13 source <(cat <<END
14${func_name} ()
15{
16base64 -d <<.
17${func_output_b64encoded}
18.
19}
20END
21)
22}
23
24reverse_hash()
25{
26 case "$#.$1" in
27 2.SHA256 )
28 ;;
29 1.SHA256_???????????????????????????????? )
30 set -- SHA256 "${1#SHA256_}"
31 ;;
32 * )
33 return 1
34 ;;
35 esac
36 case ${#2} in
37 32 | 64 )
38 set -- "${1}_${2: 0 : 32}"
39 ;;
40 * )
41 return 1
42 ;;
43 esac
44 (
45 set -o pipefail
46 set -e
47 declare -f "$1" |
48 sed -n -e '/^[ ]*base64 -d <<[.]$/,/^[.]$/ { p }' |
49 sed -e '1 d ; $ d' |
50 base64 -d
51 )
52}
53
54example_input()
55{
56 sed -n -e '/^reverse_hash *()/ , /^}$/ p' <"$0"
57}
58
59set -e
60set -o pipefail
61
62if [ -t 0 ]
63then
64 if [ $# = 0 ]
65 then
66 denominate_function f < <(example_input)
67 else
68 denominate_function f <<< "$*"
69 fi
70else
71 denominate_function f
72fi
73
74read -r -d '' < <( reverse_hash "$f" | base64) || [ "$REPLY" ]
75if read s _ < <( base64 -d <<< "$REPLY" | sha256sum ) &&
76 [ ${#s} -eq 64 -a "${s: 0 : 32}" = "${f: -32 : 32}" ]
77then
78 declare -f "$f" | grep . &&
79 printf '%s\n' "$f"
80else
81 false
82fi