#!/bin/bash
#
# GFX Remote FTP Backup for Linux servers version 1.1
#
# Copyright (c) 1998-2008 by GraFX, ltd
# Visit us at http://www.web-hosting-control-panel-addons.com/
# All rights reserved
# 

# This program 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.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#=====================================================================
#=====================================================================
# Set the following variables to your system needs
#=====================================================================

### INSTALLATION NOTES
### Create directory ex: /root/backup_script
### Copy the gfx_backup file in /root/backup_script
### Edit /root/backup_script/gfx_backup and fill in the variables
### chmod 700 /root/backup_script/gfx_backup
### Setup DIRS, FTP Server details, EMAILID, and other stuffs, BACKUPNUMBER,BACKUPKEYNAME.
### Copy gfx_backup_cron to /etc/cron.weekly/ for weekly execution or /etc/cron.daily for daily execution
### chmod 700 /etc/cron.weekly/gfx_backup_cron

### OTHER INFO TO KNOW
### Check gpg if exist, check lftp if exist
### du -h for see where are available space (estimate how many need for backup)
### On remote server, need to have enough free space for 3-5 backups.

### IF GPG ON
### Please see 'man gpg', to create your public and private key.
### Import public key before start to run backup.
### gpg --import publickeyname

### IMPORTANT
### More help by gfx_backup --help  

ROOTDIR="/root/backup_script/"

### DIRS what we suggest to add ###
### /etc - all config file, we suggest to backup
### /var/qmail/ - QMAIL Home
### /home/httpd/vhosts - if PLESK 7.5 or earlier
### /var/www/vhosts - if PLESK 8
### /home/mysqlbackup - where we usually backup MySQL database with AutoMySQLBackup.sh
### OR
### /var/lib/mysql/data/ - WE do not suggest this kind of backup.
### AutoMySQLBackup script can be found on http://sourceforge.net/projects/automysqlbackup/

DIRS="/etc /home/backups/ /var/www/vhosts/" ## Add directories with spaces. With this settings, mails are not saved /var/qmail/ 
##DIRS="/var/www"

### FTP server Setup ###
FTPD="/" ### path if exist like public_html or httpd etc.
FTPU="USERNAME"  ### username
FTPP="PASSWORD" ### password
FTPS="IP-OF-YOUR-SERVER" ### IP of remote server

### Split size (MB) ###
SPLIT_SIZE="1000"

### GPG ###
GPGSTATUS="off" ## on / off
BACKUPKEYNAME="your_unique_key_name" ## unique public key if you use GPG encryption
GPGPUBKEYRING="/root/.gnupg/pubring.gpg" ## this must be ok if you have imported right the gpg key
BACKUPNUMBER="3" ## how many files to keep on remote server.

### Other stuff ###
NOTIFICATION="yes" ## yes / no - setup this if you want to get email or not.
EMAILID="YOUR-EMAIL-HERE" ### your email here, where program will send info

####################################################
########### DO NOT EDIT LINES BELOW ################
####################################################

###	Some other stuff, edit only if you know what you do	###
TMPFILE=$TEMPDIR"tmp.txt"
TEMPDIR=$ROOTDIR"tmp/"
RESTOREDIR=$ROOTDIR"restore/"
BACKUP=$TEMPDIR"backup.$$"
NOW=$(date +"%Y%m%d-%H%M")

###	FUNCTIONS	###
## root user cheking for security reasons
check_root() {
   if [ "$UID" != "0" ]; then
      echo "You must be root to run this script!"
      exit 0
   fi
}

## Mail sending module
start_mail(){

if [ "$NOTIFICATION" == "yes" ]; then
 T=/tmp/backup.fail
 echo "Date: $(date)">$T
 echo "Hostname: $(hostname)" >>$T
 echo "Remote hostname: $FTPS" >>$T
 echo "Folders: $DIRS" >>$T
 echo "Put to: $FTPD" >>$T

 mail  -s "Backup START $(hostname) to $FTPS" "$EMAILID" <$T
 rm -f $T
fi

}

## FTP Client module 
delete_remote_backups(){

lftp $FTPS<<EOF | sort -r >$TMPFILE
user "$FTPU" "$FTPP"
cd $FTPD
cls "BACKUP_""$(hostname | tr . _ )_*"
quit
EOF

TOTALLINES=`wc -l $TMPFILE | sed "s/^ *//g" | cut -f 1 -d " "`
let "LEFTLINES=$TOTALLINES-$BACKUPNUMBER";

if [ "$BACKUPNUMBER" -lt "$TOTALLINES" ]; then

BUFFER="user ""$FTPU"" ""$FTPP";
BUFFER="$BUFFER \ncd $FTPD";

for line in `tail -n $LEFTLINES $TMPFILE`
do
BUFFER="$BUFFER \nrm $line";
done

BUFFER="$BUFFER \nquit";

rm -f $TMPFILE

#Start FTP backup using lftp
echo -e $BUFFER | lftp $FTPS
fi

}

## Will work this module local, tar etc.
local_temporary_backup(){

### Start Backup for file system ###
[ ! -d $BACKUP ] && mkdir -p $BACKUP || :

### See if we want to make a full backup ###
FILE="BACKUP_""$(hostname | tr . _ )_"$NOW".tar.gz_PART_"

mkdir -p $BACKUP

if [ "$GPGSTATUS" == "off" ]; then
#tar -zcf $BACKUP/$FILE $DIRS 2> /dev/null 
(tar -zvc $DIRS | split -a 4 -d -b "$SPLIT_SIZE"m - "$BACKUP/$FILE") 2> backup_$NOW.log
else
FILE="$FILE.gpg"
#tar -zc $DIRS  2> /dev/null | gpg --keyring "$GPGPUBKEYRING" --always-trust -z 0 -e -r "$BACKUPKEYNAME" > "$BACKUP/$FILE"
(tar -zcv $DIRS  | gpg --keyring "$GPGPUBKEYRING" --always-trust -z 0 -e -r "$BACKUPKEYNAME" | split -a 4 -d -b "$SPLIT_SIZE"M - "$BACKUP/$FILE") 2> backup_$NOW.log

fi

FILESIZE=`du -h "$BACKUP" | cut -f1`

}

