| 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 : /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.
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#
# CD/DVD discs burning features
#
function bm_safe_unmount
{
device="$1"
debug "bm_safe_unmount($device)"
realdevice=$(ls -l $device | awk '{print $10}')
if [[ -n "$realdevice" ]]; then
device="$realdevice"
fi
for m in `grep $device /etc/mtab 2>/dev/null| awk '{print $2}'`
do
info "Device \"/dev/\$device\" is mounted on \"\$m\", unmounting it."
umount $m 2>/dev/null
sleep 1
done
}
# This will get all the md5 sums of the day,
# mount the BM_BURNING_DEVICE on /tmp/device and check
# that the files are correct with md5 tests.
function check_cdrom_md5_sums()
{
debug "check_cdrom_md5_sums()"
has_error=0
if [[ -z $BM_BURNING_DEVICE ]]; then
error "MD5 checkup is only performed on disks. Please set the BM_BURNING_DEVICE in \$conffile"
fi
# first create the mount point
mount_point="$(mktemp -d ${BM_TEMP_DIR}/bm-mnt.XXXXXX)"
if [[ ! -d $mount_point ]]; then
error "The mount point \$mount_point is not there."
fi
# if MD5FILE does not exist, there are no md5 sums to compare anyway
if [[ ! -f $MD5FILE ]]; then
error "Missing md5 sums database ($MD5FILE); cannot check md5 sums."
fi
# unmount if needed
bm_safe_unmount $BM_BURNING_DEVICE
# mount the device in /tmp/
info "Mounting \$BM_BURNING_DEVICE on \$mount_point."
mount $BM_BURNING_DEVICE $mount_point >& /dev/null
export HAS_MOUNTED=1
# now we can check the md5 sums.
for file in $mount_point/*[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]*
do
base_file=$(basename $file)
date_of_file=$(get_date_from_file $file)
prefix_of_file=$(get_prefix_from_file $file)
# Do not check the md5 sums of indexes.
if [[ "$prefix_of_file" = "index" ]]; then
continue
fi
str=$(echo_translated "Checking MD5 sum for \$base_file:")
# try to read the previously saved md5 hash in the database
md5hash_trust=$(get_md5sum_from_file ${base_file} $MD5FILE)
# If the MD5 hash was not found, do not generate it; instead
# issue a warning that the burned archive cannot be verified
if [[ -z "$md5hash_trust" ]]; then
warning "Cannot verify correct burning of $base_file; did not found md5 sum in database"
continue
fi
# now calculate burnt archive's md5 sum and compare with database
md5hash_cdrom=$(get_md5sum $file) || md5hash_cdrom="undefined"
case $md5hash_cdrom in
$md5hash_trust)
echo_translated "\$str ok."
;;
undefined)
echo_translated "\$str failed (read error)."
has_error=1
;;
*)
echo_translated "\$str failed (MD5 hash mismatch)."
has_error=1
;;
esac
done
if [[ $has_error = 1 ]]; then
warning "Errors encountered during MD5 checks."
fi
# remove the mount point
umount $BM_BURNING_DEVICE || error "Unable to unmount the mount point \$mount_point"
rmdir $mount_point || error "Unable to remove the mount point \$mount_point"
}
# this will try to burn the generated archives to the disc
# choosed in the configuration.
# Obviously, we will use mkisofs for generating the iso and
# cdrecord for burning CD, growisofs for the DVD.
# Note that we pipe the iso image directly to cdrecord
# in this way, we prevent the use of precious disk place.
#
# Two cases are possible:
# - non-interactive mode: will try to burn data on a single disc
# - interactive mode : will ask for next disc if needed.
function burn_files()
{
debug "burn_files()"
if [[ "$BM_BURNING_METHOD" = "none" ]] ||
[[ -z "$BM_BURNING_METHOD" ]]; then
info "No burning method used."
return 0
fi
# Choose which mode to use (interactive or not)
# according to the standard input
if tty -s ; then
debug "tty detected, using the interactive mode"
burn_files_interactive
else
debug "no tty detected, non-interactive mode"
burn_files_non_interactive
fi
}
function find_what_to_burn()
{
source="$1"
debug "find_what_to_burn($source)"
what_to_burn=""
nb_file=$(ls -l $source 2>/dev/null | wc -l)
if [[ $nb_file -gt 0 ]]; then
info "Number of files to burn: \$nb_file."
else
error "Nothing to burn for the \$BM__BURNING_DATE, try the '--burn <date>' switch."
fi
for file in $source
do
if [[ ! -L $file ]]; then
what_to_burn="$what_to_burn $file"
fi
done
}
# This has to do something without any interactive input.
function burn_files_non_interactive()
{
debug "burn_files_non_interactive()"
# find what to burn according to the size...
what_to_burn=""
size=$(size_of_path "$BM_REPOSITORY_ROOT")
# We can't burn the whole repository, using only today's archives
if [[ $size -gt $BM_BURNING_MAXSIZE ]] ||
[[ -n "${BM__BURNING_DATE}" ]]; then
if [[ -z "$BM__BURNING_DATE" ]]; then
BM__BURNING_DATE="$TODAY"
fi
BM__BURNING_DATE="$TODAY"
info "Burning archives of \$BM__BURNING_DATE."
size=$(size_of_path "${BM_REPOSITORY_ROOT}/*${BM__BURNING_DATE}*")
# does not fit neither, cannot burn anything.
if [[ $size -gt $BM_BURNING_MAXSIZE ]]; then
error "Cannot burn archives of the \$BM__BURNING_DATE, too big: \${size}M, must fit in \$BM_BURNING_MAXSIZE"
fi
find_what_to_burn "${BM_REPOSITORY_ROOT}/*${BM__BURNING_DATE}*"
else
BM__BURNING_DATE="$TODAY"
find_what_to_burn "${BM_REPOSITORY_ROOT}/*"
fi
burn_session "$what_to_burn"
}
# This will be used only in interactive mode, then we can burn
# the whole repository safely: user will change disc when needed (hopefully).
# (anyway, we rely on this assertion, this should be documented).
function burn_files_interactive()
{
debug "burn_files_interactive()"
purge_indexes
if [[ ! -z "${BM__BURNING_DATE}" ]] ; then
info "Burning archives of \$BM__BURNING_DATE."
find_what_to_burn "${BM_REPOSITORY_ROOT}/*${BM__BURNING_DATE}*"
size=$(size_of_path "${BM_REPOSITORY_ROOT}/*${BM__BURNING_DATE}*")
else
info "Burning the whole archives."
BM__BURNING_DATE="$TODAY"
find_what_to_burn "${BM_REPOSITORY_ROOT}/*"
size=$(size_of_path "${BM_REPOSITORY_ROOT}")
fi
info "Trying to burn \$BM_REPOSITORY_ROOT (\$size MB) in interactive mode. You will be prompted to enter insert a disc when needed"
burn_multiples_media "$what_to_burn"
}
# This will burn $what_to_burn on a single session
# It must fit in a medium
function burn_session()
{
what_to_burn="$1"
session_number="$2"
number_of_indexes="$3"
debug "burn_session($what_to_burn, $session_number, $number_of_indexes)"
# Since version 0.7.5 disc-image can be non-joliet.
# This is handled by $BM_BURNING_ISO_FLAGS, let's default that
# variable for backward compat.
if [[ -z "$BM_BURNING_ISO_FLAGS" ]]; then
BM_BURNING_ISO_FLAGS="-R -J"
fi
if [[ -z "$session_number" ]] || [[ $session_number = 1 ]]; then
title="Backups of ${BM__BURNING_DATE}"
else
title="Backups of ${BM__BURNING_DATE} - $session_number/$number_of_indexes"
fi
# Let's unmount the device first
bm_safe_unmount $BM_BURNING_DEVICE
# get a log file in a secure path
logfile="$(mktemp ${BM_TEMP_DIR}/bm-burning.log.XXXXXX)"
info "Redirecting burning logs into \$logfile"
# set the cdrecord command
devforced=""
if [[ -n "$BM_BURNING_DEVFORCED" ]]; then
info "Forcing dev=\${BM_BURNING_DEVFORCED} for cdrecord commands."
devforced="dev=${BM_BURNING_DEVFORCED}"
fi
# burning the iso with the user choosen method
case "$BM_BURNING_METHOD" in
"DVD")
if [[ ! -x $growisofs ]]; then
error "DVD+R(W) burning requires \$growisofs, aborting."
fi
info "Exporting archives to the DVD+R(W) disc in \$BM_BURNING_DEVICE."
debug "$growisofs -use-the-force-luke=tty -Z ${BM_BURNING_DEVICE} ${BM_BURNING_ISO_FLAGS} -V \"${title}\" ${what_to_burn} >> ${logfile}"
tail_logfile $logfile
$growisofs -use-the-force-luke=tty -Z ${BM_BURNING_DEVICE} ${BM_BURNING_ISO_FLAGS} -V "${title}" ${what_to_burn} >> ${logfile} 2>&1 ||
error "failed, check \$logfile"
;;
"DVD-RW")
if [[ ! -x $growisofs ]]; then
error "DVD-R(W) burning requires \$growisofs, aborting."
fi
if [[ ! -x $dvdrwformat ]]; then
error "DVD-R(W) burning requires \$dvdrwformat, aborting."
fi
info "Blanking the DVD-R(W) disc in \$BM_BURNING_DEVICE"
debug "$dvdrwformat -blank $BM_BURNING_DEVICE > $logfile"
tail_logfile $logfile
$dvdrwformat -blank $BM_BURNING_DEVICE > $logfile 2>&1 ||
error "Unable to blank the DVD-R(W) disc (check \$logfile)."
info "Exporting archives to the DVD-R(W) disc in \$BM_BURNING_DEVICE."
debug "$growisofs -use-the-force-luke=tty -Z ${BM_BURNING_DEVICE} ${BM_BURNING_ISO_FLAGS} -V \"${title}\" ${what_to_burn} >> ${logfile}"
$growisofs -use-the-force-luke=tty -Z ${BM_BURNING_DEVICE} ${BM_BURNING_ISO_FLAGS} -V "${title}" ${what_to_burn} >> ${logfile} 2>&1 ||
error "failed, check \$logfile"
;;
"CDRW")
if [[ ! -x $cdrecord ]]; then
error "CD-R(W) burning requires \$cdrecord, aborting."
fi
info "Blanking the CDRW in \$BM_BURNING_DEVICE."
debug "${cdrecord} -tao $devforced blank=fast > ${logfile}"
tail_logfile $logfile
${cdrecord} -tao $devforced blank=fast > ${logfile} 2>&1 ||
error "failed, check \$logfile"
info "Burning data to \$BM_BURNING_DEVICE."
debug "${mkisofs} -V \"${title}\" -q ${BM_BURNING_ISO_FLAGS} ${what_to_burn} | ${cdrecord} -tao $devforced - > ${logfile}"
${mkisofs} -V "${title}" -q ${BM_BURNING_ISO_FLAGS} ${what_to_burn} | \
${cdrecord} -tao $devforced - > ${logfile} 2>&1 ||
error "failed, check \$logfile"
;;
"CDR")
if [[ ! -x $cdrecord ]]; then
error "CD-R(W) burning requires \$cdrecord, aborting."
fi
info "Burning data to \$BM_BURNING_DEVICE."
debug "${mkisofs} -V \"${title}\" -q ${BM_BURNING_ISO_FLAGS} ${what_to_burn} | ${cdrecord} -tao $devforced - > ${logfile}"
tail_logfile $logfile
${mkisofs} -V "${title}" -q ${BM_BURNING_ISO_FLAGS} ${what_to_burn} | \
${cdrecord} -tao $devforced - > ${logfile} 2>&1 ||
error "failed, check \$logfile"
;;
"none"|"NONE")
info "Nothing to burn."
;;
*)
error "The requested burning method is not supported, check BM_BURNING_METHOD in \$conffile"
;;
esac
# Cleaning the logile, everything was fine at this point.
rm -f $logfile
# checking the files in the CDR if wanted
if [[ $BM_BURNING_CHKMD5 = true ]]; then
check_cdrom_md5_sums
fi
}
function purge_indexes()
{
debug "purge_indexes()"
index_prefix=$(get_index_prefix)
rm -f ${index_prefix}*
}
function get_index_prefix()
{
debug "get_index_prefix()"
index_prefix="$BM_REPOSITORY_ROOT/index-${BM__BURNING_DATE}"
echo "$index_prefix"
}
# Parse "$target" and build index files. Put as many files in index as possible
# according to BM_BURNING_MAXSIZE.
# indexes are not included here, should be added by hand after that processing.
function __build_indexes_from_target()
{
target="$1"
debug "__build_indexes_from_target ($target)"
indexes=""
medium_index=""
index_number=1
number_of_indexes=1
index_prefix=$(get_index_prefix)
index_session="$index_prefix-$index_number"
# Sorting by filetypes
target=$(ls -v $target)
# Write the indexes files in order to have one index file by medium.
# When a medium is full, we create a new one.
for file in ${target}
do
if [[ ! -f $file ]]; then
continue
fi
size_of_file=$(size_of_path "$file")
if [[ $size_of_file -gt $BM_BURNING_MAXSIZE ]] ; then
warning "Not burning \$file because it does not fit in the disk."
continue
fi
# Addd file to the index file.
medium_possible_index="$medium_index $file"
size_of_possible_index=$(size_of_path "$medium_possible_index")
if [[ $size_of_possible_index -gt $BM_BURNING_MAXSIZE ]] ; then
indexes="$indexes $index_session"
number_of_indexes=$(($number_of_indexes +1))
index_number=$(($index_number + 1))
index_session="$index_prefix-$index_number"
echo "$file" > $index_session
medium_index="$file"
medium_possible_index=""
else
echo "$file" >> $index_session
medium_index="$medium_possible_index"
fi
done
indexes="$indexes $index_session"
}
function __insert_new_medium()
{
debug "__insert_new_medium()"
bm_pause "$(translate "Please insert a new disk in \$BM_BURNING_DEVICE")"
}
function __burn_session_from_file()
{
index_file="$1"
session_number="$2"
number_of_indexes="$3"
debug "__burn_session_from_file ($index_file, $session_number, $number_of_indexes)"
if [[ ! -e "$index_file" ]]; then
error "No such index file: \"\$index_file\"."
fi
what_to_burn_session=""
for file_to_burn in $(cat "$index_file")
do
what_to_burn_session="$what_to_burn_session $file_to_burn"
done
what_to_burn="$what_to_burn_session"
burn_session "$what_to_burn_session" "$session_number" "$number_of_indexes"
}
function __append_index_paths_in_indexes()
{
debug "__append_index_paths_in_indexes()"
prefix=$(get_index_prefix)
for index_file in $prefix*
do
for index_path in $prefix*
do
echo "$index_path" >> $index_file
done
done
}
function burn_multiples_media()
{
target="$1"
debug "burn_multiples_media ($target)"
# first purge existing indexs
purge_indexes
# put in $indexes a list of files that contain
# archives to put on each medium.
__build_indexes_from_target "$target"
# Display the number of medias required by the burning systemp.
if [[ $number_of_indexes -eq 1 ]]; then
info "The burning process will need one disk."
else
info "The burning process will need \$number_of_indexes disks."
fi
# Now that all indexes are built, list them so we can find
# them all in the media.
__append_index_paths_in_indexes
# foreach index, build its content on a media, interactively
session_number=0
for index in $indexes
do
session_number=$(($session_number + 1))
info "Burning content of \$index"
__insert_new_medium
__burn_session_from_file "$index" "$session_number" "$number_of_indexes"
done
# Remove all the index files.
rm -f $indexes
}