lackadaisical/binbox

175 lines
3.5 KiB
Bash
Executable file

#!/bin/bash
# binbox: Creates a multi-binary script that self-contains the input scripts.
# Symlinking to the resulting binary with the name of one of the original scripts will trigger
# said script. The idea is similar to `busybox`.
DAISY_INTERNAL=1
. daisy.source
ARGS=$@
function help()
{
echo "$DAISY_BIN is a utility that allows you to generate busybox-style combined binaries."
echo "To access the original functionality of an input binary, you can either use a symlink or"
echo "call the function like so: 'combi-bin input-bin <input-bin args>."
echo ""
echo "> Usage:"
echo "Creating boxed binary: $DAISY_BIN -o <BOXED_BIN> <-s source files> <-p include files verbatim> -i INPUT_BINS ..."
echo "<X> Unpacking a boxed binary: $DAISY_BIN -e <BOXED_BIN>"
echo "View this screen: $DAISY_BIN <noargs>"
exit 0
}
if [[ $@ == '' ]]; then
help
fi
# Define some building blocks
CASE_P1="case $BINARY in"
CASE_PM1=" $OPTION)"
CASE_PM2=" exec $OTPION_fn"
CASE_PM3=" ;;"
CASE_CM1=" *)"
CASE_CM2=" exec help_fn"
CASE_CM3=" ;;"
CASE_P2="esac"
FUNC_P1="function $OPTION_fn() {"
FUNC_P2=" exit($?)"
FUNC_P3="}"
BASIC_P1="BINARY=$0"
# Start parsing args
inputs=()
output=""
inputs=()
output=""
includes=()
sources=()
args=("$@")
i=0
b=0
s=0
p=0
while [ $i -lt $# ]; do
case "${args[$i]}" in
-i)
((i++))
while [ $i -lt $# ] && [[ ! "${args[$i]}" =~ ^- ]]; do
inputs+=("${args[$i]}")
((i++))
((b++))
done
continue
;;
-s)
((i++))
while [ $i -lt $# ] && [[ ! "${args[$i]}" =~ ^- ]]; do
sources+=("${args[$i]}")
((i++))
((s++))
done
continue
;;
-p)
((i++))
while [ $i -lt $# ] && [[ ! "${args[$i]}" =~ ^- ]]; do
includes+=("${args[$i]}")
((i++))
((p++))
done
continue
;;
-o)
((i++))
output="${args[$i]}"
;;
esac
((i++))
done
echo "Input binaries: ${inputs[*]}"
echo "Include files: ${includes[*]}"
echo "Source files: ${sources[*]}"
echo "Output binary: $output"
if [ "$b" -eq 0 ]; then
echo "Missing input binaries!"
exit 1
fi
if [[ "$output" == "" ]]; then
echo "Missing output file!"
exit 1
fi
function add()
{
echo "$@" >> "$output"
}
rm -rf "$output"
# Now to construct the binary
# >>> Section 1, includes
add "#!/bin/bash"
add "# Multi-call binary generated by LACKADAISICAL binbox"
add "# $output information:"
add "# Contained modules: ${inputs[*]}"
add "# Files included verbatim: ${includes[*]}"
add "# Files sourced: ${sources[*]}"
add "# Symlink to this binary with the module name to invoke it, or"
add "# use '$output <func>' to do the same."
for f in "${sources[@]}"; do
add ". $f"
done
for f in "${includes[@]}"; do
add ""
add "# Included file $f"
add "$(cat "$f")"
done
add ""
add "if [[ \$# -eq 0 ]]; then"
add " echo 'Available modules:'"
for f in "${inputs[@]}"; do
add "echo '$f'"
done
add " exit 0"
add "fi"
# >>> Section 2: Modules
for f in "${inputs[@]}"; do
add "# Module '$f':"
add "function $f()"
add "{"
add "$(cat "$f" | grep -v "#!")"
add "}"
done
# >>> Section 3: Module selection
add "SYMED=1"
add "BINSELF=\$(basename \$0 | rev | cut -d "/" -f 1 | rev)"
add "BOXFILE=$(basename \"$output\")"
add "if [[ \$BINSELF == \$BOXFILE ]]; then"
add " SYMED=0"
add "fi"
add "if [[ \$SYMED -eq 0 ]]; then"
add " eval \$@"
add " exit \$?"
add "fi"
add "if [[ \$SYMED -eq 1 ]]; then"
add " eval \$(basename \$0) \$@"
add "fi"
chmod +x "$output"