#!/bin/sh
# (C) 2003, 2004, 2005 by Piotr 'GhosT' Wydrych (e-mail: user:ghost host:ciapek.uci.agh.edu.pl)
# This script is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.

BM_ver="1.1"
BM_naglowek="Backup manager by GhosT v. $BM_ver"
BM_defmax=65536 #kB

###
#funkcja wyswietlająca sposób użycia
###

usage()
{
cat > /dev/stderr << EOF
$BM_naglowek
Użycie:
        `basename $0` -c KOP_KAT -d KAT [-m MAX] [-f|-i]
        `basename $0` -x KOP_KAT -d KAT [-r]
        `basename $0` {-h | -V}
Opcje:
        -c KOP_KAT      Tworzy kopię zapasową w katalogu KOP_KAT
        -x KOP_KAT      Odtwarza kopię zapasową z katalogu KOP_KAT
        -d KAT          Katalog główny danych
        -h              Wyswietla reguły tworzenia kopii
        -V              Wyswietla wersję, datę modyfikacji i autora skryptu

Opcje tworzenia kopii:
        -m MAX          Maksymalny rozmiar (w kB) plików umieszczanych w kopii
                        (domyślnie $BM_defmax kB)
        -f              Tworzy pełną kopię zapasową (domyślnie w poniedzialek)
        -i              Tworzy kopię narastającą względem ostatniej pełnej
                        (jeżeli w podanym katalogu nie ma pełnej kopii, zostanie
                        utworzona pełna zamiast narastającej)
Opcje odtwarzania z kopii:
        -r              Usuwa pliki z katalogu KAT (domyślnie program
                        przerywa działanie jeżeli KAT nie jest pusty)

Nazwy katalogów MUSZĄ być podane w sposób BEZWZGLĘDNY.
EOF
exit 1
}

help()
{
cat << EOF
$BM_naglowek

   Jeżeli nie znasz sposobu użycia, wywołaj skrypt bez argumentów.

   Tworzenie pełnej kopii polega na utworzeniu archiwum nazwanego 
backup-full-{data}.tar.gz oraz znacznika czasu w katalogu KOP_KAT.
Jeżeli katalog kop_kat istnieje, jego nazwa zostanie zmieniona na
KOP_KAT-old. Jeżeli i ten katalog istnieje, zostanie on usuniety bez pytania.

   Tworzenie kopii narastającej polega na archiwizowaniu wszystkich plików
nowszych niż ostatnia pełna kopia w katalogu KOP_KAT.
Tworzone jest archiwum backup-inc-{data}.tar.gz.

   Podczas odzyskiwania z kopii, rozpakowywane są najnowsza pełna kopia oraz
najnowsza kopia narastająca.
EOF
exit 0
}

version()
{
cat << EOF
$BM_naglowek

Aktualizacje pod adresem: http://ciapek.uci.agh.edu.pl/~ghost/

Ostatnia modyfikacja: piątek, 8.04.2005 17:25
Suma kontrolna skryptu: `md5sum -b "$0" | cut -c 1-32`

Autor: Piotr 'GhosT' Wydrych (e-mail: user:ghost host:ciapek.uci.agh.edu.pl)
EOF
exit 0
}

BM_max=$BM_defmax
if [ "`date +%w`" = "1" ] ; then
        BM_kopia="full"
else
        BM_kopia="inc"
fi
BM_r="n"

###
# sprawdzenie istnienia argumentów
###

if [ "$#" = "0" ] ; then
        usage
fi

while [ -n "$*" ] ; do
        case "$1" in
                '-c')
                        BM_akcja="c"
                        BM_kop_kat=$2
                        shift
                        shift
                        ;;
                '-x')
                        BM_akcja="x"
                        BM_kop_kat=$2
                        shift
                        shift
                        ;;
                '-d')
                        BM_kat=$2
                        shift
                        shift
                        ;;
                '-m')
                        BM_max=$2
                        shift
                        shift
                        ;;
                '-f')
                        BM_kopia="full"
                        shift
                        ;;
                '-i')
                        BM_kopia="inc"
                        shift
                        ;;
                '-r')
                        BM_r="y"
                        shift
                        ;;
                '-h')
                        help
                        ;;
                '-V')
                        version
                        ;;
                *)
                        usage
        esac
done

###
# sprawdzenie popawności argunemtów
###

if [ "$BM_akcja" != "c" -a "$BM_akcja" != "x" ] ; then
        usage
fi

BM_kop_kat=`echo "$BM_kop_kat" | sed 's|/$||g'`

if [ -z "$BM_kop_kat" ] ; then
        usage
fi

if [ "`echo "$BM_kop_kat" | cut -c 1`" != "/" -a "`echo "$BM_kop_kat" | cut -c 1`" != "~" ] ; then
        echo "`basename $0`: Nazwa katalogu musi być podana w sposób bezwzględny!" > /dev/stderr
        echo "`basename $0`: Backup manager nie może kontynuować działania!" > /dev/stderr
        exit 1
fi

