#!/bin/bash

# J.Kobus 04/2020 ver. 1.00
# modifications:
# 02/11/2020 26/01/2022 31/01/2022
# 05/02/2022: added options H and R

function helpAdd {

cat <<EOF

Instrukcja "obsługi" kolokwium/egzaminu.
========================================


Przygotowanie systemu operacyjnego
----------------------------------

Skrypt ssctl musi być uruchomiony na komputerze działającym pod kontrolą
systemu operacyjnego GNU/Linux. System GNU/Linux (Fedora, Debian/Ubuntu)
musi być albo zainstalowany na osobnej partycji, albo uruchomiony w wersji
,,live" z klucza USB.

Uwaga! System Linux NIE może być uruchomiony w środowisku wirtualizacyjnym,
np. VirtualBox.

Skrypt do prawidłowej pracy wymaga programów z pakietu ImageMagick. Można
je zainstalować przy pomocy komendy:

 bash ssctl install 

lub 

 chmod +x ssctl; ./ssctl install 

Dystrybucja Xubuntu 21.10 (impish), po zainstalowaniu pakietów Imagemagick
oraz openssh-server, pozwala na uruchomienie skryptu ssctl (lokalnie i przy
wykorzystaniu opcji '-s <server>') bez dodatkowych problemów. Zaletą tej
dystrybucji jest użycie lekkiego środowiska graficznego (Xfce).

W przypadku użycia dystrybucji Fedora-Workstation-Live-x86_64-35 
domyślnie uruchamiane jest interfejs graficzny Gnome, które korzysta z protokołu
Wayland. Niestety, w takim środowisku nie działa komenda import z pakietu 
ImageMagick, więc nie zadziała skrypt ssctl.

Rozwiązanie problemu wymaga wykonania następujących kroków:

  - przelogowania się na konto superużytkownika 
    # sudo su - root

  - utworzenie dodatkowego konta użytkownika (np. so),
    # useradd so
    # passwd so

  - przelogowania się na konto nowoutworzonego użytkownika so (w górnym prawym
    rogu trzeba wybrać "Power Off/Log Out", a następnie "Switch user")

  - na ekranie logowania, po podaniu identyfikatora nowego użytkownika i
    hasła, ale przed zatwierdzeniem hasła, należy najechać myszą na zębatkę
    (w prawym dolnym rogu) i wybrać "GNOME on Xorg"


Jeden ze studentów rekomendował użycie dystrybucji ,,elementary OS"
(https://elementary.io/docs/installation#choose-operating-system). Po
uruchomieniu wersji ,,live" skrypt ssctl powinien od razu zadziałać.

Wg tego samego źródła, użycie dystrybucji ,,Ubuntu Live" wymagało
zainstalowania starszej wersji imagemagick (imagemagick-6.q16), żeby zrzuty
ekranu były prawidłowo robione.


Jak korzystać ze skryptu ssl w czasie egzaminu/kolokwium?
=========================================================


Egzamin (sesja BBB)
-------------------

Zakładamy, że po uruchomieniu systemu operacyjnego użytkownik zalogował się
w trybie graficznym (jako zwykły użytkownik, np. "so") i uruchomił program
tworzący okno terminalowe (xterm, konsole, etc). Kroki opisane poniżej
trzeba wykonać w tym właśnie oknie.

Aktualną wersję skryptu ssctl można pobrać przy pomocy komendy:

  wget jkob.fizyka.umk.pl/so+sk/ssctl

Można też pobrać całe repozytorium tm:

   git clone ssh://<user>@ameryk.fizyka.umk.pl/home/jkob/tm

Skrypt ssctl znajduje się w podkatalogu scripts i dlatego trzeba go
przekopiować do bieżącego katalogu  ("cp tm/scripts/ssctl . ").

Rozpoczęcie egzaminu następuje w chwili użycia komendy

 ./ssctl -e -a so-exam-1.txt -g <nazwisko> -u <numer albumu> -s ameryk.fizyka.umk.pl start

Uwaga! <nazwisko> musi być zapisane małymi literami!

Ten skrypt

- automatycznie dodaje plik so-exam-1.txt do repozytorium, a potem będzie
  aktualizował jego wersję w repozytorium, czyli będzie kopiował aktualną
  wersję pliku do podkatalogu /home/<numer albumu>/<nazwisko> i ją
  zatwierdzał. Ta operacja będzie przebiegała poprawnie pod warunkiem, że
  stan repozytorium jest poprawny, tj. poprawnie działają komendy pull i push.

- tworzy zrzuty ekranu w podkatalogu ss (na lokalnym komputerze) i
  przesyła pliki do katalogu /home/<numer albumu>/<nazwisko>/ss na
  serwerze.

Plik z pytaniami egzaminacyjnymi będzie dostępny pod adresem
http://kob.fizyka.umk.pl/so-exam-1.pdf. Zalecam jego pobranie przy pomocy
komendy:

  wget http://jkob.fizyka.umk.pl/so-exam-1.pdf

i korzystanie z lokalnej jego kopii, żeby uniezależnić się od ew. krótszy
lub dłuższych trudności w dostępie do serwera WWW.

Po zakończeniu pisania egzaminu należy odczekać kilkanaście sekund na
przesłanie ostatniej wersji pliku so-exam-1.txt do repozytorium, a
następnie przy pomocy komendy

  ./ssctl stop

zakończyć robienie zrzutów i przerwać połączenie SSH z serwerem.

W celu upewnienia się, że plik z odpowiedziami i zrzuty poprawnie zostały
przekazane na serwer, należy zalogować się na serwer i sprawdzić stan
repozytorium i zawartość podkatalogu <nazwisko>/ss.


Egzamin (pracownia komputerowa)
-------------------------------

Jeśli ktoś zdaje egzamin w trybie stacjonarnym, tj. korzysta z komputera w
pracowni komputerowej, powinien zalogować się na serwer polon/tor, pobrać
skrypt ssctl (wget jkob.fizyka.umk.pl/so+sk/ssctl), a następnie rozpocząć
egzamin przy pomocy komendy

  ./ssctl -R -e -a so-exam-1.txt -g <nazwisko>  start

Po zakończeniu pisania egzaminu należy użyć komendy

  ./ssctl stop

żeby umieścić w repozytorium ostateczną wersję pliku $asheet.


Kolokwium (sesja BBB)
---------------------

Skrypty należy pisać na swoim komputerze, tj. LOKALNIE (nie na serwerze!) w
katalogu <nazwisko>, tj. katalogu który będzie lokalną kopią repozytorium. 
Repozytorium zostanie automatycznie utworzone po uruchomieniu skryptu
ssctl.

W celu zainicjowania sesji należy wykonać komendy:

./ssctl  -G <nazwisko> -u <numer albumu> -s ameryk.fizyka.umk.pl start

Uwaga! <nazwisko> musi być zapisane małymi literami!

Ten skrypt uruchomiony z powyższymi opcjami 

- automatycznie klonuje repozytorium /git/so21/<nazwisko>, czyli w bieżącym
  katalogu pojawia się podkatalog <nazwisko>

- tworzy w podkatalogu ss (bieżącego katalogu) zrzuty ekranu i przesyła
  odpowiednie pliki do katalogu /home/<numer albumu>/<nazwisko>/ss na
  serwerze (komenda "./ssctl status"  wyświetla aktualną zawartość
  podkatalogu ss).

Jeśli utworzony zostanie jakiś plik (skrypt), to nie będzie on
automatycznie przesyłany do repozytorium. Takim plikiem trzeba samodzielnie
zarządzać. Trzeba go dodać do repozytorium, a po modyfikacjach zatwierdzać
kolejne wersje, a także przesyłać do repozytorium na serwerze (git commit
...; git push).


Dodatkowe uwagi
---------------

Jeśli po uruchomieniu skryptu chcemy na czas jakiś wstrzymać robienie
zrzutów ekranu, bo musimy pilnie odejść od biurka, to wystarczy użyć
komendy

  ./ssctl pause

Tak komenda wstrzymuje robienie zrzutów, ale NIE przerywa połączenia z
serwerem. Komenda

  ./ssctl resume

wznawia robienie zrzutów.

Przykłady użycia skryptu
------------------------

Niech student nazywa się "Jan Kowalski" i ma numer albumu
123456, a także dysponuje repozytorium Git o nazwie "kowalski".

Jeśli ten student przystępuje do egzaminu, to wykonuje komendy

  wget jkob.fizyka.umk.pl/so+sk/ssctl
  chmod +x ssctl
  ./ssctl install
  ./ssctl -e -a so-exam-1.txt -G kowalski -u 123456 -s ameryk.fizyka.umk.pl start
  ./ssctl stop


Jeśli przystępuje do kolokwium to przed rozpoczęciem pracy nad skryptami
powinien wykonać poniższe komendy:

  wget jkob.fizyka.umk.pl/so+sk/ssctl
  chmod +x ssctl
  ./ssctl install
  ./ssctl  -G kowalski -u 123456 -s ameryk.fizyka.umk.pl start
  ./ssctl stop

EOF
}


bn=$(basename $0)

bold=`tput bold`
underline=`tput smul`
normal=`tput sgr0`

pid=$$

# a teacher should set the following variables

asheet=
qsheet=

asheet=so-exam-1.txt
qsheet=so-exam-1.pdf

#server=ameryk.fizyka.umk.pl
server=localhost
#wwwserver=http://grader.fizyka.umk.pl
wwwserver=http://jkob.fizyka.umk.pl

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

function help {

    cat <<EOF
${bold}NAME${normal}
        ssctl - take, archive at a server and display snapshots of the
                whole screen at randomly generated intervals.

${bold}SYNOPSIS${normal}
        $(basename $0) -h|H
        $(basename $0) [-r <range>] start
        $(basename $0) -d <dirname> 
        $(basename $0) -g <reponame> 
        $(basename $0) -d <dirname> -u <username> [-s <server>] [-a <answer sheet>] \\
                                         [-q <question sheet>] [-r <range>] start
        $(basename $0) -g <reponame> -u <username> [-s <server>] [-a <answer sheet>] \\
                                         [-q <question sheet>] [-r <range>] start
        $(basename $0) clean|cont|install|show|ss|status|stop


${bold}DESCRIPTION${normal}

        ssctl Bash script can be used to record an exam. It takes, archives
        and displays snapshots of the whole screen at randomly generated
        intervals. If dirname or reponame is defined the snapshots are
        copied into the specified directory on a server together with the
        exam's answer sheet (if specified). In case reponame is defined the
        answer sheet is added to repository and then regularily committed
        and pushed.

        Programs animate, convert, import, mogrify from the ImageMagick
        suit are used to make and display screenshots and manipulate the
        frames.

${bold}COMMANDS${normal}

        clean
              remove all ss/*-${import}.${format} files            


        clone
              clone the repository to the working directory            

  resume|cont 
              continue taking screenshots (and sending them to the repo)
              every $range seconds (on average) 

      convert 
              merge all *-$import.${format} files into the single ${import}.${format} one

      install
              copy $(basename $0) in /usr/local/bin/ and install additional packages 
              (Fedora and Debian/Ubuntu distributions are supported)

	pause 
              suspend taking snapshots but keep the ssh connection to the server

         show
              display the values of several variables: \$user, \$server, \$repo, etc 

           ss 
              begin automatic slideshow; fps variable should be used to adjust 
              the rate of display.

        start 
              begin taking screenshots every $range seconds (on average)

         stop 
              stop taking screenshots 


${bold}OPTIONS${normal}
        -a <answer sheet>
           use this option to define the name of a file to be used by a
           student to write down answers to the questions provided. This
           text file will be copied (at the same time as screenshots) to the
           student's git directory, committed and pushed.


        -d <dirname>
           "ssh -fN -o ControlPath=$controlPath -M <username>@<server>" is
           to be executed to establish a master connection which will
           facilitate the user to login into the server and access the
           specified directory and to upload screenshots to its ss
           subdirectory

        -D <time>
	   use this option to set the duration of a single animation (in seconds).
           The number of files being processed at a time is adjusted according to
           this parameter and the number of frames per second requested.

	-e 
           attempt an exam instead of a quiz    

        -f <fps>
           use this option to adjust the number of frames per second (which
           is passed to annimate) when playing back the snapshots (by default
           fps=3).
	    
        -g <reponame>
           "ssh -fN -o ControlPath=$controlPath -M <username>@<server>" is
           to be executed to establish a master connection which will
           facilitate the user to login into the server and access his Git
           repository and to upload screenshots to its ss subdirectory.

        -G <reponame>
           "ssh -fN -o ControlPath=$controlPath -M <username>@<server>" is
           to be executed to establish a master connection which will
           facilitate the user to login into the server and access his Git
           repository and to upload screenshots to its ss subdirectory.

           Additonaly the repository will be cloned to a current directory.

        -h 
           show this help           

        -H 
           show extra help messages (in Polish)

        -n <portion_of_images>
           use this option to display only a given 20% of all images: 
           1 - first, 2 - second, etc.
         
        -q <question sheet>
           use this option to define the URL location of the question sheet

        -r <range>
           use this option to adjust the frequency of screenshots; the
	              delay between screenshots is calculated as 
           \$((\$((\$RANDOM % <range>))+1))

        -R 
           use this option when taking the exam and being logged into your
           account on the server 

        -s <server>
           use this option to access user's Git repository on a different
           SSH server than $server

        -u <username>
           use this option if the username of the remote account is
           different from \$USER


${bold}EXAMPLE 1${normal}
        In order to take the screen snapshots on a regular basis just type

            ./ssctl start      

        The snapshots will be saved to ss subdirectory of a current directory. Use
	
            ./ssctl pause

        to stop taking snapshots but keeping the SSH connection open and 

            ./ssctl resume|cont 

        to resume it.

	Use

            ./ssctl stop

        to stop the program.

        Use 

            ./ssctl -f 5 ss
     
        to playback the snapshots at 5 frames per second.


${bold}EXAMPLE 2${normal}
	Let's assume that a student named Kowalski (the index number 123456) has
	cloned /git/so20/kowalski repository into his home directory on the server 
	ameryk.fizyka.umk.pl.

        In order to take a quiz he should run the following command on his home computer: 

           ./ssctl -g kowalski -u 123456 -s ameryk.fizyka.umk.pl start

	and follow the instructions. The snapshots will be saved to ss subdirectory of 
        a current directory and copied to /home/123456/kowalski/ss directory on the server.

${bold}EXAMPLE 3${normal}
	Let's assume that a student named Kowalski (the index number 123456) has
	cloned /git/so20/kowalski repository into his home directory on the server 
	ameryk.fizyka.umk.pl.

        In order to take an exam he should run the following command on his home computer: 

           ./ssctl -e -g kowalski -u 123456 -s ameryk.fizyka.umk.pl start

	and follow the instructions. The snapshots will be saved to ss subdirectory 
        of a current directory and copied to /home/123456/kowalski/ss directory on 
        the server.  The answer sheet will be copied to /home/123456/kowalski/ and 
        committed to the repository.

${bold}EXAMPLE 4${normal} 
        Let's assume that a student named Kowalski (the index number 123456) has 
        no git repository cloned to his home directory on the server ameryk.fizyka.umk.pl.

        In order to take a quiz/exam he should run the following command on his home computer: 

           ./ssctl [-e] -d quiz -u 123456 -s ameryk.fizyka.umk.pl start

	and follow the instructions. The snapshots will be saved to ss subdirectory of 
        a current directory and copied to /home/123456/quiz/ss directory on the server.


EOF
}



function convertImages {
    convert $snapshotDir/*-${import}.${format} -append $snapshotDir/${import}.${format}
}


function checkInput {

    if [[ $exam == yes && -z $asheet ]]
    then
	echo "Option '-a <answer sheet>' is missing ... try $0 -h"
	exit
    fi
}

function checkPkgs4CentOS {
    exitok=
    status=$(rpm -qi ImageMagick |& grep 'is not installed')
    if [[ -n $status ]]
    then
	#echo "convert, import, mogrify are missing ..."
 	if [[ $case == install ]]
	then
	    yum -y install ImageMagick
	else
	    echo "convert, import, mogrify are missing ... install ImageMagick ..."
	    echo "try 'yum -y install ImageMagick ... or 'ssctl install'"
	    exitok=yes
	fi
    fi
    
    status=$(rpm -qi bind-utils |& grep 'is not installed')
    if [[ -n $status ]]
    then
	#echo "package bind-utils is not installed ..."
	if [[ $case == install ]]
	then
	    yum -y install bind-utils
	else
	    echo "package bind-utils is not installed ... "
	    echo "try 'yum -y install bind-utils' or 'ssctl install'"
	    exitok=yes
	fi
    fi
    
    status=$(import |& grep 'unable to open X server')
    [[ -n $status ]] && echo "unable to open X server ..." && exitok=yes
    [[ $exitok == yes ]] && exit 
}

function checkPkgs4Fedora {
    exitok=
    status=$(rpm -qi ImageMagick |& grep 'is not installed')
    if [[ -n $status ]]
    then
	#echo "convert, import, mogrify are missing ..."
 	if [[ $case == install ]]
	then
	    dnf -y install ImageMagick
	else
	    echo "convert, import, mogrify are missing ... install ImageMagick ..."
	    echo "try 'dnf -y install ImageMagick ... or 'ssctl install'"
	    exitok=yes
	fi
    fi
    
    status=$(rpm -qi bind-utils |& grep 'is not installed')
    if [[ -n $status ]]
    then
	#echo "package bind-utils is not installed ..."
	if [[ $case == install ]]
	then
	    dnf -y install bind-utils
	else
	    echo "package bind-utils is not installed ... "
	    echo "try 'dnf -y install bind-utils' or 'ssctl install'"
	    exitok=yes
	fi
    fi
    
    status=$(import |& grep 'unable to open X server')
    [[ -n $status ]] && echo "unable to open X server ..." && exitok=yes
    [[ $exitok == yes ]] && exit 
}

function checkPkgs4Debian {
    exitok=
    status=$(which import)
    if [[ -z $status ]]
    then
	#echo "convert, import, mogrify are missing ... "
	if [[ $case ==  install ]]
	then
	    apt-get update; apt-get install imagemagick openssh-server
	else
	    echo "convert, import, mogrify are missing ... "
	    echo "try 'apt-get update; apt-get install imagemagick' ... or 'ssctl install'"
	    exitok=yes
	fi
    fi
    status=$(dpkg -s bind9-host |& grep 'is not installed')
    if [[ -n $status ]]
    then
	if [[ $case ==  install ]]
	then
	    apt-get update; apt-get install bind9-host
	else
	    echo "package bind9-host is not installed ..."
	    echo "try 'apt-get install bind9-host' ... or 'ssctl install'"
	    exitok=yes
	fi
    fi
    status=$(import |& grep 'unable to open X server')
    [[ -n $status ]] && echo "unable to open X server ..." &&  exitok=yes
    [[ $exitok == yes ]] && exit 
}

function check4Other {
    exitok=
    status=$(which convert)
    if [[ -z $status ]]
    then
	echo "convert is missing ... "
	exitok=yes
    fi

    status=$(which import)
    if [[ -z $status ]]
    then
	echo "import is missing ... "
	exitok=yes
    fi

    status=$(which mogrify)
    if [[ -z $status ]]
    then
	echo "mogrify is missing ... "
	exitok=yes
    fi

    status=$(which bc)
    if [[ -z $status ]]
    then
	echo "bc is missing ... install bc package"
	exitok=yes
    fi

    status=$(which host)
    if [[ -z $status ]]
    then
	echo "host is missing ..."
	exitok=yes
    fi
    [[ $exitok == yes ]] && exit
    
    status=$(import |& grep 'unable to open X server')
    if [[ -n $status ]]
    then
	echo "unable to open X server ..."
	echo "try using gnome-screenshot instead ..."
	exitok=yes
    fi

    [[ $exitok == yes ]] && exit 
}

function checkOS {
    [[ -d $repo ]] || mkdir -p $repo/ 
    cp /etc/os-release $repo/
    echo "virtualized environment="$(systemd-detect-virt) >> $repo/os-release
    echo "machine-id="$(cat /etc/machine-id) >> $repo/os-release

    if [[ -S $controlPath ]]
    then
	scp -o ControlPath=$controlPath $repo/os-release $user@$server:~/$repo >& /dev/null
	if [[ $gitrepo == yes ]]
	then
	    ssh -o ControlPath=$controlPath $user@$server \
		"cd $repo; git add os-release; git commit -mos-release-4-quiz os-release; git push origin master"  >& /dev/null
	fi
    fi
}

function checkSetLock {
    if [[ -f $lock ]]
    then
	echo -en "lock file detected ... continue? [y/n]"
	read answer
	if [[ $answer == y ]]
	then
	    $0 cont
	else
	    $0 stop
	    $0 start	    
	fi
    fi
}

function checkVirt {

    status=$(virt-what)
    [[ -z $status  ]] && return
    echo "Warning! cannot work in a virtual machine ... quittig" 
    exit
}



function displaySS {

    if [[ $1 == 0 ]]
    then
	cd $snapshotDir
	delay=$(echo "scale=0; 100 / $fps" | bc -l)
	n=$(echo "scale=0; $sad*$fps" | bc -l)
	#echo $n
	#ls | xargs -n $n animate -resize $resize -loop 1 -delay $delay
	ls | xargs -n $n animate  -loop 1 -delay $delay
	#animate -loop 1 -delay $delay -limit disk 200mb *.${format}
	cd - >& /dev/null
    else
	# display only a given portion of images
	cd $snapshotDir
	nimages=$(ls |wc -l)
	let n4split=$nimages/5+1
	echo $n4split
	ls *.png8 | split -l$n4split

	delay=$(echo "scale=0; 100 / $fps" | bc -l)
	n=$(echo "scale=0; $sad*$fps" | bc -l)
	portion=1
	[[ $1 == 1 ]] && portion=xaa
	[[ $1 == 2 ]] && portion=xab
	[[ $1 == 3 ]] && portion=xac
	[[ $1 == 4 ]] && portion=xad	
	[[ $1 == 5 ]] && portion=xae
	animate  -loop 1 -delay $delay $(cat $portion)
	rm -f xa* >& /dev/null
	cd - >& /dev/null
    fi
}


function rmLock {
    rm -f $lock
}

function saveVars {
    cat <<EOF > $ssctlstop
user=$user
server=$server
repo=$repo
ControlPath=$controlPath
pid4stop=$pid 
exam=$exam
remote=$remote

EOF
    
}

function getAvPngSize {

    avs=$(ls -l $snapshotDir/*.png8 | head -n $1 | awk '{print $5}' \
	      | awk 'BEGIN  {sum=0 } { sum+=$1 } END {printf "%10.0f ", sum/NR}')

}


function startClone {
    if [[ -d $repo ]]
    then
	cd $repo; git pull; cd - >& /dev/null
	return
    fi
    #rm -rf $repo
    git clone ssh://$user@$server/git/$repo4so/$repo
}



function startImport {
   
    [[ -d $snapshotDir ]] || mkdir $snapshotDir
    if [[ $contImport == no ]]
    then
	last=0
    else
	cd $snapshotDir
	last=$(ls 0*-${import}.${format} 2> /dev/null | sort -nr | cut -d- -f1|head -n1)
	cd - >& /dev/null
    fi

    (
	last=$(echo -n $last | sed -r 's/^0+//')

	while ((1>0)) 
	do
	    let last++
	    if (( $last <= 9 ))
	    then
		lastfn=$(printf "0000%d" $last)
	    elif (( $last <= 99 ))
	    then
		lastfn=$(printf "000%d" $last)
	    elif (( $last <= 999 ))
	    then
		lastfn=$(printf "00%d" $last)
	    elif (( $last <= 9999 ))
	    then
		lastfn=$(printf "0%d" $last)
	    elif (( $last <= 99999 ))
	    then
		lastfn=$(printf "%d" $last)
	    fi

	    delay=$(($(($RANDOM % $range))+1))
	    sleep $delay
	    import -silent -window root  $snapshotDir/$lastfn-${import}.${format}
	    [[ "$resize" == "100%" ]] || mogrify -resize $resize -format $format $snapshotDir/$lastfn-${import}.${format}
	    
	    if [[ -S $controlPath ]]
	    then
		scp -o ControlPath=$controlPath $snapshotDir/$lastfn-${import}.${format} $user@$server:~/$repo/$snapshotDir >& /dev/null


		#set -x
		if [[ -n $asheet ]]
		then
		    [[ -f ${asheet} ]] && scp -o ControlPath=$controlPath \
					      $asheet $user@$server:~/$repo >& /dev/null
		    [[ -f .${asheet}.swp ]] && scp -o ControlPath=$controlPath \
						   .${asheet}.swp $user@$server:~/$repo/ >& /dev/null

		    if [[ $gitrepo == yes ]]
		    then
			if [[ $gitadd == no ]]
			then
			    ssh -o ControlPath=$controlPath $user@$server \
				"cd ~/$repo; git add $asheet; git commit -mInitial-commit--$asheet $asheet; git push origin master"  >& /dev/null
			    gitadd=yes
			else
			    ssh -o ControlPath=$controlPath $user@$server \
				"cd ~/$repo; git commit -mcommit--$asheet $asheet; git push origin master"  >& /dev/null
			fi
		    fi
		fi
		#set +x
	    fi
	    [[ $verbose == yes ]] && echo $lastfn-${import}.${format}
	    if (( $last >= $nf4av ))
	    then
		getAvPngSize $nf4av
		
		(( $avs < 15000 )) && resize=75%
		(( $avs > 55000 )) && resize=25%		
		#echo "last="$last "  avsize="$avs  "resize="$resize
		nf4av=10000000
	    fi
	done
    )&
}


function startInPlace {

    if [[ -n $repo ]]
    then
	if [[ ! -d $repo/.git ]]
	then
	    echo "No repository $repo found in the current directory ... quitting ..."
	    exit
	fi
	
	if [[ $exam == yes ]]
	then
	    message4examIP
	    cd $repo
	    touch $asheet
	    git add $asheet >& /dev/null
	    git commit -mInitial-commit--$asheet >& /dev/null
	    git push >& /dev/null
	    ( while (( 1>0 )) 
	    do
		delay=$(($(($RANDOM % $range))+1))
		#echo delay=$delay
		sleep $delay
		git commit -mcommit--$asheet $asheet >& /dev/null
		git push >& /dev/null
	    done) &
	else
	    if [[ $clone == no ]]
	    then
		message4quizIP
	    else
		message4quizANDcloneIN
	    fi
	fi
    fi


    
    exit
}


function stopInPlace {
    . $ssctlstop
    if [[ $exam == yes ]]
    then
	cd $repo
	git commit -mfinal-commit--$asheet >& /dev/null
	git push >& /dev/null
    fi
    pkill -9 -f 'ssctl.*start'
    exit
}

function startPrep {

    if [[ -n $repo ]]
    then
	if [[ $exam == yes ]]
	then
	    message4exam
	    touch $asheet
	else
	    if [[ $clone == no ]]
	    then
		message4quiz
	    else
		message4quizANDclone
	    fi
	fi
    fi
    
    if [[ ! -S $controlPath ]]
    then
	ssh -fN -o ControlPath=$controlPath -M $user@$server
	echo "SSH connection: OK"
	
	if [[ $gitrepo == yes ]]
	then
	    status=$(ssh -o ControlPath=$controlPath $user@$server "cd $repo; git status" |& grep "fatal: not a git repository")
	    if [[ -n $status ]]
	    then
		echo "Error: $repo is not a git repository ... quitting"
		stopSS
	    fi
	fi
	ssh -o ControlPath=$controlPath $user@$server "[[ -d $repo/$snapshotDir ]] || mkdir -p $repo/$snapshotDir"  
	echo "repo $repo: OK"
    fi
    checkOS
}

function stopImport {
    pids=$(ps -elf | grep -P "$bn.*start" | grep -v grep| awk '{print $4}')
    [[ -n $pids ]] && echo $pids | xargs kill

    pids=$(ps -elf | grep -P "$bn.*resume" | grep -v grep| awk '{print $4}')
    [[ -n $pids ]] && echo $pids | xargs kill

    pids=$(ps -elf | grep -P "$bn.*cont" | grep -v grep| awk '{print $4}')
    [[ -n $pids ]] && echo $pids | xargs kill

    exit
}


function stopSS {
    . $ssctlstop
    [[ -S $controlPath ]] && ssh -o ControlPath=$controlPath -O exit $user@$server
    stopImport
    rmLock
}

function message4exam {
    cat <<EOF

You are about to establish a secure connection with $server 
server using your account ($user).

This connection will be used to automatically transfer the screenshots
taken at random together with the current version of ${bold}$asheet${normal} 
to the server. This file is created by the script itself and should contain
your answers to the exam questions. Its subsequent versions will
automatically be committed to your repository.

To pause the process run

   ./ssctl pause

and to resume it run

   ./ssctl resume|cont

When you are done run

   ./ssctl stop


${bold}A hint for Emacs users:${normal} Make sure that the
auto-save-visited-mode is enabled (M-x auto-save-visited-mode). You can
also add "(auto-save-visited-mode t)" into the emacs configuration file
(~/.emacs) to enable this mode automatically.

${bold}A hint for Vim users:${normal} vim editor keeps the backup in
.${asheet}.swp file so in case of a crash you may resume the editing by
running "vi -r $asheet" command.

EOF

}	    

function message4examIP {
    cat <<EOF

The ${bold}$asheet${normal} file is created by the script itself and should
contain your answers to the exam questions. Its subsequent versions will
automatically be committed to your repository.

When you are done run

   ./ssctl stop

${bold}A hint for Emacs users:${normal} Make sure that the
auto-save-visited-mode is enabled (M-x auto-save-visited-mode). You can
also add "(auto-save-visited-mode t)" into the emacs configuration file
(~/.emacs) to enable this mode automatically.

${bold}A hint for Vim users:${normal} vim editor keeps the backup in
.${asheet}.swp file so in case of a crash you may resume the editing by
running "vi -r $asheet" command.

EOF

}	    

function message4quiz {
    cat <<EOF

You are about to establish a secure connection with $server server using
your account ($user). 

It will be used to transfer automatically the screenshots taken at random
plus the identification of your operating system (/etc/os-release) to
record your session.

To pause the process run

   ./ssctl pause

and to resume it run

   ./ssctl resume

And when you are done run

   ./ssctl stop

EOF
}	    


function message4quizANDclone {
    cat <<EOF

You are about to establish a secure connection with $server server using
your account ($user). 

It will be used to transfer automatically the screenshots taken at random
plus the identification of your operating system (/etc/os-release) to
record your session.

Additionally your repository is cloned to the working directory and MUST be
used for modifying old scripts and writing new ones.

To pause the snapshots being taken run

   ./ssctl pause

and to resume it run

   ./ssctl resume

And when you are done run

   ./ssctl stop

EOF
}	    

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

#trap "rmLock; pgrep -f 'ssctl.*start' | xargs kill -9 2>/dev/null;  exit" INT

#trap "rmLock; pkill -9 -f 'ssctl.*start';" EXIT INT
trap "rmLock; pkill -9 -f 'ssctl.*start';" INT


contImport=no
backup=no
clone=no
exam=no
os=

# duration of a single animation
sad=20
fps=3
range=3
import=import
snapshotDir=ss

repo=repo
gitrepo=no
gitadd=no

#resize=50%
#resize=75%
resize=100%
#resize=150%
# adjust the resize variable by examining the average size of $nf4av png8 files 
nf4av=10

verbose=no

# when n is nonzero show only portion of the images
# n=2 >= 20%
# n=4 >= 40%
# n=6 >= 60%
# n=8 >= 80%

sspart=0

repo4so=so21

user=$USER
controlPath=/tmp/$bn-ssh-$user
lock=/tmp/$bn-lock-$user
ssctlstop=/tmp/$bn-stop-$user

#format=png
format=png8

remote=

while getopts "a:d:D:ef:g:G:hHln:q:Rr:s:u:v" option; do
    case $option in
	a ) asheet=$OPTARG;;
	d ) repo=$OPTARG;;
	D ) sad=$OPTARG;;
	e ) exam=yes;;
	f ) fps=$OPTARG;;	
	g ) repo=$OPTARG; gitrepo=yes;;
	G ) repo=$OPTARG; gitrepo=yes; clone=yes;;		
	h ) help; exit;;
	H ) helpAdd; exit;;
	n ) sspart=$OPTARG;;	
	q ) qsheet=$OPTARG;;
	r ) range=$OPTARG;;
	R ) remote=yes; range=60;;
	s ) server=$OPTARG;
	    status=$(host -i $server | grep -iP "Host $server not found:")
	    [[ -n $status ]] && echo "host $server not found ... quitting " && exit
	    ;;	
	u ) user=$OPTARG;;
	v ) verbose=yes;;	
    esac
done

shift $((OPTIND-1))
case=$1

#os=$(grep CPE_NAME /etc/os-release | cut -d: -f 4)
os=$(grep PRETTY_NAME= /etc/os-release | sed -r 's/"//g' | cut -d= -f 2  | cut -d' ' -f1)

checkInput


if [[ $case == install ]]
then
    [[ $USER != root ]] && echo "you must be root to install $(basename $0)" && exit
    cp $0 /usr/local/bin/
    chmod +x /usr/local/bin/$(basename $0)
fi

if [[ -z $remote ]]
then
    if [[ "$os" == "Fedora" ]]
    then
	checkPkgs4Fedora
    elif [[ "$os" =~ "CentOS" ]]
    then
	checkPkgs4CentOS
	
    elif [[ "$os" == "Debian" || "$os" =~ "Ubuntu" ]]
    then
	checkPkgs4Debian
    else
	check4Other
    fi

    [[ $case == install ]] && exit
fi

case $case in
    show )
	cat <<EOF
range=$range
repo=$repo
gitrepo=$gitrepo
resize=$resize
user=$user
server=$server
	
EOF
	exit 0
	;;

    clean )
        rm -f $repo/os-release
        rm -f $snapshotDir/${import}.${format} $snapshotDir/*-${import}.${format} >& /dev/null
	;;

    clone )
	startClone
	exit
	;;
    
    cont|resume )
	contImport=yes
	. $ssctlstop
	[[ -S $controlPath ]] || ssh -fN -o ControlPath=$controlPath -M $user@$server
	rsync -a $PWD/$snapshotDir $user@${server}:~/$repo/ >& /dev/null
	startImport
	;;

    convert )
        convertImages
	;;


    display )
        displaySS
	;;

    pause )
	stopImport
	;;
    
    ss|ss-start )
        displaySS $sspart
	;;

    status )
	[[ -f $ssctlstop ]] && . $ssctlstop

	if [[ $remote == yes ]]
	then
	    ps -elf | grep -P 'ssctl.*start' | grep -v grep
	    exit
	fi

	ps -elf | grep -P "$bn\s+start"	
        ls  $snapshotDir/*-${import}.${format} 2>/dev/null| sort -nr
	stat=$(ssh -o ControlPath=$controlPath -O check $user@$server |&  grep "Master running")	
	[[ -n $stat ]] && echo $stat
	;;
    
    start )
	checkSetLock
	saveVars
	[[ $clone == yes ]] && startClone
	if [[ $remote == yes ]]
	then
	    startInPlace
	    exit
	fi
	startPrep
        startImport
	;;
    
    stop )
	[[ -f $ssctlstop ]] && . $ssctlstop
	
	if [[ $remote == yes ]]
	then
	    stopInPlace
	    exit
	fi
	stopSS
	;;

    

    *  ) 	
        help; exit
	;;
esac
	      	 

