lackadaisical/binbox
Sam Hardeman 160a7763b7 - Minor cleanup
- Change shebangs to use 'env' in prep for NixOS (and others)
- `agenda` now has a symlink to the underlying tree structure named ".tree"
- `binbox` has more checking, being prepped for automatic export of symlinks.
- `cdz` now symlinks to the archive directory using "<archive name>.tmp". This is less confusing than a randomized extraction folder, and adds the benefit of being in the FS-tree of the original archive.
- daisy.source changes:
> Added basic debug mode.
> `ched` can now set global (all of the shell) editor or local (lackadaisical utils only) editor.
> The encoding/decoding functions have been expanded and improved. Extra checking, permissions are stored as well, `daisy_dec` can handle stdin.
- Added new functions to manage lackadaisical config: daisy_backup (runs `bak` on config files), daisy_clear (removes config files), and daisy_restore (restores config files archived using bak).
- All functions/tools prefixed with 'daisy_' are now also available prefixed with 'ld_' instead
- Added a new utility, `clip`. This utility keeps a local variable that can be set if given args and get if no args are supplied. Basically a simple clipboard local to the ptty. Supports stdin.
2026-01-25 18:23:05 +01:00

221 lines
5.3 KiB
Bash
Executable file

#!/usr/bin/env 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`.
LD_INTERNAL=1
. $(dirname $(realpath $0))/daisy.source
args=$@
function help()
{
echo "$LD_BIN is a utility that allows you to generate busybox-style combined binaries."
echo "It only supports shell scripts compatible with \`bash\`."
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: $LD_BIN -o <BOXED_BIN> <-s source files> <-p include files verbatim> -i INPUT_BINS ..."
echo "<X> Unpacking a boxed binary: $LD_BIN -e <BOXED_BIN>"
echo "View this screen: $LD_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
file="${args[$i]}"
((i++))
if [[ -e "$file" ]]; then
inputs+=("$file")
((b++))
else
echo "WARNING: Missing input binary: \"$file\"."
echo "Module will NOT be available!"
fi
done
continue
;;
-s)
((i++))
while [ $i -lt $# ] && [[ ! "${args[$i]}" =~ ^- ]]; do
file="${args[$i]}"
((i++))
if [[ -e "$file" ]]; then
sources+=("$file")
((s++))
else
echo "WARNING: Missing input source: \"$file\"."
echo "File will NOT be sourced!"
fi
done
continue
;;
-p)
((i++))
while [ $i -lt $# ] && [[ ! "${args[$i]}" =~ ^- ]]; do
file="${args[$i]}"
((i++))
if [[ -e "$file" ]]; then
includes+=("$file")
((p++))
else
echo "WARNING: Missing input include: \"$file\"."
echo "File will NOT be included!"
fi
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 [[ "$output" == "" ]]; then
echo "Missing output file!"
exit 1
fi
function add()
{
echo "$@" >> "$output"
}
function add_nn()
{
echo -n "$@" >> "$output"
}
rm -rf "$output"
# Now to construct the binary
# >>> Section 1, includes
add "#!/usr/bin/env 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 "readarray -t all_funcs < <(declare -F | awk '{print \$3}')"
# >>> 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 ""
add "################################################################################"
add "# END OF INCLUDED MODULES ######################################################"
add "################################################################################"
add ""
add "# Array of modules as well as array of functions."
# Add a static list of modules with a no-newline add
add_nn "modules=("
for f in "${inputs[@]}"; do
add_nn "\"$f\" "
done
add ")"
add 'mapfile -t funcs < <(printf "%s\n" "${all_funcs[@]}" "${modules[@]}" "${modules[@]}" | sort | uniq -u)'
add ""
add "# Check the export switches (-m and -f)"
add ""
add "symed=1"
add "binself=\$(basename \$0)"
add "boxfile=\"$(basename $output)\""
add ""
add "if [[ \$binself == \$boxfile ]]; then"
add " symed=0"
add " if [[ \$# -eq 0 ]]; then"
add " echo '$(basename $output): Multi-call binary generated by lackadaisical binbox.'"
add " echo 'Use switch \"-m\" to generate symlinks of modules in the current directory,'"
add " echo 'or use switch \"-f\" to generate symlinks of all available functions.'"
add " echo ''"
add " echo 'Exported modules:'"
add " for mod in \"\${modules[@]}\"; do"
add " echo \"- \$mod\""
add " done"
add " echo ''"
add " echo 'Other functions:'"
add " for func in \"\${funcs[@]}\"; do"
add " echo \"- \$func\""
add " done"
add " exit 0"
add " fi"
add "fi"
add ""
add "if [[ \$symed -eq 0 ]]; then"
add " eval \$@"
add " exit \$?"
add "fi"
add ""
add "if [[ \$symed -eq 1 ]]; then"
add " eval \$(basename \$0) \$@"
add "fi"
chmod +x "$output"