rajven 6 роки тому
батько
коміт
cea21b5831

+ 2 - 0
README.md

@@ -6,3 +6,5 @@ Simple backup script for linux. Supported:
 - mongodb backup
 - backup openvz containers
 - upload to ftp, smb
+
+P.S. It's just a set of scripts for different purposes combined in one place

+ 18 - 0
docs/rsync.xinetd.conf

@@ -0,0 +1,18 @@
+# default: off
+# description: The rsync server is a good addition to an ftp server, as it \
+#       allows crc checksumming etc.
+service rsync
+{
+        disable = no
+        flags           = IPv4
+        socket_type     = stream
+        wait            = no
+        user            = root
+        server          = /usr/bin/rsync
+        server_args     = --daemon
+        only_from       = YOU IP
+        bind            = SERVER IP
+        log_type        = FILE /var/log/rsyncd.log
+        log_on_failure  += USERID HOST
+        log_on_success  += USERID HOST
+}

+ 13 - 0
docs/rsyncd.conf

@@ -0,0 +1,13 @@
+use chroot = no
+max connections = 20
+syslog facility = local5
+pid file = /var/run/rsyncd.pid
+max verbosity = 9
+read only = yes
+uid = root
+charset =UTF-8
+
+[backup]
+path = /home
+auth users = backup
+secrets file = /etc/rsyncd.secrets

+ 1 - 0
docs/rsyncd.secrets

@@ -0,0 +1 @@
+backup:blablabla

+ 72 - 0
etc/backup-custom-place.conf

@@ -0,0 +1,72 @@
+# Dir for .tar.gz files
+$cfg_tmp_dir = "/var/spool/backup/tmp";
+
+# Dir for status files
+$cfg_status_dir = "/var/spool/backup";
+
+# Current hostname for backup name
+$cfg_hostname = "custom-place";
+
+# Number day for full backup
+$cfg_full_day = 6;
+
+# FTP parameters for save backup
+$cfg_ftp_hostname = "127.0.0.1";
+$cfg_ftp_username = "backup";
+$cfg_ftp_password = "backup";
+$cfg_ftp_path = "/servers/" . $cfg_hostname;
+$cfg_use_ftp = "no";
+$cfg_ftp_mode = 1;
+
+# smb parameters for save backup
+$cfg_smb_hostname = "127.0.0.1";
+$cfg_smb_username = "bkp\@blabla\.com";
+$cfg_smb_password = "blabla";
+$cfg_smb_share = "backup";
+$cfg_smb_path = "/servers/" . $cfg_hostname;
+$cfg_use_smb = "no";
+
+# Delete .tar.gz files after copy on ftp
+$cfg_del_files = "yes";
+
+# Admin email
+$cfg_admin_email = "root";
+
+# mail from address
+$cfg_from_email = $cfg_admin_email;
+
+# mysql backup
+$cfg_mysql_backup = "no";
+$cfg_mysql_host = "127.0.0.1";
+$cfg_mysql_user = "root";
+$cfg_mysql_pass = "blabla";
+$cfg_mysql_locale = "";
+$cfg_mysql_dump = "mysqldump";
+#$cfg_mysql_dump = "mysqlhotcopy";
+@cfg_mysql_db = ( "All" );
+
+# mongo backup
+$cfg_mongo_backup = "yes";
+$cfg_mongo_host = "";
+$cfg_mongo_user = "";
+$cfg_mongo_pass = "";
+@cfg_mongo_db = ( "all" );
+
+# postgres backup
+$cfg_pgsql_backup = "no";
+$cfg_pgsql_host = "127.0.0.1";
+$cfg_pgsql_user = "root";
+$cfg_pgsql_pass = "blabla";
+$cfg_pgsql_locale = "";
+$cfg_pgsql_dump = "pg_dump";
+#$cfg_pgsql_dump = "pg_dumpall";
+$cfg_pgsql_su = "yes";
+@cfg_pgsql_db = ( "All" );
+
+$cfg_dirlist_file = "/usr/local/etc/dirlist.conf";
+$cfg_exclist_file = "/usr/local/etc/exclist.conf";
+
+#default - no dereference symlink
+$tar_opts="--no-recursion --numeric-owner";
+
+#$tar_opts="--no-recursion --dereference --numeric-owner";

+ 72 - 0
etc/backup.conf

@@ -0,0 +1,72 @@
+# Dir for .tar.gz files
+$cfg_tmp_dir = "/var/spool/backup/tmp";
+
+# Dir for status files
+$cfg_status_dir = "/var/spool/backup";
+
+# Current hostname for backup name
+$cfg_hostname = hostname;
+
+# Number day for full backup
+$cfg_full_day = 6;
+
+# FTP parameters for save backup
+$cfg_ftp_hostname = "127.0.0.1";
+$cfg_ftp_username = "backup";
+$cfg_ftp_password = "backup";
+$cfg_ftp_path = "/servers/" . $cfg_hostname;
+$cfg_use_ftp = "no";
+$cfg_ftp_mode = 1;
+
+# smb parameters for save backup
+$cfg_smb_hostname = "127.0.0.1";
+$cfg_smb_username = "bkp\@blabla\.com";
+$cfg_smb_password = "blabla";
+$cfg_smb_share = "backup";
+$cfg_smb_path = "/servers/" . $cfg_hostname;
+$cfg_use_smb = "no";
+
+# Delete .tar.gz files after copy on ftp
+$cfg_del_files = "no";
+
+# Admin email
+$cfg_admin_email = "root";
+
+# mail from address
+$cfg_from_email = $cfg_admin_email;
+
+# mysql backup
+$cfg_mysql_backup = "no";
+$cfg_mysql_host = "127.0.0.1";
+$cfg_mysql_user = "root";
+$cfg_mysql_pass = "blabla";
+$cfg_mysql_locale = "";
+$cfg_mysql_dump = "mysqldump";
+#$cfg_mysql_dump = "mysqlhotcopy";
+@cfg_mysql_db = ( "All" );
+
+# mongo backup
+$cfg_mongo_backup = "yes";
+$cfg_mongo_host = "";
+$cfg_mongo_user = "";
+$cfg_mongo_pass = "";
+@cfg_mongo_db = ( "all" );
+
+# postgres backup
+$cfg_pgsql_backup = "no";
+$cfg_pgsql_host = "127.0.0.1";
+$cfg_pgsql_user = "root";
+$cfg_pgsql_pass = "blabla";
+$cfg_pgsql_locale = "";
+$cfg_pgsql_dump = "pg_dump";
+#$cfg_pgsql_dump = "pg_dumpall";
+$cfg_pgsql_su = "yes";
+@cfg_pgsql_db = ( "All" );
+
+$cfg_dirlist_file = "/usr/local/etc/dirlist.conf";
+$cfg_exclist_file = "/usr/local/etc/exclist.conf";
+
+#default - no dereference symlink
+$tar_opts="--no-recursion --numeric-owner";
+
+#$tar_opts="--no-recursion --dereference --numeric-owner";

