#!/bin/sh

### BEGIN INIT INFO
# Provides:          linbo-bittorrent
# Required-Start:    $network $local_fs ldap
# Required-Stop:     $network $local_fs
# Should-Start:      
# Should-Stop:       
# Default-Start:     3 5
# Default-Stop:      0 1 6
# Short-Description: Start a complete bittorrent download
# Description:       Starts a complete bittorrent download for LINBO images
### END INIT INFO

# thomas@linuxmuster.net
# 22.03.2015
# GPL v3

#set -e

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="BitTorrent service"
NAME=linbo-bittorrent
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/usr/sbin/linbo-bittorent

# read cmdline
action="$1"
images="$2"
force="$3"

# default values
MINPORT=6881
MAX_UPLOADS=20
MAX_UPLOAD_RATE=0
REREQUEST_INTERVAL=60
MIN_PEERS=20
MAX_INITIATE=20
KEEPALIVE_INTERVAL=120
DOWNLOAD_SLICE_SIZE=131072
REQUEST_BACKLOG=5
MAX_MESSAGE_LENGTH=8388608
TIMEOUT=300
TIMEOUT_CHECK_INTERVAL=60
MAX_RATE_PERIOD=20
UPLOAD_RATE_FUDGE=5
DISPLAY_INTERVAL=1
MAX_SLICE_LENGTH=131072
CLIENT_CONFIG="torrent-client.conf"
SERVERIP=10.0.0.2

# read necessary functions and constants
source /etc/linbo/linbo.conf || exit 1
source $ENVDEFAULTS || exit 1
source $LINBOSHAREDIR/helperfunctions.sh || exit 1
source /lib/lsb/init-functions

DAEMON=$LINBOSHAREDIR/linbo-torrenthelper.sh

# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0

. /lib/lsb/init-functions

# read defaults
source /etc/sysconfig/linbo-bittorrent || exit 1
[ "$START_BITTORRENT" = "1" ] || exit 0
source /etc/sysconfig/bittorrent || exit 1
[ "$START_BTTRACK" = "1" ] || exit 0

# reading server ip
if [ -s /etc/sysconfig/cranix ]; then
 . /etc/sysconfig/cranix
 SERVERIP=${CRANIX_SERVER}
fi

cd $LINBODIR

# check if single image file is given on cmdline
if [ -n "$images" -a "$images" != "all" ]; then
 if [ ! -s "$images" ]; then
  echo "$images does not exist!"
  exit 1
 fi
 omit_killall="yes"
else
 # get all active images from helperfunctions
 images="$(active_images)"
 # add additional files and dirs placed below $LINBODIR/torrentadds
 tadds="$(ls -1 torrentadds/ | grep -v .torrent | sed 's|^|torrentadds/|')"
 [ -n "$tadds" ] && images="$images $tadds"
 if [ -z "$images" ]; then
  echo "There exist no images yet!"
  exit 0
 fi
fi

# write client torrent config
write_client_config(){
 echo "MINPORT=$MINPORT"
 echo "MAX_INITIATE=$MAX_INITIATE"
 echo "MAX_UPLOAD_RATE=$MAX_UPLOAD_RATE"
 echo "DOWNLOAD_SLICE_SIZE=$DOWNLOAD_SLICE_SIZE"
 echo "TIMEOUT=$TIMEOUT"
}

