| Server IP : 37.9.174.138 / Your IP : 216.73.216.117 Web Server : Apache System : Linux vps6.backend.sk 6.12.100+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.100-1 (2026-07-30) x86_64 User : ftpuser ( 1001) PHP Version : 8.4.24 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /proc/thread-self/root/usr/share/backup-manager/ |
Upload File : |
# Copyright � 2005-2016 The Backup Manager Authors
#
# See the AUTHORS file for details.
#
# 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.
# All functions dedicated to manage the files.
#unmount_tmp_dir()
#{
# if [[ -n "$mount_point" ]] &&
# [[ -d $mount_point ]] &&
# [[ grep $mount_point /etc/mtab >/dev/null 2>&1 ]]; then
# umount "$mount_point" > /dev/null 2>&1 || error "unable to unmount \$mount_point"
# sleep 1
# rmdir "$mount_point" > /dev/null 2>&1 || error "unable to remove \$mount_point"
# fi
#}
# detect if find supports -H
find_opt=""
if find -H /tmp > /dev/null 2>&1 ; then
find_opt="-H"
fi
# this will send the appropriate name of archive to
# make according to what the user choose in the conf.
function get_dir_name()
{
base="$1"
format="$2"
debug "get_dir_name ($base, $format)"
if [[ "$format" = "long" ]]
then
# first remove the trailing slash
base=${base%/}
# every space by a _
dirname=$(echo "$base" | sed 's/ /_/g')
# every / by a -
dirname=$(echo "$dirname" | sed 's/\//-/g')
elif [[ "$format" = "short" ]]
then
OLDIFS=$IFS
export IFS="/"
for directory in $base
do
parent=$directory
done
dirname=-$directory
export IFS=$OLDIFS
else
echo ""
fi
echo "$dirname"
}
# This will take a path and return the size in mega bytes
# used on the disk.
# Thanks to Michel Grentzinger <mic.grentz@online.fr>
function size_of_path()
{
path="$1"
debug "size_of_path ($path)"
if [[ -z "$path" ]]; then
error "No path given."
fi
#echo "DEBUG: du --si --block-size=1000k -c $path | tail -n 1 | awk '{print $1}'" >&2
total_size=$(du --si --block-size=1000k -c $path | tail -n 1 | awk '{print $1}')
echo $total_size
}
# Thanks to Michel Grentzinger <mic.grentz@online.fr>
function size_left_of_path()
{
path="$1"
debug "size_left_of_path ($path)"
if [[ -z "$path" ]]; then
error "No path given."
fi
left=$(df --si --block-size=1000k "$path" | tail -n 1 | awk '{print $4}')
echo $left
}
# Will return the prefix contained in the file name
function get_prefix_from_file()
{
filename="$1"
debug "get_prefix_from_file ($filename)"
filename=$(basename $filename)
prefix=$(echo $filename | sed -e 's/^\([^-]\+\)-.*$/\1/')
echo $prefix
}
# Will return the date contained in the file name
function get_date_from_file()
{
debug "get_date_from_file ($1)"
get_date_from_archive "$1"
}
# This function is here to free each lock previously enabled.
# We have to keep in mind that lock must be done for each conffile.
# It is not global anymore, and that's the tricky thing.
function release_lock()
{
debug "release_lock()"
if [[ -e $lockfile ]]; then
# We have to remove the line which contains
# the conffile.
newfile=$(mktemp ${BM_TEMP_DIR}/lock.XXXXXX)
newcontent=""
OLDIFS=$IFS
IFS=$'\n'
for line in $(cat $lockfile)
do
thisfile=$(echo $line | awk '{print $2}')
if [[ ! $conffile = $thisfile ]]; then
echo "$line" >> $newfile
fi
done
IFS=$OLDIFS
mv $newfile $lockfile
fi
}
# This function try to get a lock, if this is not possible,
# backup-manager won't run.
# Be aware that a there will be one lock for each conffile used.
# If the PID written in the lockfile is not alive, release.
function get_lock()
{
debug "get_lock()"
if [[ -e $lockfile ]]; then
# look if a lock exists for that conffile (eg, we must find
# the path of the conffile in the lockfile)
# lockfile format :
# $pid $conffile
pid=`grep " $conffile " $lockfile | awk '{print $1}'`
# be sure that the process is running
if [[ ! -z $pid ]]; then
unamestr=`uname | xargs | awk '{print tolower($0)}'`
# For OSX & fink :
if [[ "$unamestr" == 'darwin' ]]; then
real_pid=$(ps -p $pid |tail -n +2 |awk '{print $1}')
else
real_pid=$(ps --no-headers --pid $pid |awk '{print $1}')
fi
if [[ -z $real_pid ]]; then
echo_translated "Removing lock for old PID, \$pid is not running."
release_lock
#unmount_tmp_dir
pid=""
fi
fi
if [[ -n "$pid" ]]; then
# we really must not use error or _exit here !
# this is the special point were release_lock should not be called !
echo_translated "A backup-manager process (\$pid) is already running with the conffile \$conffile"
exit 1
else
pid=$$
info "Getting lock for backup-manager \$pid with \$conffile"
echo "$$ $conffile " >> $lockfile
fi
else
pid=$$
info "Getting lock for backup-manager \$pid with \$conffile"
echo "$$ $conffile " > $lockfile
if [[ ! -e $lockfile ]]; then
error "failed (check the file permissions)."
exit 1
fi
fi
}
function get_date_from_archive()
{
file="$1"
debug "get_date_from_archive ($file)"
date=$(echo $file | sed -e 's/.*\(20[0-9][0-9][0-9][0-9][0-3][0-9]\).*/\1/')
echo "$date"
}
# Returns the name of an archive.
# eg: get_name_from_archive "ouranos-usr-bin.20060329.tar.bz2"
# usr-bin
function get_name_from_archive()
{
archive="$1"
debug "get_name_from_archive ($archive)"
archive=$(basename "$archive")
# drop the first token before a dash (the prefix)
name="${archive#*-}"
# drop the right part: everything from the first dot
name="${name%%.*}"
# done
echo "$name"
}
function get_master_from_archive()
{
archive="$1"
debug "get_master_from_archive ($archive)"
archive=$(basename "$archive")
master=$(echo "$archive" | sed -e 's/.*\.\(master\)\..*/\1/')
if [[ "$master" = "master" ]]; then
echo "true"
else
echo "false"
fi
}
function get_prefix_from_archive()
{
archive="$1"
archive=$(basename "$archive")
echo "${archive%%-*}"
}
function get_newer_master()
{
prefix="$1"
name="$2"
date="$3"
debug "get_newer_master ($prefix, $name, $date)"
master=""
for this_master in $BM_REPOSITORY_ROOT/$prefix-$name.*.master.*
do
this_date=$(get_date_from_archive "$this_master")
# is this master newer than the one we are testing?
if [[ "$this_date" -gt "$date" ]]; then
debug "found this newer master : $this_master"
master="$this_master"
fi
done
echo "$this_master"
}
function clean_file()
{
file="$1"
purge_date="$2"
debug "clean_file ($file, $purge_date)"
if [[ ! -f "$file" ]]; then
error "\$file is not a regular file."
fi
prefix=$(get_prefix_from_archive "$file")
date=$(get_date_from_archive "$file")
name=$(get_name_from_archive "$file")
master=$(get_master_from_archive "$file")
debug "parsing $file ($prefix, $date, $name, $master)"
# we assume that if we find that, we have an archive
if [[ -n "$date" ]] && [[ "$date" != "$(basename $file)" ]] &&
[[ -n "$prefix" ]] && [[ "$prefix" != "$(basename $file)" ]] &&
[[ -n "$name" ]] && [[ "$name" != "$(basename $file)" ]]; then
# look if the archive is obsolete
if [[ "$date" -lt "$purge_date" ]] ||
[[ "$date" = "$purge_date" ]]; then
# if it's a master, we have to find a newer master around
if [[ "$master" = "true" ]]; then
master_archive=$(get_newer_master "$prefix" "$name" "$date")
# if the master returned is not the same as the one we have,
# the one we have can be deleted, because it's older.
if [[ "$master_archive" != "$file" ]]; then
info "Removing obsolete master backup: \"\$file\"."
rm -f "$file"
# else, we can only remove the master archive if we cannot find any
# incremental archive related.
else
nb_incrementals=$(ls -l $BM_REPOSITORY_ROOT/$prefix-$name.*.* | wc -l)
if [[ "$nb_incrementals" = "1" ]]; then
info "Removing obsolete master backup (isolated): \"\$file\"."
rm -f $file
fi
fi
# the archive we handle isn't a master backup, we can drop it.
else
info "Removing archive \"\$file\"."
rm -f "$file"
fi
fi
fi
}
# clean one given repository.
# This will take each file that has
# a date in its names and will compare
# the file's date to the date_to_remove.
# If the file's date is older than the date_to_remove
# we drop the file.
function clean_directory()
{
directory="$1"
debug "clean_directory ($directory)"
purge_date=$(date +%Y%m%d --date "$BM_ARCHIVE_TTL days ago")
if [[ ! -d $directory ]]; then
error "Directory given was not found."
fi
if [[ "$BM_REPOSITORY_RECURSIVEPURGE" = "true" ]]; then
maxdepth=""
else
maxdepth="-maxdepth 1"
fi
# First list all the files to process
# and ask backup-manager-purge what to remove
list=$(mktemp ${BM_TEMP_DIR}/bm-list.XXXXXX)
# files & symlinks
find $find_opt "$directory" $maxdepth \
\( -type f -o -type l \) -print \
| $bmp --ttl=$BM_ARCHIVE_TTL > $list
# Then actually remove the files
for archive in `cat $list`
do
info "Removing archive \"\$archive\"."
rm -f $archive
done
rm -f $list
}
# This takes a file and the md5sum of that file.
# It will look at every archives of the same source
# and will replace duplicates (same size) by symlinks.
# CONDITION: BM_ARCHIVE_PURGEDUPS = true
function purge_duplicate_archives()
{
file_to_create="$1"
if [[ -z "$2" ]]; then
debug "purge_duplicate_archives ($file_to_create)"
md5hash=$(get_md5sum $file_to_create)
else
# if the 2nd argument exists, it is the md5sum
md5hash="$2"
debug "purge_duplicate_archives ($file_to_create, $md5hash)"
fi
# Only purge if BM_ARCHIVE_PURGEDUPS = true
if [[ -z "$BM_ARCHIVE_PURGEDUPS" ]] ||
[[ "$BM_ARCHIVE_PURGEDUPS" != "true" ]]; then
return 0
fi
if [[ ! -e $file_to_create ]]; then
error "The given file does not exist: \$file_to_create"
return 1
fi
if [[ -z "$file_to_create" ]]; then
error "No file given."
fi
# we'll parse all the files of the same source
date_of_file=$(get_date_from_file $file_to_create) ||
error "Unable to get date from file."
if [[ -z "$date_of_file" ]]; then
error "Unable to get date from file."
fi
file_pattern=$(echo $file_to_create | sed -e "s/\\(.*\\)$date_of_file/\\1\*/") ||
error "Unable to find the pattern of the file."
# loop on each archive occurences (eg: archivename-*-filetype)
for file in $file_pattern
do
# handle only regular files
if [[ ! -L $file ]] && [[ "$file" != "$file_to_create" ]]; then
# get the date of the file we parse
date_of_file=$(get_date_from_file $file) ||
error "Unable to get date from file."
# get the md5 hash of the file we parse, in its .md5 file
md5sum_to_check="$(get_md5sum_from_file $file $MD5FILE)"
if [[ -z "$md5sum_to_check" ]]; then
warning "Unable to find the md5 hash of file \"\$file\" in file \"\$MD5FILE\"."
continue
fi
# if the md5 hashes are the same, purge the duplicate
if [[ "$md5hash" = "$md5sum_to_check" ]]; then
info "\$file is a duplicate of \$file_to_create (using symlink)."
rm -f $file
ln -s $file_to_create $file
fi
fi
done
}
function assert_file_exists() {
file="$1"
if [[ ! -r "$file" ]]; then
warning "File '\$file' does not exist or is not readable."
return 1
fi
}
function assert_file_is_executable() {
file="$1"
if [[ ! -x "$file" ]]; then
warning "File '\$file' is not executable"
return 1
fi
}