if [ "`echo "$BM_kat" | cut -c 1`" != "/" -a "`echo "$BM_kat" | cut -c 1`" != "~" ] ; then
        echo "`basename $0`: Nazwa katalogu musi być podana w sposób bezwzględny!" > /dev/stderr
        echo "`basename $0`: Backup manager nie może kontynuować działania!" > /dev/stderr
        exit 1
fi

###
# tworzenie kopii
###

if [ "$BM_akcja" = "c" ] ; then

if [ ! -w "`dirname $BM_kop_kat`" ] ; then
        echo "`basename $0`: Nie masz praw pisania do `dirname $BM_kop_kat`!" > /dev/stderr
        echo "`basename $0`: Kopia nie może zostać utworzona!" > /dev/stderr
        exit 1
fi

if [ ! -d "$BM_kat" ] ; then
        echo "`basename $0`: Katalog $BM_kat nie istnieje!" > /dev/stderr
        echo "`basename $0`: Kopia nie może zostać utworzona!" > /dev/stderr
        exit 1
fi

if [ "$BM_kopia" = "inc" ] ; then
        if [ -d "$BM_kop_kat" ] ; then
                if [ ! \( -f "$BM_kop_kat/timestamp" -o -L "$BM_kop_kat/timestamp" \) ] ; then
                        BM_kopia="full"
                fi
        else
                BM_kopia="full"
        fi
fi

BM_data=`date "+%Y-%m-%d"`
BM_plik="${BM_kop_kat}/backup-${BM_kopia}-${BM_data}"

echo ">>> $BM_naglowek"
echo ">>> Jest `date '+%A, %d.%m.%Y %H:%M:%S'`"
echo ">>> Tworzenie kopii zapasowej katalogu"
echo ">>> $BM_kat"
echo ">>> do pliku"
echo ">>> ${BM_plik}.tar.gz"
echo ">>> W kopii nie zostaną umieszczone pliki o rozmiarze powyżej ${BM_max}kB."

if [ "$BM_kopia" = "full" ] ; then
        if [ -f "$BM_kop_kat" -o -d "$BM_kop_kat" -o -L "$BM_kop_kat" ] ; then
                if [ -f "${BM_kop_kat}-old" -o -d "${BM_kop_kat}-old" -o -L "${BM_kop_kat}-old" ] ; then
                        rm -rf "${BM_kop_kat}-old"
                fi
                mv -f "${BM_kop_kat}" "${BM_kop_kat}-old"
        fi
        mkdir "$BM_kop_kat"
fi

cd "$BM_kat"
echo
echo ">>> Tworzenie listy plików..."

BM_max=`expr "$BM_max" '*' 1024`

if [ "$BM_kopia" = "full" ] ; then
        touch "$BM_kop_kat/timestamp"
        find . \( -type f -o -type l \) \( -size ${BM_max}c -o -size -${BM_max}c \) | sort > "$BM_plik.include"
        find . \( -type f -o -type l \) -size +${BM_max}c | sort > "$BM_plik.exclude"
else
        find . -newer "$BM_kop_kat/timestamp" \( -type f -o -type l \) \( -size ${BM_max}c -o -size -${BM_max}c \) | sort > "$BM_plik.include"
        find . -newer "$BM_kop_kat/timestamp" \( -type f -o -type l \) -size +${BM_max}c | sort > "$BM_plik.exclude"
fi

if [ -s "$BM_plik.include" ] ; then
        echo ">>> Tworzenie archiwum $BM_plik.tar.gz..."
        tar -zcvf "$BM_plik.tar.gz" -T "$BM_plik.include" | tee "$BM_plik.tar.gz.toc" | sed 's/^/> Dodawanie /g'
        echo
        echo ">>> Zakończono tworzenie archiwum"
        if [ -s "$BM_plik.exclude" ] ; then
                echo
                echo ">>> Pliki nie umieszczone w archiwum:"
                echo
                cat "$BM_plik.exclude" | sed 's/^/> Pominięto /g'
                echo
        fi

        echo ">>> Powstałe pliki:"
        cd "$BM_kop_kat"
        ls -l backup-${BM_kopia}-${BM_data}.exclude backup-${BM_kopia}-${BM_data}.include backup-${BM_kopia}-${BM_data}.tar.gz backup-${BM_kopia}-${BM_data}.tar.gz.toc
        if [ "$BM_kopia" = "full" ] ; then
                ls -l timestamp
        fi

        if [ -n "`comm -3 "$BM_plik.include" "$BM_plik.tar.gz.toc"`" ] ; then
                echo
                echo ">>> !UWAGA! Lista plików w archiwum nie jest identyczna z listą plików, które"
                echo ">>>         powinny się w nim znaleźć!"
        fi
else
        echo ">>> Brak plików do archwizowania"
        rm -f "$BM_plik.include" "$BM_plik.exclude"
fi
echo
echo ">>> Zakończono tworzenie kopii zapasowej"
echo ">>> Jest `date '+%A, %d.%m.%Y %H:%M:%S'`"

