-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.sh
More file actions
executable file
·162 lines (124 loc) · 3.49 KB
/
main.sh
File metadata and controls
executable file
·162 lines (124 loc) · 3.49 KB
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/bin/bash
source "optparse/optparse.sh"
optparse_usage_header="[option...] file..."
optparse.define short=d long=decompile variable=decomp desc="bashball to decompile" default=""
optparse.define short=e long=edit variable=edit desc="edit bashball internals with default system editor" default=""
optparse.define short=v long=version variable=vers desc="display bashball version" flag
. <(optparse.build)
set -euo pipefail
tmpdir="/tmp/bashball-$$"
mkdir -p "$tmpdir"
trap 'rm -rf $tmpdir' EXIT
# create base bashball template
cat > "$tmpdir/ball" <<'EOF'
#!/usr/bin/env bash
# check if apps are installed
set -e
declare -a apps=("tar" "base64")
for app in ${apps[@]}; do hash $app 2>/dev/null || { echo "$app is not installed on this system"; exit 1; }; done
# useful variables (can be used in scripts)
export _localdir="$(pwd)"
export _tmpdir="/tmp/bashball-$$"
export _name="$(basename $0)"
# makes source function local
source() {
lib="$1"
cd "$_tmpdir"
. "$lib"
cd "$_localdir"
}
export -f source
# trap exit and delete temporary folder
trap "rm -rf $_tmpdir" EXIT
# makes temporary folder
mkdir -p $_tmpdir
# __TAR will be replaced with the base64 tarball content
# this extracts the content of the tarball and puts it in the temporary folder
printf $'
__TAR
' | base64 -d | tar xz -C $_tmpdir --warning=no-timestamp
# executes main
bash -c "$(cat <(echo 'cd $_localdir') $_tmpdir/main.sh)" $_name "${@}"
EOF
# check that required apps are present on system
declare -a apps=("tar" "base64" "ed" "sed" "tr")
for app in ${apps[@]}; do
hash $app 2>/dev/null || {
echo "ERROR: [$app] is missing from system" >&2
exit 1
}
done
function check_output {
[ -t 1 ] && {
echo "ERROR: refusing to output to terminal" >&2
exit 1
}
}
function bb_build {
local files="${@}"
[[ -z ${@:-} ]] && usage
check_output || true
has_main=false
for f in $files; do
[[ $f == "main.sh" ]] && has_main=true
done
$has_main || {
echo "ERROR: cannot create bashball without main.sh" >&2
exit 1
}
tar -czf - $files | base64 | tr '\n' '\r' | sed 's \r g' > "$tmpdir/tar"
printf '%s\n' "/^__TAR/r $tmpdir/tar" w | ed "$tmpdir/ball" 1>/dev/null 2>&1
cat "$tmpdir/ball" |\
tr '\n' '\r' |\
sed -e 's/\r__TAR\r//' -e 's/=\r/=/' -e "s/\r'/\'/g" |\
tr '\r' '\n' |\
sed -e '/^\s*#[^!].*/d' -e 's/\s*#[^!].*//g' -e '/^\s*$/d' |\
tr '\n' ';' |\
sed 's/{;/{/g' |\
sed 's/;/\n/'
}
function bb_dec {
local target="$1"
check_output || true
grep -oP "(?<=printf \\$').*?(?=')" "$target" |\
base64 -d
}
# version
$vers && {
echo "bashball, version <VERSION>"
exit 0
}
# decompression
[[ -n ${decomp:-} ]] && {
bb_dec "$decomp"
exit 0
}
# edit
[[ -n ${edit:-} ]] && {
[ -z ${EDITOR:-} ] && {
echo "ERROR: no editor specified, cannot edit"
exit 1
}
case $edit in
/*) edit="$edit"
;;
*) edit="$(pwd)/$edit"
;;
esac
# preparing folders
mkdir -p "$tmpdir/edit"
mkdir -p "$tmpdir/edit/build"
# decompress
bb_dec "$edit" > "$tmpdir/edit/file.tar.gz"
cd "$tmpdir/edit"
# edit
$EDITOR "file.tar.gz"
# rebuild
tar -C "$tmpdir/edit/build" -xzf "file.tar.gz"
cd "$tmpdir/edit/build"
bb_build "$(find * -type f)" > $edit
exit 0
}
# if nothing is specified,
# do standard bashball compression
bb_build ${@}