#!/bin/bash

# Patryk Czarnik
# Zadanie nr 1 z Systemow Operacyjnych
# wersja z plikami

# Skrypt dziala w petli nieskonczonej co N sekund za pomoca programu
# who sprawdzajac na ktorych sesjach zalogowany jest uzytkownik.
# Dla kazdej sesji tworzona jest lokalna zmienna o nazwie zaleznej
# od nazwy sesji (POCZ<nazwa sesji>), do ktorej zapisywany jest czas
# poczatkowy. Sesje, na ktorych zalogowany jest uzytkownik (zmienna
# Teraz) porownywane sa z sesjami, na ktorych byl zalogowany poprzednio
# (Ostatnio). Dla nowych dodawana jest odpowiednia zmienna, dla
# zakonczonych do pliku logstat.log dopisywany tekst z
# informacja o tej sesji i usuwana zmienna.

# Wyniki zapisywane sa w plikach.
# Wyniki tymczasowe, odnawiane w kazdym obrocie petli (czas sumaryczny
# i informacje o otwartych sesjach) zapisywane sa do pliku logstat.tmp,
# ktory jest za kazdym razem pisany od nowa. Zapis do pliku jest jednorazowy,
# aby to osiagnac najpierw wszystko co ma byc tam zapisane, zapisuje do zmiennej.
# Wyniki ustalone (informacje o zakonczonych sesjach) dopisywane sa do
# pliku logstat.log
# Pliki zapisywane sa w katalogu roboczym, byc moze lepiej robic to w /tmp ...

# Przy zakonczeniu skryptu wywolywana jest funkcja porzadki, ktora usuwa
# te pliki.

# Skrypt uruchomiony z opcja -show wypisuje zawartosc plikow logstat.tmp
# i logstat.log na standardowe wyjscie.
# Moze sie zdarzyc, ze plik .tmp jest w trakcie zapisywania, wtedy moga
# wypisac sie niepelne wyniki.

# Jesli skrypt wykryje, ze istnieja juz pliki, wypisze komunikat
# ale nie uruchomi sie.

function wypisz_wyniki()
{
  if [ -r logstat.tmp ]
    then
      cat logstat.tmp
  fi
  if [ -r logstat.log ]
    then
      cat logstat.log
  fi
}

function porzadki()
{
# Usuwa pliki zalozone przez program
  rm -f logstat.tmp
  rm -f logstat.log
  exit
}

function daj_wart_zmiennej()
{
# Na wyjsciu daje wartosc zmiennej o nazwie okreslonej przez pierwszy parametr
 eval echo '$'$1
}

# Poczatek skryptu #
# Sprawdzenie parametrow
if [ $# -eq 0 ]
  then
# domyslny odstep czasu
    N=3
  else
    if [ $# -eq 1 ]
      then
        if [ $1 = "-show" ]
          then
	    wypisz_wyniki
            exit
          else
# odstep czasu wczytany z parametru
	    N=$1
        fi
      else
        exit
    fi
fi

if [ -e logstat.log ]
  then
    echo "Chyba skrypt jest juz uruchomiony."
    echo "Jesli jestes pewny(a), ze nie, usun plik \"logstat.log\""
    echo "i uruchom ponownie."
    exit
fi

CzasSumaryczny=0
# Ta zmienna bedzie trzymala sumaryczny czas pracy
Ostatnio=""
# A ta nazwy sesji, na ktorych uzytkownik byl zalogowany podczas poprzedniego
# obrotu petli.
OstatniCzas=0
# Czas systemowy w sekundach od... ktory byl przy ostatnim obrocie petli

trap "porzadki" 0 1 2 3 4 5 6 7 8 10 11 12 13 14 15 16 17 18 19 20
# Nie wszedzie dziala trap bez parametrow, stad ta wyliczanka

# Stworzenie pliku logstat.log
echo "Zakonczone sesje:" > logstat.log

# Skrypt dziala w petli nieskonczonej
while true; do

# W zmiennej DoWpisania zapisuje to, co ma pojsc do pliku .tmp
  DoWpisania="Czas sumaryczny: $CzasSumaryczny\n"

# sleep nie musi byc zbyt precezyjny jesli chodzi o czas, wiec mierze go niezaleznie
  TerazCzas=`date +%s`
  Minelo=$(($TerazCzas - $OstatniCzas))
# W zmiennej Teraz bedzie lista nazw sesji, na ktorych uzytkownik jest
# aktualnie zalogowany
  Teraz=`who | grep $USER | cut -c10-18`

# Dla kazdej sesji...
  for sesja in $Teraz
  do
    DoWpisania="$DoWpisania $sesja od "`daj_wart_zmiennej POCZ$sesja`"\n"
# Jesli ostatnio jej nie bylo, to pod zmienna POCZ<nazwa sesji>
# zapisuje biezacy czas jako czas jej rozpoczecia (z dokl. do dlugosci petli)
    if echo $Ostatnio | grep $sesja > /dev/null
      then
        :
      else
        declare "POCZ$sesja"=`date +%H:%M:%S`
    fi
  done
  
  for sesja in $Ostatnio
# Dla kazdej sesji, ktora byla ostatnio...
  do
# Do czasu sumarycznego dodaje odstep czasowy od ostatniego obrotu
    CzasSumaryczny=$(($CzasSumaryczny + $Minelo))
# Jesli tej sesji nie ma juz teraz, do pliku .log dopisuje
# odpowiednia informacje i usuwam zmienna POCZ<nazwa sesji>
    if echo $Teraz | grep $sesja > /dev/null
      then
        :
      else
        echo "$sesja, od "`daj_wart_zmiennej 'POCZ'$sesja`" do "`date +%H:%M:%S` >> logstat.log
	unset "POCZ$sesja"
    fi
  done
# Zapisanie aktualnych wynikow do pliku .tmp
  echo -e $DoWpisania > logstat.tmp
  Ostatnio=$Teraz
  OstatniCzas=$TerazCzas
  sleep $N
done
