duplication bug fix
authorThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Thu, 25 Sep 2025 11:56:49 +0000 (11:56 +0000)
committerThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Thu, 25 Sep 2025 11:56:49 +0000 (11:56 +0000)
developer/source/mount/masu__map_own_all.sh
developer/source/mount/masu__subu_dir_list.sh
developer/source/mount/masu_subu__map_own.sh

index 79d035b..8e14329 100755 (executable)
@@ -1,24 +1,27 @@
+# masu__map_own_all.sh
 #!/bin/bash
+set -euo pipefail
+masu="${1:?Usage: $0 <masu> [--suid=subu1,subu2] }"
+suid_list="${2-}"  # optional: --suid=a,b,c
 
-# Check if the correct number of arguments is passed
-if [ $# -ne 1 ]; then
-  echo "Usage: $0 <username>"
-  exit 1
-fi
+# Build a set for quick membership checks
+want_suid() {
+  [[ -n "$suid_list" ]] || return 1
+  [[ "$suid_list" =~ ^--suid= ]] || return 1
+  IFS=',' read -r -a arr <<< "${suid_list#--suid=}"
+  for n in "${arr[@]}"; do [[ "$n" == "$1" ]] && return 0; done
+  return 1
+}
 
-user=$1
+subus=$(./masu__subu_dir_list.sh "$masu")
+[[ -n "$subus" ]] || { echo "No sub-users found for $masu"; exit 1; }
 
-# Get the list of sub-users by calling the user_list_subu_home.sh script
-subu_list=$(./masu__subu_dir_list.sh "$user")
-
-# Check if we received any sub-users
-if [ -z "$subu_list" ]; then
-  echo "No sub-users found for $user."
-  exit 1
-fi
-
-# Loop through the sub-users and call user_open_subu.sh for each
-for subu in $subu_list; do
-  echo "Opening sub-user: $subu"
-  ./masu_subu__map_own.sh "$user" "$subu"
-done
+while IFS= read -r s; do
+  [[ -n "$s" ]] || continue
+  echo "Opening sub-user: $s"
+  if want_suid "$s"; then
+    sudo ./masu_subu__map_own.sh "$masu" "$s" --suid
+  else
+    sudo ./masu_subu__map_own.sh "$masu" "$s"
+  fi
+done <<< "$subus"
index 6b24a53..b05af66 100755 (executable)
@@ -1,23 +1,15 @@
+# masu__subu_dir_list.sh
 #!/bin/bash
+set -euo pipefail
+user="${1:?usage: $0 <masu>}"
 
-# Function to list sub-users in /home/<user>/subu
-subu_list() {
-  local user=$1
-  local subu_dir="/home/$user/subu"
+# Prefer the /home/<masu>/subu view; if empty/nonexistent, fall back to subu_data.
+list_from_dir() { local d="$1"; [[ -d "$d" ]] && find "$d" -mindepth 1 -maxdepth 1 -type d -printf '%f\n' || true; }
 
-  if [ ! -d "/home/$user" ]; then
-    echo "Error: /home/$user does not exist!"
-    return 1
-  fi
+candidates="$(
+  list_from_dir "/home/$user/subu"
+  [[ -d "/home/$user/subu" && -n "$(ls -A /home/$user/subu 2>/dev/null || true)" ]] || list_from_dir "/home/$user/subu_data"
+)"
 
-  if [ ! -d "$subu_dir" ]; then
-    echo "Error: $subu_dir does not exist!"
-    return 1
-  fi
-
-  # List all sub-users in the subu directory
-  find "$subu_dir" -maxdepth 1 -mindepth 1 -type d -exec basename {} \;
-}
-
-# Run the function with the user as an argument
-subu_list "$1"
+# Unique, stable order
+printf '%s\n' "$candidates" | LC_ALL=C sort -u
index d6820e5..319437c 100755 (executable)
@@ -1,92 +1,62 @@
+# masu_subu__map_own.sh
 #!/bin/bash
-# masu_subu__map_own.sh <user> <subu> [--suid]
-#
-# Examples:
-#   sudo ./masu_subu__map_own.sh Thomas developer
-#   sudo ./masu_subu__map_own.sh Thomas developer --suid
-
+# usage: sudo ./masu_subu__map_own.sh <masu> <subu> [--suid]
 set -euo pipefail
 
