From: Kern Sibbald Date: Mon, 4 Jul 2005 19:57:35 +0000 (+0000) Subject: 04Jul05 X-Git-Tag: Release-1.38.0~332 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=aaf83bbfd3460ac5b92ddf7c63dbf8f26d6ab88b;p=bacula%2Fbacula 04Jul05 - Correct seg fault caused by open() calling sequence change. 03Jul05 - Add new rc-chio-changer script by Rudolf Cejka to examples/autochangers - Apply Rudolf's changes to bacula.in - Expand the space from 8 to 10 characters in editing file sizes for restore and dir of catalog, otherwise GB sizes are truncated -- fixes bug report. - Modify wx-console to know about 10 character widths. - Allow decending into top level directory if recurse=no is set. Fixes a bug report. - Install pthreadVCE.dll when installing console or wx-console on Win32 systems. Fixes bug report. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2172 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/examples/autochangers/rc-chio-changer b/bacula/examples/autochangers/rc-chio-changer new file mode 100644 index 0000000000..3f7f08d04c --- /dev/null +++ b/bacula/examples/autochangers/rc-chio-changer @@ -0,0 +1,143 @@ +#!/bin/sh +# +# Bacula interface to chio autoloader +# +# This script was written by Rudolf Cejka +# I'm sending rewrite of examples/autochangers/chio-bacula for +# FreeBSD under name chio-changer, which tries to save all features +# from original code and add the possibility to list real barcodes +# from library. I hope that this version is somewhat nicer. +# +# +# $Id$ +# +# If you set in your Device resource +# Changer Command = "path-to-this-script/chio-changer" %c %o %S %a %d +# you will have the following input to this script: +# chio-changer "changer-device" "command" "slot" "tape-device" "drive-index" +# $1 $2 $3 $4 $5 +# for example (on a FreeBSD system): +# chio-changer /dev/ch0 load 1 /dev/nsa0 0 +# +# If you need an offline, refer to the drive as $4, for example: +# mt -f $4 offline +# +# Many changers need an offline before the chio unload. +# Also many changers need to sleep some time after the chio load. +# +# If you change the script, take care to return either the chio exit +# code or a 0. If the script exits with a non-zero exit code, Bacula +# will assume the request failed. +# + +PROGNAME=`basename $0` + +usage() +{ + cat < [slot] [tape-device] [drive-index] + +Commands (): + unload Unloads a tape into the slot from where it was loaded. + load Loads a tape from the slot (1-based). + list Lists full storage slots. + loaded Gives slot from where the tape was loaded (0 = empty drive). + slots Gives number of available slots. + +Example: + ${PROGNAME} /dev/ch0 load 1 Loads a tape from first slot 1. + +EOF +} + +# This simulates a barcode reader in the changer: +#FAKE_BARCODES=/usr/local/etc/bacula-barcodes + +# Time to wait for (un)loading +SLEEP=10 + +# Default settings +CHANGER=/dev/ch0 +TAPE=/dev/nsa0 +DRIVE=0 + +CHIO=/bin/chio + +if [ $# -lt 2 ]; then + usage + exit 1 +fi + +if [ -n "$1" ]; then + CHANGER=$1; +fi +COMMAND=$2 +SLOT=$3 +if [ "${SLOT}" = slot ]; then + # btape says "... slot 1 drive 0" + shift + SLOT=$3 +fi +if [ -n "$4" ]; then + TAPE=$4 +fi +if [ -n "$5" ]; then + DRIVE=$5 +fi + +case ${COMMAND} in +unload) + # Enable the following line(s) if you need to eject the cartridge. + #mt -f ${TAPE} offline + #sleep ${SLEEP} + if [ -z "${SLOT}" ]; then + ${CHIO} -f ${CHANGER} return drive ${DRIVE} + else + ${CHIO} -f ${CHANGER} move drive ${DRIVE} slot $((${SLOT} - 1)) + fi + if [ $? -ne 0 ]; then + # Try to unload the cartridge to the first free slot. + FREE=`${CHIO} -f ${CHANGER} status slot | \ + sed -ne '/FULL/d;s/^slot *\([0-9]*\):.*/\1/p' | head -1` + if [ -n "${FREE}" ]; then + ${CHIO} -f ${CHANGER} move drive ${DRIVE} slot ${FREE} + else + exit 1 + fi + fi + ;; +load) + ${CHIO} -f ${CHANGER} move slot $((${SLOT} - 1)) drive ${DRIVE} + # Enable the following line if you need to wait after chio load. + #RET=$? ; sleep ${SLEEP} ; exit ${RET} + ;; +list) + if [ -z "${FAKE_BARCODES}" ]; then + ${CHIO} -f ${CHANGER} status -v slot | \ + sed -ne 's/^slot *\([0-9]*:\).*FULL.*voltag.*<\(.*\):.*/\1\2/p' | \ + awk -F: '{print $1 + 1 ":" $2 }' + else + if [ -f "${FAKE_BARCODES}" ]; then + grep -v -e "^#" -e "^$" < ${FAKE_BARCODES} + else + echo "${PROGNAME}: Barcode file ${FAKE_BARCODES} is missing" + exit 1 + fi + fi + ;; +loaded) + FREE=`${CHIO} -f ${CHANGER} status slot | \ + sed -ne '/FULL/d;s/^slot *\([0-9]*\):.*/\1/p' | \ + awk 'BEGIN { n = 0 } { n = $1 + 1 ; exit } END { print n }'` + ${CHIO} -f ${CHANGER} status -S drive | \ + sed -ne 's/^drive *'${DRIVE}':.*FULL.*source.*<[^0-9]*\([0-9]*\)>.*/\1/p' \ + | awk 'BEGIN { n = 0 } { n = ($1 == "") ? '${FREE}' : $1 + 1 } \ + END { print n }' + ;; +slots) + ${CHIO} -f ${CHANGER} status | grep -c "^slot " + ;; +*) + usage + ;; +esac diff --git a/bacula/kernstodo b/bacula/kernstodo index 6387dc40ac..0987d224dd 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -1,5 +1,5 @@ Kern's ToDo List - 16 June 2005 + 04 July 2005 Major development: Project Developer @@ -23,9 +23,16 @@ Autochangers: all Volumes from other drives. "update slots all-drives"? For 1.37: +- After rename + 04-Jul 13:01 MainSD: Rufus.2005-07-04_01.05.02 Warning: Director wanted Volume + "DLT-13Feb04". + Current Volume "DLT-04Jul05" not acceptable because: + 1997 Volume "DLT-13Feb04" not in catalog. + 04-Jul 13:01 MainSD: Please mount Volume "DLT-04Jul05" on Storage Device + "HP DLT 80" (/dev/nst0) for Job Rufus.2005-07-04_01.05.02 +- Remove old spool files on startup. +- Exclude SD spool/working directory. - Finish TLS implementation. -- Fix PostgreSQL GROUP BY problems in restore. -- Fix PostgreSQL sql problems in bugs. - Refuse to prune last valid Full backup. Same goes for Catalog. - --without-openssl breaks at least on Solaris. - Python: @@ -1297,4 +1304,5 @@ Block Position: 0 - Make sure that Python has access to Client address/port so that it can check if Clients are alive. - Review all items in "restore". - +- Fix PostgreSQL GROUP BY problems in restore. +- Fix PostgreSQL sql problems in bugs. diff --git a/bacula/kes-1.37 b/bacula/kes-1.37 index dc904e44f8..3a9fdb14de 100644 --- a/bacula/kes-1.37 +++ b/bacula/kes-1.37 @@ -4,6 +4,18 @@ General: Changes to 1.37.28: +03Jul05 +- Add new rc-chio-changer script by Rudolf Cejka to + examples/autochangers +- Apply Rudolf's changes to bacula.in +- Expand the space from 8 to 10 characters in editing + file sizes for restore and dir of catalog, otherwise + GB sizes are truncated -- fixes bug report. +- Modify wx-console to know about 10 character widths. +- Allow decending into top level directory if "recurse=no" + is set. Fixes a bug report. +- Install pthreadVCE.dll when installing console or wx-console + on Win32 systems. Fixes bug report. 02Jul05 - Tweak dvd-writepart script to prevent door from opening/closing so much. diff --git a/bacula/scripts/bacula.in b/bacula/scripts/bacula.in index 2f215ae244..4eb7515e6e 100755 --- a/bacula/scripts/bacula.in +++ b/bacula/scripts/bacula.in @@ -45,155 +45,155 @@ PIDOF=@PIDOF@ # A function to stop a program. killproc() { - RC=0 - # Test syntax. - if [ $# = 0 ]; then - echo "Usage: killproc {program} [signal]" - return 1 - fi - - notset=0 - # check for third arg to be kill level - if [ "$3" != "" ] ; then - killlevel=$3 - else - notset=1 - killlevel="-9" - fi - - # Get base program name - base=`basename $1` - - # Find pid. - pid=`pidofproc $base $2` - - # Kill it. - if [ "$pid" != "" ] ; then - if [ "$notset" = "1" ] ; then - if ps -p $pid>/dev/null 2>&1; then - # TERM first, then KILL if not dead - kill -TERM $pid 2>/dev/null - sleep 1 - if ps -p $pid >/dev/null 2>&1 ; then - sleep 1 - if ps -p $pid >/dev/null 2>&1 ; then - sleep 3 - if ps -p $pid >/dev/null 2>&1 ; then - kill -KILL $pid 2>/dev/null - fi - fi - fi + RC=0 + # Test syntax. + if [ $# = 0 ]; then + echo "Usage: killproc {program} {port} [signal]" + return 1 + fi + + notset=0 + # check for third arg to be kill level + if [ "$3" != "" ] ; then + killlevel=$3 + else + notset=1 + killlevel="-9" + fi + + # Get base program name + base=`basename $1` + + # Find pid. + pid=`pidofproc $base $2` + + # Kill it. + if [ "$pid" != "" ] ; then + if [ "$notset" = "1" ] ; then + if ps -p $pid>/dev/null 2>&1; then + # TERM first, then KILL if not dead + kill -TERM $pid 2>/dev/null + sleep 1 + if ps -p $pid >/dev/null 2>&1 ; then + sleep 1 + if ps -p $pid >/dev/null 2>&1 ; then + sleep 3 + if ps -p $pid >/dev/null 2>&1 ; then + kill -KILL $pid 2>/dev/null + fi + fi fi - ps -p $pid >/dev/null 2>&1 - RC=$? - [ $RC -eq 0 ] && failure "$base shutdown" || success "$base shutdown" - # RC=$((! $RC)) - # use specified level only - else - if ps -p $pid >/dev/null 2>&1; then - kill $killlevel $pid 2>/dev/null - RC=$? - [ $RC -eq 0 ] && success "$base $killlevel" || failure "$base $killlevel" - fi - fi - else - failure "$base shutdown" - fi - # Remove pid file if any. - if [ "$notset" = "1" ]; then - rm -f ${PIDDIR}/$base.$2.pid - fi - return $RC + fi + ps -p $pid >/dev/null 2>&1 + RC=$? + [ $RC -eq 0 ] && failure "$base shutdown" || success "$base shutdown" + # RC=$((! $RC)) + # use specified level only + else + if ps -p $pid >/dev/null 2>&1; then + kill $killlevel $pid 2>/dev/null + RC=$? + [ $RC -eq 0 ] && success "$base $killlevel" || failure "$base $killlevel" + fi + fi + else + failure "$base shutdown" + fi + # Remove pid file if any. + if [ "$notset" = "1" ]; then + rm -f ${PIDDIR}/$base.$2.pid + fi + return $RC } # A function to find the pid of a program. pidofproc() { - pid="" - # Test syntax. - if [ $# = 0 ] ; then - echo "Usage: pidofproc {program}" - return 1 - fi - - # Get base program name - base=`basename $1` - - # First try PID file - if [ -f ${PIDDIR}/$base.$2.pid ] ; then - pid=`head -n 1 ${PIDDIR}/$base.$2.pid` - if [ "$pid" != "" ] ; then - echo $pid - return 0 - fi - fi - - # Next try "pidof" + pid="" + # Test syntax. + if [ $# = 0 ] ; then + echo "Usage: pidofproc {program}" + return 1 + fi + + # Get base program name + base=`basename $1` + + # First try PID file + if [ -f ${PIDDIR}/$base.$2.pid ] ; then + pid=`head -n 1 ${PIDDIR}/$base.$2.pid` + if [ "$pid" != "" ] ; then + echo $pid + return 0 + fi + fi + + # Next try "pidof" if [ -x ${PIDOF} ] ; then - pid=`${PIDOF} $1` + pid=`${PIDOF} $1` fi if [ "$pid" != "" ] ; then - echo $pid - return 0 + echo $pid + return 0 fi - # Finally try to extract it from ps - ${PSCMD} | grep $1 | ${AWK} '{ print $1 }' | tr '\n' ' ' - return 0 + # Finally try to extract it from ps + ${PSCMD} | grep $1 | ${AWK} '{ print $1 }' | tr '\n' ' ' + return 0 } status() { - pid="" - # Test syntax. - if [ $# = 0 ] ; then - echo "Usage: status {program}" - return 1 - fi + pid="" + # Test syntax. + if [ $# = 0 ] ; then + echo "Usage: status {program} {port}" + return 1 + fi - # Get base program name - base=`basename $1` + # Get base program name + base=`basename $1` # First try "pidof" if [ -x ${PIDOF} ] ; then - pid=`${PIDOF} $1` + pid=`${PIDOF} $1` fi if [ "$pid" != "" ] ; then - echo "$base (pid $pid) is running..." - return 0 + echo "$base (pid $pid) is running..." + return 0 else - pid=`${PSCMD} | ${AWK} 'BEGIN { prog=ARGV[1]; ARGC=1 } - { if ((prog == $2) || (("(" prog ")") == $2) || - (("[" prog "]") == $2) || - ((prog ":") == $2)) { print $1 ; exit 0 } }' $1` - if [ "$pid" != "" ] ; then - echo "$base (pid $pid) is running..." - return 0 - fi + pid=`${PSCMD} | ${AWK} 'BEGIN { prog=ARGV[1]; ARGC=1 } + { if ((prog == $2) || (("(" prog ")") == $2) || + (("[" prog "]") == $2) || + ((prog ":") == $2)) { print $1 ; exit 0 } }' $1` + if [ "$pid" != "" ] ; then + echo "$base (pid $pid) is running..." + return 0 + fi fi - # Next try the PID files - if [ -f ${PIDDIR}/$base.$2.pid ] ; then - pid=`head -n 1 ${PIDDIR}/$base.$2.pid` - if [ "$pid" != "" ] ; then - echo "$base dead but pid file exists" - return 1 - fi - fi - # See if the subsys lock exists - if [ -f ${SUBSYSDIR}/$base ] ; then - echo "$base dead but subsys locked" - return 2 - fi - echo "$base is stopped" - return 3 + # Next try the PID files + if [ -f ${PIDDIR}/$base.$2.pid ] ; then + pid=`head -n 1 ${PIDDIR}/$base.$2.pid` + if [ "$pid" != "" ] ; then + echo "$base dead but pid file exists" + return 1 + fi + fi + # See if the subsys lock exists + if [ -f ${SUBSYSDIR}/$base ] ; then + echo "$base dead but subsys locked" + return 2 + fi + echo "$base is stopped" + return 3 } success() { - return 0 + return 0 } failure() { - rc=$? - return $rc + rc=$? + return $rc } OS=`uname -s` @@ -204,85 +204,85 @@ if [ -d "/lib/tls" -a $OS = "Linux" -a `uname -r | cut -c1-3` = "2.4" ] ; then fi case "$1" in - start) - [ -x ${BACSDBIN}/bacula-sd ] && { - echo "Starting the Bacula Storage daemon" - OPTIONS='' - if [ "${SD_USER}" != '' ]; then - OPTIONS="${OPTIONS} -u ${SD_USER}" - fi - - if [ "${SD_GROUP}" != '' ]; then - OPTIONS="${OPTIONS} -g ${SD_GROUP}" - fi - - ${BACSDBIN}/bacula-sd $2 ${OPTIONS} -v -c ${BACSDCFG}/bacula-sd.conf - } - - [ -x ${BACFDBIN}/bacula-fd ] && { - echo "Starting the Bacula File daemon" - OPTIONS='' - if [ "${FD_USER}" != '' ]; then - OPTIONS="${OPTIONS} -u ${FD_USER}" - fi - - if [ "${FD_GROUP}" != '' ]; then - OPTIONS="${OPTIONS} -g ${FD_GROUP}" - fi - - ${BACFDBIN}/bacula-fd $2 ${OPTIONS} -v -c ${BACFDCFG}/bacula-fd.conf - } - - [ -x ${BACDIRBIN}/bacula-dir ] && { - sleep 2 - echo "Starting the Bacula Director daemon" - OPTIONS='' - if [ "${DIR_USER}" != '' ]; then - OPTIONS="${OPTIONS} -u ${DIR_USER}" - fi - - if [ "${DIR_GROUP}" != '' ]; then - OPTIONS="${OPTIONS} -g ${DIR_GROUP}" - fi - - ${BACDIRBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/bacula-dir.conf - } - ;; - - stop) - # Stop the FD first so that SD will fail jobs and update catalog - [ -x ${BACFDBIN}/bacula-fd ] && { - echo "Stopping the Bacula File daemon" - killproc ${BACFDBIN}/bacula-fd ${FD_PORT} - } - - [ -x ${BACSDBIN}/bacula-sd ] && { - echo "Stopping the Bacula Storage daemon" - killproc ${BACSDBIN}/bacula-sd ${SD_PORT} - } - - [ -x ${BACDIRBIN}/bacula-dir ] && { - echo "Stopping the Bacula Director daemon" - killproc ${BACDIRBIN}/bacula-dir ${DIR_PORT} - } - echo - ;; - - restart) - $0 stop - sleep 5 - $0 start - ;; - - status) - [ -x ${BACSDBIN}/bacula-sd ] && status ${BACSDBIN}/bacula-sd ${SD_PORT} - [ -x ${BACFDBIN}/bacula-fd ] && status ${BACFDBIN}/bacula-fd ${FD_PORT} - [ -x ${BACDIRBIN}/bacula-dir ] && status ${BACDIRBIN}/bacula-dir ${DIR_PORT} - ;; - - *) - echo "Usage: $0 {start|stop|restart|status}" - exit 1 - ;; + start) + [ -x ${BACSDBIN}/bacula-sd ] && { + echo "Starting the Bacula Storage daemon" + OPTIONS='' + if [ "${SD_USER}" != '' ]; then + OPTIONS="${OPTIONS} -u ${SD_USER}" + fi + + if [ "${SD_GROUP}" != '' ]; then + OPTIONS="${OPTIONS} -g ${SD_GROUP}" + fi + + ${BACSDBIN}/bacula-sd $2 ${OPTIONS} -v -c ${BACSDCFG}/bacula-sd.conf + } + + [ -x ${BACFDBIN}/bacula-fd ] && { + echo "Starting the Bacula File daemon" + OPTIONS='' + if [ "${FD_USER}" != '' ]; then + OPTIONS="${OPTIONS} -u ${FD_USER}" + fi + + if [ "${FD_GROUP}" != '' ]; then + OPTIONS="${OPTIONS} -g ${FD_GROUP}" + fi + + ${BACFDBIN}/bacula-fd $2 ${OPTIONS} -v -c ${BACFDCFG}/bacula-fd.conf + } + + [ -x ${BACDIRBIN}/bacula-dir ] && { + sleep 2 + echo "Starting the Bacula Director daemon" + OPTIONS='' + if [ "${DIR_USER}" != '' ]; then + OPTIONS="${OPTIONS} -u ${DIR_USER}" + fi + + if [ "${DIR_GROUP}" != '' ]; then + OPTIONS="${OPTIONS} -g ${DIR_GROUP}" + fi + + ${BACDIRBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/bacula-dir.conf + } + ;; + + stop) + # Stop the FD first so that SD will fail jobs and update catalog + [ -x ${BACFDBIN}/bacula-fd ] && { + echo "Stopping the Bacula File daemon" + killproc ${BACFDBIN}/bacula-fd ${FD_PORT} + } + + [ -x ${BACSDBIN}/bacula-sd ] && { + echo "Stopping the Bacula Storage daemon" + killproc ${BACSDBIN}/bacula-sd ${SD_PORT} + } + + [ -x ${BACDIRBIN}/bacula-dir ] && { + echo "Stopping the Bacula Director daemon" + killproc ${BACDIRBIN}/bacula-dir ${DIR_PORT} + } + echo + ;; + + restart) + $0 stop + sleep 5 + $0 start + ;; + + status) + [ -x ${BACSDBIN}/bacula-sd ] && status ${BACSDBIN}/bacula-sd ${SD_PORT} + [ -x ${BACFDBIN}/bacula-fd ] && status ${BACFDBIN}/bacula-fd ${FD_PORT} + [ -x ${BACDIRBIN}/bacula-dir ] && status ${BACDIRBIN}/bacula-dir ${DIR_PORT} + ;; + + *) + echo "Usage: $0 {start|stop|restart|status}" + exit 1 + ;; esac exit 0 diff --git a/bacula/src/dird/bacula-dir.conf.in b/bacula/src/dird/bacula-dir.conf.in index 5d22a2fff1..819bd41def 100644 --- a/bacula/src/dird/bacula-dir.conf.in +++ b/bacula/src/dird/bacula-dir.conf.in @@ -188,6 +188,7 @@ Storage { } + # Definition of DDS tape storage device #Storage { # Name = DDS-4 @@ -197,6 +198,7 @@ Storage { # Password = "@sd_password@" # password for Storage daemon # Device = DDS-4 # must be same as Device in Storage daemon # Media Type = DDS-4 # must be same as MediaType in Storage daemon +# Autochanger = yes # enable for autochanger device #} # Definition of 8mm tape storage device diff --git a/bacula/src/dird/sql_cmds.c b/bacula/src/dird/sql_cmds.c index f0fa6bb0a0..65525e21a9 100644 --- a/bacula/src/dird/sql_cmds.c +++ b/bacula/src/dird/sql_cmds.c @@ -6,24 +6,18 @@ * * Version $Id$ */ - /* - Copyright (C) 2002-2004 Kern Sibbald and John Walker + Copyright (C) 2002-2005 Kern Sibbald 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. + modify it under the terms of the GNU General Public License + version 2 as ammended with additional clauses defined in the + file LICENSE in the main source directory. 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -35,14 +29,14 @@ const char *list_pool = "SELECT * FROM Pool WHERE PoolId=%s"; /* For ua_dotcmds.c */ const char *client_backups = -"SELECT DISTINCT Job.JobId,Client.Name as Client,Level,StartTime," -"JobFiles,JobBytes,VolumeName,MediaType" -" FROM Client,Job,JobMedia,Media" -" WHERE Client.Name='%s'" -" AND Client.ClientId=Job.ClientId" -" AND JobStatus='T'" -" AND JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId" -" ORDER BY Job.StartTime"; + "SELECT DISTINCT Job.JobId,Client.Name as Client,Level,StartTime," + "JobFiles,JobBytes,VolumeName,MediaType" + " FROM Client,Job,JobMedia,Media" + " WHERE Client.Name='%s'" + " AND Client.ClientId=Job.ClientId" + " AND JobStatus='T'" + " AND JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId" + " ORDER BY Job.StartTime"; /* ====== ua_prune.c */ diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 38a2655e41..9d77e07747 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -372,7 +372,7 @@ static int cancel_cmd(UAContext *ua, const char *cmd) } JobId = str_to_int64(ua->argv[i]); if (!(jcr=get_jcr_by_id(JobId))) { - bsendmsg(ua, _("JobId %d is not running.\n"), JobId); + bsendmsg(ua, _("JobId %s is not running.\n"), ua->argv[i]); return 1; } break; @@ -408,11 +408,12 @@ static int cancel_cmd(UAContext *ua, const char *cmd) } start_prompt(ua, _("Select Job:\n")); foreach_jcr(jcr) { + char ed1[50]; if (jcr->JobId == 0) { /* this is us */ free_jcr(jcr); continue; } - bsnprintf(buf, sizeof(buf), "JobId=%d Job=%s", jcr->JobId, jcr->Job); + bsnprintf(buf, sizeof(buf), "JobId=%s Job=%s", edit_int64(jcr->JobId, ed1), jcr->Job); add_prompt(ua, buf); free_jcr(jcr); } diff --git a/bacula/src/dird/ua_dotcmds.c b/bacula/src/dird/ua_dotcmds.c index e2be84ffc0..c8e181729c 100644 --- a/bacula/src/dird/ua_dotcmds.c +++ b/bacula/src/dird/ua_dotcmds.c @@ -2,32 +2,26 @@ * * Bacula Director -- User Agent Commands * These are "dot" commands, i.e. commands preceded - * by a period. These commands are meant to be used - * by a program, so there is no prompting, and the - * returned results are (supposed to be) predictable. + * by a period. These commands are meant to be used + * by a program, so there is no prompting, and the + * returned results are (supposed to be) predictable. * * Kern Sibbald, April MMII * * Version $Id$ */ - /* - Copyright (C) 2002-2004 Kern Sibbald and John Walker + Copyright (C) 2002-2005 Kern Sibbald 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. + modify it under the terms of the GNU General Public License + version 2 as ammended with additional clauses defined in the + file LICENSE in the main source directory. 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -78,7 +72,7 @@ static struct cmdstruct commands[] = { { N_(".help"), qhelp_cmd, NULL}, { N_(".quit"), quit_cmd, NULL}, { N_(".exit"), quit_cmd, NULL} - }; + }; #define comsize (sizeof(commands)/sizeof(struct cmdstruct)) /* @@ -99,13 +93,13 @@ int do_a_dot_command(UAContext *ua, const char *cmd) len = strlen(ua->argk[0]); if (len == 1) { - return 1; /* no op */ + return 1; /* no op */ } - for (i=0; i<(int)comsize; i++) { /* search for command */ + for (i=0; i<(int)comsize; i++) { /* search for command */ if (strncasecmp(ua->argk[0], _(commands[i].key), len) == 0) { - stat = (*commands[i].func)(ua, cmd); /* go execute command */ - found = true; - break; + stat = (*commands[i].func)(ua, cmd); /* go execute command */ + found = true; + break; } } if (!found) { @@ -253,12 +247,12 @@ static int defaultscmd(UAContext *ua, const char *cmd) if (ua->argc == 2 && strcmp(ua->argk[1], "job") == 0) { job = (JOB *)GetResWithName(R_JOB, ua->argv[1]); if (job) { - STORE *store; + STORE *store; bsendmsg(ua, "job=%s", job->hdr.name); bsendmsg(ua, "pool=%s", job->pool->hdr.name); bsendmsg(ua, "messages=%s", job->messages->hdr.name); bsendmsg(ua, "client=%s", job->client->hdr.name); - store = (STORE *)job->storage->first(); + store = (STORE *)job->storage->first(); bsendmsg(ua, "storage=%s", store->hdr.name); bsendmsg(ua, "where=%s", job->RestoreWhere?job->RestoreWhere:""); bsendmsg(ua, "level=%s", level_to_str(job->JobLevel)); diff --git a/bacula/src/dird/ua_input.c b/bacula/src/dird/ua_input.c index 5f19b78139..e9058692a7 100644 --- a/bacula/src/dird/ua_input.c +++ b/bacula/src/dird/ua_input.c @@ -6,24 +6,18 @@ * * Version $Id$ */ - /* - Copyright (C) 2000-2004 Kern Sibbald and John Walker + Copyright (C) 2001-2005 Kern Sibbald 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. + modify it under the terms of the GNU General Public License + version 2 as ammended with additional clauses defined in the + file LICENSE in the main source directory. 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -42,7 +36,7 @@ int get_cmd(UAContext *ua, const char *prompt) int stat; ua->cmd[0] = 0; - if (!sock) { /* No UA */ + if (!sock) { /* No UA */ return 0; } bnet_fsend(sock, "%s", prompt); @@ -50,19 +44,19 @@ int get_cmd(UAContext *ua, const char *prompt) for ( ;; ) { stat = bnet_recv(sock); if (stat == BNET_SIGNAL) { - continue; /* ignore signals */ + continue; /* ignore signals */ } if (is_bnet_stop(sock)) { - return 0; /* error or terminate */ + return 0; /* error or terminate */ } pm_strcpy(ua->cmd, sock->msg); strip_trailing_junk(ua->cmd); if (strcmp(ua->cmd, ".messages") == 0) { - qmessagescmd(ua, ua->cmd); + qmessagescmd(ua, ua->cmd); } /* Lone dot => break */ if (ua->cmd[0] == '.' && ua->cmd[1] == 0) { - return 0; + return 0; } break; } @@ -72,7 +66,7 @@ int get_cmd(UAContext *ua, const char *prompt) /* * Get a positive integer * Returns: false if failure - * true if success => value in ua->pint32_val + * true if success => value in ua->pint32_val */ bool get_pint(UAContext *ua, const char *prompt) { @@ -82,21 +76,21 @@ bool get_pint(UAContext *ua, const char *prompt) for (;;) { ua->cmd[0] = 0; if (!get_cmd(ua, prompt)) { - return false; + return false; } /* Kludge for slots blank line => 0 */ if (ua->cmd[0] == 0 && strncmp(prompt, "Enter slot", 10) == 0) { - return true; + return true; } if (!is_a_number(ua->cmd)) { bsendmsg(ua, "Expected a positive integer, got: %s\n", ua->cmd); - continue; + continue; } errno = 0; dval = strtod(ua->cmd, NULL); if (errno != 0 || dval < 0) { bsendmsg(ua, "Expected a positive integer, got: %s\n", ua->cmd); - continue; + continue; } ua->pint32_val = (uint32_t)dval; ua->int64_val = (int64_t)dval; @@ -107,8 +101,8 @@ bool get_pint(UAContext *ua, const char *prompt) /* * Gets a yes or no response * Returns: false if failure - * true if success => ua->pint32_val == 1 for yes - * ua->pint32_val == 0 for no + * true if success => ua->pint32_val == 1 for yes + * ua->pint32_val == 0 for no */ bool get_yesno(UAContext *ua, const char *prompt) { @@ -117,18 +111,18 @@ bool get_yesno(UAContext *ua, const char *prompt) ua->pint32_val = 0; for (;;) { if (!get_cmd(ua, prompt)) { - return false; + return false; } len = strlen(ua->cmd); if (len < 1 || len > 3) { - continue; + continue; } if (strncasecmp(ua->cmd, _("yes"), len) == 0) { - ua->pint32_val = 1; - return true; + ua->pint32_val = 1; + return true; } if (strncasecmp(ua->cmd, _("no"), len) == 0) { - return true; + return true; } bsendmsg(ua, _("Invalid response. You must answer yes or no.\n")); } diff --git a/bacula/src/dird/ua_prune.c b/bacula/src/dird/ua_prune.c index f61cadc48b..d05bab4883 100644 --- a/bacula/src/dird/ua_prune.c +++ b/bacula/src/dird/ua_prune.c @@ -7,24 +7,18 @@ * * Version $Id$ */ - /* Copyright (C) 2002-2005 Kern Sibbald 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. + modify it under the terms of the GNU General Public License + version 2 as ammended with additional clauses defined in the + file LICENSE in the main source directory. 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -435,22 +429,23 @@ int prune_jobs(UAContext *ua, CLIENT *client, int JobType) * Then delete the Job entry, and finally and JobMedia records. */ for (i=0; i < del.num_ids; i++) { - Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]); + edit_int64(del.JobId[i], ed1); + Dmsg1(050, "Delete JobId=%s\n", ed1); if (!del.PurgedFiles[i]) { - Mmsg(query, del_File, edit_int64(del.JobId[i], ed1)); + Mmsg(query, del_File, ed1); if (!db_sql_query(ua->db, query, NULL, (void *)NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } Dmsg1(050, "Del sql=%s\n", query); } - Mmsg(query, del_Job, edit_int64(del.JobId[i], ed1)); + Mmsg(query, del_Job, ed1); if (!db_sql_query(ua->db, query, NULL, (void *)NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } Dmsg1(050, "Del sql=%s\n", query); - Mmsg(query, del_JobMedia, edit_int64(del.JobId[i], ed1)); + Mmsg(query, del_JobMedia, ed1); if (!db_sql_query(ua->db, query, NULL, (void *)NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } @@ -546,12 +541,13 @@ int prune_volume(UAContext *ua, MEDIA_DBR *mr) if (jr.JobTDate >= (now - period)) { continue; } - Dmsg2(200, "Delete JobId=%d Job=%s\n", del.JobId[i], jr.Job); - Mmsg(query, del_File, edit_int64(del.JobId[i], ed1)); + edit_int64(del.JobId[i], ed1); + Dmsg2(200, "Delete JobId=%s Job=%s\n", ed1, jr.Job); + Mmsg(query, del_File, ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); - Mmsg(query, del_Job, edit_int64(del.JobId[i], ed1)); + Mmsg(query, del_Job, ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); - Mmsg(query, del_JobMedia, edit_int64(del.JobId[i], ed1)); + Mmsg(query, del_JobMedia, ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); Dmsg1(050, "Del sql=%s\n", query); del.num_del++; diff --git a/bacula/src/dird/ua_purge.c b/bacula/src/dird/ua_purge.c index c6d98bee6b..55cbc07476 100644 --- a/bacula/src/dird/ua_purge.c +++ b/bacula/src/dird/ua_purge.c @@ -2,32 +2,26 @@ * * Bacula Director -- User Agent Database Purge Command * - * Purges Files from specific JobIds + * Purges Files from specific JobIds * or - * Purges Jobs from Volumes + * Purges Jobs from Volumes * * Kern Sibbald, February MMII * * Version $Id$ */ - /* Copyright (C) 2002-2005 Kern Sibbald 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. + modify it under the terms of the GNU General Public License + version 2 as ammended with additional clauses defined in the + file LICENSE in the main source directory. 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -48,30 +42,30 @@ int mark_media_purged(UAContext *ua, MEDIA_DBR *mr); static const char *select_jobsfiles_from_client = "SELECT JobId FROM Job " - "WHERE ClientId=%d " + "WHERE ClientId=%s " "AND PurgedFiles=0"; static const char *select_jobs_from_client = "SELECT JobId, PurgedFiles FROM Job " - "WHERE ClientId=%d"; + "WHERE ClientId=%s"; /* In memory list of JobIds */ struct s_file_del_ctx { JobId_t *JobId; - int num_ids; /* ids stored */ - int max_ids; /* size of array */ - int num_del; /* number deleted */ - int tot_ids; /* total to process */ + int num_ids; /* ids stored */ + int max_ids; /* size of array */ + int num_del; /* number deleted */ + int tot_ids; /* total to process */ }; struct s_job_del_ctx { - JobId_t *JobId; /* array of JobIds */ - char *PurgedFiles; /* Array of PurgedFile flags */ - int num_ids; /* ids stored */ - int max_ids; /* size of array */ - int num_del; /* number deleted */ - int tot_ids; /* total to process */ + JobId_t *JobId; /* array of JobIds */ + char *PurgedFiles; /* Array of PurgedFile flags */ + int num_ids; /* ids stored */ + int max_ids; /* size of array */ + int num_del; /* number deleted */ + int tot_ids; /* total to process */ }; struct s_count_ctx { @@ -147,7 +141,7 @@ static int file_delete_handler(void *ctx, int num_fields, char **row) if (del->num_ids == del->max_ids) { del->max_ids = (del->max_ids * 3) / 2; del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) * - del->max_ids); + del->max_ids); } del->JobId[del->num_ids++] = (JobId_t)str_to_int64(row[0]); return 0; @@ -200,46 +194,46 @@ int purgecmd(UAContext *ua, const char *cmd) /* Files */ case 0: switch(find_arg_keyword(ua, files_keywords)) { - case 0: /* Job */ - case 1: /* JobId */ - if (get_job_dbr(ua, &jr)) { - purge_files_from_job(ua, &jr); - } - return 1; - case 2: /* client */ - client = get_client_resource(ua); - if (client) { - purge_files_from_client(ua, client); - } - return 1; - case 3: /* Volume */ - if (select_media_dbr(ua, &mr)) { - purge_files_from_volume(ua, &mr); - } - return 1; + case 0: /* Job */ + case 1: /* JobId */ + if (get_job_dbr(ua, &jr)) { + purge_files_from_job(ua, &jr); + } + return 1; + case 2: /* client */ + client = get_client_resource(ua); + if (client) { + purge_files_from_client(ua, client); + } + return 1; + case 3: /* Volume */ + if (select_media_dbr(ua, &mr)) { + purge_files_from_volume(ua, &mr); + } + return 1; } /* Jobs */ case 1: switch(find_arg_keyword(ua, jobs_keywords)) { - case 0: /* client */ - client = get_client_resource(ua); - if (client) { - purge_jobs_from_client(ua, client); - } - return 1; - case 1: /* Volume */ - if (select_media_dbr(ua, &mr)) { - purge_jobs_from_volume(ua, &mr); - } - return 1; + case 0: /* client */ + client = get_client_resource(ua); + if (client) { + purge_jobs_from_client(ua, client); + } + return 1; + case 1: /* Volume */ + if (select_media_dbr(ua, &mr)) { + purge_jobs_from_volume(ua, &mr); + } + return 1; } /* Volume */ case 2: while ((i=find_arg(ua, _("volume"))) >= 0) { - if (select_media_dbr(ua, &mr)) { - purge_jobs_from_volume(ua, &mr); - } - *ua->argk[i] = 0; /* zap keyword already seen */ + if (select_media_dbr(ua, &mr)) { + purge_jobs_from_volume(ua, &mr); + } + *ua->argk[i] = 0; /* zap keyword already seen */ bsendmsg(ua, "\n"); } return 1; @@ -247,21 +241,21 @@ int purgecmd(UAContext *ua, const char *cmd) break; } switch (do_keyword_prompt(ua, _("Choose item to purge"), keywords)) { - case 0: /* files */ + case 0: /* files */ client = get_client_resource(ua); if (client) { - purge_files_from_client(ua, client); + purge_files_from_client(ua, client); } break; - case 1: /* jobs */ + case 1: /* jobs */ client = get_client_resource(ua); if (client) { - purge_jobs_from_client(ua, client); + purge_jobs_from_client(ua, client); } break; - case 2: /* Volume */ + case 2: /* Volume */ if (select_media_dbr(ua, &mr)) { - purge_jobs_from_volume(ua, &mr); + purge_jobs_from_volume(ua, &mr); } break; } @@ -282,6 +276,7 @@ static int purge_files_from_client(UAContext *ua, CLIENT *client) char *query = (char *)get_pool_memory(PM_MESSAGE); int i; CLIENT_DBR cr; + char ed1[50]; memset(&cr, 0, sizeof(cr)); memset(&del, 0, sizeof(del)); @@ -291,7 +286,7 @@ static int purge_files_from_client(UAContext *ua, CLIENT *client) return 0; } bsendmsg(ua, _("Begin purging files for Client \"%s\"\n"), cr.Name); - Mmsg(query, select_jobsfiles_from_client, cr.ClientId); + Mmsg(query, select_jobsfiles_from_client, edit_int64(cr.ClientId, ed1)); Dmsg1(050, "select sql=%s\n", query); @@ -303,7 +298,7 @@ static int purge_files_from_client(UAContext *ua, CLIENT *client) if (del.tot_ids == 0) { bsendmsg(ua, _("No Files found for client %s to purge from %s catalog.\n"), - client->hdr.name, client->catalog->hdr.name); + client->hdr.name, client->catalog->hdr.name); goto bail_out; } @@ -319,8 +314,9 @@ static int purge_files_from_client(UAContext *ua, CLIENT *client) db_sql_query(ua->db, query, file_delete_handler, (void *)&del); for (i=0; i < del.num_ids; i++) { - Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]); - Mmsg(query, "DELETE FROM File WHERE JobId=%d", del.JobId[i]); + edit_int64(del.JobId[i], ed1); + Dmsg1(050, "Delete JobId=%s\n", ed1); + Mmsg(query, "DELETE FROM File WHERE JobId=%s", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); /* * Now mark Job as having files purged. This is necessary to @@ -328,7 +324,7 @@ static int purge_files_from_client(UAContext *ua, CLIENT *client) * we don't do this, the number of JobId's in our in memory list * will grow very large. */ - Mmsg(query, "UPDATE Job Set PurgedFiles=1 WHERE JobId=%d", del.JobId[i]); + Mmsg(query, "UPDATE Job Set PurgedFiles=1 WHERE JobId=%s", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); Dmsg1(050, "Del sql=%s\n", query); } @@ -359,6 +355,7 @@ static int purge_jobs_from_client(UAContext *ua, CLIENT *client) char *query = (char *)get_pool_memory(PM_MESSAGE); int i; CLIENT_DBR cr; + char ed1[50]; memset(&cr, 0, sizeof(cr)); memset(&del, 0, sizeof(del)); @@ -369,7 +366,7 @@ static int purge_jobs_from_client(UAContext *ua, CLIENT *client) } bsendmsg(ua, _("Begin purging jobs from Client \"%s\"\n"), cr.Name); - Mmsg(query, select_jobs_from_client, cr.ClientId); + Mmsg(query, select_jobs_from_client, edit_int64(cr.ClientId, ed1)); Dmsg1(050, "select sql=%s\n", query); @@ -380,7 +377,7 @@ static int purge_jobs_from_client(UAContext *ua, CLIENT *client) } if (del.tot_ids == 0) { bsendmsg(ua, _("No Jobs found for client %s to purge from %s catalog.\n"), - client->hdr.name, client->catalog->hdr.name); + client->hdr.name, client->catalog->hdr.name); goto bail_out; } @@ -403,18 +400,19 @@ static int purge_jobs_from_client(UAContext *ua, CLIENT *client) * Then delete the Job entry, and finally and JobMedia records. */ for (i=0; i < del.num_ids; i++) { - Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]); + edit_int64(del.JobId[i], ed1); + Dmsg1(050, "Delete JobId=%s\n", ed1); if (!del.PurgedFiles[i]) { - Mmsg(query, "DELETE FROM File WHERE JobId=%d", del.JobId[i]); - db_sql_query(ua->db, query, NULL, (void *)NULL); + Mmsg(query, "DELETE FROM File WHERE JobId=%s", ed1); + db_sql_query(ua->db, query, NULL, (void *)NULL); Dmsg1(050, "Del sql=%s\n", query); } - Mmsg(query, "DELETE FROM Job WHERE JobId=%d", del.JobId[i]); + Mmsg(query, "DELETE FROM Job WHERE JobId=%s", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); Dmsg1(050, "Del sql=%s\n", query); - Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%d", del.JobId[i]); + Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%s", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); Dmsg1(050, "Del sql=%s\n", query); } @@ -437,10 +435,11 @@ void purge_files_from_job(UAContext *ua, JOB_DBR *jr) char *query = (char *)get_pool_memory(PM_MESSAGE); char ed1[50]; - Mmsg(query, "DELETE FROM File WHERE JobId=%s", edit_int64(jr->JobId,ed1)); + edit_int64(jr->JobId,ed1); + Mmsg(query, "DELETE FROM File WHERE JobId=%s", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); - Mmsg(query, "UPDATE Job Set PurgedFiles=1 WHERE JobId=%s", edit_int64(jr->JobId,ed1)); + Mmsg(query, "UPDATE Job Set PurgedFiles=1 WHERE JobId=%s", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); free_pool_memory(query); @@ -451,7 +450,7 @@ void purge_files_from_volume(UAContext *ua, MEDIA_DBR *mr ) /* * Returns: 1 if Volume purged - * 0 if Volume not purged + * 0 if Volume not purged */ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr) { @@ -460,6 +459,7 @@ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr) struct s_file_del_ctx del; int i, stat = 0; JOB_DBR jr; + char ed1[50]; stat = strcmp(mr->VolStatus, "Append") == 0 || strcmp(mr->VolStatus, "Full") == 0 || @@ -469,14 +469,15 @@ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr) bsendmsg(ua, "\n"); bsendmsg(ua, _("Volume \"%s\" has VolStatus \"%s\" and cannot be purged.\n" "The VolStatus must be: Append, Full, Used, or Error to be purged.\n"), - mr->VolumeName, mr->VolStatus); + mr->VolumeName, mr->VolStatus); goto bail_out; } memset(&jr, 0, sizeof(jr)); memset(&del, 0, sizeof(del)); cnt.count = 0; - Mmsg(query, "SELECT count(*) FROM JobMedia WHERE MediaId=%d", mr->MediaId); + Mmsg(query, "SELECT count(*) FROM JobMedia WHERE MediaId=%s", + edit_int64(mr->MediaId, ed1)); if (!db_sql_query(ua->db, query, count_handler, (void *)&cnt)) { bsendmsg(ua, "%s", db_strerror(ua->db)); Dmsg0(050, "Count failed\n"); @@ -485,10 +486,10 @@ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr) if (cnt.count == 0) { bsendmsg(ua, "There are no Jobs associated with Volume \"%s\". Marking it purged.\n", - mr->VolumeName); + mr->VolumeName); if (!mark_media_purged(ua, mr)) { bsendmsg(ua, "%s", db_strerror(ua->db)); - goto bail_out; + goto bail_out; } goto bail_out; } @@ -513,21 +514,23 @@ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr) */ del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); - Mmsg(query, "SELECT JobId FROM JobMedia WHERE MediaId=%d", mr->MediaId); + Mmsg(query, "SELECT JobId FROM JobMedia WHERE MediaId=%s", + edit_int64(mr->MediaId, ed1)); if (!db_sql_query(ua->db, query, file_delete_handler, (void *)&del)) { bsendmsg(ua, "%s", db_strerror(ua->db)); Dmsg0(050, "Count failed\n"); - goto bail_out; + goto bail_out; } } for (i=0; i < del.num_ids; i++) { - Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]); - Mmsg(query, "DELETE FROM File WHERE JobId=%d", del.JobId[i]); + edit_int64(del.JobId[i], ed1); + Dmsg1(050, "Delete JobId=%s\n", ed1); + Mmsg(query, "DELETE FROM File WHERE JobId=%s", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); - Mmsg(query, "DELETE FROM Job WHERE JobId=%d", del.JobId[i]); + Mmsg(query, "DELETE FROM Job WHERE JobId=%s", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); - Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%d", del.JobId[i]); + Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%s", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); Dmsg1(050, "Del sql=%s\n", query); del.num_del++; @@ -540,7 +543,8 @@ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr) /* If purged, mark it so */ cnt.count = 0; - Mmsg(query, "SELECT count(*) FROM JobMedia WHERE MediaId=%d", mr->MediaId); + Mmsg(query, "SELECT count(*) FROM JobMedia WHERE MediaId=%s", + edit_int64(mr->MediaId, ed1)); if (!db_sql_query(ua->db, query, count_handler, (void *)&cnt)) { bsendmsg(ua, "%s", db_strerror(ua->db)); Dmsg0(050, "Count failed\n"); @@ -549,10 +553,10 @@ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr) if (cnt.count == 0) { bsendmsg(ua, "There are no more Jobs associated with Volume \"%s\". Marking it purged.\n", - mr->VolumeName); + mr->VolumeName); if (!(stat = mark_media_purged(ua, mr))) { bsendmsg(ua, "%s", db_strerror(ua->db)); - goto bail_out; + goto bail_out; } } @@ -573,7 +577,7 @@ int mark_media_purged(UAContext *ua, MEDIA_DBR *mr) strcmp(mr->VolStatus, "Error") == 0) { bstrncpy(mr->VolStatus, "Purged", sizeof(mr->VolStatus)); if (!db_update_media_record(ua->jcr, ua->db, mr)) { - return 0; + return 0; } return 1; } else { diff --git a/bacula/src/dird/ua_run.c b/bacula/src/dird/ua_run.c index 8b02aeaf48..8187c5c11c 100644 --- a/bacula/src/dird/ua_run.c +++ b/bacula/src/dird/ua_run.c @@ -6,24 +6,18 @@ * * Version $Id$ */ - /* Copyright (C) 2001-2005 Kern Sibbald 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. + modify it under the terms of the GNU General Public License + version 2 as ammended with additional clauses defined in the + file LICENSE in the main source directory. 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -43,7 +37,7 @@ extern struct s_kw ReplaceOptions[]; * run jobid=nn * * Returns: 0 on error - * JobId if OK + * JobId if OK * */ int run_cmd(UAContext *ua, const char *cmd) @@ -64,7 +58,7 @@ int run_cmd(UAContext *ua, const char *cmd) CLIENT *client = NULL; FILESET *fileset = NULL; POOL *pool = NULL; - static const char *kw[] = { /* command line arguments */ + static const char *kw[] = { /* command line arguments */ "job", /* Used in a switch() */ "jobid", /* 1 */ "client", /* 2 */ @@ -112,171 +106,171 @@ int run_cmd(UAContext *ua, const char *cmd) kw_ok = false; /* Keep looking until we find a good keyword */ for (j=0; !kw_ok && kw[j]; j++) { - if (strcasecmp(ua->argk[i], _(kw[j])) == 0) { - /* Note, yes and run have no value, so do not err */ - if (!ua->argv[i] && j != YES_POS /*yes*/) { + if (strcasecmp(ua->argk[i], _(kw[j])) == 0) { + /* Note, yes and run have no value, so do not err */ + if (!ua->argv[i] && j != YES_POS /*yes*/) { bsendmsg(ua, _("Value missing for keyword %s\n"), ua->argk[i]); - return 1; - } + return 1; + } Dmsg1(800, "Got keyword=%s\n", NPRT(kw[j])); - switch (j) { - case 0: /* job */ - if (job_name) { + switch (j) { + case 0: /* job */ + if (job_name) { bsendmsg(ua, _("Job name specified twice.\n")); - return 0; - } - job_name = ua->argv[i]; - kw_ok = true; - break; - case 1: /* JobId */ - if (jid) { + return 0; + } + job_name = ua->argv[i]; + kw_ok = true; + break; + case 1: /* JobId */ + if (jid) { bsendmsg(ua, _("JobId specified twice.\n")); - return 0; - } - jid = ua->argv[i]; - kw_ok = true; - break; - case 2: /* client */ - case 3: /* fd */ - if (client_name) { + return 0; + } + jid = ua->argv[i]; + kw_ok = true; + break; + case 2: /* client */ + case 3: /* fd */ + if (client_name) { bsendmsg(ua, _("Client specified twice.\n")); - return 0; - } - client_name = ua->argv[i]; - kw_ok = true; - break; - case 4: /* fileset */ - if (fileset_name) { + return 0; + } + client_name = ua->argv[i]; + kw_ok = true; + break; + case 4: /* fileset */ + if (fileset_name) { bsendmsg(ua, _("FileSet specified twice.\n")); - return 0; - } - fileset_name = ua->argv[i]; - kw_ok = true; - break; - case 5: /* level */ - if (level_name) { + return 0; + } + fileset_name = ua->argv[i]; + kw_ok = true; + break; + case 5: /* level */ + if (level_name) { bsendmsg(ua, _("Level specified twice.\n")); - return 0; - } - level_name = ua->argv[i]; - kw_ok = true; - break; - case 6: /* storage */ - case 7: /* sd */ - if (store_name) { + return 0; + } + level_name = ua->argv[i]; + kw_ok = true; + break; + case 6: /* storage */ + case 7: /* sd */ + if (store_name) { bsendmsg(ua, _("Storage specified twice.\n")); - return 0; - } - store_name = ua->argv[i]; - kw_ok = true; - break; - case 8: /* pool */ - if (pool_name) { + return 0; + } + store_name = ua->argv[i]; + kw_ok = true; + break; + case 8: /* pool */ + if (pool_name) { bsendmsg(ua, _("Pool specified twice.\n")); - return 0; - } - pool_name = ua->argv[i]; - kw_ok = true; - break; - case 9: /* where */ - if (where) { + return 0; + } + pool_name = ua->argv[i]; + kw_ok = true; + break; + case 9: /* where */ + if (where) { bsendmsg(ua, _("Where specified twice.\n")); - return 0; - } - where = ua->argv[i]; - kw_ok = true; - break; - case 10: /* bootstrap */ - if (bootstrap) { + return 0; + } + where = ua->argv[i]; + kw_ok = true; + break; + case 10: /* bootstrap */ + if (bootstrap) { bsendmsg(ua, _("Bootstrap specified twice.\n")); - return 0; - } - bootstrap = ua->argv[i]; - kw_ok = true; - break; - case 11: /* replace */ - if (replace) { + return 0; + } + bootstrap = ua->argv[i]; + kw_ok = true; + break; + case 11: /* replace */ + if (replace) { bsendmsg(ua, _("Replace specified twice.\n")); - return 0; - } - replace = ua->argv[i]; - kw_ok = true; - break; - case 12: /* When */ - if (when) { + return 0; + } + replace = ua->argv[i]; + kw_ok = true; + break; + case 12: /* When */ + if (when) { bsendmsg(ua, _("When specified twice.\n")); - return 0; - } - when = ua->argv[i]; - kw_ok = true; - break; - case 13: /* Priority */ - if (Priority) { + return 0; + } + when = ua->argv[i]; + kw_ok = true; + break; + case 13: /* Priority */ + if (Priority) { bsendmsg(ua, _("Priority specified twice.\n")); - return 0; - } - Priority = atoi(ua->argv[i]); - if (Priority <= 0) { + return 0; + } + Priority = atoi(ua->argv[i]); + if (Priority <= 0) { bsendmsg(ua, _("Priority must be positive nonzero setting it to 10.\n")); - Priority = 10; - } - kw_ok = true; - break; - case 14: /* yes */ - kw_ok = true; - break; - case 15: /* Verify Job */ - if (verify_job_name) { + Priority = 10; + } + kw_ok = true; + break; + case 14: /* yes */ + kw_ok = true; + break; + case 15: /* Verify Job */ + if (verify_job_name) { bsendmsg(ua, _("Verify Job specified twice.\n")); - return 0; - } - verify_job_name = ua->argv[i]; - kw_ok = true; - break; - case 16: /* files */ - files = atoi(ua->argv[i]); - kw_ok = true; - break; - - case 17: /* catalog */ - catalog_name = ua->argv[i]; - kw_ok = true; - break; - - case 18: /* since */ - since = ua->argv[i]; - kw_ok = true; - break; - - case 19: /* cloned */ - cloned = true; - kw_ok = true; - break; - - default: - break; - } - } /* end strcase compare */ + return 0; + } + verify_job_name = ua->argv[i]; + kw_ok = true; + break; + case 16: /* files */ + files = atoi(ua->argv[i]); + kw_ok = true; + break; + + case 17: /* catalog */ + catalog_name = ua->argv[i]; + kw_ok = true; + break; + + case 18: /* since */ + since = ua->argv[i]; + kw_ok = true; + break; + + case 19: /* cloned */ + cloned = true; + kw_ok = true; + break; + + default: + break; + } + } /* end strcase compare */ } /* end keyword loop */ /* * End of keyword for loop -- if not found, we got a bogus keyword */ if (!kw_ok) { Dmsg1(800, "%s not found\n", ua->argk[i]); - /* - * Special case for Job Name, it can be the first - * keyword that has no value. - */ - if (!job_name && !ua->argv[i]) { - job_name = ua->argk[i]; /* use keyword as job name */ + /* + * Special case for Job Name, it can be the first + * keyword that has no value. + */ + if (!job_name && !ua->argv[i]) { + job_name = ua->argk[i]; /* use keyword as job name */ Dmsg1(800, "Set jobname=%s\n", job_name); - } else { + } else { bsendmsg(ua, _("Invalid keyword: %s\n"), ua->argk[i]); - return 0; - } + return 0; + } } } /* end argc loop */ - + Dmsg0(800, "Done scan.\n"); CAT *catalog = NULL; @@ -284,7 +278,7 @@ int run_cmd(UAContext *ua, const char *cmd) catalog = (CAT *)GetResWithName(R_CATALOG, catalog_name); if (catalog == NULL) { bsendmsg(ua, _("Catalog \"%s\" not found\n"), catalog_name); - return 0; + return 0; } } Dmsg1(800, "Using catalog=%s\n", NPRT(catalog_name)); @@ -293,10 +287,10 @@ int run_cmd(UAContext *ua, const char *cmd) /* Find Job */ job = (JOB *)GetResWithName(R_JOB, job_name); if (!job) { - if (*job_name != 0) { + if (*job_name != 0) { bsendmsg(ua, _("Job \"%s\" not found\n"), job_name); - } - job = select_job_resource(ua); + } + job = select_job_resource(ua); } else { Dmsg1(800, "Found job=%s\n", job_name); } @@ -308,26 +302,26 @@ int run_cmd(UAContext *ua, const char *cmd) return 0; } else if (!acl_access_ok(ua, Job_ACL, job->hdr.name)) { bsendmsg(ua, _("No authorization. Job \"%s\".\n"), - job->hdr.name); + job->hdr.name); return 0; } if (store_name) { store = (STORE *)GetResWithName(R_STORAGE, store_name); if (!store) { - if (*store_name != 0) { + if (*store_name != 0) { bsendmsg(ua, _("Storage \"%s\" not found.\n"), store_name); - } - store = select_storage_resource(ua); + } + store = select_storage_resource(ua); } } else { - store = (STORE *)job->storage->first(); /* use default */ + store = (STORE *)job->storage->first(); /* use default */ } if (!store) { return 1; } else if (!acl_access_ok(ua, Storage_ACL, store->hdr.name)) { bsendmsg(ua, _("No authorization. Storage \"%s\".\n"), - store->hdr.name); + store->hdr.name); return 0; } Dmsg1(800, "Using storage=%s\n", store->hdr.name); @@ -335,19 +329,19 @@ int run_cmd(UAContext *ua, const char *cmd) if (pool_name) { pool = (POOL *)GetResWithName(R_POOL, pool_name); if (!pool) { - if (*pool_name != 0) { + if (*pool_name != 0) { bsendmsg(ua, _("Pool \"%s\" not found.\n"), pool_name); - } - pool = select_pool_resource(ua); + } + pool = select_pool_resource(ua); } } else { - pool = job->pool; /* use default */ + pool = job->pool; /* use default */ } if (!pool) { return 0; } else if (!acl_access_ok(ua, Pool_ACL, pool->hdr.name)) { bsendmsg(ua, _("No authorization. Pool \"%s\".\n"), - pool->hdr.name); + pool->hdr.name); return 0; } Dmsg1(800, "Using pool\n", pool->hdr.name); @@ -355,19 +349,19 @@ int run_cmd(UAContext *ua, const char *cmd) if (client_name) { client = (CLIENT *)GetResWithName(R_CLIENT, client_name); if (!client) { - if (*client_name != 0) { + if (*client_name != 0) { bsendmsg(ua, _("Client \"%s\" not found.\n"), client_name); - } - client = select_client_resource(ua); + } + client = select_client_resource(ua); } } else { - client = job->client; /* use default */ + client = job->client; /* use default */ } if (!client) { return 0; } else if (!acl_access_ok(ua, Client_ACL, client->hdr.name)) { bsendmsg(ua, _("No authorization. Client \"%s\".\n"), - client->hdr.name); + client->hdr.name); return 0; } Dmsg1(800, "Using client=%s\n", client->hdr.name); @@ -376,16 +370,16 @@ int run_cmd(UAContext *ua, const char *cmd) fileset = (FILESET *)GetResWithName(R_FILESET, fileset_name); if (!fileset) { bsendmsg(ua, _("FileSet \"%s\" not found.\n"), fileset_name); - fileset = select_fileset_resource(ua); + fileset = select_fileset_resource(ua); } } else { - fileset = job->fileset; /* use default */ + fileset = job->fileset; /* use default */ } if (!fileset) { return 0; } else if (!acl_access_ok(ua, FileSet_ACL, fileset->hdr.name)) { bsendmsg(ua, _("No authorization. FileSet \"%s\".\n"), - fileset->hdr.name); + fileset->hdr.name); return 0; } @@ -393,7 +387,7 @@ int run_cmd(UAContext *ua, const char *cmd) verify_job = (JOB *)GetResWithName(R_JOB, verify_job_name); if (!verify_job) { bsendmsg(ua, _("Verify Job \"%s\" not found.\n"), verify_job_name); - verify_job = select_job_resource(ua); + verify_job = select_job_resource(ua); } } else { verify_job = job->verify_job; @@ -417,7 +411,7 @@ int run_cmd(UAContext *ua, const char *cmd) } if (where) { if (jcr->where) { - free(jcr->where); + free(jcr->where); } jcr->where = bstrdup(where); } @@ -426,13 +420,13 @@ int run_cmd(UAContext *ua, const char *cmd) jcr->sched_time = str_to_utime(when); if (jcr->sched_time == 0) { bsendmsg(ua, _("Invalid time, using current time.\n")); - jcr->sched_time = time(NULL); + jcr->sched_time = time(NULL); } } if (bootstrap) { if (jcr->RestoreBootstrap) { - free(jcr->RestoreBootstrap); + free(jcr->RestoreBootstrap); } jcr->RestoreBootstrap = bstrdup(bootstrap); } @@ -440,13 +434,13 @@ int run_cmd(UAContext *ua, const char *cmd) if (replace) { jcr->replace = 0; for (i=0; ReplaceOptions[i].name; i++) { - if (strcasecmp(replace, ReplaceOptions[i].name) == 0) { - jcr->replace = ReplaceOptions[i].token; - } + if (strcasecmp(replace, ReplaceOptions[i].name) == 0) { + jcr->replace = ReplaceOptions[i].token; + } } if (!jcr->replace) { bsendmsg(ua, _("Invalid replace option: %s\n"), replace); - goto bail_out; + goto bail_out; } } else if (job->replace) { jcr->replace = job->replace; @@ -460,7 +454,7 @@ int run_cmd(UAContext *ua, const char *cmd) if (since) { if (!jcr->stime) { - jcr->stime = get_pool_memory(PM_MESSAGE); + jcr->stime = get_pool_memory(PM_MESSAGE); } pm_strcpy(jcr->stime, since); } @@ -476,13 +470,13 @@ try_again: replace = ReplaceOptions[0].name; for (i=0; ReplaceOptions[i].name; i++) { if (ReplaceOptions[i].token == jcr->replace) { - replace = ReplaceOptions[i].name; + replace = ReplaceOptions[i].name; } } if (level_name) { if (!get_level_from_name(jcr, level_name)) { bsendmsg(ua, _("Level %s not valid.\n"), level_name); - goto bail_out; + goto bail_out; } } if (jid) { @@ -496,7 +490,7 @@ try_again: /* * Prompt User to see if all run job parameters are correct, and - * allow him to modify them. + * allow him to modify them. */ Dmsg1(800, "JobType=%c\n", jcr->JobType); switch (jcr->JobType) { @@ -511,12 +505,12 @@ try_again: "When: %s\n" "Priority: %d\n"), _("Admin"), - job->hdr.name, - jcr->fileset->hdr.name, - NPRT(jcr->client->hdr.name), - NPRT(jcr->store->hdr.name), - bstrutime(dt, sizeof(dt), jcr->sched_time), - jcr->JobPriority); + job->hdr.name, + jcr->fileset->hdr.name, + NPRT(jcr->client->hdr.name), + NPRT(jcr->store->hdr.name), + bstrutime(dt, sizeof(dt), jcr->sched_time), + jcr->JobPriority); jcr->JobLevel = L_FULL; break; case JT_BACKUP: @@ -532,21 +526,21 @@ try_again: "When: %s\n" "Priority: %d\n"), _("Backup"), - job->hdr.name, - jcr->fileset->hdr.name, - level_to_str(jcr->JobLevel), - jcr->client->hdr.name, - jcr->store->hdr.name, - NPRT(jcr->pool->hdr.name), - bstrutime(dt, sizeof(dt), jcr->sched_time), - jcr->JobPriority); - } else { /* JT_VERIFY */ - const char *Name; - if (jcr->verify_job) { - Name = jcr->verify_job->hdr.name; - } else { + job->hdr.name, + jcr->fileset->hdr.name, + level_to_str(jcr->JobLevel), + jcr->client->hdr.name, + jcr->store->hdr.name, + NPRT(jcr->pool->hdr.name), + bstrutime(dt, sizeof(dt), jcr->sched_time), + jcr->JobPriority); + } else { /* JT_VERIFY */ + const char *Name; + if (jcr->verify_job) { + Name = jcr->verify_job->hdr.name; + } else { Name = ""; - } + } bsendmsg(ua, _("Run %s job\n" "JobName: %s\n" "FileSet: %s\n" @@ -558,29 +552,29 @@ try_again: "When: %s\n" "Priority: %d\n"), _("Verify"), - job->hdr.name, - jcr->fileset->hdr.name, - level_to_str(jcr->JobLevel), - jcr->client->hdr.name, - jcr->store->hdr.name, - NPRT(jcr->pool->hdr.name), - Name, - bstrutime(dt, sizeof(dt), jcr->sched_time), - jcr->JobPriority); + job->hdr.name, + jcr->fileset->hdr.name, + level_to_str(jcr->JobLevel), + jcr->client->hdr.name, + jcr->store->hdr.name, + NPRT(jcr->pool->hdr.name), + Name, + bstrutime(dt, sizeof(dt), jcr->sched_time), + jcr->JobPriority); } break; case JT_RESTORE: if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) { - if (jid) { - jcr->RestoreJobId = str_to_int64(jid); - } else { + if (jid) { + jcr->RestoreJobId = str_to_int64(jid); + } else { if (!get_pint(ua, _("Please enter a JobId for restore: "))) { - goto bail_out; - } - jcr->RestoreJobId = ua->int64_val; - } + goto bail_out; + } + jcr->RestoreJobId = ua->int64_val; + } } - jcr->JobLevel = L_FULL; /* default level */ + jcr->JobLevel = L_FULL; /* default level */ Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId); if (jcr->RestoreJobId == 0) { bsendmsg(ua, _("Run Restore job\n" @@ -594,16 +588,16 @@ try_again: "When: %s\n" "Catalog: %s\n" "Priority: %d\n"), - job->hdr.name, - NPRT(jcr->RestoreBootstrap), - jcr->where?jcr->where:NPRT(job->RestoreWhere), - replace, - jcr->fileset->hdr.name, - jcr->client->hdr.name, - jcr->store->hdr.name, - bstrutime(dt, sizeof(dt), jcr->sched_time), - jcr->catalog->hdr.name, - jcr->JobPriority); + job->hdr.name, + NPRT(jcr->RestoreBootstrap), + jcr->where?jcr->where:NPRT(job->RestoreWhere), + replace, + jcr->fileset->hdr.name, + jcr->client->hdr.name, + jcr->store->hdr.name, + bstrutime(dt, sizeof(dt), jcr->sched_time), + jcr->catalog->hdr.name, + jcr->JobPriority); } else { bsendmsg(ua, _("Run Restore job\n" "JobName: %s\n" @@ -616,16 +610,16 @@ try_again: "When: %s\n" "Catalog: %s\n" "Priority: %d\n"), - job->hdr.name, - NPRT(jcr->RestoreBootstrap), - jcr->where?jcr->where:NPRT(job->RestoreWhere), - replace, - jcr->client->hdr.name, - jcr->store->hdr.name, + job->hdr.name, + NPRT(jcr->RestoreBootstrap), + jcr->where?jcr->where:NPRT(job->RestoreWhere), + replace, + jcr->client->hdr.name, + jcr->store->hdr.name, jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1), - bstrutime(dt, sizeof(dt), jcr->sched_time), - jcr->catalog->hdr.name, - jcr->JobPriority); + bstrutime(dt, sizeof(dt), jcr->sched_time), + jcr->catalog->hdr.name, + jcr->JobPriority); } break; default: @@ -652,11 +646,11 @@ try_again: add_prompt(ua, _("When")); /* 5 */ add_prompt(ua, _("Priority")); /* 6 */ if (jcr->JobType == JT_BACKUP || - jcr->JobType == JT_VERIFY) { + jcr->JobType == JT_VERIFY) { add_prompt(ua, _("Pool")); /* 7 */ - if (jcr->JobType == JT_VERIFY) { + if (jcr->JobType == JT_VERIFY) { add_prompt(ua, _("Verify Job")); /* 8 */ - } + } } else if (jcr->JobType == JT_RESTORE) { add_prompt(ua, _("Bootstrap")); /* 7 */ add_prompt(ua, _("Where")); /* 8 */ @@ -665,8 +659,8 @@ try_again: } switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) { case 0: - /* Level */ - if (jcr->JobType == JT_BACKUP) { + /* Level */ + if (jcr->JobType == JT_BACKUP) { start_prompt(ua, _("Levels:\n")); add_prompt(ua, _("Base")); add_prompt(ua, _("Full")); @@ -674,26 +668,26 @@ try_again: add_prompt(ua, _("Differential")); add_prompt(ua, _("Since")); switch (do_prompt(ua, "", _("Select level"), NULL, 0)) { - case 0: - jcr->JobLevel = L_BASE; - break; - case 1: - jcr->JobLevel = L_FULL; - break; - case 2: - jcr->JobLevel = L_INCREMENTAL; - break; - case 3: - jcr->JobLevel = L_DIFFERENTIAL; - break; - case 4: - jcr->JobLevel = L_SINCE; - break; - default: - break; - } - goto try_again; - } else if (jcr->JobType == JT_VERIFY) { + case 0: + jcr->JobLevel = L_BASE; + break; + case 1: + jcr->JobLevel = L_FULL; + break; + case 2: + jcr->JobLevel = L_INCREMENTAL; + break; + case 3: + jcr->JobLevel = L_DIFFERENTIAL; + break; + case 4: + jcr->JobLevel = L_SINCE; + break; + default: + break; + } + goto try_again; + } else if (jcr->JobType == JT_VERIFY) { start_prompt(ua, _("Levels:\n")); add_prompt(ua, _("Initialize Catalog")); add_prompt(ua, _("Verify Catalog")); @@ -701,164 +695,164 @@ try_again: add_prompt(ua, _("Verify Disk to Catalog")); add_prompt(ua, _("Verify Volume Data (not yet implemented)")); switch (do_prompt(ua, "", _("Select level"), NULL, 0)) { - case 0: - jcr->JobLevel = L_VERIFY_INIT; - break; - case 1: - jcr->JobLevel = L_VERIFY_CATALOG; - break; - case 2: - jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG; - break; - case 3: - jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG; - break; - case 4: - jcr->JobLevel = L_VERIFY_DATA; - break; - default: - break; - } - goto try_again; - } else { + case 0: + jcr->JobLevel = L_VERIFY_INIT; + break; + case 1: + jcr->JobLevel = L_VERIFY_CATALOG; + break; + case 2: + jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG; + break; + case 3: + jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG; + break; + case 4: + jcr->JobLevel = L_VERIFY_DATA; + break; + default: + break; + } + goto try_again; + } else { bsendmsg(ua, _("Level not appropriate for this Job. Cannot be changed.\n")); - } - goto try_again; + } + goto try_again; case 1: - /* Storage */ - store = select_storage_resource(ua); - if (store) { - set_storage(jcr, store); - goto try_again; - } - break; + /* Storage */ + store = select_storage_resource(ua); + if (store) { + set_storage(jcr, store); + goto try_again; + } + break; case 2: - /* Job */ - job = select_job_resource(ua); - if (job) { - jcr->job = job; - set_jcr_defaults(jcr, job); - goto try_again; - } - break; + /* Job */ + job = select_job_resource(ua); + if (job) { + jcr->job = job; + set_jcr_defaults(jcr, job); + goto try_again; + } + break; case 3: - /* FileSet */ - fileset = select_fileset_resource(ua); - if (fileset) { - jcr->fileset = fileset; - goto try_again; - } - break; + /* FileSet */ + fileset = select_fileset_resource(ua); + if (fileset) { + jcr->fileset = fileset; + goto try_again; + } + break; case 4: - /* Client */ - client = select_client_resource(ua); - if (client) { - jcr->client = client; - goto try_again; - } - break; + /* Client */ + client = select_client_resource(ua); + if (client) { + jcr->client = client; + goto try_again; + } + break; case 5: - /* When */ + /* When */ if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) { - break; - } - if (ua->cmd[0] == 0) { - jcr->sched_time = time(NULL); - } else { - jcr->sched_time = str_to_utime(ua->cmd); - if (jcr->sched_time == 0) { + break; + } + if (ua->cmd[0] == 0) { + jcr->sched_time = time(NULL); + } else { + jcr->sched_time = str_to_utime(ua->cmd); + if (jcr->sched_time == 0) { bsendmsg(ua, _("Invalid time, using current time.\n")); - jcr->sched_time = time(NULL); - } - } - goto try_again; + jcr->sched_time = time(NULL); + } + } + goto try_again; case 6: - /* Priority */ + /* Priority */ if (!get_pint(ua, _("Enter new Priority: "))) { - break; - } - if (ua->pint32_val == 0) { + break; + } + if (ua->pint32_val == 0) { bsendmsg(ua, _("Priority must be a positive integer.\n")); - } else { - jcr->JobPriority = ua->pint32_val; - } - goto try_again; + } else { + jcr->JobPriority = ua->pint32_val; + } + goto try_again; case 7: - /* Pool or Bootstrap depending on JobType */ - if (jcr->JobType == JT_BACKUP || - jcr->JobType == JT_VERIFY) { /* Pool */ - pool = select_pool_resource(ua); - if (pool) { - jcr->pool = pool; - goto try_again; - } - break; - } - - /* Bootstrap */ + /* Pool or Bootstrap depending on JobType */ + if (jcr->JobType == JT_BACKUP || + jcr->JobType == JT_VERIFY) { /* Pool */ + pool = select_pool_resource(ua); + if (pool) { + jcr->pool = pool; + goto try_again; + } + break; + } + + /* Bootstrap */ if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) { - break; - } - if (jcr->RestoreBootstrap) { - free(jcr->RestoreBootstrap); - jcr->RestoreBootstrap = NULL; - } - if (ua->cmd[0] != 0) { - jcr->RestoreBootstrap = bstrdup(ua->cmd); + break; + } + if (jcr->RestoreBootstrap) { + free(jcr->RestoreBootstrap); + jcr->RestoreBootstrap = NULL; + } + if (ua->cmd[0] != 0) { + jcr->RestoreBootstrap = bstrdup(ua->cmd); fd = fopen(jcr->RestoreBootstrap, "r"); - if (!fd) { + if (!fd) { bsendmsg(ua, _("Warning cannot open %s: ERR=%s\n"), - jcr->RestoreBootstrap, strerror(errno)); - free(jcr->RestoreBootstrap); - jcr->RestoreBootstrap = NULL; - } else { - fclose(fd); - } - } - goto try_again; + jcr->RestoreBootstrap, strerror(errno)); + free(jcr->RestoreBootstrap); + jcr->RestoreBootstrap = NULL; + } else { + fclose(fd); + } + } + goto try_again; case 8: - /* Verify Job */ - if (jcr->JobType == JT_VERIFY) { - verify_job = select_job_resource(ua); - if (verify_job) { - jcr->verify_job = verify_job; - } - goto try_again; - } - /* Where */ + /* Verify Job */ + if (jcr->JobType == JT_VERIFY) { + verify_job = select_job_resource(ua); + if (verify_job) { + jcr->verify_job = verify_job; + } + goto try_again; + } + /* Where */ if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) { - break; - } - if (jcr->where) { - free(jcr->where); - jcr->where = NULL; - } + break; + } + if (jcr->where) { + free(jcr->where); + jcr->where = NULL; + } if (ua->cmd[0] == '/' && ua->cmd[1] == 0) { - ua->cmd[0] = 0; - } - jcr->where = bstrdup(ua->cmd); - goto try_again; + ua->cmd[0] = 0; + } + jcr->where = bstrdup(ua->cmd); + goto try_again; case 9: - /* Replace */ + /* Replace */ start_prompt(ua, _("Replace:\n")); - for (i=0; ReplaceOptions[i].name; i++) { - add_prompt(ua, ReplaceOptions[i].name); - } + for (i=0; ReplaceOptions[i].name; i++) { + add_prompt(ua, ReplaceOptions[i].name); + } opt = do_prompt(ua, "", _("Select replace option"), NULL, 0); - if (opt >= 0) { - jcr->replace = ReplaceOptions[opt].token; - } - goto try_again; + if (opt >= 0) { + jcr->replace = ReplaceOptions[opt].token; + } + goto try_again; case 10: - /* JobId */ - jid = NULL; /* force reprompt */ - jcr->RestoreJobId = 0; - if (jcr->RestoreBootstrap) { + /* JobId */ + jid = NULL; /* force reprompt */ + jcr->RestoreJobId = 0; + if (jcr->RestoreBootstrap) { bsendmsg(ua, _("You must set the bootstrap file to NULL to be able to specify a JobId.\n")); - } - goto try_again; + } + goto try_again; default: - goto try_again; + goto try_again; } goto bail_out; } @@ -868,11 +862,11 @@ try_again: Dmsg1(800, "Calling run_job job=%x\n", jcr->job); start_job: JobId = run_job(jcr); - free_jcr(jcr); /* release jcr */ + free_jcr(jcr); /* release jcr */ if (JobId == 0) { bsendmsg(ua, _("Job failed.\n")); } else { - char ed1[50]; + char ed1[50]; bsendmsg(ua, _("Job started. JobId=%s\n"), edit_int64(JobId,ed1)); } return JobId; @@ -881,5 +875,5 @@ start_job: bail_out: bsendmsg(ua, _("Job not run.\n")); free_jcr(jcr); - return 0; /* do not run */ + return 0; /* do not run */ } diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index c6e0731e86..e25dd24701 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -6,24 +6,18 @@ * * Version $Id$ */ - /* - Copyright (C) 2000-2004 Kern Sibbald and John Walker + Copyright (C) 2001-2005 Kern Sibbald 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. + modify it under the terms of the GNU General Public License + version 2 as ammended with additional clauses defined in the + file LICENSE in the main source directory. 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -43,25 +37,25 @@ int confirm_retention(UAContext *ua, utime_t *ret, const char *msg) for ( ;; ) { bsendmsg(ua, _("The current %s retention period is: %s\n"), - msg, edit_utime(*ret, ed1, sizeof(ed1))); + msg, edit_utime(*ret, ed1, sizeof(ed1))); if (!get_cmd(ua, _("Continue? (yes/mod/no): "))) { - return 0; + return 0; } if (strcasecmp(ua->cmd, _("mod")) == 0) { if (!get_cmd(ua, _("Enter new retention period: "))) { - return 0; - } - if (!duration_to_utime(ua->cmd, ret)) { + return 0; + } + if (!duration_to_utime(ua->cmd, ret)) { bsendmsg(ua, _("Invalid period.\n")); - continue; - } - continue; + continue; + } + continue; } if (strcasecmp(ua->cmd, _("yes")) == 0) { - return 1; + return 1; } if (strcasecmp(ua->cmd, _("no")) == 0) { - return 0; + return 0; } } return 1; @@ -71,15 +65,15 @@ int confirm_retention(UAContext *ua, utime_t *ret, const char *msg) * Given a list of keywords, find the first one * that is in the argument list. * Returns: -1 if not found - * index into list (base 0) on success + * index into list (base 0) on success */ int find_arg_keyword(UAContext *ua, const char **list) { for (int i=1; iargc; i++) { for(int j=0; list[j]; j++) { - if (strcasecmp(_(list[j]), ua->argk[i]) == 0) { - return j; - } + if (strcasecmp(_(list[j]), ua->argk[i]) == 0) { + return j; + } } } return -1; @@ -89,13 +83,13 @@ int find_arg_keyword(UAContext *ua, const char **list) * Given one keyword, find the first one that * is in the argument list. * Returns: argk index (always gt 0) - * -1 if not found + * -1 if not found */ int find_arg(UAContext *ua, const char *keyword) { for (int i=1; iargc; i++) { if (strcasecmp(keyword, ua->argk[i]) == 0) { - return i; + return i; } } return -1; @@ -105,17 +99,17 @@ int find_arg(UAContext *ua, const char *keyword) * Given a single keyword, find it in the argument list, but * it must have a value * Returns: -1 if not found or no value - * list index (base 0) on success + * list index (base 0) on success */ int find_arg_with_value(UAContext *ua, const char *keyword) { for (int i=1; iargc; i++) { if (strcasecmp(keyword, ua->argk[i]) == 0) { - if (ua->argv[i]) { - return i; - } else { - return -1; - } + if (ua->argv[i]) { + return i; + } else { + return -1; + } } } return -1; @@ -126,7 +120,7 @@ int find_arg_with_value(UAContext *ua, const char *keyword) * to choose one. * * Returns: -1 on failure - * index into list (base 0) on success + * index into list (base 0) on success */ int do_keyword_prompt(UAContext *ua, const char *msg, const char **list) { @@ -151,7 +145,7 @@ STORE *select_storage_resource(UAContext *ua) LockRes(); foreach_res(store, R_STORAGE) { if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) { - add_prompt(ua, store->hdr.name); + add_prompt(ua, store->hdr.name); } } UnlockRes(); @@ -172,7 +166,7 @@ FILESET *select_fileset_resource(UAContext *ua) LockRes(); foreach_res(fs, R_FILESET) { if (acl_access_ok(ua, FileSet_ACL, fs->hdr.name)) { - add_prompt(ua, fs->hdr.name); + add_prompt(ua, fs->hdr.name); } } UnlockRes(); @@ -193,19 +187,19 @@ CAT *get_catalog_resource(UAContext *ua) for (i=1; iargc; i++) { if (strcasecmp(ua->argk[i], _("catalog")) == 0 && ua->argv[i]) { - if (acl_access_ok(ua, Catalog_ACL, ua->argv[i])) { - catalog = (CAT *)GetResWithName(R_CATALOG, ua->argv[i]); - break; - } + if (acl_access_ok(ua, Catalog_ACL, ua->argv[i])) { + catalog = (CAT *)GetResWithName(R_CATALOG, ua->argv[i]); + break; + } } } if (!catalog) { start_prompt(ua, _("The defined Catalog resources are:\n")); LockRes(); foreach_res(catalog, R_CATALOG) { - if (acl_access_ok(ua, Catalog_ACL, catalog->hdr.name)) { - add_prompt(ua, catalog->hdr.name); - } + if (acl_access_ok(ua, Catalog_ACL, catalog->hdr.name)) { + add_prompt(ua, catalog->hdr.name); + } } UnlockRes(); do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name)); @@ -227,7 +221,7 @@ JOB *select_job_resource(UAContext *ua) LockRes(); foreach_res(job, R_JOB) { if (acl_access_ok(ua, Job_ACL, job->hdr.name)) { - add_prompt(ua, job->hdr.name); + add_prompt(ua, job->hdr.name); } } UnlockRes(); @@ -248,7 +242,7 @@ JOB *select_restore_job_resource(UAContext *ua) LockRes(); foreach_res(job, R_JOB) { if (job->JobType == JT_RESTORE && acl_access_ok(ua, Job_ACL, job->hdr.name)) { - add_prompt(ua, job->hdr.name); + add_prompt(ua, job->hdr.name); } } UnlockRes(); @@ -271,7 +265,7 @@ CLIENT *select_client_resource(UAContext *ua) LockRes(); foreach_res(client, R_CLIENT) { if (acl_access_ok(ua, Client_ACL, client->hdr.name)) { - add_prompt(ua, client->hdr.name); + add_prompt(ua, client->hdr.name); } } UnlockRes(); @@ -293,15 +287,15 @@ CLIENT *get_client_resource(UAContext *ua) for (i=1; iargc; i++) { if ((strcasecmp(ua->argk[i], _("client")) == 0 || strcasecmp(ua->argk[i], _("fd")) == 0) && ua->argv[i]) { - if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) { - break; - } - client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]); - if (client) { - return client; - } + if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) { + break; + } + client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]); + if (client) { + return client; + } bsendmsg(ua, _("Error: Client resource %s does not exist.\n"), ua->argv[i]); - break; + break; } } return select_client_resource(ua); @@ -315,32 +309,32 @@ CLIENT *get_client_resource(UAContext *ua) * to choose from. * * returns: 0 on error - * 1 on success and fills in CLIENT_DBR + * 1 on success and fills in CLIENT_DBR */ int get_client_dbr(UAContext *ua, CLIENT_DBR *cr) { int i; - if (cr->Name[0]) { /* If name already supplied */ + if (cr->Name[0]) { /* If name already supplied */ if (db_get_client_record(ua->jcr, ua->db, cr)) { - return 1; + return 1; } bsendmsg(ua, _("Could not find Client %s: ERR=%s"), cr->Name, db_strerror(ua->db)); } for (i=1; iargc; i++) { if ((strcasecmp(ua->argk[i], _("client")) == 0 || strcasecmp(ua->argk[i], _("fd")) == 0) && ua->argv[i]) { - if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) { - break; - } - bstrncpy(cr->Name, ua->argv[i], sizeof(cr->Name)); - if (!db_get_client_record(ua->jcr, ua->db, cr)) { + if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) { + break; + } + bstrncpy(cr->Name, ua->argv[i], sizeof(cr->Name)); + if (!db_get_client_record(ua->jcr, ua->db, cr)) { bsendmsg(ua, _("Could not find Client \"%s\": ERR=%s"), ua->argv[i], - db_strerror(ua->db)); - cr->ClientId = 0; - break; - } - return 1; + db_strerror(ua->db)); + cr->ClientId = 0; + break; + } + return 1; } } if (!select_client_dbr(ua, cr)) { /* try once more by proposing a list */ @@ -352,7 +346,7 @@ int get_client_dbr(UAContext *ua, CLIENT_DBR *cr) /* * Select a Client record from the catalog * Returns 1 on success - * 0 on failure + * 0 on failure */ int select_client_dbr(UAContext *ua, CLIENT_DBR *cr) { @@ -376,8 +370,8 @@ int select_client_dbr(UAContext *ua, CLIENT_DBR *cr) for (i=0; i < num_clients; i++) { ocr.ClientId = ids[i]; if (!db_get_client_record(ua->jcr, ua->db, &ocr) || - !acl_access_ok(ua, Client_ACL, ocr.Name)) { - continue; + !acl_access_ok(ua, Client_ACL, ocr.Name)) { + continue; } add_prompt(ua, ocr.Name); } @@ -406,14 +400,14 @@ int select_client_dbr(UAContext *ua, CLIENT_DBR *cr) * to choose from. * * returns: false on error - * true on success and fills in POOL_DBR + * true on success and fills in POOL_DBR */ bool get_pool_dbr(UAContext *ua, POOL_DBR *pr) { - if (pr->Name[0]) { /* If name already supplied */ + if (pr->Name[0]) { /* If name already supplied */ if (db_get_pool_record(ua->jcr, ua->db, pr) && - acl_access_ok(ua, Pool_ACL, pr->Name)) { - return true; + acl_access_ok(ua, Pool_ACL, pr->Name)) { + return true; } bsendmsg(ua, _("Could not find Pool \"%s\": ERR=%s"), pr->Name, db_strerror(ua->db)); } @@ -435,15 +429,15 @@ bool select_pool_dbr(UAContext *ua, POOL_DBR *pr) for (i=1; iargc; i++) { if (strcasecmp(ua->argk[i], _("pool")) == 0 && ua->argv[i] && - acl_access_ok(ua, Pool_ACL, ua->argv[i])) { - bstrncpy(pr->Name, ua->argv[i], sizeof(pr->Name)); - if (!db_get_pool_record(ua->jcr, ua->db, pr)) { + acl_access_ok(ua, Pool_ACL, ua->argv[i])) { + bstrncpy(pr->Name, ua->argv[i], sizeof(pr->Name)); + if (!db_get_pool_record(ua->jcr, ua->db, pr)) { bsendmsg(ua, _("Could not find Pool \"%s\": ERR=%s"), ua->argv[i], - db_strerror(ua->db)); - pr->PoolId = 0; - break; - } - return true; + db_strerror(ua->db)); + pr->PoolId = 0; + break; + } + return true; } } @@ -461,8 +455,8 @@ bool select_pool_dbr(UAContext *ua, POOL_DBR *pr) for (i=0; i < num_pools; i++) { opr.PoolId = ids[i]; if (!db_get_pool_record(ua->jcr, ua->db, &opr) || - !acl_access_ok(ua, Pool_ACL, opr.Name)) { - continue; + !acl_access_ok(ua, Pool_ACL, opr.Name)) { + continue; } add_prompt(ua, opr.Name); } @@ -519,17 +513,17 @@ int select_media_dbr(UAContext *ua, MEDIA_DBR *mr) memset(&pr, 0, sizeof(pr)); /* Get the pool from pool= */ if (!get_pool_dbr(ua, &pr)) { - return 0; + return 0; } mr->PoolId = pr.PoolId; db_list_media_records(ua->jcr, ua->db, mr, prtit, ua, HORZ_LIST); if (!get_cmd(ua, _("Enter MediaId or Volume name: "))) { - return 0; + return 0; } if (is_a_number(ua->cmd)) { - mr->MediaId = str_to_int64(ua->cmd); + mr->MediaId = str_to_int64(ua->cmd); } else { - bstrncpy(mr->VolumeName, ua->cmd, sizeof(mr->VolumeName)); + bstrncpy(mr->VolumeName, ua->cmd, sizeof(mr->VolumeName)); } } @@ -553,7 +547,7 @@ POOL *select_pool_resource(UAContext *ua) LockRes(); foreach_res(pool, R_POOL) { if (acl_access_ok(ua, Pool_ACL, pool->hdr.name)) { - add_prompt(ua, pool->hdr.name); + add_prompt(ua, pool->hdr.name); } } UnlockRes(); @@ -577,7 +571,7 @@ POOL *get_pool_resource(UAContext *ua) if (i >= 0 && acl_access_ok(ua, Pool_ACL, ua->argv[i])) { pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]); if (pool) { - return pool; + return pool; } bsendmsg(ua, _("Error: Pool resource \"%s\" does not exist.\n"), ua->argv[i]); } @@ -611,7 +605,7 @@ int select_job_dbr(UAContext *ua, JOB_DBR *jr) * to choose from. * * returns: 0 on error - * JobId on success and fills in JOB_DBR + * JobId on success and fills in JOB_DBR */ int get_job_dbr(UAContext *ua, JOB_DBR *jr) { @@ -619,18 +613,18 @@ int get_job_dbr(UAContext *ua, JOB_DBR *jr) for (i=1; iargc; i++) { if (strcasecmp(ua->argk[i], _("job")) == 0 && ua->argv[i]) { - jr->JobId = 0; - bstrncpy(jr->Job, ua->argv[i], sizeof(jr->Job)); + jr->JobId = 0; + bstrncpy(jr->Job, ua->argv[i], sizeof(jr->Job)); } else if (strcasecmp(ua->argk[i], _("jobid")) == 0 && ua->argv[i]) { - jr->JobId = str_to_int64(ua->argv[i]); + jr->JobId = str_to_int64(ua->argv[i]); } else { - continue; + continue; } if (!db_get_job_record(ua->jcr, ua->db, jr)) { bsendmsg(ua, _("Could not find Job \"%s\": ERR=%s"), ua->argv[i], - db_strerror(ua->db)); - jr->JobId = 0; - break; + db_strerror(ua->db)); + jr->JobId = 0; + break; } return jr->JobId; } @@ -663,11 +657,11 @@ void add_prompt(UAContext *ua, const char *prompt) if (ua->num_prompts == ua->max_prompts) { ua->max_prompts *= 2; ua->prompt = (char **)brealloc(ua->prompt, sizeof(char *) * - ua->max_prompts); + ua->max_prompts); } for (i=1; i < ua->num_prompts; i++) { if (strcmp(ua->prompt[i], prompt) == 0) { - return; + return; } } ua->prompt[ua->num_prompts++] = bstrdup(prompt); @@ -677,8 +671,8 @@ void add_prompt(UAContext *ua, const char *prompt) * Display prompts and get user's choice * * Returns: -1 on error - * index base 0 on success, and choice - * is copied to prompt if not NULL + * index base 0 on success, and choice + * is copied to prompt if not NULL */ int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt) { @@ -688,7 +682,7 @@ int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, if (ua->num_prompts == 2) { item = 1; if (prompt) { - bstrncpy(prompt, ua->prompt[1], max_prompt); + bstrncpy(prompt, ua->prompt[1], max_prompt); } bsendmsg(ua, _("Automatically selected %s: %s\n"), automsg, ua->prompt[1]); goto done; @@ -712,32 +706,32 @@ int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, /* First item is the prompt string, not the items */ if (ua->num_prompts == 1) { bsendmsg(ua, _("Selection is empty!\n")); - item = 0; /* list is empty ! */ - break; + item = 0; /* list is empty ! */ + break; } if (ua->num_prompts == 2) { - item = 1; + item = 1; bsendmsg(ua, _("Item 1 selected automatically.\n")); - if (prompt) { - bstrncpy(prompt, ua->prompt[1], max_prompt); - } - break; + if (prompt) { + bstrncpy(prompt, ua->prompt[1], max_prompt); + } + break; } else { sprintf(pmsg, "%s (1-%d): ", msg, ua->num_prompts-1); } /* Either a . or an @ will get you out of the loop */ if (!get_pint(ua, pmsg)) { - item = -1; /* error */ + item = -1; /* error */ bsendmsg(ua, _("Selection aborted, nothing done.\n")); - break; + break; } item = ua->pint32_val; if (item < 1 || item >= ua->num_prompts) { bsendmsg(ua, _("Please enter a number between 1 and %d\n"), ua->num_prompts-1); - continue; + continue; } if (prompt) { - bstrncpy(prompt, ua->prompt[item], max_prompt); + bstrncpy(prompt, ua->prompt[item], max_prompt); } break; } @@ -756,7 +750,7 @@ done: * storage= * job= * jobid= - * ? (prompt him with storage list) + * ? (prompt him with storage list) * (prompt him with storage list) * * If use_default is set, we assume that any keyword without a value @@ -769,59 +763,60 @@ STORE *get_storage_resource(UAContext *ua, int use_default) int jobid; JCR *jcr; int i; + char ed1[50]; for (i=1; iargc; i++) { if (use_default && !ua->argv[i]) { - /* Ignore slots, scan and barcode(s) keywords */ + /* Ignore slots, scan and barcode(s) keywords */ if (strncasecmp("scan", ua->argk[i], 4) == 0 || strncasecmp("barcode", ua->argk[i], 7) == 0 || strncasecmp("slots", ua->argk[i], 5) == 0) { - continue; - } - /* Default argument is storage */ - if (store_name) { + continue; + } + /* Default argument is storage */ + if (store_name) { bsendmsg(ua, _("Storage name given twice.\n")); - return NULL; - } - store_name = ua->argk[i]; + return NULL; + } + store_name = ua->argk[i]; if (*store_name == '?') { - *store_name = 0; - break; - } + *store_name = 0; + break; + } } else { if (strcasecmp(ua->argk[i], _("storage")) == 0 || strcasecmp(ua->argk[i], _("sd")) == 0) { - store_name = ua->argv[i]; - break; + store_name = ua->argv[i]; + break; } else if (strcasecmp(ua->argk[i], _("jobid")) == 0) { - jobid = str_to_int64(ua->argv[i]); - if (jobid <= 0) { + jobid = str_to_int64(ua->argv[i]); + if (jobid <= 0) { bsendmsg(ua, _("Expecting jobid=nn command, got: %s\n"), ua->argk[i]); - return NULL; - } - if (!(jcr=get_jcr_by_id(jobid))) { - bsendmsg(ua, _("JobId %d is not running.\n"), jobid); - return NULL; - } - store = jcr->store; - free_jcr(jcr); - break; + return NULL; + } + if (!(jcr=get_jcr_by_id(jobid))) { + bsendmsg(ua, _("JobId %s is not running.\n"), edit_int64(jobid, ed1)); + return NULL; + } + store = jcr->store; + free_jcr(jcr); + break; } else if (strcasecmp(ua->argk[i], _("job")) == 0) { - if (!ua->argv[i]) { + if (!ua->argv[i]) { bsendmsg(ua, _("Expecting job=xxx, got: %s.\n"), ua->argk[i]); - return NULL; - } - if (!(jcr=get_jcr_by_partial_name(ua->argv[i]))) { + return NULL; + } + if (!(jcr=get_jcr_by_partial_name(ua->argv[i]))) { bsendmsg(ua, _("Job \"%s\" is not running.\n"), ua->argv[i]); - return NULL; - } - store = jcr->store; - free_jcr(jcr); - break; - } + return NULL; + } + store = jcr->store; + free_jcr(jcr); + break; + } } } if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) { @@ -851,7 +846,7 @@ STORE *get_storage_resource(UAContext *ua, int use_default) * if not found or error, put up selection list * * Returns: 0 on error - * 1 on success, MediaType is set + * 1 on success, MediaType is set */ int get_media_type(UAContext *ua, char *MediaType, int max_media) { @@ -879,9 +874,9 @@ bool get_level_from_name(JCR *jcr, const char *level_name) bool found = false; for (int i=0; joblevels[i].level_name; i++) { if (strcasecmp(level_name, joblevels[i].level_name) == 0) { - jcr->JobLevel = joblevels[i].level; - found = true; - break; + jcr->JobLevel = joblevels[i].level; + found = true; + break; } } return found; diff --git a/bacula/src/dird/ua_server.c b/bacula/src/dird/ua_server.c index 4b70ba82a8..bc6bf2af6e 100644 --- a/bacula/src/dird/ua_server.c +++ b/bacula/src/dird/ua_server.c @@ -6,24 +6,18 @@ * * Version $Id$ */ - /* Copyright (C) 2000-2005 Kern Sibbald 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. + modify it under the terms of the GNU General Public License + version 2 as ammended with additional clauses defined in the + file LICENSE in the main source directory. 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -124,7 +118,7 @@ static void *handle_UA_client_request(void *arg) ua = new_ua_context(jcr); ua->UA_sock = (BSOCK *)arg; - bnet_recv(ua->UA_sock); /* Get first message */ + bnet_recv(ua->UA_sock); /* Get first message */ if (!authenticate_user_agent(ua)) { goto getout; } @@ -132,28 +126,28 @@ static void *handle_UA_client_request(void *arg) while (!ua->quit) { stat = bnet_recv(ua->UA_sock); if (stat >= 0) { - pm_strcpy(ua->cmd, ua->UA_sock->msg); - parse_ua_args(ua); + pm_strcpy(ua->cmd, ua->UA_sock->msg); + parse_ua_args(ua); if (ua->argc > 0 && ua->argk[0][0] == '.') { - do_a_dot_command(ua, ua->cmd); - } else { - do_a_command(ua, ua->cmd); - } - if (!ua->quit) { - if (ua->auto_display_messages) { + do_a_dot_command(ua, ua->cmd); + } else { + do_a_command(ua, ua->cmd); + } + if (!ua->quit) { + if (ua->auto_display_messages) { pm_strcpy(ua->cmd, "messages"); - qmessagescmd(ua, ua->cmd); - ua->user_notified_msg_pending = FALSE; - } else if (!ua->user_notified_msg_pending && console_msg_pending) { + qmessagescmd(ua, ua->cmd); + ua->user_notified_msg_pending = FALSE; + } else if (!ua->user_notified_msg_pending && console_msg_pending) { bsendmsg(ua, _("You have messages.\n")); - ua->user_notified_msg_pending = TRUE; - } - bnet_sig(ua->UA_sock, BNET_EOD); /* send end of command */ - } + ua->user_notified_msg_pending = TRUE; + } + bnet_sig(ua->UA_sock, BNET_EOD); /* send end of command */ + } } else if (is_bnet_stop(ua->UA_sock)) { - ua->quit = true; + ua->quit = true; } else { /* signal */ - bnet_sig(ua->UA_sock, BNET_POLL); + bnet_sig(ua->UA_sock, BNET_POLL); } } diff --git a/bacula/src/dird/ua_status.c b/bacula/src/dird/ua_status.c index 1d2a390f87..5eec04d41b 100644 --- a/bacula/src/dird/ua_status.c +++ b/bacula/src/dird/ua_status.c @@ -38,15 +38,16 @@ static void do_director_status(UAContext *ua); static void do_all_status(UAContext *ua); static char OKqstatus[] = "1000 OK .status\n"; -static char DotStatusJob[] = "JobId=%d JobStatus=%c JobErrors=%d\n"; +static char DotStatusJob[] = "JobId=%s JobStatus=%c JobErrors=%d\n"; /* * .status command */ int qstatus_cmd(UAContext *ua, const char *cmd) { - JCR* njcr; + JCR* njcr = NULL; s_last_job* job; + char ed1[50]; if (!open_db(ua)) { return 1; @@ -62,19 +63,19 @@ int qstatus_cmd(UAContext *ua, const char *cmd) bsendmsg(ua, OKqstatus, ua->argk[2]); foreach_jcr(njcr) { if (njcr->JobId != 0) { - bsendmsg(ua, DotStatusJob, njcr->JobId, njcr->JobStatus, njcr->JobErrors); + bsendmsg(ua, DotStatusJob, edit_int64(njcr->JobId, ed1), + njcr->JobStatus, njcr->JobErrors); } free_jcr(njcr); } - } - else if (strcasecmp(ua->argk[2], "last") == 0) { + } else if (strcasecmp(ua->argk[2], "last") == 0) { bsendmsg(ua, OKqstatus, ua->argk[2]); if ((last_jobs) && (last_jobs->size() > 0)) { job = (s_last_job*)last_jobs->last(); - bsendmsg(ua, DotStatusJob, job->JobId, job->JobStatus, job->Errors); + bsendmsg(ua, DotStatusJob, edit_int64(njcr->JobId, ed1), + njcr->JobStatus, njcr->JobErrors); } - } - else { + } else { bsendmsg(ua, "1900 Bad .status command, wrong argument.\n"); return 1; } diff --git a/bacula/src/dird/ua_tree.c b/bacula/src/dird/ua_tree.c index 0d3bb6d31e..0460329951 100644 --- a/bacula/src/dird/ua_tree.c +++ b/bacula/src/dird/ua_tree.c @@ -469,7 +469,7 @@ static void ls_output(char *buf, const char *fname, const char *tag, struct stat n = sprintf(p, "%-8.8s %-8.8s", getuser(statp->st_uid, en1, sizeof(en1)), getgroup(statp->st_gid, en2, sizeof(en2))); p += n; - n = sprintf(p, "%8.8s ", edit_uint64(statp->st_size, ec1)); + n = sprintf(p, "%10.10s ", edit_uint64(statp->st_size, ec1)); p += n; p = encode_time(statp->st_ctime, p); *p++ = ' '; diff --git a/bacula/src/dird/ua_update.c b/bacula/src/dird/ua_update.c index a9b0567015..319f55bbae 100644 --- a/bacula/src/dird/ua_update.c +++ b/bacula/src/dird/ua_update.c @@ -7,24 +7,18 @@ * * Version $Id$ */ - /* Copyright (C) 2000-2005 Kern Sibbald 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. + modify it under the terms of the GNU General Public License + version 2 as ammended with additional clauses defined in the + file LICENSE in the main source directory. 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c index 0bf2862ae8..24c06426b0 100755 --- a/bacula/src/findlib/find_one.c +++ b/bacula/src/findlib/find_one.c @@ -401,7 +401,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, * to cross, or we may be restricted by a list of permitted * file systems. */ - if (ff_pkt->flags & FO_NO_RECURSION) { + if (!top_level && ff_pkt->flags & FO_NO_RECURSION) { ff_pkt->type = FT_NORECURSE; recurse = false; } else if (!top_level && parent_device != ff_pkt->statp.st_dev) { diff --git a/bacula/src/lib/attr.c b/bacula/src/lib/attr.c index 53ca134a34..74076b13c2 100644 --- a/bacula/src/lib/attr.c +++ b/bacula/src/lib/attr.c @@ -200,7 +200,7 @@ void print_ls_output(JCR *jcr, ATTR *attr) p += sprintf(p, " %2d ", (uint32_t)attr->statp.st_nlink); p += sprintf(p, "%-8.8s %-8.8s", getuser(attr->statp.st_uid, en1, sizeof(en1)), getgroup(attr->statp.st_gid, en2, sizeof(en2))); - p += sprintf(p, "%8.8s ", edit_uint64(attr->statp.st_size, ec1)); + p += sprintf(p, "%10.10s ", edit_uint64(attr->statp.st_size, ec1)); p = encode_time(attr->statp.st_ctime, p); *p++ = ' '; *p++ = ' '; diff --git a/bacula/src/stored/bacula-sd.conf.in b/bacula/src/stored/bacula-sd.conf.in index 97ac761892..19cfe98b26 100644 --- a/bacula/src/stored/bacula-sd.conf.in +++ b/bacula/src/stored/bacula-sd.conf.in @@ -53,6 +53,43 @@ Device { AlwaysOpen = no; } +# +# An autochanger device with two drives +# +#Autochanger { +# Name = Autochanger +# Device = Drive-1 +# Device = Drive-2 +# Changer Command = "/home/kern/bacula/bin/mtx-changer %c %o %S %a %d" +# Changer Device = /dev/sg0 +#} + +#Device { +# Name = Drive-1 # +# Drive Index = 0 +# Media Type = DLT-8000 +# Archive Device = /dev/nst0 +# AutomaticMount = yes; # when device opened, read it +# AlwaysOpen = yes; +# RemovableMedia = yes; +# RandomAccess = no; +# AutoChanger = yes +# Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'" +#} + +#Device { +# Name = Drive-2 # +# Drive Index = 1 +# Media Type = DLT-8000 +# Archive Device = /dev/nst1 +# AutomaticMount = yes; # when device opened, read it +# AlwaysOpen = yes; +# RemovableMedia = yes; +# RandomAccess = no; +# AutoChanger = yes +# Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'" +#} + # # A Linux or Solaris tape drive # diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 371842635a..94ecfb312e 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -1162,7 +1162,7 @@ try_again: slot = 1; dcr->VolCatInfo.Slot = slot; - Pmsg2(-1, _("3303 Issuing autochanger \"load slot %d %d\" command.\n"), + Pmsg2(-1, _("3303 Issuing autochanger \"load %d %d\" command.\n"), slot, dev->drive_index); changer = edit_device_codes(dcr, changer, dcr->device->changer_command, "load"); @@ -1170,7 +1170,7 @@ try_again: force_close_device(dev); status = run_program(changer, timeout, results); if (status == 0) { - Pmsg2(-1, _("3303 Autochanger \"load slot %d %d\" status is OK.\n"), + Pmsg2(-1, _("3303 Autochanger \"load %d %d\" status is OK.\n"), slot, dev->drive_index); } else { berrno be; diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index b495f9f70b..1484edcf66 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -274,7 +274,9 @@ DEVICE::open(DCR *dcr, int mode) ::close(fd); /* use system close so correct mode will be used on open */ } } - bstrncpy(VolCatInfo.VolCatName, dcr->VolumeName, sizeof(VolCatInfo.VolCatName)); + if (dcr) { + bstrncpy(VolCatInfo.VolCatName, dcr->VolumeName, sizeof(VolCatInfo.VolCatName)); + } Dmsg4(29, "open dev: tape=%d dev_name=%s vol=%s mode=%s\n", is_tape(), dev_name, VolCatInfo.VolCatName, mode_to_str(mode)); diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index d876eff448..0c4d2f95b5 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -557,7 +557,7 @@ static bool mount_cmd(JCR *jcr) case BST_UNMOUNTED_WAITING_FOR_SYSOP: case BST_UNMOUNTED: /* We freed the device, so reopen it and wake any waiting threads */ - if (dev->open(NULL, OPEN_READ_WRITE) < 0) { + if (dev->open(dcr, OPEN_READ_WRITE) < 0) { bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"), strerror_dev(dev)); break; diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index b7a101b3ec..46e74647a8 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -218,7 +218,7 @@ read_volume: /* Restore desired volume name, note device info out of sync */ /* This gets the info regardless of the Pool */ bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName)); - if (autochanger && dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) { + if (autochanger && !dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) { mark_volume_not_inchanger(dcr); } memcpy(&dev->VolCatInfo, &devVolCatInfo, sizeof(dev->VolCatInfo)); diff --git a/bacula/src/version.h b/bacula/src/version.h index 0aee6f7f73..b1dfb9f995 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #undef VERSION #define VERSION "1.37.28" -#define BDATE "02 July 2005" -#define LSMDATE "02Jul05" +#define BDATE "03 July 2005" +#define LSMDATE "03Jul05" /* Debug flags */ #undef DEBUG diff --git a/bacula/src/win32/winbacula.nsi.in b/bacula/src/win32/winbacula.nsi.in index cc83244df6..56a3e24250 100755 --- a/bacula/src/win32/winbacula.nsi.in +++ b/bacula/src/win32/winbacula.nsi.in @@ -184,6 +184,7 @@ Section "Install Console" SecConsole File console\Release\bconsole.exe IfFileExists "$INSTDIR\bin\bconsole.conf" newconf File console\bconsole.conf + File ..\..\..\depkgs-win32\pthreads\pthreadVCE.dll goto do_next newconf: File /oname=bconsole.conf.new console\bconsole.conf @@ -202,6 +203,7 @@ Section "Install wx-Console" SecWxConsole File wx-console\Release\wx-console.exe IfFileExists "$INSTDIR\bin\wx-console.conf" newconf File wx-console\wx-console.conf + File ..\..\..\depkgs-win32\pthreads\pthreadVCE.dll goto do_next newconf: File /oname=wx-console.conf.new wx-console\wx-console.conf diff --git a/bacula/src/wx-console/wxbrestorepanel.cpp b/bacula/src/wx-console/wxbrestorepanel.cpp index 469a5cccbf..f8d657dab0 100644 --- a/bacula/src/wx-console/wxbrestorepanel.cpp +++ b/bacula/src/wx-console/wxbrestorepanel.cpp @@ -1483,18 +1483,18 @@ wxString* wxbRestorePanel::ParseList(wxString line) { wxString* ret = new wxString[9]; - ret[0] = line.Mid(0, 10).Trim(); + ret[0] = line.Mid(0, 10).Trim(); // modes /* Column 1 has a variable width */ i = line.find(' ', 14) - 14; - ret[1] = line.Mid(12, 2+i).Trim(); - - ret[2] = line.Mid(15+i, 8).Trim(); - ret[3] = line.Mid(24+i, 8).Trim(); - ret[4] = line.Mid(32+i, 8).Trim(); - ret[5] = line.Mid(42+i, 19).Trim(); - ret[6] = line.Mid(62+i, 1); - ret[7] = line.Mid(63+i).Trim(); + ret[1] = line.Mid(12, 2+i).Trim(); // number of links + + ret[2] = line.Mid(15+i, 8).Trim(); // user + ret[3] = line.Mid(24+i, 8).Trim(); // group + ret[4] = line.Mid(32+i, 10).Trim(); // file size + ret[5] = line.Mid(42+i, 19).Trim(); // date + time + ret[6] = line.Mid(62+i, 1); // ? + ret[7] = line.Mid(63+i).Trim(); // filename if (ret[6] == wxT(" ")) ret[6] = wxT("");