#!/usr/bin/env bash # --- CONFIGURATION --- # 1. Give your profile a distinct, single-word name (NO spaces) PROFILE_NAME="SharedProfile" # 2. Define exactly where the folder should live PROFILE_DIR="$HOME/network_drives/home/.mozilla/shared_profile" # Detect OS to set the correct Firefox binary path if [[ "$OSTYPE" == "darwin"* ]]; then FIREFOX_BIN="/Applications/Firefox.app/Contents/MacOS/firefox" LOCK_FILE="$PROFILE_DIR/.parentlock" else FIREFOX_BIN="firefox" # Assumes 'firefox' is in your system PATH on Linux LOCK_FILE="$PROFILE_DIR/lock" fi # --------------------- # Ensure the parent directory folder physically exists first mkdir -p "$PROFILE_DIR" # Check if the folder is empty/doesn't exist if [ ! -d "$PROFILE_DIR" ] || [ -z "$(ls -A "$PROFILE_DIR")" ]; then echo "[INFO] Profile not found or empty. Forcing registration via Firefox CLI..." # Modern Firefox fix: We use -CreateProfile paired with a dummy screenshot # to force Firefox to write the directory structure and exit cleanly. $FIREFOX_BIN -CreateProfile "$PROFILE_NAME $PROFILE_DIR" --headless --screenshot /dev/null > /dev/null 2>&1 echo "[SUCCESS] Profile '$PROFILE_NAME' registered at: $PROFILE_DIR" else echo "[INFO] Profile folder already exists. Skipping creation step." fi SIGNAL_FILE="$PROFILE_DIR/remote_shutdown.signal" # --- NEW NETWORK-SAFE LOCK DETECTION LOGIC --- echo "[INFO] Scanning for active network locks..." # Force network share to drop local metadata cache ls -la "$PROFILE_DIR" > /dev/null 2>&1 ACTIVE_LOCK_FOUND=false # Check all 3 potential lock names for POSSIBLE_LOCK in "lock" ".parentlock" "parent.lock"; do TARGET_LOCK_PATH="$PROFILE_DIR/$POSSIBLE_LOCK" if [ -e "$TARGET_LOCK_PATH" ] || [ -L "$TARGET_LOCK_PATH" ]; then # FIXED: We use -newermt to see if the lock was touched within the last 25 seconds. # This operates natively across Linux/Mac and accepts precise time strings safely. IS_ACTIVE=$(find "$TARGET_LOCK_PATH" -newermt '25 seconds ago' 2>/dev/null) if [ -n "$IS_ACTIVE" ]; then echo "[WARN] Active remote lock verified: $POSSIBLE_LOCK (Modified within last 25s)" ACTIVE_LOCK_FOUND=true break else echo "[INFO] Stale lock ignored: $POSSIBLE_LOCK (Not modified recently)" fi fi done # Act on our findings if [ "$ACTIVE_LOCK_FOUND" = true ]; then zenity --question \ --title="Firefox Profile Warning" \ --text="This profile is actively running on another computer.\n\nDo you want to send a SHUTDOWN SIGNAL to close the other session remotely?" \ --ok-label="Close Other & Open Here" \ --cancel-label="Cancel Launch" \ --width=420 2>/dev/null if [ $? -eq 0 ]; then echo "[INFO] Creating shutdown signal file..." touch "$SIGNAL_FILE" ( for i in {1..12}; do ls -la "$PROFILE_DIR" > /dev/null 2>&1 # Update the progress tracker loop to use the same -newermt logic STILL_ACTIVE=$(find "$PROFILE_DIR" \( -name "lock" -o -name ".parentlock" -o -name "parent.lock" \) -newermt '25 seconds ago' 2>/dev/null) if [ -z "$STILL_ACTIVE" ]; then echo 100; break fi echo $((i * 8)) sleep 1 done ) | zenity --progress --title="Waiting" --text="Signaling remote session to close cleanly..." --auto-close --width=300 2>/dev/null rm -f "$PROFILE_DIR/lock" "$PROFILE_DIR/.parentlock" "$PROFILE_DIR/parent.lock" "$SIGNAL_FILE" else echo "[INFO] Aborted by user." exit 0 fi fi echo "[INFO] Launching Firefox instance..." # FIX: Added the '&' back to the end of the line so the script can continue # executing the background heartbeat loop while Firefox runs. $FIREFOX_BIN --profile "$PROFILE_DIR" -no-remote > /dev/null 2>&1 & FF_PID=$! # This will now successfully capture Firefox's background PID echo "[INFO] Monitoring session (PID: $FF_PID). Close the window to exit." # --- STEP 3: BACKGROUND MONITORING LOOP WITH HEARTBEAT --- while kill -0 $FF_PID 2>/dev/null; do # 1. Update our local lock file timestamp so other machines know we are alive touch "$PROFILE_DIR/lock" "$PROFILE_DIR/.parentlock" 2>/dev/null # 2. Check for the remote shutdown signal if [ -f "$SIGNAL_FILE" ]; then echo "[SIGNAL] Remote shutdown request received! Closing Firefox..." kill -15 $FF_PID rm -f "$SIGNAL_FILE" wait $FF_PID 2>/dev/null break fi sleep 3 # Heartbeat/check interval every 3 seconds done # Safety wait to ensure the process is fully reaped if closed manually wait $FF_PID 2>/dev/null # Final local cleanup rm -f "$PROFILE_DIR/lock" "$PROFILE_DIR/.parentlock" "$PROFILE_DIR/parent.lock" echo "[INFO] Session closed cleanly." exit 0