#!/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 ." echo "" echo "> Usage:" echo "Creating boxed binary: $DAISY_BIN -o <-s source files> <-p include files verbatim> -i INPUT_BINS ..." echo " Unpacking a boxed binary: $DAISY_BIN -e " echo "View this screen: $DAISY_BIN " 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 ' 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"