diff --git a/README.md b/README.md
index 701b0da..aa0dc3d 100755
--- a/README.md
+++ b/README.md
@@ -36,8 +36,6 @@ lackadaisical` if you so desire.
To read this notice again, call the function 'daisy_help'.
===============================================================================
These are the included binaries and utilities:
- - calm:
- Reduce a process 'niceness' to 0.
- cdz:
This utility extracts an archive to /tmp and changes
directory to it in a new shell instance. Upon exit,
@@ -47,6 +45,27 @@ These are the included binaries and utilities:
NO_ARCHIVEMOUNT=1. The standard script supports zip,
tarballs, and rar archives. We recommend relying on
archivemount` if you have it installed.
+ Use "--check" to only check if a file is an archive.
+ It returns 0 if it is, 1 otherwise.
+ - squasher:
+ These convenient set of tools allow you to easily create
+ XZ-compressed SquashFS images from existing folders to save
+ disk space. The resulting folder is still writable since it is
+ mounted using an 'overlay' system. You can use 'squasher make'
+ to compresses an existing folder. These folders are automatically
+ mounted when you use 'cd' to navigate to them (via an alias).
+ When using 'make-squash-image' on an already mounted folder, it will
+ instead update the existing image. As of writing, we do not have a
+ SystemD service to auto-mount, however, you cam easily add auto-mount
+ as a cron job. Here is a list of tools, they all take the same
+ folder argument:
+ > squasher make: Converts the folder into a hidden image
+ on the same disk as the folder.
+ > squasher mount: Sets up a mount for the XZ image alongside
+ directories for changes
+ > squasher umount: Self-explanatory.
+ > squasher destroy: Extracts the image and essentially reverts
+ everything. File changes are kept, however.
- editx:
Uses your standard CLI editor to create/modify a
file and make it executable.
@@ -64,7 +83,7 @@ These are the included binaries and utilities:
Format is
-> .daisy////.
Recommended to run via crontab - automatically cleans
up empty folders.
- A symlink to the base of the folder's tree, ".tree",
+ A symbolic link to the base of the folder's tree, ".tree",
is created in the root of the specified directly.
Can be used for everything you'd like to sort by date.
For example; a diary, browser downloads, backups, code.
@@ -92,11 +111,11 @@ These are the included binaries and utilities:
This is a tool similar to which and others, the key
difference is that it returns partial matches. It can
be used to search for binaries.
- - binbox:
+ - scripbox:
This tool can be used to pack bash scripts into one
big megascript, much like how `busybox` works.
You can also make symlinks to it to invoke a specific
- script (as of writing, 11/25, symlinks do not work well).
+ script.
- bak/unbak:
These small utilities make backups of files by making
a copy with a .bak suffix. Unbak reverses the process
@@ -137,6 +156,8 @@ These are the included binaries and utilities:
The variable is stored locally in the shell as "LD_CLIP".
- ldrc:
Edits daisy.source and re-sources it, similarly to shrc.
+ Append "-e" to edit "extra.src", to add custom functions in the
+ lackadaisical namespace.
- daisy_reload:
Re-sources daisy.source. Essentially `ldrc` without
editing.
diff --git a/agenda b/agenda
index 837cd0f..f89dd61 100755
--- a/agenda
+++ b/agenda
@@ -28,10 +28,7 @@ root_dir=$(dirname $1)/.daisy/$(basename $1)
today_sym=$1
# Present day
-today=$(date -I)
-year=$(echo $today | awk -F"-" '{print $1}')
-month=$(echo $today | awk -F"-" '{print $2}')
-day=$(echo $today | awk -F"-" '{print $3}')
+read year month day < <(date "+%Y %m %d")
set -e
@@ -50,11 +47,10 @@ function errorFn
trap errorFn ERR
# First we clear out empty folders, and remove the symlink if it exists
-test -e "$root_dir" && find "$root_dir" -maxdepth 3 -type d -empty -print | xargs rm -rf
-test -L "$today_sym" && rm -rf "$today_sym"
+test -e "$root_dir" && find "$root_dir" -maxdepth 3 -type d -empty -delete
# Now we can set up today's directory
mkdir -p "$root_dir/$year/$month/$day"
-ln -s "$root_dir/$year/$month/$day" "$today_sym"
+ln -sf "$root_dir/$year/$month/$day" "$today_sym"
ln -s "$root_dir" "$today_sym/.tree"
-exitcode=@?
+exitcode=$?
diff --git a/calm b/calm
deleted file mode 100755
index cd4052e..0000000
--- a/calm
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env bash
-# Calm a process down
-# NEEDS_WORK: cleanup
-# calm == only one process
-# calm == all processes that match query
-# calm * == if used in proc or a folder with just PID files, if not you will get an error
-# calm .... OK
-# set's NICE value to 0
-# need sudo
-
-LD_INTERNAL=1
-. $(dirname $(realpath $0))/daisy.source
-
-pids=$@
-
-errorFn()
-{
- echo calm: Invalid operation or no such PID/process \(\"$(echo "$pids" | tr '\n' ' ' | cut -c -20)...\"\)
- exit
-}
-
-for pid in $pids
-do
- # Process to PID in elegant way
- newpids=$(pidof "$pid")
- if [ "$newpids" ]
- then
- binary=$pid
- pid=$newpids
- else
- newbins=$pid
- binary=$(ps -p "$pid" -o comm= 2>/dev/null )
- if [ $? != 0 ]
- then
- errorFn
- fi
- fi
-
- echo Calming down $pid \("$binary"\)...
- sudo renice -n 0 -p $pid;
-done
diff --git a/cdz b/cdz
index a380222..3b8d15a 100755
--- a/cdz
+++ b/cdz
@@ -1,118 +1,151 @@
#!/usr/bin/env bash
+# Usage: cdz [--check]
-if [[ $LD_INTERNAL -ne 1 ]];
+if [[ $LD_INTERNAL -ne 1 ]]
then
LD_INTERNAL=1
. $(dirname $(realpath $0))/daisy.source
fi
-target=$1
+is_archive()
+{
+ local file="$1"
+ local mime_type=$(file --mime-type -b "$file")
+
+ if [[ $mime_type == *"tar"* || $file == *.tar* || $mime_type == "application/zip" || $mime_type == "application/x-rar" ]]
+ then
+ return 0
+ fi
+
+ if command -v archivemount >/dev/null 2>&1
+ then
+ local test_dir=$(mktemp -d /tmp/cdz_check.XXXXXXXX)
+ local result=1
+ if archivemount -o readonly "$file" "$test_dir" >/dev/null 2>&1
+ then
+ result=0
+ umount "$test_dir"
+ fi
+ rmdir "$test_dir"
+ return $result
+ fi
+
+ return 1
+}
-# Check if file exists
-if [[ -z "$target" ]];
+check_mode=0
+if [[ "$1" == "--check" ]]
then
- echo "No target specified."
+ check_mode=1
+ shift
+fi
+
+target=$1
+if [[ -z "$target" ]]
+then
+ if [[ $check_mode -eq 0 ]]
+ then
+ echo "No target specified."
+ fi
exit 1
fi
-if ! test -f "$target";
+if [[ ! -f "$target" ]]
then
- echo "File not found: \"$target\""
+ if [[ $check_mode -eq 0 ]]
+ then
+ echo "File not found: \"$target\""
+ fi
exit 2
fi
-# Check if archivemount is present
-which archivemount 1>/dev/null 2>/dev/null
-hasmounter=$?
+target_abs=$(realpath "$target")
+name=$(basename "$target")
-file "$target" 1>/dev/null
-exitcode=$?
-report=$(file "$target")
-name=$(echo $@ | sed 's/:.*//' | sed 's|.*/||')
+if is_archive "$target_abs"
+then
+ if [[ $check_mode -eq 1 ]]
+ then
+ exit 0
+ fi
+else
+ if [[ $check_mode -eq 1 ]]
+ then
+ exit 1
+ fi
+ mime_type=$(file --mime-type -b "$target_abs")
+ echo "Unsupported archive type: $mime_type"
+ exit 1
+fi
-# Check for archive type, supported types are zip/tar/rar
+# Proceed with extraction
+has_archivemount=$(command -v archivemount >/dev/null 2>&1; echo $?)
+
+if [[ $has_archivemount -eq 0 && $NO_ARCHIVEMOUNT -ne 1 ]]
+then
+ use_mounter=1
+else
+ use_mounter=0
+fi
+
+mime_type=$(file --mime-type -b "$target_abs")
comm1=(:)
-comm2=(echo "Unsupported archive type$add: \"$target\"")
+comm2=(echo "Unsupported archive type: $mime_type")
comm3=(:)
comm4=(:)
comm5=(:)
-echo $report | grep "tar archive" 1>/dev/null
-istar=$?
-echo $report | grep "Zip archive" 1>/dev/null
-iszip=$?
-echo $report | grep "Android" 1>/dev/null
-iszip=$?
-echo $report | grep "RAR archive" 1>/dev/null
-israr=$?
-
-# TAR archives come in many forms, if none of our tests say it's tar
-# ...but it looks like tar and barks like tar, let's take the shot.
-# Seems to work fairly well for the record.
-res=$(echo "$target" | grep ".tar")
-if [[ $res != "" ]];
+if [[ $use_mounter -eq 1 ]]
then
- istar=0
+ echo "Using archivemount..."
+ comm2=(archivemount -o allow_root,use_ino "$target_abs")
+ comm4=(cd ..)
+ comm5=(umount)
+elif [[ $mime_type == *"tar"* || $target_abs == *.tar* ]]
+then
+ comm2=(tar xvf "$target_abs" -C)
+elif [[ $mime_type == "application/zip" ]]
+then
+ if command -v unzip >/dev/null 2>&1
+ then
+ comm2=(unzip -q "$target_abs" -d)
+ else
+ comm1=(echo "unzip is missing")
+ comm3=(exit 1)
+ fi
+elif [[ $mime_type == "application/x-rar" ]]
+then
+ if command -v unrar >/dev/null 2>&1
+ then
+ # unrar needs the directory as the last argument
+ comm2=(unrar x -idq "$target_abs")
+ else
+ comm1=(echo "unrar is missing")
+ comm3=(exit 1)
+ fi
fi
-if [[ $NO_ARCHIVEMOUNT -eq 1 ]]; then
- hasmounter=1
-fi
-
-if (( $hasmounter == 0 )); then
- echo "We have \`archivemount\`, so we'll use that!"
- echo "If you'd prefer we not use it, please specify NO_ARCHIVEMOUNT=1"
- istar=1
- iszip=1
- israr=1
-fi
-
-# Now we set the right command
-if (( $istar == 0 )); then
- comm2=(tar xvf "$target" -C)
-elif (( $iszip == 0 )); then
- which unzip 1>/dev/null
- exitcode=$?
- if (( $exitcode == 0 )); then
- comm2=(unzip -q "$target" -d)
- else
- comm1=(echo "The utility 'unzip' is missing, please install it")
- comm3=(exit 1)
- fi
-elif (( $israr == 0 )); then
- which unrar 1>/dev/null
- exitcode=$?
- if (( exitcode == 0 )); then
- comm2=(unrar -i nul "$target")
- else
- comm1=(echo "The utility 'unrar' is missing, please install it")
- comm3=(exit 1)
- fi
-elif (( $hasmounter == 0 )); then
- comm2=(archivemount -o allow_root -o use_ino "$target")
- comm4=(cd ..)
- comm5=(umount)
-fi
-
-# Create the temp dir, usually
dir=$(mktemp -d /tmp/extracted.XXXXXXXX)
-# And the rest of the commands
"${comm1[@]}"
-"${comm2[@]}" $dir
+if [[ ${comm2[0]} == "unrar" ]]
+then
+ "${comm2[@]}" "$dir"
+else
+ "${comm2[@]}" "$dir"
+fi
"${comm3[@]}"
-currentpath=$(pwd)
-sym="$currentpath/$name.tmp"
-ln -f -s "$dir" "$sym"
+sym="$(pwd)/$name.tmp"
+ln -sf "$dir" "$sym"
cd "$sym"
-echo "A symlink has been made under the name \"$sym\"."
-echo "This symlink points to the data directory \"$dir\"."
+echo "Extracted to $dir (linked via $sym)"
+echo "Type exit to finish."
-echo "Type 'exit' to exit the extracted archive's folder and auto-delete it."
eval $SHELL
+
"${comm4[@]}"
-"${comm5[@]}" $dir
-rm -rf $dir
+"${comm5[@]}" "$dir"
+rm -rf "$dir"
rm "$sym"
diff --git a/daisy.source b/daisy.source
index 2b109fe..915ab1b 100755
--- a/daisy.source
+++ b/daisy.source
@@ -24,7 +24,6 @@ function ld_dbg
then
$@
fi
- echo
}
# Variables for use in other utilities
@@ -38,10 +37,11 @@ fi
# Check for dependencies
function _daisy_dependency_check
{
- BIN=$(command -v $1 2>/dev/null)
- res=$?
-
- echo $(($res ^ 1))
+ if command -v "$1" >/dev/null 2>&1; then
+ echo 1
+ else
+ echo 0
+ fi
}
LD_HAS_fzf=$(_daisy_dependency_check fzf)
@@ -77,20 +77,22 @@ fi
# [LEA.TODO] Turn these into arrays
LD_ALIASFILE="$LD_CONFIG_FOLDER/aliases.src"
LD_EDITORFILE="$LD_CONFIG_FOLDER/editor.src"
+LD_ESOURCEFILE="$LD_CONFIG_FOLDER/extra.src"
touch $LD_ALIASFILE
touch $LD_EDITORFILE
+touch $LD_ESOURCEFILE
ld_dbg echo "Sourced config contents:"
ld_dbg cat $LD_ALIASFILE
ld_dbg cat $LD_EDITORFILE
+ld_dbg cat $LD_ESOURCEFILE
# Source everything in the config folder
function _daisy_source_configs
{
- for f in `find "$LD_CONFIG_FOLDER" -name "*.src" -type f`;
- do
- source "$f"
- done
+while IFS= read -r -d '' f; do
+ source "$f"
+ done < <(find "$LD_CONFIG_FOLDER" -name "*.src" -type f -print0)
}
# Installation into PATH
@@ -123,7 +125,7 @@ function daisy_wait_for_editor
while true;
do
- alive=$(ps aux | grep $fname | grep $pname)
+ alive=$(pgrep -f "$pname.*$fname")
if [[ $alive == "" ]]
then
break
@@ -132,12 +134,37 @@ function daisy_wait_for_editor
done
}
+function multicd
+{
+ cdpath="$@"
+ if [[ $cdpath == '' ]]
+ then
+ \cd
+ return
+ fi
+
+ if cdz --check "$cdpath" >/dev/null 2>&1
+ then
+ cdz "$cdpath"
+ return
+ fi
+
+ if [[ -f "$cdpath/.needs_mount" ]]
+ then
+ squasher mount "$cdpath"
+ fi
+ \cd "$cdpath"
+}
+
+alias cd=multicd
+
# Undocumented but internally used
function daisy_editor
{
editor=${LD_EDITOR:-$EDITOR};
ld_dbg echo Opening $editor to edit file: $1
- $editor "$1"
+ $editor "$1"
+ sleep 1
daisy_wait_for_editor $editor "$1"
}
@@ -248,7 +275,7 @@ function ched
for editor in "${editors[@]}";
do
editor_real=$(command -v "$editor")
- if command -v "$editor_rmeal" >/dev/null 2>&1;
+ if command -v "$editor_real" >/dev/null 2>&1;
then
if [[ $(realpath "$EDITOR") == "$editor_real" ]];
then
@@ -299,8 +326,12 @@ function daisy_reload
function ldrc
{
- daisy_editor "$LD_SOURCE_FILE"
- LD_INTERNAL=0 source "$LD_SOURCE_FILE"
+ ARG=$1
+ SOURCE="$LD_SOURCE_FILE"
+ [[ "$ARG" == "-e" ]] && SOURCE="$LD_ESOURCEFILE"
+
+ daisy_editor "$SOURCE"
+ LD_INTERNAL=0 source "$SOURCE"
}
enc_is_folder=0
@@ -483,7 +514,7 @@ function daisy_unalias
# Remove from aliases list
newdata=$(cat "$LD_ALIASFILE" | grep -v "alias $unalias_param")
- bak "$LD_ALIASFILE" 1>/dev/null
+ [[ NO_BAK -lt 1 ]] && bak "$LD_ALIASFILE" 1>/dev/null
echo -e $newdata > "$LD_ALIASFILE"
}
diff --git a/editx b/editx
index 839dfd2..685a977 100755
--- a/editx
+++ b/editx
@@ -16,15 +16,12 @@ then
ched "EDITOR env variable not set! You will have to set it yourself in the next screen."
fi
-exists=$(file "$1" >/dev/null && echo $?)
+[[ -e "$1" ]] && existed=1 || existed=0
touch "$1"
-chmod +x "$1"
-$EDITOR "$1"
-wait $!
-size=$(du "$1" | cut -f 1)
+chmod +x "$1"
+daisy_editor "$1"
-if [[ $size -eq 0 && $exists -ne 0 ]];
-then
- rm -rf "$1"
+if [[ ! -s "$1" && $existed -eq 0 ]]; then
+ rm -f "$1"
fi
diff --git a/own b/own
index 916c06e..6db1b49 100755
--- a/own
+++ b/own
@@ -5,13 +5,19 @@
LD_INTERNAL=1
. $(dirname $(realpath $0))/daisy.source
-if [[ $@ == '' ]];
-then
- echo "$LD_BIN: Used to quickly take ownership of files/folders."
- echo "Requires sudo. If sudo is not installed, this tool will fai."
+if [[ -z "$1" ]]; then
+ echo "$LD_BIN: Quickly take ownership of files/folders."
echo "Usage: $LD_BIN "
- echo "Means: chown -R : "
+ echo "Requires sudo. If sudo is not installed, this tool will fail."
exit 2
fi
-sudo chown -R $(whoami):$(whoami) $@
+# Ensure all arguments exist before attempting chown
+for target in "$@"; do
+ if [[ ! -e "$target" ]]; then
+ echo "Error: \"$target\" does not exist."
+ exit 1
+ fi
+done
+
+sudo chown -R "$(whoami):$(whoami)" "$@"
diff --git a/binbox b/scriptbox
similarity index 98%
rename from binbox
rename to scriptbox
index 214e50d..6aeb03d 100755
--- a/binbox
+++ b/scriptbox
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-# binbox: Creates a multi-binary script that self-contains the input scripts.
+# scriptbox: 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`.
diff --git a/squasher b/squasher
new file mode 100755
index 0000000..213181d
--- /dev/null
+++ b/squasher
@@ -0,0 +1,179 @@
+#!/bin/bash
+# Lackadaisical squashfs tools - Squasher
+# Combined utility for make, mount, umount, and destroy operations.
+
+BIN_DIR=$(dirname "$(readlink -f "$0")")
+COMMAND="$1"
+DIR="$2"
+
+usage() {
+ echo "Usage: $0 {make|mount|umount|destroy} "
+ exit 1
+}
+
+if [[ -z "$COMMAND" || -z "$DIR" ]]; then
+ usage
+fi
+
+DIR=$(readlink -f "$DIR")
+DIR_SHORT=$(basename "$DIR")
+OVERLAY_ROOT="$(dirname "$DIR")/.squashfs/$DIR_SHORT"
+OVERLAY_UPPER="$OVERLAY_ROOT/upper"
+OVERLAY_LOWER="$OVERLAY_ROOT/lower"
+OVERLAY_WORK="$OVERLAY_ROOT/work"
+OVERLAY_TARG="$DIR"
+
+case "$COMMAND" in
+ make)
+ if [[ ! -d "$DIR" ]]; then
+ echo "Error: Directory \"$DIR\" does not exist!"
+ exit 1
+ fi
+
+ echo "Checking system requirements (FUSE, SquashFS, OverlayFS)..."
+ for fs in fuse squashfs overlay; do
+ if ! grep -q "$fs" /proc/filesystems; then
+ echo "Attempting to load $fs module..."
+ sudo modprobe "$fs" || { echo "Error: $fs is not supported."; exit 1; }
+ fi
+ done
+
+ DIRSIZE=$(du -sh "$DIR" | cut -f1)
+ RECREATE=false
+ mkdir -p "$OVERLAY_ROOT"
+
+ if [[ -f "${OVERLAY_ROOT}.img" ]]; then
+ echo "Existing image found, updating..."
+ "$0" mount "$DIR"
+ DIRSIZE=$(du -sh "$DIR" | cut -f1)
+ RECREATE=true
+ fi
+
+ echo "Compressing \"$DIR\"..."
+ sudo mksquashfs "$DIR" "${OVERLAY_ROOT}.img.1" -noappend -comp xz || exit 1
+
+ if [[ "$RECREATE" == "true" ]]; then
+ echo "Cleaning up old layers..."
+ "$0" umount "$DIR"
+ if [[ -n "$OVERLAY_ROOT" && "$OVERLAY_ROOT" != "/" ]]; then
+ sudo rm -rf "$OVERLAY_UPPER" "$OVERLAY_LOWER" "$OVERLAY_WORK"
+ rm -f "${OVERLAY_ROOT}.img"
+ fi
+ fi
+
+ mv "${OVERLAY_ROOT}.img.1" "${OVERLAY_ROOT}.img"
+ mkdir -p "$OVERLAY_UPPER" "$OVERLAY_LOWER" "$OVERLAY_WORK" "$OVERLAY_TARG"
+
+ sudo rm -rf "$DIR"
+ mkdir -p "$DIR"
+ touch "$DIR/.needs_mount"
+
+ echo "-------------------------------------------------------------------------"
+ echo "Storage Stats:"
+ echo " Original size: $DIRSIZE"
+ echo " Compressed: $(du -sh "${OVERLAY_ROOT}.img" | cut -f1)"
+ echo "-------------------------------------------------------------------------"
+
+ SERVICE_CONTENT="[Unit]
+ Description=SquashFS Mount for %I
+ After=local-fs.target
+
+ [Service]
+ Type=oneshot
+ RemainAfterExit=yes
+ ExecStart=${BIN_DIR}/squasher mount %I
+ ExecStop=${BIN_DIR}/squasher umount %I
+
+ [Install]
+ WantedBy=multi-user.target"
+
+ echo "$SERVICE_CONTENT" | sudo tee /etc/systemd/system/squash-mount@.service > /dev/null
+ sudo systemctl daemon-reload
+
+ ESC_PATH=$(systemd-escape -p "$DIR")
+ SERVICE_NAME="squash-mount@$ESC_PATH.service"
+
+ read -p "Enable auto-mount service ($SERVICE_NAME)? [y/N] " yn
+
+ if [[ "$yn" =~ ^[Yy]$ ]]; then
+ sudo systemctl enable --now "$SERVICE_NAME"
+ sudo systemctl stop "$SERVICE_NAME"
+ sudo systemctl start "$SERVICE_NAME"
+ else
+ echo "Manual mount command: sudo systemctl start $SERVICE_NAME"
+ fi
+ ;;
+
+ mount)
+ if [[ ! -f "${OVERLAY_ROOT}.img" ]]; then
+ echo "Error: SquashFS image \"${OVERLAY_ROOT}.img\" not found." >&2
+ exit 1
+ fi
+
+ "$0" umount "$DIR" 2>/dev/null
+ mkdir -p "$OVERLAY_LOWER"
+ sudo mount "${OVERLAY_ROOT}.img" "$OVERLAY_LOWER" -t squashfs -o loop
+
+ if [[ $? -ne 0 ]]; then
+ echo "Error: Failed to mount squashfs image." >&2
+ exit 1
+ fi
+
+ sudo mount -t overlay none "$OVERLAY_TARG" \
+ -o lowerdir="$OVERLAY_LOWER",upperdir="$OVERLAY_UPPER",workdir="$OVERLAY_WORK"
+
+ if [[ $? -ne 0 ]]; then
+ echo "Error: Failed to mount overlay." >&2
+ sudo umount "$OVERLAY_LOWER" 2>/dev/null
+ exit 1
+ fi
+
+ echo "SquashFS filesystem is mounted and ready."
+ ;;
+
+ umount)
+ sudo umount -l -R "$OVERLAY_TARG" 2>/dev/null
+ sudo umount -l -R "$OVERLAY_LOWER" 2>/dev/null
+
+ if mountpoint -q "$OVERLAY_TARG" || mountpoint -q "$OVERLAY_LOWER"; then
+ echo "Warning: Filesystem is still mounted. Check for open processes."
+ exit 1
+ fi
+
+ echo "SquashFS filesystem has been unmounted."
+ ;;
+
+ destroy)
+ if [[ ! -f "$DIR/.needs_mount" ]]; then
+ if ! mountpoint -q "$DIR"; then
+ echo "Error: $DIR is not a SquashFS directory."
+ exit 1
+ fi
+ fi
+
+ ESC_PATH=$(systemd-escape -p "$DIR")
+ SERVICE_NAME="squash-mount@$ESC_PATH.service"
+
+ echo "Disabling service ($SERVICE_NAME)..."
+ sudo systemctl stop "$SERVICE_NAME" 2>/dev/null
+ sudo systemctl disable "$SERVICE_NAME" 2>/dev/null
+
+ echo "Ensuring image is mounted to preserve data..."
+ "$0" mount "$DIR" 1>/dev/null 2>/dev/null
+
+ echo "Destroying image and restoring data..."
+ TEMP_DIR=$(mktemp -d /tmp/squash-dest.XXXXXXXX)
+ sudo rsync -aX "$DIR/" "$TEMP_DIR/" || { echo "Error: Failed to copy data."; exit 1; }
+
+ "$0" umount "$DIR"
+ sudo rm -rf "$DIR"
+ sudo mv "$TEMP_DIR" "$DIR"
+ sudo rm -rf "$OVERLAY_ROOT" "${OVERLAY_ROOT}.img"
+
+ echo "Success: SquashFS image destroyed and data restored to \"$DIR\"."
+ ;;
+
+ *)
+ usage
+ ;;
+esac
diff --git a/sshp b/sshp
index eeedc7e..8f5c5c5 100755
--- a/sshp
+++ b/sshp
@@ -1,95 +1,58 @@
#!/usr/bin/env bash
+# sshp ("SSH PLUS") from lackadaisical
mounts=()
ssh_args=()
remote_port=$((10000 + RANDOM % 10000))
local_user=$(whoami)
-usage()
-{
- echo "sshp (\"SSH PLUS\") from lackadaisical."
- echo "Accepts all standard SSH options (see man ssh)."
- echo "Additionally, supports SSHFS mounts using a Docker-style syntax (-m)."
- echo "Usage: sshp -m : [user@]host [ssh_options]"
- echo "Example: sshp -m /home/juli:/home/juli juli@juli.pyon"
- exit 1
+usage() {
+ echo "Usage: sshp -m : [user@]host [ssh_options]"
+ exit 1
}
while [[ $# -gt 0 ]]; do
- case "$1" in
- -m)
- if [[ -z "$2" ]]
- then
- echo "Error: -m requires argument"
- exit 1
- fi
- mounts+=("$2")
- shift 2
- ;;
- *)
- ssh_args+=("$1")
- shift
- ;;
- esac
+ case "$1" in
+ -m)
+ if [[ -z "$2" ]]; then echo "Error: -m requires argument"; exit 1; fi
+ mounts+=("$2")
+ shift 2
+ ;;
+ *)
+ ssh_args+=("$1")
+ shift
+ ;;
+ esac
done
-if [[ ${#ssh_args[@]} -eq 0 ]]
-then
- usage
-fi
+[[ ${#ssh_args[@]} -eq 0 ]] && usage
mount_logic=""
unmount_logic=""
for map in "${mounts[@]}"; do
- local_path="${map%%:*}"
- remote_path="${map##*:}"
+ local_path="${map%%:*}"
+ remote_path="${map##*:}"
+ [[ "$local_path" != /* ]] && local_path="$PWD/$local_path"
- if [[ "$local_path" != /* ]]
- then
- local_path="$PWD/$local_path"
- fi
+ mount_logic+="
+ echo '>> Preparing mount: ${remote_path}';
+ mkdir -p \"${remote_path}\" 2>/dev/null || sudo mkdir -p \"${remote_path}\"
- mount_logic+="
- echo '>> Preparing mount: ${remote_path}';
- if ! mkdir -p \"${remote_path}\" 2>/dev/null
- then
- sudo mkdir -p \"${remote_path}\"
- fi
-
- if ! sshfs -p ${remote_port} -o StrictHostKeyChecking=no,idmap=user ${local_user}@localhost:\"${local_path}\" \"${remote_path}\" 2>/dev/null
- then
- echo ' (User mount failed, attempting escalation...)';
- if ! sudo sshfs -p ${remote_port} -o StrictHostKeyChecking=no,idmap=user,allow_other ${local_user}@localhost:\"${local_path}\" \"${remote_path}\"
- then
- echo ' ! Mount failed completely. Check permissions or keys.';
- fi
- else
- echo ' > Mounted successfully.';
- fi
- "
-
- unmount_logic+="
- fusermount -u -z \"${remote_path}\" 2>/dev/null || sudo fusermount -u -z \"${remote_path}\" 2>/dev/null;
- "
+ sshfs -p ${remote_port} -o StrictHostKeyChecking=no,idmap=user ${local_user}@localhost:\"${local_path}\" \"${remote_path}\" 2>/dev/null || \
+ sudo sshfs -p ${remote_port} -o StrictHostKeyChecking=no,idmap=user,allow_other ${local_user}@localhost:\"${local_path}\" \"${remote_path}\"
+ "
+ unmount_logic+="fusermount -u -z \"${remote_path}\" 2>/dev/null || sudo fusermount -u -z \"${remote_path}\" 2>/dev/null;"
done
remote_script="
- if ! command -v sshfs >/dev/null 2>&1
- then
- echo 'WARNING: \"sshfs\" not found on remote host.'
- echo '>> Skipping mounts, proceeding with shell only...';
- echo '----------------------------------------------';
- else
- ${mount_logic}
- fi
-
- ${SHELL:-bash};
-
- if command -v sshfs >/dev/null 2>&1
- then
+ if ! command -v sshfs >/dev/null 2>&1; then
+ echo 'WARNING: \"sshfs\" not found on remote host.'
+ else
+ ${mount_logic}
+ fi
+ \${SHELL:-bash};
${unmount_logic}
- fi
"
ssh -t -R ${remote_port}:localhost:22 "${ssh_args[@]}" "$remote_script"
diff --git a/what b/what
index b4a470d..707e0ce 100755
--- a/what
+++ b/what
@@ -26,7 +26,10 @@
LD_INTERNAL=1
. $(dirname $(realpath $0))/daisy.source
-pwd=/
-all_bins=$(cd / && echo $PATH | sed 's/[:]/ /g' | xargs ls -A | grep -v ":" | sort | uniq)
-output=$(printf '%s\n' "-n" $all_bins | grep -i "$1")
-echo "$output"
+all_bins=$(compgen -c | sort -u)
+
+if [[ -n "$1" ]]; then
+ echo "$all_bins" | grep -i "$1"
+else
+ echo "$all_bins"
+fi