#!/bin/bash
# Skript for switching off modem power.

# be verbose
set -x

########## Lockfile Part #####################

sleeptime="1"           # timeout for creating the lockfile
retries="10"		# default number of retries of creating the lockfile: 10 (should be > locktimeout*sleeptime)
locktimeout="5"         # default timeout : 5 s. The lockfile will be removed
                        # by force after locktimeout seconds have passed since the lock”¾
                        # file was last modified/created. Lockfile is clock skew immune.
lockdir="/var/tmp"
lockfile="$lockdir/lockfile.modem" # modem lockfile name

# Eleminate the optional bash call with sed and get this process name from basename.
this_process="$(basename "$(ps -p $$ -o cmd= | sed 's/^[^ ]*bash //')")"


# ascertain whether we have lockf or lockfile system apps
check ()
{
  if [ -z "$(which lockfile | grep -v '^no ')" ] ; then
    echo "$0 failed: 'lockfile' utility not found in PATH." >&2
    exit 1
  fi
}


# make lockifle
lock () 
{
  typeset -i pid=0
  # check if a lockfile is present  
  if [ -f "$lockfile" ]; then 
    # check the PID in the lockfile
    pid="$(cat "$lockfile")"
    if [ $pid -eq 0 ]; then 
      echo "Could not read a valid PID from the lockfile."
      echo "Trying to remove that lockfile"
      echo "$lockfile"
      echo "."
      rm -f "$lockfile"
    else
      if kill -0 $pid 2> /dev/null; then
        echo "The locking executable with pid $pid appears to be already running."
        locking_process="$(basename "$(ps -p $pid -o cmd= | sed 's/^[^ ]*bash //')")"
        # check if the process with the found PID has the name of this skript (run this skript always without /bin/bash)
        #if [ "$locking_process" == "$0" ] ; then
        if [ "$locking_process" == "$this_process" ] ; then
          echo "The locking executable has the same name (without the path) as this script"
	  echo "$this_process"
	  echo "."
	  # check if the process with the found UID
	  if [ $(ps -p $pid -o uid=) == $UID ] ; then
	    echo "The locking process has been created from the same user $UID which is running this script; exiting."
	    exit 1
	  else
            echo "The locking process has been created from the different user"
            echo $(ps -p $pid -o uid=)
	    echo "; the user (UID) of this script is $UID."
	    # If you want to (try to) kill the blocking process, uncomment the following 3 lines.
	    echo "Try to kill this locking process."
  	    kill -9 $pid
	    rm -f "$lockfile"
            echo "Done killing and lockfile deletion."
	    # Maybe in the line before the next fi you should send an email to root@localhost that a user tried (or maybe caused)
	    # a DOS attack and that the blocking process (here undocumented because already killed) was killed.
          fi
        else
          echo "The locking executable"
	  echo "$locking_process"
	  echo "DOES NOT has the same name as this script,"
	  echo "$this_process"
 	  echo "."
  	  echo "Trying to remove that lockfile $lockfile."
	  rm -f "$lockfile"
        fi
      else
        echo "The locking executable with pid $pid has completed or was killed without cleaning up its lockfile"
        echo "or the locking executable has another name than this script or it is run by an other user;"
        echo "removing that lockfile"
        echo "$lockfile"
        echo "."
        rm -f "$lockfile"
      fi
    fi
  fi
  # (try to) create the lockfile; wait 
  if ! lockfile -$sleeptime -r $retries -l $locktimeout "$lockfile" 2> /dev/null; then
    echo "$0: Failed: Couldn't create lockfile in time" >&2
    exit 1
  fi
  chmod u+rw "$lockfile"
  # store the pid
  echo $$ > "$lockfile"
  chmod u-wx "$lockfile"
  # A trap to delete the lockfile when the script gets killed by SIGHUP SIGINT or SIGTERM.
  # In many cases, e. g. a kernel hangup, this does not work and the checks above are necessary.
  trap "rm $lockfile; exit" SIGHUP SIGINT SIGTERM
}


# cleanup
unlock () 
{
  rm -f "$lockfile"
}

#################################

#################### "main" ##############################

echo "Start of main part at"
date | xargs echo

# get the name of this dir
dirname="$(dirname "$0")"
command=relais

# lockfile: first check, then set for locking
check
lock

$dirname/$command /dev/ttyS0 -r1

# wait five seconds; less does not make much sense and during poweroff the lock is needed
sleep 5

unlock

exit 0