-need() { command -v "$1" >/dev/null 2>&1 || { echo "missing: $1" >&2; exit 1; }; }
-
-subu_bind() {
-  local user="$1"
-  local subu="$2"
-  local want_suid="${3-}"   # optional third arg
-
-  need bindfs
-  need findmnt
-  need mountpoint
-
-  # identities
-  local master_user_name="$user"
-  local master_group="$user"
-  local subu_user_name="${user}-${subu}"
-  local subu_group="${user}-${subu}"
-
-  id "$master_user_name" &>/dev/null || { echo "Error: user '$master_user_name' not found!" >&2; return 1; }
-  id "$subu_user_name"   &>/dev/null || { echo "Error: sub-user '$subu_user_name' not found!"   >&2; return 1; }
-
-  # paths
-  local subu_data_path="/home/$user/subu_data/$subu"
-  local subu_mount_point_path="/home/$user/subu/$subu"
-
-  [[ -d "$subu_data_path" ]] || { echo "Error: source dir '$subu_data_path' does not exist!" >&2; return 1; }
-  mkdir -p "$subu_mount_point_path"
-
-  # desired options
-  local base_opts="allow_other,default_permissions,exec"
-  local opts="$base_opts,nosuid"
-  if [[ "$want_suid" == "--suid" ]]; then
-    opts="$base_opts,suid"
+need(){ command -v "$1" >/dev/null 2>&1 || { echo "missing: $1" >&2; exit 1; }; }
+
+want_suid=0
+case "${3-}" in
+  --suid) want_suid=1 ;;
+  "" ) ;;
+  * ) echo "unknown option: $3" >&2; exit 2 ;;
+esac
+
+masu="${1:?usage: $0 <masu> <subu> [--suid] }"
+subu="${2:?usage: $0 <masu> <subu> [--suid] }"
+
+need bindfs; need findmnt; need mountpoint; id "$masu" >/dev/null
+id "${masu}-${subu}" >/dev/null
+
+src="/home/$masu/subu_data/$subu"
+tgt="/home/$masu/subu/$subu"
+[[ -d "$src" ]] || { echo "Error: source dir '$src' does not exist" >&2; exit 1; }
+mkdir -p "$tgt"
+
+base_opts="allow_other,default_permissions,exec"
+desired_opts="$base_opts,$([[ $want_suid -eq 1 ]] && echo suid || echo nosuid)"
+map_opt="--map=${masu}-${subu}/${masu}:@${masu}-${subu}/@${masu}"
+
+opts_have() { grep -qw "$1"; }
+
+# Peel off incorrect layers until either:
+#  - nothing is mounted on $tgt, or
+#  - the top-most layer is a bindfs of $src with desired opts
+while mountpoint -q "$tgt"; do
+  read -r FSTYPE SOURCE OPTIONS < <(findmnt -T "$tgt" -no FSTYPE,SOURCE,OPTIONS)
+  if [[ "$FSTYPE" != fuse*bindfs* && "$FSTYPE" != fuse.bindfs && "$FSTYPE" != fuse3.bindfs ]]; then
+    echo "⚠︎ '$tgt' is a mountpoint but not bindfs (fstype=$FSTYPE); unmounting this layer…"
+    umount "$tgt" || umount -l "$tgt" || true
+    continue
   fi
 
-  # map rule
-  local map_opt="--map=${subu_user_name}/${master_user_name}:@${subu_group}/@${master_group}"
-
-  # check if *this path* is already a mountpoint
-  if mountpoint -q "$subu_mount_point_path"; then
-    # only care about a few options, avoid brittle whole-string compare
-    local current_opts
-    current_opts="$(findmnt -no OPTIONS -T "$subu_mount_point_path" 2>/dev/null || true)"
-
-    have_exec=$(grep -qw exec <<<"$current_opts" && echo 1 || echo 0)
-    have_suid=$(grep -qw suid <<<"$current_opts" && echo 1 || echo 0)
-    have_nosuid=$(grep -qw nosuid <<<"$current_opts" && echo 1 || echo 0)
-    have_allow=$(grep -qw allow_other <<<"$current_opts" && echo 1 || echo 0)
-
-    want_suid_flag=$([[ "$want_suid" == "--suid" ]] && echo 1 || echo 0)
-
-    needs_change=0
-    [[ $have_exec -eq 1 ]] || needs_change=1
-    [[ $have_allow -eq 1 ]] || needs_change=1
-    if [[ $want_suid_flag -eq 1 ]]; then
-      [[ $have_suid -eq 1 && $have_nosuid -eq 0 ]] || needs_change=1
-    else
-      [[ $have_nosuid -eq 1 && $have_suid -eq 0 ]] || needs_change=1
-    fi
-
-    if [[ $needs_change -eq 1 ]]; then
-      echo "remounting $subu_mount_point_path with opts: $opts"
-      umount "$subu_mount_point_path" || { echo "⚠︎ umount failed; trying lazy"; umount -l "$subu_mount_point_path" || true; }
-      bindfs -o "$opts" $map_opt "$subu_data_path" "$subu_mount_point_path"
-    else
-      echo "already mounted with compatible options: $current_opts"
-    fi
-  else
-    echo "mounting $subu_data_path -> $subu_mount_point_path with opts: $opts"
-    bindfs -o "$opts" $map_opt "$subu_data_path" "$subu_mount_point_path"
+  # Normalize desired
+  want_suid_kw=$([[ $want_suid -eq 1 ]] && echo suid || echo nosuid)
+  # Check source and essential flags without brittle full-string compare
+  if [[ "$SOURCE" == "$src" ]] \
+     && opts_have <<<"$OPTIONS" allow_other \
+     && opts_have <<<"$OPTIONS" exec \
+     && opts_have <<<"$OPTIONS" "$want_suid_kw" \
+     && ! opts_have <<<"$OPTIONS" "$([[ $want_suid -eq 1 ]] && echo nosuid || echo suid)"; then
+    echo "already mounted OK: $tgt ← $src ($OPTIONS)"
+    exit 0
   fi
 
-  # verify
-  findmnt "$subu_mount_point_path" -o TARGET,FSTYPE,OPTIONS
-  echo "OK: $subu_data_path -> $subu_mount_point_path"
-  if [[ "$want_suid" == "--suid" ]]; then
-    echo "note: suid is ENABLED; setuid binaries (e.g., the gasket) can take effect on this mount."
-  else
-    echo "note: nosuid (default) — setuid will NOT take effect on this mount."
-  fi
-}
+  echo "unmounting incorrect layer on $tgt (src=$SOURCE opts=$OPTIONS)…"
+  umount "$tgt" || umount -l "$tgt" || true
+done
 
-# run (sudo not needed if already root)
-subu_bind "${1:-}" "${2:-}" "${3:-}"
+echo "mounting $src -> $tgt  (opts: $desired_opts)"
+bindfs -o "$desired_opts" $map_opt "$src" "$tgt"
+findmnt "$tgt" -o TARGET,SOURCE,FSTYPE,OPTIONS
+echo "OK"