Code Snippet

Date: 2025-04-21
From: D-Bus Drifting For User-Land Persistence
Language: bash
Title: dbus-path-proof.sh
#!/bin/bash

# Function to normalize path (remove trailing slash)
normalize_path() {
    echo "${1%/}"
}

# ANSI color codes
RED='\033[0;31m'
NC='\033[0m' # No Color

# Function to check if user can write to a directory or its parent
check_path_write_access() {
    local dir="$1"
    local priority="$2"
    
    if [ -d "$dir" ]; then
        # Directory exists
        if [ -w "$dir" ]; then
            echo -e "${priority}. ${RED}$dir${NC} (exists, writable)"
        else
            echo -e "${priority}. $dir (exists, not writable)"
        fi
    else
        # Directory doesn't exist, check parent
        local parent_dir=$(dirname "$dir")
        if [ -d "$parent_dir" ]; then
            if [ -w "$parent_dir" ]; then
                echo -e "${priority}. ${RED}$dir${NC} (doesn't exist, can be created)"
            else
                echo -e "${priority}. $dir (doesn't exist, parent not writable)"
            fi
        else
            echo -e "${priority}. $dir (doesn't exist, parent also doesn't exist)"
        fi
    fi
}

# Path definitions
echo "D-Bus service file search paths:"

# Path 1
RUNTIME_PATH=""
if [ -n "$XDG_RUNTIME_DIR" ]; then
    RUNTIME_PATH="$(normalize_path "$XDG_RUNTIME_DIR")/dbus-1/services"
    echo "1. $RUNTIME_PATH"
fi

# Path 2
XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
DATA_HOME_PATH="$(normalize_path "$XDG_DATA_HOME")/dbus-1/services"
echo "2. $DATA_HOME_PATH"

# Path 3
XDG_DATA_DIRS="${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
echo "3. Directories from XDG_DATA_DIRS:"
IFS=':'
data_dirs_paths=()
for dir in $XDG_DATA_DIRS; do
    normalized_dir="$(normalize_path "$dir")/dbus-1/services"
    echo "   $normalized_dir"
    data_dirs_paths+=("$normalized_dir")
done

# Path 4
USR_SHARE_PATH="/usr/share/dbus-1/services"
echo "4. $USR_SHARE_PATH"

# Check all paths with priorities and write permissions
echo -e "\nAll paths with their priorities and write permissions:"

# Check path 1
if [ -n "$XDG_RUNTIME_DIR" ]; then
    check_path_write_access "$RUNTIME_PATH" 1
fi

# Check path 2
check_path_write_access "$DATA_HOME_PATH" 2

# Check paths from XDG_DATA_DIRS (path 3)
sub_priority=0
for path in "${data_dirs_paths[@]}"; do
    sub_priority=$((sub_priority + 1))
    priority_string="3.$sub_priority"
    check_path_write_access "$path" "$priority_string"
done

# Check path 4 if not already listed in XDG_DATA_DIRS
if ! [[ " ${data_dirs_paths[*]} " =~ " $USR_SHARE_PATH " ]]; then
    check_path_write_access "$USR_SHARE_PATH" 4
fi

# Summary section - provide recommendations
echo -e "\nRecommendations:"
# Find highest priority writable path
if [ -n "$XDG_RUNTIME_DIR" ]; then
    parent_runtime=$(dirname "$RUNTIME_PATH")
    if [ -d "$RUNTIME_PATH" ] && [ -w "$RUNTIME_PATH" ]; then
        echo -e "- Highest priority writable path: ${RED}$RUNTIME_PATH${NC} (priority 1)"
        echo "  Note: This path is temporary and cleared on logout/reboot"
    elif [ -d "$parent_runtime" ] && [ -w "$parent_runtime" ]; then
        echo -e "- Highest priority path that can be created: ${RED}$RUNTIME_PATH${NC} (priority 1)"
        echo "  Note: This path is temporary and cleared on logout/reboot"
    elif [ -d "$DATA_HOME_PATH" ] && [ -w "$DATA_HOME_PATH" ]; then
        echo -e "- Highest priority writable path: ${RED}$DATA_HOME_PATH${NC} (priority 2)"
        echo "  Note: This path persists across reboots"
    else
        parent_data_home=$(dirname "$DATA_HOME_PATH")
        if [ -d "$parent_data_home" ] && [ -w "$parent_data_home" ]; then
            echo -e "- Highest priority path that can be created: ${RED}$DATA_HOME_PATH${NC} (priority 2)"
            echo "  Note: This path persists across reboots"
        fi
    fi
fi

echo -e "- For persistent services that survive reboots, use: ${RED}$DATA_HOME_PATH${NC}"
echo -e "- For temporary services for the current session only, use: ${RED}$RUNTIME_PATH${NC}"
echo "- After adding a service file, you may need to run: dbus-send --session --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.ReloadConfig"
| View Source