File no-hardcoded-deck.patch of Package jupiter-hw-support
diff --git a/usr/bin/steamos-polkit-helpers/steamos-priv-write b/usr/bin/steamos-polkit-helpers/steamos-priv-write
index 9278a2d..13d6f27 100755
--- a/usr/bin/steamos-polkit-helpers/steamos-priv-write
+++ b/usr/bin/steamos-polkit-helpers/steamos-priv-write
@@ -3,11 +3,36 @@
set -euo pipefail
shopt -s nullglob
+usage() {
+ echo "Usage: $0 [--owner <uid>:<gid>] <path> <value>"
+ exit 1
+}
+
if [[ $EUID -ne 0 ]];
then
- exec pkexec --disable-internal-agent "$0" "$@"
+ gid="$(id -g "$UID")"
+ exec pkexec --disable-internal-agent "$0" --owner "$UID:$gid" "$@"
fi
+OWNER_GID=""
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --owner)
+ [ $# -ge 2 ] || usage
+ owner="$2"
+ OWNER_GID="${owner##*:}"
+ shift 2
+ ;;
+ --) shift; break ;;
+ *) break ;;
+ esac
+done
+
+[ $# -eq 2 ] || usage
+
+[ -n "$OWNER_GID" ] || { echo "Missing --owner (expected UID:GID)"; exit 1; }
+[[ "$OWNER_GID" =~ ^[0-9]+$ ]] || { echo "Invalid --owner (expected UID:GID)"; exit 1; }
+
WRITE_PATH=$(realpath -s -- "$1")
WRITE_VALUE="$2"
@@ -42,7 +67,7 @@ function CommitWrite()
printf "%s" "$WRITE_VALUE" > "$WRITE_PATH"
fi
- chgrp deck "$WRITE_PATH"
+ chgrp "$OWNER_GID" "$WRITE_PATH"
chmod g+w "$WRITE_PATH"
exit 0
}
diff --git a/usr/lib/hwsupport/block-device-event.sh b/usr/lib/hwsupport/block-device-event.sh
index 7023aa5..41211c3 100755
--- a/usr/lib/hwsupport/block-device-event.sh
+++ b/usr/lib/hwsupport/block-device-event.sh
@@ -13,6 +13,33 @@ usage()
exit 1
}
+get_active_gui_user()
+{
+ local sid uid user seat active remote type
+
+ # list-sessions output
+ while read -r sid uid user seat _; do
+ active=$(loginctl show-session "$sid" -p Active --value 2>/dev/null || echo no)
+ remote=$(loginctl show-session "$sid" -p Remote --value 2>/dev/null || echo yes)
+ type=$(loginctl show-session "$sid" -p Type --value 2>/dev/null || echo "")
+ seat=$(loginctl show-session "$sid" -p Seat --value 2>/dev/null || echo "")
+
+ # Prefer the active, local graphical session on seat0
+ if [[ "$active" == "yes" && "$remote" == "no" && "$seat" == "seat0" ]] && \
+ [[ "$type" == "wayland" || "$type" == "x11" ]]; then
+ echo "$user"
+ return 0
+ fi
+ done < <(loginctl list-sessions --no-legend 2>/dev/null)
+
+ return 1
+}
+
+get_fallback_user()
+{
+ getent passwd 1000 | cut -d: -f1 | head -n1
+}
+
is_os_partition ()
{
local -r dev="/dev/${DEVBASE}"
@@ -89,7 +116,16 @@ do_add()
fi
fi
- /usr/libexec/hwsupport/steamos-automount.sh add "${DEVBASE}"
+ local user
+ user="$(get_active_gui_user || true)"
+ if [[ -z "$user" ]]; then
+ user="$(get_fallback_user || true)"
+ fi
+ if [[ -z "$user" ]]; then
+ exit 0
+ fi
+
+ /usr/libexec/hwsupport/steamos-automount.sh --user "$user" add "${DEVBASE}"
}
do_remove()
diff --git a/usr/lib/hwsupport/format-device.sh b/usr/lib/hwsupport/format-device.sh
index 21ca5a7..bd86f67 100755
--- a/usr/lib/hwsupport/format-device.sh
+++ b/usr/lib/hwsupport/format-device.sh
@@ -41,8 +41,21 @@ if [[ "$#" -gt 0 ]]; then
echo "Unknown option $1"; exit 22
fi
+if [[ ! "$OWNER" =~ ^[0-9]+:[0-9]+$ ]]; then
+ echo "Invalid --owner '$OWNER' (expected <uid>:<gid>)"
+ exit 22
+fi
+
EXTENDED_OPTIONS="$EXTENDED_OPTIONS,root_owner=$OWNER"
+OWNER_UID="${OWNER%%:*}"
+
+OWNER_USER="$(getent passwd "$OWNER_UID" | cut -d: -f1 || true)"
+if [[ -z "$OWNER_USER" ]]; then
+ echo "Could not resolve username for UID $OWNER_UID"
+ exit 22
+fi
+
# We only support SD/MMC and USB mass-storage devices
case "$STORAGE_DEVICE" in
"")
@@ -76,12 +89,12 @@ fi
# If any partitions on the device are mounted, unmount them before continuing
# to prevent problems later
-lsblk -n "$STORAGE_DEVICE" -o MOUNTPOINTS | awk NF | sort -u | while read m; do
+while read -r m; do
if ! umount "$m"; then
echo "Failed to unmount filesystem: $m"
exit 32 # EPIPE
fi
-done
+done < <(lsblk -n "$STORAGE_DEVICE" -o MOUNTPOINTS | awk NF | sort -u)
# Test the sdcard
# Some fake cards advertise a larger size than their actual capacity,
@@ -137,7 +150,7 @@ mkfs.ext4 -m 0 -O casefold -E "$EXTENDED_OPTIONS" "${EXTRA_MKFS_ARGS[@]}" -F "$S
udevadm settle
# Mount the device
-if ! /usr/libexec/hwsupport/steamos-automount.sh add "$STORAGE_PARTBASE"; then
+if ! /usr/libexec/hwsupport/steamos-automount.sh --user "$OWNER_USER" add "$STORAGE_PARTBASE"; then
echo "Failed to mount ${STORAGE_PARTBASE}"
exit 5
fi
diff --git a/usr/lib/hwsupport/steamos-automount.sh b/usr/lib/hwsupport/steamos-automount.sh
index af0dca4..52ccecc 100755
--- a/usr/lib/hwsupport/steamos-automount.sh
+++ b/usr/lib/hwsupport/steamos-automount.sh
@@ -11,35 +11,67 @@ set -euo pipefail
usage()
{
- echo "Usage: $0 {add|remove} device_name (e.g. sdb1)"
+ echo "Usage: $0 [--user USER] {add|remove} device_name (e.g. sdb1)"
exit 1
}
-if [[ $# -ne 2 ]]; then
- usage
-fi
+USER_NAME=""
+
+# simple option parsing
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --user)
+ [ $# -ge 2 ] || usage
+ USER_NAME="$2"
+ shift 2
+ ;;
+ --) shift; break;;
+ -*) usage;;
+ *) break;;
+ esac
+done
+
+[ $# -eq 2 ] || usage
ACTION=$1
DEVBASE=$2
DEVICE="/dev/${DEVBASE}"
-DECK_UID=$(id -u deck)
-DECK_GID=$(id -g deck)
+TARGET_UID=""
+TARGET_GID=""
+
send_steam_url()
{
local command="$1"
local arg="$2"
- local encoded=$(urlencode "$arg")
- if pgrep -x "steam" > /dev/null; then
- # TODO use -ifrunning and check return value - if there was a steam process and it returns -1, the message wasn't sent
- # need to retry until either steam process is gone or -ifrunning returns 0, or timeout i guess
- systemd-run -M ${DECK_UID}@ --user --collect --wait sh -c "./.steam/root/ubuntu12_32/steam steam://${command}/${encoded@Q}"
- echo "Sent URL to steam: steam://${command}/${arg} (steam://${command}/${encoded})"
- else
+ local encoded home steam_bin
+
+ encoded="$(urlencode "$arg")"
+
+ # If Steam isn't running for that user, don't bother
+ if ! pgrep -u "$TARGET_UID" -x "steam" > /dev/null; then
echo "Could not send steam URL steam://${command}/${arg} (steam://${command}/${encoded}) -- steam not running"
+ return 0
+ fi
+
+ home="$(getent passwd "$USER_NAME" | cut -d: -f6 || true)"
+ if [[ -z "$home" ]]; then
+ echo "Could not determine home for user '$USER_NAME'; skipping steam URL"
+ return 0
fi
+
+ steam_bin="$home/.steam/root/ubuntu12_32/steam"
+ if [[ ! -x "$steam_bin" ]]; then
+ echo "Steam binary not found at $steam_bin; skipping steam URL"
+ return 0
+ fi
+
+ systemd-run -M "${TARGET_UID}@" --user --collect --wait "$steam_bin" "steam://${command}/${encoded}"
+
+ echo "Sent URL to steam: steam://${command}/${arg} (steam://${command}/${encoded})"
}
+
# From https://gist.github.com/HazCod/da9ec610c3d50ebff7dd5e7cac76de05
urlencode()
{
@@ -53,6 +85,9 @@ do_mount()
readonly FSCK_ERROR=1
readonly MOUNT_ERROR=2
+ TARGET_UID="$(id -u "$USER_NAME")" || exit 1
+ TARGET_GID="$(id -g "$USER_NAME")" || exit 1
+
# Get info for this drive: $ID_FS_LABEL, and $ID_FS_TYPE
dev_json=$(lsblk -o PATH,LABEL,FSTYPE --json -- "$DEVICE" | jq '.blockdevices[0]')
ID_FS_LABEL=$(jq -r '.label | select(type == "string")' <<< "$dev_json")
@@ -71,7 +106,6 @@ do_mount()
echo "Error mounting ${DEVICE}: wrong fstype: ${ID_FS_TYPE} - ${dev_json}"
exit 2
fi
-
# Try to repair the filesystem if it's known to have errors.
# ret=0 means no errors, 1 means that errors were corrected.
# In all other cases we try to mount the fs read-only and report an error.
@@ -90,12 +124,12 @@ do_mount()
"block_devices/${DEVBASE}" \
Filesystem Mount \
'a{sv}' 3 \
- as-user s deck \
+ as-user s "$USER_NAME" \
auth.no_user_interaction b true \
options s "$OPTS")
- # Ensure that the deck user can write to the root directory
- if ! setpriv --clear-groups --reuid "${DECK_UID}" --regid "${DECK_GID}" test -w "${mount_point}"; then
+ # Ensure that the user can write to the root directory
+ if ! setpriv --clear-groups --reuid "${TARGET_UID}" --regid "${TARGET_GID}" test -w "${mount_point}"; then
chmod 777 "${mount_point}" || true
fi
@@ -132,6 +166,7 @@ do_unmount()
case "${ACTION}" in
add)
+ [ -n "$USER_NAME" ] || usage
do_mount
;;
remove)