start(){

 local RC=0
 local c=0

 write_client_config > "$CLIENT_CONFIG"

 # check and create torrents first
 local i=""
 local tfile=""
 local tname=""
 for i in $images; do
  tfile="$i.torrent"
  tname="$(basename $tfile)"
  # check torrent file and delete it if it does not match with image
  if [ -e "$tfile" ]; then
   if ! check_torrent "$i"; then
    echo "$i and $tfile do not match!"
    rm -f "$tfile"
   fi
  fi
  # create torrent files if necessary
  [ ! -e "$tfile" -o "$force" = "force" ] && create_torrent "$i" "$SERVERIP" "$PORT"
 done

 # restart tracker
 systemctl stop bittorrent
 sleep 1
 killall bttrack.bittorrent &> /dev/null
 sleep 1
 systemctl start bittorrent
 sleep 1
 # start torrents
 for i in $images; do
  tfile="$i.torrent"
  tname="$(basename $tfile)"

  # start torrent daemon for image only if torrent file is present
  [ -e "$tfile" ] || continue

  # start daemon stuff
  echo -n "  - Starting $DESC for" "$i"

  if screen -list | grep -qw "$tname"; then
   echo
   echo "Torrent for $i is already running. Skipped!"
   continue
  fi

  OPTIONS="$tfile \
           --minport $MINPORT \
           --max_uploads $MAX_UPLOADS \
           --max_upload_rate $MAX_UPLOAD_RATE \
           --rerequest_interval $REREQUEST_INTERVAL \
           --min_peers $MIN_PEERS \
           --max_initiate $MAX_INITIATE \
           --keepalive_interval $KEEPALIVE_INTERVAL \
           --download_slice_size $DOWNLOAD_SLICE_SIZE \
           --max_message_length $MAX_MESSAGE_LENGTH \
           --timeout_check_interval $TIMEOUT_CHECK_INTERVAL \
           --max_rate_period $MAX_RATE_PERIOD \
           --display_interval $DISPLAY_INTERVAL \
           --max_slice_length $MAX_SLICE_LENGTH \
           --check_hashes 0"

# following options not supported
#           --timeout $TIMEOUT \
#           --request_backlog $REQUEST_BACKLOG \
#           --upload_rate_fudge $UPLOAD_RATE_FUDGE \
#           --saveas $i

  screen -dmS "$tname" $DAEMON $OPTIONS
  sleep 1
  if ! screen -list | grep -qw "$tname"; then
   echo -n " "
   echo " failed!"
  else
   RC=0
   echo " OK."
  fi
 done
 return 0
}

stop(){

 local i=""
 local pid=""
 for i in $images; do
  if screen -list | grep -qw "$(basename $i.torrent)"; then
    echo -n "  - Stopping $DESC for" "$i"
    pid="$(screen -list | grep "$(basename $i.torrent)" | awk -F\. '{ print $1 }' | awk '{ print $1 }')"
    kill $pid ; RC="$?"
    if [ "$RC" = "0" ]; then
      echo " OK." 
    else 
      echo " failed($RC)!" 
    fi
  fi
 done
 if [ -z "$omit_killall" ]; then
  local pids="$(screen -list | grep torrent | awk -F\. '{ print $1 }' | awk '{ print $1 }')"
  if [ -n "$pids" ]; then
   echo -n "Sending all remaining linbo-bittorrent processes the TERM signal."
   kill $pids ; RC="$?"
   if [ "$RC" = "0" ]; then 
     return 0
   else 
     return 1
   fi
  fi
 fi
}

status(){
   local line=""
   local pid=""
   local screen=""
   local status=""
   local c=0
   local d=""
   screen -wipe | grep '.torrent\b' | while read line; do
    let c+=1
    pid="$(echo $line | awk -F\. '{ print $1 }' | awk '{ print $1 }')"
    screen="$(echo $line | awk '{ print $1 }')"
    screen="${screen#*.}"
    status="$(echo $line | awk '{ print $2 }')"
    d=""
    [ $c -lt 100 ] && d=" "
    [ $c -lt 10 ] && d="  "
    echo -e "  - $d$c\t$pid\t$screen\t$status"
   done
}

case "$action" in
 start) 
    echo "Starting $DESC" "$NAME"
    start 
    rc_status -v
    ;;
  stop)
  	echo "Stopping $DESC" "$NAME"
	stop
	rc_status -v
	;;
  restart|force-reload)
  	echo "Restarting $DESC" "$NAME"
	stop
	sleep 1
	start
	rc_status -v
	;;
  status)
	echo -n "Checking $DESC" "$NAME"
	status
	checkproc $DAEMON
	rc_status -v
	;;
 *)
	 echo "Usage: $0 {status} | {start|stop|restart} [<imagefile>|all] [force]" >&2
	 exit 1 ;;
esac

exit 0

