Skip to content

Commit

Permalink
mount-helper, fm-rm: fixes and improvements
Browse files Browse the repository at this point in the history
mount-helper:
    - fix source checking being the same as type checking
    - fix gocryptfs unmounts when the cipher doesn't exist (e.g. is unmounted from a parent mount)
    - fix ownership removals
    - skip unmount confirm if correct expectation and goal is unmounting
- fm-rm:
    - add `user` and `group` options to ensure correct access when removing
    - update conventions
  • Loading branch information
balupton committed Jul 17, 2023
1 parent cbdf126 commit c0efbea
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 38 deletions.
52 changes: 29 additions & 23 deletions commands/fs-rm
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ function fs-rm() (
# =====================================
# Arguments

# @todo add user,group,owner settings

function help {
cat <<-EOF >/dev/stderr
ABOUT:
Expand All @@ -22,6 +20,10 @@ function fs-rm() (
--sudo
If specified, use sudo when removing the files.
--user=<user>
--group=<group>
If specified run the removal commands as this <user> and <group>.
EOF
if test "$#" -ne 0; then
echo-error "$@"
Expand All @@ -30,32 +32,34 @@ function fs-rm() (
}

# process
local item paths=() quiet='no' confirm='yes' sudo='no'
quiet="$(echo-quiet "$quiet" -- "$@")"
local item option_paths=() option_quiet='no' option_confirm='yes' option_sudo='no' option_user='' option_group=''
option_quiet="$(echo-quiet "$option_quiet" -- "$@")"
while test "$#" -ne 0; do
item="$1"
shift
case "$item" in
'--help' | '-h') help ;;
'--no-quiet'* | '--quiet'* | '--no-verbose'* | '--verbose'*) ;; # handled by echo-quiet
'--no-confirm'* | '--confirm'*)
confirm="$(get-flag-value confirm --missing="$confirm" -- "$item" | echo-affirmative)"
option_confirm="$(get-flag-value confirm --missing="$option_confirm" -- "$item" | echo-affirmative)"
;;
'--no-sudo'* | '--sudo'*)
sudo="$(get-flag-value sudo --missing="$sudo" -- "$item" | echo-affirmative)"
option_sudo="$(get-flag-value sudo --missing="$option_sudo" -- "$item" | echo-affirmative)"
;;
'--user='*) option_user="${item#*--user=}" ;;
'--group='*) option_group="${item#*--group=}" ;;
'--')
paths+=("$@")
option_paths+=("$@")
shift $#
break
;;
'--'*) help "An unrecognised flag was provided: $item" ;;
*) paths+=("$item") ;;
*) option_paths+=("$item") ;;
esac
done

# check
if test "${#paths[@]}" -eq 0; then
if test "${#option_paths[@]}" -eq 0; then
help "No <paths> were provided."
fi

