#!/bin/bash
# Created by Alex Simeonov, 08.03.2024, Barix AG
#
# This scripts serves as a proxy between the script
# that is fired by UDEV on a specific rule, and external
# script, that might take possibly long time to finish, ex:
# USB backup task on plug, start stop script one USB prug, etc
# UDEV does not work well with time consuming scripts, because
# it kills them as soon as the UDEV event process is finished.
# For that reason spawning subprocesses using "&", nohup, etc
# will not work
# The officially supported method by UDEV is creating s systemd
# service, but we use SysV, so using named pipes is an easy "IPC
# like" method
# NB! This script just reads the commands from the pipe, and executes
# them as received, so it could be a potential security risk!

pipe=/var/run/udevpipe
UDEV_PROXY_NAME="udev_command_proxy"
LOCKFILE="/var/run/$UDEV_PROXY_NAME".pid

function cleanup() {
    rm -f $pipe
    rm -f $LOCKFILE
}

# create the pipe if not existing
[[ ! -p $pipe ]] && mkfifo $pipe

# check for running instance/lockfile
if [ -e "$LOCKFILE" ]; then
  # lockfile exists
   if [ ! -r "$LOCKFILE" ]; then
      echo error: lockfile is not readable
      exit 1
   fi
   PID=`cat "$LOCKFILE"`
   kill -0 "$PID" 2>/dev/null
   if [ $? == 0 ]; then
      echo error: existing instance of this task is already running
      exit 1
   fi
   # process that created lockfile is no longer running - delete lockfile
   rm -f "$LOCKFILE"
   if [ $? != 0 ]; then
      # error: failed to delete lockfile
      exit 1
   fi
fi

# create the lock file
echo $$ >"$LOCKFILE"
if [ $? != 0 ]; then
  # error: failed to create lockfile
   exit 1
fi

trap cleanup EXIT

while true
do
    if read line <$pipe; then
        if [[ "$line" == 'quit' ]]; then
            break
        fi
        # for debugging only!
	      # echo "$line" > /var/run/udev.log
        eval "$line"
    fi
done

echo "UDEV Command Proxy  exiting ..."