## Will put file to remote server
ftp_dump(){

### Dump backup using FTP ###
#Start FTP backup using lftp
lftp $FTPS<<EOF
user "$FTPU" "$FTPP"
cd $FTPD
lcd $BACKUP
mput *
quit
EOF

### Find out if ftp backup failed or not ###
if [ "$?" == "0" ]; then
 rm -f $BACKUP/*
 if [ "$NOTIFICATION" == "yes" ]; then
  T=/tmp/backup.fail
  echo "Date: $(date)">$T
  echo "Hostname: $(hostname)" >>$T
  echo "Remote hostname: $FTPS" >>$T
  echo "Folders: $DIRS" >>$T
  echo "Put to: $FTPD" >>$T
  echo "Size of $FILE = $FILESIZE bytes." >>$T

  mail  -s "Backup END $(hostname) to $FTPS SUCCESS" "$EMAILID" <$T
  rm -f $T
 fi
else
  T=/tmp/backup.fail
  echo "Date: $(date)">$T
  echo "Hostname: $(hostname)" >>$T
  echo "Remote hostname: $FTPS" >>$T
  echo "Folders: $DIRS" >>$T
  echo "Put to: $FTPD" >>$T
  echo "Operation failed" >>$T

  mail  -s "Backup END $(hostname) to $FTPS FAILED" "$EMAILID" <$T
  rm -f $T

fi

rmdir --ignore-fail-on-non-empty $BACKUP

}

## Restore backup from server
restore_backup(){

###	RESTORE DIR	###
[ ! -d $RESTOREDIR ] && mkdir -p $RESTOREDIR || :


if [ -n "$1" ]; then

BUFFER="user ""$FTPU"" ""$FTPP";
BUFFER="$BUFFER \ncd $FTPD";
BUFFER="$BUFFER \n lcd "$RESTOREDIR
BUFFER="$BUFFER \n mget "$1;
BUFFER="$BUFFER \nquit";
rm -f $TMPFILE

#Start FTP restore using lftp
echo -e $BUFFER | lftp $FTPS 

else

lftp $FTPS<<EOF | sort >$TMPFILE
user "$FTPU" "$FTPP"
cd $FTPD
cls "BACKUP_""$(hostname | tr . _ )_*"
quit
EOF

TOTALLINES=`wc -l $TMPFILE | sed "s/^ *//g" | cut -f 1 -d " "`


	if [ $TOTALLINES  -eq  0 ]; then
		echo "NO file to restore!"
		exit;
	else

		FILES=$(tail -n 1 $TMPFILE | sed s/_PART_.*$/_PART_/g);

		BUFFER="user ""$FTPU"" ""$FTPP";
		BUFFER="$BUFFER \ncd $FTPD";
		BUFFER="$BUFFER \n lcd "$RESTOREDIR
		BUFFER="$BUFFER \n mget $FILES*";
		BUFFER="$BUFFER \nquit";
		rm -f $TMPFILE

		#Start FTP restore using lftp
		echo -e $BUFFER | lftp $FTPS

		OUTFILE=$(echo -n $FILES | sed s/_PART_//g);
		echo "You must to concatenate files from the restore directories before untarring."
		echo "Example: cat $FILES* | tar xvz "
	fi
fi
}

## Will ask for report from remote FTP
report_remote(){

lftp $FTPS<<EOF | sort -r>$TMPFILE
user "$FTPU" "$FTPP"
cd $FTPD
cls "BACKUP_""$(hostname | tr . _ )_*"
quit
EOF

TOTALLINES=`wc -l $TMPFILE | sed "s/^ *//g" | cut -f 1 -d " "`

if [ $TOTALLINES  -eq  0 ]; then
                echo "NO files on the remote server!"
                exit;
else

echo "The available files for restorring:"  
cat $TMPFILE
echo "";

lftp $FTPS<<EOF | sort>$TMPFILE
user "$FTPU" "$FTPP"
cd $FTPD
ls "BACKUP_*_PART_*"
quit
EOF

TOTAL=`awk '{ sum += $5; } END { print sum/1048576; }' < $TMPFILE`
rm -f $TMPFILE

echo "Total size in folder: "$TOTAL" MB" 

fi

}

###	END FUNTIONS	###
 
## Perform the root checking

check_root

###	tempdir	###
[ ! -d $TEMPDIR ] && mkdir -p $TEMPDIR || :


case "$1" in
--backup)

### STARTING MAIL  ###
start_mail

### CHECK FOR FTP DELETE   ###
delete_remote_backups

###	LOCAL BACKUP	###
local_temporary_backup

###	FTP DUMP	###
ftp_dump

;;
--restore)
restore_backup $2

;;
--report)
report_remote

;;

--help)
echo "--backup		: start the backup from your local server to the"
echo "			  remote server"
echo "--restore	[file_name]	: restore the file_name from remote server"
echo "				  if no file is specified, the last one is"
echo "				  restored"
echo "--report		: the list of available files to restore"
echo "--help 		: this message "
;;
*)
   echo "Error: Missing or invalid option"
   echo "Use --help to view available options"
   ;;
esac

exit;