Expand All @@ -67,11 +71,13 @@ function fs-rm() (
# =====================================
# Action

function maybe_sudo {
if test "$sudo" = 'yes'; then
sudo-helper --inherit -- "$@"
function eval_wrapper {
if test "$option_sudo" = 'yes' -o -n "$option_user" -o -n "$option_group"; then
eval-helper --no-quiet --wrap \
-- sudo-helper --inherit --user="$option_user" --group="$option_group" \
-- "$@"
else
"$@"
eval-helper --no-quiet --wrap -- "$@"
fi
}

Expand All @@ -80,7 +86,7 @@ function fs-rm() (

# note its structure and size
echo
maybe_sudo eval-helper --no-quiet --wrap -- ls -la "$path"
eval_wrapper ls -la "$path"
echo

# confirm their removal
Expand All @@ -93,11 +99,11 @@ function fs-rm() (

# note its structure and size
echo
maybe_sudo eval-helper --no-quiet --wrap -- ls -la "$path"
eval_wrapper ls -la "$path"
echo
maybe_sudo eval-helper --no-quiet --wrap -- dust --no-percent-bars "$path"
eval_wrapper dust --no-percent-bars "$path"
echo
maybe_sudo eval-helper --no-quiet --wrap -- dust --no-percent-bars --filecount "$path"
eval_wrapper dust --no-percent-bars --filecount "$path"
echo

# confirm their removal
Expand All @@ -111,7 +117,7 @@ function fs-rm() (
export title conclusion=''
path="$(fs-absolute -- "$path" || echo-quote "$path")"
title="fs-rm $path"
if test "$quiet" != 'yes'; then
if test "$option_quiet" != 'yes'; then
echo-segment --h2="$title"
conclusion="$(
echo-style --red="failed to remove."
Expand Down Expand Up @@ -139,8 +145,8 @@ function fs-rm() (
# path exists

# delete empty directories
if test "$confirm" = 'no' || do_confirm_trim "$path"; then
maybe_sudo find "$path" -empty -type d -delete || :
if test "$option_confirm" = 'no' || do_confirm_trim "$path"; then
eval_wrapper find "$path" -empty -type d -delete || :
if test ! -e "$path"; then
conclusion="$(
echo-style --green="was only empty directories, it has been removed."
Expand All @@ -151,8 +157,8 @@ function fs-rm() (
# there are leftovers

# confirm and remove, or no confirm and remove
if test "$confirm" = 'no' || do_confirm_removal "$path"; then
maybe_sudo rm -rfv "$path" || :
if test "$option_confirm" = 'no' || do_confirm_removal "$path"; then
eval_wrapper rm -rfv "$path" || :
# || : as we detect successful removal below
fi

Expand All @@ -172,7 +178,7 @@ function fs-rm() (

# act with wrapping of success
local path
for path in "${paths[@]}"; do
for path in "${option_paths[@]}"; do
act "$path"
done
)
Expand Down
53 changes: 38 additions & 15 deletions commands/mount-helper
Original file line number Diff line number Diff line change
Expand Up @@ -931,12 +931,6 @@ function mount-helper() (
fstab_source="$(echo-fstab-encode "$option_share")"
fi

# validate
if ! gocryptfs-helper verify -- "$gocryptfs_source" "--user=$option_user" "--group=$option_group"; then
echo-error "Failed to verify gocryptfs mount source: $gocryptfs_source"
return 22 # Invalid argument
fi

if test -n "$option_target"; then # optional under [check]
# gocryptfs
gocryptfs_cmd=(
Expand Down Expand Up @@ -1128,11 +1122,33 @@ function mount-helper() (
if test "$uses_root_for_mount" = 'yes'; then
mounting_cmd+=("${root_cmd[@]}")
mkdir_cmd+=("${root_cmd[@]}")
rm_cmd+=("${root_cmd[@]}")
rm_cmd+=(
fs-rm
--sudo
--
"$option_target"
)
elif test "$uses_ownership" = 'yes'; then
mounting_cmd+=("${owner_cmd[@]}")
mkdir_cmd+=("${owner_cmd[@]}")
rm_cmd+=("${owner_cmd[@]}")

rm_cmd+=('fs-rm')
if test -n "$option_user"; then
rm_cmd+=("--user=$option_user")
fi
if test -n "$option_group"; then
rm_cmd+=("--group=$option_group")
fi
rm_cmd+=(
--
"$option_target"
)
else
rm_cmd+=(
fs-rm
--
"$option_target"
)
fi
if test "$uses_ownership" = 'yes'; then
exists_cmd+=("${owner_cmd[@]}")
Expand Down Expand Up @@ -1166,11 +1182,6 @@ function mount-helper() (
-p
"$option_target"
)
rm_cmd+=(
fs-rm
--
"$option_target"
)
if is-mac; then
unmount_cmd+=(
umount
Expand Down Expand Up @@ -1384,6 +1395,7 @@ function mount-helper() (
shared_check_status+='[type-unknown]'
fi
if test -n "$check_source"; then
found="$(scan "$haystack" "$check_source")"
if test -n "$found"; then
shared_check_status+='[source-found]'
echo-style --positive="matching source: " --invert="$check_source" $'\n' --code="$found"
Expand Down Expand Up @@ -1468,7 +1480,7 @@ function mount-helper() (
# echo-style --notice="will prepare..."
break
elif [[ $local_check_status == *'[source-found][target-found][valid]'* ]]; then # needs both as unmounting with only --target and no source information is still [valid]
echo-style --positive="Source already mounted to target."
echo-style --positive="Correct source is mounted to correct target."
# if the goal is mounting, then check if they want to remount
if test "$option_remount" = 'yes'; then
# remount
Expand All @@ -1482,6 +1494,9 @@ function mount-helper() (
echo-style --warning="will exit..."
return 98 # EADDRINUSE 98 Address already in use
fi
elif test "$goal" = 'unmount'; then
# goal is to unmount, so continue with unmount
true
else
# already mounted, remount?
confirm_ec=0 && confirm --negative --ppid=$$ -- 'Do you wish to unmount to enable remounting?' || confirm_ec="$?"
Expand Down Expand Up @@ -1551,7 +1566,7 @@ function mount-helper() (
# cleaning
echo-style --notice='Cleaning target...' ' ' --invert="$option_target"
if "${exists_cmd[@]}"; then
"${rm_cmd[@]}"
eval-helper --no-quiet --wrap -- "${rm_cmd[@]}"
fi
if "${exists_cmd[@]}"; then
echo-style --warning='Failed to clean...'
Expand Down Expand Up @@ -1588,6 +1603,14 @@ function mount-helper() (
return "$unmount_ec"
fi

# validate here, as validating earlier can fail if the gocryptfs vault is inside a nested mount that is not moutned yet, and we just want to make sure that it is unmounted
if test -n "$gocryptfs_source"; then
if ! gocryptfs-helper verify -- "$gocryptfs_source" --user="$option_user" --group="$option_group"; then
echo-error "Failed to verify gocryptfs mount source: $gocryptfs_source"
return 22 # Invalid argument
fi
fi

# segment
echo-segment --h2='mount'

Expand Down

0 comments on commit c0efbea

Please sign in to comment.