+ 2 - 0
etc/dirlist.conf

@@ -0,0 +1,2 @@
+/etc
+/usr/local/

+ 20 - 0
etc/exclist.conf

@@ -0,0 +1,20 @@
+access_log
+error_log
+lost+found
+^/boot
+^/dev
+^/media
+^/misc
+^/proc
+^/root
+^/sys
+^/tmp
+^/usr/src
+^/var/cache/yum
+^/var/lib/mysql
+^/var/lib/pgsql
+^/var/log
+^/var/named/chroot/proc
+^/var/spool/backup
+^/var/tmp
+^/vz

+ 7 - 0
etc/share.conf

@@ -0,0 +1,7 @@
+HOSTNAME="127.0.0.1"
+USER="bkp@blabla.com"
+PASS="blabla"
+SHARE="backup"
+[ -z "${USER}" ] && USER="guest"
+[ -z "${PASS}" ] && PASS="quest"
+MNT_POINT="/mnt/backup"

+ 1 - 0
rsync/rsyncd.secrets

@@ -0,0 +1 @@
+blablabla

+ 6 - 0
rsync/server.exclude

@@ -0,0 +1,6 @@
+/proc/*
+/sys/*
+/dev/*
+/run/*
+/tmp/*
+/var/lib/mysql/*

+ 22 - 0
rsync/sync-backups-to-ftp

@@ -0,0 +1,22 @@
+#!/bin/bash
+
+. /etc/rsync/sync-functions
+
+########################### SYNC DIR ##########################
+
+WORKDIR="backup"
+ROOTPATH="/mnt/sdb/"
+DELLIMIT="10000000"
+MAXFILES=44
+USERID="backup"
+PASSWDFILE="/etc/rsync/rsyncd.secrets"
+HOST="server"
+MODE=$1
+SETLOCALE="ru_RU.UTF-8"
+OPTS=" --exclude-from /etc/rsync/server.exclude --bwlimit=40m"
+
+sync_share
+
+/usr/local/sbin/backup.pl /usr/local/etc/backup-custom-place.conf
+
+exit

+ 43 - 0
rsync/sync-backups-to-smb

@@ -0,0 +1,43 @@
+#!/bin/bash
+
+. /etc/rsync/sync-functions
+. /usr/local/etc/share.conf
+
+#mounted?
+mount | grep -i "backup" >/dev/null
+
+if [ $? -ne 0 ]; then
+    [ ! -e "${MNT_POINT}" ] && mkdir -p "${MNT_POINT}" >/dev/null
+    OPTS=
+    [ -n "${USER}" ] && OPTS="-o user=${USER}"
+    [ -n "${PASS}" ] && OPTS="$OPTS,pass=${PASS}"
+    /sbin/mount.cifs "\\\\${HOSTNAME}\\${SHARE}" "${MNT_POINT}" $OPTS >/dev/null
+    [ $? -ne 0 ] && exit 10
+    fi
+
+#sync remote rsync path and local folder
+WORKDIR="backup"
+ROOTPATH="/mnt/backup/server"
+DELLIMIT="10000000"
+MAXFILES=44
+USERID="backup"
+PASSWDFILE="/etc/rsync/rsyncd.secrets"
+HOST="server"
+MODE=$1
+SETLOCALE="ru_RU.UTF-8"
+OPTS="--chmod=Du=rwx,Fu=rw,Dg=rwx,Fg=rw --bwlimit=40m"
+
+[ ! -e "${ROOTPATH}" ] && {
+    echo "Backup share not found!"
+    exit 110
+    }
+
+#sync files between remote and local
+sync_share
+
+#append files from remote to local path
+#append_share
+
+umount "${MNT_POINT}" >/dev/null
+
+exit

+ 214 - 0
rsync/sync-functions

@@ -0,0 +1,214 @@
+#!/bin/bash
+
+### sync data
+TM=`date +%y%m%d-%H%M`
+
+WORKDIR=
+ROOTPATH=
+USERID=
+PASSWDFILE=
+HOST=
+OPTS=
+
+BACKUPDIR=
+#max deleted file summary size limit for normal backup
+DELLIMIT="102400000"
+#max deleted file count for normal backup
+MAXFILES=100
+
+LOGDIR="/var/log/rsync"
+ADMINEMAIL="root"
+RSYNC=`which rsync`
+MODE=
+
+SETLOCALE=
+#SETLOCALE="LANG=ru_RU.UTF-8"
+#SETLOCALE="LANG=ru_RU.KOI8-R"
+#ICONV="--iconv=KOI8-R,UTF-8"
+ICONV=
+
+#basename
+BN=`basename $0`
+LOG1="$LOGDIR/$BN.log"
+#lock file for working process
+LOCK1="/var/run/$BN.pid"
+
+#debug
+DEBUG=1
+DEBUG_LOG=${LOG1}
+
+[ ! -e "${LOGDIR}" ] && {
+    mkdir -p ${LOGDIR} >/dev/null 2>&1
+    chmod 750 ${LOGDIR} >/dev/null 2>&1
+    }
+
+
+function log_debug {
+[ "${DEBUG}" -eq 0 ] && return
+TS="`date +%Y%m%d-%H%M%S` DEBUG:"
+echo "$1" | while read LINE; do
+echo "${TS} ${LINE}" >>${DEBUG_LOG}
+done
+}
+
+function log_info {
+TS="`date +%Y%m%d-%H%M%S` INFO:"
+echo "$1" | while read LINE; do
+echo "${TS} ${LINE}" >>${LOG1}
+done
+}
+
+function log_error {
+TS="`date +%Y%m%d-%H%M%S` ERROR:"
+echo "$1" | while read LINE; do
+echo "${TS} ${LINE}" >>${LOG1}
+done
+}
+
+
+function do_exit {
+log_debug "Script work $SECONDS sec. Exit code: $1"
+[ -n $1 ] && exit $1 || exit
+}
+
+function do_exec {
+[ -z "$1" ] && return
+FAIL="OK"
+eval "$1" || { FAIL="FAIL"; }
+log_debug "$1 - $FAIL"
+eval "FAIL=${FAIL}"
+}
+
+function check_run {
+log_debug "Check for always running - search pid-file $LOCK1"
+while [ -f $LOCK1 ]; do
+local PID=`cat $LOCK1`
+if [ -z `ps awx | awk '{ print $1}' | grep "^$PID$"` ]; then
+        log_error "Найден ничейный файл блокировки! pid=$PID. Удаляю! "
+        do_exec "rm -f $LOCK1 >/dev/null 2>&1"
+        else
+        log_error "Скрипт $BN уже запущен pid=$PID. Жду 5 сек..."
+        sleep 5
+        fi
+done
+}
+
+function create_lock {
+log_debug "Check for always running - search pid $LOCK1"
+[ -f $LOCK1 ] && {
+    log_debug "Pid file found. Aborting..."
+    exit 100
+    }
+log_debug "Create pid file $LOCK1"
+do_exec "echo '$$'>$LOCK1"
+}
+
+function remove_lock {
+local PID=`cat $LOCK1`
+if [ $PID -ne $$ ]; then
+        log_error "Файл блокировки принадлежит другому процессу с pid=$PID, мой pid=$$. Exiting... "
+        do_exit 100
+        else
+        log_debug "Remove pid file."
+        do_exec "rm -f $LOCK1 >/dev/null 2>&1"
+        fi
+}
+
+function set_locale {
+[ -z "${SETLOCALE}" ] && return
+export LANG=${SETLOCALE}
+export LC_ALL=${SETLOCALE}
+}
+
+function send_email {
+BODY=$1
+[ ! -e "${BODY}" ] && return
+SUBJ=$2
+set_locale
+[ -z "${SUBJ}" ] && SUBJ="Mail from $BN at $HOSTNAME"
+CHARSET=`locale | grep LANG | awk -F. '{ print $2 }'`
+[ -z "$CHARSET" ] && CHARSET=`cat /etc/sysconfig/i18n  | grep  LANG | awk -F. '{ print $2 }' | sed 's/"//g;'`
+SUBJ=`echo -ne "${SUBJ}\nMIME-Version: 1.0\nContent-Language: ru\nContent-Type: text/html; charset=$CHARSET\nContent-Transfer-Encoding: 8bit"`
+cat "${BODY}" | sed 's/$/<br>/g;' | mail -s "${SUBJ}" "${ADMINEMAIL}"
+}
+
+#-------------------------------------------------------------------------
+
+function sync_data() {
+set_locale
+do_exec "mkdir -p /var/log/rsync"
+TM=`date +%y%m%d-%H%M`
+do_exec "$RSYNC -rltvh $ICONV $OPTS --partial --delete --delete-after --delay-updates --password-file=$1 $2@$3::$4 $5 >$LOGDIR/$3-$4-$TM.log 2>&1"
+send_email "$LOGDIR/$4-$TM.log" "Sync report for $4 at $HOSTNAME"
+}
+
+function append_data() {
+set_locale
+do_exec "mkdir -p /var/log/rsync"
+TM=`date +%y%m%d-%H%M`
+do_exec "$RSYNC -rltvh $ICONV $OPTS --partial --append --password-file=$1 $2@$3::$4 $5 >$LOGDIR/$3-$4-$TM.log 2>&1"
+send_email "$LOGDIR/$4-$TM.log" "Sync report for $4 at $HOSTNAME"
+}
+
+function check_sync() {
+set_locale
+WORKLIST=`$RSYNC -rltn $ICONV $OPTS --out-format="%o %f" --delete --delete-after --delay-updates --password-file=$1 $2@$3::$4 $5`
+DELLIST=`echo "${WORKLIST}" | grep -i "^del." | sed 's/^del. //'`
+RECVLIST=`echo "${WORKLIST}" | grep -i "^recv " | sed 's/^recv //'`
+
+TMP=`mktemp -t rsync.XXXXXXXXXX`
+cat /dev/null >$TMP
+echo "$DELLIST" | while read FN; do
+FF="$ROOTPATH/$WORKDIR/$FN"
+[ -f "$FF" ] && /usr/bin/du -b "$FF" >>$TMP
+done
+
+SD=`cat $TMP | awk '{ s = s + \$1 } END { print s }'`
+[ -z $SD ] && SD="0"
+
+DC=`echo "$DELLIST" | wc -l`
+rm -f $TMP
+
+LIMIT=`expr $SD / $DELLIMIT`
+[ -z $LIMIT ] && LIMIT="0"
+
+if [ $LIMIT -gt 1 -o $DC -gt $MAXFILES ]; then
+    TMP=`mktemp -t rsync.XXXXXXXXXX`
+    echo "On main share $WORKDIR deleted $DC files, total size $SD bytes. List of deleted files:" >$TMP
+    echo >>$TMP
+    echo "$DELLIST" >>$TMP
+    echo >>$TMP
+    echo "New files list: ">>$TMP
+    echo "$RECVLIST" >>$TMP
+    echo >>$TMP
+    echo "Please check share and sync manyally..." >>$TMP
+    eval "ERRFILE=${TMP}"
+    else
+    eval "ERRFILE="
+    fi
+}
+
+function sync_share() {
+if [ "$MODE" != "manual" ]; then
+    check_sync $PASSWDFILE $USERID $HOST $WORKDIR "$ROOTPATH/$BACKUPDIR"
+    if [ -f "$ERRFILE" -a ! -z "$ERRFILE" ]; then
+            if [ -z "$MODE" -o "$MODE" == "viewonly" ]; then
+                    cat $ERRFILE
+                    else
+                    send_email "$ERRFILE" "Warning! Sync $WORKDIR at $HOSTNAME is overlimit!"
+                    fi
+            rm -f $ERRFILE
+            exit 1
+            fi
+    fi
+sync_data $PASSWDFILE $USERID $HOST $WORKDIR "$ROOTPATH/$BACKUPDIR"
+}
+
+function append_share() {
+append_data $PASSWDFILE $USERID $HOST $WORKDIR "$ROOTPATH/$BACKUPDIR"
+}
+
+log_debug "Running $0 $*"
+log_debug "by user $USER($UID) with effective uid:$EUID"
+log_debug "Parent process id: $PPID (`ps --no-heading -o command -p $PPID`)."
+log_debug "Process id: $$"

+ 17 - 0
sbin/backup-vz.sh

@@ -0,0 +1,17 @@
+#!/bin/sh
+
+umask 0077
+
+#backup virtualhosts
+VZL=`which vzlist 2>/dev/null`
+[ -z "${VZL}" ] && exit
+
+VZLIST=`${VZL} -H -o veid | awk '{ print $1 }' 2>/dev/null`
+echo "${VZLIST}" | while read VEID; do
+[ -n "${VEID}" ] && {
+    /usr/local/sbin/backup.pl "/usr/local/etc/backup.conf" "${VEID}" >/dev/null
+    chmod 400 /var/spool/backup/tmp/* >/dev/null 2>&1
+    }
+done
+
+exit

+ 456 - 0
sbin/backup.pl

@@ -0,0 +1,456 @@
+#!/usr/bin/perl
+use Cwd;
+use File::Basename;
+use File::Find;
+use File::stat qw(:FIELDS);
+use File::Spec::Functions;
+use Sys::Hostname;
+use DirHandle;
+use Time::localtime;
+use Fcntl;
+use Tie::File;
+use Net::FTP;
+use Data::Dumper;
+
+my $WAIT_TIME = 10800; # 3 hours
+
+my @FN=split("/",$0);
+my $SPID="/var/run/".$FN[-1];
+
+my $script_name= basename($0);
+
+my $cfg_file = "/usr/local/etc/backup.conf";
+my $ve_id = "";
+my $ve_root = "";
+
+if ($ARGV[0]) { $cfg_file = $ARGV[0]; }
+if ($ARGV[1]) { $ve_id = $ARGV[1]; }
+
+eval {
+#set timeout for script work
+$SIG{ALRM} = sub { die "Maximum worktime $WAIT_TIME sec reached!\n" };
+
+alarm $WAIT_TIME;
+
+if (! -e $cfg_file) { die ("File $cfg_file not found. Die...\n"); }
+
+require $cfg_file;
+
+my $filename = "";
+my $filefrom = "";
+
+
+my $tm = localtime;
+($year,$month,$day,$wday) = ($tm->year+1900,$tm->mon+1,$tm->mday,$tm->wday);
+my $date = sprintf("%04d",$year).sprintf("%02d",$month).sprintf("%02d",$day);
+my $ttop = time;
+my $empty = 0;
+
+@dirlist = ();
+@exclist = ();
+*name = *File::Find::name;
+
+if (!($cfg_tmp_dir ne "" and $cfg_hostname ne "" and $cfg_ftp_hostname ne "" 
+    and $cfg_ftp_username ne "" and $cfg_ftp_password ne "" and $cfg_ftp_path 
+    ne "" and $cfg_full_day ne "" and $cfg_del_files ne ""))  {
+	die ("Not set configuration variables! Die...\n");
+    }
+
+if ($cfg_admin_email eq "" or $cfg_from_email eq "") { $cfg_admin_email = "root"; $cfg_from_email = $cfg_admin_email; }
+if (!$cfg_use_ftp) { $cfg_use_ftp = "no"; }
+if (!$cfg_use_smb) { $cfg_use_smb = "no"; }
+
+if (!$tar_opts) { $tar_opts="--no-recursion"; }
+
+if (IsNotRun($SPID)) { Add_PID($SPID); }
+    else { die ("Warning!!! backup.pl already runnning!\n"); }
+
+if (!$cfg_dirlist_file) { $cfg_dirlist_file ="/usr/local/etc/dirlist.conf"; }
+if (!$cfg_exclist_file) { $cfg_exclist_file ="/usr/local/etc/exclist.conf"; }
+
+if (!$cfg_mysql_dump) { $cfg_mysql_dump = "mysqldump"; }
+
+#for vz container
+if ($ve_id) {
+    $cfg_exclist_file=~s/.conf//;
+    $cfg_exclist_path=$cfg_exclist_file;
+    #if found personal rule - use it
+    if (-e $cfg_exclist_path."-$ve_id.conf") { $cfg_exclist_file=$cfg_exclist_path."-$ve_id.conf"; }
+	else {
+	#use common rule
+        if (-e $cfg_exclist_path."-vz.conf") { $cfg_exclist_file=$cfg_exclist_path."-vz.conf"; }
+	    else {
+	    #if personal and common file not found - use default
+	    $cfg_exclist_file=$cfg_exclist_path.".conf";
+	    }
+	}
+    $ve_root = "/vz/root/$ve_id/";
+    $cfg_hostname=$ve_id;
+    }
+
+if (-e $cfg_dirlist_file) {
+    open (FD,"<",$cfg_dirlist_file);
+    while (<FD>) {
+	chomp;
+        push(@dirlist,$_);
+	}
+    close(FD);
+    die ("Warning!!! no listing dir for backup. Exit.\n") if ($#dirlist eq "-1");
+    }
+    else { die ("File $cfg_dirlist_file not found! die...\n"); }
+
+if (-e $cfg_exclist_file) {
+    open (FD1,"<",$cfg_exclist_file);
+    while (<FD1>) {
+        chomp;
+        my $ex=$_;
+        if ($ve_id) {
+            if ($ex=~/\//) {
+        	if ($ex=~/\^(.*)/) {$ex="^".$ve_root.$1; } else { $ex=$ve_root.$ex; }
+        	$ex=~s/\/\//\//g; 
+        	}
+            }
+	push(@exclist,$ex);
+	}
+    close(FD1);
+    }
+
+#dirlist ignored if backup vz container
+#Left for compatibility
+if ($ve_id) { @dirlist = ( "./" ); }
+
+my $fullbackup = ($cfg_full_day eq $wday);
+
+if ((!$fullbackup) and (! -e "$cfg_status_dir/$cfg_hostname-back_file_size$ve_id.list")) { $fullbackup=1; }
+
+if (!$fullbackup) {
+    open (FHD,">","$cfg_status_dir/$cfg_hostname-back_file_diff$ve_id.list");
+    sub process_file_diff {
+	if ($#exclist eq "-1") {
+	    if (-f) {
+		$info = stat($name);
+		print FHD $info->mtime."	".$info->size."	".$name."\n";
+	    }
+	}else{
+	    if (-f) {
+		$exists = 0;
+		$info = stat($name);
+		for ($i = 0; $i < @exclist; $i++) {
+		    $ii = $exclist[$i];
+		    $exists = ($exists or ($name =~ /$ii/));
+		}
+		if (!$exists) {
+		    print FHD $info->mtime."	".$info->size."	".$name."\n";
+		}
+	    }
+	}
+    }
+    if ($ve_root) { find(\&process_file_diff, $ve_root); }
+	else {
+	foreach $idir (@dirlist) {
+	    find(\&process_file_diff, $idir);
+	    }
+	}
+    close(FHD);
+    system("diff -f $cfg_status_dir/$cfg_hostname-back_file_size$ve_id.list $cfg_status_dir/$cfg_hostname-back_file_diff$ve_id.list | grep / > $cfg_status_dir/$cfg_hostname-file$ve_id.diff");
+    tie @ddiff, Tie::File, "$cfg_status_dir/$cfg_hostname-file$ve_id.diff";
+    if ($#ddiff ne "-1") {
+        open(FDD,">","$cfg_status_dir/$cfg_hostname-back_diff$ve_id.list");
+	foreach $mdiff (@ddiff) {
+	    ($a,$b,$c) = split /\t/,$mdiff;
+	    $a = "";
+	    $b = "";
+	    print FDD $c."\n";
+	}
+	close (FDD);
+        $filename = "$cfg_tmp_dir/$cfg_hostname-inc-$wday.tar.gz";
+	$filefrom = "$cfg_status_dir/$cfg_hostname-back_diff$ve_id.list";
+	}
+	else { $empty=1; }
+    }
+    else{
+    unlink <$cfg_tmp_dir/$cfg_hostname*>;
+    open (FH1,">","$cfg_status_dir/$cfg_hostname-back_file_size$ve_id.list");
+    open (FH2,">","$cfg_status_dir/$cfg_hostname-back_file$ve_id.list");
+    sub process_file {
+	if ($#exclist eq "-1") {
+	    if (-f) {
+		$info = stat($name);
+		print FH1 $info->mtime."	".$info->size."	".$name."\n";
+		print FH2 $name."\n";
+	    }
+	}else{
+	    if (-f) {
+		$exists = 0;
+		for ($i = 0; $i < @exclist; $i++) {
+		    $ii = $exclist[$i];
+		    $exists = ($exists or ($name =~ /$ii/));
+		}
+		if (!$exists) {
+		    $info = stat($name);
+		    print FH1 $info->mtime."	".$info->size."	".$name."\n";
+		    print FH2 $name."\n";
+		}
+	    }
+	}
+    }
+    if ($ve_root) { find(\&process_file, $ve_root); }
+	else {
+        foreach $idir (@dirlist) {
+		find(\&process_file, $idir);
+	    }
+	}
+    close(FH1);
+    close(FH2);
+    $filename = "$cfg_tmp_dir/$cfg_hostname-full-$date.tar.gz";
+    $filefrom = "$cfg_status_dir/$cfg_hostname-back_file$ve_id.list";
+    }
+if ($empty eq 0) {
+my $ret=`tar $tar_opts -czPf $filename --files-from=$filefrom`;
+$tbot = time - $ttop;
+open(FHR,">","$cfg_status_dir/report$ve_id.txt");
+$minfo = stat($filename);
+print FHR sprintf("%-45s %10s %20s\n",basename($filename),$tbot,$minfo->size);
+close(FHR);
+}
+
+my @mysql_backup_files = ();
+my @mongo_backup_files = ();
+my @pgsql_backup_files = ();
+
+if ($cfg_mysql_backup eq "yes") {
+    if ($cfg_mysql_db[0]=~/all/i) {
+	my $run_cmd="echo 'show databases;' | mysql -u \"$cfg_mysql_user\" -h \"$cfg_mysql_host\" -s --password=\"$cfg_mysql_pass\"";
+	if ($cfg_mysql_host!~/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/) {
+		$run_cmd = "echo 'show databases;' | mysql -u \"$cfg_mysql_user\" -S \"$cfg_mysql_host\" -s --password=\"$cfg_mysql_pass\"";
+		}
+	@cfg_mysql_db = `$run_cmd`;
+        chomp(@cfg_mysql_db);
+	}
+    $mysql_path = $0;
+    $mysql_path=~ s/$script_name$/mysqld_backup/;
+
+    $mysql_path=$mysql_path."2" if ($cfg_mysql_dump eq "mysqldump");
+
+    foreach my $db (@cfg_mysql_db) {
+	next if ($db=~/^information_schema$/);
+        $ttop = time;
+	my $lang='';
+	if ($cfg_mysql_locale) { $lang="LANG=".$cfg_mysql_locale." "; }
+	$fname="$cfg_tmp_dir/$cfg_hostname-mysql-$date-$db".".tgz";
+	$ret=`$lang$mysql_path \"$cfg_mysql_host\" \"$cfg_mysql_user\" \"$cfg_mysql_pass\" \"$db\" \"$cfg_tmp_dir/$cfg_hostname-mysql-$date\"`;
+	push (@mysql_backup_files,$fname) if ($? eq 0);
+        $tbot = time - $ttop;
+        open(FHR,">>","$cfg_status_dir/report$ve_id.txt");
+        $minfo = stat($fname);
+        print FHR sprintf("%-45s %10s %20s\n",$fname,$tbot,$minfo->size);
+        close(FHR);
+	}
+    }
+
+if ($cfg_mongo_backup eq "yes") {
+        $mongo_path = $0;
+	$mongo_path=~ s/$script_name$/mongo_backup/;
+        if ($cfg_mysql_db[0]=~/all/i) {
+	        $ttop = time;
+		$fname="$cfg_tmp_dir/$cfg_hostname-mongo-$date-all".".tgz";
+		my $ret=`$mongo_path \"$cfg_mongo_host\" \"$cfg_mongo_user\" \"$cfg_mongo_pass\" \"all\" \"$cfg_tmp_dir/$cfg_hostname-mongo-$date\"`;
+		push (@mongo_backup_files,$fname) if ($? eq 0);
+	        $tbot = time - $ttop;
+	        open(FHR,">>","$cfg_status_dir/report$ve_id.txt");
+	        $minfo = stat($fname);
+	        print FHR sprintf("%-45s %10s %20s\n",$fname,$tbot,$minfo->size);
+	        close(FHR);
+		} else {
+	        foreach my $db (@cfg_mongo_db) {
+		        $ttop = time;
+			$fname="$cfg_tmp_dir/$cfg_hostname-mongo-$date-$db".".tgz";
+			my $ret=`$mongo_path \"$cfg_mongo_host\" \"$cfg_mongo_user\" \"$cfg_mongo_pass\" \"$db\" \"$cfg_tmp_dir/$cfg_hostname-mongo-$date\"`;
+			push (@mongo_backup_files,$fname) if ($? eq 0);
+		        $tbot = time - $ttop;
+		        open(FHR,">>","$cfg_status_dir/report$ve_id.txt");
+		        $minfo = stat($fname);
+		        print FHR sprintf("%-45s %10s %20s\n",$fname,$tbot,$minfo->size);
+		        close(FHR);
+		}
+	}
+    }
+
+if ($cfg_pgsql_backup eq "yes") {
+    $cfg_pgsql_su = "no" if (!$cfg_pgsql_su);
+    open(PGP,">","/root/.pgpass");
+    print PGP "$cfg_pgsql_host:5432:*:$cfg_pgsql_user:$cfg_pgsql_pass";
+    close(PGP);
+    chmod 0400,"/root/.pgpass";
+    chown 0,0,"/root/.pgpass";
+    if ($cfg_pgsql_dump eq "pg_dump") {
+        $pgsql_path = $0;
+	$pgsql_path=~ s/$script_name$/postgres_listdb/;
+        if ($cfg_pgsql_db[0]=~/all/i) {
+		@cfg_pgsql_db = `$lang$pgsql_path \"$cfg_pgsql_su\" \"$cfg_pgsql_host\" \"$cfg_pgsql_user\"`;
+		chomp(@cfg_pgsql_db);
+		}
+        $pgsql_path = $0;
+	$pgsql_path=~ s/$script_name$/postgres_backup1/;
+        foreach my $db (@cfg_pgsql_db) {
+		next if (!$db);
+		my $lang='';
+	        $ttop = time;
+		if ($cfg_pgsql_locale) { $lang="LANG=".$cfg_pgsql_locale." "; }
+		$fname = "$cfg_tmp_dir/$cfg_hostname-pgsql-$date-$db".".tgz";
+		$ret=`$lang$pgsql_path \"$db\" \"$cfg_tmp_dir/$cfg_hostname-pgsql-$date\" \"$cfg_pgsql_su\" \"$cfg_pgsql_host\" \"$cfg_pgsql_user\"`;
+		push (@pgsql_backup_files,$fname) if ($? eq 0);
+	        $tbot = time - $ttop;
+		open(FHR,">>","$cfg_status_dir/report$ve_id.txt");
+	        $minfo = stat($fname);
+		print FHR sprintf("%-45s %10s %20s\n",$fname,$tbot,$minfo->size);
+	        close(FHR);
+	    }
+        } else {
+        $pgsql_path = $0;
+	$pgsql_path=~ s/$script_name$/postgres_backup2/;
+	my $lang='';
+        $ttop = time;
+	if ($cfg_pgsql_locale) { $lang="LANG=".$cfg_pgsql_locale." "; }
+	$fname = "$cfg_tmp_dir/$cfg_hostname-pgsql-$date-$cfg_hostname".".tgz";
+	$ret=`$lang$pgsql_path \"$cfg_tmp_dir/$cfg_hostname-pgsql-$date\" \"$cfg_pgsql_su\"  \"$cfg_pgsql_user\" \"$cfg_pgsql_host\" \"$cfg_hostname\"`;
+	push (@pgsql_backup_files,$fname) if ($? eq 0);
+        $tbot = time - $ttop;
+	open(FHR,">>","$cfg_status_dir/report$ve_id.txt");
+        $minfo = stat($fname);
+	print FHR sprintf("%-45s %10s %20s\n",$fname,$tbot,$minfo->size);
+        close(FHR);
+	}
+    unlink "/root/.pgpass";
+    }
+
+if ($cfg_use_ftp ne "no") {
+
+    $ftp = Net::FTP->new($cfg_ftp_hostname,Timeout => 30,Passive => $cfg_ftp_mode);
+
+    die("Can't connect to $cfg_ftp_hostname !\n") if (!$ftp);
+    die ("Couldn't authenticate, even with explicit username and password.\n") if (!$ftp->login($cfg_ftp_username,$cfg_ftp_password));
+
+    if (!$ftp->cwd($cfg_ftp_path)) {
+	if ($ftp->mkdir ($cfg_ftp_path,1)) { $ftp->cwd($cfg_ftp_path); }
+	    else { die ("Can't create directory $cfg_ftp_path at $cfg_ftp_hostname! Die...\n"); }
+	}
+    $ftp->binary();
+    if ($filename) {
+        die ("Can't put backup $filename to $cfg_ftp_hostname!\n") if (!$ftp->put($filename));
+	}
+    foreach $db (@mysql_backup_files) {
+    die ("Can't put $db to $cfg_ftp_hostname!\n") if (!$ftp->put("$db"));
+    }
+    foreach $db (@pgsql_backup_files) {
+    die ("Can't put $db to $cfg_ftp_hostname!\n") if (!$ftp->put("$db"));
+    }
+
+    $ftp->put("$cfg_status_dir/report$ve_id.txt");
+    $ftp->quit();
+    };
+
+if ($cfg_use_smb ne "no") {
+    my $smb_path=$0;
+    $smb_path=~ s/$script_name$/smb_copy/;
+    my $ret=`$smb_path \"$cfg_smb_hostname\" \"$cfg_smb_username\" \"$cfg_smb_password\" \"$cfg_smb_share\" \"$cfg_smb_path\" \"$filename\"`;
+    my $res = $?;
+    die "$ret" if ($res);
+    foreach $db (@mysql_backup_files) {
+        `$smb_path \"$cfg_smb_hostname\" \"$cfg_smb_username\" \"$cfg_smb_password\" \"$cfg_smb_share\" \"$cfg_smb_path\" \"$db\"`;
+	$res = $?;
+        die "$ret" if ($res);
+	}
+    foreach $db (@mongo_backup_files) {
+        die ("Can't put $db to $cfg_ftp_hostname!\n") if (!$ftp->put("$db"));
+	}
+    foreach $db (@pgsql_backup_files) {
+        `$smb_path \"$cfg_smb_hostname\" \"$cfg_smb_username\" \"$cfg_smb_password\" \"$cfg_smb_share\" \"$cfg_smb_path\" \"$db\"`;
+	$res = $?;
+        die "$ret" if ($res);
+	}
+    }
+
+unlink <$cfg_tmp_dir/$cfg_hostname*> if ($cfg_del_files eq "yes");
+$SIG{ALRM} = 'DEFAULT';
+};
+
+if ($@) { abort($cfg_admin_email,$cfg_from_email,"Script aborted. Error: $@\n",$SPID); };
+
+if (IsMyPID($SPID)) { Remove_PID($SPID); };
+
+exit 0;
+
+#---------------------------------------------------------------------------------------------------------
+
+sub sendEmail
+{
+my ($to, $from, $subject, $message) = @_;
+my $sendmail = '/usr/lib/sendmail';
+open(MAIL, "|$sendmail -oi -t");
+print MAIL "From: $from\n";
+print MAIL "To: $to\n";
+print MAIL "Subject: $subject\n\n";
+print MAIL "$message\n";
+close(MAIL);
+}
+
+#---------------------------------------------------------------------------------------------------------
+
+sub abort {
+my ($to,$from,$message, $pid) = @_;
+sendEmail ($to,$from,"Backup error at $cfg_hostname!",$message);
+if (IsMyPID($pid)) { Remove_PID($pid); };
+die ($message);
+}
+
+#---------------------------------------------------------------------------------------------------------
+
+sub IsNotRun {
+my $pname = shift;
+my $lockfile = $pname.".pid";
+if (! -e $lockfile) { return 1; }
+open (FF,"<$lockfile") or die "can't open file $lockfile: $!";
+my $lockid = <FF>;
+close(FF);
+if ($lockid eq $$) { return 1; }
+my $process_count = `ps axwu | awk '\{ print \$2 \}' | grep $lockid | wc -l`;
+if ($process_count lt 1) { unlink $lockfile; return 1; }
+return 0;
+}
+
+#---------------------------------------------------------------------------------------------------------
+
+sub IsMyPID {
+my $pname = shift;
+my $lockfile = $pname.".pid";
+if (! -e $lockfile) { return 0; }
+open (FF,"<$lockfile") or die "can't open file $lockfile: $!";
+my $lockid = <FF>;
+close(FF);
+if ($lockid eq $$) { return 1; }
+return 0;
+}
+
+#---------------------------------------------------------------------------------------------------------
+
+sub Add_PID {
+my $pname = shift;
+my $lockfile = $pname.".pid";
+open (FF,">$lockfile") or die "can't open file $lockfile: $!";
+flock(FF,2) or die "can't flock $lockfile: $!";
+print FF $$;
+close(FF);
+return 1;
+}
+
+#---------------------------------------------------------------------------------------------------------
+
+sub Remove_PID {
+my $pname = shift;
+my $lockfile = $pname.".pid";
+if (! -e $lockfile) { return 1; }
+unlink $lockfile or return 0;
+return 1;
+}
+

+ 22 - 0
sbin/backup.sh

@@ -0,0 +1,22 @@
+#!/bin/sh
+
+umask 0077
+renice +19 -p $$ >/dev/null 2>&1
+
+[ ! -e /var/spool/backup ] && mkdir -p /var/spool/backup
+[ ! -e /var/spool/backup/tmp ] && mkdir -p /var/spool/backup/tmp
+
+#postgres backup enabled?
+cfg_pgsql_backup=`grep cfg_pgsql_backup /usr/local/etc/backup.conf | awk -F= '{ print $2 }' | sed 's/"//g;s/ //g;s/;//g;s/no//i'`
+[ -z "${cfg_pgsql_backup}" ] && b_group=root || b_group=postgres
+
+chown root:${b_group} -R /var/spool/backup
+chmod 750 /var/spool/backup/tmp >/dev/null 2>&1
+chmod 750 /var/spool/backup >/dev/null 2>&1
+/usr/local/sbin/backup.pl >/dev/null
+
+chown root:${b_group} -R /var/spool/backup
+chmod 640 /var/spool/backup/tmp/* >/dev/null 2>&1
+chmod 640 /var/spool/backup/* >/dev/null 2>&1
+
+exit 0

+ 36 - 0
sbin/mongo_backup

@@ -0,0 +1,36 @@
+#!/bin/bash
+
+[ $# -ne 5 ] && exit 6
+
+DBHOST=${1}
+DBUSER=${2}
+DBPASS=${3}
+DATABASE=${4}
+BACKUP_DIR=${5}
+
+MDUMP=`which mongodump`
+
+[ -z "${MDUMP}" ] && exit 200
+[ -z "${BACKUP_DIR}" -o "${BACKUP_DIR}" == "/" ] && exit 200
+
+[ -e "${BACKUP_DIR}/${DATABASE}" ] && rm -rf "${BACKUP_DIR}/${DATABASE}"
+[ ! -e "${BACKUP_DIR}/${DATABASE}" ] && mkdir -p "${BACKUP_DIR}/${DATABASE}" >/dev/null
+
+HOST=
+[ -n "${DBHOST}" ] && HOST="-h ${DBHOST}"
+USER=
+[ -n "${DBUSER}" ] && USER="-u ${DBUSER}"
+PASS=
+[ -n "${DBPASS}" ] && PASS="-p ${DBPASS}"
+DB=
+[ -n "${DATABASE}" -a "${DATABASE}" != "all" ] && DB="-d ${DATABASE}"
+
+$MDUMP ${HOST} ${USER} ${PASS} ${DB} -o "${BACKUP_DIR}/${DATABASE}" >/dev/null
+
+[ $? -ne 0 ] && exit 100
+
+tar -czf "${BACKUP_DIR}-${DATABASE}.tgz" "${BACKUP_DIR}/${DATABASE}" >/dev/null 2>&1
+ret=$?
+rm -rf "${BACKUP_DIR}" >/dev/null
+
+exit ${ret}

+ 38 - 0
sbin/mysqld_backup

@@ -0,0 +1,38 @@
+#!/bin/bash
+
+[ $# -ne 5 ] && exit 6
+
+DBHOST=${1}
+DBUSER=${2}
+DBPASS=${3}
+DATABASE=${4}
+BACKUP_DIR=${5}
+
+BUG=`echo "${DATABASE}" | sed 's/ //g' | grep -i "^information_schema$"`
+[ -n "${BUG}" ] && exit 0
+
+HOTCOPY=`which mysqlhotcopy`
+
+[ -z "${HOTCOPY}" ] && exit
+[ -z "${BACKUP_DIR}" -o "${BACKUP_DIR}" == "/" ] && exit
+
+[ -e "${BACKUP_DIR}" ] && rm -rf "${BACKUP_DIR}"
+[ ! -e "${BACKUP_DIR}" ] && mkdir -p "${BACKUP_DIR}" >/dev/null
+
+use_ip=$(echo "${DBHOST}" | egrep "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$")
+
+if [ -z "${use_ip}" ]; then
+    OPTS="-S ${DBHOST}"
+    else
+    OPTS="-h ${DBHOST}"
+    fi
+
+$HOTCOPY -u "${DBUSER}" -p "${DBPASS}" ${OPTS} --allowold -q "${DATABASE}" "${BACKUP_DIR}" >/dev/null
+
+[ $? -ne 0 ] && exit 100
+
+tar -czf "${BACKUP_DIR}-${DATABASE}.tgz" "${BACKUP_DIR}/${DATABASE}" >/dev/null 2>&1
+ret=$?
+rm -rf "${BACKUP_DIR}" >/dev/null
+
+exit ${ret}

+ 52 - 0
sbin/mysqld_backup2

@@ -0,0 +1,52 @@
+#!/bin/bash
+
+[ $# -ne 5 ] && exit 6
+
+DBHOST=${1}
+DBUSER=${2}
+DBPASS=${3}
+DATABASE=${4}
+BACKUP_DIR=${5}
+
+BUG=`echo "${DATABASE}" | sed 's/ //g' | grep -i "^information_schema$"`
+[ -n "${BUG}" ] && exit 0
+
+MDUMP=`which mysqldump`
+MSQL=`which mysql`
+
+[ -z "${MDUMP}" ] && exit 200
+[ -z "${BACKUP_DIR}" -o "${BACKUP_DIR}" == "/" ] && exit 200
+
+[ -e "${BACKUP_DIR}/${DATABASE}" ] && rm -rf "${BACKUP_DIR}/${DATABASE}"
+[ ! -e "${BACKUP_DIR}/${DATABASE}" ] && mkdir -p "${BACKUP_DIR}/${DATABASE}" >/dev/null
+
+BUG_26121=`${MDUMP} --help | grep skip-lock-tables`
+
+if [ -z "${BUG_26121}" ]; then
+    FIX_26121="--lock-tables=0"
+    else
+    FIX_26121="--skip-lock-tables"
+    fi
+
+use_ip=$(echo "${DBHOST}" | egrep "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$")
+
+if [ -z "${use_ip}" ]; then
+    OPTS="-S ${DBHOST}"
+    else
+    OPTS="--host=${DBHOST}"
+    fi
+
+${MDUMP} --user="${DBUSER}" --password="${DBPASS}" ${OPTS} "${FIX_26121}" --quick --single-transaction --routines --skip-triggers --hex-blob --no-data ${DATABASE} | sed -e 's/\/\*\![0-9][0-9]* *DEFINER[^\*]*\*\///g' > ${BACKUP_DIR}/${DATABASE}/__structure.sql
+[ $? -ne 0 ] && exit 101
+${MDUMP} --user="${DBUSER}" --password="${DBPASS}" ${OPTS} "${FIX_26121}" --quick --single-transaction --triggers --hex-blob --no-data --skip-add-drop-table --no-create-info ${DATABASE} | sed -e 's/\/\*\![0-9][0-9]* *DEFINER[^\*]*\*\///g' > ${BACKUP_DIR}/${DATABASE}/__triggers.sql
+
+TABLE_LIST=`${MSQL} --user="${DBUSER}" --password="${DBPASS}" ${OPTS} --disable-pager -B -e "show tables;" --skip-column-names -q --silent ${DATABASE}`
+echo "${TABLE_LIST}" | while read TB; do
+[ -n "${TB}" ] && ${MDUMP} --user="${DBUSER}" --password="${DBPASS}" ${OPTS} "${FIX_26121}" --quick --skip-add-drop-table --no-create-info ${DATABASE} ${TB} >${BACKUP_DIR}/${DATABASE}/${TB}.sql
+done
+
+tar -czf "${BACKUP_DIR}-${DATABASE}.tgz" "${BACKUP_DIR}/${DATABASE}" >/dev/null 2>&1
+ret=$?
+rm -rf "${BACKUP_DIR}" >/dev/null
+
+exit ${ret}

+ 39 - 0
sbin/postgres_backup1

@@ -0,0 +1,39 @@
+#!/bin/bash
+
+[ $# -ne 5 ] && exit 6
+
+PGDUMP=`which pg_dump`
+DB_NAME=${1}
+BACKUP_DIR=${2}
+USE_SU=${3}
+HOST=${4}
+USER=${5}
+
+PG_OPTS1=
+PG_OPTS2=
+[ -z "$DB_NAME" ] && exit
+[ -n "${USER}" ] && PG_OPTS1="-U ${USER}"
+[ -n "${HOST}" ] && PG_OPTS2="-h ${HOST}"
+
+[ ! -e "${BACKUP_DIR}/${DB_NAME}" ] && mkdir -p "${BACKUP_DIR}/${DB_NAME}"
+chown -R postgres:root "${BACKUP_DIR}"
+chmod 750 -R "${BACKUP_DIR}"
+find "${BACKUP_DIR}" -type f -exec chmod 640 {} \;
+
+if [ "${USE_SU}" == "no" ]; then
+    $PGDUMP ${PG_OPTS1} ${PG_OPTS2} -f "${BACKUP_DIR}/${DB_NAME}/${DB_NAME}.sql" $DB_NAME
+    ret=$?
+    else
+    su postgres -c "$PGDUMP ${PG_OPTS1} ${PG_OPTS2} -f \"${BACKUP_DIR}/${DB_NAME}/${DB_NAME}.sql\" $DB_NAME"
+    ret=$?
+    fi
+
+if [ ${ret} -eq 0 ]; then
+        FNAME="${BACKUP_DIR}-${DB_NAME}.tgz"
+        tar c -z -f $FNAME "${BACKUP_DIR}/${DB_NAME}/${DB_NAME}.sql" >/dev/null 2>&1
+        ret=$?
+        fi
+
+rm -rf "${BACKUP_DIR}"
+
+exit ${ret}

+ 38 - 0
sbin/postgres_backup2

@@ -0,0 +1,38 @@
+#!/bin/bash
+
+[ $# -ne 5 ] && exit 6
+
+PGDUMP=`which pg_dumpall`
+BACKUP_DIR=${1}
+USE_SU=${2}
+USER=${3}
+HOST=${4}
+DB_NAME=${5}
+
+PG_OPTS1=
+PG_OPTS2=
+[ -n "${USER}" ] && PG_OPTS1="-U ${USER}"
+[ -n "${HOST}" ] && PG_OPTS2="-h ${HOST}"
+
+[ ! -e "${BACKUP_DIR}/${DB_NAME}" ] && mkdir -p "${BACKUP_DIR}/${DB_NAME}"
+chown -R postgres:root "${BACKUP_DIR}"
+chmod 750 -R "${BACKUP_DIR}"
+find "${BACKUP_DIR}" -type f -exec chmod 640 {} \;
+
+if [ "${USE_SU}" == "no" ]; then
+    $PGDUMP ${PG_OPTS1} ${PG_OPTS2} -f "${BACKUP_DIR}/${DB_NAME}/${DB_NAME}.sql"
+    ret=$?
+    else
+    su postgres -c "$PGDUMP ${PG_OPTS1} ${PG_OPTS2} -f \"${BACKUP_DIR}/${DB_NAME}/${DB_NAME}.sql\""
+    ret=$?
+    fi
+
+if [ ${ret} -eq 0 ]; then
+        FNAME="${BACKUP_DIR}-${DB_NAME}.tgz"
+        tar c -z -f $FNAME "${BACKUP_DIR}/${DB_NAME}/${DB_NAME}.sql" >/dev/null 2>&1
+        ret=$?
+        fi
+
+rm -rf "${BACKUP_DIR}"
+
+exit ${ret}

+ 24 - 0
sbin/postgres_listdb

@@ -0,0 +1,24 @@
+#!/bin/bash
+
+[ $# -lt 1 ] && exit 6
+
+PSQL=`which psql`
+
+USE_SU=${1}
+HOST=${2}
+USER=${3}
+
+PG_OPTS1=
+PG_OPTS2=
+[ -n "${USER}" ] && PG_OPTS1="-U ${USER}"
+[ -n "${HOST}" ] && PG_OPTS2="-h ${HOST}"
+
+if [ "${USE_SU}" == "no" ]; then
+    $PSQL -l ${PG_OPTS1} ${PG_OPTS2} -t -x | grep Name | awk '{ print $3 }' | grep -v template
+    ret=$?
+    else
+    su postgres -c "$PSQL -l ${PG_OPTS1} ${PG_OPTS2} -t -x | grep Name | awk '{ print \$3 }' | grep -v template"
+    ret=$?
+    fi
+
+exit ${ret}

+ 36 - 0
sbin/smb_copy

@@ -0,0 +1,36 @@
+#!/bin/bash
+
+[ $# -ne 6 ] && exit 6
+
+HOSTNAME=${1}
+USER=${2}
+PASS=${3}
+SHARE=${4}
+DIR=${5}
+FILE=${6}
+
+[ -z "${USER}" ] && USER="guest"
+[ -z "${PASS}" ] && PASS="quest"
+
+MNT_POINT="/mnt/${HOSTNAME}-${SHARE}"
+
+#mounted?
+mount | grep -i "${SHARE}" >/dev/null
+
+if [ $? -ne 0 ]; then
+    [ ! -e "${MNT_POINT}" ] && mkdir -p "${MNT_POINT}" >/dev/null
+    OPTS=
+    [ -n "${USER}" ] && OPTS="-o user=${USER}"
+    [ -n "${PASS}" ] && OPTS="$OPTS,password=${PASS}"
+    /sbin/mount.cifs "\\\\${HOSTNAME}\\${SHARE}" "${MNT_POINT}" $OPTS >/dev/null
+    [ $? -ne 0 ] && exit 10
+    fi
+
+[ ! -e "${MNT_POINT}/${DIR}" ] && mkdir -p "${MNT_POINT}/${DIR}" >/dev/null
+
+cp -f "${FILE}" "${MNT_POINT}/${DIR}" >/dev/null
+ret=$?
+
+umount "${MNT_POINT}" >/dev/null
+
+exit ${ret}