[Refdb-cvs] CVS: refdb/scripts refdb-restore,1.3.2.5,1.3.2.6
Status: Beta
Brought to you by:
mhoenicka
From: David N. <dav...@us...> - 2005-09-30 19:44:43
|
Update of /cvsroot/refdb/refdb/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6170 Modified Files: Tag: Release_0_9_5_stable refdb-restore Log Message: Removed reliance on bash-specific string chopping, added error feedback, skip empty notes files (caused major run-time error) Index: refdb-restore =================================================================== RCS file: /cvsroot/refdb/refdb/scripts/refdb-restore,v retrieving revision 1.3.2.5 retrieving revision 1.3.2.6 diff -u -U2 -r1.3.2.5 -r1.3.2.6 --- refdb-restore 3 Feb 2005 13:07:02 -0000 1.3.2.5 +++ refdb-restore 30 Sep 2005 16:55:21 -0000 1.3.2.6 @@ -13,12 +13,16 @@ # VARIABLES -references_backup="references" # base of references backup file name -notes_backup="xnotes.xml" # notes backup file name -styles_directory="styles" # name of styles directory (intra-archive) -start_dir=`pwd` # directory in which utility is run + +self="$( basename ${0} )" +ref_base="references" # base of references backup file name +note_filename="xnotes.xml" # notes backup file name +style_dir="styles" # name of styles directory (intra-archive) +start_dir="$( pwd )" # directory in which utility is run refdba="refdba" # refdba command refdbc="refdbc" # refdbc command -archive=$1 # name of backup archive +archive="${1}" # name of backup archive parameters="[-u USER] [-w PWD] <backup_archive>" # cmd-line options +divider="----------------------------------------------------------------" + # PROCEDURES @@ -26,35 +30,43 @@ # Report success of operation # params: 1 - exit status +# prints: feedback ('OK'|'Failed') # return: nil report () { - if [ $1 -eq 0 ] ; then echo "OK." ; else echo "Failed." ; fi + if [ ${1} -eq 0 ] ; then echo "OK." ; else echo "Failed." ; fi } # Report failure and abort # params: 1 - exit message -# 2 - success indicator ( 'succeeded'|* ) -# retuns: nil +# 2 - exit status ( 0|* ) +# prints: feedback (not for capture) +# return: nil endScript () { + # set variables + local msg="${1}" local status="failed" + if [ ${2} -eq 0 ] ; then status="succeeded" + else msg="Error: ${msg}" + fi # attempt to change back to initial directory cd ${start_dir} || \ echo "Error: Unable to cd to start dir '${start_dir}'." # attempt to delete temporary files - [ -d ${tempdir} ] && rm -fr ${tempdir} || \ - echo "Error: Unable to delete temporary directory '${tempdir}'." + [ -d ${tmp_dir} ] && rm -fr ${tmp_dir} || \ + echo "Error: Unable to delete temporary directory '${tmp_dir}'." # provide feedback regarding success of backup - echo ; echo "$1" - echo ; echo "refdb restore $2." - echo "`basename $0` is finished." + echo ; echo "${1}" + echo ; echo "refdb restore ${status}." + echo "${self} is finished." # provide exit status to shell - if [ "$2" = "succeeded" ] ; then exit 0 ; else exit 1 ; fi + exit ${2} } # Show usage # params: nil +# prints: message (not for capture) # return: nil displayUsage () { - echo "`basename $0`: Restores RefDb data from backup." + echo "${self}: Restores RefDb data from backup." echo echo "Restores references, notes and styles from backup archive." echo - echo "Usage: `basename $0` ${parameters}" + echo "Usage: ${self} ${parameters}" echo echo "Must be archive created by 'refdb-backup' utility." @@ -69,28 +81,126 @@ # 2 - database name # 3 - backup file basename -# return: filename ('db_DBNAME/BACKUPFILE.EXTENSION') -get_filename () { - archive=$1 - db=$2 - base=$3 - filelist=`tar -tzf $1 | grep -v "/$" | grep "^db_"` - [ `echo "${filelist}" | grep "^db_${db}/${references_backup}.xml"` ] \ - && extension="xml" - [ `echo "${filelist}" | grep "^db_${db}/${references_backup}.ris"` ] \ - && extension="ris" - echo "db_${db}/${references_backup}.${extension}" +# prints: filename ('db_DBNAME/BACKUPFILE.EXTENSION') +# return: nil +getFilename () { + local archive="${1}" db="${2}" base="${3}" file="" ext="" + files="$( tar -tzf ${archive} | grep -v -- "/$" | grep -- "^db_" )" + file="$( echo "${files}" | grep -- "^db_${db}/${base}\." )" + ext="$( echo "${file}" | sed -e "s:^db_${db}\/${base}\.\(.*\)$:\1:" )" + echo "db_${db}/${base}.${ext}" } # Determines format of backup reference file # params: 1 - backup filepath -# return: format ('ris'|'risx') -get_format () { - filepath=$1 - filename=${filepath##*/} # strip path - extension=${filename##*.} # strip basename - case ${extension} in +# prints: format ('ris'|'risx') +# return: nil +getFormat () { + local path="${1}" + local name="$( basename "${path}" )" + local ext="$( echo "${name}" | awk -F "." '{ print $NF }' )" + case ${ext} in ris ) echo "ris";; xml ) echo "risx";; * ) echo "ERROR";; esac +} +# Remove terminal slash from string +# params: 1 - string +# prints: altered string +# return: nil +removeTerminalSlash () { + echo "$( echo "${1}" | sed -e 's/\(.*\)\/$/\1/' )" +} +# Normalise path (make absolute) +# params: 1 - path +# prints: normalised path +# return: nil +normalisePath () { + local path="${1}" + # deal with shorthand for home directory + path="$( echo ${path} | sed -e "s?^~?${HOME}?" )" + # deal with relative path + [ $( echo ${path} | grep -c -- "^/" ) -eq 0 ] && path="$( pwd )/${path}" + # remove relative "parent" directories + while [ $( echo "${path}" | grep -c -- "\.\.\/.*\?\/" ) -gt 0 ] ; do + path="$( echo "${path}" \ + | perl -pe 's:(.*\/)[^\.\.].*?\/\.\.\/(.*):\1\2:' )" + done + # remove terminal slash from directory + path="$( removeTerminalSlash "${path}" )" + # return result + echo "${path}" +} +# Provide feedback after shell command execution +# params: 1 - shell exit value +# 2 - shell messages +# prints: feedback (not for capture) +# return: nil +# needs: variables [divider] +# assume: shell operation preceded by msg requiring 'report' completion +shellCmdResult () { + # set variables + local exit_value=${1} err_msg="${2}" + # finish off previous message + report ${exit_value} + # print error message(s) if command failed + if [ ${exit_value} -ne 0 ] ; then # give error feedback + if [ -n "${err_msg}" ] ; then # error messages captured + echo "The following error messages were generated:" + echo "${divider}" + echo "${err_msg}" + echo "${divider}" + else # no error messages captured + echo "No error messages were generated." + fi + fi +} +# Get file size +# params: 1 - filepath +# prints: file size +# return: nil +getFileSize () { + local path="${1}" + path="$( normalisePath "${path}" )" + echo $( dir -l ${path} | sed -e 's/ \+/ /g' | cut -d ' ' -f 5 ) +} +# Is file of zero size? +# params: 1 - filepath +# prints: nil +# return: boolean (0|*) +zeroFileSize () { + return $( getFileSize "${1}" ) +} +# Contains space? +# params: 1 - string +# prints: nil +# return: 0|1 (no space|space) +noSpace () { + return $( echo "${1}" | grep -c -- " " ) +} +# File exists and readable +# params: 1 - file +# prints: nil +# return: 0|1 (exists|does not exist) +# invoke: if dnFileValid "${filename}" ; then ... +# needs: functions [dnNoSpace] +fileValid () { + if test -f "${1}" -a -r "${1}" && noSpace "${1}" ; then return 0 + else return 1 + fi +} +# Checks whether archive is a valid tarzip +# params: 1 - archive filepath +# prints: nil +# return: 0|1 (valid|not valid) +validTarzip () { + # check it exists + local archive="$( normalisePath "${1}" )" + fileValid "${archive}" || return 1 + # check it has correct extension + [ $( echo "${archive}" | grep -c -- "\.tar\.gz$" ) -gt 0 ] || return 1 + # check it is in correct format + tar --gunzip --list --file "${archive}" &> /dev/null || return 1 + # done + return 0 } @@ -107,11 +217,11 @@ refdbc="${refdbc} -w \"${OPTARG}\"";; \? ) echo "Error: Invalid flag '${OPTARG}' detected" - echo "Usage: `basename $0` ${parameters}" - echo "Try '`basename $0` -h' for help" + echo "Usage: ${self} ${parameters}" + echo "Try '${self} -h' for help" echo -ne "\a" exit 1;; \: ) echo "Error: No argument supplied for flag '${OPTARG}'" - echo "Usage: `basename $0` ${parameters}" - echo "Try '`basename $0` -h' for help" + echo "Usage: ${self} ${parameters}" + echo "Try '${self} -h' for help" echo -ne "\a" exit 1;; @@ -121,94 +231,90 @@ -# Check for valid arguments -# - run tests on archive - # - first, convert relative to absolute filepath -[ `echo ${archive} | grep -v "^\/"` ] && archive="${start_dir}/${archive}" - # - must exist and be readable -[ -r ${archive} ] || \ - endScript "Cannot read backup archive '${archive}'." "failed" - # - must be valid archive (this test is a bit crude - just list - # archive contents and check exit status) -tar -tzf ${archive} &> /dev/null || \ - endScript "'${archive}' is not a valid archive." "failed" +# Check for valid argument +# 1 - archive +archive="$( normalisePath "${archive}" )" +validTarzip "${archive}" || endScript "'${archive}' is not a valid archive." 1 # Test for RefDB access -${refdba} -C listdb &> /dev/null || \ - endScript "Error: Unable to access RefDB using client 'refdba'." "failed" -${refdbc} -C listdb &> /dev/null || \ - endScript "Error: Unable to access RefDB using client 'refdbc'." "failed" +${refdba} -C listdb &> /dev/null \ + || endScript "Unable to access RefDB using client 'refdba'." 1 +${refdbc} -C listdb &> /dev/null \ + || endScript "Unable to access RefDB using client 'refdbc'." 1 # Will use temporary directory for working # - ensure deletion on exit and change to working directory -tempdir_base="`basename $0`.XXXXXX" -tempdir=`mktemp -dq ${tempdir_base}` \ - || endScript "Error: Unable to create temporary directory." "failed" -[ `echo ${tempdir} | grep -v "^\/"` ] && tempdir="${start_dir}/${tempdir}" -trap "rm -fr ${tempdir}" 0 1 2 3 5 15 # delete on exit -cd ${tempdir} || \ - endScript "Error: Unable to cd to temporary directory '${tempdir}'." \ - "failed" +tmp_dir="$( mktemp -p ${start_dir} -dq )" \ + || endScript "Unable to create temporary directory." 1 +trap "rm -fr ${tmp_dir}" 0 1 2 3 5 15 # delete on exit +cd ${tmp_dir} \ + || endScript "Unable to cd to temporary directory '${tmp_dir}'." 1 # Informational message -echo "`basename $0` is running..." ; echo +echo "${self} is running..." ; echo # Cycle through databases in turn and restore references and notes -for dbdir in `tar -tzf ${archive} | grep "/$"` ; do +for dbdir in $( tar -tzf ${archive} | grep "/$" ) ; do # get db name - if [ ${dbdir} != "styles/" ] ; then - db=${dbdir##db_} # remove prefix - db=${db%%/} # remove trailing slash + if [ ${dbdir} != "${style_dir}/" ] ; then + db="$( echo "${dbdir}" | sed 's:^db_\(.*\)$:\1:' )" # remove prefix + db="$( removeTerminalSlash "${db}" )" # remove trailing slash echo "Restoring database: ${db}" # restore references - reffile=`get_filename ${archive} ${db} ${references_backup}` + ref_file="$( getFilename ${archive} ${db} ${ref_base} )" echo " Restore references" # - extract file echo -n " Extracting temporary file ... " - tar -xzf ${archive} ${reffile} &> /dev/null - report $? + fb="$( tar -xzf ${archive} ${ref_file} 2>&1 )" + shellCmdResult ${?} "${fb}" # - create database echo -n " Create database ... " - refdba -C createdb ${db} &> /dev/null - report $? + fb="$( ${refdba} -C createdb ${db} 2>&1 )" + shellCmdResult ${?} "${fb}" # - add references echo -n " Adding references ... " - format=`get_format ${reffile}` - refdbc -C addref -d ${db} -t ${format} ${reffile} &> /dev/null - report $? + format="$( getFormat ${ref_file} )" + fb="$( ${refdbc} -C addref -d ${db} -t ${format} ${ref_file} 2>&1 )" + shellCmdResult ${?} "${fb}" # restore notes - notefile="db_${db}/${notes_backup}" + notefile="db_${db}/${note_filename}" echo " Restore notes" # - extract file echo -n " Extracting temporary file ... " - tar -xzf ${archive} ${notefile} &> /dev/null - report $? + fb="$( tar -xzf ${archive} ${notefile} 2>&1 )" + shellCmdResult ${?} "${fb}" # - add notes - echo -n " Adding notes ... " - refdbc -C addnote -d ${db} ${notefile} &> /dev/null - report $? + if zeroFileSize ${notefile} ; then + echo " No notes to add." + else + echo -n " Adding notes ... " + fb="$( ${refdbc} -C addnote -d ${db} ${notefile} 2>&1 )" + shellCmdResult ${?} "${fb}" + fi fi done +unset ref_base note_filename db ref_file format fb notefile # Restore styles echo "Restoring styles" -for stylefile in `tar -tzf ${archive} | grep "^styles/[[:print:]]\+"` ; do +stylefiles="$( tar -tzf ${archive} | grep "^${style_dir}/[[:print:]]\+" )" +for stylefile in ${stylefiles} ; do # extract style file echo -n " Extracting style: " - tar -xzf ${archive} ${stylefile} &> /dev/null - if [ $? -eq 0 ] ; then + fb="$( tar -xzf ${archive} ${stylefile} 2>&1 )" + if [ ${?} -eq 0 ] ; then # extract style name - stylename=`grep "^[[:print:]]*<STYLENAME>" ${stylefile}` - stylename=${stylename#[[:print:]]*<STYLENAME>} - stylename=${stylename%<\/STYLENAME>} - echo ${stylename} + style="$( grep "^[[:print:]]*<STYLENAME>" ${stylefile} | \ + sed 's?^[[:print:]]*<STYLENAME>\(.*\)<\/STYLENAME>?\1?' )" + echo ${style} # add style echo -n " Adding style ... " - refdba -C addstyle ${stylefile} &> /dev/null - report $? + fb="$( ${refdba} -C addstyle ${stylefile} 2>&1 )" + shellCmdResult ${?} "${fb}" else - report 1 + shellCmdResult 1 "${fb}" fi done +unset style_dir archive divider stylefiles style fb # Finished -endScript "Restore finished." "succeeded" +endScript "Restore finished." 0 |