175 lines
3.5 KiB
Bash
Executable file
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"
|