###
# koniec tworzeniia kopii
###
# odtwarzanie danych z kopii
###

elif [ "$BM_akcja" = "x" ] ; then

if [ ! -d "$BM_kop_kat" ] ; then
        echo "`basename $0`: $BM_kop_kat nie jest katalogiem!" > /dev/stderr
        echo "`basename $0`: Kopia nie może zostać odtworzona!" > /dev/stderr
        exit 1
fi

if [ ! -r "$BM_kop_kat" ] ; then
        echo "`basename $0`: Nie masz prawa czytać $BM_kop_kat!" > /dev/stderr
        echo "`basename $0`: Kopia nie może zostać odtworzona!" > /dev/stderr
        exit 1
fi

if [ ! -x "$BM_kop_kat" ] ; then
        echo "`basename $0`: Nie masz prawa wejść do $BM_kop_kat!" > /dev/stderr
        echo "`basename $0`: Kopia nie może zostać odtworzona!" > /dev/stderr
        exit 1
fi

if [ ! -d "$BM_kat" ] ; then
        echo "`basename $0`: $BM_kat nie jest katalogiem!" > /dev/stderr
        echo "`basename $0`: Kopia nie może zostać odtworzona!" > /dev/stderr
        exit 1
fi

if [ ! -w "$BM_kat" ] ; then
        echo "`basename $0`: Nie masz prawa pisać do $BM_kat!" > /dev/stderr
        echo "`basename $0`: Kopia nie może zostać odtworzona!" > /dev/stderr
        exit 1
fi

if [ ! -x "$BM_kat" ] ; then
        echo "`basename $0`: Nie masz prawa wejść do $BM_kat!" > /dev/stderr
        echo "`basename $0`: Kopia nie może zostać odtworzona!" > /dev/stderr
        exit 1
fi

cd "$BM_kat"
if [ -n "`ls -A`" ] ; then
        if [ "$BM_r" != "y" ] ; then
                echo "`basename $0`: Katalog $BM_kat nie jest pusty!" > /dev/stderr
                echo "`basename $0`: Kopia nie może zostać odtworzona!" > /dev/stderr
                exit 1
        fi
fi

if [ -n "`ls $BM_kop_kat/backup-full-????-??-??.tar.gz 2> /dev/null`" ] ; then
        BM_odtwarzana_full=`ls $BM_kop_kat/backup-full-????-??-??.tar.gz | sort | tail -1`
        if [ -n "`ls $BM_kop_kat/backup-inc-????-??-??.tar.gz 2> /dev/null`" ] ; then
                BM_odtwarzana_inc=`ls $BM_kop_kat/backup-inc-????-??-??.tar.gz | sort | tail -1`
        fi
fi

if [ -z "$BM_odtwarzana_full" ] ; then
        echo "`basename $0`: W podanym katalogu nie znajduje się kopia zapasowa!" > /dev/stderr
        echo "`basename $0`: Kopia nie może zostać odtworzona!" > /dev/stderr
        exit 1
fi

if [ ! -r "$BM_odtwarzana_full" ] ; then
        echo "`basename $0`: Nie masz prawa odzczytywać pliku kopii głównej!" > /dev/stderr
        echo "`basename $0`: Kopia nie może zostać odtworzona!" > /dev/stderr
        exit 1
fi

if [ ! -r "$BM_odtwarzana_inc" ] ; then
        BM_odtwarzana_inc=""
fi

echo ">>> $BM_naglowek"
echo ">>> Jest `date '+%A, %d.%m.%Y %H:%M:%S'`"
echo ">>> Odtwarzanie kopii zapasowej katalogu"
echo ">>> $BM_kat"
if [ -z "$BM_odtwarzana_inc" ] ; then
        echo ">>> z pliku"
        echo ">>> ${BM_odtwarzana_full}"
else
        echo ">>> z plików"
        echo ">>> ${BM_odtwarzana_full}"
        echo ">>> i"
        echo ">>> ${BM_odtwarzana_inc}"
fi
echo
if [ -n "`ls -A`" -a "$BM_r" = "y" ] ; then
        echo ">>> Katalog $BM_kat nie jest pusty"
        echo ">>> Oczyszczanie katalogu..."
        rm -rfv -- `find -maxdepth 1 -mindepth 1`
        echo ">>> Katalog oczyszczono"
        echo
fi
echo ">>> Wypakowywanie z archiwum ${BM_odtwarzana_full}"
echo
tar -zxvpf "${BM_odtwarzana_full}" | sed 's/^/> Odtwarzanie /g'
echo
if [ -n "$BM_odtwarzana_inc" ] ; then
        echo ">>> Wypakowywanie z archiwum ${BM_odtwarzana_inc}"
        echo
        tar -zxvpf "${BM_odtwarzana_inc}" | sed 's/^/> Odtwarzanie /g'
        echo
fi
echo ">>> Odtwarzanie z kopii zostało zakończone"
echo ">>> Jest `date '+%A, %d.%m.%Y %H:%M:%S'`"

###
# koniec tworzeniia kopii
###
fi