#!/bin/sh # 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 . $(dirname $(realpath $0))/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 # >>> 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)" add "boxfile=\"$output\"" add "if [[ \$binself == \$boxfile ]]; then" add " symed=0" add " if [[ \$# -eq 0 ]]; then" add " echo 'Available modules:'" for f in "${inputs[@]}"; do add " echo '$f'" done add " exit 0" add " fi" 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"