#!/bin/bash

CONFFILE=/etc/ueventd.conf
PIDFILE=/run/ueventd.pid
RESTART=0
SYSFS=${SYSFS:-/sys}
TRIGGER=0

while getopts :f:p:t OPTION; do
  case $OPTION in
    f)
      CONFFILE=$OPTARG
      ;;
    p)
      PIDFILE=$OPTARG
      ;;
    t)
      TRIGGER=1
      ;;
  esac
done

add() { :; }
change() { :; }
event() { :; }
move() { :; }
offline() { :; }
online() { :; }
remove() { :; }

if [[ ! -f $CONFFILE ]]; then
  exit 0
elif ! source "$CONFFILE"; then
  exit 1
fi

if [[ ${*:$OPTIND} != "-" ]]; then
  if { exec 3>>"$PIDFILE" && flock -n 3; } 2>/dev/null; then
    exec env -i PATH="$PATH" daemon uevent "$0" "${@:1:OPTIND - 1}" -
    rm -f "$PIDFILE"
  else
    echo "Failed to lock $PIDFILE; is ${0##*/} already running?" >&2
  fi
  exit 1
fi

trap 'RESTART=0 && exit' SIGTERM
trap 'RESTART=1 && exit' SIGHUP SIGINT SIGUSR1 SIGUSR2
trap '(( RESTART )) && exec "$0" "$@" || rm -f "$PIDFILE"' EXIT

echo $PPID >"$PIDFILE"
exec 3>&-

if (( TRIGGER )); then
  find $SYSFS/{module,bus,devices} -name uevent -type f \
    | while read UEVENT; do echo change >"$UEVENT"; done
  for (( INDEX = 1; INDEX <= $#; INDEX++ )); do
    [[ ${!INDEX} == "-t" ]] && set -- "${@:1:INDEX - 1}" "${@:INDEX + 1}"
  done
  unset INDEX
fi

declare -A ENV=()
while read -r KEY VALUE; do
  if [[ -n $KEY ]]; then
    ENV[$KEY]=$VALUE
    continue
  fi

  unset ACTION DEVNAME DEVPATH DRIVER INTERFACE KEY SUBSYSTEM SYSPATH VALUE
  [[ -v ENV[ACTION] ]] && ACTION=${ENV[ACTION]}
  [[ -v ENV[DEVNAME] ]] && DEVNAME=${ENV[DEVNAME]}
  [[ -v ENV[DEVPATH] ]] && DEVPATH=${ENV[DEVPATH]}
  [[ -v ENV[DRIVER] ]] && DRIVER=${ENV[DRIVER]}
  [[ -v ENV[INTERFACE] ]] && DRIVER=${ENV[INTERFACE]}
  [[ -v ENV[SUBSYSTEM] ]] && SUBSYSTEM=${ENV[SUBSYSTEM]}
  [[ -v ENV[DEVPATH] ]] && SYSPATH=$SYSFS${ENV[DEVPATH]}

  case $ACTION in
    add | change | move | offline | online | overflow | remove)
      event $ACTION $DEVPATH && $ACTION $DEVPATH
      ;;
  esac
  ENV=()
done
