]> git.sur5r.net Git - bacula/bacula/commitdiff
Vacation work -- see tech log
authorKern Sibbald <kern@sibbald.com>
Sat, 29 Jan 2005 22:39:04 +0000 (22:39 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 29 Jan 2005 22:39:04 +0000 (22:39 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1806 91ce42f0-d328-0410-95d8-f526ca767f89

114 files changed:
bacula/ReleaseNotes
bacula/autoconf/acconfig.h
bacula/autoconf/aclocal.m4
bacula/autoconf/config.h.in
bacula/autoconf/config.h.in.save
bacula/autoconf/configure.in
bacula/configure
bacula/examples/python/EndJob.py
bacula/kernstodo
bacula/platforms/solaris/bacula-dir.in
bacula/platforms/solaris/bacula-fd.in
bacula/platforms/solaris/bacula-sd.in
bacula/src/baconfig.h
bacula/src/cats/bdb_create.c
bacula/src/cats/cats.h
bacula/src/cats/create_bacula_database.in
bacula/src/cats/create_sqlite_database.in
bacula/src/cats/drop_bacula_database.in
bacula/src/cats/drop_bacula_tables.in
bacula/src/cats/drop_sqlite_database.in
bacula/src/cats/grant_bacula_privileges.in
bacula/src/cats/make_bacula_tables.in
bacula/src/cats/make_mysql_tables.in
bacula/src/cats/make_postgresql_tables.in
bacula/src/cats/make_sqlite_tables.in
bacula/src/cats/protos.h
bacula/src/cats/sql.c
bacula/src/cats/sql_create.c
bacula/src/cats/sql_delete.c
bacula/src/cats/sql_find.c
bacula/src/cats/sql_get.c
bacula/src/cats/sql_list.c
bacula/src/cats/sql_update.c
bacula/src/cats/sqlite.c
bacula/src/cats/update_bacula_tables.in
bacula/src/cats/update_mysql_tables.in
bacula/src/cats/update_postgresql_tables.in
bacula/src/cats/update_sqlite_tables.in
bacula/src/dird/backup.c
bacula/src/dird/bsr.c
bacula/src/dird/catreq.c
bacula/src/dird/dird.c
bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/dird/getmsg.c
bacula/src/dird/inc_conf.c
bacula/src/dird/job.c
bacula/src/dird/jobq.c
bacula/src/dird/mac.c
bacula/src/dird/msgchan.c
bacula/src/dird/protos.h
bacula/src/dird/restore.c
bacula/src/dird/scheduler.c
bacula/src/dird/sql_cmds.c
bacula/src/dird/ua_acl.c
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_dotcmds.c
bacula/src/dird/ua_label.c
bacula/src/dird/ua_output.c
bacula/src/dird/ua_query.c
bacula/src/dird/ua_restore.c
bacula/src/dird/ua_run.c
bacula/src/dird/ua_server.c
bacula/src/dird/ua_tree.c
bacula/src/dird/verify.c
bacula/src/filed/acl.c
bacula/src/filed/job.c
bacula/src/filed/verify_vol.c
bacula/src/jcr.h
bacula/src/lib/alist.h
bacula/src/lib/bnet.c
bacula/src/lib/bpipe.c
bacula/src/lib/daemon.c
bacula/src/lib/edit.c
bacula/src/lib/htable.c
bacula/src/lib/htable.h
bacula/src/lib/jcr.c
bacula/src/lib/message.c
bacula/src/lib/parse_conf.c
bacula/src/lib/protos.h
bacula/src/lib/scan.c
bacula/src/lib/watchdog.c
bacula/src/lib/workq.c
bacula/src/stored/acquire.c
bacula/src/stored/append.c
bacula/src/stored/askdir.c
bacula/src/stored/autochanger.c
bacula/src/stored/bcopy.c
bacula/src/stored/bextract.c
bacula/src/stored/block.c
bacula/src/stored/block.h
bacula/src/stored/bls.c
bacula/src/stored/bsr.h
bacula/src/stored/btape.c
bacula/src/stored/butil.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/device.c
bacula/src/stored/dircmd.c
bacula/src/stored/fd_cmds.c
bacula/src/stored/job.c
bacula/src/stored/label.c
bacula/src/stored/mount.c
bacula/src/stored/parse_bsr.c
bacula/src/stored/protos.h
bacula/src/stored/read.c
bacula/src/stored/read_record.c
bacula/src/stored/record.c
bacula/src/stored/spool.c
bacula/src/stored/status.c
bacula/src/stored/stored.c
bacula/src/stored/stored_conf.c
bacula/src/stored/stored_conf.h
bacula/src/version.h

index 42cb27e695de13464cbe5a6332cfc23924690d0e..d8bd80297d9824c32411e739c28a7250bd140475 100644 (file)
@@ -1,10 +1,21 @@
 
-          Release Notes for Bacula 1.37.2
+          Release Notes for Bacula 1.37.3
 
-  Bacula code: Total files = 398 Total lines = 117,151 (*.h *.c *.in)
+  Bacula code: Total files = 411 Total lines = 121,855 (*.h *.c *.in)
 
 
 Major Changes:
+- This version has a new database format that is not compatible
+  with previous databases. There are NO upgrade scripts yet.
+- Due to the massive changes made during the last two weeks, 
+  version 1.37.3 should be considered unstable.  It does, however,
+  pass the regression tests.
+- SQLite3 support.
+- First cut at ANSI labels.
+- New communications protocol between DIR and SD to reserve 
+  drives.
+
+
 - Preliminary Python Event support has been added. See below for
   configuration.
   A Python script will be called at particular points or conditions
index bd0bb6b78e29d7da5e27e4c4ddc8af989b9b0b52..e93344357f8cdd021563251d9575dffb60b472d6 100644 (file)
 /* Define if you want to use SQLite */
 #undef HAVE_SQLITE
 
+/* Define if you want to use SQLite3 */
+#undef HAVE_SQLITE3
+
 /* Define if you want to use Berkeley DB */
 #undef HAVE_BERKELEY_DB
 
-
-/* Define if you want to use PostgreSQL */
-#undef HAVE_PGSQL
-
 /* Define if you want to use mSQL */
 #undef HAVE_MSQL
 
index 3f05d19f35bbd74bfad925a5d4ecdb8419696b03..8641178cfd92bbbb4a4f5963513c06b8635fb27d 100644 (file)
@@ -541,6 +541,72 @@ AC_SUBST(SQL_BINDIR)
   
 ])
 
+AC_DEFUN(BA_CHECK_SQLITE3_DB,
+[
+db_found=no
+AC_MSG_CHECKING(for SQLite3 support)
+AC_ARG_WITH(sqlite3,
+[
+  --with-sqlite3[=DIR]    Include SQLite3 support.  DIR is the SQLite3 base
+                          install directory, default is to search through
+                          a number of common places for the SQLite3 files.],
+[
+  if test "$withval" != "no"; then
+     if test "$withval" = "yes"; then
+        if test -f /usr/local/include/sqlite3.h; then
+           SQLITE_INCDIR=/usr/local/include
+           SQLITE_LIBDIR=/usr/local/lib
+           SQLITE_BINDIR=/usr/local/bin
+        elif test -f /usr/include/sqlite3.h; then
+           SQLITE_INCDIR=/usr/include
+           SQLITE_LIBDIR=/usr/lib
+           SQLITE_BINDIR=/usr/bin      
+        elif test -f $prefix/include/sqlite3.h; then
+           SQLITE_INCDIR=$prefix/include
+           SQLITE_LIBDIR=$prefix/lib
+           SQLITE_BINDIR=$prefix/bin      
+        else
+           AC_MSG_RESULT(no)
+           AC_MSG_ERROR(Unable to find sqlite3.h in standard locations)
+        fi
+     else
+        if test -f $withval/sqlite3.h; then
+           SQLITE_INCDIR=$withval
+           SQLITE_LIBDIR=$withval
+           SQLITE_BINDIR=$withval
+        elif test -f $withval/include/sqlite3.h; then
+           SQLITE_INCDIR=$withval/include
+           SQLITE_LIBDIR=$withval/lib
+           SQLITE_BINDIR=$withval/bin
+        else
+           AC_MSG_RESULT(no)
+           AC_MSG_ERROR(Invalid SQLite3 directory $withval - unable to find sqlite3.h under $withval)
+        fi
+     fi
+     SQL_INCLUDE=-I$SQLITE_INCDIR
+     SQL_LFLAGS="-L$SQLITE_LIBDIR -lsqlite3"
+     SQL_BINDIR=$SQLITE_BINDIR
+
+     AC_DEFINE(HAVE_SQLITE3)
+     AC_MSG_RESULT(yes)
+     db_found=yes
+     support_sqlite3=yes
+     db_name=SQLite3
+     DB_NAME=sqlite3
+
+  else
+     AC_MSG_RESULT(no)
+  fi
+],[
+  AC_MSG_RESULT(no)
+])
+AC_SUBST(SQL_LFLAGS)
+AC_SUBST(SQL_INCLUDE)
+AC_SUBST(SQL_BINDIR)
+  
+])
+
+
 
 AC_DEFUN(BA_CHECK_POSTGRESQL_DB,
 [
index 8d3797e6b419676a72723c0693afa14a01109b38..9470a3e23a4d3c0c0c9acaacf86965136e9f48de 100644 (file)
 /* Define if you want to use SQLite */
 #undef HAVE_SQLITE
 
+/* Define if you want to use SQLite3 */
+#undef HAVE_SQLITE3
+
 /* Define if you want to use Berkeley DB */
 #undef HAVE_BERKELEY_DB
 
-
-/* Define if you want to use PostgreSQL */
-#undef HAVE_PGSQL
-
 /* Define if you want to use mSQL */
 #undef HAVE_MSQL
 
index adac090114858ad76c045061c686d40ba76cfbdc..9470a3e23a4d3c0c0c9acaacf86965136e9f48de 100644 (file)
 /* Define if you want to use SQLite */
 #undef HAVE_SQLITE
 
+/* Define if you want to use SQLite3 */
+#undef HAVE_SQLITE3
+
 /* Define if you want to use Berkeley DB */
 #undef HAVE_BERKELEY_DB
 
-
-/* Define if you want to use PostgreSQL */
-#undef HAVE_PGSQL
-
 /* Define if you want to use mSQL */
 #undef HAVE_MSQL
 
 /* If using the C implementation of alloca, define if you know the
    direction of stack growth for your system; otherwise it will be
    automatically deduced at run-time.
-        STACK_DIRECTION > 0 => grows toward higher addresses
-        STACK_DIRECTION < 0 => grows toward lower addresses
-        STACK_DIRECTION = 0 => direction of growth unknown */
+       STACK_DIRECTION > 0 => grows toward higher addresses
+       STACK_DIRECTION < 0 => grows toward lower addresses
+       STACK_DIRECTION = 0 => direction of growth unknown */
 #undef STACK_DIRECTION
 
 /* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
index a3e70fa4a4566dbee322cc076278d5542ff9787e..cd22084c4ae17d4283668fb103e91e3877295f4d 100644 (file)
@@ -147,6 +147,7 @@ fi
 
 support_mysql=no
 support_sqlite=no
+support_sqlite3=no
 support_postgresql=no
 support_smartalloc=yes
 support_readline=yes
@@ -577,6 +578,12 @@ if test ! x$CDRECORD = x ; then
    if test x${CDSTL} = x ; then
       CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep CD+RW | ${AWK} '{print $1}'`
    fi
+   if test x${CDSTL} = x ; then
+      CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep DVD+RW | ${AWK} '{print $1}'`
+   fi
+   if test x${CDSTL} = x ; then
+      CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep DVD-RW | ${AWK} '{print $1}'`
+   fi
    if test x${CDSTL} = x ; then
       CDSTL="3,0,0"
    fi
@@ -1187,6 +1194,8 @@ BA_CHECK_POSTGRESQL_DB
 
 BA_CHECK_MYSQL_DB
 
+BA_CHECK_SQLITE3_DB
+
 BA_CHECK_SQLITE_DB
 
 AC_SUBST(cats)
@@ -1959,8 +1968,8 @@ AC_OUTPUT([autoconf/Make.common \
           scripts/dvd-writepart \
           scripts/dvd-freespace \
           scripts/bacula-tray-monitor.desktop \
-           scripts/logwatch/Makefile \
-           scripts/logwatch/logfile.bacula.conf \
+          scripts/logwatch/Makefile \
+          scripts/logwatch/logfile.bacula.conf \
           doc/Makefile \
           src/Makefile \
           src/host.h \
@@ -2003,6 +2012,12 @@ AC_OUTPUT([autoconf/Make.common \
           src/cats/grant_sqlite_privileges \
           src/cats/drop_sqlite_tables \
           src/cats/drop_sqlite_database \
+          src/cats/create_sqlite3_database \
+          src/cats/update_sqlite3_tables \
+          src/cats/make_sqlite3_tables \
+          src/cats/grant_sqlite3_privileges \
+          src/cats/drop_sqlite3_tables \
+          src/cats/drop_sqlite3_database \
           src/cats/sqlite \
           src/cats/mysql \
           src/cats/create_bdb_database \
@@ -2091,7 +2106,7 @@ if test "x${db_name}" = "xInternal" ; then
    echo " "
    echo " "
    echo "You have not specified either --enable-client-only or one of the"
-   echo "  supported databases: MySQL, PostgreSQL, or SQLite".
+   echo "  supported databases: MySQL, PostgreSQL, SQLite3 or SQLite."
    echo "  This is not permitted. Please reconfigure."
    echo " "
    echo "Aborting the configuration ..."
index 870cd22dc2650f5d1bc832a2bfe446e90a57ba51..1c1693a48ee4a711159a20b7ea3bd5f8eb78e7c9 100755 (executable)
@@ -922,6 +922,10 @@ Optional Packages:
                           install directory, default is to search through
                           a number of common places for the MySQL files.
 
+  --with-sqlite3=DIR    Include SQLite3 support.  DIR is the SQLite3 base
+                          install directory, default is to search through
+                          a number of common places for the SQLite3 files.
+
   --with-sqlite=DIR     Include SQLite support.  DIR is the SQLite base
                           install directory, default is to search through
                           a number of common places for the SQLite files.
@@ -4701,6 +4705,7 @@ fi
 
 support_mysql=no
 support_sqlite=no
+support_sqlite3=no
 support_postgresql=no
 support_smartalloc=yes
 support_readline=yes
@@ -7483,6 +7488,12 @@ if test ! x$CDRECORD = x ; then
    if test x${CDSTL} = x ; then
       CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep CD+RW | ${AWK} '{print $1}'`
    fi
+   if test x${CDSTL} = x ; then
+      CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep DVD+RW | ${AWK} '{print $1}'`
+   fi
+   if test x${CDSTL} = x ; then
+      CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep DVD-RW | ${AWK} '{print $1}'`
+   fi
    if test x${CDSTL} = x ; then
       CDSTL="3,0,0"
    fi
@@ -9005,6 +9016,85 @@ fi;
 
 
 
+db_found=no
+echo "$as_me:$LINENO: checking for SQLite3 support" >&5
+echo $ECHO_N "checking for SQLite3 support... $ECHO_C" >&6
+
+# Check whether --with-sqlite3 or --without-sqlite3 was given.
+if test "${with_sqlite3+set}" = set; then
+  withval="$with_sqlite3"
+
+  if test "$withval" != "no"; then
+     if test "$withval" = "yes"; then
+        if test -f /usr/local/include/sqlite3.h; then
+           SQLITE_INCDIR=/usr/local/include
+           SQLITE_LIBDIR=/usr/local/lib
+           SQLITE_BINDIR=/usr/local/bin
+        elif test -f /usr/include/sqlite3.h; then
+           SQLITE_INCDIR=/usr/include
+           SQLITE_LIBDIR=/usr/lib
+           SQLITE_BINDIR=/usr/bin
+        elif test -f $prefix/include/sqlite3.h; then
+           SQLITE_INCDIR=$prefix/include
+           SQLITE_LIBDIR=$prefix/lib
+           SQLITE_BINDIR=$prefix/bin
+        else
+           echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+           { { echo "$as_me:$LINENO: error: Unable to find sqlite3.h in standard locations" >&5
+echo "$as_me: error: Unable to find sqlite3.h in standard locations" >&2;}
+   { (exit 1); exit 1; }; }
+        fi
+     else
+        if test -f $withval/sqlite3.h; then
+           SQLITE_INCDIR=$withval
+           SQLITE_LIBDIR=$withval
+           SQLITE_BINDIR=$withval
+        elif test -f $withval/include/sqlite3.h; then
+           SQLITE_INCDIR=$withval/include
+           SQLITE_LIBDIR=$withval/lib
+           SQLITE_BINDIR=$withval/bin
+        else
+           echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+           { { echo "$as_me:$LINENO: error: Invalid SQLite3 directory $withval - unable to find sqlite3.h under $withval" >&5
+echo "$as_me: error: Invalid SQLite3 directory $withval - unable to find sqlite3.h under $withval" >&2;}
+   { (exit 1); exit 1; }; }
+        fi
+     fi
+     SQL_INCLUDE=-I$SQLITE_INCDIR
+     SQL_LFLAGS="-L$SQLITE_LIBDIR -lsqlite3"
+     SQL_BINDIR=$SQLITE_BINDIR
+
+     cat >>confdefs.h <<\_ACEOF
+#define HAVE_SQLITE3 1
+_ACEOF
+
+     echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+     db_found=yes
+     support_sqlite3=yes
+     db_name=SQLite3
+     DB_NAME=sqlite3
+
+  else
+     echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  fi
+
+else
+
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi;
+
+
+
+
+
+
+
 db_found=no
 echo "$as_me:$LINENO: checking for SQLite support" >&5
 echo $ECHO_N "checking for SQLite support... $ECHO_C" >&6
@@ -21411,7 +21501,7 @@ if test "x${subsysdir}" = "x${sbindir}" ; then
    exit 1
 fi
 
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ac_config_files="$ac_config_files autoconf/Make.common Makefile rescue/Makefile rescue/linux/Makefile rescue/linux/floppy/Makefile rescue/linux/cdrom/Makefile rescue/linux/cdrom/bacula/Makefile rescue/freebsd/Makefile rescue/solaris/Makefile scripts/startmysql scripts/stopmysql scripts/btraceback scripts/startit scripts/stopit scripts/bconsole scripts/gconsole scripts/bacula scripts/devel_bacula scripts/Makefile scripts/logrotate scripts/bacula.desktop.gnome1 scripts/bacula.desktop.gnome2 scripts/bacula.desktop.gnome1.consolehelper scripts/bacula.desktop.gnome2.consolehelper scripts/bacula.desktop.gnome1.xsu scripts/bacula.desktop.gnome2.xsu scripts/gnome-console.console_apps scripts/mtx-changer scripts/dvd-writepart scripts/dvd-freespace scripts/bacula-tray-monitor.desktop scripts/logwatch/Makefile scripts/logwatch/logfile.bacula.conf doc/Makefile src/Makefile src/host.h src/console/Makefile src/console/bconsole.conf src/gnome-console/Makefile src/gnome-console/gnome-console.conf src/gnome2-console/Makefile src/gnome2-console/gnome-console.conf src/wx-console/Makefile src/wx-console/wx-console.conf src/tray-monitor/Makefile src/tray-monitor/tray-monitor.conf src/dird/Makefile src/dird/bacula-dir.conf src/lib/Makefile src/stored/Makefile src/stored/bacula-sd.conf src/filed/Makefile src/filed/bacula-fd.conf src/filed/win32/Makefile src/cats/Makefile src/cats/make_catalog_backup src/cats/delete_catalog_backup src/cats/create_postgresql_database src/cats/update_postgresql_tables src/cats/make_postgresql_tables src/cats/grant_postgresql_privileges src/cats/drop_postgresql_tables src/cats/drop_postgresql_database src/cats/create_mysql_database src/cats/update_mysql_tables src/cats/make_mysql_tables src/cats/grant_mysql_privileges src/cats/drop_mysql_tables src/cats/drop_mysql_database src/cats/create_sqlite_database src/cats/update_sqlite_tables src/cats/make_sqlite_tables src/cats/grant_sqlite_privileges src/cats/drop_sqlite_tables src/cats/drop_sqlite_database src/cats/sqlite src/cats/mysql src/cats/create_bdb_database src/cats/update_bdb_tables src/cats/make_bdb_tables src/cats/grant_bdb_privileges src/cats/drop_bdb_tables src/cats/drop_bdb_database src/cats/create_bacula_database src/cats/update_bacula_tables src/cats/grant_bacula_privileges src/cats/make_bacula_tables src/cats/drop_bacula_tables src/cats/drop_bacula_database src/findlib/Makefile src/tools/Makefile src/win32/winbacula.nsi src/win32/baculafd/bacula-fd.conf src/win32/Makefile src/win32/console/bconsole.conf src/win32/wx-console/wx-console.conf src/win32/pebuilder/Makefile src/bimagemgr/Makefile src/bimagemgr/bacula-bimagemgr.spec $PFILES"
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ac_config_files="$ac_config_files autoconf/Make.common Makefile rescue/Makefile rescue/linux/Makefile rescue/linux/floppy/Makefile rescue/linux/cdrom/Makefile rescue/linux/cdrom/bacula/Makefile rescue/freebsd/Makefile rescue/solaris/Makefile scripts/startmysql scripts/stopmysql scripts/btraceback scripts/startit scripts/stopit scripts/bconsole scripts/gconsole scripts/bacula scripts/devel_bacula scripts/Makefile scripts/logrotate scripts/bacula.desktop.gnome1 scripts/bacula.desktop.gnome2 scripts/bacula.desktop.gnome1.consolehelper scripts/bacula.desktop.gnome2.consolehelper scripts/bacula.desktop.gnome1.xsu scripts/bacula.desktop.gnome2.xsu scripts/gnome-console.console_apps scripts/mtx-changer scripts/dvd-writepart scripts/dvd-freespace scripts/bacula-tray-monitor.desktop scripts/logwatch/Makefile scripts/logwatch/logfile.bacula.conf doc/Makefile src/Makefile src/host.h src/console/Makefile src/console/bconsole.conf src/gnome-console/Makefile src/gnome-console/gnome-console.conf src/gnome2-console/Makefile src/gnome2-console/gnome-console.conf src/wx-console/Makefile src/wx-console/wx-console.conf src/tray-monitor/Makefile src/tray-monitor/tray-monitor.conf src/dird/Makefile src/dird/bacula-dir.conf src/lib/Makefile src/stored/Makefile src/stored/bacula-sd.conf src/filed/Makefile src/filed/bacula-fd.conf src/filed/win32/Makefile src/cats/Makefile src/cats/make_catalog_backup src/cats/delete_catalog_backup src/cats/create_postgresql_database src/cats/update_postgresql_tables src/cats/make_postgresql_tables src/cats/grant_postgresql_privileges src/cats/drop_postgresql_tables src/cats/drop_postgresql_database src/cats/create_mysql_database src/cats/update_mysql_tables src/cats/make_mysql_tables src/cats/grant_mysql_privileges src/cats/drop_mysql_tables src/cats/drop_mysql_database src/cats/create_sqlite_database src/cats/update_sqlite_tables src/cats/make_sqlite_tables src/cats/grant_sqlite_privileges src/cats/drop_sqlite_tables src/cats/drop_sqlite_database src/cats/create_sqlite3_database src/cats/update_sqlite3_tables src/cats/make_sqlite3_tables src/cats/grant_sqlite3_privileges src/cats/drop_sqlite3_tables src/cats/drop_sqlite3_database src/cats/sqlite src/cats/mysql src/cats/create_bdb_database src/cats/update_bdb_tables src/cats/make_bdb_tables src/cats/grant_bdb_privileges src/cats/drop_bdb_tables src/cats/drop_bdb_database src/cats/create_bacula_database src/cats/update_bacula_tables src/cats/grant_bacula_privileges src/cats/make_bacula_tables src/cats/drop_bacula_tables src/cats/drop_bacula_database src/findlib/Makefile src/tools/Makefile src/win32/winbacula.nsi src/win32/baculafd/bacula-fd.conf src/win32/Makefile src/win32/console/bconsole.conf src/win32/wx-console/wx-console.conf src/win32/pebuilder/Makefile src/bimagemgr/Makefile src/bimagemgr/bacula-bimagemgr.spec $PFILES"
           ac_config_commands="$ac_config_commands default"
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
   "src/cats/grant_sqlite_privileges" ) CONFIG_FILES="$CONFIG_FILES src/cats/grant_sqlite_privileges" ;;
   "src/cats/drop_sqlite_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_sqlite_tables" ;;
   "src/cats/drop_sqlite_database" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_sqlite_database" ;;
+  "src/cats/create_sqlite3_database" ) CONFIG_FILES="$CONFIG_FILES src/cats/create_sqlite3_database" ;;
+  "src/cats/update_sqlite3_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/update_sqlite3_tables" ;;
+  "src/cats/make_sqlite3_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/make_sqlite3_tables" ;;
+  "src/cats/grant_sqlite3_privileges" ) CONFIG_FILES="$CONFIG_FILES src/cats/grant_sqlite3_privileges" ;;
+  "src/cats/drop_sqlite3_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_sqlite3_tables" ;;
+  "src/cats/drop_sqlite3_database" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_sqlite3_database" ;;
   "src/cats/sqlite" ) CONFIG_FILES="$CONFIG_FILES src/cats/sqlite" ;;
   "src/cats/mysql" ) CONFIG_FILES="$CONFIG_FILES src/cats/mysql" ;;
   "src/cats/create_bdb_database" ) CONFIG_FILES="$CONFIG_FILES src/cats/create_bdb_database" ;;
@@ -22988,7 +23084,7 @@ if test "x${db_name}" = "xInternal" ; then
    echo " "
    echo " "
    echo "You have not specified either --enable-client-only or one of the"
-   echo "  supported databases: MySQL, PostgreSQL, or SQLite".
+   echo "  supported databases: MySQL, PostgreSQL, SQLite3 or SQLite."
    echo "  This is not permitted. Please reconfigure."
    echo " "
    echo "Aborting the configuration ..."
index 7624766f317196281b50ee18c51ed24b9ff6be18..282ac7c6eef0a54f8250d2f35c01d2af91352464 100644 (file)
@@ -3,9 +3,9 @@ import bacula
 def EndJob(j):
     jobid = bacula.get(j, "JobId")
     client = bacula.get(j, "Client") 
-    bacula.set(jcr=j, JobReport="Python JodJob output: JobId=%d Client=%s.\n" % (jobid, client))
+    bacula.set(jcr=j, JobReport="Python EndJob output: JobId=%d Client=%s.\n" % (jobid, client))
     if (jobid < 5) :
        startid = bacula.run(j, "run kernsave")
-       print "Python started jobid=", startid
+       print "Python started new Job: jobid=", startid
 
     return 1
index e5a94f422e3aacf1cc1e7404a3327f0d0b978a8c..84046115470d667ced6f0c2f880d279779311551 100644 (file)
@@ -1,5 +1,5 @@
                     Kern's ToDo List
-                     31 December 2004
+                     23 January 2005
 
 Major development:      
 Project                     Developer
@@ -12,8 +12,10 @@ Version 1.37                Kern (see below)
 
 1.37 Major Projects:
 #3   Migration (Move, Copy, Archive Jobs)
-#4   Embedded Python Scripting (implemented in Dir)
-#5   Events that call a Python program (Implemented in Dir)
+#4   Embedded Python Scripting 
+     (Implemented in Dir/SD)
+#5   Events that call a Python program 
+     (Implemented in Dir/SD)
 #6   Select one from among Multiple Storage Devices for Job
 #7   Single Job Writing to Multiple Storage Devices
 
@@ -33,7 +35,6 @@ For 1.37:
 - Look at Preben's acl.c error handling code.
 - See multiple-store.txt for Multiple Storage implementation
   design.
-- Add Set Error from Python.
 - Create a new GUI chapter explaining all the GUI programs.
 - Tell the "restore" user when browsing is no longer possible.
 - Add disk seeking on restore.  
@@ -42,9 +43,10 @@ For 1.37:
   get the bootstrap file.
 - Add dump of VolSessionId/Time and FileIndex with bls.
 - Make bootstrap file handle multiple MediaTypes (SD)
-- Add offline command to Bacula console.
+- Add offline tape command to Bacula console.
 - Add performance testing hooks
-- Add Python writable variable for changing the Priority.
+- Add Python writable variable for changing the Priority,
+    Client, Storage, JobStatus (error), ...
 - Document that Bootstrap files can be written with cataloging
   turned off.
 - Look at adding full Volume and Pool information to a Volume 
index bd433b162555d73399da9356321a326b3f64e527..0346dafcc27958871554f9392b40353244f40200 100755 (executable)
@@ -20,7 +20,7 @@ case "$1" in
        ;;
     stop)
        echo "Stopping the Director daemon: "
-#      killproc @sbindir@/bacula-dir
+       pkill -x bacula-dir
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bacula-dir
index 14160a7643b9a4476a0b307d97608c0e972ea143..31dbbad476268a72f3a161b39711fa262c539f5c 100755 (executable)
@@ -19,7 +19,7 @@ case "$1" in
        ;;
     stop)
        echo "Stopping the Bacula File daemon: "
-#      killproc @sbindir@/bacula-fd
+       pkill -x bacula-fd
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bacula-fd
index fb55fb47cfd009917e53095da9bd389b640f8a95..37230ff971cba7c0f0629288ff4119ead1f99d27 100755 (executable)
@@ -19,7 +19,7 @@ case "$1" in
        ;;
     stop)
        echo "Stopping the Bacula Storage daemon: "
-#      killproc @sbindir@/bacula-sd
+       pkill -x bacula-sd
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bacula-sd
index 47712645114371fb29e653b589f0a4b5177b2e53..8db3edca0c67ffbf76d0801ae8b05be2dbeeb690 100644 (file)
@@ -5,7 +5,7 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
 #define MD5_SIG  1
 #define SHA1_SIG 2
 
+/*
+ * Tape label types -- stored in catalog
+ */
+#define B_BACULA_LABEL 0
+#define B_ANSI_LABEL   1
+#define B_IBM_LABEL    2
+
 /* Size of File Address stored in STREAM_SPARSE_DATA. Do NOT change! */
 #define SPARSE_FADDR_SIZE (sizeof(uint64_t))
 
@@ -260,13 +267,13 @@ extern void _v(char *file, int line, pthread_mutex_t *m);
 #define P(x) \
    do { int errstat; if ((errstat=pthread_mutex_lock(&(x)))) \
       e_msg(__FILE__, __LINE__, M_ABORT, 0, "Mutex lock failure. ERR=%s\n",\
-          strerror(errstat)); \
+           strerror(errstat)); \
    } while(0)
 
 #define V(x) \
    do { int errstat; if ((errstat=pthread_mutex_unlock(&(x)))) \
-        e_msg(__FILE__, __LINE__, M_ABORT, 0, "Mutex unlock failure. ERR=%s\n",\
-          strerror(errstat)); \
+         e_msg(__FILE__, __LINE__, M_ABORT, 0, "Mutex unlock failure. ERR=%s\n",\
+           strerror(errstat)); \
    } while(0)
 
 #endif /* DEBUG_MUTEX */
@@ -275,13 +282,13 @@ extern void _v(char *file, int line, pthread_mutex_t *m);
 #define Pw(x) \
    do { int errstat; if ((errstat=rwl_writelock(&(x)))) \
       e_msg(__FILE__, __LINE__, M_ABORT, 0, "Write lock lock failure. ERR=%s\n",\
-          strerror(errstat)); \
+           strerror(errstat)); \
    } while(0)
 
 #define Vw(x) \
    do { int errstat; if ((errstat=rwl_writeunlock(&(x)))) \
-        e_msg(__FILE__, __LINE__, M_ABORT, 0, "Write lock unlock failure. ERR=%s\n",\
-          strerror(errstat)); \
+         e_msg(__FILE__, __LINE__, M_ABORT, 0, "Write lock unlock failure. ERR=%s\n",\
+           strerror(errstat)); \
    } while(0)
 
 #define LockRes()   b_LockRes(__FILE__, __LINE__)
index 165404124020107b62811fc061211e879ce04115..c9d9d9bbc76bb0f087f9653c1c94cf325d465640 100644 (file)
@@ -46,7 +46,7 @@
 #ifdef HAVE_BACULA_DB
 
 /* Forward referenced functions */
-int db_create_pool_record(B_DB *mdb, POOL_DBR *pr);
+bool db_create_pool_record(B_DB *mdb, POOL_DBR *pr);
 
 /* -----------------------------------------------------------------------
  *
@@ -137,7 +137,7 @@ bool db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
  * Returns: 0 on failure
  *         1 on success
  */
-int db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
+bool db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
 {
    int len;
    POOL_DBR mpr;
@@ -171,6 +171,15 @@ int db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
    return 1;
 }
 
+bool db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
+{ return false; }
+
+bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *dr)
+{ return false; }
+
+bool db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *dr)
+{ return false; }
+
 
 /*
  * Create Unique Media record. This record
@@ -259,7 +268,7 @@ int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
  * Returns: 0 on failure
  *         1 on success
  */
-int db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
+bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
 {
    int len;
    FILESET_DBR lfsr;
index 28c6a41de1ab1eba941f56c1a09dacc46aae8ef9..c2d2637b38e62dd39b3d208bdbba535028f2b5b0 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -48,16 +48,6 @@ typedef int (DB_RESULT_HANDLER)(void *, int, char **);
 
 #ifdef HAVE_SQLITE
 
-#ifdef HAVE_SQLITE3
-#define sqlite_last_insert_rowid sqlite3_last_insert_rowid
-#define sqlite_open sqlite3_open
-#define sqlite_close sqlite3_close
-#define sqlite_result sqlite3_result
-#define sqlite_exec sqlite3_exec
-#define sqlite_get_table sqlite3_get_table
-#define sqlite_free_table sqlite3_free_table
-#endif  
-
 #define BDB_VERSION 8
 
 #include <sqlite.h>
@@ -150,6 +140,125 @@ typedef struct s_db {
 
 
 
+/* In cats/sqlite.c */
+void       my_sqlite_free_table(B_DB *mdb);
+SQL_ROW    my_sqlite_fetch_row(B_DB *mdb);
+int        my_sqlite_query(B_DB *mdb, char *cmd);
+void       my_sqlite_field_seek(B_DB *mdb, int field);
+SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb);
+
+
+#else
+
+/*                    S Q L I T E 3            */
+
+#ifdef HAVE_SQLITE3
+
+
+#define BDB_VERSION 8
+
+#include <sqlite3.h>
+
+/* Define opaque structure for sqlite */
+struct sqlite3 {
+   char dummy;
+};
+
+#define IS_NUM(x)             ((x) == 1)
+#define IS_NOT_NULL(x)        ((x) == 1)
+
+typedef struct s_sql_field {
+   char *name;                        /* name of column */
+   int length;                        /* length */
+   int max_length;                    /* max length */
+   uint32_t type;                     /* type */
+   uint32_t flags;                    /* flags */
+} SQL_FIELD;
+
+/*
+ * This is the "real" definition that should only be
+ * used inside sql.c and associated database interface
+ * subroutines.
+ *                    S Q L I T E
+ */
+typedef struct s_db {
+   BQUEUE bq;                         /* queue control */
+   brwlock_t lock;                    /* transaction lock */
+   struct sqlite3 *db;
+   char **result;
+   int status;
+   int nrow;                          /* nrow returned from sqlite */
+   int ncolumn;                       /* ncolum returned from sqlite */
+   int num_rows;                      /* used by code */
+   int row;                           /* seek row */
+   int field;                         /* seek field */
+   SQL_FIELD **fields;                /* defined fields */
+   int ref_count;
+   char *db_name;
+   char *db_user;
+   char *db_address;                  /* host name address */
+   char *db_socket;                   /* socket for local access */
+   char *db_password;
+   int  db_port;                      /* port for host name address */
+   bool connected;                    /* connection made to db */
+   bool have_insert_id;               /* do not have insert id */
+   bool fields_defined;               /* set when fields defined */
+   char *sqlite_errmsg;               /* error message returned by sqlite */
+   POOLMEM *errmsg;                   /* nicely edited error message */
+   POOLMEM *cmd;                      /* SQL command string */
+   POOLMEM *cached_path;              /* cached path name */
+   int cached_path_len;               /* length of cached path */
+   uint32_t cached_path_id;           /* cached path id */
+   bool allow_transactions;           /* transactions allowed */
+   bool transaction;                  /* transaction started */
+   int changes;                       /* changes during transaction */
+   POOLMEM *fname;                    /* Filename only */
+   POOLMEM *path;                     /* Path only */
+   POOLMEM *esc_name;                 /* Escaped file/path name */
+   int fnl;                           /* file name length */
+   int pnl;                           /* path name length */
+} B_DB;
+
+/*
+ * Conversion of sqlite 2 names to sqlite3
+ */
+#define sqlite_last_insert_rowid sqlite3_last_insert_rowid
+#define sqlite_open sqlite3_open
+#define sqlite_close sqlite3_close
+#define sqlite_result sqlite3_result
+#define sqlite_exec sqlite3_exec
+#define sqlite_get_table sqlite3_get_table
+#define sqlite_free_table sqlite3_free_table
+
+
+/*
+ * "Generic" names for easier conversion
+ *
+ *                    S Q L I T E 3
+ */
+#define sql_store_result(x)   (x)->result
+#define sql_free_result(x)    my_sqlite_free_table(x)
+#define sql_fetch_row(x)      my_sqlite_fetch_row(x)
+#define sql_query(x, y)       my_sqlite_query((x), (y))
+#ifdef HAVE_SQLITE3
+#define sql_insert_id(x,y)    sqlite3_last_insert_rowid((x)->db)
+#define sql_close(x)          sqlite3_close((x)->db)
+#else
+#define sql_insert_id(x,y)    sqlite_last_insert_rowid((x)->db)
+#define sql_close(x)          sqlite_close((x)->db)
+#endif
+#define sql_strerror(x)       (x)->sqlite_errmsg?(x)->sqlite_errmsg:"unknown"
+#define sql_num_rows(x)       (x)->nrow
+#define sql_data_seek(x, i)   (x)->row = (i)
+#define sql_affected_rows(x)  1
+#define sql_field_seek(x, y)  my_sqlite_field_seek((x), (y))
+#define sql_fetch_field(x)    my_sqlite_fetch_field(x)
+#define sql_num_fields(x)     ((x)->ncolumn)
+#define SQL_ROW               char**
+
+
+
 /* In cats/sqlite.c */
 void       my_sqlite_free_table(B_DB *mdb);
 SQL_ROW    my_sqlite_fetch_row(B_DB *mdb);
@@ -357,6 +466,7 @@ typedef struct s_db {
    uint32_t cached_path_id;
 } B_DB;
 
+#endif /* HAVE_SQLITE3 */
 #endif /* HAVE_MYSQL */
 #endif /* HAVE_SQLITE */
 #endif /* HAVE_POSTGRESQL */
@@ -454,6 +564,7 @@ struct JOBMEDIA_DBR {
 /* Volume Parameter structure */
 struct VOL_PARAMS {
    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
+   char MediaType[MAX_NAME_LENGTH];   /* Media Type */
    uint32_t VolIndex;                 /* Volume seqence no. */
    uint32_t FirstIndex;               /* First index this Volume */
    uint32_t LastIndex;                /* Last index this Volume */
@@ -491,7 +602,6 @@ struct FILE_DBR {
    DBId_t PathId;
    JobId_t  MarkId;
    char LStat[256];
-/*   int Status; */
    char SIG[50];
    int SigType;                       /* NO_SIG/MD5_SIG/SHA1_SIG */
 };
@@ -502,6 +612,7 @@ struct POOL_DBR {
    char Name[MAX_NAME_LENGTH];        /* Pool name */
    uint32_t NumVols;                  /* total number of volumes */
    uint32_t MaxVols;                  /* max allowed volumes */
+   int32_t LabelType;                 /* Bacula/ANSI/IBM */
    int32_t UseOnce;                   /* set to use once only */
    int32_t UseCatalog;                /* set to use catalog */
    int32_t AcceptAnyVolume;           /* set to accept any volume sequence */
@@ -518,6 +629,40 @@ struct POOL_DBR {
    faddr_t rec_addr;
 };
 
+class DEVICE_DBR {
+public:
+   DBId_t DeviceId;
+   char Name[MAX_NAME_LENGTH];        /* Device name */
+   DBId_t MediaTypeId;                /* MediaType */
+   DBId_t StorageId;                  /* Storage id if autochanger */
+   uint32_t DevMounts;                /* Number of times mounted */
+   uint32_t DevErrors;                /* Number of read/write errors */
+   uint64_t DevReadBytes;             /* Number of bytes read */
+   uint64_t DevWriteBytes;            /* Number of bytew written */
+   uint64_t DevReadTime;              /* time spent reading volume */
+   uint64_t DevWriteTime;             /* time spent writing volume */
+   uint64_t DevReadTimeSincCleaning;  /* read time since cleaning */
+   uint64_t DevWriteTimeSincCleaning; /* write time since cleaning */
+   time_t   CleaningDate;             /* time last cleaned */
+   utime_t  CleaningPeriod;           /* time between cleanings */
+};
+
+class STORAGE_DBR {
+public:
+   DBId_t StorageId;
+   char Name[MAX_NAME_LENGTH];        /* Device name */
+   DBId_t MediaTypeId;                /* MediaType */
+   int AutoChanger;                   /* Set if autochanger */
+};
+
+class MEDIATYPE_DBR {
+public:
+   DBId_t MediaTypeId;
+   char MediaType[MAX_NAME_LENGTH];   /* MediaType string */
+   int ReadOnly;                      /* Set if read-only */
+};
+
+
 /* Media record -- same as the database */
 struct MEDIA_DBR {
    DBId_t MediaId;                    /* Unique volume id */
@@ -527,6 +672,7 @@ struct MEDIA_DBR {
    time_t   FirstWritten;             /* Time Volume first written */
    time_t   LastWritten;              /* Time Volume last written */
    time_t   LabelDate;                /* Date/Time Volume labeled */
+   int32_t  LabelType;                /* Label (Bacula/ANSI/IBM) */
    uint32_t VolJobs;                  /* number of jobs on this medium */
    uint32_t VolFiles;                 /* Number of files */
    uint32_t VolBlocks;                /* Number of blocks */
index 57123c07d6a667cdd3238eba383d7ada88907741..6a3775f823d4219cd65a4a142c4fdd98d7287b13 100644 (file)
@@ -3,9 +3,9 @@
 # This routine creates the Bacula database
 #  using PostgreSQL, MySQL, or SQLite.
 #
-if test xsqlite = x@DB_NAME@ ; then
+if test xsqlite = x@DB_NAME@ -o xsqlite3 = x@DB_NAME@ ; then
   echo "Creating SQLite database"
-  @scriptdir@/create_sqlite_database $*
+  @scriptdir@/create_@DB_NAME@_database $*
 else
   if test xmysql = x@DB_NAME@ ; then
     echo "Creating MySQL database"
index 4cbd7338a68fa7902d1ccd961c40ad51c4f2106c..3d7ba64644ef2f4be479442b1f7d6cbee13856e2 100644 (file)
@@ -4,7 +4,8 @@
 
 bindir=@SQL_BINDIR@
 cd @working_dir@
+sqlite=@DB_NAME@
 
-$bindir/sqlite $* bacula.db <<END-OF-DATA
+${bindir}/${sqlite} $* bacula.db <<END-OF-DATA
 END-OF-DATA
 exit 0
index cdc02fa4dbddd51994c7576162c27f4be6ae73ce..d77908c162272ff0e2687ae1a9d1464d584d1b0e 100755 (executable)
@@ -3,8 +3,8 @@
 #  Drop Bacula database -- works for whatever is configured,
 #    MySQL, SQLite, PostgreSQL
 #
-if test xsqlite = x@DB_NAME@ ; then
-  @scriptdir@/drop_sqlite_database $*
+if test xsqlite = x@DB_NAME@ -o xsqlite3 = x@DB_NAME@ ; then
+  @scriptdir@/drop_@DB_NAME@_database $*
 else
   if test xmysql = x@DB_NAME@ ; then 
     echo "Making MySQL database"
index 96c0fb7d98819466edf5e17a10b6f719166d0a55..3707765cc92d8ee38f8cefd3b0582c2e0bb74f81 100755 (executable)
@@ -3,8 +3,8 @@
 #  Drop Bacula tables -- works for whatever is configured,
 #    MySQL, SQLite, or PostgreSQL
 #
-if test xsqlite = x@DB_NAME@ ; then
-  @scriptdir@/drop_sqlite_tables $*
+if test xsqlite = x@DB_NAME@ -o xsqlite3 = x@DB_NAME@ ; then
+  @scriptdir@/drop_@DB_NAME@_tables $*
   echo "Dropped SQLite tables"
 else
   if test xmysql = x@DB_NAME@ ; then 
index 09913a6a400aaacf3fd9fb63e9a0abee6f11733f..4af81af0ba92f24865a8462f79124f83c7f0f4f3 100644 (file)
@@ -2,7 +2,7 @@
 #
 # shell script to drop Bacula SQLite tables
 
-if test xsqlite = x@DB_NAME@ ; then 
+if test xsqlite = x@DB_NAME@ -o xsqlite3 = x@DB_NAME@ ; then 
   cd @working_dir@
   rm -rf bacula.db
   echo "SQLite database dropped."
index 73b5c18af639e63cf143a92ed0b80684a70766eb..b064553c14d0ed325c9162ae4166aacaa30aa8c0 100755 (executable)
@@ -12,9 +12,9 @@ else
     echo "Granting PostgreSQL privileges"
     @scriptdir@/grant_postgresql_privileges $*
   else
-    if test xsqlite = x@DB_NAME@ ; then 
+    if test xsqlite = x@DB_NAME@ -o xsqlite3 = x@DB_NAME@ ; then 
       echo "Granting SQLite privileges"
-      @scriptdir@/grant_sqlite_privileges $*
+      @scriptdir@/grant_@DB_NAME@_privileges $*
     fi
   fi
 fi
index 6360980abbd6baf2570caae96228c828370d0411..a71462d2308e5b6163160b2632d12835a2b1911f 100755 (executable)
@@ -3,9 +3,9 @@
 # This routine makes the appropriately configured
 #  Bacula tables for PostgreSQL, MySQL, or SQLite.
 #
-if test xsqlite = x@DB_NAME@ ; then
+if test xsqlite = x@DB_NAME@ -o xsqlite3 = x@DB_NAME@ ; then
   echo "Making SQLite tables"
-  @scriptdir@/make_sqlite_tables $*
+  @scriptdir@/make_@DB_NAME@_tables $*
 else
   if test xmysql = x@DB_NAME@ ; then 
     echo "Making MySQL tables"
index 8dc27817808c4f28deccde6676571510bac1fd02..b9f96246546d9114eeaec51ce11f7964688b9a37 100644 (file)
@@ -103,6 +103,7 @@ CREATE TABLE Media (
    Slot INTEGER NOT NULL DEFAULT 0,
    PoolId INTEGER UNSIGNED NOT NULL REFERENCES Pool,
    MediaType TINYBLOB NOT NULL,
+   LabelType TINYINT NOT NULL DEFAULT 0,
    FirstWritten DATETIME NOT NULL,
    LastWritten DATETIME NOT NULL,
    LabelDate DATETIME NOT NULL,
@@ -133,6 +134,41 @@ CREATE TABLE Media (
    INDEX (PoolId)
    );
 
+CREATE INDEX inx8 ON Media (PoolId);
+
+CREATE TABLE MediaType (
+   MediaTypeId INTERGER UNSIGNED NOT NULL AUTO_INCREMENT,
+   MediaType VARCHAR(128) NOT NULL,
+   ReadOnly TINYINT DEFAULT 0,
+   PRIMARY KEY(MediaTypeId)
+   );
+
+CREATE TABLE Device (
+   DeviceId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+   Name VARCHAR(128) NOT NULL,
+   MediaTypeId INTEGER UNSIGNED REFERENCES MediaType NOT NULL,
+   StorageId INTEGER UNSIGNED REFERENCES Storage,
+   DevMounts INTEGER UNSIGNED DEFAULT 0,
+   DevReadBytes BIGINT UNSIGNED DEFAULT 0,
+   DevWriteBytes BIGINT UNSIGNED DEFAULT 0,
+   DevReadBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+   DevWriteBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+   DevReadTime BIGINT UNSIGNED DEFAULT 0,
+   DevWriteTime BIGINT UNSIGNED DEFAULT 0,
+   DevReadTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+   DevWriteTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+   CleaningDate DATETIME DEFAULT 0,
+   CleaningPeriod BIGINT UNSIGNED DEFAULT 0,
+   PRIMARY KEY(DeviceId)
+   );
+
+CREATE TABLE Storage (
+   StorageId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+   Name VARCHAR(128) NOT NULL,
+   AutoChanger TINYINT DEFAULT 0,
+   PRIMARY KEY(StorageId)
+   );
+
 CREATE TABLE Pool (
    PoolId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    Name TINYBLOB NOT NULL,
index 25941db8670004cfe604bb03a1ed7b39e14cc03f..d6fde78152922aa059539ae51d22ded1d06aabdc 100644 (file)
@@ -6,248 +6,239 @@ bindir=@SQL_BINDIR@
 
 if $bindir/psql $* bacula -f - <<END-OF-DATA
 
-create table version
+CREATE TABLE filename
 (
-    versionid        integer               not null
+    filenameid       serial      not null,
+    name             text        not null,
+    primary key (filenameid)
 );
 
-INSERT INTO Version (VersionId) VALUES (8);
+CREATE INDEX filename_name_idx on filename (name);
 
-create table counters
+CREATE TABLE path
 (
-    counter          text                  not null,
-    minvalue         integer                       ,
-    maxvalue         integer                       ,
-    currentvalue      integer                      ,
-    wrapcounter       text                 not null,
-    primary key (counter)
+    pathid           serial      not null,
+    path             text        not null,
+    primary key (pathid)
 );
 
-create table filename
+CREATE INDEX path_name_idx on path (path);
+
+CREATE TABLE file
 (
-    filenameid       serial                not null,
-    name             text                  not null,
-    primary key (filenameid)
+    fileid           serial      not null,
+    fileindex        integer     not null  default 0,
+    jobid            integer     not null,
+    pathid           integer     not null,
+    filenameid       integer     not null,
+    markid           integer     not null  default 0,
+    lstat            text        not null,
+    md5              text        not null,
+    primary key (fileid)
 );
 
-create index filename_name_idx on filename (name);
+CREATE INDEX file_jobid_idx on file (jobid);
+CREATE INDEX file_fp_idx on file (filenameid, pathid);
 
-create table path
+--
+-- Possibly add one or more of the following indexes
+--  if your Verifies are too slow.
+--
+-- CREATE INDEX file_pathid_idx on file(pathid);
+-- CREATE INDEX file_filenameid_idx on file(filenameid);
+-- CREATE INDEX file_jpfid_idx on file (jobid, pathid, filenameid);
+
+CREATE TABLE job
 (
-    pathid           serial                not null,
-    path             text                  not null,
-    primary key (pathid)
+    jobid            serial      not null,
+    job              text        not null,
+    name             text        not null,
+    type             char(1)     not null,
+    level            char(1)     not null,
+    clientid         integer,
+    jobstatus        char(1)     not null,
+    schedtime        timestamp   without time zone not null,
+    starttime        timestamp   without time zone,
+    endtime          timestamp   without time zone,
+    jobtdate         bigint      not null,
+    volsessionid      integer    not null default 0,
+    volsessiontime    integer    not null default 0,
+    jobfiles         integer     not null default 0,
+    jobbytes         bigint      not null default 0,
+    joberrors        integer     not null default 0,
+    jobmissingfiles   integer    not null default 0,
+    poolid           integer,
+    filesetid        integer,
+    purgedfiles       smallint   not null default 0,
+    hasbase          smallint    not null default 0,
+    primary key (jobid)
 );
 
-create index path_name_idx on path (path);
+CREATE INDEX job_name_idx on job (name);
 
-create table fileset
+CREATE TABLE fileset
 (
-    filesetid        serial                not null,
-    fileset          text                  not null,
-    md5              text                  not null,
+    filesetid        serial      not null,
+    fileset          text        not null,
+    md5              text        not null,
     createtime       timestamp without time zone not null,
     primary key (filesetid)
 );
 
-create index fileset_name_idx on fileset (fileset);
+CREATE INDEX fileset_name_idx on fileset (fileset);
 
-create table pool
+CREATE TABLE jobmedia
 (
-    poolid           serial                not null,
-    name             text                  not null,
-    numvols          integer               not null
-       default 0,
-    maxvols          integer               not null
-       default 0,
-    useonce          smallint              not null,
-    usecatalog       smallint              not null,
-    acceptanyvolume   smallint                     
-       default 0,
-    volretention      bigint               not null,
-    voluseduration    bigint               not null,
-    maxvoljobs       integer               not null
-       default 0,
-    maxvolfiles       integer              not null
-       default 0,
-    maxvolbytes       bigint               not null,
-    autoprune        smallint              not null
-       default 0,
-    recycle          smallint                      
-       default 0,
-    pooltype         text                          
-       check (pooltype is null or (pooltype in ('Backup','Copy','Cloned','Archive','Migration'))),
-    labelformat       text                 not null,
-    enabled          smallint              not null
-       default 1,
-    scratchpoolid     integer                      ,
-    recyclepoolid     integer                      ,
-    primary key (poolid)
-);
-
-create index pool_name_idx on pool (name);
-
-create table client
-(
-    clientid         serial                not null,
-    name             text                  not null,
-    uname            text                  not null,
-    autoprune        smallint                      
-       default 0,
-    fileretention     bigint               not null,
-    jobretention      bigint               not null,
-    primary key (clientid)
+    jobmediaid       serial      not null,
+    jobid            integer     not null,
+    mediaid          integer     not null,
+    firstindex       integer     not null default 0,
+    lastindex        integer     not null default 0,
+    startfile        integer     not null default 0,
+    endfile          integer     not null default 0,
+    startblock       bigint      not null default 0,
+    endblock         bigint      not null default 0,
+    volindex         integer     not null default 0,
+    primary key (jobmediaid)
 );
 
-create unique index client_name_idx on client (name);
+CREATE INDEX job_media_job_id_media_id_idx on jobmedia (jobid, mediaid);
 
-create table media
+CREATE TABLE media
 (
-    mediaid          serial                not null,
-    volumename       text                  not null,
-    slot             integer               not null
-       default 0,
-    poolid           integer               not null,
-    mediatype        text                  not null,
-    firstwritten      timestamp without time zone,
-    lastwritten       timestamp without time zone,
-    labeldate        timestamp without time zone,
-    voljobs          integer               not null
-       default 0,
-    volfiles         integer               not null
-       default 0,
-    volblocks        integer               not null
-       default 0,
-    volmounts        integer               not null
-       default 0,
-    volbytes         bigint                not null
-       default 0,
-    volparts         integer               not null
-       default 0,
-    volerrors        integer               not null
-       default 0,
-    volwrites        integer               not null
-       default 0,
-    volcapacitybytes  bigint               not null,
-    volstatus        text                  not null
-       check (volstatus in ('Full','Archive','Append','Recycle','Purged','Read-Only','Disabled','Error','Busy',
-           'Used','Cleaning')),
-    recycle          smallint              not null
-       default 0,
-    volretention      bigint               not null
-       default 0,
-    voluseduration    bigint               not null
-       default 0,
-    maxvoljobs       integer               not null
-       default 0,
-    maxvolfiles       integer              not null
-       default 0,
-    maxvolbytes       bigint               not null
-       default 0,
-    inchanger        smallint              not null
-       default 0,
-    mediaaddressing   smallint             not null
-       default 0,
-    volreadtime       bigint               not null
-       default 0,
-    volwritetime      bigint               not null
-       default 0,
-    endfile          integer               not null
-       default 0,
-    endblock         bigint                not null
-       default 0,
+    mediaid          serial      not null,
+    volumename       text        not null,
+    slot             integer     not null default 0,
+    poolid           integer     not null,
+    mediatype        text        not null,
+    labeltype        integer     not null default 0,
+    firstwritten      timestamp   without time zone,
+    lastwritten       timestamp   without time zone,
+    labeldate        timestamp   without time zone,
+    voljobs          integer     not null default 0,
+    volfiles         integer     not null default 0,
+    volblocks        integer     not null default 0,
+    volmounts        integer     not null default 0,
+    volbytes         bigint      not null default 0,
+    volparts         integer     not null default 0,
+    volerrors        integer     not null default 0,
+    volwrites        integer     not null default 0,
+    volcapacitybytes  bigint     not null default 0,
+    volstatus        text        not null
+       check (volstatus in ('Full','Archive','Append',
+             'Recycle','Purged','Read-Only','Disabled',
+             'Error','Busy','Used','Cleaning')),
+    recycle          smallint    not null default 0,
+    volretention      bigint     not null default 0,
+    voluseduration    bigint     not null default 0,
+    maxvoljobs       integer     not null default 0,
+    maxvolfiles       integer    not null default 0,
+    maxvolbytes       bigint     not null default 0,
+    inchanger        smallint    not null default 0,
+    mediaaddressing   smallint   not null default 0,
+    volreadtime       bigint     not null default 0,
+    volwritetime      bigint     not null default 0,
+    endfile          integer     not null default 0,
+    endblock         bigint      not null default 0,
     primary key (mediaid)
 );
 
 create unique index media_volumename_id on media (volumename);
 
-create table job
+CREATE TABLE MediaType (
+   MediaTypeId SERIAL,
+   MediaType TEXT NOT NULL,
+   ReadOnly INTEGER DEFAULT 0,
+   PRIMARY KEY(MediaTypeId)
+   );
+
+CREATE TABLE Device (
+   DeviceId SERIAL,
+   Name TEXT NOT NULL,
+   MediaTypeId INTEGER NOT NULL,
+   StorageId INTEGER UNSIGNED,
+   DevMounts INTEGER NOT NULL DEFAULT 0,
+   DevReadBytes BIGINT NOT NULL DEFAULT 0,
+   DevWriteBytes BIGINT NOT NULL DEFAULT 0,
+   DevReadBytesSinceCleaning BIGINT NOT NULL DEFAULT 0,
+   DevWriteBytesSinceCleaning BIGINT NOT NULL DEFAULT 0,
+   DevReadTime BIGINT NOT NULL DEFAULT 0,
+   DevWriteTime BIGINT NOT NULL DEFAULT 0,
+   DevReadTimeSinceCleaning BIGINT NOT NULL DEFAULT 0,
+   DevWriteTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+   CleaningDate TIMESTAMP WITHOUT TIME ZONE,
+   CleaningPeriod BIGINT NOT NULL DEFAULT 0,
+   PRIMARY KEY(DeviceId)
+   );
+
+CREATE TABLE Storage (
+   StorageId SERIAL,
+   Name TEXT NOT NULL,
+   AutoChanger INTEGER DEFAULT 0,
+   PRIMARY KEY(StorageId)
+   );
+
+CREATE TABLE pool
 (
-    jobid            serial                not null,
-    job              text                  not null,
-    name             text                  not null,
-    type             char(1)               not null,
-    level            char(1)               not null,
-    clientid         integer                       ,
-    jobstatus        char(1)               not null,
-    schedtime        timestamp without time zone not null,
-    starttime        timestamp without time zone         ,
-    endtime          timestamp without time zone         ,
-    jobtdate         bigint                not null,
-    volsessionid      integer              not null
-       default 0,
-    volsessiontime    integer              not null
-       default 0,
-    jobfiles         integer               not null
-       default 0,
-    jobbytes         bigint                not null
-       default 0,
-    joberrors        integer               not null
-       default 0,
-    jobmissingfiles   integer              not null
-       default 0,
-    poolid           integer                       ,
-    filesetid        integer                       ,
-    purgedfiles       smallint             not null
-       default 0,
-    hasbase          smallint              not null
-       default 0,
-    primary key (jobid)
+    poolid           serial      not null,
+    name             text        not null,
+    numvols          integer     not null default 0,
+    maxvols          integer     not null default 0,
+    useonce          smallint    not null default 0,
+    usecatalog       smallint    not null default 0,
+    acceptanyvolume   smallint   not null default 0,
+    volretention      bigint     not null default 0,
+    voluseduration    bigint     not null default 0,
+    maxvoljobs       integer     not null default 0,
+    maxvolfiles       integer    not null default 0,
+    maxvolbytes       bigint     not null default 0,
+    autoprune        smallint    not null default 0,
+    recycle          smallint    not null default 0,
+    pooltype         text                          
+       check (pooltype is null or (pooltype in ('Backup','Copy','Cloned','Archive','Migration'))),
+    labelformat       text                 not null,
+    enabled          smallint              not null default 1,
+    scratchpoolid     integer,                      
+    recyclepoolid     integer,
+    primary key (poolid)
 );
 
-create index job_name_idx on job (name);
+CREATE INDEX pool_name_idx on pool (name);
 
-create table file
+CREATE TABLE client
 (
-    fileid           serial                not null,
-    fileindex        integer               not null
-       default 0,
-    jobid            integer               not null,
-    pathid           integer               not null,
-    filenameid       integer               not null,
-    markid           integer               not null
-       default 0,
-    lstat            text                  not null,
-    md5              text                  not null,
-    primary key (fileid)
+    clientid         serial      not null,
+    name             text        not null,
+    uname            text        not null,
+    autoprune        smallint    default 0,
+    fileretention     bigint     not null,
+    jobretention      bigint     not null,
+    primary key (clientid)
 );
 
-create index file_jobid_idx on file (jobid);
-create index file_fp_idx on file (filenameid, pathid);
+create unique index client_name_idx on client (name);
+
 
---
--- Possibly add one or more of the following indexes
---  if your Verifies are too slow.
---
--- create index file_pathid_idx on file(pathid);
--- create index file_filenameid_idx on file(filenameid);
--- create index file_jpfid_idx on file (jobid, pathid, filenameid);
+CREATE TABLE counters
+(
+    counter          text        not null,
+    minvalue         integer,
+    maxvalue         integer,
+    currentvalue      integer,
+    wrapcounter       text       not null,
+    primary key (counter)
+);
 
-create table jobmedia
+CREATE TABLE version
 (
-    jobmediaid       serial                not null,
-    jobid            integer               not null,
-    mediaid          integer               not null,
-    firstindex       integer               not null
-       default 0,
-    lastindex        integer               not null
-       default 0,
-    startfile        integer               not null
-       default 0,
-    endfile          integer               not null
-       default 0,
-    startblock       bigint                not null
-       default 0,
-    endblock         bigint                not null
-       default 0,
-    volindex         integer               not null
-       default 0,
-    primary key (jobmediaid)
+    versionid        integer               not null
 );
 
-create index job_media_job_id_media_id_idx on jobmedia (jobid, mediaid);
+INSERT INTO Version (VersionId) VALUES (8);
+
 
-create table basefiles
+CREATE TABLE basefiles
 (
     baseid           serial                not null,
     jobid            integer               not null,
@@ -257,7 +248,7 @@ create table basefiles
     primary key (baseid)
 );
 
-create table unsavedfiles
+CREATE TABLE unsavedfiles
 (
     UnsavedId        integer               not null,
     jobid            integer               not null,
@@ -266,7 +257,7 @@ create table unsavedfiles
     primary key (UnsavedId)
 );
 
-create table CDImages 
+CREATE TABLE CDImages 
 (
    MediaId integer not null,
    LastBurn timestamp without time zone not null,
index 9288ca75757112cd3d81af0e1f8733af2ba32c31..7c46bb387fd8842d081895ed6359296c54c10f73 100644 (file)
@@ -4,10 +4,11 @@
 
 bindir=@SQL_BINDIR@
 cd @working_dir@
+sqlite=@DB_NAME@
 
-$bindir/sqlite $* bacula.db <<END-OF-DATA
+${bindir}/${sqlite} $* bacula.db <<END-OF-DATA
 CREATE TABLE Filename (
-  FilenameId INTEGER UNSIGNED AUTOINCREMENT,
+  FilenameId INTEGER,
   Name TEXT DEFAULT "",
   PRIMARY KEY(FilenameId) 
   );
@@ -15,7 +16,7 @@ CREATE TABLE Filename (
 CREATE INDEX inx1 ON Filename (Name);
 
 CREATE TABLE Path (
-   PathId INTEGER UNSIGNED AUTOINCREMENT,
+   PathId INTEGER,
    Path TEXT DEFAULT "",
    PRIMARY KEY(PathId) 
    );
@@ -24,7 +25,7 @@ CREATE INDEX inx2 ON Path (Path);
 
 
 CREATE TABLE File (
-   FileId INTEGER UNSIGNED AUTOINCREMENT,
+   FileId INTEGER,
    FileIndex INTEGER UNSIGNED NOT NULL,
    JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
    PathId INTEGER UNSIGNED REFERENCES Path NOT NULL,
@@ -46,7 +47,7 @@ CREATE INDEX inx4 ON File (FilenameId, PathId);
 -- CREATE INDEX inx9 ON File (JobId, PathId, FilenameId);
 
 CREATE TABLE Job (
-   JobId INTEGER UNSIGNED NOT NULL,
+   JobId INTEGER,
    Job VARCHAR(128) NOT NULL,
    Name VARCHAR(128) NOT NULL,
    Type CHAR NOT NULL,
@@ -73,7 +74,7 @@ CREATE TABLE Job (
 CREATE INDEX inx6 ON Job (Name);
 
 CREATE TABLE FileSet (
-   FileSetId INTEGER UNSIGNED AUTOINCREMENT,
+   FileSetId INTEGER,
    FileSet VARCHAR(128) NOT NULL,
    MD5 VARCHAR(25) NOT NULL,
    CreateTime DATETIME DEFAULT 0,
@@ -81,7 +82,7 @@ CREATE TABLE FileSet (
    );
 
 CREATE TABLE JobMedia (
-   JobMediaId INTEGER UNSIGNED AUTOINCREMENT,
+   JobMediaId INTEGER,
    JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
    MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL,
    FirstIndex INTEGER UNSIGNED NOT NULL,
@@ -98,11 +99,12 @@ CREATE INDEX inx7 ON JobMedia (JobId, MediaId);
 
 
 CREATE TABLE Media (
-   MediaId INTEGER UNSIGNED AUTOINCREMENT,
+   MediaId INTEGER,
    VolumeName VARCHAR(128) NOT NULL,
    Slot INTEGER DEFAULT 0,
    PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL,
    MediaType VARCHAR(128) NOT NULL,
+   LabelType TINYINT DEFAULT 0,
    FirstWritten DATETIME DEFAULT 0,
    LastWritten DATETIME DEFAULT 0,
    LabelDate DATETIME DEFAULT 0,
@@ -123,6 +125,7 @@ CREATE TABLE Media (
    MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
    MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
    InChanger TINYINT DEFAULT 0,
+   StorageId INTEGER UNSIGNED REFERENCES Storage,        
    MediaAddressing TINYINT DEFAULT 0,
    VolReadTime BIGINT UNSIGNED DEFAULT 0,
    VolWriteTime BIGINT UNSIGNED DEFAULT 0,
@@ -133,8 +136,42 @@ CREATE TABLE Media (
 
 CREATE INDEX inx8 ON Media (PoolId);
 
+CREATE TABLE MediaType (
+   MediaTypeId INTERGER,
+   MediaType VARCHAR(128) NOT NULL,
+   ReadOnly TINYINT DEFAULT 0,
+   PRIMARY KEY(MediaTypeId)
+   );
+
+CREATE TABLE Device (
+   DeviceId INTEGER,
+   Name VARCHAR(128) NOT NULL,
+   MediaTypeId INTEGER UNSIGNED REFERENCES MediaType NOT NULL,
+   StorageId INTEGER UNSIGNED REFERENCES Storage,
+   DevMounts INTEGER UNSIGNED DEFAULT 0,
+   DevReadBytes BIGINT UNSIGNED DEFAULT 0,
+   DevWriteBytes BIGINT UNSIGNED DEFAULT 0,
+   DevReadBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+   DevWriteBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+   DevReadTime BIGINT UNSIGNED DEFAULT 0,
+   DevWriteTime BIGINT UNSIGNED DEFAULT 0,
+   DevReadTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+   DevWriteTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+   CleaningDate DATETIME DEFAULT 0,
+   CleaningPeriod BIGINT UNSIGNED DEFAULT 0,
+   PRIMARY KEY(DeviceId)
+   );
+
+CREATE TABLE Storage (
+   StorageId INTEGER,
+   Name VARCHAR(128) NOT NULL,
+   AutoChanger TINYINT DEFAULT 0,
+   PRIMARY KEY(StorageId)
+   );
+
+
 CREATE TABLE Pool (
-   PoolId INTEGER UNSIGNED AUTOINCREMENT,
+   PoolId INTEGER,
    Name VARCHAR(128) NOT NULL,
    NumVols INTEGER UNSIGNED DEFAULT 0,
    MaxVols INTEGER UNSIGNED DEFAULT 0,
@@ -159,7 +196,7 @@ CREATE TABLE Pool (
 
 
 CREATE TABLE Client (
-   ClientId INTEGER UNSIGNED AUTOINCREMENT,
+   ClientId INTEGER,
    Name VARCHAR(128) NOT NULL,
    Uname VARCHAR(255) NOT NULL,   -- uname -a field
    AutoPrune TINYINT DEFAULT 0,
@@ -170,7 +207,7 @@ CREATE TABLE Client (
    );
 
 CREATE TABLE BaseFiles (
-   BaseId INTEGER UNSIGNED AUTOINCREMENT,
+   BaseId INTEGER,
    BaseJobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
    JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
    FileId INTEGER UNSIGNED REFERENCES File NOT NULL,
@@ -179,7 +216,7 @@ CREATE TABLE BaseFiles (
    );
 
 CREATE TABLE UnsavedFiles (
-   UnsavedId INTEGER UNSIGNED AUTOINCREMENT,
+   UnsavedId INTEGER,
    JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
    PathId INTEGER UNSIGNED REFERENCES Path NOT NULL,
    FilenameId INTEGER UNSIGNED REFERENCES Filename NOT NULL,
index 4c049ce99f01cca7d2d47c279e487ba7588df911..305679d1f639bdc45b4ef8f952ffeee5c474ab3e 100644 (file)
@@ -51,10 +51,13 @@ int db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
 int db_create_job_record(JCR *jcr, B_DB *db, JOB_DBR *jr);
 int db_create_media_record(JCR *jcr, B_DB *db, MEDIA_DBR *media_dbr);
 int db_create_client_record(JCR *jcr, B_DB *db, CLIENT_DBR *cr);
-int db_create_fileset_record(JCR *jcr, B_DB *db, FILESET_DBR *fsr);
-int db_create_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pool_dbr);
+bool db_create_fileset_record(JCR *jcr, B_DB *db, FILESET_DBR *fsr);
+bool db_create_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pool_dbr);
 bool db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jr);
 int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr);
+bool db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr);
+bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr);
+bool db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr);
 
 /* delete.c */
 int db_delete_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pool_dbr);
@@ -70,16 +73,16 @@ bool db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime,
 int db_get_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pdbr);
 int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr);
 int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr);
-int db_get_job_volume_names(JCR *jcr, B_DB *mdb, uint32_t JobId, POOLMEM **VolumeNames);
+int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **VolumeNames);
 int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr);
 int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr);
 int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr);
 int db_get_num_media_records(JCR *jcr, B_DB *mdb);
 int db_get_num_pool_records(JCR *jcr, B_DB *mdb);
-int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t **ids);
-int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t **ids);
-int db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_t **ids);
-int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolParams);
+int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, DBId_t **ids);
+int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, DBId_t **ids);
+int db_get_media_ids(JCR *jcr, B_DB *mdb, DBId_t PoolId, int *num_ids, uint32_t **ids);
+int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS **VolParams);
 int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr);
 int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr);
 
@@ -94,7 +97,7 @@ void db_list_job_records(JCR *jcr, B_DB *db, JOB_DBR *jr, DB_LIST_HANDLER sendit
 void db_list_job_totals(JCR *jcr, B_DB *db, JOB_DBR *jr, DB_LIST_HANDLER sendit, void *ctx);
 void db_list_files_for_job(JCR *jcr, B_DB *db, uint32_t jobid, DB_LIST_HANDLER sendit, void *ctx);
 void db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
-void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
+void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, JobId_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
 int  db_list_sql_query(JCR *jcr, B_DB *mdb, char *query, DB_LIST_HANDLER *sendit, void *ctx, int verbose, e_list_type type);
 void db_list_client_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
 
index a4c1872a70bafd668117f099ce1102e5b351d817..e7b09f611507dd6566736b2ca6a71d518ee6e298 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -37,7 +37,7 @@
 #include "bacula.h"
 #include "cats.h"
 
-#if    HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
+#if    HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
 
 uint32_t bacula_db_version = 0;
 
@@ -96,7 +96,7 @@ QueryDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd)
       m_msg(file, line, &mdb->errmsg, _("query %s failed:\n%s\n"), cmd, sql_strerror(mdb));
       j_msg(file, line, jcr, M_FATAL, 0, "%s", mdb->errmsg);
       if (verbose) {
-        j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
+         j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
       }
       return 0;
    }
@@ -118,7 +118,7 @@ InsertDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd)
       m_msg(file, line, &mdb->errmsg,  _("insert %s failed:\n%s\n"), cmd, sql_strerror(mdb));
       j_msg(file, line, jcr, M_FATAL, 0, "%s", mdb->errmsg);
       if (verbose) {
-        j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
+         j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
       }
       return 0;
    }
@@ -132,7 +132,7 @@ InsertDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd)
       m_msg(file, line, &mdb->errmsg, _("Insertion problem: affected_rows=%s\n"),
         edit_uint64(mdb->num_rows, ed1));
       if (verbose) {
-        j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
+         j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
       }
       return 0;
    }
@@ -152,7 +152,7 @@ UpdateDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd)
       m_msg(file, line, &mdb->errmsg, _("update %s failed:\n%s\n"), cmd, sql_strerror(mdb));
       j_msg(file, line, jcr, M_ERROR, 0, "%s", mdb->errmsg);
       if (verbose) {
-        j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
+         j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
       }
       return 0;
    }
@@ -183,7 +183,7 @@ DeleteDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd)
       m_msg(file, line, &mdb->errmsg, _("delete %s failed:\n%s\n"), cmd, sql_strerror(mdb));
       j_msg(file, line, jcr, M_ERROR, 0, "%s", mdb->errmsg);
       if (verbose) {
-        j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
+         j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
       }
       return -1;
    }
@@ -206,7 +206,7 @@ int get_sql_record_max(JCR *jcr, B_DB *mdb)
 
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       if ((row = sql_fetch_row(mdb)) == NULL) {
-        Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+         Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
         stat = -1;
       } else {
         stat = atoi(row[0]);
@@ -411,7 +411,7 @@ list_dashes(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx)
    for (i = 0; i < sql_num_fields(mdb); i++) {
       field = sql_fetch_field(mdb);
       for (j = 0; j < (int)field->max_length + 2; j++) {
-        send(ctx, "-");
+         send(ctx, "-");
       }
       send(ctx, "+");
    }
@@ -455,7 +455,7 @@ list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type t
            col_len = field->max_length;
         }
         if (col_len < 4 && !IS_NOT_NULL(field->flags)) {
-           col_len = 4;                 /* 4 = length of the word "NULL" */
+            col_len = 4;                 /* 4 = length of the word "NULL" */
         }
         field->max_length = col_len;    /* reset column info */
       }
@@ -486,12 +486,12 @@ list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type t
       for (i = 0; i < sql_num_fields(mdb); i++) {
         field = sql_fetch_field(mdb);
         if (row[i] == NULL) {
-           bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, "NULL");
+            bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, "NULL");
         } else if (IS_NUM(field->type) && !jcr->gui && is_an_integer(row[i])) {
-           bsnprintf(buf, sizeof(buf), " %*s |", (int)field->max_length,
+            bsnprintf(buf, sizeof(buf), " %*s |", (int)field->max_length,
                      add_commas(row[i], ewc));
         } else {
-           bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, row[i]);
+            bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, row[i]);
         }
         send(ctx, buf);
       }
@@ -508,12 +508,12 @@ vertical_list:
       for (i = 0; i < sql_num_fields(mdb); i++) {
         field = sql_fetch_field(mdb);
         if (row[i] == NULL) {
-           bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, "NULL");
+            bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, "NULL");
         } else if (IS_NUM(field->type) && !jcr->gui && is_an_integer(row[i])) {
-           bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name,
+            bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name,
                add_commas(row[i], ewc));
         } else {
-           bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, row[i]);
+            bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, row[i]);
         }
         send(ctx, buf);
       }
@@ -523,4 +523,4 @@ vertical_list:
 }
 
 
-#endif /* HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
index 6dffada30284cf544e095c4d4d675eaa4625e73c..689d4dcc3ec444a2182df98127dd9f75c01145dd 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 /*
-   Copyright (C) 2000-2003 Kern Sibbald and John Walker
+   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
@@ -34,7 +34,7 @@
 #include "bacula.h"
 #include "cats.h"
 
-#if    HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
+#if    HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
 
 /* -----------------------------------------------------------------------
  *
@@ -122,9 +122,9 @@ db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
    count++;
 
    Mmsg(mdb->cmd,
-       "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex,"
-       "StartFile,EndFile,StartBlock,EndBlock,VolIndex) "
-       "VALUES (%u,%u,%u,%u,%u,%u,%u,%u,%u)",
+        "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex,"
+        "StartFile,EndFile,StartBlock,EndBlock,VolIndex) "
+        "VALUES (%u,%u,%u,%u,%u,%u,%u,%u,%u)",
        jm->JobId, jm->MediaId, jm->FirstIndex, jm->LastIndex,
        jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count);
 
@@ -136,10 +136,10 @@ db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
    } else {
       /* Worked, now update the Media record with the EndFile and EndBlock */
       Mmsg(mdb->cmd,
-          "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u",
+           "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u",
           jm->EndFile, jm->EndBlock, jm->MediaId);
       if (!UPDATE_DB(jcr, mdb, mdb->cmd)) {
-        Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd,
+         Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd,
              sql_strerror(mdb));
         ok = false;
       }
@@ -152,13 +152,13 @@ db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
 
 
 /* Create Unique Pool record
- * Returns: 0 on failure
- *         1 on success
+ * Returns: false on failure
+ *         true  on success
  */
-int
+bool
 db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
 {
-   int stat;
+   bool stat;       
    char ed1[30], ed2[30], ed3[50];
 
    Dmsg0(200, "In create pool\n");
@@ -169,10 +169,10 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 0) {
-        Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
+         Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
         sql_free_result(mdb);
         db_unlock(mdb);
-        return 0;
+        return false;
       }
       sql_free_result(mdb);
    }
@@ -198,17 +198,159 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
       Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"),
            mdb->cmd, sql_strerror(mdb));
       pr->PoolId = 0;
-      stat = 0;
+      stat = false;
    } else {
       pr->PoolId = sql_insert_id(mdb, _("Pool"));
-      stat = 1;
+      stat = true;
    }
    db_unlock(mdb);
+   return stat;
+}
+
+/*
+ * Create Unique Device record
+ * Returns: false on failure
+ *         true  on success
+ */
+bool
+db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
+{
+   bool stat;       
+   char ed1[30], ed2[30];
+
+   Dmsg0(200, "In create Device\n");
+   db_lock(mdb);
+   Mmsg(mdb->cmd, "SELECT DeviceId,Name FROM Device WHERE Name='%s'", dr->Name);
+   Dmsg1(200, "selectdevice: %s\n", mdb->cmd);
+
+   if (QUERY_DB(jcr, mdb, mdb->cmd)) {
+      mdb->num_rows = sql_num_rows(mdb);
+      if (mdb->num_rows > 0) {
+         Mmsg1(&mdb->errmsg, _("Device record %s already exists\n"), dr->Name);
+        sql_free_result(mdb);
+        db_unlock(mdb);
+        return false;
+      }
+      sql_free_result(mdb);
+   }
 
+   /* Must create it */
+   Mmsg(mdb->cmd,
+"INSERT INTO Device (Name,MediaTypeId,StorageId) "
+"VALUES ('%s',%s,%s)",
+                 dr->Name,
+                 edit_uint64(dr->MediaTypeId, ed1),
+                 edit_uint64(dr->StorageId, ed2));
+   Dmsg1(200, "Create Device: %s\n", mdb->cmd);
+   if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
+      Mmsg2(&mdb->errmsg, _("Create db Device record %s failed: ERR=%s\n"),
+           mdb->cmd, sql_strerror(mdb));
+      dr->DeviceId = 0;
+      stat = false;
+   } else {
+      dr->DeviceId = sql_insert_id(mdb, _("Device"));
+      stat = true;
+   }
+   db_unlock(mdb);
+   return stat;
+}
+
+/*
+ * Create Unique storage record
+ * Returns: false on failure
+ *         true  on success
+ */
+bool
+db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
+{
+   bool stat;       
+
+   Dmsg0(200, "In create storage\n");
+   db_lock(mdb);
+   Mmsg(mdb->cmd, "SELECT StorageId,Name FROM Storage WHERE Name='%s'", sr->Name);
+   Dmsg1(200, "selectstorage: %s\n", mdb->cmd);
+
+   if (QUERY_DB(jcr, mdb, mdb->cmd)) {
+      mdb->num_rows = sql_num_rows(mdb);
+      if (mdb->num_rows > 0) {
+         Mmsg1(&mdb->errmsg, _("Storage record %s already exists\n"), sr->Name);
+        sql_free_result(mdb);
+        db_unlock(mdb);
+        return false;
+      }
+      sql_free_result(mdb);
+   }
+
+   /* Must create it */
+   Mmsg(mdb->cmd,
+"INSERT INTO Storage (Name,AutoChanger) "
+"VALUES ('%s',%d)",
+                 sr->Name,
+                 sr->AutoChanger);
+   Dmsg1(200, "Create storage: %s\n", mdb->cmd);
+   if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
+      Mmsg2(&mdb->errmsg, _("Create db storage record %s failed: ERR=%s\n"),
+           mdb->cmd, sql_strerror(mdb));
+      sr->StorageId = 0;
+      stat = false;
+   } else {
+      sr->StorageId = sql_insert_id(mdb, _("Storage"));
+      stat = true;
+   }
+   db_unlock(mdb);
    return stat;
 }
 
 
+/*
+ * Create Unique MediaType record
+ * Returns: false on failure
+ *         true  on success
+ */
+bool
+db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
+{
+   bool stat;       
+
+   Dmsg0(200, "In create mediatype\n");
+   db_lock(mdb);
+   Mmsg(mdb->cmd, "SELECT MediaTypeId,MediaType FROM MediaType WHERE MediaType='%s'", mr->MediaType);
+   Dmsg1(200, "selectmediatype: %s\n", mdb->cmd);
+
+   if (QUERY_DB(jcr, mdb, mdb->cmd)) {
+      mdb->num_rows = sql_num_rows(mdb);
+      if (mdb->num_rows > 0) {
+         Mmsg1(&mdb->errmsg, _("mediatype record %s already exists\n"), mr->MediaType);
+        sql_free_result(mdb);
+        db_unlock(mdb);
+        return false;
+      }
+      sql_free_result(mdb);
+   }
+
+   /* Must create it */
+   Mmsg(mdb->cmd,
+"INSERT INTO MediaType (MediaType,ReadOnly) "
+"VALUES ('%s',%d)",
+                 mr->MediaType,
+                 mr->ReadOnly);
+   Dmsg1(200, "Create mediatype: %s\n", mdb->cmd);
+   if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
+      Mmsg2(&mdb->errmsg, _("Create db mediatype record %s failed: ERR=%s\n"),
+           mdb->cmd, sql_strerror(mdb));
+      mr->MediaTypeId = 0;
+      stat = false;
+   } else {
+      mr->MediaTypeId = sql_insert_id(mdb, _("MediaType"));
+      stat = true;
+   }
+   db_unlock(mdb);
+   return stat;
+}
+
+
+
+
 /*
  * Create Media record. VolumeName and non-zero Slot must be unique
  *
@@ -230,7 +372,7 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 0) {
-        Mmsg1(&mdb->errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName);
+         Mmsg1(&mdb->errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName);
         sql_free_result(mdb);
         db_unlock(mdb);
         return 0;
@@ -243,8 +385,8 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
 "INSERT INTO Media (VolumeName,MediaType,PoolId,MaxVolBytes,VolCapacityBytes,"
 "Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
 "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts,"
-"EndFile,EndBlock) "
-"VALUES ('%s','%s',%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0)",
+"EndFile,EndBlock,LabelType) "
+"VALUES ('%s','%s',%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d)",
                  mr->VolumeName,
                  mr->MediaType, mr->PoolId,
                  edit_uint64(mr->MaxVolBytes,ed1),
@@ -260,7 +402,8 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
                  mr->InChanger,
                  edit_uint64(mr->VolReadTime, ed6),
                  edit_uint64(mr->VolWriteTime, ed7),
-                 mr->VolParts
+                 mr->VolParts,
+                 mr->LabelType
                  );
 
 
@@ -275,9 +418,9 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
       if (mr->LabelDate) {
         char dt[MAX_TIME_LENGTH];
         localtime_r(&mr->LabelDate, &tm);
-        strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
-        Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
-             "WHERE MediaId=%d", dt, mr->MediaId);
+         strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
+         Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
+              "WHERE MediaId=%d", dt, mr->MediaId);
         stat = UPDATE_DB(jcr, mdb, mdb->cmd);
       }
    }
@@ -303,7 +446,7 @@ int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
 {
    SQL_ROW row;
    int stat;
-   char ed1[30], ed2[30];
+   char ed1[50], ed2[50];
 
    db_lock(mdb);
    Mmsg(mdb->cmd, "SELECT ClientId,Uname FROM Client WHERE Name='%s'", cr->Name);
@@ -313,18 +456,18 @@ int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
       mdb->num_rows = sql_num_rows(mdb);
       /* If more than one, report error, but return first row */
       if (mdb->num_rows > 1) {
-        Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), (int)(mdb->num_rows));
-        Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+         Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), (int)(mdb->num_rows));
+         Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
-           Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
-           Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+            Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
+            Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
            sql_free_result(mdb);
            db_unlock(mdb);
            return 0;
         }
-        cr->ClientId = atoi(row[0]);
+        cr->ClientId = str_to_int64(row[0]);
         if (row[1]) {
            bstrncpy(cr->Uname, row[1], sizeof(cr->Uname));
         } else {
@@ -338,9 +481,9 @@ int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
    }
 
    /* Must create it */
-   Mmsg(mdb->cmd, "INSERT INTO Client (Name, Uname, AutoPrune, "
-"FileRetention, JobRetention) VALUES "
-"('%s', '%s', %d, %s, %s)", cr->Name, cr->Uname, cr->AutoPrune,
+   Mmsg(mdb->cmd, "INSERT INTO Client (Name,Uname,AutoPrune,"
+"FileRetention,JobRetention) VALUES "
+"('%s','%s',%d,%s,%s)", cr->Name, cr->Uname, cr->AutoPrune,
       edit_uint64(cr->FileRetention, ed1),
       edit_uint64(cr->JobRetention, ed2));
 
@@ -403,10 +546,10 @@ int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
  *  Returns: 0 on failure
  *          1 on success with FileSetId in record
  */
-int db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
+bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
 {
    SQL_ROW row;
-   int stat;
+   bool stat;
    struct tm tm;
 
    db_lock(mdb);
@@ -418,18 +561,18 @@ int db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
-        Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), (int)(mdb->num_rows));
-        Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+         Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), (int)(mdb->num_rows));
+         Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
-           Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
-           Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+            Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
+            Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
            sql_free_result(mdb);
            db_unlock(mdb);
-           return 0;
+           return false;
         }
-        fsr->FileSetId = atoi(row[0]);
+        fsr->FileSetId = str_to_int64(row[0]);
         if (row[1] == NULL) {
            fsr->cCreateTime[0] = 0;
         } else {
@@ -437,7 +580,7 @@ int db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
         }
         sql_free_result(mdb);
         db_unlock(mdb);
-        return 1;
+        return true;
       }
       sql_free_result(mdb);
    }
@@ -457,11 +600,11 @@ int db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
            mdb->cmd, sql_strerror(mdb));
       Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       fsr->FileSetId = 0;
-      stat = 0;
+      stat = false;
    } else {
       fsr->FileSetId = sql_insert_id(mdb, _("FileSet"));
       fsr->created = true;
-      stat = 1;
+      stat = true;
    }
 
    db_unlock(mdb);
@@ -558,8 +701,8 @@ static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
 
    /* Must create it */
    Mmsg(mdb->cmd,
-       "INSERT INTO File (FileIndex,JobId,PathId,FilenameId,"
-       "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','0')",
+        "INSERT INTO File (FileIndex,JobId,PathId,FilenameId,"
+        "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','0')",
        ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId,
        ar->attr);
 
@@ -597,21 +740,21 @@ static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
         char ed1[30];
-        Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
+         Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
            edit_uint64(mdb->num_rows, ed1), mdb->path);
-        Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
+         Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
       }
       /* Even if there are multiple paths, take the first one */
       if (mdb->num_rows >= 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
-           Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
-           Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+            Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+            Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
            sql_free_result(mdb);
            ar->PathId = 0;
            ASSERT(ar->PathId);
            return 0;
         }
-        ar->PathId = atoi(row[0]);
+        ar->PathId = str_to_int64(row[0]);
         sql_free_result(mdb);
         /* Cache path */
         if (ar->PathId != mdb->cached_path_id) {
@@ -661,18 +804,18 @@ static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
         char ed1[30];
-        Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"),
+         Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"),
            edit_uint64(mdb->num_rows, ed1), mdb->fname);
-        Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
+         Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
-           Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"),
+            Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"),
                mdb->fname, sql_strerror(mdb));
-           Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+            Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
            ar->FilenameId = 0;
         } else {
-           ar->FilenameId = atoi(row[0]);
+           ar->FilenameId = str_to_int64(row[0]);
         }
         sql_free_result(mdb);
         return ar->FilenameId > 0;
@@ -693,4 +836,4 @@ static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
    return ar->FilenameId > 0;
 }
 
-#endif /* HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
index a35b64e90055395afc954c504c057f7cccfd6795..839c9b39e2172e766ccc9b938c98fb40e3f75530 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   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
@@ -37,7 +37,7 @@
 #include "cats.h"
 
 
-#if    HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
+#if    HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
 /* -----------------------------------------------------------------------
  *
  *   Generic Routines (or almost generic)
@@ -76,18 +76,18 @@ db_delete_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
       mdb->num_rows = sql_num_rows(mdb);
 
       if (mdb->num_rows == 0) {
-        Mmsg(mdb->errmsg, _("No pool record %s exists\n"), pr->Name);
+         Mmsg(mdb->errmsg, _("No pool record %s exists\n"), pr->Name);
         sql_free_result(mdb);
         db_unlock(mdb);
         return 0;
       } else if (mdb->num_rows != 1) {
-        Mmsg(mdb->errmsg, _("Expecting one pool record, got %d\n"), mdb->num_rows);
+         Mmsg(mdb->errmsg, _("Expecting one pool record, got %d\n"), mdb->num_rows);
         sql_free_result(mdb);
         db_unlock(mdb);
         return 0;
       }
       if ((row = sql_fetch_row(mdb)) == NULL) {
-        Mmsg1(&mdb->errmsg, _("Error fetching row %s\n"), sql_strerror(mdb));
+         Mmsg1(&mdb->errmsg, _("Error fetching row %s\n"), sql_strerror(mdb));
         db_unlock(mdb);
         return 0;
       }
@@ -235,4 +235,4 @@ int db_purge_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
 }
 
 
-#endif /* HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
index cb53f6b3d652a7f43db15dac8f9c93f6517520aa..f364ca91415614eb076e5ed419ce7cf1ead304f3 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -39,7 +39,7 @@
 #include "bacula.h"
 #include "cats.h"
 
-#if    HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
+#if    HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
 
 /* -----------------------------------------------------------------------
  *
@@ -90,14 +90,14 @@ db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime)
          *  backup
          */
         if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
-           Mmsg2(&mdb->errmsg, _("Query error for start time request: ERR=%s\nCMD=%s\n"),
+            Mmsg2(&mdb->errmsg, _("Query error for start time request: ERR=%s\nCMD=%s\n"),
               sql_strerror(mdb), mdb->cmd);
            db_unlock(mdb);
            return 0;
         }
         if ((row = sql_fetch_row(mdb)) == NULL) {
            sql_free_result(mdb);
-           Mmsg(mdb->errmsg, _("No prior Full backup Job record found.\n"));
+            Mmsg(mdb->errmsg, _("No prior Full backup Job record found.\n"));
            db_unlock(mdb);
            return 0;
         }
@@ -110,7 +110,7 @@ db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime)
            jr->JobType, L_INCREMENTAL, L_DIFFERENTIAL, L_FULL, jr->Name,
            jr->ClientId, jr->FileSetId);
       } else {
-        Mmsg1(&mdb->errmsg, _("Unknown level=%d\n"), jr->JobLevel);
+         Mmsg1(&mdb->errmsg, _("Unknown level=%d\n"), jr->JobLevel);
         db_unlock(mdb);
         return 0;
       }
@@ -266,33 +266,35 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr
    if (item == -1) {      /* find oldest volume */
       /* Find oldest volume */
       Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
-         "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
-         "VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,Recycle,Slot,"
-         "FirstWritten,LastWritten,VolStatus,InChanger,VolParts "
-         "FROM Media WHERE PoolId=%u AND MediaType='%s' AND VolStatus IN ('Full',"
-         "'Recycle','Purged','Used','Append') "
-         "ORDER BY LastWritten LIMIT 1", mr->PoolId, mr->MediaType);
+          "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
+          "VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,Recycle,Slot,"
+          "FirstWritten,LastWritten,VolStatus,InChanger,VolParts,"
+          "LabelType "
+          "FROM Media WHERE PoolId=%u AND MediaType='%s' AND VolStatus IN ('Full',"
+          "'Recycle','Purged','Used','Append') "
+          "ORDER BY LastWritten LIMIT 1", mr->PoolId, mr->MediaType);
      item = 1;
    } else {
       /* Find next available volume */
       if (InChanger) {
-        changer = "AND InChanger=1";
+         changer = "AND InChanger=1";
       } else {
-        changer = "";
+         changer = "";
       }
       if (strcmp(mr->VolStatus, "Recycled") == 0 ||
-         strcmp(mr->VolStatus, "Purged") == 0) {
-        order = "ORDER BY LastWritten ASC,MediaId";  /* take oldest */
+          strcmp(mr->VolStatus, "Purged") == 0) {
+         order = "ORDER BY LastWritten ASC,MediaId";  /* take oldest */
       } else {
-        order = "ORDER BY LastWritten IS NULL,LastWritten DESC,MediaId";   /* take most recently written */
+         order = "ORDER BY LastWritten IS NULL,LastWritten DESC,MediaId";   /* take most recently written */
       }
       Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
-         "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
-         "VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,Recycle,Slot,"
-         "FirstWritten,LastWritten,VolStatus,InChanger,VolParts "
-         "FROM Media WHERE PoolId=%u AND MediaType='%s' AND VolStatus='%s' "
-         "%s "
-         "%s LIMIT %d",
+          "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
+          "VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,Recycle,Slot,"
+          "FirstWritten,LastWritten,VolStatus,InChanger,VolParts,"
+          "LabelType "
+          "FROM Media WHERE PoolId=%u AND MediaType='%s' AND VolStatus='%s' "
+          "%s "
+          "%s LIMIT %d",
          mr->PoolId, mr->MediaType, mr->VolStatus, changer, order, item);
    }
    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
@@ -345,6 +347,7 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr
    bstrncpy(mr->VolStatus, row[19], sizeof(mr->VolStatus));
    mr->InChanger = str_to_int64(row[20]);
    mr->VolParts = str_to_int64(row[21]);
+   mr->LabelType = str_to_int64(row[22]);
    sql_free_result(mdb);
 
    db_unlock(mdb);
@@ -352,4 +355,4 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr
 }
 
 
-#endif /* HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
index 958e86503c3be84ddf7cde4d18ca49b39c2b3e97..eab5f76aaf59bcc7e3ee9005f2e8ae94bd316fe1 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /*
-   Copyright (C) 2000-2003 Kern Sibbald and John Walker
+   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
@@ -38,7 +38,7 @@
 #include "bacula.h"
 #include "cats.h"
 
-#if    HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
+#if    HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
 
 /* -----------------------------------------------------------------------
  *
@@ -125,12 +125,12 @@ int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr)
       mdb->num_rows = sql_num_rows(mdb);
       Dmsg1(050, "get_file_record num_rows=%d\n", (int)mdb->num_rows);
       if (mdb->num_rows > 1) {
-        Mmsg1(&mdb->errmsg, _("get_file_record want 1 got rows=%d\n"),
+         Mmsg1(&mdb->errmsg, _("get_file_record want 1 got rows=%d\n"),
            mdb->num_rows);
       }
       if (mdb->num_rows >= 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
-           Mmsg1(&mdb->errmsg, _("Error fetching row: %s\n"), sql_strerror(mdb));
+            Mmsg1(&mdb->errmsg, _("Error fetching row: %s\n"), sql_strerror(mdb));
         } else {
            fdbr->FileId = (FileId_t)str_to_int64(row[0]);
            bstrncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat));
@@ -138,7 +138,7 @@ int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr)
            stat = 1;
         }
       } else {
-        Mmsg2(&mdb->errmsg, _("File record for PathId=%u FilenameId=%u not found.\n"),
+         Mmsg2(&mdb->errmsg, _("File record for PathId=%u FilenameId=%u not found.\n"),
            fdbr->PathId, fdbr->FilenameId);
       }
       sql_free_result(mdb);
@@ -168,23 +168,23 @@ static int db_get_filename_record(JCR *jcr, B_DB *mdb)
       char ed1[30];
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
-        Mmsg2(&mdb->errmsg, _("More than one Filename!: %s for file: %s\n"),
+         Mmsg2(&mdb->errmsg, _("More than one Filename!: %s for file: %s\n"),
            edit_uint64(mdb->num_rows, ed1), mdb->fname);
-        Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
+         Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
-           Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+            Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
         } else {
            FilenameId = atoi(row[0]);
            if (FilenameId <= 0) {
-              Mmsg2(&mdb->errmsg, _("Get DB Filename record %s found bad record: %d\n"),
+               Mmsg2(&mdb->errmsg, _("Get DB Filename record %s found bad record: %d\n"),
                  mdb->cmd, FilenameId);
               FilenameId = 0;
            }
         }
       } else {
-        Mmsg1(&mdb->errmsg, _("Filename record: %s not found.\n"), mdb->fname);
+         Mmsg1(&mdb->errmsg, _("Filename record: %s not found.\n"), mdb->fname);
       }
       sql_free_result(mdb);
    } else {
@@ -218,18 +218,18 @@ static int db_get_path_record(JCR *jcr, B_DB *mdb)
       char ed1[30];
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
-        Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
+         Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
            edit_uint64(mdb->num_rows, ed1), mdb->path);
-        Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
+         Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
       }
       /* Even if there are multiple paths, take the first one */
       if (mdb->num_rows >= 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
-           Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+            Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
         } else {
            PathId = atoi(row[0]);
            if (PathId <= 0) {
-              Mmsg2(&mdb->errmsg, _("Get DB path record %s found bad record: %u\n"),
+               Mmsg2(&mdb->errmsg, _("Get DB path record %s found bad record: %u\n"),
                  mdb->cmd, PathId);
               PathId = 0;
            } else {
@@ -242,7 +242,7 @@ static int db_get_path_record(JCR *jcr, B_DB *mdb)
            }
         }
       } else {
-        Mmsg1(&mdb->errmsg, _("Path record: %s not found.\n"), mdb->path);
+         Mmsg1(&mdb->errmsg, _("Path record: %s not found.\n"), mdb->path);
       }
       sql_free_result(mdb);
    } else {
@@ -314,19 +314,20 @@ int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
  *
  *  Returns: number of volumes on success
  */
-int db_get_job_volume_names(JCR *jcr, B_DB *mdb, uint32_t JobId, POOLMEM **VolumeNames)
+int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **VolumeNames)
 {
    SQL_ROW row;
+   char ed1[50];
    int stat = 0;
    int i;
 
    db_lock(mdb);
    /* Get one entry per VolumeName, but "sort" by VolIndex */
    Mmsg(mdb->cmd,
-       "SELECT VolumeName,MAX(VolIndex) FROM JobMedia,Media WHERE "
-       "JobMedia.JobId=%u AND JobMedia.MediaId=Media.MediaId "
-       "GROUP BY VolumeName "
-       "ORDER BY 2 ASC", JobId);
+        "SELECT VolumeName,MAX(VolIndex) FROM JobMedia,Media WHERE "
+        "JobMedia.JobId=%s AND JobMedia.MediaId=Media.MediaId "
+        "GROUP BY VolumeName "
+        "ORDER BY 2 ASC", edit_uint64(JobId,ed1));
 
    Dmsg1(130, "VolNam=%s\n", mdb->cmd);
    *VolumeNames[0] = 0;
@@ -334,19 +335,19 @@ int db_get_job_volume_names(JCR *jcr, B_DB *mdb, uint32_t JobId, POOLMEM **Volum
       mdb->num_rows = sql_num_rows(mdb);
       Dmsg1(130, "Num rows=%d\n", mdb->num_rows);
       if (mdb->num_rows <= 0) {
-        Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId);
+         Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId);
         stat = 0;
       } else {
         stat = mdb->num_rows;
         for (i=0; i < stat; i++) {
            if ((row = sql_fetch_row(mdb)) == NULL) {
-              Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb));
-              Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+               Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb));
+               Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
               stat = 0;
               break;
            } else {
               if (*VolumeNames[0] != 0) {
-                 pm_strcat(VolumeNames, "|");
+                  pm_strcat(VolumeNames, "|");
               }
               pm_strcat(VolumeNames, row[0]);
            }
@@ -368,26 +369,28 @@ int db_get_job_volume_names(JCR *jcr, B_DB *mdb, uint32_t JobId, POOLMEM **Volum
  *
  *  Returns: number of volumes on success
  */
-int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolParams)
+int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS **VolParams)
 {
    SQL_ROW row;
+   char ed1[50];
    int stat = 0;
    int i;
    VOL_PARAMS *Vols = NULL;
 
    db_lock(mdb);
    Mmsg(mdb->cmd,
-"SELECT VolumeName,FirstIndex,LastIndex,StartFile,JobMedia.EndFile,"
-"StartBlock,JobMedia.EndBlock"
-" FROM JobMedia,Media WHERE JobMedia.JobId=%u"
-" AND JobMedia.MediaId=Media.MediaId ORDER BY VolIndex,JobMediaId", JobId);
+"SELECT VolumeName,MediaType,FirstIndex,LastIndex,StartFile,"
+"JobMedia.EndFile,StartBlock,JobMedia.EndBlock"
+" FROM JobMedia,Media WHERE JobMedia.JobId=%s"
+" AND JobMedia.MediaId=Media.MediaId ORDER BY VolIndex,JobMediaId",
+       edit_int64(JobId, ed1));
 
    Dmsg1(130, "VolNam=%s\n", mdb->cmd);
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
       Dmsg1(130, "Num rows=%d\n", mdb->num_rows);
       if (mdb->num_rows <= 0) {
-        Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId);
+         Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId);
         stat = 0;
       } else {
         stat = mdb->num_rows;
@@ -396,18 +399,19 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, uint32_t JobId, VOL_PARAMS
         }
         for (i=0; i < stat; i++) {
            if ((row = sql_fetch_row(mdb)) == NULL) {
-              Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb));
-              Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+               Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb));
+               Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
               stat = 0;
               break;
            } else {
               bstrncpy(Vols[i].VolumeName, row[0], MAX_NAME_LENGTH);
-              Vols[i].FirstIndex = str_to_uint64(row[1]);
-              Vols[i].LastIndex = str_to_uint64(row[2]);
-              Vols[i].StartFile = str_to_uint64(row[3]);
-              Vols[i].EndFile = str_to_uint64(row[4]);
-              Vols[i].StartBlock = str_to_uint64(row[5]);
-              Vols[i].EndBlock = str_to_uint64(row[6]);
+              bstrncpy(Vols[i].MediaType, row[1], MAX_NAME_LENGTH);
+              Vols[i].FirstIndex = str_to_uint64(row[2]);
+              Vols[i].LastIndex = str_to_uint64(row[3]);
+              Vols[i].StartFile = str_to_uint64(row[4]);
+              Vols[i].EndFile = str_to_uint64(row[5]);
+              Vols[i].StartBlock = str_to_uint64(row[6]);
+              Vols[i].EndBlock = str_to_uint64(row[7]);
            }
         }
       }
@@ -541,16 +545,16 @@ int db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
         char ed1[30];
-        Mmsg1(&mdb->errmsg, _("More than one Pool!: %s\n"),
+         Mmsg1(&mdb->errmsg, _("More than one Pool!: %s\n"),
            edit_uint64(mdb->num_rows, ed1));
-        Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+         Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       } else if (mdb->num_rows == 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
-           Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
-           Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+            Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+            Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
         } else {
            pdbr->PoolId = str_to_int64(row[0]);
-           bstrncpy(pdbr->Name, row[1]!=NULL?row[1]:"", sizeof(pdbr->Name));
+            bstrncpy(pdbr->Name, row[1]!=NULL?row[1]:"", sizeof(pdbr->Name));
            pdbr->NumVols = str_to_int64(row[2]);
            pdbr->MaxVols = str_to_int64(row[3]);
            pdbr->UseOnce = str_to_int64(row[4]);
@@ -563,12 +567,12 @@ int db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr)
            pdbr->MaxVolJobs = str_to_int64(row[11]);
            pdbr->MaxVolFiles = str_to_int64(row[12]);
            pdbr->MaxVolBytes = str_to_uint64(row[13]);
-           bstrncpy(pdbr->PoolType, row[13]!=NULL?row[14]:"", sizeof(pdbr->PoolType));
-           bstrncpy(pdbr->LabelFormat, row[14]!=NULL?row[15]:"", sizeof(pdbr->LabelFormat));
+            bstrncpy(pdbr->PoolType, row[13]!=NULL?row[14]:"", sizeof(pdbr->PoolType));
+            bstrncpy(pdbr->LabelFormat, row[14]!=NULL?row[15]:"", sizeof(pdbr->LabelFormat));
            stat = pdbr->PoolId;
         }
       } else {
-        Mmsg(mdb->errmsg, _("Pool record not found in Catalog.\n"));
+         Mmsg(mdb->errmsg, _("Pool record not found in Catalog.\n"));
       }
       sql_free_result(mdb);
    } else {
@@ -605,24 +609,24 @@ int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
         char ed1[30];
-        Mmsg1(&mdb->errmsg, _("More than one Client!: %s\n"),
+         Mmsg1(&mdb->errmsg, _("More than one Client!: %s\n"),
            edit_uint64(mdb->num_rows, ed1));
-        Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+         Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       } else if (mdb->num_rows == 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
-           Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
-           Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+            Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+            Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
         } else {
            cdbr->ClientId = str_to_int64(row[0]);
-           bstrncpy(cdbr->Name, row[1]!=NULL?row[1]:"", sizeof(cdbr->Name));
-           bstrncpy(cdbr->Uname, row[2]!=NULL?row[1]:"", sizeof(cdbr->Uname));
+            bstrncpy(cdbr->Name, row[1]!=NULL?row[1]:"", sizeof(cdbr->Name));
+            bstrncpy(cdbr->Uname, row[2]!=NULL?row[1]:"", sizeof(cdbr->Uname));
            cdbr->AutoPrune = str_to_int64(row[3]);
            cdbr->FileRetention = str_to_int64(row[4]);
            cdbr->JobRetention = str_to_int64(row[5]);
            stat = 1;
         }
       } else {
-        Mmsg(mdb->errmsg, _("Client record not found in Catalog.\n"));
+         Mmsg(mdb->errmsg, _("Client record not found in Catalog.\n"));
       }
       sql_free_result(mdb);
    } else {
@@ -651,13 +655,13 @@ int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
 
       /* If more than one, report error, but return first row */
       if (mdb->num_rows > 1) {
-        Mmsg1(&mdb->errmsg, _("More than one Counter!: %d\n"), (int)(mdb->num_rows));
-        Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+         Mmsg1(&mdb->errmsg, _("More than one Counter!: %d\n"), (int)(mdb->num_rows));
+         Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
-           Mmsg1(&mdb->errmsg, _("error fetching Counter row: %s\n"), sql_strerror(mdb));
-           Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+            Mmsg1(&mdb->errmsg, _("error fetching Counter row: %s\n"), sql_strerror(mdb));
+            Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
            sql_free_result(mdb);
            db_unlock(mdb);
            return 0;
@@ -698,29 +702,29 @@ int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
    db_lock(mdb);
    if (fsr->FileSetId != 0) {              /* find by id */
       Mmsg(mdb->cmd,
-          "SELECT FileSetId,FileSet,MD5,CreateTime FROM FileSet "
-          "WHERE FileSetId=%u", fsr->FileSetId);
+           "SELECT FileSetId,FileSet,MD5,CreateTime FROM FileSet "
+           "WHERE FileSetId=%u", fsr->FileSetId);
    } else {                          /* find by name */
       Mmsg(mdb->cmd,
-          "SELECT FileSetId,FileSet,CreateTime,MD5 FROM FileSet "
-          "WHERE FileSet='%s' ORDER BY CreateTime DESC LIMIT 1", fsr->FileSet);
+           "SELECT FileSetId,FileSet,CreateTime,MD5 FROM FileSet "
+           "WHERE FileSet='%s' ORDER BY CreateTime DESC LIMIT 1", fsr->FileSet);
    }
 
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
         char ed1[30];
-        Mmsg1(&mdb->errmsg, _("Error got %s FileSets but expected only one!\n"),
+         Mmsg1(&mdb->errmsg, _("Error got %s FileSets but expected only one!\n"),
            edit_uint64(mdb->num_rows, ed1));
         sql_data_seek(mdb, mdb->num_rows-1);
       }
       if ((row = sql_fetch_row(mdb)) == NULL) {
-        Mmsg1(&mdb->errmsg, _("FileSet record \"%s\" not found.\n"), fsr->FileSet);
+         Mmsg1(&mdb->errmsg, _("FileSet record \"%s\" not found.\n"), fsr->FileSet);
       } else {
         fsr->FileSetId = atoi(row[0]);
-        bstrncpy(fsr->FileSet, row[1]!=NULL?row[1]:"", sizeof(fsr->FileSet));
-        bstrncpy(fsr->MD5, row[2]!=NULL?row[2]:"", sizeof(fsr->MD5));
-        bstrncpy(fsr->cCreateTime, row[3]!=NULL?row[3]:"", sizeof(fsr->cCreateTime));
+         bstrncpy(fsr->FileSet, row[1]!=NULL?row[1]:"", sizeof(fsr->FileSet));
+         bstrncpy(fsr->MD5, row[2]!=NULL?row[2]:"", sizeof(fsr->MD5));
+         bstrncpy(fsr->cCreateTime, row[3]!=NULL?row[3]:"", sizeof(fsr->cCreateTime));
         stat = fsr->FileSetId;
       }
       sql_free_result(mdb);
@@ -808,33 +812,35 @@ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
    }
    if (mr->MediaId != 0) {              /* find by id */
       Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
-        "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
-        "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
-        "Recycle,Slot,FirstWritten,LastWritten,InChanger,EndFile,EndBlock,VolParts "
-        "FROM Media WHERE MediaId=%d", mr->MediaId);
+         "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
+         "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs,"
+         "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger,"
+         "EndFile,EndBlock,VolParts,LabelType "
+         "FROM Media WHERE MediaId=%u", mr->MediaId);
    } else {                          /* find by name */
       Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
-        "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
-        "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
-        "Recycle,Slot,FirstWritten,LastWritten,InChanger,EndFile,EndBlock,VolParts "
-        "FROM Media WHERE VolumeName='%s'", mr->VolumeName);
+         "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
+         "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs,"
+         "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger,"
+         "EndFile,EndBlock,VolParts,LabelType "
+         "FROM Media WHERE VolumeName='%s'", mr->VolumeName);
    }
 
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
         char ed1[30];
-        Mmsg1(&mdb->errmsg, _("More than one Volume!: %s\n"),
+         Mmsg1(&mdb->errmsg, _("More than one Volume!: %s\n"),
            edit_uint64(mdb->num_rows, ed1));
-        Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+         Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       } else if (mdb->num_rows == 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
-           Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
-           Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+            Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+            Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
         } else {
            /* return values */
            mr->MediaId = str_to_int64(row[0]);
-           bstrncpy(mr->VolumeName, row[1]!=NULL?row[1]:"", sizeof(mr->VolumeName));
+            bstrncpy(mr->VolumeName, row[1]!=NULL?row[1]:"", sizeof(mr->VolumeName));
            mr->VolJobs = str_to_int64(row[2]);
            mr->VolFiles = str_to_int64(row[3]);
            mr->VolBlocks = str_to_int64(row[4]);
@@ -844,8 +850,8 @@ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
            mr->VolWrites = str_to_int64(row[8]);
            mr->MaxVolBytes = str_to_uint64(row[9]);
            mr->VolCapacityBytes = str_to_uint64(row[10]);
-           bstrncpy(mr->MediaType, row[11]!=NULL?row[11]:"", sizeof(mr->MediaType));
-           bstrncpy(mr->VolStatus, row[12]!=NULL?row[12]:"", sizeof(mr->VolStatus));
+            bstrncpy(mr->MediaType, row[11]!=NULL?row[11]:"", sizeof(mr->MediaType));
+            bstrncpy(mr->VolStatus, row[12]!=NULL?row[12]:"", sizeof(mr->VolStatus));
            mr->PoolId = str_to_int64(row[13]);
            mr->VolRetention = str_to_uint64(row[14]);
            mr->VolUseDuration = str_to_uint64(row[15]);
@@ -853,31 +859,37 @@ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
            mr->MaxVolFiles = str_to_int64(row[17]);
            mr->Recycle = str_to_int64(row[18]);
            mr->Slot = str_to_int64(row[19]);
-           bstrncpy(mr->cFirstWritten, row[20]!=NULL?row[20]:"", sizeof(mr->cFirstWritten));
+            bstrncpy(mr->cFirstWritten, row[20]!=NULL?row[20]:"", sizeof(mr->cFirstWritten));
            mr->FirstWritten = (time_t)str_to_utime(mr->cFirstWritten);
-           bstrncpy(mr->cLastWritten, row[21]!=NULL?row[21]:"", sizeof(mr->cLastWritten));
+            bstrncpy(mr->cLastWritten, row[21]!=NULL?row[21]:"", sizeof(mr->cLastWritten));
            mr->LastWritten = (time_t)str_to_utime(mr->cLastWritten);
            mr->InChanger = str_to_uint64(row[22]);
            mr->EndFile = str_to_uint64(row[23]);
            mr->EndBlock = str_to_uint64(row[24]);
            mr->VolParts = str_to_int64(row[25]);
+           mr->LabelType = str_to_int64(row[26]);
            stat = mr->MediaId;
         }
       } else {
         if (mr->MediaId != 0) {
-           Mmsg1(&mdb->errmsg, _("Media record MediaId=%u not found.\n"), mr->MediaId);
+            Mmsg1(&mdb->errmsg, _("Media record MediaId=%u not found.\n"), mr->MediaId);
         } else {
-           Mmsg1(&mdb->errmsg, _("Media record for Volume \"%s\" not found.\n"),
+            Mmsg1(&mdb->errmsg, _("Media record for Volume \"%s\" not found.\n"),
                  mr->VolumeName);
         }
       }
       sql_free_result(mdb);
    } else {
-      Mmsg(mdb->errmsg, _("Media record not found in Catalog.\n"));
-   }
+      if (mr->MediaId != 0) {
+         Mmsg(mdb->errmsg, _("Media record for MediaId=%u not found in Catalog.\n"),
+           mr->MediaId);
+       } else {
+         Mmsg(mdb->errmsg, _("Media record for Vol=%s not found in Catalog.\n"),
+           mr->VolumeName);
+   }   }
    db_unlock(mdb);
    return stat;
 }
 
 
-#endif /* HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
index 287d7809352bf4c69c4e5aec791eb6797d241158..794a67647952c25325ac9eb16c1e3a005bc7ad24 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   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
@@ -34,7 +34,7 @@
 #include "bacula.h"
 #include "cats.h"
 
-#if    HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
+#if    HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
 
 /* -----------------------------------------------------------------------
  *
@@ -141,7 +141,7 @@ db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr,
             "VolFiles,VolBlocks,VolMounts,VolBytes,VolErrors,VolWrites,"
             "VolCapacityBytes,VolStatus,Recycle,VolRetention,"
             "VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger,"
-            "EndFile,EndBlock,VolParts "
+            "EndFile,EndBlock,VolParts,LabelType "
             "FROM Media WHERE Media.VolumeName='%s'", mdbr->VolumeName);
       } else {
          Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,Slot,PoolId,"
@@ -149,7 +149,7 @@ db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr,
             "VolFiles,VolBlocks,VolMounts,VolBytes,VolErrors,VolWrites,"
             "VolCapacityBytes,VolStatus,Recycle,VolRetention,"
             "VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger,"
-            "EndFile,EndBlock,VolParts "
+            "EndFile,EndBlock,VolParts,LabelType "
             "FROM Media WHERE Media.PoolId=%u ORDER BY MediaId", mdbr->PoolId);
       }
    } else {
@@ -337,4 +337,4 @@ db_list_files_for_job(JCR *jcr, B_DB *mdb, uint32_t jobid, DB_LIST_HANDLER *send
 }
 
 
-#endif /* HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
index 3785fda5e7829fc2aad7c82ee318fbe6014c283c..e007bdf2e9a55ec181af130fd6007d546dfc7948 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -34,7 +34,7 @@
 #include "bacula.h"
 #include "cats.h"
 
-#if    HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
+#if    HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
 
 /* -----------------------------------------------------------------------
  *
@@ -120,7 +120,7 @@ db_update_job_start_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
  *
  */
 void edit_num_or_null(char *s, size_t n, uint32_t id) {
-       bsnprintf(s, n, id ? "%u" : "NULL", id);
+        bsnprintf(s, n, id ? "%u" : "NULL", id);
 }
 
 
@@ -261,7 +261,7 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
    time_t ttime;
    struct tm tm;
    int stat;
-   char ed1[30], ed2[30], ed3[30], ed4[30], ed5[30];
+   char ed1[30], ed2[30], ed3[30], ed4[30];
 
 
    Dmsg1(100, "update_media: FirstWritten=%d\n", mr->FirstWritten);
@@ -286,7 +286,7 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
       localtime_r(&ttime, &tm);
       strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
       Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
-          "WHERE VolumeName='%s'", dt, mr->VolumeName);
+           "WHERE VolumeName='%s'", dt, mr->VolumeName);
       stat = UPDATE_DB(jcr, mdb, mdb->cmd);
    }
 
@@ -296,31 +296,35 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
       strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
 
       Mmsg(mdb->cmd, "UPDATE Media SET VolJobs=%u,"
-          "VolFiles=%u,VolBlocks=%u,VolBytes=%s,VolMounts=%u,VolErrors=%u,"
-          "VolWrites=%u,MaxVolBytes=%s,LastWritten='%s',VolStatus='%s',"
-          "Slot=%d,InChanger=%d,VolReadTime=%s,VolWriteTime=%s,VolParts=%s "
-          " WHERE VolumeName='%s'",
+           "VolFiles=%u,VolBlocks=%u,VolBytes=%s,VolMounts=%u,VolErrors=%u,"
+           "VolWrites=%u,MaxVolBytes=%s,LastWritten='%s',VolStatus='%s',"
+           "Slot=%d,InChanger=%d,VolReadTime=%s,VolWriteTime=%s,VolParts=%d,"
+           "LabelType=%d"
+           " WHERE VolumeName='%s'",
           mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1),
           mr->VolMounts, mr->VolErrors, mr->VolWrites,
           edit_uint64(mr->MaxVolBytes, ed2), dt,
           mr->VolStatus, mr->Slot, mr->InChanger,
           edit_uint64(mr->VolReadTime, ed3),
           edit_uint64(mr->VolWriteTime, ed4),
-           edit_uint64(mr->VolParts, ed5),
+          mr->VolParts,
+          mr->LabelType,
           mr->VolumeName);
    } else {
       Mmsg(mdb->cmd, "UPDATE Media SET VolJobs=%u,"
-          "VolFiles=%u,VolBlocks=%u,VolBytes=%s,VolMounts=%u,VolErrors=%u,"
-          "VolWrites=%u,MaxVolBytes=%s,VolStatus='%s',"
-                 "Slot=%d,InChanger=%d,VolReadTime=%s,VolWriteTime=%s,VolParts=%s "
-          " WHERE VolumeName='%s'",
+           "VolFiles=%u,VolBlocks=%u,VolBytes=%s,VolMounts=%u,VolErrors=%u,"
+           "VolWrites=%u,MaxVolBytes=%s,VolStatus='%s',"
+           "Slot=%d,InChanger=%d,VolReadTime=%s,VolWriteTime=%s,VolParts=%d,"
+           "LabelType=%d"
+           " WHERE VolumeName='%s'",
           mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1),
           mr->VolMounts, mr->VolErrors, mr->VolWrites,
           edit_uint64(mr->MaxVolBytes, ed2),
           mr->VolStatus, mr->Slot, mr->InChanger,
           edit_uint64(mr->VolReadTime, ed3),
           edit_uint64(mr->VolWriteTime, ed4),
-           edit_uint64(mr->VolParts, ed5),
+          mr->VolParts,
+          mr->LabelType,
           mr->VolumeName);
    }
 
@@ -351,9 +355,9 @@ db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
    db_lock(mdb);
    if (mr->VolumeName[0]) {
       Mmsg(mdb->cmd, "UPDATE Media SET "
-          "Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
-          "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s"
-          " WHERE VolumeName='%s'",
+           "Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
+           "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s"
+           " WHERE VolumeName='%s'",
           mr->Recycle,edit_uint64(mr->VolRetention, ed1),
           edit_uint64(mr->VolUseDuration, ed2),
           mr->MaxVolJobs, mr->MaxVolFiles,
@@ -361,9 +365,9 @@ db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
           mr->VolumeName);
    } else {
       Mmsg(mdb->cmd, "UPDATE Media SET "
-          "Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
-          "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s"
-          " WHERE PoolId=%u",
+           "Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
+           "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s"
+           " WHERE PoolId=%u",
           mr->Recycle,edit_uint64(mr->VolRetention, ed1),
           edit_uint64(mr->VolUseDuration, ed2),
           mr->MaxVolJobs, mr->MaxVolFiles,
@@ -391,7 +395,7 @@ db_make_inchanger_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
 {
    if (mr->InChanger != 0 && mr->Slot != 0) {
       Mmsg(mdb->cmd, "UPDATE Media SET InChanger=0 WHERE "
-          "Slot=%d AND PoolId=%u AND MediaId!=%u",
+           "Slot=%d AND PoolId=%u AND MediaId!=%u",
            mr->Slot, mr->PoolId, mr->MediaId);
       Dmsg1(400, "%s\n", mdb->cmd);
       UPDATE_DB(jcr, mdb, mdb->cmd);
@@ -407,4 +411,4 @@ db_make_inchanger_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
   return;
 }
 
-#endif /* HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
index c0398f9aa8f52dc6658f849eb3fa31103c4dc8ea..4af75d52d05c23f74f43e3a33429912ac7c81d57 100644 (file)
@@ -35,7 +35,7 @@
 #include "bacula.h"
 #include "cats.h"
 
-#ifdef HAVE_SQLITE
+#if    HAVE_SQLITE || HAVE_SQLITE3
 
 /* -----------------------------------------------------------------------
  *
@@ -70,7 +70,7 @@ db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char
    if (!mult_db_connections) {
       for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) {
         if (strcmp(mdb->db_name, db_name) == 0) {
-           Dmsg2(300, "DB REopen %d %s\n", mdb->ref_count, db_name);
+            Dmsg2(300, "DB REopen %d %s\n", mdb->ref_count, db_name);
            mdb->ref_count++;
            V(mutex);
            return mdb;                  /* already open */
@@ -139,16 +139,27 @@ db_open_database(JCR *jcr, B_DB *mdb)
       V(mutex);
       return 0;
    }
+
+#ifdef HAVE_SQLITE3
+   int stat = sqlite3_open(db_name, &mdb->db);
+   if (stat != SQLITE_OK) {
+      mdb->sqlite_errmsg = (char *)sqlite3_errmsg(mdb->db); 
+   } else {
+      mdb->sqlite_errmsg = NULL;
+   }
+
+#else
    mdb->db = sqlite_open(
        db_name,                      /* database name */
        644,                          /* mode */
        &mdb->sqlite_errmsg);         /* error message */
+#endif
 
    Dmsg0(300, "sqlite_open\n");
 
    if (mdb->db == NULL) {
       Mmsg2(&mdb->errmsg, _("Unable to open Database=%s. ERR=%s\n"),
-        db_name, mdb->sqlite_errmsg ? mdb->sqlite_errmsg : _("unknown"));
+         db_name, mdb->sqlite_errmsg ? mdb->sqlite_errmsg : _("unknown"));
       free(db_name);
       V(mutex);
       return 0;
@@ -159,7 +170,7 @@ db_open_database(JCR *jcr, B_DB *mdb)
       return 0;
    }
 
-   mdb->connected = TRUE;
+   mdb->connected = true;
    V(mutex);
    return 1;
 }
@@ -198,6 +209,7 @@ db_close_database(JCR *jcr, B_DB *mdb)
  */
 int db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index)
 {
+#ifdef xxxx
    SQL_ROW row;
 
    db_lock(mdb);
@@ -227,6 +239,8 @@ int db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index)
    sql_free_result(mdb);
 
    db_unlock(mdb);
+#endif
+   strcpy(index, "NULL");
    return 1;
 }
 
@@ -248,12 +262,12 @@ db_escape_string(char *snew, char *old, int len)
    while (len--) {
       switch (*o) {
       case '\'':
-        *n++ = '\'';
-        *n++ = '\'';
+         *n++ = '\'';
+         *n++ = '\'';
         o++;
         break;
       case 0:
-        *n++ = '\\';
+         *n++ = '\\';
         *n++ = 0;
         o++;
         break;
@@ -294,7 +308,11 @@ int db_sql_query(B_DB *mdb, const char *query, DB_RESULT_HANDLER *result_handler
 
    db_lock(mdb);
    if (mdb->sqlite_errmsg) {
+#ifdef HAVE_SQLITE3
+      sqlite3_free(mdb->sqlite_errmsg);
+#else
       actuallyfree(mdb->sqlite_errmsg);
+#endif
       mdb->sqlite_errmsg = NULL;
    }
    rh_data.result_handler = result_handler;
@@ -393,6 +411,4 @@ SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb)
    return mdb->fields[mdb->field++];
 }
 
-
-
 #endif /* HAVE_SQLITE */
index 5a7dc8926149c3a87fa0bc827dd33f69e42612eb..d640da17c31f67d0833e73c3873dbc834b1b051f 100755 (executable)
@@ -3,9 +3,9 @@
 # This routine alters the appropriately configured
 #  Bacula tables for PostgreSQL, MySQL, or SQLite.
 #
-if test xsqlite = x@DB_NAME@ ; then
+if test xsqlite = x@DB_NAME@ -o xsqlite3 = x@DB_NAME@ ; then
   echo "Altering SQLite tables"
-  @scriptdir@/update_sqlite_tables $*
+  @scriptdir@/update_@DB_NAME@_tables $*
 fi
 if test xmysql = x@DB_NAME@ ; then
   echo "Altering MySQL tables"
index f47f2137c55f55eeab8c2328d105f6fbb7f5a96d..f1bd2a7b518519901e893ea279d940ebb36ac707 100755 (executable)
@@ -12,6 +12,7 @@ bindir=@SQL_BINDIR@
 if $bindir/mysql $* -f <<END-OF-DATA
 USE bacula;
 
+ALTER TABLE Media ADD COLUMN LabelType INTEGER UNSIGNED NOT NULL DEFAULT 0;
 ALTER TABLE Media ADD COLUMN VolParts INTEGER UNSIGNED NOT NULL DEFAULT 0;
 
 END-OF-DATA
index e13b850d2ed8880fe8f56f407b6afa6db8f9faee..0e69e39a747334c7dd1e58220dbac10e6efcdb3d 100755 (executable)
@@ -12,6 +12,10 @@ bindir=@SQL_BINDIR@
 if $bindir/psql $* -f - <<END-OF-DATA
 \c bacula
 
+ALTER TABLE media ADD COLUMN labeltype integer;
+UPDATE media SET labeltype=0;
+ALTER TABLE media ALTER COLUMN labeltype SET NOT NULL;
+
 ALTER TABLE media ADD COLUMN volparts integer;
 UPDATE media SET volparts=0;
 ALTER TABLE media ALTER COLUMN volparts SET NOT NULL;
index 82114207ddd27eadb3afaaffb9f36aa2de138a4c..f4ad061c71ad10dbc49d11e74f8f6e5125ef4720 100755 (executable)
@@ -10,9 +10,9 @@ echo " "
 
 bindir=@SQL_BINDIR@
 cd @working_dir@
+sqlite=@DB_NAME@
 
-$bindir/sqlite $* bacula.db <<END-OF-DATA
-
+${bindir}/${sqlite} $* bacula.db <<END-OF-DATA
 BEGIN TRANSACTION;
 CREATE TEMPORARY TABLE Media_backup (
    MediaId INTEGER UNSIGNED AUTOINCREMENT,
@@ -50,7 +50,7 @@ CREATE TEMPORARY TABLE Media_backup (
 
 INSERT INTO Media_backup SELECT 
    MediaId, VolumeName, Slot, PoolId,
-   MediaType, FirstWritten, LastWritten,
+   MediaType, 0, FirstWritten, LastWritten,
    LabelDate, VolJobs, VolFiles, VolBlocks,
    VolMounts, VolBytes, 0, VolErrors, VolWrites,
    VolCapacityBytes, VolStatus, Recycle,
@@ -68,6 +68,7 @@ CREATE TABLE Media (
    Slot INTEGER DEFAULT 0,
    PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL,
    MediaType VARCHAR(128) NOT NULL,
+   LabelType TINYINT DEFAULT 0,
    FirstWritten DATETIME DEFAULT 0,
    LastWritten DATETIME DEFAULT 0,
    LabelDate DATETIME DEFAULT 0,
index e3f744bec62919561bccc2d07c07c67f1d77cca6..b2736bf6457ee5c4b281dd1ed80e6e3167cf1cad 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -46,7 +46,7 @@ static char storaddr[]  = "storage address=%s port=%d ssl=%d\n";
 static char OKbackup[]   = "2000 OK backup\n";
 static char OKstore[]    = "2000 OK storage\n";
 static char EndJob[]     = "2800 End Job TermCode=%d JobFiles=%u "
-                          "ReadBytes=%" lld " JobBytes=%" lld " Errors=%u\n";
+                           "ReadBytes=%" lld " JobBytes=%" lld " Errors=%u\n";
 
 
 /* Forward referenced functions */
@@ -71,18 +71,12 @@ int do_backup(JCR *jcr)
 
    since[0] = 0;
 
-   if (!get_or_create_client_record(jcr)) {
-      goto bail_out;
-   }
-
    if (!get_or_create_fileset_record(jcr, &fsr)) {
       goto bail_out;
    }
 
    get_level_since_time(jcr, since, sizeof(since));
 
-   jcr->fname = get_pool_memory(PM_FNAME);
-
    /*
     * Get the Pool record -- first apply any level defined pools
     */
@@ -109,11 +103,11 @@ int do_backup(JCR *jcr)
    while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
       /* Try to create the pool */
       if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
-        Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
+         Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
            db_strerror(jcr->db));
         goto bail_out;
       } else {
-        Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
+         Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
       }
    }
    jcr->PoolId = pr.PoolId;              /****FIXME**** this can go away */
@@ -148,7 +142,7 @@ int do_backup(JCR *jcr)
    /*
     * Now start a job with the Storage daemon
     */
-   if (!start_storage_daemon_job(jcr)) {
+   if (!start_storage_daemon_job(jcr, jcr->storage, SD_APPEND)) {
       goto bail_out;
    }
    /*
@@ -234,9 +228,9 @@ int wait_for_job_termination(JCR *jcr)
          &ReadBytes, &JobBytes, &Errors) == 5) {
         fd_ok = true;
         set_jcr_job_status(jcr, jcr->FDJobStatus);
-        Dmsg1(100, "FDStatus=%c\n", (char)jcr->JobStatus);
+         Dmsg1(100, "FDStatus=%c\n", (char)jcr->JobStatus);
       } else {
-        Jmsg(jcr, M_WARNING, 0, _("Unexpected Client Job message: %s\n"),
+         Jmsg(jcr, M_WARNING, 0, _("Unexpected Client Job message: %s\n"),
            fd->msg);
       }
       if (job_canceled(jcr)) {
@@ -326,18 +320,18 @@ static void backup_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr
       if (*fname == '|') {
         fname++;
         got_pipe = 1;
-        bpipe = open_bpipe(fname, 0, "w");
+         bpipe = open_bpipe(fname, 0, "w");
         fd = bpipe ? bpipe->wfd : NULL;
       } else {
         /* ***FIXME*** handle BASE */
-        fd = fopen(fname, jcr->JobLevel==L_FULL?"w+":"a+");
+         fd = fopen(fname, jcr->JobLevel==L_FULL?"w+":"a+");
       }
       if (fd) {
         VolCount = db_get_job_volume_parameters(jcr, jcr->db, jcr->JobId,
                    &VolParams);
         if (VolCount == 0) {
-           Jmsg(jcr, M_ERROR, 0, _("Could not get Job Volume Parameters to "
-                "update Bootstrap file. ERR=%s\n"), db_strerror(jcr->db));
+            Jmsg(jcr, M_ERROR, 0, _("Could not get Job Volume Parameters to "
+                 "update Bootstrap file. ERR=%s\n"), db_strerror(jcr->db));
             if (jcr->SDJobFiles != 0) {
                set_jcr_job_status(jcr, JS_ErrorTerminated);
             }
@@ -345,14 +339,15 @@ static void backup_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr
         }
         for (int i=0; i < VolCount; i++) {
            /* Write the record */
-           fprintf(fd, "Volume=\"%s\"\n", VolParams[i].VolumeName);
-           fprintf(fd, "VolSessionId=%u\n", jcr->VolSessionId);
-           fprintf(fd, "VolSessionTime=%u\n", jcr->VolSessionTime);
-           fprintf(fd, "VolFile=%u-%u\n", VolParams[i].StartFile,
+            fprintf(fd, "Volume=\"%s\"\n", VolParams[i].VolumeName);
+            fprintf(fd, "MediaType=\"%s\"\n", VolParams[i].MediaType);
+            fprintf(fd, "VolSessionId=%u\n", jcr->VolSessionId);
+            fprintf(fd, "VolSessionTime=%u\n", jcr->VolSessionTime);
+            fprintf(fd, "VolFile=%u-%u\n", VolParams[i].StartFile,
                         VolParams[i].EndFile);
-           fprintf(fd, "VolBlock=%u-%u\n", VolParams[i].StartBlock,
+            fprintf(fd, "VolBlock=%u-%u\n", VolParams[i].StartBlock,
                         VolParams[i].EndBlock);
-           fprintf(fd, "FileIndex=%d-%d\n", VolParams[i].FirstIndex,
+            fprintf(fd, "FileIndex=%d-%d\n", VolParams[i].FirstIndex,
                         VolParams[i].LastIndex);
         }
         if (VolParams) {
@@ -365,8 +360,8 @@ static void backup_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr
         }
       } else {
         berrno be;
-        Jmsg(jcr, M_ERROR, 0, _("Could not open WriteBootstrap file:\n"
-             "%s: ERR=%s\n"), fname, be.strerror());
+         Jmsg(jcr, M_ERROR, 0, _("Could not open WriteBootstrap file:\n"
+              "%s: ERR=%s\n"), fname, be.strerror());
         set_jcr_job_status(jcr, JS_ErrorTerminated);
       }
    }
@@ -375,14 +370,14 @@ static void backup_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr
    switch (jcr->JobStatus) {
       case JS_Terminated:
         if (jcr->Errors || jcr->SDErrors) {
-           term_msg = _("Backup OK -- with warnings");
+            term_msg = _("Backup OK -- with warnings");
         } else {
-           term_msg = _("Backup OK");
+            term_msg = _("Backup OK");
         }
         break;
       case JS_FatalError:
       case JS_ErrorTerminated:
-        term_msg = _("*** Backup Error ***");
+         term_msg = _("*** Backup Error ***");
         msg_type = M_ERROR;          /* Generate error message */
         if (jcr->store_bsock) {
            bnet_sig(jcr->store_bsock, BNET_TERMINATE);
@@ -392,7 +387,7 @@ static void backup_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr
         }
         break;
       case JS_Canceled:
-        term_msg = _("Backup Canceled");
+         term_msg = _("Backup Canceled");
         if (jcr->store_bsock) {
            bnet_sig(jcr->store_bsock, BNET_TERMINATE);
            if (jcr->SD_msg_chan) {
@@ -402,7 +397,7 @@ static void backup_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr
         break;
       default:
         term_msg = term_code;
-        sprintf(term_code, _("Inappropriate term code: %c\n"), jcr->JobStatus);
+         sprintf(term_code, _("Inappropriate term code: %c\n"), jcr->JobStatus);
         break;
    }
    bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime);
@@ -421,7 +416,7 @@ static void backup_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr
        *  normal exit should we complain about this error.
        */
       if (jcr->JobStatus == JS_Terminated && jcr->jr.JobBytes) {
-        Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
+         Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
       }
       jcr->VolumeName[0] = 0;        /* none */
    }
@@ -431,9 +426,9 @@ static void backup_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr
    } else {
       compression = (double)100 - 100.0 * ((double)jcr->JobBytes / (double)jcr->ReadBytes);
       if (compression < 0.5) {
-        bstrncpy(compress, "None", sizeof(compress));
+         bstrncpy(compress, "None", sizeof(compress));
       } else {
-        bsnprintf(compress, sizeof(compress), "%.1f %%", (float)compression);
+         bsnprintf(compress, sizeof(compress), "%.1f %%", (float)compression);
       }
    }
    jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
index 4545d65504e151de65bed92d217ae493f12a65a1..9554cf2db7e256cec2b9bc84db8fffb77ade1ef2 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 /*
-   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
@@ -79,10 +79,10 @@ static uint32_t write_findex(UAContext *ua, RBSR_FINDEX *fi,
         findex = fi->findex < FirstIndex ? FirstIndex : fi->findex;
         findex2 = fi->findex2 > LastIndex ? LastIndex : fi->findex2;
         if (findex == findex2) {
-           fprintf(fd, "FileIndex=%d\n", findex);
+            fprintf(fd, "FileIndex=%d\n", findex);
            count++;
         } else {
-           fprintf(fd, "FileIndex=%d-%d\n", findex, findex2);
+            fprintf(fd, "FileIndex=%d-%d\n", findex, findex2);
            count += findex2 - findex + 1;
         }
       }
@@ -115,10 +115,10 @@ static void print_findex(UAContext *ua, RBSR_FINDEX *fi)
    bsendmsg(ua, "fi=0x%lx\n", fi);
    for ( ; fi; fi=fi->next) {
       if (fi->findex == fi->findex2) {
-        bsendmsg(ua, "FileIndex=%d\n", fi->findex);
+         bsendmsg(ua, "FileIndex=%d\n", fi->findex);
 //       Dmsg1(100, "FileIndex=%d\n", fi->findex);
       } else {
-        bsendmsg(ua, "FileIndex=%d-%d\n", fi->findex, fi->findex2);
+         bsendmsg(ua, "FileIndex=%d-%d\n", fi->findex, fi->findex2);
 //       Dmsg2(100, "FileIndex=%d-%d\n", fi->findex, fi->findex2);
       }
    }
@@ -156,14 +156,14 @@ int complete_bsr(UAContext *ua, RBSR *bsr)
       memset(&jr, 0, sizeof(jr));
       jr.JobId = bsr->JobId;
       if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
-        bsendmsg(ua, _("Unable to get Job record. ERR=%s\n"), db_strerror(ua->db));
+         bsendmsg(ua, _("Unable to get Job record. ERR=%s\n"), db_strerror(ua->db));
         return 0;
       }
       bsr->VolSessionId = jr.VolSessionId;
       bsr->VolSessionTime = jr.VolSessionTime;
       if ((bsr->VolCount=db_get_job_volume_parameters(ua->jcr, ua->db, bsr->JobId,
           &(bsr->VolParams))) == 0) {
-        bsendmsg(ua, _("Unable to get Job Volume Parameters. ERR=%s\n"), db_strerror(ua->db));
+         bsendmsg(ua, _("Unable to get Job Volume Parameters. ERR=%s\n"), db_strerror(ua->db));
         if (bsr->VolParams) {
            free(bsr->VolParams);
            bsr->VolParams = NULL;
@@ -251,19 +251,20 @@ static uint32_t write_bsr(UAContext *ua, RBSR *bsr, FILE *fd)
            bsr->VolParams[i].VolumeName[0] = 0;  /* zap VolumeName */
            continue;
         }
-        fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
-        fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
-        fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
+         fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
+         fprintf(fd, "MediaType=\"%s\"\n", bsr->VolParams[i].MediaType);
+         fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
+         fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
         if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
-           fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
+            fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
         } else {
-           fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
+            fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
                    bsr->VolParams[i].EndFile);
         }
         if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) {
-           fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartBlock);
+            fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartBlock);
         } else {
-           fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
+            fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
                    bsr->VolParams[i].EndBlock);
         }
 //       Dmsg2(100, "bsr VolParam FI=%u LI=%u\n",
@@ -272,7 +273,7 @@ static uint32_t write_bsr(UAContext *ua, RBSR *bsr, FILE *fd)
         count = write_findex(ua, bsr->fi, bsr->VolParams[i].FirstIndex,
                              bsr->VolParams[i].LastIndex, fd);
         if (count) {
-           fprintf(fd, "Count=%u\n", count);
+            fprintf(fd, "Count=%u\n", count);
         }
         total_count += count;
         /* If the same file is present on two tapes or in two files
@@ -294,12 +295,13 @@ void print_bsr(UAContext *ua, RBSR *bsr)
 {
    if (bsr) {
       for (int i=0; i < bsr->VolCount; i++) {
-        bsendmsg(ua, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
-        bsendmsg(ua, "VolSessionId=%u\n", bsr->VolSessionId);
-        bsendmsg(ua, "VolSessionTime=%u\n", bsr->VolSessionTime);
-        bsendmsg(ua, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
+         bsendmsg(ua, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
+         bsendmsg(ua, "MediaType\"%s\"\n", bsr->VolParams[i].MediaType);
+         bsendmsg(ua, "VolSessionId=%u\n", bsr->VolSessionId);
+         bsendmsg(ua, "VolSessionTime=%u\n", bsr->VolSessionTime);
+         bsendmsg(ua, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
                  bsr->VolParams[i].EndFile);
-        bsendmsg(ua, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
+         bsendmsg(ua, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
                  bsr->VolParams[i].EndBlock);
         print_findex(ua, bsr->fi);
       }
index 1cacf017973dfe8bc17b6e30954ffb35b339bfca..21d759e6e47aa1f7e945526e21f7da9d52af3198 100644 (file)
@@ -45,14 +45,14 @@ static char Find_media[] = "CatReq Job=%127s FindMedia=%d\n";
 static char Get_Vol_Info[] = "CatReq Job=%127s GetVolInfo VolName=%127s write=%d\n";
 
 static char Update_media[] = "CatReq Job=%127s UpdateMedia VolName=%s"
-" VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%" lld " VolMounts=%u"
-" VolErrors=%u VolWrites=%u MaxVolBytes=%" lld " EndTime=%d VolStatus=%10s"
-" Slot=%d relabel=%d InChanger=%d VolReadTime=%" lld " VolWriteTime=%" lld
-" VolParts=%u\n";
+   " VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%" lld " VolMounts=%u"
+   " VolErrors=%u VolWrites=%u MaxVolBytes=%" lld " EndTime=%d VolStatus=%10s"
+   " Slot=%d relabel=%d InChanger=%d VolReadTime=%" lld " VolWriteTime=%" lld
+   " VolParts=%u\n";
 
 static char Create_job_media[] = "CatReq Job=%127s CreateJobMedia "
-" FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u "
-" StartBlock=%u EndBlock=%u\n";
+   " FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u "
+   " StartBlock=%u EndBlock=%u\n";
 
 
 /* Responses  sent to Storage daemon */
@@ -60,7 +60,7 @@ static char OK_media[] = "1000 OK VolName=%s VolJobs=%u VolFiles=%u"
    " VolBlocks=%u VolBytes=%s VolMounts=%u VolErrors=%u VolWrites=%u"
    " MaxVolBytes=%s VolCapacityBytes=%s VolStatus=%s Slot=%d"
    " MaxVolJobs=%u MaxVolFiles=%u InChanger=%d VolReadTime=%s"
-   " VolWriteTime=%s EndFile=%u EndBlock=%u VolParts=%u\n";
+   " VolWriteTime=%s EndFile=%u EndBlock=%u VolParts=%u LabelType=%d\n";
 
 static char OK_create[] = "1000 OK CreateJobMedia\n";
 
@@ -83,9 +83,10 @@ static int send_volume_info_to_storage_daemon(JCR *jcr, BSOCK *sd, MEDIA_DBR *mr
       edit_uint64(mr->VolReadTime, ed4),
       edit_uint64(mr->VolWriteTime, ed5),
       mr->EndFile, mr->EndBlock,
-      mr->VolParts);
+      mr->VolParts,
+      mr->LabelType);
    unbash_spaces(mr->VolumeName);
-   Dmsg2(200, "Vol Info for %s: %s", jcr->Job, sd->msg);
+   Dmsg2(400, "Vol Info for %s: %s", jcr->Job, sd->msg);
    return stat;
 }
 
@@ -104,7 +105,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
    /*
     * Request to find next appendable Volume for this Job
     */
-   Dmsg1(200, "catreq %s", bs->msg);
+   Dmsg1(400, "catreq %s", bs->msg);
    if (sscanf(bs->msg, Find_media, &Job, &index) == 2) {
       ok = find_next_volume_for_append(jcr, &mr, true /*permit create new vol*/);
       /*
@@ -182,21 +183,22 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
     *  of a Storage daemon Job Session, when labeling/relabeling a
     *  Volume, or when an EOF mark is written.
     */
-   } else if (sscanf(bs->msg, Update_media, &Job, &sdmr.VolumeName, &sdmr.VolJobs,
-      &sdmr.VolFiles, &sdmr.VolBlocks, &sdmr.VolBytes, &sdmr.VolMounts, &sdmr.VolErrors,
-      &sdmr.VolWrites, &sdmr.MaxVolBytes, &sdmr.LastWritten, &sdmr.VolStatus,
-      &sdmr.Slot, &label, &sdmr.InChanger, &sdmr.VolReadTime,
-      &sdmr.VolWriteTime, &sdmr.VolParts) == 18) {
+   } else if (sscanf(bs->msg, Update_media, &Job, &sdmr.VolumeName,
+      &sdmr.VolJobs, &sdmr.VolFiles, &sdmr.VolBlocks, &sdmr.VolBytes,
+      &sdmr.VolMounts, &sdmr.VolErrors, &sdmr.VolWrites, &sdmr.MaxVolBytes,
+      &sdmr.LastWritten, &sdmr.VolStatus, &sdmr.Slot, &label, &sdmr.InChanger,
+      &sdmr.VolReadTime, &sdmr.VolWriteTime, &sdmr.VolParts) == 18) {
 
       db_lock(jcr->db);
-      Dmsg3(300, "Update media %s oldStat=%s newStat=%s\n", sdmr.VolumeName,
+      Dmsg3(400, "Update media %s oldStat=%s newStat=%s\n", sdmr.VolumeName,
         mr.VolStatus, sdmr.VolStatus);
       bstrncpy(mr.VolumeName, sdmr.VolumeName, sizeof(mr.VolumeName)); /* copy Volume name */
       unbash_spaces(mr.VolumeName);
       if (!db_get_media_record(jcr, jcr->db, &mr)) {
          Jmsg(jcr, M_ERROR, 0, _("Unable to get Media record for Volume %s: ERR=%s\n"),
              mr.VolumeName, db_strerror(jcr->db));
-         bnet_fsend(bs, "1991 Catalog Request failed: %s", db_strerror(jcr->db));
+         bnet_fsend(bs, "1991 Catalog Request for vol=%s failed: %s", 
+           mr.VolumeName, db_strerror(jcr->db));
         db_unlock(jcr->db);
         return;
       }
@@ -205,7 +207,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
         mr.FirstWritten = jcr->start_time;   /* use Job start time as first write */
       }
       /* If we just labeled the tape set time */
-      Dmsg2(300, "label=%d labeldate=%d\n", label, mr.LabelDate);
+      Dmsg2(400, "label=%d labeldate=%d\n", label, mr.LabelDate);
       if (label || mr.LabelDate == 0) {
         mr.LabelDate = time(NULL);
       } else {
@@ -217,7 +219,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
               mr.VolFiles, sdmr.VolFiles);
         }
       }
-      Dmsg2(300, "Update media: BefVolJobs=%u After=%u\n", mr.VolJobs, sdmr.VolJobs);
+      Dmsg2(400, "Update media: BefVolJobs=%u After=%u\n", mr.VolJobs, sdmr.VolJobs);
       /* Copy updated values to original media record */
       mr.VolJobs      = sdmr.VolJobs;
       mr.VolFiles     = sdmr.VolFiles;
@@ -234,7 +236,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
       mr.VolParts     = sdmr.VolParts;
       bstrncpy(mr.VolStatus, sdmr.VolStatus, sizeof(mr.VolStatus));
 
-      Dmsg2(300, "db_update_media_record. Stat=%s Vol=%s\n", mr.VolStatus, mr.VolumeName);
+      Dmsg2(400, "db_update_media_record. Stat=%s Vol=%s\n", mr.VolStatus, mr.VolumeName);
       /*
        * Check if it has expired, and if not update the DB. Note, if
        *   Volume has expired, has_volume_expired() will update the DB.
@@ -247,7 +249,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
          Jmsg(jcr, M_ERROR, 0, _("Catalog error updating Media record. %s"),
            db_strerror(jcr->db));
          bnet_fsend(bs, "1992 Update Media error\n");
-         Dmsg0(190, "send error\n");
+         Dmsg0(400, "send error\n");
       }
       db_unlock(jcr->db);
 
@@ -260,14 +262,14 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
 
       jm.JobId = jcr->JobId;
       jm.MediaId = jcr->MediaId;
-      Dmsg6(300, "create_jobmedia JobId=%d MediaId=%d SF=%d EF=%d FI=%d LI=%d\n",
+      Dmsg6(400, "create_jobmedia JobId=%d MediaId=%d SF=%d EF=%d FI=%d LI=%d\n",
         jm.JobId, jm.MediaId, jm.StartFile, jm.EndFile, jm.FirstIndex, jm.LastIndex);
       if (!db_create_jobmedia_record(jcr, jcr->db, &jm)) {
          Jmsg(jcr, M_ERROR, 0, _("Catalog error creating JobMedia record. %s"),
            db_strerror(jcr->db));
          bnet_fsend(bs, "1991 Update JobMedia error\n");
       } else {
-         Dmsg0(300, "JobMedia record created\n");
+         Dmsg0(400, "JobMedia record created\n");
         bnet_fsend(bs, OK_create);
       }
 
@@ -278,8 +280,8 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
       Jmsg1(jcr, M_ERROR, 0, _("Invalid Catalog request: %s"), omsg);
       free_memory(omsg);
    }
-   Dmsg1(300, ">CatReq response: %s", bs->msg);
-   Dmsg1(200, "Leave catreq jcr 0x%x\n", jcr);
+   Dmsg1(400, ">CatReq response: %s", bs->msg);
+   Dmsg1(400, "Leave catreq jcr 0x%x\n", jcr);
    return;
 }
 
@@ -320,8 +322,8 @@ void catalog_update(JCR *jcr, BSOCK *bs, char *msg)
    unser_uint32(data_len);
    p += unser_length(p);
 
-   Dmsg1(300, "UpdCat msg=%s\n", bs->msg);
-   Dmsg5(300, "UpdCat VolSessId=%d VolSessT=%d FI=%d Strm=%d data_len=%d\n",
+   Dmsg1(400, "UpdCat msg=%s\n", bs->msg);
+   Dmsg5(400, "UpdCat VolSessId=%d VolSessT=%d FI=%d Strm=%d data_len=%d\n",
       VolSessionId, VolSessionTime, FileIndex, Stream, data_len);
 
    if (Stream == STREAM_UNIX_ATTRIBUTES || Stream == STREAM_UNIX_ATTRIBUTES_EX) {
@@ -333,8 +335,8 @@ void catalog_update(JCR *jcr, BSOCK *bs, char *msg)
       len = strlen(fname);       /* length before attributes */
       attr = &fname[len+1];
 
-      Dmsg2(300, "dird<stored: stream=%d %s\n", Stream, fname);
-      Dmsg1(300, "dird<stored: attr=%s\n", attr);
+      Dmsg2(400, "dird<stored: stream=%d %s\n", Stream, fname);
+      Dmsg1(400, "dird<stored: attr=%s\n", attr);
       ar.attr = attr;
       ar.fname = fname;
       ar.FileIndex = FileIndex;
@@ -342,8 +344,8 @@ void catalog_update(JCR *jcr, BSOCK *bs, char *msg)
       ar.link = NULL;
       ar.JobId = jcr->JobId;
 
-      Dmsg2(300, "dird<filed: stream=%d %s\n", Stream, fname);
-      Dmsg1(120, "dird<filed: attr=%s\n", attr);
+      Dmsg2(400, "dird<filed: stream=%d %s\n", Stream, fname);
+      Dmsg1(400, "dird<filed: attr=%s\n", attr);
 
       if (!db_create_file_attributes_record(jcr, jcr->db, &ar)) {
          Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db));
@@ -367,7 +369,7 @@ void catalog_update(JCR *jcr, BSOCK *bs, char *msg)
            type = SHA1_SIG;
         }
         bin_to_base64(SIGbuf, fname, len);
-         Dmsg3(190, "SIGlen=%d SIG=%s type=%d\n", strlen(SIGbuf), SIGbuf, Stream);
+         Dmsg3(400, "SIGlen=%d SIG=%s type=%d\n", strlen(SIGbuf), SIGbuf, Stream);
         if (!db_add_SIG_to_file_record(jcr, jcr->db, jcr->FileId, SIGbuf, type)) {
             Jmsg(jcr, M_ERROR, 0, _("Catalog error updating MD5/SHA1. %s"),
               db_strerror(jcr->db));
index e3484c79dbae8809753f9c67fb9e0925588ae9a3..7dccc440812311cdc86fe746248945f30a147747 100644 (file)
@@ -7,7 +7,7 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -50,6 +50,7 @@ void term_job_server();
 void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
 void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
 void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
+void init_device_resources();
 
 static char *configfile = NULL;
 static char *runjob = NULL;
@@ -74,7 +75,7 @@ extern URES res_all;
 static void usage()
 {
    fprintf(stderr, _(
-"Copyright (C) 2000-2004 Kern Sibbald and John Walker\n"
+"Copyright (C) 2000-2005 Kern Sibbald.\n"
 "\nVersion: " VERSION " (" BDATE ")\n\n"
 "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
 "       -c <file>   set configuration file to file\n"
@@ -238,6 +239,8 @@ int main (int argc, char *argv[])
 
    init_job_server(director->MaxConcurrentJobs);
 
+   init_device_resources();
+
    Dmsg0(200, "wait for next job\n");
    /* Main loop -- call scheduler to get next job to run */
    while ((jcr = wait_for_next_job(runjob))) {
@@ -499,13 +502,11 @@ static int check_resources()
       if (job->jobdefs) {
         /* Handle Storage alists specifically */
         JOB *jobdefs = job->jobdefs;
-        for (i=0; i < MAX_STORE; i++) {
-           if (jobdefs->storage[i] && !job->storage[i]) {
-              STORE *st;
-              job->storage[i] = New(alist(10, not_owned_by_alist));
-              foreach_alist(st, jobdefs->storage[i]) {
-                 job->storage[i]->append(st);
-              }
+        if (jobdefs->storage && !job->storage) {
+           STORE *st;
+           job->storage = New(alist(10, not_owned_by_alist));
+           foreach_alist(st, jobdefs->storage) {
+              job->storage->append(st);
            }
         }
 
@@ -637,8 +638,26 @@ static int check_resources()
       foreach_res(pool, R_POOL) {
         create_pool(NULL, db, pool, POOL_OP_UPDATE);  /* update request */
       }
-      /* Loop over all counters, defining them in each database */
 
+      /* ***FIXME*** we need to update store and media_type records */
+      STORE *store;
+      foreach_res(store, R_STORAGE) {
+        STORAGE_DBR sr;
+        MEDIATYPE_DBR mr;
+        if (store->media_type) {
+           bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
+           mr.ReadOnly = 0;
+           db_create_mediatype_record(NULL, db, &mr);
+        } else {
+           mr.MediaTypeId = 0;
+        }
+        sr.MediaTypeId = mr.MediaTypeId;
+        bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
+        sr.AutoChanger = store->autochanger;
+        db_create_storage_record(NULL, db, &sr);
+      }
+
+      /* Loop over all counters, defining them in each database */
       /* Set default value in all counters */
       COUNTER *counter;
       foreach_res(counter, R_COUNTER) {
index 430d0a6bec440f1d6c30bc6d1d7e9d0ea819d02e..d388fc963bcd6f8e9ae6bc8e21607c5a3f0ae20e 100644 (file)
@@ -63,8 +63,10 @@ extern void store_inc(LEX *lc, RES_ITEM *item, int index, int pass);
 
 void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
 void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
+void store_label(LEX *lc, RES_ITEM *item, int index, int pass);
 void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
 void store_acl(LEX *lc, RES_ITEM *item, int index, int pass);
+static void store_device(LEX *lc, RES_ITEM *item, int index, int pass);
 
 
 /* We build the current resource here as we are
@@ -164,8 +166,7 @@ static RES_ITEM store_items[] = {
    {"sdaddress",   store_str,      ITEM(res_store.address),    0, 0, 0},
    {"password",    store_password, ITEM(res_store.password),   0, ITEM_REQUIRED, 0},
    {"sdpassword",  store_password, ITEM(res_store.password),   0, 0, 0},
-   {"device",      store_strname,  ITEM(res_store.dev_name),   0, ITEM_REQUIRED, 0},
-   {"sddevicename", store_strname, ITEM(res_store.dev_name),   0, 0, 0},
+   {"device",      store_device,   ITEM(res_store.device),     R_DEVICE, ITEM_REQUIRED, 0},
    {"mediatype",   store_strname,  ITEM(res_store.media_type), 0, ITEM_REQUIRED, 0},
    {"autochanger", store_yesno,    ITEM(res_store.autochanger), 1, ITEM_DEFAULT, 0},
    {"enablessl",   store_yesno,    ITEM(res_store.enable_ssl),  1, ITEM_DEFAULT, 0},
@@ -206,7 +207,7 @@ RES_ITEM job_items[] = {
    {"type",      store_jobtype, ITEM(res_job.JobType),  0, ITEM_REQUIRED, 0},
    {"level",     store_level,   ITEM(res_job.JobLevel),    0, 0, 0},
    {"messages",  store_res,     ITEM(res_job.messages), R_MSGS, ITEM_REQUIRED, 0},
-   {"storage",   store_alist_res, ITEM(res_job.storage),  R_STORAGE, ITEM_REQUIRED, MAX_STORE},
+   {"storage",   store_alist_res, ITEM(res_job.storage),  R_STORAGE, ITEM_REQUIRED, 0},
    {"pool",      store_res,     ITEM(res_job.pool),     R_POOL, ITEM_REQUIRED, 0},
    {"fullbackuppool",  store_res, ITEM(res_job.full_pool),   R_POOL, 0, 0},
    {"incrementalbackuppool",  store_res, ITEM(res_job.inc_pool), R_POOL, 0, 0},
@@ -279,22 +280,23 @@ static RES_ITEM pool_items[] = {
    {"description",     store_str,     ITEM(res_pool.hdr.desc),      0, 0,     0},
    {"pooltype",        store_strname, ITEM(res_pool.pool_type),     0, ITEM_REQUIRED, 0},
    {"labelformat",     store_strname, ITEM(res_pool.label_format),  0, 0,     0},
-   {"cleaningprefix",  store_strname, ITEM(res_pool.cleaning_prefix),  0, 0,     0},
-   {"usecatalog",      store_yesno, ITEM(res_pool.use_catalog),     1, ITEM_DEFAULT,  1},
-   {"usevolumeonce",   store_yesno, ITEM(res_pool.use_volume_once), 1, 0,        0},
+   {"labeltype",       store_label,   ITEM(res_pool.LabelType),     0, 0,     0},     
+   {"cleaningprefix",  store_strname, ITEM(res_pool.cleaning_prefix), 0, 0,     0},
+   {"usecatalog",      store_yesno,   ITEM(res_pool.use_catalog),    1, ITEM_DEFAULT,  1},
+   {"usevolumeonce",   store_yesno,   ITEM(res_pool.use_volume_once),1, 0,        0},
    {"purgeoldestvolume", store_yesno, ITEM(res_pool.purge_oldest_volume), 1, 0, 0},
-   {"recycleoldestvolume", store_yesno, ITEM(res_pool.recycle_oldest_volume), 1, 0, 0},
+   {"recycleoldestvolume", store_yesno,  ITEM(res_pool.recycle_oldest_volume), 1, 0, 0},
    {"recyclecurrentvolume", store_yesno, ITEM(res_pool.recycle_current_volume), 1, 0, 0},
-   {"maximumvolumes",  store_pint,  ITEM(res_pool.max_volumes),     0, 0,        0},
+   {"maximumvolumes",  store_pint,    ITEM(res_pool.max_volumes),   0, 0,        0},
    {"maximumvolumejobs", store_pint,  ITEM(res_pool.MaxVolJobs),    0, 0,       0},
    {"maximumvolumefiles", store_pint, ITEM(res_pool.MaxVolFiles),   0, 0,       0},
    {"maximumvolumebytes", store_size, ITEM(res_pool.MaxVolBytes),   0, 0,       0},
-   {"acceptanyvolume", store_yesno, ITEM(res_pool.accept_any_volume), 1, ITEM_DEFAULT,     1},
-   {"catalogfiles",    store_yesno, ITEM(res_pool.catalog_files),   1, ITEM_DEFAULT,  1},
-   {"volumeretention", store_time,  ITEM(res_pool.VolRetention),    0, ITEM_DEFAULT, 60*60*24*365},
-   {"volumeuseduration", store_time,  ITEM(res_pool.VolUseDuration),0, 0, 0},
-   {"autoprune",       store_yesno, ITEM(res_pool.AutoPrune), 1, ITEM_DEFAULT, 1},
-   {"recycle",         store_yesno, ITEM(res_pool.Recycle),     1, ITEM_DEFAULT, 1},
+   {"acceptanyvolume", store_yesno,   ITEM(res_pool.accept_any_volume), 1, ITEM_DEFAULT,     1},
+   {"catalogfiles",    store_yesno,   ITEM(res_pool.catalog_files),  1, ITEM_DEFAULT,  1},
+   {"volumeretention", store_time,    ITEM(res_pool.VolRetention),   0, ITEM_DEFAULT, 60*60*24*365},
+   {"volumeuseduration", store_time,  ITEM(res_pool.VolUseDuration), 0, 0, 0},
+   {"autoprune",       store_yesno,   ITEM(res_pool.AutoPrune), 1, ITEM_DEFAULT, 1},
+   {"recycle",         store_yesno,   ITEM(res_pool.Recycle),     1, ITEM_DEFAULT, 1},
    {NULL, NULL, NULL, 0, 0, 0}
 };
 
@@ -338,6 +340,7 @@ RES_TABLE resources[] = {
    {"counter",       counter_items, R_COUNTER},
    {"console",       con_items,   R_CONSOLE},
    {"jobdefs",       job_items,   R_JOBDEFS},
+   {"device",        NULL,        R_DEVICE},  /* info obtained from SD */
    {NULL,           NULL,        0}
 };
 
@@ -374,6 +377,19 @@ struct s_jt jobtypes[] = {
    {NULL,           0}
 };
 
+/* 
+ * Tape Label types permitted in Pool records 
+ *
+ *   tape label      label code = token
+ */
+struct s_kw tapelabels[] = {
+   {"bacula",        B_BACULA_LABEL},
+   {"ansi",          B_ANSI_LABEL},
+   {"ibm",           B_IBM_LABEL},
+   {NULL,           0}
+};
+
+
 #ifdef old_deprecated_code
 
 /* Keywords (RHS) permitted in Backup and Verify records */
@@ -427,6 +443,7 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
    URES *res = (URES *)reshdr;
    bool recurse = true;
    char ed1[100], ed2[100];
+   DEVICE *dev;
 
    if (res == NULL) {
       sendit(sock, "No %s resource defined\n", res_to_str(type));
@@ -484,12 +501,22 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
         dump_resource(-R_CATALOG, (RES *)res->res_client.catalog, sendit, sock);
       }
       break;
+   case R_DEVICE:
+      dev = &res->res_dev;
+      sendit(sock, "Device: name=%s ok=%d num_writers=%d num_waiting=%d\n"
+"      use_cnt=%d open=%d append=%d read=%d labeled=%d\n"
+"      volname=%s MediaType=%s\n",
+        dev->hdr.name, dev->found, dev->num_writers, dev->num_waiting,
+        dev->use_count, dev->open, dev->append, dev->read, dev->labeled,
+        dev->VolumeName, dev->MediaType);
+      break;
    case R_STORAGE:
       sendit(sock, "Storage: name=%s address=%s SDport=%d MaxJobs=%u\n"
 "      DeviceName=%s MediaType=%s\n",
         res->res_store.hdr.name, res->res_store.address, res->res_store.SDport,
         res->res_store.MaxConcurrentJobs,
-        res->res_store.dev_name, res->res_store.media_type);
+        res->res_store.dev_name(),
+        res->res_store.media_type);
       break;
    case R_CATALOG:
       sendit(sock, "Catalog: name=%s address=%s DBport=%d db_name=%s\n"
@@ -539,10 +566,12 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
       if (res->res_job.WriteBootstrap) {
          sendit(sock, "  --> WriteBootstrap=%s\n", NPRT(res->res_job.WriteBootstrap));
       }
-      if (res->res_job.storage[0]) {
-         sendit(sock, "  --> ");
-        /* ***FIXME*** */
-//        dump_resource(-R_STORAGE, (RES *)res->res_job.storage, sendit, sock);
+      if (res->res_job.storage) {
+        STORE *store;
+        foreach_alist(store, res->res_job.storage) {
+            sendit(sock, "  --> ");
+           dump_resource(-R_STORAGE, (RES *)store, sendit, sock);
+        }
       }
       if (res->res_job.pool) {
          sendit(sock, "  --> ");
@@ -832,6 +861,7 @@ void free_resource(RES *sres, int type)
         free_addresses(res->res_dir.DIRaddrs);
       }
       break;
+   case R_DEVICE:
    case R_COUNTER:
        break;
    case R_CONSOLE:
@@ -863,8 +893,8 @@ void free_resource(RES *sres, int type)
       if (res->res_store.media_type) {
         free(res->res_store.media_type);
       }
-      if (res->res_store.dev_name) {
-        free(res->res_store.dev_name);
+      if (res->res_store.device) {
+        delete res->res_store.device;
       }
       break;
    case R_CATALOG:
@@ -948,10 +978,8 @@ void free_resource(RES *sres, int type)
       if (res->res_job.ClientRunAfterJob) {
         free(res->res_job.ClientRunAfterJob);
       }
-      for (int i=0; i < MAX_STORE; i++) {
-        if (res->res_job.storage[i]) {
-           delete (alist *)res->res_job.storage[i];
-        }
+      if (res->res_job.storage) {
+        delete res->res_job.storage;
       }
       break;
    case R_MSGS:
@@ -987,7 +1015,7 @@ void save_resource(int type, RES_ITEM *items, int pass)
    URES *res;
    int rindex = type - r_first;
    int i, size;
-   int error = 0;
+   bool error = false;
 
    /* Check Job requirements after applying JobDefs */
    if (type != R_JOB && type != R_JOBDEFS) {
@@ -1019,19 +1047,27 @@ void save_resource(int type, RES_ITEM *items, int pass)
       /* Resources not containing a resource */
       case R_CONSOLE:
       case R_CATALOG:
-      case R_STORAGE:
       case R_POOL:
       case R_MSGS:
       case R_FILESET:
+      case R_DEVICE:
         break;
 
-      /* Resources containing another resource */
+      /* Resources containing another resource or alist */
       case R_DIRECTOR:
         if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) {
             Emsg1(M_ERROR_TERM, 0, "Cannot find Director resource %s\n", res_all.res_dir.hdr.name);
         }
         res->res_dir.messages = res_all.res_dir.messages;
         break;
+      case R_STORAGE:
+        if ((res = (URES *)GetResWithName(type, res_all.res_store.hdr.name)) == NULL) {
+            Emsg1(M_ERROR_TERM, 0, "Cannot find Storage resource %s\n",
+                 res_all.res_dir.hdr.name);
+        }
+        /* we must explicitly copy the device alist pointer */
+        res->res_store.device   = res_all.res_store.device;
+        break;
       case R_JOB:
       case R_JOBDEFS:
         if ((res = (URES *)GetResWithName(type, res_all.res_dir.hdr.name)) == NULL) {
@@ -1042,9 +1078,7 @@ void save_resource(int type, RES_ITEM *items, int pass)
         res->res_job.schedule   = res_all.res_job.schedule;
         res->res_job.client     = res_all.res_job.client;
         res->res_job.fileset    = res_all.res_job.fileset;
-        for (int i=0; i < MAX_STORE; i++) {
-           res->res_job.storage[i] = res_all.res_job.storage[i];
-        }
+        res->res_job.storage    = res_all.res_job.storage;
         res->res_job.pool       = res_all.res_job.pool;
         res->res_job.full_pool  = res_all.res_job.full_pool;
         res->res_job.inc_pool   = res_all.res_job.inc_pool;
@@ -1080,7 +1114,7 @@ void save_resource(int type, RES_ITEM *items, int pass)
         break;
       default:
          Emsg1(M_ERROR, 0, "Unknown resource type %d in save_resource.\n", type);
-        error = 1;
+        error = true;
         break;
       }
       /* Note, the resource name was already saved during pass 1,
@@ -1135,10 +1169,12 @@ void save_resource(int type, RES_ITEM *items, int pass)
    case R_COUNTER:
       size = sizeof(COUNTER);
       break;
+   case R_DEVICE:
+      error = true;
+      break;
    default:
       printf("Unknown resource type %d in save_resrouce.\n", type);
-      error = 1;
-      size = 1;
+      error = true; 
       break;
    }
    /* Common */
@@ -1166,6 +1202,55 @@ void save_resource(int type, RES_ITEM *items, int pass)
    }
 }
 
+/*
+ * Store Device. Note, the resource is created upon the
+ *  first reference. The details of the resource are obtained
+ *  later from the SD.
+ */
+static void store_device(LEX *lc, RES_ITEM *item, int index, int pass)
+{
+   int token;
+   URES *res;
+   int rindex = R_DEVICE - r_first;
+   int size = sizeof(DEVICE);
+   bool found = false;
+
+   if (pass == 1) {
+      token = lex_get_token(lc, T_NAME);
+      if (!res_head[rindex]) {
+        res = (URES *)malloc(size);
+        memset(res, 0, size);
+        res->res_dev.hdr.name = bstrdup(lc->str);
+        res_head[rindex] = (RES *)res; /* store first entry */
+         Dmsg3(900, "Inserting first %s res: %s index=%d\n", res_to_str(R_DEVICE),
+              res->res_dir.hdr.name, rindex);
+      } else {
+        RES *next;
+        /* See if it is already defined */
+        for (next=res_head[rindex]; next->next; next=next->next) {
+           if (strcmp(next->name, lc->str) == 0) {
+              found = true;
+              break;
+           }
+        }
+        if (!found) {
+           res = (URES *)malloc(size);
+           memset(res, 0, size);
+           res->res_dev.hdr.name = bstrdup(lc->str);
+           next->next = (RES *)res;
+            Dmsg4(900, "Inserting %s res: %s index=%d pass=%d\n", res_to_str(R_DEVICE),
+              res->res_dir.hdr.name, rindex, pass);
+        }
+      }
+
+      scan_to_eol(lc);
+      set_bit(index, res_all.hdr.item_present);
+   } else {
+      store_alist_res(lc, item, index, pass);
+   }
+}
+
+
 /*
  * Store JobType (backup, verify, restore)
  *
@@ -1214,6 +1299,33 @@ void store_level(LEX *lc, RES_ITEM *item, int index, int pass)
    set_bit(index, res_all.hdr.item_present);
 }
 
+
+/*
+ * Store Tape Label Type (Bacula, ANSI, IBM)
+ *
+ */
+void store_label(LEX *lc, RES_ITEM *item, int index, int pass)
+{
+   int token, i;
+
+   token = lex_get_token(lc, T_NAME);
+   /* Store the label pass 2 so that type is defined */
+   for (i=0; tapelabels[i].name; i++) {
+      if (strcasecmp(lc->str, tapelabels[i].name) == 0) {
+        *(int *)(item->value) = tapelabels[i].token;
+        i = 0;
+        break;
+      }
+   }
+   if (i != 0) {
+      scan_err1(lc, "Expected a Tape Label keyword, got: %s", lc->str);
+   }
+   scan_to_eol(lc);
+   set_bit(index, res_all.hdr.item_present);
+}
+
+
+
 void store_replace(LEX *lc, RES_ITEM *item, int index, int pass)
 {
    int token, i;
index 084257de233b8a0453e9344dc18c52bd3c08cb5b..b1542aa1b3fae741d1012f649ba80fbac962cbbe 100644 (file)
@@ -43,8 +43,9 @@ enum {
    R_COUNTER,
    R_CONSOLE,
    R_JOBDEFS,
+   R_DEVICE,
    R_FIRST = R_DIRECTOR,
-   R_LAST  = R_JOBDEFS               /* keep this updated */
+   R_LAST  = R_DEVICE                 /* keep this updated */
 };
 
 
@@ -68,9 +69,9 @@ struct s_kw {
 
 /* Job Level keyword structure */
 struct s_jl {
-   const char *level_name;                 /* level keyword */
-   int level;                        /* level */
-   int job_type;                     /* JobType permitting this level */
+   const char *level_name;                  /* level keyword */
+   int  level;                        /* level */
+   int  job_type;                     /* JobType permitting this level */
 };
 
 /* Job Type keyword structure */
@@ -86,28 +87,53 @@ struct CLIENT;
 struct FILESET;
 struct POOL;
 struct RUN;
+struct DEVICE;
 
 /*
  *   Director Resource
  *
  */
-struct DIRRES {
-   RES  hdr;
+class DIRRES {
+public:
+   RES   hdr;
    dlist *DIRaddrs;
-   char *password;                   /* Password for UA access */
-   int enable_ssl;                   /* Use SSL for UA */
-   char *query_file;                 /* SQL query file */
-   char *working_directory;          /* WorkingDirectory */
+   char *password;                    /* Password for UA access */
+   int enable_ssl;                    /* Use SSL for UA */
+   char *query_file;                  /* SQL query file */
+   char *working_directory;           /* WorkingDirectory */
    const char *scripts_directory;     /* ScriptsDirectory */
-   char *pid_directory;              /* PidDirectory */
-   char *subsys_directory;           /* SubsysDirectory */
-   int require_ssl;                  /* Require SSL for all connections */
-   MSGS *messages;                   /* Daemon message handler */
-   uint32_t MaxConcurrentJobs;       /* Max concurrent jobs for whole director */
-   utime_t FDConnectTimeout;         /* timeout for connect in seconds */
-   utime_t SDConnectTimeout;         /* timeout in seconds */
+   char *pid_directory;               /* PidDirectory */
+   char *subsys_directory;            /* SubsysDirectory */
+   int require_ssl;                   /* Require SSL for all connections */
+   MSGS *messages;                    /* Daemon message handler */
+   uint32_t MaxConcurrentJobs;        /* Max concurrent jobs for whole director */
+   utime_t FDConnectTimeout;          /* timeout for connect in seconds */
+   utime_t SDConnectTimeout;          /* timeout in seconds */
 };
 
+/*
+ * Device Resource
+ *  This resource is a bit different from the other resources
+ *  because it is not defined in the Director 
+ *  by DEVICE { ... }, but rather by a "reference" such as
+ *  DEVICE = xxx; Then when the Director connects to the
+ *  SD, it requests the information about the device.
+ */
+class DEVICE {
+public:
+   RES hdr;
+
+   bool found;                        /* found with SD */
+   int num_writers;
+   int num_waiting;
+   int use_count;
+   bool open;
+   bool append;                       /* in append mode */
+   bool read;
+   bool labeled;
+   char VolumeName[MAX_NAME_LENGTH];
+   char MediaType[MAX_NAME_LENGTH];
+};
 
 /*
  * Console ACL positions
@@ -122,17 +148,18 @@ enum {
    Command_ACL,
    FileSet_ACL,
    Catalog_ACL,
-   Num_ACL                           /* keep last */
+   Num_ACL                            /* keep last */
 };
 
 /*
  *    Console Resource
  */
-struct CONRES {
-   RES  hdr;
-   char *password;                   /* UA server password */
-   int enable_ssl;                   /* Use SSL */
-   alist *ACL_lists[Num_ACL];        /* pointers to ACLs */
+class CONRES {
+public:
+   RES   hdr;
+   char *password;                    /* UA server password */
+   int enable_ssl;                    /* Use SSL */
+   alist *ACL_lists[Num_ACL];         /* pointers to ACLs */
 };
 
 
@@ -140,16 +167,17 @@ struct CONRES {
  *   Catalog Resource
  *
  */
-struct CAT {
-   RES  hdr;
+class CAT {
+public:
+   RES   hdr;
 
-   int  db_port;                     /* Port -- not yet implemented */
-   char *db_address;                 /* host name for remote access */
-   char *db_socket;                  /* Socket for local access */
+   int   db_port;                     /* Port -- not yet implemented */
+   char *db_address;                  /* host name for remote access */
+   char *db_socket;                   /* Socket for local access */
    char *db_password;
    char *db_user;
    char *db_name;
-   int  mult_db_connections;         /* set if multiple connections wanted */
+   int   mult_db_connections;         /* set if multiple connections wanted */
 };
 
 
@@ -157,135 +185,148 @@ struct CAT {
  *   Client Resource
  *
  */
-struct CLIENT {
-   RES  hdr;
-
-   int  FDport;                      /* Where File daemon listens */
-   int  AutoPrune;                   /* Do automatic pruning? */
-   utime_t FileRetention;            /* file retention period in seconds */
-   utime_t JobRetention;             /* job retention period in seconds */
+class CLIENT {
+public:
+   RES   hdr;
+
+   int   FDport;                      /* Where File daemon listens */
+   int   AutoPrune;                   /* Do automatic pruning? */
+   utime_t FileRetention;             /* file retention period in seconds */
+   utime_t JobRetention;              /* job retention period in seconds */
    char *address;
    char *password;
-   CAT *catalog;                     /* Catalog resource */
-   uint32_t MaxConcurrentJobs;       /* Maximume concurrent jobs */
-   uint32_t NumConcurrentJobs;       /* number of concurrent jobs running */
-   int enable_ssl;                   /* Use SSL */
+   CAT *catalog;                      /* Catalog resource */
+   uint32_t MaxConcurrentJobs;        /* Maximume concurrent jobs */
+   uint32_t NumConcurrentJobs;        /* number of concurrent jobs running */
+   int enable_ssl;                    /* Use SSL */
 };
 
 /*
  *   Store Resource
  *
  */
-struct STORE {
-   RES  hdr;
+class STORE {
+public:
+   RES   hdr;
 
-   int  SDport;                      /* port where Directors connect */
-   int  SDDport;                     /* data port for File daemon */
+   int   SDport;                      /* port where Directors connect */
+   int   SDDport;                     /* data port for File daemon */
    char *address;
    char *password;
    char *media_type;
-   char *dev_name;
-   int autochanger;                  /* set if autochanger */
-   uint32_t MaxConcurrentJobs;       /* Maximume concurrent jobs */
-   uint32_t NumConcurrentJobs;       /* number of concurrent jobs running */
-   int enable_ssl;                   /* Use SSL */
+   alist *device;                     /* Device name(s) */
+   int  autochanger;                  /* set if autochanger */
+   uint32_t MaxConcurrentJobs;        /* Maximume concurrent jobs */
+   uint32_t NumConcurrentJobs;        /* number of concurrent jobs running */
+   int enable_ssl;                    /* Use SSL */
+
+   char *dev_name() const;
+   char *name() const;
 };
 
+inline char *STORE::dev_name() const
+{ 
+   DEVICE *dev = (DEVICE *)device->first();
+   return dev->hdr.name;
+}
+
+inline char *STORE::name() const { return hdr.name; }
 
-#define MAX_STORE 2                  /* Max storage directives in Job */
 
 /*
  *   Job Resource
  */
-struct JOB {
-   RES  hdr;
-
-   int  JobType;                     /* job type (backup, verify, restore */
-   int  JobLevel;                    /* default backup/verify level */
-   int  Priority;                    /* Job priority */
-   int  RestoreJobId;                /* What -- JobId to restore */
-   char *RestoreWhere;               /* Where on disk to restore -- directory */
-   char *RestoreBootstrap;           /* Bootstrap file */
-   char *RunBeforeJob;               /* Run program before Job */
-   char *RunAfterJob;                /* Run program after Job */
-   char *RunAfterFailedJob;          /* Run program after Job that errs */
-   char *ClientRunBeforeJob;         /* Run client program before Job */
-   char *ClientRunAfterJob;          /* Run client program after Job */
-   char *WriteBootstrap;             /* Where to write bootstrap Job updates */
-   int  replace;                     /* How (overwrite, ..) */
-   utime_t MaxRunTime;               /* max run time in seconds */
-   utime_t MaxWaitTime;              /* max blocking time in seconds */
-   utime_t MaxStartDelay;            /* max start delay in seconds */
-   int PrefixLinks;                  /* prefix soft links with Where path */
-   int PruneJobs;                    /* Force pruning of Jobs */
-   int PruneFiles;                   /* Force pruning of Files */
-   int PruneVolumes;                 /* Force pruning of Volumes */
-   int SpoolAttributes;              /* Set to spool attributes in SD */
-   int spool_data;                   /* Set to spool data in SD */
-   int rerun_failed_levels;          /* Upgrade to rerun failed levels */
-   uint32_t MaxConcurrentJobs;       /* Maximume concurrent jobs */
-   int RescheduleOnError;            /* Set to reschedule on error */
-   int RescheduleTimes;              /* Number of times to reschedule job */
-   utime_t RescheduleInterval;       /* Reschedule interval */
-   utime_t JobRetention;             /* job retention period in seconds */
-   bool write_part_after_job;        /* Set to write part after job in SD */
+class JOB {
+public:
+   RES   hdr;
+
+   int   JobType;                     /* job type (backup, verify, restore */
+   int   JobLevel;                    /* default backup/verify level */
+   int   Priority;                    /* Job priority */
+   int   RestoreJobId;                /* What -- JobId to restore */
+   char *RestoreWhere;                /* Where on disk to restore -- directory */
+   char *RestoreBootstrap;            /* Bootstrap file */
+   char *RunBeforeJob;                /* Run program before Job */
+   char *RunAfterJob;                 /* Run program after Job */
+   char *RunAfterFailedJob;           /* Run program after Job that errs */
+   char *ClientRunBeforeJob;          /* Run client program before Job */
+   char *ClientRunAfterJob;           /* Run client program after Job */
+   char *WriteBootstrap;              /* Where to write bootstrap Job updates */
+   int   replace;                     /* How (overwrite, ..) */
+   utime_t MaxRunTime;                /* max run time in seconds */
+   utime_t MaxWaitTime;               /* max blocking time in seconds */
+   utime_t MaxStartDelay;             /* max start delay in seconds */
+   int PrefixLinks;                   /* prefix soft links with Where path */
+   int PruneJobs;                     /* Force pruning of Jobs */
+   int PruneFiles;                    /* Force pruning of Files */
+   int PruneVolumes;                  /* Force pruning of Volumes */
+   int SpoolAttributes;               /* Set to spool attributes in SD */
+   int spool_data;                    /* Set to spool data in SD */
+   int rerun_failed_levels;           /* Upgrade to rerun failed levels */
+   uint32_t MaxConcurrentJobs;        /* Maximume concurrent jobs */
+   int RescheduleOnError;             /* Set to reschedule on error */
+   int RescheduleTimes;               /* Number of times to reschedule job */
+   utime_t RescheduleInterval;        /* Reschedule interval */
+   utime_t JobRetention;              /* job retention period in seconds */
+   bool write_part_after_job;         /* Set to write part after job in SD */
    
-   MSGS      *messages;              /* How and where to send messages */
-   SCHED     *schedule;              /* When -- Automatic schedule */
-   CLIENT    *client;                /* Who to backup */
-   FILESET   *fileset;               /* What to backup -- Fileset */
-   alist     *storage[MAX_STORE];     /* Where is device -- Storage daemon */
-   POOL      *pool;                  /* Where is media -- Media Pool */
-   POOL      *full_pool;             /* Pool for Full backups */
-   POOL      *inc_pool;              /* Pool for Incremental backups */
-   POOL      *dif_pool;              /* Pool for Differental backups */
-   JOB      *verify_job;             /* Job name to verify */
-   JOB      *jobdefs;                /* Job defaults */
-   uint32_t NumConcurrentJobs;       /* number of concurrent jobs running */
+   MSGS      *messages;               /* How and where to send messages */
+   SCHED     *schedule;               /* When -- Automatic schedule */
+   CLIENT    *client;                 /* Who to backup */
+   FILESET   *fileset;                /* What to backup -- Fileset */
+   alist     *storage;                /* Where is device -- Storage daemon */
+   POOL      *pool;                   /* Where is media -- Media Pool */
+   POOL      *full_pool;              /* Pool for Full backups */
+   POOL      *inc_pool;               /* Pool for Incremental backups */
+   POOL      *dif_pool;               /* Pool for Differental backups */
+   JOB       *verify_job;             /* Job name to verify */
+   JOB       *jobdefs;                /* Job defaults */
+   uint32_t NumConcurrentJobs;        /* number of concurrent jobs running */
 };
 
-#undef MAX_FOPTS
+#undef  MAX_FOPTS
 #define MAX_FOPTS 34
 
 /* File options structure */
 struct FOPTS {
-   char opts[MAX_FOPTS];             /* options string */
-   alist regex;                      /* regex string(s) */
-   alist regexdir;                   /* regex string(s) for directories */
-   alist regexfile;                  /* regex string(s) for files */
-   alist wild;                       /* wild card strings */
-   alist wilddir;                    /* wild card strings for directories */
-   alist wildfile;                   /* wild card strings for files */
-   alist base;                       /* list of base names */
-   alist fstype;                     /* file system type limitation */
-   char *reader;                     /* reader program */
-   char *writer;                     /* writer program */
+   char opts[MAX_FOPTS];              /* options string */
+   alist regex;                       /* regex string(s) */
+   alist regexdir;                    /* regex string(s) for directories */
+   alist regexfile;                   /* regex string(s) for files */
+   alist wild;                        /* wild card strings */
+   alist wilddir;                     /* wild card strings for directories */
+   alist wildfile;                    /* wild card strings for files */
+   alist base;                        /* list of base names */
+   alist fstype;                      /* file system type limitation */
+   char *reader;                      /* reader program */
+   char *writer;                      /* writer program */
 };
 
 
 /* This is either an include item or an exclude item */
 struct INCEXE {
-   FOPTS *current_opts;              /* points to current options structure */
-   FOPTS **opts_list;                /* options list */
-   int num_opts;                     /* number of options items */
-   alist name_list;                  /* filename list -- holds char * */
+   FOPTS *current_opts;               /* points to current options structure */
+   FOPTS **opts_list;                 /* options list */
+   int num_opts;                      /* number of options items */
+   alist name_list;                   /* filename list -- holds char * */
 };
 
 /*
  *   FileSet Resource
  *
  */
-struct FILESET {
-   RES  hdr;
+class FILESET {
+public:
+   RES   hdr;
 
-   bool new_include;                 /* Set if new include used */
-   INCEXE **include_items;           /* array of incexe structures */
-   int num_includes;                 /* number in array */
+   bool new_include;                  /* Set if new include used */
+   INCEXE **include_items;            /* array of incexe structures */
+   int num_includes;                  /* number in array */
    INCEXE **exclude_items;
    int num_excludes;
-   bool have_MD5;                    /* set if MD5 initialized */
-   struct MD5Context md5c;           /* MD5 of include/exclude */
-   char MD5[30];                     /* base 64 representation of MD5 */
+   bool have_MD5;                     /* set if MD5 initialized */
+   struct MD5Context md5c;            /* MD5 of include/exclude */
+   char MD5[30];                      /* base 64 representation of MD5 */
    int ignore_fs_changes;             /* Don't force Full if FS changed */
 };
 
@@ -294,8 +335,9 @@ struct FILESET {
  *   Schedule Resource
  *
  */
-struct SCHED {
-   RES  hdr;
+class SCHED {
+public:
+   RES   hdr;
 
    RUN *run;
 };
@@ -303,45 +345,50 @@ struct SCHED {
 /*
  *   Counter Resource
  */
-struct COUNTER {
-   RES  hdr;
-
-   int32_t  MinValue;                /* Minimum value */
-   int32_t  MaxValue;                /* Maximum value */
-   int32_t  CurrentValue;            /* Current value */
-   COUNTER *WrapCounter;             /* Wrap counter name */
-   CAT    *Catalog;                  /* Where to store */
-   bool     created;                 /* Created in DB */
+class COUNTER {
+public:
+   RES   hdr;
+
+   int32_t  MinValue;                 /* Minimum value */
+   int32_t  MaxValue;                 /* Maximum value */
+   int32_t  CurrentValue;             /* Current value */
+   COUNTER *WrapCounter;              /* Wrap counter name */
+   CAT     *Catalog;                  /* Where to store */
+   bool     created;                  /* Created in DB */
 };
 
 /*
  *   Pool Resource
  *
  */
-struct POOL {
-   RES  hdr;
-
-   char *pool_type;                  /* Pool type */
-   char *label_format;               /* Label format string */
-   char *cleaning_prefix;            /* Cleaning label prefix */
-   int  use_catalog;                 /* maintain catalog for media */
-   int  catalog_files;               /* maintain file entries in catalog */
-   int  use_volume_once;             /* write on volume only once */
-   int  accept_any_volume;           /* accept any volume */
-   int  purge_oldest_volume;         /* purge oldest volume */
-   int  recycle_oldest_volume;       /* attempt to recycle oldest volume */
-   int  recycle_current_volume;      /* attempt recycle of current volume */
-   uint32_t max_volumes;             /* max number of volumes */
-   utime_t VolRetention;             /* volume retention period in seconds */
-   utime_t VolUseDuration;           /* duration volume can be used */
-   uint32_t MaxVolJobs;              /* Maximum jobs on the Volume */
-   uint32_t MaxVolFiles;             /* Maximum files on the Volume */
-   uint64_t MaxVolBytes;             /* Maximum bytes on the Volume */
-   int  AutoPrune;                   /* default for pool auto prune */
-   int  Recycle;                     /* default for media recycle yes/no */
+class POOL {
+public:
+   RES   hdr;
+
+   char *pool_type;                   /* Pool type */
+   char *label_format;                /* Label format string */
+   char *cleaning_prefix;             /* Cleaning label prefix */
+   int   LabelType;                   /* Bacula/ANSI/IBM label type */
+   int   use_catalog;                 /* maintain catalog for media */
+   int   catalog_files;               /* maintain file entries in catalog */
+   int   use_volume_once;             /* write on volume only once */
+   int   accept_any_volume;           /* accept any volume */
+   int   purge_oldest_volume;         /* purge oldest volume */
+   int   recycle_oldest_volume;       /* attempt to recycle oldest volume */
+   int   recycle_current_volume;      /* attempt recycle of current volume */
+   uint32_t max_volumes;              /* max number of volumes */
+   utime_t VolRetention;              /* volume retention period in seconds */
+   utime_t VolUseDuration;            /* duration volume can be used */
+   uint32_t MaxVolJobs;               /* Maximum jobs on the Volume */
+   uint32_t MaxVolFiles;              /* Maximum files on the Volume */
+   uint64_t MaxVolBytes;              /* Maximum bytes on the Volume */
+   int   AutoPrune;                   /* default for pool auto prune */
+   int   Recycle;                     /* default for media recycle yes/no */
 };
 
 
+
+
 /* Define the Union of all the above
  * resource structure definitions.
  */
@@ -350,40 +397,42 @@ union URES {
    CONRES     res_con;
    CLIENT     res_client;
    STORE      res_store;
-   CAT       res_cat;
-   JOB       res_job;
+   CAT        res_cat;
+   JOB        res_job;
    FILESET    res_fs;
    SCHED      res_sch;
    POOL       res_pool;
    MSGS       res_msgs;
    COUNTER    res_counter;
-   RES       hdr;
+   DEVICE     res_dev;
+   RES        hdr;
 };
 
 
 
 /* Run structure contained in Schedule Resource */
-struct RUN {
-   RUN *next;                        /* points to next run record */
-   int level;                        /* level override */
-   int Priority;                     /* priority override */
+class RUN {
+public:
+   RUN *next;                         /* points to next run record */
+   int level;                         /* level override */
+   int Priority;                      /* priority override */
    int job_type;
-   bool spool_data;                  /* Data spooling override */
-   bool spool_data_set;              /* Data spooling override given */
-   bool write_part_after_job;        /* Write part after job override */
+   bool spool_data;                   /* Data spooling override */
+   bool spool_data_set;               /* Data spooling override given */
+   bool write_part_after_job;         /* Write part after job override */
    bool write_part_after_job_set;     /* Write part after job override given */
    
-   POOL *pool;                       /* Pool override */
-   POOL *full_pool;                  /* Pool override */
-   POOL *inc_pool;                   /* Pool override */
-   POOL *dif_pool;                   /* Pool override */
-   STORE *storage;                   /* Storage override */
-   MSGS *msgs;                       /* Messages override */
+   POOL *pool;                        /* Pool override */
+   POOL *full_pool;                   /* Pool override */
+   POOL *inc_pool;                    /* Pool override */
+   POOL *dif_pool;                    /* Pool override */
+   STORE *storage;                    /* Storage override */
+   MSGS *msgs;                        /* Messages override */
    char *since;
    int level_no;
-   int minute;                       /* minute to run job */
-   time_t last_run;                  /* last time run */
-   time_t next_run;                  /* next time to run */
+   int minute;                        /* minute to run job */
+   time_t last_run;                   /* last time run */
+   time_t next_run;                   /* next time to run */
    char hour[nbytes_for_bits(24)];    /* bit set for each hour */
    char mday[nbytes_for_bits(31)];    /* bit set for each day of month */
    char month[nbytes_for_bits(12)];   /* bit set for each month */
index 6eba9894e9000883acf228470997d20c8b53ba98..79a63117229d4711d2f16e83e59da959bfcabed2 100644 (file)
@@ -21,7 +21,7 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -46,6 +46,9 @@
 /* Forward referenced functions */
 static char *find_msg_start(char *msg);
 
+static char Job_status[] = "Status Job=%127s JobStatus=%d\n";
+
+
 static char OK_msg[] = "1000 OK\n";
 
 /*
@@ -75,7 +78,7 @@ int bget_dirmsg(BSOCK *bs)
 
    for (;;) {
       n = bnet_recv(bs);
-      Dmsg2(120, "bget_dirmsg %d: %s\n", n, bs->msg);
+      Dmsg2(900, "bget_dirmsg %d: %s\n", n, bs->msg);
 
       if (is_bnet_stop(bs)) {
         return n;                    /* error or terminate */
@@ -102,15 +105,15 @@ int bget_dirmsg(BSOCK *bs)
            break;
         case BNET_STATUS:
            /* *****FIXME***** Implement more completely */
-           bnet_fsend(bs, "Status OK\n");
+            bnet_fsend(bs, "Status OK\n");
            bnet_sig(bs, BNET_EOD);
            break;
         case BNET_BTIME:             /* send Bacula time */
            char ed1[50];
-           bnet_fsend(bs, "btime %s\n", edit_uint64(get_current_btime(),ed1));
+            bnet_fsend(bs, "btime %s\n", edit_uint64(get_current_btime(),ed1));
            break;
         default:
-           Emsg1(M_WARNING, 0, _("bget_dirmsg: unknown bnet signal %d\n"), bs->msglen);
+            Emsg1(M_WARNING, 0, _("bget_dirmsg: unknown bnet signal %d\n"), bs->msglen);
            return n;
         }
         continue;
@@ -128,18 +131,18 @@ int bget_dirmsg(BSOCK *bs)
        *  Try to fulfill it.
        */
       if (sscanf(bs->msg, "%020s Job=%127s ", MsgType, Job) != 2) {
-        Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
+         Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
         continue;
       }
       if (!(jcr=get_jcr_by_full_name(Job))) {
-        Emsg1(M_ERROR, 0, _("Job not found: %s\n"), bs->msg);
+         Emsg1(M_ERROR, 0, _("Job not found: %s\n"), bs->msg);
         continue;
       }
-      Dmsg1(200, "Getmsg got jcr 0x%x\n", jcr);
+      Dmsg1(900, "Getmsg got jcr 0x%x\n", jcr);
 
       /* Skip past "Jmsg Job=nnn" */
       if (!(msg=find_msg_start(bs->msg))) {
-        Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
+         Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
         free_jcr(jcr);
         continue;
       }
@@ -149,21 +152,21 @@ int bget_dirmsg(BSOCK *bs)
        *   Jmsg Job=nnn type=nnn level=nnn Message-string
        */
       if (bs->msg[0] == 'J') {           /* Job message */
-        if (sscanf(bs->msg, "Jmsg Job=%127s type=%d level=%d",
+         if (sscanf(bs->msg, "Jmsg Job=%127s type=%d level=%d",
                    Job, &type, &level) != 3) {
-           Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
+            Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
            free_jcr(jcr);
            continue;
         }
-        Dmsg1(120, "Got msg: %s\n", bs->msg);
+         Dmsg1(900, "Got msg: %s\n", bs->msg);
         skip_spaces(&msg);
         skip_nonspaces(&msg);        /* skip type=nnn */
         skip_spaces(&msg);
         skip_nonspaces(&msg);        /* skip level=nnn */
-        if (*msg == ' ') {
+         if (*msg == ' ') {
            msg++;                    /* skip leading space */
         }
-        Dmsg1(120, "Dispatch msg: %s", msg);
+         Dmsg1(900, "Dispatch msg: %s", msg);
         dispatch_message(jcr, type, level, msg);
         free_jcr(jcr);
         continue;
@@ -173,25 +176,34 @@ int bget_dirmsg(BSOCK *bs)
        *   CatReq Job=nn Catalog-Request-Message
        */
       if (bs->msg[0] == 'C') {        /* Catalog request */
-        Dmsg2(120, "Catalog req jcr 0x%x: %s", jcr, bs->msg);
+         Dmsg2(900, "Catalog req jcr 0x%x: %s", jcr, bs->msg);
         catalog_request(jcr, bs, msg);
-        Dmsg1(200, "Calling freejcr 0x%x\n", jcr);
+         Dmsg1(900, "Calling freejcr 0x%x\n", jcr);
         free_jcr(jcr);
         continue;
       }
       if (bs->msg[0] == 'U') {        /* Catalog update */
-        Dmsg2(120, "Catalog upd jcr 0x%x: %s", jcr, bs->msg);
+         Dmsg2(900, "Catalog upd jcr 0x%x: %s", jcr, bs->msg);
         catalog_update(jcr, bs, msg);
-        Dmsg1(200, "Calling freejcr 0x%x\n", jcr);
+         Dmsg1(900, "Calling freejcr 0x%x\n", jcr);
         free_jcr(jcr);
         continue;
       }
       if (bs->msg[0] == 'M') {        /* Mount request */
-        Dmsg1(120, "Mount req: %s", bs->msg);
+         Dmsg1(900, "Mount req: %s", bs->msg);
         mount_request(jcr, bs, msg);
         free_jcr(jcr);
         continue;
       }
+      if (bs->msg[0] == 'S') {       /* Status change */
+        int JobStatus;
+        char Job[MAX_NAME_LENGTH];
+        if (sscanf(bs->msg, Job_status, &Job, &JobStatus) == 2) {
+           jcr->SDJobStatus = JobStatus; /* current status */
+           free_jcr(jcr);
+           continue;
+        }
+      }
       return n;
    }
 }
@@ -208,31 +220,32 @@ static char *find_msg_start(char *msg)
 }
 
 /*
- * Get response from File daemon to a command we
+ * Get response from FD or SD to a command we
  * sent. Check that the response agrees with what we expect.
  *
- *  Returns: 0 on failure
- *          1 on success
+ *  Returns: false on failure
+ *          true  on success
  */
-int response(JCR *jcr, BSOCK *fd, char *resp, const char *cmd, e_prtmsg prtmsg)
+bool response(JCR *jcr, BSOCK *bs, char *resp, const char *cmd, e_prtmsg prtmsg)
 {
    int n;
 
-   if (is_bnet_error(fd)) {
-      return 0;
+   if (is_bnet_error(bs)) {
+      return false;
    }
-   if ((n = bget_dirmsg(fd)) >= 0) {
-      Dmsg0(110, fd->msg);
-      if (strcmp(fd->msg, resp) == 0) {
-        return 1;
+   if ((n = bget_dirmsg(bs)) >= 0) {
+      Dmsg0(900, bs->msg);
+      if (strcmp(bs->msg, resp) == 0) {
+        return true;
       }
+      Dmsg1(900, "Bad response: ERR=%s", bs->msg);
       if (prtmsg == DISPLAY_ERROR) {
-        Jmsg(jcr, M_FATAL, 0, _("FD gave bad response to %s command: wanted %s got: %s\n"),
-           cmd, resp, fd->msg);
+         Jmsg(jcr, M_FATAL, 0, _("Bad response to %s command: wanted %s got: %s\n"),
+           cmd, resp, bs->msg);
       }
-      return 0;
+      return false;
    }
-   Jmsg(jcr, M_FATAL, 0, _("Socket error from Filed on %s command: ERR=%s\n"),
-        cmd, bnet_strerror(fd));
-   return 0;
+   Jmsg(jcr, M_FATAL, 0, _("Socket error on %s command: ERR=%s\n"),
+        cmd, bnet_strerror(bs));
+   return false;
 }
index 6f30607143a22f597f92144c351d28e12bda7eed..51f4ced8b8bb338a4aa40235489eb303d41d932a 100644 (file)
@@ -323,7 +323,7 @@ void store_inc(LEX *lc, RES_ITEM *item, int index, int pass)
    }
 
    if (!inc_opts[0]) {
-      strcat(inc_opts, "0");          /* set no options */
+      bstrncat(inc_opts, "0", sizeof(inc_opts));   /* set no options */
    }
    inc_opts_len = strlen(inc_opts);
 
index de88b1e9141efe930dcaa540d74fe9899b298b18..1107ef425b1049a790144075acc146873fe7ac4a 100644 (file)
@@ -134,6 +134,15 @@ JobId_t run_job(JCR *jcr)
 
    Dmsg4(100, "Created job record JobId=%d Name=%s Type=%c Level=%c\n",
        jcr->JobId, jcr->Job, jcr->jr.JobType, jcr->jr.JobLevel);
+
+   if (!get_or_create_client_record(jcr)) {
+      goto bail_out;
+   }
+
+   if (!jcr->fname) {
+      jcr->fname = get_pool_memory(PM_FNAME);
+   }
+
    Dmsg0(200, "Add jrc to work queue\n");
 
    /* Queue the job to be run */
@@ -343,7 +352,7 @@ int cancel_job(UAContext *ua, JCR *jcr)
 
       /* Cancel Storage daemon */
       if (jcr->store_bsock) {
-        if (!ua->jcr->storage[0]) {
+        if (!ua->jcr->storage) {
            copy_storage(ua->jcr, jcr);
         } else {
            set_storage(ua->jcr, jcr->store);
@@ -381,7 +390,7 @@ static void job_monitor_watchdog(watchdog_t *self)
 
    control_jcr = (JCR *)self->data;
 
-   Dmsg1(400, "job_monitor_watchdog %p called\n", self);
+   Dmsg1(800, "job_monitor_watchdog %p called\n", self);
 
    lock_jcr_chain();
 
@@ -389,7 +398,7 @@ static void job_monitor_watchdog(watchdog_t *self)
       bool cancel;
 
       if (jcr->JobId == 0) {
-         Dmsg2(400, "Skipping JCR %p (%s) with JobId 0\n",
+         Dmsg2(800, "Skipping JCR %p (%s) with JobId 0\n",
               jcr, jcr->Job);
         /* Keep reference counts correct */
         free_locked_jcr(jcr);
@@ -403,7 +412,7 @@ static void job_monitor_watchdog(watchdog_t *self)
       cancel |= job_check_maxruntime(control_jcr, jcr);
 
       if (cancel) {
-         Dmsg3(200, "Cancelling JCR %p jobid %d (%s)\n",
+         Dmsg3(800, "Cancelling JCR %p jobid %d (%s)\n",
               jcr, jcr->JobId, jcr->Job);
 
         UAContext *ua = new_ua_context(jcr);
@@ -411,7 +420,7 @@ static void job_monitor_watchdog(watchdog_t *self)
         cancel_job(ua, jcr);
         free_ua_context(ua);
 
-         Dmsg1(200, "Have cancelled JCR %p\n", jcr);
+         Dmsg1(800, "Have cancelled JCR %p\n", jcr);
       }
 
       /* Keep reference counts correct */
@@ -432,11 +441,11 @@ static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr)
       return false;
    }
    if ((watchdog_time - jcr->start_time) < jcr->job->MaxWaitTime) {
-      Dmsg3(200, "Job %p (%s) with MaxWaitTime %d not expired\n",
+      Dmsg3(800, "Job %p (%s) with MaxWaitTime %d not expired\n",
            jcr, jcr->Job, jcr->job->MaxWaitTime);
       return false;
    }
-   Dmsg3(200, "Job %d (%s): MaxWaitTime of %d seconds exceeded, "
+   Dmsg3(800, "Job %d (%s): MaxWaitTime of %d seconds exceeded, "
          "checking status\n",
         jcr->JobId, jcr->Job, jcr->job->MaxWaitTime);
    switch (jcr->JobStatus) {
@@ -454,16 +463,16 @@ static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr)
       Dmsg0(200, "JCR blocked in #1\n");
       break;
    case JS_Running:
-      Dmsg0(200, "JCR running, checking SD status\n");
+      Dmsg0(800, "JCR running, checking SD status\n");
       switch (jcr->SDJobStatus) {
       case JS_WaitMount:
       case JS_WaitMedia:
       case JS_WaitFD:
         cancel = true;
-         Dmsg0(200, "JCR blocked in #2\n");
+         Dmsg0(800, "JCR blocked in #2\n");
         break;
       default:
-         Dmsg0(200, "JCR not blocked in #2\n");
+         Dmsg0(800, "JCR not blocked in #2\n");
         break;
       }
       break;
@@ -471,13 +480,13 @@ static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr)
    case JS_ErrorTerminated:
    case JS_Canceled:
    case JS_FatalError:
-      Dmsg0(200, "JCR already dead in #3\n");
+      Dmsg0(800, "JCR already dead in #3\n");
       break;
    default:
       Jmsg1(jcr, M_ERROR, 0, _("Unhandled job status code %d\n"),
            jcr->JobStatus);
    }
-   Dmsg3(200, "MaxWaitTime result: %scancel JCR %p (%s)\n",
+   Dmsg3(800, "MaxWaitTime result: %scancel JCR %p (%s)\n",
          cancel ? "" : "do not ", jcr, jcr->job);
 
    return cancel;
@@ -727,10 +736,8 @@ void dird_free_jcr(JCR *jcr)
       pthread_cond_destroy(&jcr->term_wait);
    }
    /* Delete lists setup to hold storage pointers */
-   for (int i=0; i<MAX_STORE; i++) {
-      if (jcr->storage[i]) {
-        delete jcr->storage[i];
-      }
+   if (jcr->storage) {
+      delete jcr->storage;
    }
    jcr->job_end_push.destroy();
    Dmsg0(200, "End dird free_jcr\n");
@@ -745,6 +752,7 @@ void dird_free_jcr(JCR *jcr)
  */
 void set_jcr_defaults(JCR *jcr, JOB *job)
 {
+   STORE *st;
    jcr->job = job;
    jcr->JobType = job->JobType;
    switch (jcr->JobType) {
@@ -758,20 +766,17 @@ void set_jcr_defaults(JCR *jcr, JOB *job)
    }
    jcr->JobPriority = job->Priority;
    /* Copy storage definitions -- deleted in dir_free_jcr above */
-   for (int i=0; i < MAX_STORE; i++) {
-      STORE *st;
-      if (job->storage[i]) {
-        if (jcr->storage[i]) {
-           delete jcr->storage[i];
-        }
-        jcr->storage[i] = New(alist(10, not_owned_by_alist));
-        foreach_alist(st, job->storage[i]) {
-           jcr->storage[i]->append(st);
-        }
+   if (job->storage) {
+      if (jcr->storage) {
+        delete jcr->storage;
+      }
+      jcr->storage = New(alist(10, not_owned_by_alist));
+      foreach_alist(st, job->storage) {
+        jcr->storage->append(st);
       }
    }
-   if (jcr->storage[0]) {
-      jcr->store = (STORE *)jcr->storage[0]->first();
+   if (jcr->storage) {
+      jcr->store = (STORE *)jcr->storage->first();
    }
    jcr->client = job->client;
    if (!jcr->client_name) {
@@ -821,28 +826,34 @@ void set_jcr_defaults(JCR *jcr, JOB *job)
  */
 void copy_storage(JCR *new_jcr, JCR *old_jcr)
 {
-   for (int i=0; i < MAX_STORE; i++) {
-      if (old_jcr->storage[i]) {
-        STORE *st;
-        if (old_jcr->storage[i]) {
-           delete old_jcr->storage[i];
-        }
-        new_jcr->storage[i] = New(alist(10, not_owned_by_alist));
-        foreach_alist(st, old_jcr->storage[i]) {
-           new_jcr->storage[i]->append(st);
-        }
+   if (old_jcr->storage) {
+      STORE *st;
+      if (old_jcr->storage) {
+        delete old_jcr->storage;
       }
-      if (old_jcr->store) {
-        new_jcr->store = old_jcr->store;
-      } else if (new_jcr->storage[0]) {
-        new_jcr->store = (STORE *)new_jcr->storage[0]->first();
+      new_jcr->storage = New(alist(10, not_owned_by_alist));
+      foreach_alist(st, old_jcr->storage) {
+        new_jcr->storage->append(st);
       }
    }
+   if (old_jcr->store) {
+      new_jcr->store = old_jcr->store;
+   } else if (new_jcr->storage) {
+      new_jcr->store = (STORE *)new_jcr->storage->first();
+   }
 }
 
 /* Set storage override */
 void set_storage(JCR *jcr, STORE *store)
 {
+   STORE *storage;
+
    jcr->store = store;
-   jcr->storage[0]->prepend(store);
+   foreach_alist(storage, jcr->storage) {
+      if (store == storage) {
+        return;
+      }
+   }
+   /* Store not in list, so add it */
+   jcr->storage->prepend(store);
 }
index 4ca44bc37acb3553a89e648df9892426fb8c9e15..eea66c004acb22c79241d9ee06a0398271949b18 100755 (executable)
@@ -18,7 +18,7 @@
  *
  */
 /*
-   Copyright (C) 2003-2004 Kern Sibbald
+   Copyright (C) 2003-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
@@ -170,7 +170,7 @@ void *sched_wait(void *arg)
    JCR *jcr = ((wait_pkt *)arg)->jcr;
    jobq_t *jq = ((wait_pkt *)arg)->jq;
 
-   Dmsg0(300, "Enter sched_wait.\n");
+   Dmsg0(2300, "Enter sched_wait.\n");
    free(arg);
    time_t wtime = jcr->sched_time - time(NULL);
    set_jcr_job_status(jcr, JS_WaitStartTime);
@@ -181,7 +181,7 @@ void *sched_wait(void *arg)
    }
    /* Check every 30 seconds if canceled */
    while (wtime > 0) {
-      Dmsg2(300, "Waiting on sched time, jobid=%d secs=%d\n", jcr->JobId, wtime);
+      Dmsg2(2300, "Waiting on sched time, jobid=%d secs=%d\n", jcr->JobId, wtime);
       if (wtime > 30) {
         wtime = 30;
       }
@@ -195,7 +195,7 @@ void *sched_wait(void *arg)
    jobq_add(jq, jcr);
    V(jcr->mutex);
    free_jcr(jcr);                    /* we are done with jcr */
-   Dmsg0(300, "Exit sched_wait\n");
+   Dmsg0(2300, "Exit sched_wait\n");
    return NULL;
 }
 
@@ -215,14 +215,14 @@ int jobq_add(jobq_t *jq, JCR *jcr)
    pthread_t id;
    wait_pkt *sched_pkt;
 
-   Dmsg3(300, "jobq_add jobid=%d jcr=0x%x use_count=%d\n", jcr->JobId, jcr, jcr->use_count);
+   Dmsg3(2300, "jobq_add jobid=%d jcr=0x%x use_count=%d\n", jcr->JobId, jcr, jcr->use_count);
    if (jq->valid != JOBQ_VALID) {
       Jmsg0(jcr, M_ERROR, 0, "Jobq_add queue not initialized.\n");
       return EINVAL;
    }
 
    jcr->use_count++;                 /* mark jcr in use by us */
-   Dmsg3(300, "jobq_add jobid=%d jcr=0x%x use_count=%d\n", jcr->JobId, jcr, jcr->use_count);
+   Dmsg3(2300, "jobq_add jobid=%d jcr=0x%x use_count=%d\n", jcr->JobId, jcr, jcr->use_count);
    if (!job_canceled(jcr) && wtime > 0) {
       set_thread_concurrency(jq->max_workers + 2);
       sched_pkt = (wait_pkt *)malloc(sizeof(wait_pkt));
@@ -253,15 +253,15 @@ int jobq_add(jobq_t *jq, JCR *jcr)
    if (job_canceled(jcr)) {
       /* Add job to ready queue so that it is canceled quickly */
       jq->ready_jobs->prepend(item);
-      Dmsg1(300, "Prepended job=%d to ready queue\n", jcr->JobId);
+      Dmsg1(2300, "Prepended job=%d to ready queue\n", jcr->JobId);
    } else {
       /* Add this job to the wait queue in priority sorted order */
       foreach_dlist(li, jq->waiting_jobs) {
-        Dmsg2(300, "waiting item jobid=%d priority=%d\n",
+         Dmsg2(2300, "waiting item jobid=%d priority=%d\n",
            li->jcr->JobId, li->jcr->JobPriority);
         if (li->jcr->JobPriority > jcr->JobPriority) {
            jq->waiting_jobs->insert_before(item, li);
-           Dmsg2(300, "insert_before jobid=%d before waiting job=%d\n",
+            Dmsg2(2300, "insert_before jobid=%d before waiting job=%d\n",
               li->jcr->JobId, jcr->JobId);
            inserted = true;
            break;
@@ -270,7 +270,7 @@ int jobq_add(jobq_t *jq, JCR *jcr)
       /* If not jobs in wait queue, append it */
       if (!inserted) {
         jq->waiting_jobs->append(item);
-        Dmsg1(300, "Appended item jobid=%d to waiting queue\n", jcr->JobId);
+         Dmsg1(2300, "Appended item jobid=%d to waiting queue\n", jcr->JobId);
       }
    }
 
@@ -278,7 +278,7 @@ int jobq_add(jobq_t *jq, JCR *jcr)
    stat = start_server(jq);
 
    pthread_mutex_unlock(&jq->mutex);
-   Dmsg0(300, "Return jobq_add\n");
+   Dmsg0(2300, "Return jobq_add\n");
    return stat;
 }
 
@@ -297,7 +297,7 @@ int jobq_remove(jobq_t *jq, JCR *jcr)
    bool found = false;
    jobq_item_t *item;
 
-   Dmsg2(300, "jobq_remove jobid=%d jcr=0x%x\n", jcr->JobId, jcr);
+   Dmsg2(2300, "jobq_remove jobid=%d jcr=0x%x\n", jcr->JobId, jcr);
    if (jq->valid != JOBQ_VALID) {
       return EINVAL;
    }
@@ -316,19 +316,19 @@ int jobq_remove(jobq_t *jq, JCR *jcr)
    }
    if (!found) {
       pthread_mutex_unlock(&jq->mutex);
-      Dmsg2(300, "jobq_remove jobid=%d jcr=0x%x not in wait queue\n", jcr->JobId, jcr);
+      Dmsg2(2300, "jobq_remove jobid=%d jcr=0x%x not in wait queue\n", jcr->JobId, jcr);
       return EINVAL;
    }
 
    /* Move item to be the first on the list */
    jq->waiting_jobs->remove(item);
    jq->ready_jobs->prepend(item);
-   Dmsg2(300, "jobq_remove jobid=%d jcr=0x%x moved to ready queue\n", jcr->JobId, jcr);
+   Dmsg2(2300, "jobq_remove jobid=%d jcr=0x%x moved to ready queue\n", jcr->JobId, jcr);
 
    stat = start_server(jq);
 
    pthread_mutex_unlock(&jq->mutex);
-   Dmsg0(300, "Return jobq_remove\n");
+   Dmsg0(2300, "Return jobq_remove\n");
    return stat;
 }
 
@@ -343,14 +343,14 @@ static int start_server(jobq_t *jq)
 
    /* if any threads are idle, wake one */
    if (jq->idle_workers > 0) {
-      Dmsg0(300, "Signal worker to wake up\n");
+      Dmsg0(2300, "Signal worker to wake up\n");
       if ((stat = pthread_cond_signal(&jq->work)) != 0) {
         berrno be;
          Jmsg1(NULL, M_ERROR, 0, "pthread_cond_signal: ERR=%s\n", be.strerror(stat));
         return stat;
       }
    } else if (jq->num_workers < jq->max_workers) {
-      Dmsg0(300, "Create worker thread\n");
+      Dmsg0(2300, "Create worker thread\n");
       /* No idle threads so create a new one */
       set_thread_concurrency(jq->max_workers + 1);
       if ((stat = pthread_create(&id, &jq->attr, jobq_server, (void *)jq)) != 0) {
@@ -378,7 +378,7 @@ void *jobq_server(void *arg)
    bool timedout = false;
    bool work = true;
 
-   Dmsg0(300, "Start jobq_server\n");
+   Dmsg0(2300, "Start jobq_server\n");
    if ((stat = pthread_mutex_lock(&jq->mutex)) != 0) {
       berrno be;
       Jmsg1(NULL, M_ERROR, 0, "pthread_mutex_lock: ERR=%s\n", be.strerror(stat));
@@ -390,7 +390,7 @@ void *jobq_server(void *arg)
       struct timeval tv;
       struct timezone tz;
 
-      Dmsg0(300, "Top of for loop\n");
+      Dmsg0(2300, "Top of for loop\n");
       if (!work && !jq->quit) {
         gettimeofday(&tv, &tz);
         timeout.tv_nsec = 0;
@@ -400,15 +400,15 @@ void *jobq_server(void *arg)
            /*
             * Wait 4 seconds, then if no more work, exit
             */
-           Dmsg0(300, "pthread_cond_timedwait()\n");
+            Dmsg0(2300, "pthread_cond_timedwait()\n");
            stat = pthread_cond_timedwait(&jq->work, &jq->mutex, &timeout);
            if (stat == ETIMEDOUT) {
-              Dmsg0(300, "timedwait timedout.\n");
+               Dmsg0(2300, "timedwait timedout.\n");
               timedout = true;
               break;
            } else if (stat != 0) {
-              /* This shouldn't happen */
-              Dmsg0(300, "This shouldn't happen\n");
+               /* This shouldn't happen */
+               Dmsg0(2300, "This shouldn't happen\n");
               jq->num_workers--;
               pthread_mutex_unlock(&jq->mutex);
               return NULL;
@@ -419,14 +419,14 @@ void *jobq_server(void *arg)
       /*
        * If anything is in the ready queue, run it
        */
-      Dmsg0(300, "Checking ready queue.\n");
+      Dmsg0(2300, "Checking ready queue.\n");
       while (!jq->ready_jobs->empty() && !jq->quit) {
         JCR *jcr;
         je = (jobq_item_t *)jq->ready_jobs->first();
         jcr = je->jcr;
         jq->ready_jobs->remove(je);
         if (!jq->ready_jobs->empty()) {
-           Dmsg0(300, "ready queue not empty start server\n");
+            Dmsg0(2300, "ready queue not empty start server\n");
            if (start_server(jq) != 0) {
               jq->num_workers--;
               pthread_mutex_unlock(&jq->mutex);
@@ -434,7 +434,7 @@ void *jobq_server(void *arg)
            }
         }
         jq->running_jobs->append(je);
-         Dmsg1(300, "Took jobid=%d from ready and appended to run\n", jcr->JobId);
+         Dmsg1(2300, "Took jobid=%d from ready and appended to run\n", jcr->JobId);
 
         /* Release job queue lock */
         if ((stat = pthread_mutex_unlock(&jq->mutex)) != 0) {
@@ -445,10 +445,10 @@ void *jobq_server(void *arg)
         }
 
          /* Call user's routine here */
-         Dmsg1(300, "Calling user engine for jobid=%d\n", jcr->JobId);
+         Dmsg1(2300, "Calling user engine for jobid=%d\n", jcr->JobId);
         jq->engine(je->jcr);
 
-         Dmsg1(300, "Back from user engine jobid=%d.\n", jcr->JobId);
+         Dmsg1(2300, "Back from user engine jobid=%d.\n", jcr->JobId);
 
         /* Reacquire job queue lock */
         if ((stat = pthread_mutex_lock(&jq->mutex)) != 0) {
@@ -490,16 +490,16 @@ void *jobq_server(void *arg)
              */
            jcr->reschedule_count++;
            jcr->sched_time = time(NULL) + jcr->job->RescheduleInterval;
-           Dmsg2(300, "Rescheduled Job %s to re-run in %d seconds.\n", jcr->Job,
+            Dmsg2(2300, "Rescheduled Job %s to re-run in %d seconds.\n", jcr->Job,
               (int)jcr->job->RescheduleInterval);
            bstrftime(dt, sizeof(dt), time(NULL));
-           Jmsg(jcr, M_INFO, 0, _("Rescheduled Job %s at %s to re-run in %d seconds.\n"),
+            Jmsg(jcr, M_INFO, 0, _("Rescheduled Job %s at %s to re-run in %d seconds.\n"),
               jcr->Job, dt, (int)jcr->job->RescheduleInterval);
            dird_free_jcr(jcr);          /* partial cleanup old stuff */
            jcr->JobStatus = JS_WaitStartTime;
            jcr->SDJobStatus = 0;
            if (jcr->JobBytes == 0) {
-              Dmsg1(300, "Requeue job=%d\n", jcr->JobId);
+               Dmsg1(2300, "Requeue job=%d\n", jcr->JobId);
               jcr->JobStatus = JS_WaitStartTime;
               V(jq->mutex);
               jobq_add(jq, jcr);     /* queue the job to run again */
@@ -520,19 +520,19 @@ void *jobq_server(void *arg)
            njcr->JobStatus = jcr->JobStatus;
            copy_storage(njcr, jcr);
            njcr->messages = jcr->messages;
-           Dmsg0(300, "Call to run new job\n");
+            Dmsg0(2300, "Call to run new job\n");
            V(jq->mutex);
-           run_job(njcr);            /* This creates a "new" job */
-           free_jcr(njcr);           /* release "new" jcr */
+            run_job(njcr);            /* This creates a "new" job */
+            free_jcr(njcr);           /* release "new" jcr */
            P(jq->mutex);
-           Dmsg0(300, "Back from running new job.\n");
+            Dmsg0(2300, "Back from running new job.\n");
         }
         /* Clean up and release old jcr */
         if (jcr->db) {
            db_close_database(jcr, jcr->db);
            jcr->db = NULL;
         }
-        Dmsg2(300, "====== Termination job=%d use_cnt=%d\n", jcr->JobId, jcr->use_count);
+         Dmsg2(2300, "====== Termination job=%d use_cnt=%d\n", jcr->JobId, jcr->use_count);
         jcr->SDJobStatus = 0;
         V(jq->mutex);                /* release internal lock */
         free_jcr(jcr);
@@ -543,17 +543,17 @@ void *jobq_server(void *arg)
        * If any job in the wait queue can be run,
        *  move it to the ready queue
        */
-      Dmsg0(300, "Done check ready, now check wait queue.\n");
+      Dmsg0(2300, "Done check ready, now check wait queue.\n");
       while (!jq->waiting_jobs->empty() && !jq->quit) {
         int Priority;
         je = (jobq_item_t *)jq->waiting_jobs->first();
         jobq_item_t *re = (jobq_item_t *)jq->running_jobs->first();
         if (re) {
            Priority = re->jcr->JobPriority;
-           Dmsg2(300, "JobId %d is running. Look for pri=%d\n", re->jcr->JobId, Priority);
+            Dmsg2(2300, "JobId %d is running. Look for pri=%d\n", re->jcr->JobId, Priority);
         } else {
            Priority = je->jcr->JobPriority;
-           Dmsg1(300, "No job running. Look for Job pri=%d\n", Priority);
+            Dmsg1(2300, "No job running. Look for Job pri=%d\n", Priority);
         }
         /*
          * Walk down the list of waiting jobs and attempt
@@ -564,7 +564,7 @@ void *jobq_server(void *arg)
            JCR *jcr = je->jcr;
            bool skip_this_jcr = false;
            jobq_item_t *jn = (jobq_item_t *)jq->waiting_jobs->next(je);
-           Dmsg3(300, "Examining Job=%d JobPri=%d want Pri=%d\n",
+            Dmsg3(2300, "Examining Job=%d JobPri=%d want Pri=%d\n",
               jcr->JobId, jcr->JobPriority, Priority);
            /* Take only jobs of correct Priority */
            if (jcr->JobPriority != Priority) {
@@ -647,32 +647,32 @@ void *jobq_server(void *arg)
            jcr->acquired_resource_locks = true;
            jq->waiting_jobs->remove(je);
            jq->ready_jobs->append(je);
-           Dmsg1(300, "moved JobId=%d from wait to ready queue\n", je->jcr->JobId);
+            Dmsg1(2300, "moved JobId=%d from wait to ready queue\n", je->jcr->JobId);
            je = jn;                  /* Point to next waiting job */
         } /* end for loop */
         break;
       } /* end while loop */
-      Dmsg0(300, "Done checking wait queue.\n");
+      Dmsg0(2300, "Done checking wait queue.\n");
       /*
        * If no more ready work and we are asked to quit, then do it
        */
       if (jq->ready_jobs->empty() && jq->quit) {
         jq->num_workers--;
         if (jq->num_workers == 0) {
-           Dmsg0(300, "Wake up destroy routine\n");
+            Dmsg0(2300, "Wake up destroy routine\n");
            /* Wake up destroy routine if he is waiting */
            pthread_cond_broadcast(&jq->work);
         }
         break;
       }
-      Dmsg0(300, "Check for work request\n");
+      Dmsg0(2300, "Check for work request\n");
       /*
        * If no more work requests, and we waited long enough, quit
        */
-      Dmsg2(300, "timedout=%d read empty=%d\n", timedout,
+      Dmsg2(2300, "timedout=%d read empty=%d\n", timedout,
         jq->ready_jobs->empty());
       if (jq->ready_jobs->empty() && timedout) {
-        Dmsg0(300, "break big loop\n");
+         Dmsg0(2300, "break big loop\n");
         jq->num_workers--;
         break;
       }
@@ -701,7 +701,7 @@ void *jobq_server(void *arg)
         /* Recompute work as something may have changed in last 2 secs */
         work = !jq->ready_jobs->empty() || !jq->waiting_jobs->empty();
       }
-      Dmsg1(300, "Loop again. work=%d\n", work);
+      Dmsg1(2300, "Loop again. work=%d\n", work);
    } /* end of big for loop */
 
    Dmsg0(200, "unlock mutex\n");
@@ -709,6 +709,6 @@ void *jobq_server(void *arg)
       berrno be;
       Jmsg1(NULL, M_ERROR, 0, "pthread_mutex_unlock: ERR=%s\n", be.strerror(stat));
    }
-   Dmsg0(300, "End jobq_server\n");
+   Dmsg0(2300, "End jobq_server\n");
    return NULL;
 }
index c9853bdd68717b4bf28a0eb59404a80887733fa6..e385204a958f6a89fba2e9124a9f9c82d9bd7650 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 /*
-   Copyright (C) 2004 Kern Sibbald and John Walker
+   Copyright (C) 2004-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
@@ -77,10 +77,6 @@ bool do_mac(JCR *jcr)
       break;
    }
 
-   if (!get_or_create_client_record(jcr)) {
-      goto bail_out;
-   }
-
    if (!get_or_create_fileset_record(jcr, &fsr)) {
       goto bail_out;
    }
@@ -93,15 +89,13 @@ bool do_mac(JCR *jcr)
    Dmsg1(100, "find last jobid for: %s\n", NPRT(Name));
    if (!db_find_last_jobid(jcr, jcr->db, Name, &jr)) {
       Jmsg(jcr, M_FATAL, 0, _(
-          "Unable to find JobId of previous Job for this client.\n"));
+           "Unable to find JobId of previous Job for this client.\n"));
       goto bail_out;
    }
    input_jobid = jr.JobId;
    jcr->JobLevel = jr.JobLevel;
    Dmsg1(100, "Last jobid=%d\n", input_jobid);
 
-   jcr->fname = get_pool_memory(PM_FNAME);
-
    /*
     * Get the Pool record -- first apply any level defined pools
     */
@@ -128,11 +122,11 @@ bool do_mac(JCR *jcr)
    while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
       /* Try to create the pool */
       if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
-        Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
+         Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
            db_strerror(jcr->db));
         goto bail_out;
       } else {
-        Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
+         Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
       }
    }
    jcr->PoolId = pr.PoolId;              /****FIXME**** this can go away */
@@ -150,7 +144,6 @@ bool do_mac(JCR *jcr)
       goto bail_out;
    }
 
-
    /*
     * Open a message channel connection with the Storage
     * daemon. This is to let him know that our client
@@ -168,7 +161,7 @@ bool do_mac(JCR *jcr)
    /*
     * Now start a job with the Storage daemon
     */
-   if (!start_storage_daemon_job(jcr)) {
+   if (!start_storage_daemon_job(jcr, jcr->storage, SD_APPEND)) {
       goto bail_out;
    }
    /*
@@ -247,18 +240,18 @@ static void mac_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr,
       if (*fname == '|') {
         fname++;
         got_pipe = 1;
-        bpipe = open_bpipe(fname, 0, "w");
+         bpipe = open_bpipe(fname, 0, "w");
         fd = bpipe ? bpipe->wfd : NULL;
       } else {
         /* ***FIXME*** handle BASE */
-        fd = fopen(fname, jcr->JobLevel==L_FULL?"w+":"a+");
+         fd = fopen(fname, jcr->JobLevel==L_FULL?"w+":"a+");
       }
       if (fd) {
         VolCount = db_get_job_volume_parameters(jcr, jcr->db, jcr->JobId,
                    &VolParams);
         if (VolCount == 0) {
-           Jmsg(jcr, M_ERROR, 0, _("Could not get Job Volume Parameters to "
-                "update Bootstrap file. ERR=%s\n"), db_strerror(jcr->db));
+            Jmsg(jcr, M_ERROR, 0, _("Could not get Job Volume Parameters to "
+                 "update Bootstrap file. ERR=%s\n"), db_strerror(jcr->db));
             if (jcr->SDJobFiles != 0) {
                set_jcr_job_status(jcr, JS_ErrorTerminated);
             }
@@ -266,14 +259,15 @@ static void mac_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr,
         }
         for (int i=0; i < VolCount; i++) {
            /* Write the record */
-           fprintf(fd, "Volume=\"%s\"\n", VolParams[i].VolumeName);
-           fprintf(fd, "VolSessionId=%u\n", jcr->VolSessionId);
-           fprintf(fd, "VolSessionTime=%u\n", jcr->VolSessionTime);
-           fprintf(fd, "VolFile=%u-%u\n", VolParams[i].StartFile,
+            fprintf(fd, "Volume=\"%s\"\n", VolParams[i].VolumeName);
+            fprintf(fd, "MediaType=\"%s\"\n", VolParams[i].MediaType);
+            fprintf(fd, "VolSessionId=%u\n", jcr->VolSessionId);
+            fprintf(fd, "VolSessionTime=%u\n", jcr->VolSessionTime);
+            fprintf(fd, "VolFile=%u-%u\n", VolParams[i].StartFile,
                         VolParams[i].EndFile);
-           fprintf(fd, "VolBlock=%u-%u\n", VolParams[i].StartBlock,
+            fprintf(fd, "VolBlock=%u-%u\n", VolParams[i].StartBlock,
                         VolParams[i].EndBlock);
-           fprintf(fd, "FileIndex=%d-%d\n", VolParams[i].FirstIndex,
+            fprintf(fd, "FileIndex=%d-%d\n", VolParams[i].FirstIndex,
                         VolParams[i].LastIndex);
         }
         if (VolParams) {
@@ -286,8 +280,8 @@ static void mac_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr,
         }
       } else {
         berrno be;
-        Jmsg(jcr, M_ERROR, 0, _("Could not open WriteBootstrap file:\n"
-             "%s: ERR=%s\n"), fname, be.strerror());
+         Jmsg(jcr, M_ERROR, 0, _("Could not open WriteBootstrap file:\n"
+              "%s: ERR=%s\n"), fname, be.strerror());
         set_jcr_job_status(jcr, JS_ErrorTerminated);
       }
    }
@@ -296,14 +290,14 @@ static void mac_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr,
    switch (jcr->JobStatus) {
       case JS_Terminated:
         if (jcr->Errors || jcr->SDErrors) {
-           term_msg = _("Backup OK -- with warnings");
+            term_msg = _("Backup OK -- with warnings");
         } else {
-           term_msg = _("Backup OK");
+            term_msg = _("Backup OK");
         }
         break;
       case JS_FatalError:
       case JS_ErrorTerminated:
-        term_msg = _("*** Backup Error ***");
+         term_msg = _("*** Backup Error ***");
         msg_type = M_ERROR;          /* Generate error message */
         if (jcr->store_bsock) {
            bnet_sig(jcr->store_bsock, BNET_TERMINATE);
@@ -313,7 +307,7 @@ static void mac_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr,
         }
         break;
       case JS_Canceled:
-        term_msg = _("Backup Canceled");
+         term_msg = _("Backup Canceled");
         if (jcr->store_bsock) {
            bnet_sig(jcr->store_bsock, BNET_TERMINATE);
            if (jcr->SD_msg_chan) {
@@ -323,7 +317,7 @@ static void mac_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr,
         break;
       default:
         term_msg = term_code;
-        sprintf(term_code, _("Inappropriate term code: %c\n"), jcr->JobStatus);
+         sprintf(term_code, _("Inappropriate term code: %c\n"), jcr->JobStatus);
         break;
    }
    bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime);
@@ -342,7 +336,7 @@ static void mac_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr,
        *  normal exit should we complain about this error.
        */
       if (jcr->JobStatus == JS_Terminated && jcr->jr.JobBytes) {
-        Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
+         Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
       }
       jcr->VolumeName[0] = 0;        /* none */
    }
@@ -352,9 +346,9 @@ static void mac_cleanup(JCR *jcr, int TermCode, char *since, FILESET_DBR *fsr,
    } else {
       compression = (double)100 - 100.0 * ((double)jcr->JobBytes / (double)jcr->ReadBytes);
       if (compression < 0.5) {
-        bstrncpy(compress, "None", sizeof(compress));
+         bstrncpy(compress, "None", sizeof(compress));
       } else {
-        bsnprintf(compress, sizeof(compress), "%.1f %%", (float)compression);
+         bsnprintf(compress, sizeof(compress), "%.1f %%", (float)compression);
       }
    }
    jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
index b34e29e4c0eb869375841f751bb2ed6ce3a04238..f0d4cf84427add19c51eba7946719304ae77a010 100644 (file)
 
 /* Commands sent to Storage daemon */
 static char jobcmd[]     = "JobId=%d job=%s job_name=%s client_name=%s "
-"type=%d level=%d FileSet=%s NoAttr=%d SpoolAttr=%d FileSetMD5=%s SpoolData=%d WritePartAfterJob=%d";
-static char use_device[] = "use device=%s media_type=%s pool_name=%s pool_type=%s\n";
+   "type=%d level=%d FileSet=%s NoAttr=%d SpoolAttr=%d FileSetMD5=%s "
+   "SpoolData=%d WritePartAfterJob=%d";
+static char use_device[] = "use device=%s media_type=%s pool_name=%s "
+   "pool_type=%s append=%d\n";
+static char query_device[] = "query device=%s";
 
 /* Response from Storage daemon */
 static char OKjob[]      = "3000 OK Job SDid=%d SDtime=%d Authorization=%100s\n";
 static char OK_device[]  = "3000 OK use device\n";
+static char OK_query[]  = "3001 OK query append=%d read=%d num_writers=%d "
+   "num_waiting=%d open=%d use_count=%d labeled=%d "
+   "media_type=%127s volume_name=%127s";
 
 /* Storage Daemon requests */
 static char Job_start[]  = "3010 Job %127s start\n";
 static char Job_end[]   =
    "3099 Job %127s end JobStatus=%d JobFiles=%d JobBytes=%" lld "\n";
-static char Job_status[] = "3012 Job %127s jobstatus %d\n";
 
 /* Forward referenced functions */
 extern "C" void *msg_thread(void *arg);
@@ -66,7 +71,10 @@ bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
    BSOCK *sd;
    STORE *store;
 
-   store = (STORE *)jcr->storage[0]->first();
+   if (jcr->store_bsock) {
+      return true;                   /* already connected */
+   }
+   store = (STORE *)jcr->storage->first();
 
    /*
     *  Open message channel with the Storage daemon
@@ -83,6 +91,47 @@ bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
    jcr->store_bsock = sd;
 
    if (!authenticate_storage_daemon(jcr, store)) {
+      bnet_close(sd);
+      jcr->store_bsock = NULL;
+      return false;
+   }
+   return true;
+}
+
+/*
+ * Here we ask the SD to send us the info for a 
+ *  particular device resource.
+ */
+bool update_device_res(JCR *jcr, DEVICE *dev)
+{
+   POOL_MEM device_name, media_type, volume_name;
+   int dev_open, dev_append, dev_read, dev_labeled;
+   BSOCK *sd;
+   if (!connect_to_storage_daemon(jcr, 5, 30, 0)) {
+      return false;
+   }
+   sd = jcr->store_bsock;
+   pm_strcpy(device_name, dev->hdr.name);
+   bash_spaces(device_name);
+   bnet_fsend(sd, query_device, device_name.c_str());
+   if (bget_dirmsg(sd) > 0) {
+      Dmsg1(400, "<stored: %s", sd->msg);
+      if (sscanf(sd->msg, OK_query, &dev_append, &dev_read,
+         &dev->num_writers, &dev->num_waiting, &dev_open,
+         &dev->use_count, &dev_labeled, media_type.c_str(),
+         volume_name.c_str()) != 9) {
+        return false;
+      }
+      unbash_spaces(media_type);
+      unbash_spaces(volume_name);
+      bstrncpy(dev->MediaType, media_type.c_str(), sizeof(dev->MediaType));
+      bstrncpy(dev->VolumeName, volume_name.c_str(), sizeof(dev->VolumeName));
+      dev->open = dev_open;
+      dev->append = dev_append;
+      dev->read = dev_read;
+      dev->labeled = dev_labeled;
+      dev->found = true;
+   } else {
       return false;
    }
    return true;
@@ -91,14 +140,13 @@ bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
 /*
  * Start a job with the Storage daemon
  */
-int start_storage_daemon_job(JCR *jcr)
+int start_storage_daemon_job(JCR *jcr, alist *store, int append)
 {
-   int status = 0;
+   bool ok;
    STORE *storage;
    BSOCK *sd;
    char auth_key[100];
    POOL_MEM device_name, pool_name, pool_type, media_type;
-   int i;
 
    sd = jcr->store_bsock;
    /*
@@ -108,7 +156,7 @@ int start_storage_daemon_job(JCR *jcr)
    bash_spaces(jcr->client->hdr.name);
    bash_spaces(jcr->fileset->hdr.name);
    if (jcr->fileset->MD5[0] == 0) {
-      strcpy(jcr->fileset->MD5, "**Dummy**");
+      bstrncpy(jcr->fileset->MD5, "**Dummy**", sizeof(jcr->fileset->MD5));
    }
    bnet_fsend(sd, jobcmd, jcr->JobId, jcr->Job, jcr->job->hdr.name,
              jcr->client->hdr.name, jcr->JobType, jcr->JobLevel,
@@ -135,34 +183,32 @@ int start_storage_daemon_job(JCR *jcr)
       return 0;
    }
 
-   /*
-    * Send use device = xxx media = yyy pool = zzz
-    */
-
-   for (i=0; i < MAX_STORE; i++) {
-      if (jcr->storage[i]) {
-        storage = (STORE *)jcr->storage[i]->first();
-        pm_strcpy(device_name, storage->dev_name);
-        pm_strcpy(media_type, storage->media_type);
-        pm_strcpy(pool_type, jcr->pool->pool_type);
-        pm_strcpy(pool_name, jcr->pool->hdr.name);
-        bash_spaces(device_name);
-        bash_spaces(media_type);
-        bash_spaces(pool_type);
-        bash_spaces(pool_name);
-        bnet_fsend(sd, use_device, device_name.c_str(),
-                   media_type.c_str(), pool_name.c_str(), pool_type.c_str());
-         Dmsg1(110, ">stored: %s", sd->msg);
-         status = response(jcr, sd, OK_device, "Use Device", NO_DISPLAY);
-        if (!status) {
-           pm_strcpy(pool_type, sd->msg); /* save message */
-            Jmsg(jcr, M_FATAL, 0, _("\n"
-               "     Storage daemon didn't accept Device \"%s\" because:\n     %s"),
-              device_name.c_str(), pool_type.c_str()/* sd->msg */);
-        }
+// foreach_alist(storage, store) {
+      storage = (STORE *)store->first();
+      pm_strcpy(device_name, storage->dev_name());
+      pm_strcpy(media_type, storage->media_type);
+      pm_strcpy(pool_type, jcr->pool->pool_type);
+      pm_strcpy(pool_name, jcr->pool->hdr.name);
+      bash_spaces(device_name);
+      bash_spaces(media_type);
+      bash_spaces(pool_type);
+      bash_spaces(pool_name);
+      bnet_fsend(sd, use_device, device_name.c_str(),
+                media_type.c_str(), pool_name.c_str(), pool_type.c_str(),
+                append);
+      Dmsg1(200, ">stored: %s", sd->msg);
+      ok = response(jcr, sd, OK_device, "Use Device", NO_DISPLAY);
+      if (!ok) {
+        pm_strcpy(pool_type, sd->msg); /* save message */
+         Jmsg(jcr, M_FATAL, 0, _("\n"
+            "     Storage daemon didn't accept Device \"%s\" because:\n     %s"),
+           device_name.c_str(), pool_type.c_str()/* sd->msg */);
       }
+// }
+   if (ok) {
+      bnet_fsend(sd, "run");
    }
-   return status;
+   return ok;
 }
 
 /*
@@ -181,7 +227,8 @@ int start_storage_daemon_message_thread(JCR *jcr)
    V(jcr->mutex);
    Dmsg0(100, "Start SD msg_thread.\n");
    if ((status=pthread_create(&thid, NULL, msg_thread, (void *)jcr)) != 0) {
-      Jmsg1(jcr, M_ABORT, 0, _("Cannot create message thread: %s\n"), strerror(status));
+      berrno be;
+      Jmsg1(jcr, M_ABORT, 0, _("Cannot create message thread: %s\n"), be.strerror(status));
    }
    Dmsg0(100, "SD msg_thread started.\n");
    /* Wait for thread to start */
@@ -209,8 +256,7 @@ extern "C" void msg_thread_cleanup(void *arg)
  *  Storage daemon).
  * Note, we are running in a separate thread.
  */
-extern "C"
-void *msg_thread(void *arg)
+extern "C" void *msg_thread(void *arg)
 {
    JCR *jcr = (JCR *)arg;
    BSOCK *sd;
@@ -240,10 +286,6 @@ void *msg_thread(void *arg)
         jcr->SDJobBytes = JobBytes;
         break;
       }
-      if (sscanf(sd->msg, Job_status, &Job, &JobStatus) == 2) {
-        jcr->SDJobStatus = JobStatus; /* current status */
-        continue;
-      }
    }
    if (is_bnet_error(sd)) {
       jcr->SDJobStatus = JS_ErrorTerminated;
@@ -279,3 +321,54 @@ void wait_for_storage_daemon_termination(JCR *jcr)
    V(jcr->mutex);
    set_jcr_job_status(jcr, JS_Terminated);
 }
+
+
+#define MAX_TRIES 30
+#define WAIT_TIME 2
+extern "C" void *device_thread(void *arg)
+{
+   int i;
+   JCR *jcr;
+   DEVICE *dev;
+
+
+   pthread_detach(pthread_self());
+   jcr = new_control_jcr("*DeviceInit*", JT_SYSTEM);
+   for (i=0; i < MAX_TRIES; i++) {
+      if (!connect_to_storage_daemon(jcr, 10, 30, 1)) {
+         Dmsg0(000, "Failed connecting to SD.\n");
+        continue;
+      }
+      LockRes();
+      foreach_res(dev, R_DEVICE) {
+        if (!update_device_res(jcr, dev)) {
+            Dmsg1(900, "Error updating device=%s\n", dev->hdr.name);
+        } else {
+            Dmsg1(900, "Updated Device=%s\n", dev->hdr.name);
+        }
+      }
+      UnlockRes();
+      bnet_close(jcr->store_bsock);
+      jcr->store_bsock = NULL;
+      break;
+
+   }
+   free_jcr(jcr);
+   return NULL;
+}
+
+/*
+ * Start a thread to handle getting Device resource information
+ *  from SD. This is called once at startup of the Director.
+ */
+void init_device_resources()
+{
+   int status;
+   pthread_t thid;
+
+   Dmsg0(100, "Start Device thread.\n");
+   if ((status=pthread_create(&thid, NULL, device_thread, NULL)) != 0) {
+      berrno be;
+      Jmsg1(NULL, M_ABORT, 0, _("Cannot create message thread: %s\n"), be.strerror(status));
+   }
+}
index 81ae6d5c0b569b2e15d5b879d5dadab1f1b5d767..17658c3eab36002d1aa1841de2256b9367507e58 100644 (file)
@@ -79,7 +79,7 @@ enum e_prtmsg {
    DISPLAY_ERROR,
    NO_DISPLAY
 };
-extern int response(JCR *jcr, BSOCK *fd, char *resp, const char *cmd, e_prtmsg prtmsg);
+extern bool response(JCR *jcr, BSOCK *fd, char *resp, const char *cmd, e_prtmsg prtmsg);
 
 /* job.c */
 extern void set_jcr_defaults(JCR *jcr, JOB *job);
@@ -99,7 +99,7 @@ extern void mount_request(JCR *jcr, BSOCK *bs, char *buf);
 /* msgchan.c */
 extern bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
                              int max_retry_time, int verbose);
-extern int start_storage_daemon_job(JCR *jcr);
+extern int start_storage_daemon_job(JCR *jcr, alist *store, int append);
 extern int start_storage_daemon_message_thread(JCR *jcr);
 extern int bget_dirmsg(BSOCK *bs);
 extern void wait_for_storage_daemon_termination(JCR *jcr);
index d8a894bf243408234540d56e1cfe9c6b857a0ba1..ef82f94dbaa6156f0c93e6a254c39fe98d8e070b 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -67,11 +67,6 @@ int do_restore(JCR *jcr)
    BSOCK   *fd;
    JOB_DBR rjr;                      /* restore job record */
 
-   if (!get_or_create_client_record(jcr)) {
-      restore_cleanup(jcr, JS_ErrorTerminated);
-      return 0;
-   }
-
    memset(&rjr, 0, sizeof(rjr));
    jcr->jr.JobLevel = L_FULL;        /* Full restore */
    if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
@@ -80,7 +75,6 @@ int do_restore(JCR *jcr)
       return 0;
    }
    Dmsg0(20, "Updated job start record\n");
-   jcr->fname = (char *) get_pool_memory(PM_FNAME);
 
    Dmsg1(20, "RestoreJobId=%d\n", jcr->job->RestoreJobId);
 
@@ -99,7 +93,7 @@ int do_restore(JCR *jcr)
         rjr.JobId = jcr->job->RestoreJobId; /* specified by Job Resource */
       }
       if (!db_get_job_record(jcr, jcr->db, &rjr)) {
-        Jmsg2(jcr, M_FATAL, 0, _("Cannot get job record id=%d %s"), rjr.JobId,
+         Jmsg2(jcr, M_FATAL, 0, _("Cannot get job record id=%d %s"), rjr.JobId,
            db_strerror(jcr->db));
         restore_cleanup(jcr, JS_ErrorTerminated);
         return 0;
@@ -111,7 +105,7 @@ int do_restore(JCR *jcr)
       jcr->VolumeName[0] = 0;
       if (!db_get_job_volume_names(jcr, jcr->db, rjr.JobId, &jcr->VolumeName) ||
           jcr->VolumeName[0] == 0) {
-        Jmsg(jcr, M_FATAL, 0, _("Cannot find Volume names for restore Job %d. %s"),
+         Jmsg(jcr, M_FATAL, 0, _("Cannot find Volume names for restore Job %d. %s"),
            rjr.JobId, db_strerror(jcr->db));
         restore_cleanup(jcr, JS_ErrorTerminated);
         return 0;
@@ -141,7 +135,7 @@ int do_restore(JCR *jcr)
    /*
     * Now start a job with the Storage daemon
     */
-   if (!start_storage_daemon_job(jcr)) {
+   if (!start_storage_daemon_job(jcr, jcr->storage, SD_READ)) {
       restore_cleanup(jcr, JS_ErrorTerminated);
       return 0;
    }
@@ -281,9 +275,9 @@ static void restore_cleanup(JCR *jcr, int TermCode)
    switch (TermCode) {
    case JS_Terminated:
       if (jcr->ExpectedFiles > jcr->jr.JobFiles) {
-        term_msg = _("Restore OK -- warning file count mismatch");
+         term_msg = _("Restore OK -- warning file count mismatch");
       } else {
-        term_msg = _("Restore OK");
+         term_msg = _("Restore OK");
       }
       break;
    case JS_FatalError:
index 3cbcee500055d35df1087abb62d547a63fc14c19..edd9afe853e5ed124ae11da79d0c98fd49e1b5fd 100644 (file)
@@ -206,7 +206,7 @@ static void find_runs()
    /* Items corresponding to above at the next hour */
    int nh_hour, nh_mday, nh_wday, nh_month, nh_wom, nh_woy, nh_year;
 
-   Dmsg0(200, "enter find_runs()\n");
+   Dmsg0(1200, "enter find_runs()\n");
 
 
    /* compute values for time now */
@@ -242,7 +242,7 @@ static void find_runs()
       if (sched == NULL) {           /* scheduled? */
         continue;                    /* no, skip this job */
       }
-      Dmsg1(200, "Got job: %s\n", job->hdr.name);
+      Dmsg1(1200, "Got job: %s\n", job->hdr.name);
       for (run=sched->run; run; run=run->next) {
         bool run_now, run_nh;
         /*
@@ -285,7 +285,7 @@ static void find_runs()
            bit_is_set(nh_wom, run->wom) &&
            bit_is_set(nh_woy, run->woy);
 
-         Dmsg2(200, "run_now=%d run_nh=%d\n", run_now, run_nh);
+         Dmsg2(1200, "run_now=%d run_nh=%d\n", run_now, run_nh);
 
         /* find time (time_t) job is to be run */
         localtime_r(&now, &tm);      /* reset tm structure */
@@ -308,7 +308,7 @@ static void find_runs()
       }
    }
    UnlockRes();
-   Dmsg0(200, "Leave find_runs()\n");
+   Dmsg0(1200, "Leave find_runs()\n");
 }
 
 static void add_job(JOB *job, RUN *run, time_t now, time_t runtime)
index 99708e41ae9a100051dc23e1516eb2a711190c86..98432c1c57737744049b6c12ceddf53dbe2a68c4 100644 (file)
@@ -36,7 +36,7 @@ const char *list_pool = "SELECT * FROM Pool WHERE PoolId=%u";
 /* For ua_dotcmds.c */
 const char *client_backups =
 "SELECT DISTINCT Job.JobId,Client.Name as Client,Level,StartTime,"
-"JobFiles,JobBytes,VolumeName"
+"JobFiles,JobBytes,VolumeName,MediaType"
 " FROM Client,Job,JobMedia,Media"
 " WHERE Client.Name='%s'"
 " AND Client.ClientId=Job.ClientId"
index 2cd63618bcb4e8fbaac7e3540d70abb2dc8ff0cc..dcfc0e468a8d339c165bb1e634bd8c31f5123f47 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /*
-   Copyright (C) 2004 Kern Sibbald and John Walker
+   Copyright (C) 2004-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
@@ -45,7 +45,7 @@ bool acl_access_ok(UAContext *ua, int acl, char *item, int len)
 
    /* If no console resource => default console and all is permitted */
    if (!ua->cons) {
-      Dmsg0(400, "Root cons access OK.\n");
+      Dmsg0(1400, "Root cons access OK.\n");
       return true;                   /* No cons resource -> root console OK for everything */
    }
 
@@ -62,7 +62,7 @@ bool acl_access_ok(UAContext *ua, int acl, char *item, int len)
    /* Search list for item */
    for (int i=0; i<list->size(); i++) {
       if (strcasecmp(item, (char *)list->get(i)) == 0) {
-         Dmsg3(400, "Found %s in %d %s\n", item, acl, (char *)list->get(i));
+         Dmsg3(1400, "ACL found %s in %d %s\n", item, acl, (char *)list->get(i));
         return true;
       }
    }
index 3a5b0f03fba1b9569f9a223d6fec16277ad3cd40..b3c4279b289ae177e5a0eeea68bb8cb571f903d6 100644 (file)
@@ -149,7 +149,7 @@ int do_a_command(UAContext *ua, const char *cmd)
 
    stat = 1;
 
-   Dmsg1(200, "Command: %s\n", ua->UA_sock->msg);
+   Dmsg1(900, "Command: %s\n", ua->UA_sock->msg);
    if (ua->argc == 0) {
       return 1;
    }
@@ -186,6 +186,7 @@ void set_pool_dbr_defaults_in_media_dbr(MEDIA_DBR *mr, POOL_DBR *pr)
    mr->MaxVolJobs = pr->MaxVolJobs;
    mr->MaxVolFiles = pr->MaxVolFiles;
    mr->MaxVolBytes = pr->MaxVolBytes;
+   mr->LabelType = pr->LabelType;
 }
 
 
@@ -224,7 +225,7 @@ static int add_cmd(UAContext *ua, const char *cmd)
    while (pr.MaxVols > 0 && pr.NumVols >= pr.MaxVols) {
       bsendmsg(ua, _("Pool already has maximum volumes = %d\n"), pr.MaxVols);
       for (;;) {
-        if (!get_pint(ua, _("Enter new maximum (zero for unlimited): "))) {
+         if (!get_pint(ua, _("Enter new maximum (zero for unlimited): "))) {
            return 1;
         }
         pr.MaxVols = ua->pint32_val;
@@ -251,7 +252,7 @@ static int add_cmd(UAContext *ua, const char *cmd)
       }
       num = ua->pint32_val;
       if (num < 0 || num > max) {
-        bsendmsg(ua, _("The number must be between 0 and %d\n"), max);
+         bsendmsg(ua, _("The number must be between 0 and %d\n"), max);
         continue;
       }
       break;
@@ -281,15 +282,15 @@ getVolName:
 
    bstrncpy(name, ua->cmd, sizeof(name));
    if (num > 0) {
-      strcat(name, "%04d");
+      bstrncat(name, "%04d", sizeof(name));
 
       for (;;) {
-        if (!get_pint(ua, _("Enter the starting number: "))) {
+         if (!get_pint(ua, _("Enter the starting number: "))) {
            return 1;
         }
         startnum = ua->pint32_val;
         if (startnum < 1) {
-           bsendmsg(ua, _("Start number must be greater than zero.\n"));
+            bsendmsg(ua, _("Start number must be greater than zero.\n"));
            continue;
         }
         break;
@@ -317,7 +318,7 @@ getVolName:
       mr.InChanger = InChanger;
       Dmsg1(200, "Create Volume %s\n", mr.VolumeName);
       if (!db_create_media_record(ua->jcr, ua->db, &mr)) {
-        bsendmsg(ua, "%s", db_strerror(ua->db));
+         bsendmsg(ua, "%s", db_strerror(ua->db));
         return 1;
       }
       if (i == startnum) {
@@ -381,7 +382,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 %d is not running.\n"),  JobId);
            return 1;
         }
         break;
@@ -390,7 +391,7 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
            break;
         }
         if (!(jcr=get_jcr_by_partial_name(ua->argv[i]))) {
-           bsendmsg(ua, _("Job %s is not running.\n"), ua->argv[i]);
+            bsendmsg(ua, _("Job %s is not running.\n"), ua->argv[i]);
            return 1;
         }
         break;
@@ -400,6 +401,7 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
     *  throw up a list and ask the user to select one.
     */
    if (!jcr) {
+      char buf[1000];
       /* Count Jobs running */
       lock_jcr_chain();
       foreach_jcr(jcr) {
@@ -413,7 +415,7 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
       unlock_jcr_chain();
 
       if (njobs == 0) {
-        bsendmsg(ua, _("No Jobs running.\n"));
+         bsendmsg(ua, _("No Jobs running.\n"));
         return 1;
       }
       start_prompt(ua, _("Select Job:\n"));
@@ -423,23 +425,25 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
            free_locked_jcr(jcr);
            continue;
         }
-        add_prompt(ua, jcr->Job);
+         bsnprintf(buf, sizeof(buf), "JobId=%d Job=%s", jcr->JobId, jcr->Job);
+        add_prompt(ua, buf);
         free_locked_jcr(jcr);
       }
       unlock_jcr_chain();
 
-      if (do_prompt(ua, _("Job"),  _("Choose Job to cancel"), JobName, sizeof(JobName)) < 0) {
+      if (do_prompt(ua, _("Job"),  _("Choose Job to cancel"), buf, sizeof(buf)) < 0) {
         return 1;
       }
       if (njobs == 1) {
-        if (!get_yesno(ua, _("Confirm cancel (yes/no): ")) || ua->pint32_val == 0) {
+         if (!get_yesno(ua, _("Confirm cancel (yes/no): ")) || ua->pint32_val == 0) {
            return 1;
         }
       }
       /* NOTE! This increments the ref_count */
+      sscanf(buf, "JobId=%d Job=%127s", &njobs, JobName);
       jcr = get_jcr_by_full_name(JobName);
       if (!jcr) {
-        bsendmsg(ua, _("Job %s not found.\n"), JobName);
+         bsendmsg(ua, _("Job %s not found.\n"), JobName);
         return 1;
       }
    }
@@ -459,7 +463,7 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
  */
 static void set_pooldbr_from_poolres(POOL_DBR *pr, POOL *pool, e_pool_op op)
 {
-   strcpy(pr->PoolType, pool->pool_type);
+   bstrncpy(pr->PoolType, pool->pool_type, sizeof(pr->PoolType));
    if (op == POOL_OP_CREATE) {
       pr->MaxVols = pool->max_volumes;
       pr->NumVols = 0;
@@ -471,6 +475,7 @@ static void set_pooldbr_from_poolres(POOL_DBR *pr, POOL *pool, e_pool_op op)
         pr->MaxVols = pr->NumVols;
       }
    }
+   pr->LabelType = pool->LabelType;
    pr->UseOnce = pool->use_volume_once;
    pr->UseCatalog = pool->use_catalog;
    pr->AcceptAnyVolume = pool->accept_any_volume;
@@ -483,9 +488,9 @@ static void set_pooldbr_from_poolres(POOL_DBR *pr, POOL *pool, e_pool_op op)
    pr->AutoPrune = pool->AutoPrune;
    pr->Recycle = pool->Recycle;
    if (pool->label_format) {
-      strcpy(pr->LabelFormat, pool->label_format);
+      bstrncpy(pr->LabelFormat, pool->label_format, sizeof(pr->LabelFormat));
    } else {
-      strcpy(pr->LabelFormat, "*");    /* none */
+      bstrncpy(pr->LabelFormat, "*", sizeof(pr->LabelFormat));    /* none */
    }
 }
 
@@ -504,7 +509,7 @@ int create_pool(JCR *jcr, B_DB *db, POOL *pool, e_pool_op op)
 
    memset(&pr, 0, sizeof(POOL_DBR));
 
-   strcpy(pr.Name, pool->hdr.name);
+   bstrncpy(pr.Name, pool->hdr.name, sizeof(pr.Name));
 
    if (db_get_pool_record(jcr, db, &pr)) {
       /* Pool Exists */
@@ -545,7 +550,7 @@ static int create_cmd(UAContext *ua, const char *cmd)
    switch (create_pool(ua->jcr, ua->db, pool, POOL_OP_CREATE)) {
    case 0:
       bsendmsg(ua, _("Error: Pool %s already exists.\n"
-              "Use update to change it.\n"), pool->hdr.name);
+               "Use update to change it.\n"), pool->hdr.name);
       break;
 
    case -1:
@@ -571,7 +576,7 @@ static int python_cmd(UAContext *ua, const char *cmd)
    if (strcasecmp(ua->argk[1], _("restart")) == 0) {
       term_python_interpreter();
       init_python_interpreter(director->hdr.name, director->scripts_directory ?
-        director->scripts_directory : ".");
+         director->scripts_directory : ".");
       bsendmsg(ua, _("Python interpreter restarted.\n"));
    } else {
       bsendmsg(ua, _("Nothing done.\n"));
@@ -702,9 +707,9 @@ static void update_volstatus(UAContext *ua, const char *val, MEDIA_DBR *mr)
       Mmsg(query, "UPDATE Media SET VolStatus='%s' WHERE MediaId=%u",
         mr->VolStatus, mr->MediaId);
       if (!db_sql_query(ua->db, query, NULL, NULL)) {
-        bsendmsg(ua, "%s", db_strerror(ua->db));
+         bsendmsg(ua, "%s", db_strerror(ua->db));
       } else {
-        bsendmsg(ua, _("New Volume status is: %s\n"), mr->VolStatus);
+         bsendmsg(ua, _("New Volume status is: %s\n"), mr->VolStatus);
       }
    }
    free_pool_memory(query);
@@ -817,7 +822,7 @@ static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr)
       bsendmsg(ua, "%s", db_strerror(ua->db));
    } else {
       bsendmsg(ua, _("New Recycle flag is: %s\n"),
-        mr->Recycle==1?_("yes"):_("no"));
+         mr->Recycle==1?_("yes"):_("no"));
    }
    free_pool_memory(query);
 }
@@ -846,11 +851,11 @@ static void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *o
       bsendmsg(ua, _("New Pool is: %s\n"), pr.Name);
       opr->NumVols--;
       if (!db_update_pool_record(ua->jcr, ua->db, opr)) {
-        bsendmsg(ua, "%s", db_strerror(ua->db));
+         bsendmsg(ua, "%s", db_strerror(ua->db));
       }
       pr.NumVols++;
       if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
-        bsendmsg(ua, "%s", db_strerror(ua->db));
+         bsendmsg(ua, "%s", db_strerror(ua->db));
       }
       db_make_inchanger_unique(ua->jcr, ua->db, mr);
    }
@@ -963,7 +968,7 @@ static int update_volume(UAContext *ua)
            memset(&pr, 0, sizeof(POOL_DBR));
            pr.PoolId = mr.PoolId;
            if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
-              bsendmsg(ua, "%s", db_strerror(ua->db));
+               bsendmsg(ua, "%s", db_strerror(ua->db));
               break;
            }
            update_vol_pool(ua, ua->argv[j], &mr, &pr);
@@ -1002,60 +1007,60 @@ static int update_volume(UAContext *ua)
       switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
       case 0:                        /* Volume Status */
         /* Modify Volume Status */
-        bsendmsg(ua, _("Current Volume status is: %s\n"), mr.VolStatus);
-        start_prompt(ua, _("Possible Values are:\n"));
-        add_prompt(ua, "Append");      /* Better not translate these as */
-        add_prompt(ua, "Archive");     /* They are known in the database code */
-        add_prompt(ua, "Disabled");
-        add_prompt(ua, "Full");
-        add_prompt(ua, "Used");
-        add_prompt(ua, "Cleaning");
-        if (strcmp(mr.VolStatus, "Purged") == 0) {
-           add_prompt(ua, "Recycle");
+         bsendmsg(ua, _("Current Volume status is: %s\n"), mr.VolStatus);
+         start_prompt(ua, _("Possible Values are:\n"));
+         add_prompt(ua, "Append");      /* Better not translate these as */
+         add_prompt(ua, "Archive");     /* They are known in the database code */
+         add_prompt(ua, "Disabled");
+         add_prompt(ua, "Full");
+         add_prompt(ua, "Used");
+         add_prompt(ua, "Cleaning");
+         if (strcmp(mr.VolStatus, "Purged") == 0) {
+            add_prompt(ua, "Recycle");
         }
-        add_prompt(ua, "Read-Only");
-        if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) {
+         add_prompt(ua, "Read-Only");
+         if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) {
            return 1;
         }
         update_volstatus(ua, ua->cmd, &mr);
         break;
       case 1:                        /* Retention */
-        bsendmsg(ua, _("Current retention period is: %s\n"),
+         bsendmsg(ua, _("Current retention period is: %s\n"),
            edit_utime(mr.VolRetention, ed1, sizeof(ed1)));
-        if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
+         if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
            return 0;
         }
         update_volretention(ua, ua->cmd, &mr);
         break;
 
       case 2:                        /* Use Duration */
-        bsendmsg(ua, _("Current use duration is: %s\n"),
+         bsendmsg(ua, _("Current use duration is: %s\n"),
            edit_utime(mr.VolUseDuration, ed1, sizeof(ed1)));
-        if (!get_cmd(ua, _("Enter Volume Use Duration: "))) {
+         if (!get_cmd(ua, _("Enter Volume Use Duration: "))) {
            return 0;
         }
         update_voluseduration(ua, ua->cmd, &mr);
         break;
 
       case 3:                        /* Max Jobs */
-        bsendmsg(ua, _("Current max jobs is: %u\n"), mr.MaxVolJobs);
-        if (!get_pint(ua, _("Enter new Maximum Jobs: "))) {
+         bsendmsg(ua, _("Current max jobs is: %u\n"), mr.MaxVolJobs);
+         if (!get_pint(ua, _("Enter new Maximum Jobs: "))) {
            return 0;
         }
         update_volmaxjobs(ua, ua->cmd, &mr);
         break;
 
       case 4:                        /* Max Files */
-        bsendmsg(ua, _("Current max files is: %u\n"), mr.MaxVolFiles);
-        if (!get_pint(ua, _("Enter new Maximum Files: "))) {
+         bsendmsg(ua, _("Current max files is: %u\n"), mr.MaxVolFiles);
+         if (!get_pint(ua, _("Enter new Maximum Files: "))) {
            return 0;
         }
         update_volmaxfiles(ua, ua->cmd, &mr);
         break;
 
       case 5:                        /* Max Bytes */
-        bsendmsg(ua, _("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1));
-        if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) {
+         bsendmsg(ua, _("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1));
+         if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) {
            return 0;
         }
         update_volmaxbytes(ua, ua->cmd, &mr);
@@ -1063,9 +1068,9 @@ static int update_volume(UAContext *ua)
 
 
       case 6:                        /* Recycle */
-        bsendmsg(ua, _("Current recycle flag is: %s\n"),
-           mr.Recycle==1?_("yes"):_("no"));
-        if (!get_yesno(ua, _("Enter new Recycle status: "))) {
+         bsendmsg(ua, _("Current recycle flag is: %s\n"),
+            mr.Recycle==1?_("yes"):_("no"));
+         if (!get_yesno(ua, _("Enter new Recycle status: "))) {
            return 0;
         }
         update_volrecycle(ua, ua->cmd, &mr);
@@ -1077,16 +1082,16 @@ static int update_volume(UAContext *ua)
         memset(&pr, 0, sizeof(POOL_DBR));
         pr.PoolId = mr.PoolId;
         if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
-           bsendmsg(ua, "%s", db_strerror(ua->db));
+            bsendmsg(ua, "%s", db_strerror(ua->db));
            return 0;
         }
-        bsendmsg(ua, _("Current Slot is: %d\n"), mr.Slot);
-        if (!get_pint(ua, _("Enter new Slot: "))) {
+         bsendmsg(ua, _("Current Slot is: %d\n"), mr.Slot);
+         if (!get_pint(ua, _("Enter new Slot: "))) {
            return 0;
         }
         Slot = ua->pint32_val;
         if (pr.MaxVols > 0 && Slot > (int)pr.MaxVols) {
-           bsendmsg(ua, _("Invalid slot, it must be between 0 and %d\n"),
+            bsendmsg(ua, _("Invalid slot, it must be between 0 and %d\n"),
               pr.MaxVols);
            break;
         }
@@ -1096,15 +1101,15 @@ static int update_volume(UAContext *ua)
          *   so that any Slot is handled correctly.
          */
         if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
-           bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
+            bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
         } else {
-           bsendmsg(ua, _("New Slot is: %d\n"), mr.Slot);
+            bsendmsg(ua, _("New Slot is: %d\n"), mr.Slot);
         }
         break;
 
       case 8:                        /* InChanger */
-        bsendmsg(ua, _("Current InChanger flag is: %d\n"), mr.InChanger);
-        if (!get_yesno(ua, _("Set InChanger flag? yes/no: "))) {
+         bsendmsg(ua, _("Current InChanger flag is: %d\n"), mr.InChanger);
+         if (!get_yesno(ua, _("Set InChanger flag? yes/no: "))) {
            return 0;
         }
         mr.InChanger = ua->pint32_val;
@@ -1113,35 +1118,35 @@ static int update_volume(UAContext *ua)
          *   so that any Slot is handled correctly.
          */
         if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
-           bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
+            bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
         } else {
-           bsendmsg(ua, _("New InChanger flag is: %d\n"), mr.InChanger);
+            bsendmsg(ua, _("New InChanger flag is: %d\n"), mr.InChanger);
         }
         break;
 
 
       case 9:                        /* Volume Files */
         int32_t VolFiles;
-        bsendmsg(ua, _("Warning changing Volume Files can result\n"
-                       "in loss of data on your Volume\n\n"));
-        bsendmsg(ua, _("Current Volume Files is: %u\n"), mr.VolFiles);
-        if (!get_pint(ua, _("Enter new number of Files for Volume: "))) {
+         bsendmsg(ua, _("Warning changing Volume Files can result\n"
+                        "in loss of data on your Volume\n\n"));
+         bsendmsg(ua, _("Current Volume Files is: %u\n"), mr.VolFiles);
+         if (!get_pint(ua, _("Enter new number of Files for Volume: "))) {
            return 0;
         }
         VolFiles = ua->pint32_val;
         if (VolFiles != (int)(mr.VolFiles + 1)) {
-           bsendmsg(ua, _("Normally, you should only increase Volume Files by one!\n"));
-           if (!get_yesno(ua, _("Continue? (yes/no): ")) || ua->pint32_val == 0) {
+            bsendmsg(ua, _("Normally, you should only increase Volume Files by one!\n"));
+            if (!get_yesno(ua, _("Continue? (yes/no): ")) || ua->pint32_val == 0) {
               break;
            }
         }
         query = get_pool_memory(PM_MESSAGE);
-        Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%u",
+         Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%u",
            VolFiles, mr.MediaId);
         if (!db_sql_query(ua->db, query, NULL, NULL)) {
-           bsendmsg(ua, "%s", db_strerror(ua->db));
+            bsendmsg(ua, "%s", db_strerror(ua->db));
         } else {
-           bsendmsg(ua, _("New Volume Files is: %u\n"), VolFiles);
+            bsendmsg(ua, _("New Volume Files is: %u\n"), VolFiles);
         }
         free_pool_memory(query);
         break;
@@ -1150,11 +1155,11 @@ static int update_volume(UAContext *ua)
         memset(&pr, 0, sizeof(POOL_DBR));
         pr.PoolId = mr.PoolId;
         if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
-           bsendmsg(ua, "%s", db_strerror(ua->db));
+            bsendmsg(ua, "%s", db_strerror(ua->db));
            return 0;
         }
-        bsendmsg(ua, _("Current Pool is: %s\n"), pr.Name);
-        if (!get_cmd(ua, _("Enter new Pool name: "))) {
+         bsendmsg(ua, _("Current Pool is: %s\n"), pr.Name);
+         if (!get_cmd(ua, _("Enter new Pool name: "))) {
            return 0;
         }
         update_vol_pool(ua, ua->cmd, &mr, &pr);
@@ -1167,7 +1172,7 @@ static int update_volume(UAContext *ua)
         update_all_vols_from_pool(ua);
         return 1;
       default:                       /* Done or error */
-        bsendmsg(ua, "Selection done.\n");
+         bsendmsg(ua, "Selection done.\n");
         return 1;
       }
    }
@@ -1190,7 +1195,7 @@ static int update_pool(UAContext *ua)
    }
 
    memset(&pr, 0, sizeof(pr));
-   strcpy(pr.Name, pool->hdr.name);
+   bstrncpy(pr.Name, pool->hdr.name, sizeof(pr.Name));
    if (!get_pool_dbr(ua, &pr)) {
       return 0;
    }
@@ -1295,7 +1300,7 @@ static void do_all_setdebug(UAContext *ua, int level, int trace_flag)
       }
       if (!found) {
         unique_store[i++] = store;
-        Dmsg2(140, "Stuffing: %s:%d\n", store->address, store->SDport);
+         Dmsg2(140, "Stuffing: %s:%d\n", store->address, store->SDport);
       }
    }
    UnlockRes();
@@ -1329,7 +1334,7 @@ static void do_all_setdebug(UAContext *ua, int level, int trace_flag)
       }
       if (!found) {
         unique_client[i++] = client;
-        Dmsg2(140, "Stuffing: %s:%d\n", client->address, client->FDport);
+         Dmsg2(140, "Stuffing: %s:%d\n", client->address, client->FDport);
       }
    }
    UnlockRes();
@@ -1385,13 +1390,13 @@ static int setdebug_cmd(UAContext *ua, const char *cmd)
         return 1;
       }
       if (strcasecmp(ua->argk[i], _("dir")) == 0 ||
-         strcasecmp(ua->argk[i], _("director")) == 0) {
+          strcasecmp(ua->argk[i], _("director")) == 0) {
         debug_level = level;
         set_trace(trace_flag);
         return 1;
       }
       if (strcasecmp(ua->argk[i], _("client")) == 0 ||
-         strcasecmp(ua->argk[i], _("fd")) == 0) {
+          strcasecmp(ua->argk[i], _("fd")) == 0) {
         client = NULL;
         if (ua->argv[i]) {
            client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
@@ -1408,8 +1413,8 @@ static int setdebug_cmd(UAContext *ua, const char *cmd)
       }
 
       if (strcasecmp(ua->argk[i], _("store")) == 0 ||
-         strcasecmp(ua->argk[i], _("storage")) == 0 ||
-         strcasecmp(ua->argk[i], _("sd")) == 0) {
+          strcasecmp(ua->argk[i], _("storage")) == 0 ||
+          strcasecmp(ua->argk[i], _("sd")) == 0) {
         store = NULL;
         if (ua->argv[i]) {
            store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]);
@@ -1515,7 +1520,7 @@ static int estimate_cmd(UAContext *ua, const char *cmd)
    jcr->JobLevel = L_FULL;
    for (int i=1; i<ua->argc; i++) {
       if (strcasecmp(ua->argk[i], _("client")) == 0 ||
-         strcasecmp(ua->argk[i], _("fd")) == 0) {
+          strcasecmp(ua->argk[i], _("fd")) == 0) {
         if (ua->argv[i]) {
            client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
            continue;
@@ -1539,7 +1544,7 @@ static int estimate_cmd(UAContext *ua, const char *cmd)
       }
       if (strcasecmp(ua->argk[i], _("level")) == 0) {
         if (!get_level_from_name(ua->jcr, ua->argv[i])) {
-           bsendmsg(ua, _("Level %s not valid.\n"), ua->argv[i]);
+            bsendmsg(ua, _("Level %s not valid.\n"), ua->argv[i]);
         }
         continue;
       }
@@ -1552,7 +1557,7 @@ static int estimate_cmd(UAContext *ua, const char *cmd)
    if (!job) {
       job = (JOB *)GetResWithName(R_JOB, ua->argk[1]);
       if (!job) {
-        bsendmsg(ua, _("No job specified.\n"));
+         bsendmsg(ua, _("No job specified.\n"));
         return 1;
       }
    }
@@ -1725,26 +1730,26 @@ static void delete_job(UAContext *ua)
        s = bstrdup(ua->argv[i]);
        tok = s;
        /*
-        * We could use strtok() here.  But we're not going to, because:
+         * We could use strtok() here.  But we're not going to, because:
         * (a) strtok() is deprecated, having been replaced by strsep();
         * (b) strtok() is broken in significant ways.
-        * we could use strsep() instead, but it's not universally available.
+         * we could use strsep() instead, but it's not universally available.
         * so we grow our own using strchr().
         */
-       sep = strchr(tok, ',');
+        sep = strchr(tok, ',');
        while (sep != NULL) {
-          *sep = '\0';
-          if (strchr(tok, '-')) {
+           *sep = '\0';
+           if (strchr(tok, '-')) {
               delete_job_id_range(ua, tok);
           } else {
              JobId = str_to_int64(tok);
              do_job_delete(ua, JobId);
           }
           tok = ++sep;
-          sep = strchr(tok, ',');
+           sep = strchr(tok, ',');
        }
        /* pick up the last token */
-       if (strchr(tok, '-')) {
+        if (strchr(tok, '-')) {
            delete_job_id_range(ua, tok);
        } else {
            JobId = str_to_int64(tok);
@@ -1864,7 +1869,7 @@ static void do_mount_cmd(UAContext *ua, const char *command)
    }
 
    Dmsg2(120, "Found storage, MediaType=%s DevName=%s\n",
-      store->media_type, store->dev_name);
+      store->media_type, store->dev_name());
 
    set_storage(jcr, store);
    if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
@@ -1872,7 +1877,7 @@ static void do_mount_cmd(UAContext *ua, const char *command)
       return;
    }
    sd = jcr->store_bsock;
-   bstrncpy(dev_name, store->dev_name, sizeof(dev_name));
+   bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
    bash_spaces(dev_name);
    bnet_fsend(sd, "%s %s", command, dev_name);
    while (bnet_recv(sd) >= 0) {
@@ -2013,10 +2018,10 @@ int open_db(UAContext *ua)
       ua->catalog = (CAT *)GetNextRes(R_CATALOG, NULL);
       UnlockRes();
       if (!ua->catalog) {
-        bsendmsg(ua, _("Could not find a Catalog resource\n"));
+         bsendmsg(ua, _("Could not find a Catalog resource\n"));
         return 0;
       } else {
-        bsendmsg(ua, _("Using default Catalog name=%s DB=%s\n"),
+         bsendmsg(ua, _("Using default Catalog name=%s DB=%s\n"),
            ua->catalog->hdr.name, ua->catalog->db_name);
       }
    }
@@ -2032,7 +2037,7 @@ int open_db(UAContext *ua)
       bsendmsg(ua, _("Could not open database \"%s\".\n"),
                 ua->catalog->db_name);
       if (ua->db) {
-        bsendmsg(ua, "%s", db_strerror(ua->db));
+         bsendmsg(ua, "%s", db_strerror(ua->db));
       }
       close_db(ua);
       return 0;
index aa18973a422e456817ed82c4bc5d287f18c4b9d6..e2be84ffc0b67941e1daa1f1391bd354ad33d961 100644 (file)
@@ -92,7 +92,7 @@ int do_a_dot_command(UAContext *ua, const char *cmd)
 
    stat = 1;
 
-   Dmsg1(400, "Dot command: %s\n", ua->UA_sock->msg);
+   Dmsg1(1400, "Dot command: %s\n", ua->UA_sock->msg);
    if (ua->argc == 0) {
       return 1;
    }
@@ -254,16 +254,16 @@ static int defaultscmd(UAContext *ua, const char *cmd)
       job = (JOB *)GetResWithName(R_JOB, ua->argv[1]);
       if (job) {
         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[0]->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));
-        bsendmsg(ua, "type=%s", job_type_to_str(job->JobType));
-        bsendmsg(ua, "fileset=%s", job->fileset->hdr.name);
+         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();
+         bsendmsg(ua, "storage=%s", store->hdr.name);
+         bsendmsg(ua, "where=%s", job->RestoreWhere?job->RestoreWhere:"");
+         bsendmsg(ua, "level=%s", level_to_str(job->JobLevel));
+         bsendmsg(ua, "type=%s", job_type_to_str(job->JobType));
+         bsendmsg(ua, "fileset=%s", job->fileset->hdr.name);
       }
    }
    return 1;
index a6d939688965792ef2ea0058a653da3b808a5ce2..6343ca2366deb108f96b3f46539f3b72f52af456 100644 (file)
@@ -85,47 +85,47 @@ static bool get_user_slot_list(UAContext *ua, char *slot_list, int num_slots)
       strip_trailing_junk(ua->argv[i]);
       for (p=ua->argv[i]; p && *p; p=e) {
         /* Check for list */
-        e = strchr(p, ',');
+         e = strchr(p, ',');
         if (e) {
            *e++ = 0;
         }
         /* Check for range */
-        h = strchr(p, '-');             /* range? */
+         h = strchr(p, '-');             /* range? */
         if (h == p) {
-           msg = _("Negative numbers not permitted\n");
+            msg = _("Negative numbers not permitted\n");
            goto bail_out;
         }
         if (h) {
            *h++ = 0;
            if (!is_an_integer(h)) {
-              msg = _("Range end is not integer.\n");
+               msg = _("Range end is not integer.\n");
               goto bail_out;
            }
            skip_spaces(&p);
            if (!is_an_integer(p)) {
-              msg = _("Range start is not an integer.\n");
+               msg = _("Range start is not an integer.\n");
               goto bail_out;
            }
            beg = atoi(p);
            end = atoi(h);
            if (end < beg) {
-              msg = _("Range end not bigger than start.\n");
+               msg = _("Range end not bigger than start.\n");
               goto bail_out;
            }
         } else {
            skip_spaces(&p);
            if (!is_an_integer(p)) {
-              msg = _("Input value is not an integer.\n");
+               msg = _("Input value is not an integer.\n");
               goto bail_out;
            }
            beg = end = atoi(p);
         }
         if (beg <= 0 || end <= 0) {
-           msg = _("Values must be be greater than zero.\n");
+            msg = _("Values must be be greater than zero.\n");
            goto bail_out;
         }
         if (end >= num_slots) {
-           msg = _("Slot too large.\n");
+            msg = _("Slot too large.\n");
            goto bail_out;
         }
         for (i=beg; i<=end; i++) {
@@ -142,7 +142,7 @@ static bool get_user_slot_list(UAContext *ua, char *slot_list, int num_slots)
    printf("Slots turned on:\n");
    for (i=1; i<num_slots; i++) {
       if (slot_list[i]) {
-        printf("%d\n", i);
+         printf("%d\n", i);
       }
    }
 #endif
@@ -190,12 +190,12 @@ int update_slots(UAContext *ua)
    /* Walk through the list updating the media records */
    for (vl=vol_list; vl; vl=vl->next) {
       if (vl->Slot >= max_slots) {
-        bsendmsg(ua, _("Slot %d larger than max %d ignored.\n"));
+         bsendmsg(ua, _("Slot %d larger than max %d ignored.\n"));
         continue;
       }
       /* Check if user wants us to look at this slot */
       if (!slot_list[vl->Slot]) {
-        Dmsg1(100, "Skipping slot=%d\n", vl->Slot);
+         Dmsg1(100, "Skipping slot=%d\n", vl->Slot);
         continue;
       }
       /* If scanning, we read the label rather than the barcode */
@@ -205,11 +205,11 @@ int update_slots(UAContext *ua)
            vl->VolName = NULL;
         }
         vl->VolName = get_volume_name_from_SD(ua, vl->Slot);
-        Dmsg2(100, "Got Vol=%s from SD for Slot=%d\n", vl->VolName, vl->Slot);
+         Dmsg2(100, "Got Vol=%s from SD for Slot=%d\n", vl->VolName, vl->Slot);
       }
       slot_list[vl->Slot] = 0;       /* clear Slot */
       if (!vl->VolName) {
-        Dmsg1(100, "No VolName for Slot=%d setting InChanger to zero.\n", vl->Slot);
+         Dmsg1(100, "No VolName for Slot=%d setting InChanger to zero.\n", vl->Slot);
         memset(&mr, 0, sizeof(mr));
         mr.Slot = vl->Slot;
         mr.InChanger = 1;
@@ -217,7 +217,7 @@ int update_slots(UAContext *ua)
         db_lock(ua->db);
         db_make_inchanger_unique(ua->jcr, ua->db, &mr);
         db_unlock(ua->db);
-        bsendmsg(ua, _("No VolName for Slot=%d set InChanger to zero.\n"), vl->Slot);
+         bsendmsg(ua, _("No VolName for Slot=%d set InChanger to zero.\n"), vl->Slot);
         continue;
       }
       memset(&mr, 0, sizeof(mr));
@@ -228,20 +228,20 @@ int update_slots(UAContext *ua)
             mr.Slot = vl->Slot;
             mr.InChanger = 1;
             if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
-               bsendmsg(ua, "%s", db_strerror(ua->db));
+                bsendmsg(ua, "%s", db_strerror(ua->db));
             } else {
                bsendmsg(ua, _(
-                 "Catalog record for Volume \"%s\" updated to reference slot %d.\n"),
+                  "Catalog record for Volume \"%s\" updated to reference slot %d.\n"),
                  mr.VolumeName, mr.Slot);
             }
          } else {
-            bsendmsg(ua, _("Catalog record for Volume \"%s\" is up to date.\n"),
+             bsendmsg(ua, _("Catalog record for Volume \"%s\" is up to date.\n"),
                mr.VolumeName);
          }
          db_unlock(ua->db);
          continue;
       } else {
-         bsendmsg(ua, _("Record for Volume \"%s\" not found in catalog.\n"),
+          bsendmsg(ua, _("Record for Volume \"%s\" not found in catalog.\n"),
             mr.VolumeName);
       }
       db_unlock(ua->db);
@@ -313,7 +313,7 @@ static int do_label(UAContext *ua, const char *cmd, int relabel)
         if (db_get_media_record(ua->jcr, ua->db, &omr)) {
            goto checkVol;
         }
-        bsendmsg(ua, "%s", db_strerror(ua->db));
+         bsendmsg(ua, "%s", db_strerror(ua->db));
       }
       /* No keyword or Vol not found, ask user to select */
       if (!select_media_dbr(ua, &omr)) {
@@ -323,7 +323,7 @@ static int do_label(UAContext *ua, const char *cmd, int relabel)
       /* Require Volume to be Purged or Recycled */
 checkVol:
       if (strcmp(omr.VolStatus, "Purged") != 0 && strcmp(omr.VolStatus, "Recycle") != 0) {
-        bsendmsg(ua, _("Volume \"%s\" has VolStatus %s. It must be Purged or Recycled before relabeling.\n"),
+         bsendmsg(ua, _("Volume \"%s\" has VolStatus %s. It must be Purged or Recycled before relabeling.\n"),
            omr.VolumeName, omr.VolStatus);
         return 1;
       }
@@ -352,7 +352,7 @@ checkName:
       /* If VolBytes are zero the Volume is not labeled */
       if (db_get_media_record(ua->jcr, ua->db, &mr)) {
         if (mr.VolBytes != 0) {
-            bsendmsg(ua, _("Media record for new Volume \"%s\" already exists.\n"),
+             bsendmsg(ua, _("Media record for new Volume \"%s\" already exists.\n"),
                mr.VolumeName);
             continue;
          }
@@ -392,34 +392,34 @@ checkName:
       if (relabel) {
         /* Delete the old media record */
         if (!db_delete_media_record(ua->jcr, ua->db, &omr)) {
-           bsendmsg(ua, _("Delete of Volume \"%s\" failed. ERR=%s"),
+            bsendmsg(ua, _("Delete of Volume \"%s\" failed. ERR=%s"),
               omr.VolumeName, db_strerror(ua->db));
         } else {
-           bsendmsg(ua, _("Old volume \"%s\" deleted from catalog.\n"),
+            bsendmsg(ua, _("Old volume \"%s\" deleted from catalog.\n"),
               omr.VolumeName);
            /* Update the number of Volumes in the pool */
            pr.NumVols--;
            if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
-              bsendmsg(ua, "%s", db_strerror(ua->db));
+               bsendmsg(ua, "%s", db_strerror(ua->db));
            }
         }
       }
       if (ua->automount) {
-        bstrncpy(dev_name, store->dev_name, sizeof(dev_name));
-        bsendmsg(ua, _("Requesting to mount %s ...\n"), dev_name);
+        bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
+         bsendmsg(ua, _("Requesting to mount %s ...\n"), dev_name);
         bash_spaces(dev_name);
-        bnet_fsend(sd, "mount %s", dev_name);
+         bnet_fsend(sd, "mount %s", dev_name);
         unbash_spaces(dev_name);
         while (bnet_recv(sd) >= 0) {
-           bsendmsg(ua, "%s", sd->msg);
+            bsendmsg(ua, "%s", sd->msg);
            /* Here we can get
             *  3001 OK mount. Device=xxx      or
             *  3001 Mounted Volume vvvv
             *  3906 is cannot mount non-tape
             * So for those, no need to print a reminder
             */
-           if (strncmp(sd->msg, "3001 ", 5) == 0 ||
-               strncmp(sd->msg, "3906 ", 5) == 0) {
+            if (strncmp(sd->msg, "3001 ", 5) == 0 ||
+                strncmp(sd->msg, "3906 ", 5) == 0) {
               print_reminder = false;
            }
         }
@@ -460,8 +460,8 @@ static void label_from_barcodes(UAContext *ua)
 
    /* Display list of Volumes and ask if he really wants to proceed */
    bsendmsg(ua, _("The following Volumes will be labeled:\n"
-                 "Slot  Volume\n"
-                 "==============\n"));
+                  "Slot  Volume\n"
+                  "==============\n"));
    for (vl=vol_list; vl; vl=vl->next) {
       if (!vl->VolName || !slot_list[vl->Slot]) {
         continue;
@@ -489,12 +489,12 @@ static void label_from_barcodes(UAContext *ua)
       media_record_exists = false;
       if (db_get_media_record(ua->jcr, ua->db, &mr)) {
          if (mr.VolBytes != 0) {
-            bsendmsg(ua, _("Media record for Slot %d Volume \"%s\" already exists.\n"),
+             bsendmsg(ua, _("Media record for Slot %d Volume \"%s\" already exists.\n"),
                vl->Slot, mr.VolumeName);
             if (!mr.InChanger) {
                mr.InChanger = 1;
                if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
-                  bsendmsg(ua, "Error setting InChanger: ERR=%s", db_strerror(ua->db));
+                   bsendmsg(ua, "Error setting InChanger: ERR=%s", db_strerror(ua->db));
                }
             }
             continue;
@@ -510,19 +510,19 @@ static void label_from_barcodes(UAContext *ua)
         if (media_record_exists) {      /* we update it */
            mr.VolBytes = 1;
            if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
-               bsendmsg(ua, "%s", db_strerror(ua->db));
+                bsendmsg(ua, "%s", db_strerror(ua->db));
            }
         } else {                        /* create the media record */
            set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
            if (db_create_media_record(ua->jcr, ua->db, &mr)) {
-              bsendmsg(ua, _("Catalog record for cleaning tape \"%s\" successfully created.\n"),
+               bsendmsg(ua, _("Catalog record for cleaning tape \"%s\" successfully created.\n"),
                  mr.VolumeName);
               pr.NumVols++;          /* this is a bit suspect */
               if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
-                 bsendmsg(ua, "%s", db_strerror(ua->db));
+                  bsendmsg(ua, "%s", db_strerror(ua->db));
               }
            } else {
-              bsendmsg(ua, "Catalog error on cleaning tape: %s", db_strerror(ua->db));
+               bsendmsg(ua, "Catalog error on cleaning tape: %s", db_strerror(ua->db));
            }
         }
         continue;                    /* done, go handle next volume */
@@ -558,20 +558,20 @@ bool is_volume_name_legal(UAContext *ua, const char *name)
         continue;
       }
       if (ua) {
-        bsendmsg(ua, _("Illegal character \"%c\" in a volume name.\n"), *p);
+         bsendmsg(ua, _("Illegal character \"%c\" in a volume name.\n"), *p);
       }
       return 0;
    }
    len = strlen(name);
    if (len >= MAX_NAME_LENGTH) {
       if (ua) {
-        bsendmsg(ua, _("Volume name too long.\n"));
+         bsendmsg(ua, _("Volume name too long.\n"));
       }
       return 0;
    }
    if (len == 0) {
       if (ua) {
-        bsendmsg(ua, _("Volume name must be at least one character long.\n"));
+         bsendmsg(ua, _("Volume name must be at least one character long.\n"));
       }
       return 0;
    }
@@ -591,7 +591,7 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    if (!(sd=open_sd_bsock(ua))) {
       return false;
    }
-   bstrncpy(dev_name, ua->jcr->store->dev_name, sizeof(dev_name));
+   bstrncpy(dev_name, ua->jcr->store->dev_name(), sizeof(dev_name));
    bash_spaces(dev_name);
    bash_spaces(mr->VolumeName);
    bash_spaces(mr->MediaType);
@@ -626,7 +626,7 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
         mr->VolBytes = 1;
         mr->InChanger = 1;
         if (!db_update_media_record(ua->jcr, ua->db, mr)) {
-            bsendmsg(ua, "%s", db_strerror(ua->db));
+             bsendmsg(ua, "%s", db_strerror(ua->db));
             ok = false;
         }
       } else {                       /* create the media record */
@@ -634,15 +634,15 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
         mr->VolBytes = 1;               /* flag indicating Volume labeled */
         mr->InChanger = 1;
         if (db_create_media_record(ua->jcr, ua->db, mr)) {
-           bsendmsg(ua, _("Catalog record for Volume \"%s\", Slot %d  successfully created.\n"),
+            bsendmsg(ua, _("Catalog record for Volume \"%s\", Slot %d  successfully created.\n"),
            mr->VolumeName, mr->Slot);
            /* Update number of volumes in pool */
            pr->NumVols++;
            if (!db_update_pool_record(ua->jcr, ua->db, pr)) {
-              bsendmsg(ua, "%s", db_strerror(ua->db));
+               bsendmsg(ua, "%s", db_strerror(ua->db));
            }
         } else {
-           bsendmsg(ua, "%s", db_strerror(ua->db));
+            bsendmsg(ua, "%s", db_strerror(ua->db));
            ok = false;
         }
       }
@@ -660,7 +660,7 @@ static BSOCK *open_sd_bsock(UAContext *ua)
       bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d ...\n"),
         store->hdr.name, store->address, store->SDport);
       if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
-        bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
+         bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
         return NULL;
       }
    }
@@ -688,7 +688,7 @@ static char *get_volume_name_from_SD(UAContext *ua, int Slot)
       bsendmsg(ua, _("Could not open SD socket.\n"));
       return NULL;
    }
-   bstrncpy(dev_name, store->dev_name, sizeof(dev_name));
+   bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
    bash_spaces(dev_name);
    /* Ask for autochanger list of volumes */
    bnet_fsend(sd, _("readlabel %s Slot=%d\n"), dev_name, Slot);
@@ -700,7 +700,7 @@ static char *get_volume_name_from_SD(UAContext *ua, int Slot)
       Dmsg1(100, "Got: %s", sd->msg);
       if (strncmp(sd->msg, "3001 Volume=", 12) == 0) {
         VolName = (char *)malloc(sd->msglen);
-        if (sscanf(sd->msg, "3001 Volume=%s Slot=%d", VolName, &rtn_slot) == 2) {
+         if (sscanf(sd->msg, "3001 Volume=%s Slot=%d", VolName, &rtn_slot) == 2) {
            break;
         }
         free(VolName);
@@ -730,7 +730,7 @@ static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan)
       return NULL;
    }
 
-   bstrncpy(dev_name, store->dev_name, sizeof(dev_name));
+   bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
    bash_spaces(dev_name);
    /* Ask for autochanger list of volumes */
    bnet_fsend(sd, _("autochanger list %s \n"), dev_name);
@@ -744,8 +744,8 @@ static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan)
       /* Check for returned SD messages */
       if (sd->msg[0] == '3'     && B_ISDIGIT(sd->msg[1]) &&
          B_ISDIGIT(sd->msg[2]) && B_ISDIGIT(sd->msg[3]) &&
-         sd->msg[4] == ' ') {
-        bsendmsg(ua, "%s\n", sd->msg);   /* pass them on to user */
+          sd->msg[4] == ' ') {
+         bsendmsg(ua, "%s\n", sd->msg);   /* pass them on to user */
         continue;
       }
 
@@ -756,8 +756,8 @@ static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan)
         Slot = atoi(sd->msg);
         if (Slot <= 0) {
            p--;
-           *p = ':';
-           bsendmsg(ua, _("Invalid Slot number: %s\n"), sd->msg);
+            *p = ':';
+            bsendmsg(ua, _("Invalid Slot number: %s\n"), sd->msg);
            continue;
         }
       } else {
@@ -766,8 +766,8 @@ static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan)
            *p++ = 0;
            if (!is_an_integer(sd->msg) || (Slot=atoi(sd->msg)) <= 0) {
               p--;
-              *p = ':';
-              bsendmsg(ua, _("Invalid Slot number: %s\n"), sd->msg);
+               *p = ':';
+               bsendmsg(ua, _("Invalid Slot number: %s\n"), sd->msg);
               continue;
            }
         } else {
@@ -775,8 +775,8 @@ static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan)
         }
         if (!is_volume_name_legal(ua, p)) {
            p--;
-           *p = ':';
-           bsendmsg(ua, _("Invalid Volume name: %s\n"), sd->msg);
+            *p = ':';
+            bsendmsg(ua, _("Invalid Volume name: %s\n"), sd->msg);
            continue;
         }
       }
@@ -785,7 +785,7 @@ static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan)
       vl = (vol_list_t *)malloc(sizeof(vol_list_t));
       vl->Slot = Slot;
       if (p) {
-        if (*p == ':') {
+         if (*p == ':') {
            p++;                      /* skip separator */
         }
         vl->VolName = bstrdup(p);
index 41ad6b3cc250a33e06716269a7c46129f1584af3..55420662804cf173d4b41f31cd518a2087b8c25f 100644 (file)
@@ -105,6 +105,7 @@ static struct showstruct reses[] = {
    {N_("directors"),  R_DIRECTOR},
    {N_("clients"),    R_CLIENT},
    {N_("counters"),   R_COUNTER},
+   {N_("devices"),    R_DEVICE},
    {N_("jobs"),       R_JOB},
    {N_("storages"),   R_STORAGE},
    {N_("catalogs"),   R_CATALOG},
@@ -149,7 +150,6 @@ int show_cmd(UAContext *ua, const char *cmd)
               type = reses[j].type;
               if (type > 0) {
                  res = res_head[type-r_first];
-//               res = resources[type-r_first].res_head;
               } else {
                  res = NULL;
               }
@@ -177,20 +177,19 @@ int show_cmd(UAContext *ua, const char *cmd)
       case -1:                          /* all */
         for (j=r_first; j<=r_last; j++) {
            dump_resource(j, res_head[j-r_first], bsendmsg, ua);
-//         dump_resource(j, resources[j-r_first].res_head, bsendmsg, ua);
         }
         break;
       case -2:
-        bsendmsg(ua, _("Keywords for the show command are:\n"));
+         bsendmsg(ua, _("Keywords for the show command are:\n"));
         for (j=0; reses[j].res_name; j++) {
-           bsendmsg(ua, "%s\n", _(reses[j].res_name));
+            bsendmsg(ua, "%s\n", _(reses[j].res_name));
         }
         goto bail_out;
       case -3:
-        bsendmsg(ua, _("%s resource %s not found.\n"), res_name, ua->argv[i]);
+         bsendmsg(ua, _("%s resource %s not found.\n"), res_name, ua->argv[i]);
         goto bail_out;
       case 0:
-        bsendmsg(ua, _("Resource %s not found\n"), res_name);
+         bsendmsg(ua, _("Resource %s not found\n"), res_name);
         goto bail_out;
       default:
         dump_resource(recurse?type:-type, res, bsendmsg, ua);
@@ -272,7 +271,7 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
       /* List JOBID */
       } else if (strcasecmp(ua->argk[i], _("jobid")) == 0) {
         if (ua->argv[i]) {
-           jobid = atoi(ua->argv[i]);
+           jobid = str_to_int64(ua->argv[i]);
            if (jobid > 0) {
               jr.JobId = jobid;
               db_list_job_records(ua->jcr, ua->db, &jr, prtit, ua, llist);
@@ -289,13 +288,13 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
       } else if (strcasecmp(ua->argk[i], _("files")) == 0) {
 
         for (j=i+1; j<ua->argc; j++) {
-           if (strcasecmp(ua->argk[j], _("job")) == 0 && ua->argv[j]) {
+            if (strcasecmp(ua->argk[j], _("job")) == 0 && ua->argv[j]) {
               bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH);
               jr.JobId = 0;
               db_get_job_record(ua->jcr, ua->db, &jr);
               jobid = jr.JobId;
-           } else if (strcasecmp(ua->argk[j], _("jobid")) == 0 && ua->argv[j]) {
-              jobid = atoi(ua->argv[j]);
+            } else if (strcasecmp(ua->argk[j], _("jobid")) == 0 && ua->argv[j]) {
+              jobid = str_to_int64(ua->argv[j]);
            } else {
               continue;
            }
@@ -308,13 +307,13 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
       } else if (strcasecmp(ua->argk[i], _("jobmedia")) == 0) {
         int done = FALSE;
         for (j=i+1; j<ua->argc; j++) {
-           if (strcasecmp(ua->argk[j], _("job")) == 0 && ua->argv[j]) {
+            if (strcasecmp(ua->argk[j], _("job")) == 0 && ua->argv[j]) {
               bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH);
               jr.JobId = 0;
               db_get_job_record(ua->jcr, ua->db, &jr);
               jobid = jr.JobId;
-           } else if (strcasecmp(ua->argk[j], _("jobid")) == 0 && ua->argv[j]) {
-              jobid = atoi(ua->argv[j]);
+            } else if (strcasecmp(ua->argk[j], _("jobid")) == 0 && ua->argv[j]) {
+              jobid = str_to_int64(ua->argv[j]);
            } else {
               continue;
            }
@@ -336,22 +335,22 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
 
       /* List MEDIA or VOLUMES */
       } else if (strcasecmp(ua->argk[i], _("media")) == 0 ||
-                strcasecmp(ua->argk[i], _("volumes")) == 0) {
+                 strcasecmp(ua->argk[i], _("volumes")) == 0) {
         bool done = false;
         for (j=i+1; j<ua->argc; j++) {
-           if (strcasecmp(ua->argk[j], _("job")) == 0 && ua->argv[j]) {
+            if (strcasecmp(ua->argk[j], _("job")) == 0 && ua->argv[j]) {
               bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH);
               jr.JobId = 0;
               db_get_job_record(ua->jcr, ua->db, &jr);
               jobid = jr.JobId;
-           } else if (strcasecmp(ua->argk[j], _("jobid")) == 0 && ua->argv[j]) {
-              jobid = atoi(ua->argv[j]);
+            } else if (strcasecmp(ua->argk[j], _("jobid")) == 0 && ua->argv[j]) {
+              jobid = str_to_int64(ua->argv[j]);
            } else {
               continue;
            }
            VolumeName = get_pool_memory(PM_FNAME);
            n = db_get_job_volume_names(ua->jcr, ua->db, jobid, &VolumeName);
-           bsendmsg(ua, _("Jobid %d used %d Volume(s): %s\n"), jobid, n, VolumeName);
+            bsendmsg(ua, _("Jobid %d used %d Volume(s): %s\n"), jobid, n, VolumeName);
            free_pool_memory(VolumeName);
            done = true;
         }
@@ -361,9 +360,9 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
            uint32_t *ids;
            /* Is a specific pool wanted? */
            for (i=1; i<ua->argc; i++) {
-              if (strcasecmp(ua->argk[i], _("pool")) == 0) {
+               if (strcasecmp(ua->argk[i], _("pool")) == 0) {
                  if (!get_pool_dbr(ua, &pr)) {
-                    bsendmsg(ua, _("No Pool specified.\n"));
+                     bsendmsg(ua, _("No Pool specified.\n"));
                     return 1;
                  }
                  mr.PoolId = pr.PoolId;
@@ -373,7 +372,7 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
            }
            /* List Volumes in all pools */
            if (!db_get_pool_ids(ua->jcr, ua->db, &num_pools, &ids)) {
-              bsendmsg(ua, _("Error obtaining pool ids. ERR=%s\n"),
+               bsendmsg(ua, _("Error obtaining pool ids. ERR=%s\n"),
                        db_strerror(ua->db));
               return 1;
            }
@@ -383,7 +382,7 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
            for (i=0; i < num_pools; i++) {
               pr.PoolId = ids[i];
               if (db_get_pool_record(ua->jcr, ua->db, &pr)) {
-                 bsendmsg(ua, _("Pool: %s\n"), pr.Name);
+                  bsendmsg(ua, _("Pool: %s\n"), pr.Name);
               }
               mr.PoolId = ids[i];
               db_list_media_records(ua->jcr, ua->db, &mr, prtit, ua, llist);
@@ -394,7 +393,7 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
       /* List a specific volume */
       } else if (strcasecmp(ua->argk[i], _("volume")) == 0) {
         if (!ua->argv[i]) {
-           bsendmsg(ua, _("No Volume Name specified.\n"));
+            bsendmsg(ua, _("No Volume Name specified.\n"));
            return 1;
         }
         bstrncpy(mr.VolumeName, ua->argv[i], sizeof(mr.VolumeName));
@@ -402,10 +401,10 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
         return 1;
       /* List next volume */
       } else if (strcasecmp(ua->argk[i], _("nextvol")) == 0 ||
-                strcasecmp(ua->argk[i], _("nextvolume")) == 0) {
+                 strcasecmp(ua->argk[i], _("nextvolume")) == 0) {
         list_nextvol(ua);
       } else {
-        bsendmsg(ua, _("Unknown list keyword: %s\n"), NPRT(ua->argk[i]));
+         bsendmsg(ua, _("Unknown list keyword: %s\n"), NPRT(ua->argk[i]));
       }
    }
    return 1;
@@ -430,7 +429,7 @@ static bool list_nextvol(UAContext *ua)
    } else {
       job = (JOB *)GetResWithName(R_JOB, ua->argv[i]);
       if (!job) {
-        Jmsg(jcr, M_ERROR, 0, _("%s is not a job name.\n"), ua->argv[i]);
+         Jmsg(jcr, M_ERROR, 0, _("%s is not a job name.\n"), ua->argv[i]);
         if ((job = select_job_resource(ua)) == NULL) {
            return false;
         }
@@ -443,9 +442,9 @@ static bool list_nextvol(UAContext *ua)
       }
 
       if (!find_next_volume_for_append(jcr, &mr, 0)) {
-        bsendmsg(ua, _("Could not find next Volume.\n"));
+         bsendmsg(ua, _("Could not find next Volume.\n"));
       } else {
-        bsendmsg(ua, _("The next Volume to be used by Job \"%s\" will be %s\n"),
+         bsendmsg(ua, _("The next Volume to be used by Job \"%s\" will be %s\n"),
            job->hdr.name, mr.VolumeName);
         found = true;
       }
@@ -525,15 +524,15 @@ RUN *find_next_run(RUN *run, JOB *job, time_t &runtime)
       if (tod) {                  /* Jobs scheduled today (next 24 hours) */
 #ifdef xxx
         char buf[300], num[10];
-        bsnprintf(buf, sizeof(buf), "tm.hour=%d hour=", tm.tm_hour);
+         bsnprintf(buf, sizeof(buf), "tm.hour=%d hour=", tm.tm_hour);
         for (i=0; i<24; i++) {
            if (bit_is_set(i, run->hour)) {
-              bsnprintf(num, sizeof(num), "%d ", i);
+               bsnprintf(num, sizeof(num), "%d ", i);
               bstrncat(buf, num, sizeof(buf));
            }
         }
-        bstrncat(buf, "\n", sizeof(buf));
-        Dmsg1(000, "%s", buf);
+         bstrncat(buf, "\n", sizeof(buf));
+         Dmsg1(000, "%s", buf);
 #endif
         /* find time (time_t) job is to be run */
         localtime_r(&now, &tm);
@@ -543,9 +542,9 @@ RUN *find_next_run(RUN *run, JOB *job, time_t &runtime)
               tm.tm_min = run->minute;
               tm.tm_sec = 0;
               runtime = mktime(&tm);
-              Dmsg2(200, "now=%d runtime=%d\n", now, runtime);
+               Dmsg2(200, "now=%d runtime=%d\n", now, runtime);
               if (runtime > now) {
-                 Dmsg2(200, "Found it level=%d %c\n", run->level, run->level);
+                  Dmsg2(200, "Found it level=%d %c\n", run->level, run->level);
                  return run;         /* found it, return run resource */
               }
            }
@@ -561,9 +560,9 @@ RUN *find_next_run(RUN *run, JOB *job, time_t &runtime)
               tm.tm_min = run->minute;
               tm.tm_sec = 0;
               runtime = mktime(&tm);
-              Dmsg2(200, "now=%d runtime=%d\n", now, runtime);
+               Dmsg2(200, "now=%d runtime=%d\n", now, runtime);
               if (runtime < tomorrow) {
-                 Dmsg2(200, "Found it level=%d %c\n", run->level, run->level);
+                  Dmsg2(200, "Found it level=%d %c\n", run->level, run->level);
                  return run;         /* found it, return run resource */
               }
            }
@@ -594,7 +593,7 @@ int complete_jcr_for_job(JCR *jcr, JOB *job, POOL *pool)
       Jmsg(jcr, M_FATAL, 0, _("Could not open database \"%s\".\n"),
                 jcr->catalog->db_name);
       if (jcr->db) {
-        Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
+         Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
       }
       return 0;
    }
@@ -602,7 +601,7 @@ int complete_jcr_for_job(JCR *jcr, JOB *job, POOL *pool)
    while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
       /* Try to create the pool */
       if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
-        Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
+         Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
            db_strerror(jcr->db));
         if (jcr->db) {
            db_close_database(jcr, jcr->db);
@@ -610,7 +609,7 @@ int complete_jcr_for_job(JCR *jcr, JOB *job, POOL *pool)
         }
         return 0;
       } else {
-        Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
+         Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
       }
    }
    jcr->PoolId = pr.PoolId;
index 9b18ac9406972c70dc089cec07ac4dbb66fad607..8c22b602043e585261322462b60e4c86f6399aa9 100644 (file)
@@ -106,16 +106,16 @@ int querycmd(UAContext *ua, const char *cmd)
       len = strlen(line);
       if (line[0] == '*') {            /* prompt */
         if (nprompt >= 9) {
-           bsendmsg(ua, _("Too many prompts in query, max is 9.\n"));
+            bsendmsg(ua, _("Too many prompts in query, max is 9.\n"));
         } else {
-           line[len++] = ' ';
+            line[len++] = ' ';
            line[len] = 0;
            prompt[nprompt++] = bstrdup(line+1);
            continue;
         }
       }
       if (*query != 0) {
-        pm_strcat(query, " ");
+         pm_strcat(query, " ");
       }
       pm_strcat(query, line);
       if (line[len-1] != ';') {
@@ -124,11 +124,11 @@ int querycmd(UAContext *ua, const char *cmd)
       line[len-1] = 0;            /* zap ; */
       if (query[0] != 0) {
         query = substitute_prompts(ua, query, prompt, nprompt);
-        Dmsg1(100, "Query2=%s\n", query);
-        if (query[0] == '!') {
+         Dmsg1(100, "Query2=%s\n", query);
+         if (query[0] == '!') {
            db_list_sql_query(ua->jcr, ua->db, query+1, prtit, ua, 0, VERT_LIST);
         } else if (!db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST)) {
-           bsendmsg(ua, "%s\n", query);
+            bsendmsg(ua, "%s\n", query);
         }
         query[0] = 0;
       }
@@ -137,10 +137,10 @@ int querycmd(UAContext *ua, const char *cmd)
    if (query[0] != 0) {
       query = substitute_prompts(ua, query, prompt, nprompt);
       Dmsg1(100, "Query2=%s\n", query);
-        if (query[0] == '!') {
+         if (query[0] == '!') {
            db_list_sql_query(ua->jcr, ua->db, query+1, prtit, ua, 0, VERT_LIST);
         } else if (!db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST)) {
-           bsendmsg(ua, "%s\n", query);
+            bsendmsg(ua, "%s\n", query);
         }
    }
 
@@ -181,16 +181,16 @@ static POOLMEM *substitute_prompts(UAContext *ua,
         }
         p++;
         switch (*p) {
-        case '1':
-        case '2':
-        case '3':
-        case '4':
-        case '5':
-        case '6':
-        case '7':
-        case '8':
-        case '9':
-           n = (int)(*p) - (int)'1';
+         case '1':
+         case '2':
+         case '3':
+         case '4':
+         case '5':
+         case '6':
+         case '7':
+         case '8':
+         case '9':
+            n = (int)(*p) - (int)'1';
            if (prompt[n]) {
               if (!subst[n]) {
                  if (!get_cmd(ua, prompt[n])) {
@@ -209,16 +209,16 @@ static POOLMEM *substitute_prompts(UAContext *ua,
                  *o++ = *p++;
               }
            } else {
-              bsendmsg(ua, _("Warning prompt %d missing.\n"), n+1);
+               bsendmsg(ua, _("Warning prompt %d missing.\n"), n+1);
            }
            q += 2;
            break;
-        case '%':
-           *o++ = '%';
+         case '%':
+            *o++ = '%';
            q += 2;
            break;
         default:
-           *o++ = '%';
+            *o++ = '%';
            q++;
            break;
         }
@@ -267,17 +267,17 @@ int sqlquerycmd(UAContext *ua, const char *cmd)
       }
       query = check_pool_memory_size(query, len + 1);
       if (*query != 0) {
-        strcat(query, " ");
+         pm_strcat(query, " ");
       }
-      strcat(query, ua->cmd);
+      pm_strcat(query, ua->cmd);
       if (ua->cmd[len-1] == ';') {
         ua->cmd[len-1] = 0;          /* zap ; */
         /* Submit query */
         db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
         *query = 0;                  /* start new query */
-        msg = _("Enter SQL query: ");
+         msg = _("Enter SQL query: ");
       } else {
-        msg = _("Add to SQL query: ");
+         msg = _("Add to SQL query: ");
       }
    }
    free_pool_memory(query);
index a62b4ec9612dde4d852197529ced8a93e5ff9387..d4ca3b1b2a9fb0572da50ec8462ad90a0520b6cc 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 /*
-   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
@@ -149,8 +149,8 @@ int restore_cmd(UAContext *ua, const char *cmd)
    UnlockRes();
    if (!rx.restore_jobs) {
       bsendmsg(ua, _(
-        "No Restore Job Resource found. You must create at least\n"
-        "one before running this command.\n"));
+         "No Restore Job Resource found. You must create at least\n"
+         "one before running this command.\n"));
       goto bail_out;
    }
 
@@ -165,7 +165,7 @@ int restore_cmd(UAContext *ua, const char *cmd)
       goto bail_out;
    case 1:                           /* select by jobid */
       if (!build_directory_tree(ua, &rx)) {
-        bsendmsg(ua, _("Restore not done.\n"));
+         bsendmsg(ua, _("Restore not done.\n"));
         goto bail_out;
       }
       break;
@@ -175,14 +175,14 @@ int restore_cmd(UAContext *ua, const char *cmd)
 
    if (rx.bsr->JobId) {
       if (!complete_bsr(ua, rx.bsr)) {  /* find Vol, SessId, SessTime from JobIds */
-        bsendmsg(ua, _("Unable to construct a valid BSR. Cannot continue.\n"));
+         bsendmsg(ua, _("Unable to construct a valid BSR. Cannot continue.\n"));
         goto bail_out;
       }
       if (!write_bsr_file(ua, rx.bsr)) {
         goto bail_out;
       }
       bsendmsg(ua, _("\n%u file%s selected to be restored.\n\n"), rx.selected_files,
-        rx.selected_files==1?"":"s");
+         rx.selected_files==1?"":"s");
    } else {
       bsendmsg(ua, _("No files selected to be restored.\n"));
       goto bail_out;
@@ -206,15 +206,15 @@ int restore_cmd(UAContext *ua, const char *cmd)
    /* Build run command */
    if (rx.where) {
       Mmsg(ua->cmd,
-         "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\""
-         " where=\"%s\" files=%d catalog=\"%s\"",
-         job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"",
+          "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\""
+          " where=\"%s\" files=%d catalog=\"%s\"",
+          job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"",
          working_directory, rx.where, rx.selected_files, ua->catalog->hdr.name);
    } else {
       Mmsg(ua->cmd,
-         "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\""
-         " files=%d catalog=\"%s\"",
-         job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"",
+          "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\""
+          " files=%d catalog=\"%s\"",
+          job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"",
          working_directory, rx.selected_files, ua->catalog->hdr.name);
    }
    if (find_arg(ua, _("yes")) > 0) {
@@ -329,14 +329,14 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
         }
       }
       if (!found_kw) {
-        bsendmsg(ua, _("Unknown keyword: %s\n"), ua->argk[i]);
+         bsendmsg(ua, _("Unknown keyword: %s\n"), ua->argk[i]);
         return 0;
       }
       /* Found keyword in kw[] list, process it */
       switch (j) {
       case 0:                           /* jobid */
         if (*rx->JobIds != 0) {
-           pm_strcat(rx->JobIds, ",");
+            pm_strcat(rx->JobIds, ",");
         }
         pm_strcat(rx->JobIds, ua->argv[i]);
         done = true;
@@ -347,7 +347,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
         break;
       case 2:                           /* before */
         if (str_to_utime(ua->argv[i]) == 0) {
-           bsendmsg(ua, _("Improper date format: %s\n"), ua->argv[i]);
+            bsendmsg(ua, _("Improper date format: %s\n"), ua->argv[i]);
            return 0;
         }
         bstrncpy(date, ua->argv[i], sizeof(date));
@@ -380,12 +380,12 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
       case 5:                           /* pool specified */
         rx->pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]);
         if (!rx->pool) {
-           bsendmsg(ua, _("Error: Pool resource \"%s\" does not exist.\n"), ua->argv[i]);
+            bsendmsg(ua, _("Error: Pool resource \"%s\" does not exist.\n"), ua->argv[i]);
            return 0;
         }
         if (!acl_access_ok(ua, Pool_ACL, ua->argv[i])) {
            rx->pool = NULL;
-           bsendmsg(ua, _("Error: Pool resource \"%s\" access not allowed.\n"), ua->argv[i]);
+            bsendmsg(ua, _("Error: Pool resource \"%s\" access not allowed.\n"), ua->argv[i]);
            return 0;
         }
         break;
@@ -405,9 +405,9 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
 
    if (!done) {
       bsendmsg(ua, _("\nFirst you select one or more JobIds that contain files\n"
-                 "to be restored. You will be presented several methods\n"
-                 "of specifying the JobIds. Then you will be allowed to\n"
-                 "select which files from those JobIds are to be restored.\n\n"));
+                  "to be restored. You will be presented several methods\n"
+                  "of specifying the JobIds. Then you will be allowed to\n"
+                  "select which files from those JobIds are to be restored.\n\n"));
    }
 
    /* If choice not already made above, prompt */
@@ -432,7 +432,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
         done = false;
         break;
       case 1:                        /* list where a file is saved */
-        if (!get_cmd(ua, _("Enter Filename (no path):"))) {
+         if (!get_cmd(ua, _("Enter Filename (no path):"))) {
            return 0;
         }
         len = strlen(ua->cmd);
@@ -447,13 +447,13 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
         done = false;
         break;
       case 2:                        /* enter a list of JobIds */
-        if (!get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) {
+         if (!get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) {
            return 0;
         }
         pm_strcpy(rx->JobIds, ua->cmd);
         break;
       case 3:                        /* Enter an SQL list command */
-        if (!get_cmd(ua, _("Enter SQL list command: "))) {
+         if (!get_cmd(ua, _("Enter SQL list command: "))) {
            return 0;
         }
         gui_save = ua->jcr->gui;
@@ -481,11 +481,11 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
         if (!get_client_name(ua, rx)) {
            return 0;
         }
-        bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n"
-                       "containg a list of file names with paths, and terminate\n"
-                       "them with a blank line.\n"));
+         bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n"
+                        "containg a list of file names with paths, and terminate\n"
+                        "them with a blank line.\n"));
         for ( ;; ) {
-           if (!get_cmd(ua, _("Enter full filename: "))) {
+            if (!get_cmd(ua, _("Enter full filename: "))) {
               return 0;
            }
            len = strlen(ua->cmd);
@@ -506,11 +506,11 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
         if (!get_client_name(ua, rx)) {
            return 0;
         }
-        bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n"
-                       "containg a list of file names with paths, and terminate\n"
-                       "them with a blank line.\n"));
+         bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n"
+                        "containg a list of file names with paths, and terminate\n"
+                        "them with a blank line.\n"));
         for ( ;; ) {
-           if (!get_cmd(ua, _("Enter full filename: "))) {
+            if (!get_cmd(ua, _("Enter full filename: "))) {
               return 0;
            }
            len = strlen(ua->cmd);
@@ -544,7 +544,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
    for (p=rx->JobIds; ; ) {
       int stat = get_next_jobid_from_list(&p, &JobId);
       if (stat < 0) {
-        bsendmsg(ua, _("Invalid JobId in list.\n"));
+         bsendmsg(ua, _("Invalid JobId in list.\n"));
         return 0;
       }
       if (stat == 0) {
@@ -555,12 +555,12 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
       }
       jr.JobId = JobId;
       if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
-        bsendmsg(ua, _("Unable to get Job record for JobId=%u: ERR=%s\n"),
+         bsendmsg(ua, _("Unable to get Job record for JobId=%u: ERR=%s\n"),
            JobId, db_strerror(ua->db));
         return 0;
       }
       if (!acl_access_ok(ua, Job_ACL, jr.Name)) {
-        bsendmsg(ua, _("No authorization. Job \"%s\" not selected.\n"),
+         bsendmsg(ua, _("No authorization. Job \"%s\" not selected.\n"),
            jr.Name);
         continue;
       }
@@ -575,7 +575,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
 static int get_date(UAContext *ua, char *date, int date_len)
 {
    bsendmsg(ua, _("The restored files will the most current backup\n"
-                 "BEFORE the date you specify below.\n\n"));
+                  "BEFORE the date you specify below.\n\n"));
    for ( ;; ) {
       if (!get_cmd(ua, _("Enter date as YYYY-MM-DD HH:MM:SS :"))) {
         return 0;
@@ -603,14 +603,15 @@ static void insert_one_file(UAContext *ua, RESTORE_CTX *rx, char *date)
    case '<':
       p++;
       if ((ffd = fopen(p, "r")) == NULL) {
-        bsendmsg(ua, _("Cannot open file %s: ERR=%s\n"),
-           p, strerror(errno));
+        berrno be;
+         bsendmsg(ua, _("Cannot open file %s: ERR=%s\n"),
+           p, be.strerror());
         break;
       }
       while (fgets(file, sizeof(file), ffd)) {
         line++;
         if (!insert_file_into_findex_list(ua, rx, file, date)) {
-           bsendmsg(ua, _("Error occurred on line %d of %s\n"), line, p);
+            bsendmsg(ua, _("Error occurred on line %d of %s\n"), line, p);
         }
       }
       fclose(ffd);
@@ -734,7 +735,7 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx)
       /* Use first JobId as estimate of the number of files to restore */
       Mmsg(rx->query, uar_count_files, JobId);
       if (!db_sql_query(ua->db, rx->query, count_handler, (void *)rx)) {
-        bsendmsg(ua, "%s\n", db_strerror(ua->db));
+         bsendmsg(ua, "%s\n", db_strerror(ua->db));
       }
       if (rx->found) {
         /* Add about 25% more than this job for over estimate */
@@ -755,14 +756,14 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx)
        */
       Mmsg(rx->query, uar_sel_files, JobId);
       if (!db_sql_query(ua->db, rx->query, insert_tree_handler, (void *)&tree)) {
-        bsendmsg(ua, "%s", db_strerror(ua->db));
+         bsendmsg(ua, "%s", db_strerror(ua->db));
       }
       /*
        * Find the MediaTypes for this JobId and add to the name_list
        */
       Mmsg(rx->query, uar_mediatype, JobId);
       if (!db_sql_query(ua->db, rx->query, unique_name_list_handler, (void *)&rx->name_list)) {
-        bsendmsg(ua, "%s", db_strerror(ua->db));
+         bsendmsg(ua, "%s", db_strerror(ua->db));
       }
    }
    char ec1[50];
@@ -784,9 +785,9 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx)
     */
    if (OK) {
       for (TREE_NODE *node=first_tree_node(tree.root); node; node=next_tree_node(node)) {
-        Dmsg2(400, "FI=%d node=0x%x\n", node->FileIndex, node);
+         Dmsg2(400, "FI=%d node=0x%x\n", node->FileIndex, node);
         if (node->extract || node->extract_dir) {
-           Dmsg2(400, "type=%d FI=%d\n", node->type, node->FileIndex);
+            Dmsg2(400, "type=%d FI=%d\n", node->type, node->FileIndex);
            add_findex(rx->bsr, node->JobId, node->FileIndex);
            if (node->extract && node->type != TN_NEWDIR) {
               rx->selected_files++;  /* count only saved files */
@@ -841,7 +842,7 @@ static int select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *date
    if (i >= 0) {
       bstrncpy(fsr.FileSet, ua->argv[i], sizeof(fsr.FileSet));
       if (!db_get_fileset_record(ua->jcr, ua->db, &fsr)) {
-        bsendmsg(ua, _("Error getting FileSet \"%s\": ERR=%s\n"), fsr.FileSet,
+         bsendmsg(ua, _("Error getting FileSet \"%s\": ERR=%s\n"), fsr.FileSet,
            db_strerror(ua->db));
         i = -1;
       }
@@ -850,7 +851,7 @@ static int select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *date
       Mmsg(rx->query, uar_sel_fileset, cr.ClientId, cr.ClientId);
       start_prompt(ua, _("The defined FileSet resources are:\n"));
       if (!db_sql_query(ua->db, rx->query, fileset_handler, (void *)ua)) {
-        bsendmsg(ua, "%s\n", db_strerror(ua->db));
+         bsendmsg(ua, "%s\n", db_strerror(ua->db));
       }
       if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"),
                 fileset_name, sizeof(fileset_name)) < 0) {
@@ -859,9 +860,9 @@ static int select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *date
 
       bstrncpy(fsr.FileSet, fileset_name, sizeof(fsr.FileSet));
       if (!db_get_fileset_record(ua->jcr, ua->db, &fsr)) {
-        bsendmsg(ua, _("Error getting FileSet record: %s\n"), db_strerror(ua->db));
-        bsendmsg(ua, _("This probably means you modified the FileSet.\n"
-                    "Continuing anyway.\n"));
+         bsendmsg(ua, _("Error getting FileSet record: %s\n"), db_strerror(ua->db));
+         bsendmsg(ua, _("This probably means you modified the FileSet.\n"
+                     "Continuing anyway.\n"));
       }
    }
 
@@ -872,9 +873,9 @@ static int select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *date
       memset(&pr, 0, sizeof(pr));
       bstrncpy(pr.Name, rx->pool->hdr.name, sizeof(pr.Name));
       if (db_get_pool_record(ua->jcr, ua->db, &pr)) {
-        bsnprintf(pool_select, sizeof(pool_select), "AND Media.PoolId=%u ", pr.PoolId);
+         bsnprintf(pool_select, sizeof(pool_select), "AND Media.PoolId=%u ", pr.PoolId);
       } else {
-        bsendmsg(ua, _("Pool \"%s\" not found, using any pool.\n"), pr.Name);
+         bsendmsg(ua, _("Pool \"%s\" not found, using any pool.\n"), pr.Name);
       }
    }
 
@@ -968,14 +969,14 @@ static int get_next_jobid_from_list(char **p, uint32_t *JobId)
       return 0;
    }
    *p = q;
-   *JobId = strtoul(jobid, NULL, 10);
+   *JobId = str_to_int64(jobid);
    return 1;
 }
 
 static int count_handler(void *ctx, int num_fields, char **row)
 {
    RESTORE_CTX *rx = (RESTORE_CTX *)ctx;
-   rx->JobId = atoi(row[0]);
+   rx->JobId = str_to_int64(row[0]);
    rx->found = true;
    return 0;
 }
@@ -986,8 +987,8 @@ static int count_handler(void *ctx, int num_fields, char **row)
 static int jobid_fileindex_handler(void *ctx, int num_fields, char **row)
 {
    RESTORE_CTX *rx = (RESTORE_CTX *)ctx;
-   rx->JobId = atoi(row[0]);
-   add_findex(rx->bsr, rx->JobId, atoi(row[1]));
+   rx->JobId = str_to_int64(row[0]);
+   add_findex(rx->bsr, rx->JobId, str_to_int64(row[1]));
    rx->found = true;
    return 0;
 }
@@ -1100,7 +1101,7 @@ static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, REST
 
    if (name_list->num_ids > 1) {
       bsendmsg(ua, _("Warning, the JobIds that you selected refer to more than one MediaType.\n"
-        "Restore is not possible. The MediaTypes used are:\n"));
+         "Restore is not possible. The MediaTypes used are:\n"));
       print_name_list(ua, name_list);
       rx->store = select_storage_resource(ua);
       return;
@@ -1139,7 +1140,7 @@ static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, REST
         }
       }
       if (store && (store != rx->store)) {
-        bsendmsg(ua, _("Warning default storage overridden by %s on command line.\n"),
+         bsendmsg(ua, _("Warning default storage overridden by %s on command line.\n"),
            store->hdr.name);
         rx->store = store;
       }
@@ -1151,8 +1152,8 @@ static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, REST
 
    if (!rx->store) {
       bsendmsg(ua, _("\nWarning. Unable to find Storage resource for\n"
-        "MediaType \"%s\", needed by the Jobs you selected.\n"
-        "You will be allowed to select a Storage device later.\n"),
+         "MediaType \"%s\", needed by the Jobs you selected.\n"
+         "You will be allowed to select a Storage device later.\n"),
         name_list->name[0]);
    }
 }
index f9e61a47bde0a6af6943a449a066d43abf3550fe..2b770e173a50fffae73f7f8c85ea4a608258baaf 100644 (file)
@@ -126,7 +126,7 @@ int run_cmd(UAContext *ua, const char *cmd)
               break;
            case 1: /* JobId */
               if (jid) {
-                 bsendmsg(ua, _("JobId specified twice.\n"));
+                  bsendmsg(ua, _("JobId specified twice.\n"));
                  return 0;
               }
               jid = ua->argv[i];
@@ -135,7 +135,7 @@ int run_cmd(UAContext *ua, const char *cmd)
            case 2: /* client */
            case 3: /* fd */
               if (client_name) {
-                 bsendmsg(ua, _("Client specified twice.\n"));
+                  bsendmsg(ua, _("Client specified twice.\n"));
                  return 0;
               }
               client_name = ua->argv[i];
@@ -143,7 +143,7 @@ int run_cmd(UAContext *ua, const char *cmd)
               break;
            case 4: /* fileset */
               if (fileset_name) {
-                 bsendmsg(ua, _("FileSet specified twice.\n"));
+                  bsendmsg(ua, _("FileSet specified twice.\n"));
                  return 0;
               }
               fileset_name = ua->argv[i];
@@ -151,7 +151,7 @@ int run_cmd(UAContext *ua, const char *cmd)
               break;
            case 5: /* level */
               if (level_name) {
-                 bsendmsg(ua, _("Level specified twice.\n"));
+                  bsendmsg(ua, _("Level specified twice.\n"));
                  return 0;
               }
               level_name = ua->argv[i];
@@ -160,7 +160,7 @@ int run_cmd(UAContext *ua, const char *cmd)
            case 6: /* storage */
            case 7: /* sd */
               if (store_name) {
-                 bsendmsg(ua, _("Storage specified twice.\n"));
+                  bsendmsg(ua, _("Storage specified twice.\n"));
                  return 0;
               }
               store_name = ua->argv[i];
@@ -168,7 +168,7 @@ int run_cmd(UAContext *ua, const char *cmd)
               break;
            case 8: /* pool */
               if (pool_name) {
-                 bsendmsg(ua, _("Pool specified twice.\n"));
+                  bsendmsg(ua, _("Pool specified twice.\n"));
                  return 0;
               }
               pool_name = ua->argv[i];
@@ -176,7 +176,7 @@ int run_cmd(UAContext *ua, const char *cmd)
               break;
            case 9: /* where */
               if (where) {
-                 bsendmsg(ua, _("Where specified twice.\n"));
+                  bsendmsg(ua, _("Where specified twice.\n"));
                  return 0;
               }
               where = ua->argv[i];
@@ -184,7 +184,7 @@ int run_cmd(UAContext *ua, const char *cmd)
               break;
            case 10: /* bootstrap */
               if (bootstrap) {
-                 bsendmsg(ua, _("Bootstrap specified twice.\n"));
+                  bsendmsg(ua, _("Bootstrap specified twice.\n"));
                  return 0;
               }
               bootstrap = ua->argv[i];
@@ -192,7 +192,7 @@ int run_cmd(UAContext *ua, const char *cmd)
               break;
            case 11: /* replace */
               if (replace) {
-                 bsendmsg(ua, _("Replace specified twice.\n"));
+                  bsendmsg(ua, _("Replace specified twice.\n"));
                  return 0;
               }
               replace = ua->argv[i];
@@ -200,7 +200,7 @@ int run_cmd(UAContext *ua, const char *cmd)
               break;
            case 12: /* When */
               if (when) {
-                 bsendmsg(ua, _("When specified twice.\n"));
+                  bsendmsg(ua, _("When specified twice.\n"));
                  return 0;
               }
               when = ua->argv[i];
@@ -208,12 +208,12 @@ int run_cmd(UAContext *ua, const char *cmd)
               break;
            case 13:  /* Priority */
               if (Priority) {
-                 bsendmsg(ua, _("Priority specified twice.\n"));
+                  bsendmsg(ua, _("Priority specified twice.\n"));
                  return 0;
               }
               Priority = atoi(ua->argv[i]);
               if (Priority <= 0) {
-                 bsendmsg(ua, _("Priority must be positive nonzero setting it to 10.\n"));
+                  bsendmsg(ua, _("Priority must be positive nonzero setting it to 10.\n"));
                  Priority = 10;
               }
               kw_ok = true;
@@ -223,7 +223,7 @@ int run_cmd(UAContext *ua, const char *cmd)
               break;
            case 15: /* Verify Job */
               if (verify_job_name) {
-                 bsendmsg(ua, _("Verify Job specified twice.\n"));
+                  bsendmsg(ua, _("Verify Job specified twice.\n"));
                  return 0;
               }
               verify_job_name = ua->argv[i];
@@ -248,16 +248,16 @@ int run_cmd(UAContext *ua, const char *cmd)
        * End of keyword for loop -- if not found, we got a bogus keyword
        */
       if (!kw_ok) {
-        Dmsg1(200, "%s not found\n", ua->argk[i]);
+         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 */
-           Dmsg1(200, "Set jobname=%s\n", job_name);
+            Dmsg1(800, "Set jobname=%s\n", job_name);
         } else {
-           bsendmsg(ua, _("Invalid keyword: %s\n"), ua->argk[i]);
+            bsendmsg(ua, _("Invalid keyword: %s\n"), ua->argk[i]);
            return 0;
         }
       }
@@ -269,22 +269,22 @@ int run_cmd(UAContext *ua, const char *cmd)
    if (catalog_name != NULL) {
        catalog = (CAT *)GetResWithName(R_CATALOG, catalog_name);
        if (catalog == NULL) {
-           bsendmsg(ua, _("Catalog \"%s\" not found\n"), catalog_name);
+            bsendmsg(ua, _("Catalog \"%s\" not found\n"), catalog_name);
           return 0;
        }
    }
-   Dmsg1(200, "Using catalog=%s\n", catalog_name);
+   Dmsg1(800, "Using catalog=%s\n", catalog_name);
 
    if (job_name) {
       /* Find Job */
       job = (JOB *)GetResWithName(R_JOB, job_name);
       if (!job) {
         if (*job_name != 0) {
-           bsendmsg(ua, _("Job \"%s\" not found\n"), job_name);
+            bsendmsg(ua, _("Job \"%s\" not found\n"), job_name);
         }
         job = select_job_resource(ua);
       } else {
-        Dmsg1(200, "Found job=%s\n", job_name);
+         Dmsg1(800, "Found job=%s\n", job_name);
       }
    } else {
       bsendmsg(ua, _("A job name must be specified.\n"));
@@ -302,12 +302,12 @@ int run_cmd(UAContext *ua, const char *cmd)
       store = (STORE *)GetResWithName(R_STORAGE, store_name);
       if (!store) {
         if (*store_name != 0) {
-           bsendmsg(ua, _("Storage \"%s\" not found.\n"), store_name);
+            bsendmsg(ua, _("Storage \"%s\" not found.\n"), store_name);
         }
         store = select_storage_resource(ua);
       }
    } else {
-      store = (STORE *)job->storage[0]->first();          /* use default */
+      store = (STORE *)job->storage->first();          /* use default */
    }
    if (!store) {
       return 1;
@@ -316,13 +316,13 @@ int run_cmd(UAContext *ua, const char *cmd)
               store->hdr.name);
       return 0;
    }
-   Dmsg1(200, "Using storage=%s\n", store->hdr.name);
+   Dmsg1(800, "Using storage=%s\n", store->hdr.name);
 
    if (pool_name) {
       pool = (POOL *)GetResWithName(R_POOL, pool_name);
       if (!pool) {
         if (*pool_name != 0) {
-           bsendmsg(ua, _("Pool \"%s\" not found.\n"), pool_name);
+            bsendmsg(ua, _("Pool \"%s\" not found.\n"), pool_name);
         }
         pool = select_pool_resource(ua);
       }
@@ -336,13 +336,13 @@ int run_cmd(UAContext *ua, const char *cmd)
               pool->hdr.name);
       return 0;
    }
-   Dmsg1(200, "Using pool\n", pool->hdr.name);
+   Dmsg1(800, "Using pool\n", pool->hdr.name);
 
    if (client_name) {
       client = (CLIENT *)GetResWithName(R_CLIENT, client_name);
       if (!client) {
         if (*client_name != 0) {
-           bsendmsg(ua, _("Client \"%s\" not found.\n"), client_name);
+            bsendmsg(ua, _("Client \"%s\" not found.\n"), client_name);
         }
         client = select_client_resource(ua);
       }
@@ -356,12 +356,12 @@ int run_cmd(UAContext *ua, const char *cmd)
               client->hdr.name);
       return 0;
    }
-   Dmsg1(200, "Using client=%s\n", client->hdr.name);
+   Dmsg1(800, "Using client=%s\n", client->hdr.name);
 
    if (fileset_name) {
       fileset = (FILESET *)GetResWithName(R_FILESET, fileset_name);
       if (!fileset) {
-        bsendmsg(ua, _("FileSet \"%s\" not found.\n"), fileset_name);
+         bsendmsg(ua, _("FileSet \"%s\" not found.\n"), fileset_name);
         fileset = select_fileset_resource(ua);
       }
    } else {
@@ -378,7 +378,7 @@ int run_cmd(UAContext *ua, const char *cmd)
    if (verify_job_name) {
       verify_job = (JOB *)GetResWithName(R_JOB, verify_job_name);
       if (!verify_job) {
-        bsendmsg(ua, _("Verify Job \"%s\" not found.\n"), verify_job_name);
+         bsendmsg(ua, _("Verify Job \"%s\" not found.\n"), verify_job_name);
         verify_job = select_job_resource(ua);
       }
    } else {
@@ -411,7 +411,7 @@ int run_cmd(UAContext *ua, const char *cmd)
    if (when) {
       jcr->sched_time = str_to_utime(when);
       if (jcr->sched_time == 0) {
-        bsendmsg(ua, _("Invalid time, using current time.\n"));
+         bsendmsg(ua, _("Invalid time, using current time.\n"));
         jcr->sched_time = time(NULL);
       }
    }
@@ -431,7 +431,7 @@ int run_cmd(UAContext *ua, const char *cmd)
         }
       }
       if (!jcr->replace) {
-        bsendmsg(ua, _("Invalid replace option: %s\n"), replace);
+         bsendmsg(ua, _("Invalid replace option: %s\n"), replace);
         goto bail_out;
       }
    } else if (job->replace) {
@@ -458,7 +458,7 @@ try_again:
    }
    if (level_name) {
       if (!get_level_from_name(jcr, level_name)) {
-        bsendmsg(ua, _("Level %s not valid.\n"), level_name);
+         bsendmsg(ua, _("Level %s not valid.\n"), level_name);
         goto bail_out;
       }
    }
@@ -475,19 +475,19 @@ try_again:
     * Prompt User to see if all run job parameters are correct, and
     *  allow him to modify them.
     */
-   Dmsg1(20, "JobType=%c\n", jcr->JobType);
+   Dmsg1(800, "JobType=%c\n", jcr->JobType);
    switch (jcr->JobType) {
       char ec1[30];
       char dt[MAX_TIME_LENGTH];
    case JT_ADMIN:
-        bsendmsg(ua, _("Run %s job\n"
+         bsendmsg(ua, _("Run %s job\n"
 "JobName:  %s\n"
 "FileSet:  %s\n"
 "Client:   %s\n"
 "Storage:  %s\n"
 "When:     %s\n"
 "Priority: %d\n"),
-                _("Admin"),
+                 _("Admin"),
                 job->hdr.name,
                 jcr->fileset->hdr.name,
                 NPRT(jcr->client->hdr.name),
@@ -499,7 +499,7 @@ try_again:
    case JT_BACKUP:
    case JT_VERIFY:
       if (jcr->JobType == JT_BACKUP) {
-        bsendmsg(ua, _("Run %s job\n"
+         bsendmsg(ua, _("Run %s job\n"
 "JobName:  %s\n"
 "FileSet:  %s\n"
 "Level:    %s\n"
@@ -508,7 +508,7 @@ try_again:
 "Pool:     %s\n"
 "When:     %s\n"
 "Priority: %d\n"),
-                _("Backup"),
+                 _("Backup"),
                 job->hdr.name,
                 jcr->fileset->hdr.name,
                 level_to_str(jcr->JobLevel),
@@ -522,9 +522,9 @@ try_again:
         if (jcr->verify_job) {
            Name = jcr->verify_job->hdr.name;
         } else {
-           Name = "";
+            Name = "";
         }
-        bsendmsg(ua, _("Run %s job\n"
+         bsendmsg(ua, _("Run %s job\n"
 "JobName:     %s\n"
 "FileSet:     %s\n"
 "Level:       %s\n"
@@ -534,7 +534,7 @@ try_again:
 "Verify Job:  %s\n"
 "When:        %s\n"
 "Priority:    %d\n"),
-             _("Verify"),
+              _("Verify"),
              job->hdr.name,
              jcr->fileset->hdr.name,
              level_to_str(jcr->JobLevel),
@@ -551,26 +551,26 @@ try_again:
         if (jid) {
            jcr->RestoreJobId = atoi(jid);
         } else {
-           if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
+            if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
               goto bail_out;
            }
            jcr->RestoreJobId = ua->pint32_val;
         }
       }
       jcr->JobLevel = L_FULL;     /* default level */
-      Dmsg1(20, "JobId to restore=%d\n", jcr->RestoreJobId);
+      Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId);
       if (jcr->RestoreJobId == 0) {
-        bsendmsg(ua, _("Run Restore job\n"
-                       "JobName:    %s\n"
-                       "Bootstrap:  %s\n"
-                       "Where:      %s\n"
-                       "Replace:    %s\n"
-                       "FileSet:    %s\n"
-                       "Client:     %s\n"
-                       "Storage:    %s\n"
-                       "When:       %s\n"
-                       "Catalog:    %s\n"
-                       "Priority:   %d\n"),
+         bsendmsg(ua, _("Run Restore job\n"
+                        "JobName:    %s\n"
+                        "Bootstrap:  %s\n"
+                        "Where:      %s\n"
+                        "Replace:    %s\n"
+                        "FileSet:    %s\n"
+                        "Client:     %s\n"
+                        "Storage:    %s\n"
+                        "When:       %s\n"
+                        "Catalog:    %s\n"
+                        "Priority:   %d\n"),
              job->hdr.name,
              NPRT(jcr->RestoreBootstrap),
              jcr->where?jcr->where:NPRT(job->RestoreWhere),
@@ -582,24 +582,24 @@ try_again:
              jcr->catalog->hdr.name,
              jcr->JobPriority);
       } else {
-        bsendmsg(ua, _("Run Restore job\n"
-                      "JobName:    %s\n"
-                      "Bootstrap:  %s\n"
-                      "Where:      %s\n"
-                      "Replace:    %s\n"
-                      "Client:     %s\n"
-                      "Storage:    %s\n"
-                      "JobId:      %s\n"
-                      "When:       %s\n"
-                      "Catalog:    %s\n"
-                      "Priority:   %d\n"),
+         bsendmsg(ua, _("Run Restore job\n"
+                       "JobName:    %s\n"
+                       "Bootstrap:  %s\n"
+                       "Where:      %s\n"
+                       "Replace:    %s\n"
+                       "Client:     %s\n"
+                       "Storage:    %s\n"
+                       "JobId:      %s\n"
+                       "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,
-             jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
+              jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
              bstrutime(dt, sizeof(dt), jcr->sched_time),
              jcr->catalog->hdr.name,
              jcr->JobPriority);
@@ -633,27 +633,27 @@ try_again:
       add_prompt(ua, _("Priority"));         /* 6 */
       if (jcr->JobType == JT_BACKUP ||
          jcr->JobType == JT_VERIFY) {
-        add_prompt(ua, _("Pool"));          /* 7 */
+         add_prompt(ua, _("Pool"));          /* 7 */
         if (jcr->JobType == JT_VERIFY) {
-           add_prompt(ua, _("Verify Job"));  /* 8 */
+            add_prompt(ua, _("Verify Job"));  /* 8 */
         }
       } else if (jcr->JobType == JT_RESTORE) {
-        add_prompt(ua, _("Bootstrap"));     /* 7 */
-        add_prompt(ua, _("Where"));         /* 8 */
-        add_prompt(ua, _("Replace"));       /* 9 */
-        add_prompt(ua, _("JobId"));         /* 10 */
+         add_prompt(ua, _("Bootstrap"));     /* 7 */
+         add_prompt(ua, _("Where"));         /* 8 */
+         add_prompt(ua, _("Replace"));       /* 9 */
+         add_prompt(ua, _("JobId"));         /* 10 */
       }
       switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
       case 0:
         /* Level */
         if (jcr->JobType == JT_BACKUP) {
-           start_prompt(ua, _("Levels:\n"));
-           add_prompt(ua, _("Base"));
-           add_prompt(ua, _("Full"));
-           add_prompt(ua, _("Incremental"));
-           add_prompt(ua, _("Differential"));
-           add_prompt(ua, _("Since"));
-           switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
+            start_prompt(ua, _("Levels:\n"));
+            add_prompt(ua, _("Base"));
+            add_prompt(ua, _("Full"));
+            add_prompt(ua, _("Incremental"));
+            add_prompt(ua, _("Differential"));
+            add_prompt(ua, _("Since"));
+            switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
            case 0:
               jcr->JobLevel = L_BASE;
               break;
@@ -674,13 +674,13 @@ try_again:
            }
            goto try_again;
         } else if (jcr->JobType == JT_VERIFY) {
-           start_prompt(ua, _("Levels:\n"));
-           add_prompt(ua, _("Initialize Catalog"));
-           add_prompt(ua, _("Verify Catalog"));
-           add_prompt(ua, _("Verify Volume to Catalog"));
-           add_prompt(ua, _("Verify Disk to Catalog"));
-           add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
-           switch (do_prompt(ua, "",  _("Select level"), NULL, 0)) {
+            start_prompt(ua, _("Levels:\n"));
+            add_prompt(ua, _("Initialize Catalog"));
+            add_prompt(ua, _("Verify Catalog"));
+            add_prompt(ua, _("Verify Volume to Catalog"));
+            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;
@@ -701,7 +701,7 @@ try_again:
            }
            goto try_again;
         } else {
-           bsendmsg(ua, _("Level not appropriate for this Job. Cannot be changed.\n"));
+            bsendmsg(ua, _("Level not appropriate for this Job. Cannot be changed.\n"));
         }
         goto try_again;
       case 1:
@@ -739,7 +739,7 @@ try_again:
         break;
       case 5:
         /* When */
-        if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) {
+         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) {
@@ -747,18 +747,18 @@ try_again:
         } else {
            jcr->sched_time = str_to_utime(ua->cmd);
            if (jcr->sched_time == 0) {
-              bsendmsg(ua, _("Invalid time, using current time.\n"));
+               bsendmsg(ua, _("Invalid time, using current time.\n"));
               jcr->sched_time = time(NULL);
            }
         }
         goto try_again;
       case 6:
         /* Priority */
-        if (!get_pint(ua, _("Enter new Priority: "))) {
+         if (!get_pint(ua, _("Enter new Priority: "))) {
            break;
         }
         if (ua->pint32_val == 0) {
-           bsendmsg(ua, _("Priority must be a positive integer.\n"));
+            bsendmsg(ua, _("Priority must be a positive integer.\n"));
         } else {
            jcr->JobPriority = ua->pint32_val;
         }
@@ -776,7 +776,7 @@ try_again:
         }
 
         /* Bootstrap */
-        if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
+         if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
            break;
         }
         if (jcr->RestoreBootstrap) {
@@ -785,9 +785,9 @@ try_again:
         }
         if (ua->cmd[0] != 0) {
            jcr->RestoreBootstrap = bstrdup(ua->cmd);
-           fd = fopen(jcr->RestoreBootstrap, "r");
+            fd = fopen(jcr->RestoreBootstrap, "r");
            if (!fd) {
-              bsendmsg(ua, _("Warning cannot open %s: ERR=%s\n"),
+               bsendmsg(ua, _("Warning cannot open %s: ERR=%s\n"),
                  jcr->RestoreBootstrap, strerror(errno));
               free(jcr->RestoreBootstrap);
               jcr->RestoreBootstrap = NULL;
@@ -806,25 +806,25 @@ try_again:
            goto try_again;
         }
         /* Where */
-        if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
+         if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
            break;
         }
         if (jcr->where) {
            free(jcr->where);
            jcr->where = NULL;
         }
-        if (ua->cmd[0] == '/' && ua->cmd[1] == 0) {
+         if (ua->cmd[0] == '/' && ua->cmd[1] == 0) {
            ua->cmd[0] = 0;
         }
         jcr->where = bstrdup(ua->cmd);
         goto try_again;
       case 9:
         /* Replace */
-        start_prompt(ua, _("Replace:\n"));
+         start_prompt(ua, _("Replace:\n"));
         for (i=0; ReplaceOptions[i].name; i++) {
            add_prompt(ua, ReplaceOptions[i].name);
         }
-        opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
+         opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
         if (opt >=  0) {
            jcr->replace = ReplaceOptions[opt].token;
         }
@@ -834,7 +834,7 @@ try_again:
         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"));
+            bsendmsg(ua, _("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
         }
         goto try_again;
       default:
@@ -845,14 +845,14 @@ try_again:
 
    if (strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) {
       JobId_t JobId;
-      Dmsg1(200, "Calling run_job job=%x\n", jcr->job);
+      Dmsg1(800, "Calling run_job job=%x\n", jcr->job);
 start_job:
       JobId = run_job(jcr);
       free_jcr(jcr);                 /* release jcr */
       if (JobId == 0) {
-        bsendmsg(ua, _("Job failed.\n"));
+         bsendmsg(ua, _("Job failed.\n"));
       } else {
-        bsendmsg(ua, _("Job started. JobId=%u\n"), JobId);
+         bsendmsg(ua, _("Job started. JobId=%u\n"), JobId);
       }
       return JobId;
    }
index 3e4adef377dd602172df8a585853cbbb22cc71d7..4b70ba82a8aedba89f211d56636d93156d3c4e27 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -30,8 +30,6 @@
 #include "bacula.h"
 #include "dird.h"
 
-/* Imported subroutines */
-
 /* Imported variables */
 extern int r_first;
 extern int r_last;
@@ -39,17 +37,9 @@ extern struct s_res resources[];
 extern int console_msg_pending;
 extern char my_name[];
 
-/* Static variables */
-
-/* Exported variables */
-int quit_cmd_thread = 0;
-
-/* Imported functions */
 
 /* Forward referenced functions */
-
 extern "C" void *connect_thread(void *arg);
-
 static void *handle_UA_client_request(void *arg);
 
 
@@ -74,8 +64,7 @@ void start_UA_server(dlist *addrs)
 
    if ((status=pthread_create(&thid, NULL, connect_thread, (void *)myaddrs)) != 0) {
       berrno be;
-      be.set_errno(status);
-      Emsg1(M_ABORT, 0, _("Cannot create UA thread: %s\n"), be.strerror());
+      Emsg1(M_ABORT, 0, _("Cannot create UA thread: %s\n"), be.strerror(status));
    }
    started = TRUE;
    return;
@@ -86,7 +75,7 @@ void *connect_thread(void *arg)
 {
    pthread_detach(pthread_self());
 
-   /*  ****FIXME**** put # 10 (timeout) on config parameter */
+   /* Permit 10 console connections */
    bnet_thread_server((dlist*)arg, 10, &ua_workq, handle_UA_client_request);
    return NULL;
 }
@@ -127,14 +116,13 @@ static void *handle_UA_client_request(void *arg)
    int stat;
    UAContext *ua;
    JCR *jcr;
-   BSOCK *UA_sock = (BSOCK *)arg;
 
    pthread_detach(pthread_self());
 
    jcr = new_control_jcr("*Console*", JT_CONSOLE);
 
    ua = new_ua_context(jcr);
-   ua->UA_sock = UA_sock;
+   ua->UA_sock = (BSOCK *)arg;
 
    bnet_recv(ua->UA_sock);         /* Get first message */
    if (!authenticate_user_agent(ua)) {
@@ -146,18 +134,18 @@ static void *handle_UA_client_request(void *arg)
       if (stat >= 0) {
         pm_strcpy(ua->cmd, ua->UA_sock->msg);
         parse_ua_args(ua);
-        if (ua->argc > 0 && ua->argk[0][0] == '.') {
+         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) {
-              strcpy(ua->cmd, "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) {
-              bsendmsg(ua, _("You have messages.\n"));
+               bsendmsg(ua, _("You have messages.\n"));
               ua->user_notified_msg_pending = TRUE;
            }
            bnet_sig(ua->UA_sock, BNET_EOD); /* send end of command */
@@ -213,6 +201,7 @@ void free_ua_context(UAContext *ua)
 
    if (ua->UA_sock) {
       bnet_close(ua->UA_sock);
+      ua->UA_sock = NULL;
    }
    free(ua);
 }
@@ -226,5 +215,4 @@ void term_ua_server()
    if (!started) {
       return;
    }
-   quit_cmd_thread = TRUE;
 }
index 533e0ae86b7f9377dc11b788a62214a881448771..5023002e54d08bc16ba43c6cb2a47e728740aac8 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /*
-   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
@@ -126,7 +126,7 @@ bool user_select_files_from_tree(TREE_CTX *tree)
            break;
         }
       if (!found) {
-        bsendmsg(tree->ua, _("Illegal command. Enter \"done\" to exit.\n"));
+         bsendmsg(tree->ua, _("Illegal command. Enter \"done\" to exit.\n"));
         continue;
       }
       if (!stat) {
@@ -208,7 +208,7 @@ int insert_tree_handler(void *ctx, int num_fields, char **row)
    if (node->inserted) {
       tree->FileCount++;
       if (tree->DeltaCount > 0 && (tree->FileCount-tree->LastCount) > tree->DeltaCount) {
-        bsendmsg(tree->ua, "+");
+         bsendmsg(tree->ua, "+");
         tree->LastCount = tree->FileCount;
       }
    }
@@ -311,7 +311,7 @@ static int markcmd(UAContext *ua, TREE_CTX *tree)
       bsendmsg(ua, _("No files marked.\n"));
    } else {
       bsendmsg(ua, _("%s file%s marked.\n"),
-              edit_uint64_with_commas(count, ec1), count==0?"":"s");
+               edit_uint64_with_commas(count, ec1), count==0?"":"s");
    }
    return 1;
 }
@@ -340,7 +340,7 @@ static int markdircmd(UAContext *ua, TREE_CTX *tree)
       bsendmsg(ua, _("No directories marked.\n"));
    } else {
       bsendmsg(ua, _("%s director%s marked.\n"),
-              edit_uint64_with_commas(count, ec1), count==1?"y":"ies");
+               edit_uint64_with_commas(count, ec1), count==1?"y":"ies");
    }
    return 1;
 }
@@ -381,13 +381,13 @@ static int findcmd(UAContext *ua, TREE_CTX *tree)
            const char *tag;
            tree_getpath(node, cwd, sizeof(cwd));
            if (node->extract) {
-              tag = "*";
+               tag = "*";
            } else if (node->extract_dir) {
-              tag = "+";
+               tag = "+";
            } else {
-              tag = "";
+               tag = "";
            }
-           bsendmsg(ua, "%s%s\n", tag, cwd);
+            bsendmsg(ua, "%s%s\n", tag, cwd);
         }
       }
    }
@@ -407,13 +407,13 @@ static int lscmd(UAContext *ua, TREE_CTX *tree)
       if (ua->argc == 1 || fnmatch(ua->argk[1], node->fname, 0) == 0) {
         const char *tag;
         if (node->extract) {
-           tag = "*";
+            tag = "*";
         } else if (node->extract_dir) {
-           tag = "+";
+            tag = "+";
         } else {
-           tag = "";
+            tag = "";
         }
-        bsendmsg(ua, "%s%s%s\n", tag, node->fname, tree_node_has_child(node)?"/":"");
+         bsendmsg(ua, "%s%s%s\n", tag, node->fname, tree_node_has_child(node)?"/":"");
       }
    }
    return 1;
@@ -433,13 +433,13 @@ static void rlsmark(UAContext *ua, TREE_NODE *tnode)
          (node->extract || node->extract_dir)) {
         const char *tag;
         if (node->extract) {
-           tag = "*";
+            tag = "*";
         } else if (node->extract_dir) {
-           tag = "+";
+            tag = "+";
         } else {
-           tag = "";
+            tag = "";
         }
-        bsendmsg(ua, "%s%s%s\n", tag, node->fname, tree_node_has_child(node)?"/":"");
+         bsendmsg(ua, "%s%s%s\n", tag, node->fname, tree_node_has_child(node)?"/":"");
         if (tree_node_has_child(node)) {
            rlsmark(ua, node);
         }
@@ -507,11 +507,11 @@ static int dircmd(UAContext *ua, TREE_CTX *tree)
       const char *tag;
       if (ua->argc == 1 || fnmatch(ua->argk[1], node->fname, 0) == 0) {
         if (node->extract) {
-           tag = "*";
+            tag = "*";
         } else if (node->extract_dir) {
-           tag = "+";
+            tag = "+";
         } else {
-           tag = " ";
+            tag = " ";
         }
         tree_getpath(node, cwd, sizeof(cwd));
         fdbr.FileId = 0;
@@ -541,7 +541,7 @@ static int dircmd(UAContext *ua, TREE_CTX *tree)
            memset(&statp, 0, sizeof(statp));
         }
         ls_output(buf, cwd, tag, &statp);
-        bsendmsg(ua, "%s\n", buf);
+         bsendmsg(ua, "%s\n", buf);
       }
    }
    return 1;
@@ -617,12 +617,12 @@ static int cdcmd(UAContext *ua, TREE_CTX *tree)
    if (!node) {
       /* Try once more if Win32 drive -- make absolute */
       if (ua->argk[1][1] == ':') {  /* win32 drive */
-        bstrncpy(cwd, "/", sizeof(cwd));
+         bstrncpy(cwd, "/", sizeof(cwd));
         bstrncat(cwd, ua->argk[1], sizeof(cwd));
         node = tree_cwd(cwd, tree->root, tree->node);
       }
       if (!node) {
-        bsendmsg(ua, _("Invalid path given.\n"));
+         bsendmsg(ua, _("Invalid path given.\n"));
       } else {
         tree->node = node;
       }
index 6e0019da224dcdc7a79609855f1bb147e36e4db4..9f3082d4d4c176c497b2525529b695b6bdebf815 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 /*
-   Copyright (C) 2000-2004 Kern Sibbald
+   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
@@ -74,9 +74,6 @@ bool do_verify(JCR *jcr)
    if (!jcr->verify_jr) {
       jcr->verify_jr = &verify_jr;
    }
-   if (!get_or_create_client_record(jcr)) {
-      goto bail_out;
-   }
 
    Dmsg1(9, "bdird: created client %s record\n", jcr->client->hdr.name);
 
@@ -119,10 +116,6 @@ bool do_verify(JCR *jcr)
       goto bail_out;
    }
 
-   if (!jcr->fname) {
-      jcr->fname = get_pool_memory(PM_FNAME);
-   }
-
    /* Print Job Start message */
    Jmsg(jcr, M_INFO, 0, _("Start Verify JobId=%d Level=%s Job=%s\n"),
       jcr->JobId, level_to_str(jcr->JobLevel), jcr->Job);
@@ -190,7 +183,7 @@ bool do_verify(JCR *jcr)
       /*
        * Now start a job with the Storage daemon
        */
-      if (!start_storage_daemon_job(jcr)) {
+      if (!start_storage_daemon_job(jcr, jcr->storage, SD_READ)) {
         goto bail_out;
       }
       /*
index 2e5a85a692f1ecf12c41ac6cfeef420daf1d5fa4..e9e093f286d174f283d8c2c613b6d569584233fa 100644 (file)
@@ -97,7 +97,7 @@ JCR jcr;
  *    with what we have and give all ACL streams a new number/type.
  */
 #endif
-#if !defined(HAVE_ACL) || ! defined(HAVE_LINUX_OS)
+#if !defined(HAVE_ACL) || !defined(HAVE_LINUX_OS)
 
 /* bacl_get() returns the lenght of the string, or -1 on error. */
 int bacl_get(JCR *jcr, int acltype)
@@ -181,7 +181,7 @@ int bacl_get(JCR *jcr, int acltype)
    }
    /***** Do we really want to silently ignore errors from acl_get_file
      and acl_to_text?  *****/
-   return -1;
+   return 0;
 }
 
 int bacl_set(JCR *jcr, int acltype)
@@ -418,7 +418,7 @@ int aclcp(char *src, char *dst)
    if (S_ISDIR(st.st_mode) && (BACL_CAP & BACL_CAP_DEFAULTS_DIR)) {
       jcr.last_fname = src;
       if (bacl_get(&jcr, BACL_TYPE_DEFAULT) < 0) {
-        Dmsg1(200, "aclcp: could not read default ACLs for %s\n", jcr.last_fname);
+         Dmsg1(200, "aclcp: could not read default ACLs for %s\n", jcr.last_fname);
         return EXIT_FAILURE;
       } else {
         jcr.last_fname = dst;
index f0a0e0c890ff53c9d8f28e58cfe19132a68065d9..d6faeadaa3d24edbb8640eff275877642a905331 100644 (file)
@@ -533,8 +533,8 @@ static void add_fname_to_list(JCR *jcr, char *fname, int list)
       /* Copy File options */
       if (list == INC_LIST) {
         *q = 0;                      /* terminate options */
-        strcpy(buf, fname);
-         strcat(buf, " ");
+        bstrncpy(buf, fname, sizeof(buf));
+         bstrncat(buf, " ", sizeof(buf));
         optlen = strlen(buf);
       } else {
         optlen = 0;
@@ -564,8 +564,8 @@ static void add_fname_to_list(JCR *jcr, char *fname, int list)
       /* Copy File options */
       if (list == INC_LIST) {
         *q = 0;                      /* terminate options */
-        strcpy(buf, fname);
-         strcat(buf, " ");
+        bstrncpy(buf, fname, sizeof(buf));
+         bstrncat(buf, " ", sizeof(buf));
         optlen = strlen(buf);
       } else {
         optlen = 0;
index 99e296d09b7ebbee582a44d30396c651630c4820..23940b0920a905a5e43ad1fc20f80533bd6dcac7 100644 (file)
@@ -87,7 +87,7 @@ void do_verify_volume(JCR *jcr)
        */
       if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
          &stream, &size) != 5) {
-        Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
+         Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
         goto bail_out;
       }
       Dmsg2(30, "Got hdr: FilInx=%d Stream=%d.\n", file_index, stream);
@@ -96,11 +96,11 @@ void do_verify_volume(JCR *jcr)
        * Now we expect the Stream Data
        */
       if (bget_msg(sd) < 0) {
-        Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
+         Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
         goto bail_out;
       }
       if (size != ((uint32_t)sd->msglen)) {
-        Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size);
+         Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size);
         goto bail_out;
       }
       Dmsg1(30, "Got stream data, len=%d\n", sd->msglen);
@@ -111,7 +111,7 @@ void do_verify_volume(JCR *jcr)
       case STREAM_UNIX_ATTRIBUTES_EX:
         char *ap, *lp, *fp;
 
-        Dmsg0(400, "Stream=Unix Attributes.\n");
+         Dmsg0(400, "Stream=Unix Attributes.\n");
 
         if ((int)sizeof_pool_memory(fname) < sd->msglen) {
            fname = realloc_pool_memory(fname, sd->msglen + 1);
@@ -132,22 +132,22 @@ void do_verify_volume(JCR *jcr)
          *    Link name (if file linked i.e. FT_LNK)
          *    Extended Attributes (if Win32)
          */
-        if (sscanf(sd->msg, "%d %d", &record_file_index, &type) != 2) {
-           Jmsg(jcr, M_FATAL, 0, _("Error scanning record header: %s\n"), sd->msg);
-           Dmsg0(0, "\nError scanning header\n");
+         if (sscanf(sd->msg, "%d %d", &record_file_index, &type) != 2) {
+            Jmsg(jcr, M_FATAL, 0, _("Error scanning record header: %s\n"), sd->msg);
+            Dmsg0(0, "\nError scanning header\n");
            goto bail_out;
         }
-        Dmsg2(30, "Got Attr: FilInx=%d type=%d\n", record_file_index, type);
+         Dmsg2(30, "Got Attr: FilInx=%d type=%d\n", record_file_index, type);
         if (record_file_index != file_index) {
-           Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
+            Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
               file_index, record_file_index);
-           Dmsg0(0, "File index error\n");
+            Dmsg0(0, "File index error\n");
            goto bail_out;
         }
         ap = sd->msg;
-        while (*ap++ != ' ')         /* skip record file index */
+         while (*ap++ != ' ')         /* skip record file index */
            ;
-        while (*ap++ != ' ')         /* skip type */
+         while (*ap++ != ' ')         /* skip type */
            ;
         /* Save filename and position to attributes */
         fp = fname;
@@ -156,21 +156,21 @@ void do_verify_volume(JCR *jcr)
         }
         *fp = *ap++;                 /* terminate filename & point to attribs */
 
-        Dmsg1(200, "Attr=%s\n", ap);
+         Dmsg1(200, "Attr=%s\n", ap);
         /* Skip to Link name */
         if (type == FT_LNK || type == FT_LNKSAVED) {
            lp = ap;
            while (*lp++ != 0) {
               ;
            }
-           strcat(lname, lp);        /* "save" link name */
+            pm_strcat(lname, lp);        /* "save" link name */
         } else {
            *lname = 0;
         }
         P(jcr->mutex);
         jcr->JobFiles++;
         jcr->num_files_examined++;
-        pm_strcpy(&jcr->last_fname, fname); /* last file examined */
+        pm_strcpy(jcr->last_fname, fname); /* last file examined */
         V(jcr->mutex);
 
         /*
@@ -185,19 +185,19 @@ void do_verify_volume(JCR *jcr)
          * slash. For a linked file, link is the link.
          */
         /* Send file attributes to Director */
-        Dmsg2(200, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, fname);
+         Dmsg2(200, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, fname);
         if (type == FT_LNK || type == FT_LNKSAVED) {
-           stat = bnet_fsend(dir, "%d %d %s %s%c%s%c%s%c", jcr->JobFiles,
-                         STREAM_UNIX_ATTRIBUTES, "pinsug5", fname,
+            stat = bnet_fsend(dir, "%d %d %s %s%c%s%c%s%c", jcr->JobFiles,
+                          STREAM_UNIX_ATTRIBUTES, "pinsug5", fname,
                          0, ap, 0, lname, 0);
         } else {
-           stat = bnet_fsend(dir,"%d %d %s %s%c%s%c%c", jcr->JobFiles,
-                         STREAM_UNIX_ATTRIBUTES, "pinsug5", fname,
+            stat = bnet_fsend(dir,"%d %d %s %s%c%s%c%c", jcr->JobFiles,
+                          STREAM_UNIX_ATTRIBUTES, "pinsug5", fname,
                          0, ap, 0, 0);
         }
-        Dmsg2(200, "bfiled>bdird: attribs len=%d: msg=%s\n", dir->msglen, dir->msg);
+         Dmsg2(200, "bfiled>bdird: attribs len=%d: msg=%s\n", dir->msglen, dir->msg);
         if (!stat) {
-           Jmsg(jcr, M_FATAL, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir));
+            Jmsg(jcr, M_FATAL, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir));
            goto bail_out;
         }
         break;
@@ -216,23 +216,23 @@ void do_verify_volume(JCR *jcr)
       case STREAM_MD5_SIGNATURE:
         char MD5buf[30];
         bin_to_base64(MD5buf, (char *)sd->msg, 16); /* encode 16 bytes */
-        Dmsg2(400, "send inx=%d MD5=%s\n", jcr->JobFiles, MD5buf);
-        bnet_fsend(dir, "%d %d %s *MD5-%d*", jcr->JobFiles, STREAM_MD5_SIGNATURE, MD5buf,
+         Dmsg2(400, "send inx=%d MD5=%s\n", jcr->JobFiles, MD5buf);
+         bnet_fsend(dir, "%d %d %s *MD5-%d*", jcr->JobFiles, STREAM_MD5_SIGNATURE, MD5buf,
            jcr->JobFiles);
-        Dmsg2(20, "bfiled>bdird: MD5 len=%d: msg=%s\n", dir->msglen, dir->msg);
+         Dmsg2(20, "bfiled>bdird: MD5 len=%d: msg=%s\n", dir->msglen, dir->msg);
         break;
 
       case STREAM_SHA1_SIGNATURE:
         char SHA1buf[30];
         bin_to_base64(SHA1buf, (char *)sd->msg, 20); /* encode 20 bytes */
-        Dmsg2(400, "send inx=%d SHA1=%s\n", jcr->JobFiles, SHA1buf);
-        bnet_fsend(dir, "%d %d %s *SHA1-%d*", jcr->JobFiles, STREAM_SHA1_SIGNATURE,
+         Dmsg2(400, "send inx=%d SHA1=%s\n", jcr->JobFiles, SHA1buf);
+         bnet_fsend(dir, "%d %d %s *SHA1-%d*", jcr->JobFiles, STREAM_SHA1_SIGNATURE,
            SHA1buf, jcr->JobFiles);
-        Dmsg2(20, "bfiled>bdird: SHA1 len=%d: msg=%s\n", dir->msglen, dir->msg);
+         Dmsg2(20, "bfiled>bdird: SHA1 len=%d: msg=%s\n", dir->msglen, dir->msg);
         break;
 
       default:
-        Pmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
+         Pmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
         break;
       } /* end switch */
    } /* end while bnet_get */
index 38a9cd7b5afaa8e8a435992acdfebd15df7df966..085e720c30305e29565c42f09ba90783791749c6 100644 (file)
@@ -86,6 +86,8 @@
 #define foreach_jcr(jcr) \
    for ((jcr)=NULL; ((jcr)=get_next_jcr(jcr)); )
 
+#define SD_APPEND 1
+#define SD_READ   0
 
 
 struct JCR;
@@ -141,7 +143,6 @@ struct JCR {
    /* This should be empty in the library */
 
 #ifdef DIRECTOR_DAEMON
-#define MAX_STORE 2
    /* Director Daemon specific part of JCR */
    pthread_t SD_msg_chan;             /* Message channel thread id */
    pthread_cond_t term_wait;          /* Wait for job termination */
@@ -150,7 +151,7 @@ struct JCR {
    BSOCK *ua;                         /* User agent */
    JOB *job;                          /* Job resource */
    JOB *verify_job;                   /* Job resource of verify target job */
-   alist *storage[MAX_STORE];         /* Storage possibilities */
+   alist *storage;                    /* Storage possibilities */
    STORE *store;                      /* Storage daemon selected */
    CLIENT *client;                    /* Client resource */
    POOL *pool;                        /* Pool resource */
@@ -224,7 +225,8 @@ struct JCR {
    pthread_cond_t job_start_wait;     /* Wait for FD to start Job */
    int type;
    DCR *dcr;                          /* device context record */
-   DEVRES *device;                    /* device resource to use */
+   alist *dcrs;                       /* list of dcrs open */
+// DEVRES *device;                    /* device resource to use */
    POOLMEM *job_name;                 /* base Job name (not unique) */
    POOLMEM *fileset_name;             /* FileSet */
    POOLMEM *fileset_md5;              /* MD5 for FileSet */
index 2a1a26d18241d6695ea64265abd9202f7270f253..f02be3d5c0c8998a63044e695c888754ece94a7b 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 /*
-   Copyright (C) 2003-2004 Kern Sibbald and John Walker
+   Copyright (C) 2003-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
  * Loop var through each member of list
  */
 #define foreach_alist(var, list) \
-    for((*((void **)&(var))=(void*)((list)->first())); (var); (*((void **)&(var))=(void*)((list)->next())))
+    for((*((void **)&(var))=(void*)((list)->first())); \
+         (var); \
+         (*((void **)&(var))=(void*)((list)->next())))
 
 #ifdef the_easy_way
 #define foreach_alist(var, list) \
-       for((void*(var))=(list)->first(); (var); (void *(var))=(list)->next(var)); )
+        for((void*(var))=(list)->first(); (var); (void *(var))=(list)->next(var)); )
 #endif
 
 
index cc7b2fb92c40d40bc68841b61d8f94a3a0fb1d4c..10657394f1f49933569feadca9aff843d0d2eb49 100644 (file)
@@ -370,7 +370,7 @@ bool bnet_send(BSOCK * bsock)
       if (rc < 0) {
         if (!bsock->suppress_error_msgs && !bsock->timed_out) {
            Qmsg4(bsock->jcr, M_ERROR, 0,
-                  _("Write error sending to %s:%s:%d: ERR=%s\n"), bsock->who,
+                  _("Write error sending len to %s:%s:%d: ERR=%s\n"), bsock->who,
                  bsock->host, bsock->port, bnet_strerror(bsock));
         }
       } else {
@@ -400,8 +400,9 @@ bool bnet_send(BSOCK * bsock)
       }
       if (rc < 0) {
         if (!bsock->suppress_error_msgs) {
-           Qmsg4(bsock->jcr, M_ERROR, 0,
-                  _("Write error sending to %s:%s:%d: ERR=%s\n"), bsock->who,
+           Qmsg5(bsock->jcr, M_ERROR, 0,
+                  _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"), 
+                 bsock->msglen, bsock->who,
                  bsock->host, bsock->port, bnet_strerror(bsock));
         }
       } else {
index 4350de4c05da60ec9b0c3b1a5b596542a3159ba1..4778b84aad62cbb50e69b9ac5f0975947e5d3eb2 100644 (file)
@@ -195,38 +195,38 @@ int close_bpipe(BPIPE *bpipe)
 
    /* wait for worker child to exit */
    for ( ;; ) {
-      Dmsg2(200, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
+      Dmsg2(800, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
       do {
         wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
       } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
       if (wpid == bpipe->worker_pid || wpid == -1) {
         stat = errno;
-        Dmsg3(200, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
-           wpid==-1?strerror(errno):"none");
+         Dmsg3(800, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
+            wpid==-1?strerror(errno):"none");
         break;
       }
-      Dmsg3(200, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
-           wpid==-1?strerror(errno):"none");
+      Dmsg3(800, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
+            wpid==-1?strerror(errno):"none");
       if (remaining_wait > 0) {
         bmicrosleep(1, 0);           /* wait one second */
         remaining_wait--;
       } else {
         stat = ETIME;                /* set error status */
         wpid = -1;
-        break;                       /* don't wait any longer */
+         break;                       /* don't wait any longer */
       }
    }
    if (wpid > 0) {
       if (WIFEXITED(chldstatus)) {    /* process exit()ed */
         stat = WEXITSTATUS(chldstatus);
         if (stat != 0) {
-           Dmsg1(200, "Non-zero status %d returned from child.\n", stat);
+            Dmsg1(800, "Non-zero status %d returned from child.\n", stat);
            stat |= b_errno_exit;        /* exit status returned */
         }
-        Dmsg1(200, "child status=%d\n", stat & ~b_errno_exit);
+         Dmsg1(800, "child status=%d\n", stat & ~b_errno_exit);
       } else if (WIFSIGNALED(chldstatus)) {  /* process died */
         stat = WTERMSIG(chldstatus);
-        Dmsg1(200, "Child died from signale %d\n", stat);
+         Dmsg1(800, "Child died from signale %d\n", stat);
         stat |= b_errno_signal;      /* exit signal returned */
       }
    }
@@ -234,7 +234,7 @@ int close_bpipe(BPIPE *bpipe)
       stop_child_timer(bpipe->timer_id);
    }
    free(bpipe);
-   Dmsg1(200, "returning stat = %d\n", stat);
+   Dmsg1(800, "returning stat = %d\n", stat);
    return stat;
 }
 
@@ -269,9 +269,9 @@ int run_program(char *prog, int wait, POOLMEM *results)
         stat1 = ferror(bpipe->rfd);
       }
       if (stat1 < 0) {
-        Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, strerror(errno));
+         Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, strerror(errno));
       } else if (stat1 != 0) {
-        Dmsg1(100, "Run program fgets stat=%d\n", stat1);
+         Dmsg1(100, "Run program fgets stat=%d\n", stat1);
       }
    } else {
       stat1 = 0;
@@ -317,18 +317,18 @@ int run_program_full_output(char *prog, int wait, POOLMEM *results)
 
    while (1) {
       fgets(tmp, sizeof_pool_memory(tmp), bpipe->rfd);
-      Dmsg1(200, "Run program fgets=%s", tmp);
+      Dmsg1(800, "Run program fgets=%s", tmp);
       pm_strcat(results, tmp);
       if (feof(bpipe->rfd)) {
-         stat1 = 0;
+        stat1 = 0;
          Dmsg1(100, "Run program fgets stat=%d\n", stat1);
-         break;
+        break;
       } else {
-         stat1 = ferror(bpipe->rfd);
+        stat1 = ferror(bpipe->rfd);
       }
       if (stat1 < 0) {
          Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, strerror(errno));
-         break;
+        break;
       } else if (stat1 != 0) {
          Dmsg1(100, "Run program fgets stat=%d\n", stat1);
       }
@@ -371,16 +371,16 @@ static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
            q++;
            quote = 0;
         } else {
-           while (*q && *q != ' ')
+            while (*q && *q != ' ')
            q++;
         }
         if (*q)
-           *(q++) = '\0';
+            *(q++) = '\0';
         bargv[argc++] = p;
         p = q;
-        while (*p && (*p == ' ' || *p == '\t'))
+         while (*p && (*p == ' ' || *p == '\t'))
            p++;
-        if (*p == '\"' || *p == '\'') {
+         if (*p == '\"' || *p == '\'') {
            quote = *p;
            p++;
         }
index 177ffe7c3de646c032f565b48a1d9395f7131cdf..cd0545a61cde4b323ec5d95df5b09654a8662659 100644 (file)
@@ -53,7 +53,7 @@ daemon_start()
     *  Become a daemon.
     */
 
-   Dmsg0(200, "Enter daemon_start\n");
+   Dmsg0(900, "Enter daemon_start\n");
    if ( (cpid = fork() ) < 0)
       Emsg1(M_ABORT, 0, "Cannot fork to become daemon: %s\n", strerror(errno));
    else if (cpid > 0)
@@ -106,5 +106,5 @@ daemon_start()
    }
 
 #endif /* HAVE_CYGWIN */
-   Dmsg0(200, "Exit daemon_start\n");
+   Dmsg0(900, "Exit daemon_start\n");
 }
index 97cdb810dad8036fa6ad63c059a6cea838b4c560..526af060f8557c3d2e3265a15e3e974b0c15955e 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -94,7 +94,7 @@ char *edit_uint64_with_commas(uint64_t val, char *buf)
       mbuf[i--] = '0';
    } else {
       while (val != 0) {
-        mbuf[i--] = "0123456789"[val%10];
+         mbuf[i--] = "0123456789"[val%10];
         val /= 10;
       }
    }
@@ -119,7 +119,7 @@ char *edit_uint64(uint64_t val, char *buf)
       mbuf[i--] = '0';
    } else {
       while (val != 0) {
-        mbuf[i--] = "0123456789"[val%10];
+         mbuf[i--] = "0123456789"[val%10];
         val /= 10;
       }
    }
@@ -127,6 +127,35 @@ char *edit_uint64(uint64_t val, char *buf)
    return buf;
 }
 
+char *edit_int64(int64_t val, char *buf)
+{
+   /*
+    * Replacement for sprintf(buf, "%" llu, val)
+    */
+   char mbuf[50];
+   bool negative = false;
+   mbuf[sizeof(mbuf)-1] = 0;
+   int i = sizeof(mbuf)-2;                /* edit backward */
+   if (val == 0) {
+      mbuf[i--] = '0';
+   } else {
+      if (val < 0) {
+        negative = true;
+        val = -val;
+      }
+      while (val != 0) {
+         mbuf[i--] = "0123456789"[val%10];
+        val /= 10;
+      }
+   }
+   if (negative) {
+      mbuf[i--] = '-';
+   }
+   strcpy(buf, &mbuf[i+1]);
+   return buf;
+}
+
+
 /*
  * Given a string "str", separate the integer part into
  *   str, and the modifier into mod.
@@ -206,7 +235,7 @@ int duration_to_utime(char *str, utime_t *value)
     *  Baculas.
     */
    static const char *mod[] = {"n", "seconds", "months", "minutes",
-                 "hours", "days", "weeks",   "quarters",   "years", NULL};
+                  "hours", "days", "weeks",   "quarters",   "years", NULL};
    static const int32_t mult[] = {60,  1, 60*60*24*30, 60,
                  60*60, 60*60*24, 60*60*24*7, 60*60*24*91, 60*60*24*365};
 
@@ -256,7 +285,7 @@ char *edit_utime(utime_t val, char *buf, int buf_len)
       times = (uint32_t)(val / mult[i]);
       if (times > 0) {
         val = val - (utime_t)times * mult[i];
-        bsnprintf(mybuf, sizeof(mybuf), "%d %s%s ", times, mod[i], times>1?"s":"");
+         bsnprintf(mybuf, sizeof(mybuf), "%d %s%s ", times, mod[i], times>1?"s":"");
         bstrncat(buf, mybuf, buf_len);
       }
    }
@@ -372,20 +401,20 @@ bool is_name_valid(char *name, POOLMEM **msg)
         continue;
       }
       if (msg) {
-        Mmsg(msg, _("Illegal character \"%c\" in name.\n"), *p);
+         Mmsg(msg, _("Illegal character \"%c\" in name.\n"), *p);
       }
       return false;
    }
    len = strlen(name);
    if (len >= MAX_NAME_LENGTH) {
       if (msg) {
-        Mmsg(msg, _("Name too long.\n"));
+         Mmsg(msg, _("Name too long.\n"));
       }
       return false;
    }
    if (len == 0) {
       if (msg) {
-        Mmsg(msg,  _("Volume name must be at least one character long.\n"));
+         Mmsg(msg,  _("Volume name must be at least one character long.\n"));
       }
       return false;
    }
@@ -437,7 +466,7 @@ int main(int argc, char *argv[])
    for (int i=0; i<8; i++) {
       strcpy(buf, str[i]);
       if (!duration_to_utime(buf, &val)) {
-        printf("Error return from duration_to_utime for in=%s\n", str[i]);
+         printf("Error return from duration_to_utime for in=%s\n", str[i]);
         continue;
       }
       edit_utime(val, outval);
index 1d440c40fa60c4423cb0344043de2cd7a5ae8520..0af1101356b1de5077fea0dca615e9162268c021 100644 (file)
@@ -8,10 +8,10 @@
  *    the randomness. In this program, the hash table can grow when
  *    it gets too full, so the table size here is a binary number. The
  *    hashing is provided using an idea from Tcl where the initial
- *    hash code is then "randomized" using a simple calculation from
+ *    hash code is "randomized" using a simple calculation from
  *    a random number generator that multiplies by a big number
  *    (I multiply by a prime number, while Tcl did not)
- *    then shifts the results down and does the binary division
+ *    then shifts the result down and does the binary division
  *    by masking.  Increasing the size of the hash table is simple.
  *    Just create a new larger table, walk the old table and
  *    re-hash insert each entry into the new table.
@@ -23,7 +23,7 @@
  *
  */
 /*
-   Copyright (C) 2003-2004 Kern Sibbald and John Walker
+   Copyright (C) 2003-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
@@ -90,33 +90,30 @@ void htable::init(void *item, void *link, int tsize)
    walk_index = 0;
 }
 
-#ifdef xxx
-void * htable::operator new(size_t)
-{
-   return malloc(sizeof(htable));
-}
-
-void htable::operator delete(void *tbl)
-{
-   ((htable *)tbl)->destroy();
-   free(tbl);
-}
-#endif
-
 uint32_t htable::size()
 {
    return num_items;
 }
 
+/*
+ * Take each hash link and walk down the chain of items
+ *  that hash there counting them (i.e. the hits), 
+ *  then report that number.
+ *  Obiously, the more hits in a chain, the more time
+ *  it takes to reference them. Empty chains are not so
+ *  hot either -- as it means unused or wasted space.
+ */
+#define MAX_COUNT 20
 void htable::stats()
 {
-   int count[10];
+   int hits[MAX_COUNT];
    int max = 0;
    int i, j;
    hlink *p;
-   printf("\n\nNumItems=%d\nBuckets=%d\n", num_items, buckets);
-   for (i=0; i<10; i++) {
-      count[i] = 0;
+   printf("\n\nNumItems=%d\nTotal buckets=%d\n", num_items, buckets);
+   printf("Hits/bucket: buckets\n");
+   for (i=0; i < MAX_COUNT; i++) {
+      hits[i] = 0;
    }
    for (i=0; i<(int)buckets; i++) {
       p = table[i];
@@ -128,14 +125,14 @@ void htable::stats()
       if (j > max) {
         max = j;
       }
-      if (j < 10) {
-        count[j]++;
+      if (j < MAX_COUNT) {
+        hits[j]++;
       }
    }
-   for (i=0; i<10; i++) {
-      printf("%2d: %d\n",i, count[i]);
+   for (i=0; i < MAX_COUNT; i++) {
+      printf("%2d:           %d\n",i, hits[i]);
    }
-   printf("max = %d\n", max);
+   printf("max hits in a bucket = %d\n", max);
 }
 
 void htable::grow_table()
@@ -217,7 +214,7 @@ void *htable::lookup(char *key)
    for (hlink *hp=table[index]; hp; hp=(hlink *)hp->next) {
 //    Dmsg2(100, "hp=0x%x key=%s\n", (long)hp, hp->key);
       if (hash == hp->hash && strcmp(key, hp->key) == 0) {
-        Dmsg1(100, "lookup return %x\n", ((char *)hp)-loffset);
+         Dmsg1(100, "lookup return %x\n", ((char *)hp)-loffset);
         return ((char *)hp)-loffset;
       }
    }
@@ -233,7 +230,7 @@ void *htable::next()
    while (!walkptr && walk_index < buckets) {
       walkptr = table[walk_index++];
       if (walkptr) {
-        Dmsg3(100, "new walkptr=0x%x next=0x%x inx=%d\n", (unsigned)walkptr,
+         Dmsg3(100, "new walkptr=0x%x next=0x%x inx=%d\n", (unsigned)walkptr,
            (unsigned)(walkptr->next), walk_index-1);
       }
    }
@@ -254,7 +251,7 @@ void *htable::first()
    while (!walkptr && walk_index < buckets) {
       walkptr = table[walk_index++];  /* go to next bucket */
       if (walkptr) {
-        Dmsg3(100, "first new walkptr=0x%x next=0x%x inx=%d\n", (unsigned)walkptr,
+         Dmsg3(100, "first new walkptr=0x%x next=0x%x inx=%d\n", (unsigned)walkptr,
            (unsigned)(walkptr->next), walk_index-1);
       }
    }
index 1573f22338def2e82efabcfef7241b5aa4d3c957..cb18c8fd30adb396496e31bcb2ad2356a86ad1f8 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 /*
-   Copyright (C) 2000-2003 Kern Sibbald and John Walker
+   Copyright (C) 2003-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
@@ -32,9 +32,9 @@
  * Loop var through each member of table
  */
 #define foreach_htable(var, tbl) \
-       for(((void *)(var))=(tbl)->first(); \
-           (var); \
-           ((void *)(var))=(tbl)->next())
+        for((*((void **)&(var))=(void *)((tbl)->first())); \
+            (var); \
+            (*((void **)&(var))=(void *)((tbl)->next())))
 
 struct hlink {
    void *next;                        /* next hash item */
index 5b61b5da9258092393d05b658b5af6120032022f..6b95c321678d74bd7066873198f1d4f763c11320 100755 (executable)
@@ -9,7 +9,7 @@
  *
  */
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -53,7 +53,7 @@ void init_last_jobs_list()
    if (!last_jobs) {
       last_jobs = New(dlist(job_entry, &job_entry->link));
       if ((errstat=rwl_init(&lock)) != 0) {
-        Emsg1(M_ABORT, 0, _("Unable to initialize jcr_chain lock. ERR=%s\n"),
+         Emsg1(M_ABORT, 0, _("Unable to initialize jcr_chain lock. ERR=%s\n"),
               strerror(errstat));
       }
    }
@@ -92,7 +92,7 @@ void read_last_jobs_list(int fd, uint64_t addr)
    }
    for ( ; num; num--) {
       if (read(fd, &job, sizeof(job)) != sizeof(job)) {
-        Dmsg1(000, "Read job entry. ERR=%s\n", strerror(errno));
+         Dmsg1(000, "Read job entry. ERR=%s\n", strerror(errno));
         return;
       }
       if (job.JobId > 0) {
@@ -124,12 +124,12 @@ uint64_t write_last_jobs_list(int fd, uint64_t addr)
       /* First record is number of entires */
       num = last_jobs->size();
       if (write(fd, &num, sizeof(num)) != sizeof(num)) {
-        Dmsg1(000, "Error writing num_items: ERR=%s\n", strerror(errno));
+         Dmsg1(000, "Error writing num_items: ERR=%s\n", strerror(errno));
         return 0;
       }
       foreach_dlist(je, last_jobs) {
         if (write(fd, je, sizeof(struct s_last_job)) != sizeof(struct s_last_job)) {
-           Dmsg1(000, "Error writing job: ERR=%s\n", strerror(errno));
+            Dmsg1(000, "Error writing job: ERR=%s\n", strerror(errno));
            return 0;
         }
       }
@@ -188,7 +188,7 @@ JCR *new_jcr(int size, JCR_free_HANDLER *daemon_free_jcr)
    MQUEUE_ITEM *item = NULL;
    struct sigaction sigtimer;
 
-   Dmsg0(400, "Enter new_jcr\n");
+   Dmsg0(3400, "Enter new_jcr\n");
    jcr = (JCR *)malloc(size);
    memset(jcr, 0, size);
    jcr->my_thread_id = pthread_self();
@@ -234,7 +234,7 @@ JCR *new_jcr(int size, JCR_free_HANDLER *daemon_free_jcr)
  */
 static void remove_jcr(JCR *jcr)
 {
-   Dmsg0(400, "Enter remove_jcr\n");
+   Dmsg0(3400, "Enter remove_jcr\n");
    if (!jcr) {
       Emsg0(M_ABORT, 0, "NULL jcr.\n");
    }
@@ -246,7 +246,7 @@ static void remove_jcr(JCR *jcr)
    if (jcr->next) {
       jcr->next->prev = jcr->prev;
    }
-   Dmsg0(400, "Leave remove_jcr\n");
+   Dmsg0(3400, "Leave remove_jcr\n");
 }
 
 /*
@@ -342,14 +342,14 @@ static void free_common_jcr(JCR *jcr)
 #ifdef DEBUG
 void b_free_jcr(const char *file, int line, JCR *jcr)
 {
-   Dmsg3(400, "Enter free_jcr 0x%x from %s:%d\n", jcr, file, line);
+   Dmsg3(3400, "Enter free_jcr 0x%x from %s:%d\n", jcr, file, line);
 
 #else
 
 void free_jcr(JCR *jcr)
 {
 
-   Dmsg1(400, "Enter free_jcr 0x%x\n", jcr);
+   Dmsg1(3400, "Enter free_jcr 0x%x\n", jcr);
 
 #endif
 
@@ -360,10 +360,10 @@ void free_jcr(JCR *jcr)
       Emsg2(M_ERROR, 0, _("JCR use_count=%d JobId=%d\n"),
         jcr->use_count, jcr->JobId);
    }
-   Dmsg3(400, "Dec free_jcr 0x%x use_count=%d jobid=%d\n", jcr, jcr->use_count, jcr->JobId);
+   Dmsg3(3400, "Dec free_jcr 0x%x use_count=%d jobid=%d\n", jcr, jcr->use_count, jcr->JobId);
    if (jcr->use_count > 0) {         /* if in use */
       unlock_jcr_chain();
-      Dmsg2(400, "free_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+      Dmsg2(3400, "free_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
       return;
    }
    remove_jcr(jcr);                  /* remove Jcr from chain */
@@ -371,13 +371,13 @@ void free_jcr(JCR *jcr)
 
    job_end_pop(jcr);                 /* pop and call hooked routines */
 
-   Dmsg1(400, "End job=%d\n", jcr->JobId);
+   Dmsg1(3400, "End job=%d\n", jcr->JobId);
    if (jcr->daemon_free_jcr) {
       jcr->daemon_free_jcr(jcr);      /* call daemon free routine */
    }
    free_common_jcr(jcr);
    close_msg(NULL);                  /* flush any daemon messages */
-   Dmsg0(400, "Exit free_jcr\n");
+   Dmsg0(3400, "Exit free_jcr\n");
 }
 
 
@@ -388,7 +388,7 @@ void free_jcr(JCR *jcr)
 void free_locked_jcr(JCR *jcr)
 {
    jcr->use_count--;                 /* decrement use count */
-   Dmsg2(400, "Dec free_locked_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+   Dmsg2(3400, "Dec free_locked_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
    if (jcr->use_count > 0) {         /* if in use */
       return;
    }
@@ -414,7 +414,7 @@ JCR *get_jcr_by_id(uint32_t JobId)
         P(jcr->mutex);
         jcr->use_count++;
         V(jcr->mutex);
-        Dmsg2(400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+         Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
         break;
       }
    }
@@ -438,7 +438,7 @@ JCR *get_jcr_by_session(uint32_t SessionId, uint32_t SessionTime)
         P(jcr->mutex);
         jcr->use_count++;
         V(jcr->mutex);
-        Dmsg2(400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+         Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
         break;
       }
    }
@@ -469,7 +469,7 @@ JCR *get_jcr_by_partial_name(char *Job)
         P(jcr->mutex);
         jcr->use_count++;
         V(jcr->mutex);
-        Dmsg2(400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+         Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
         break;
       }
    }
@@ -497,7 +497,7 @@ JCR *get_jcr_by_full_name(char *Job)
         P(jcr->mutex);
         jcr->use_count++;
         V(jcr->mutex);
-        Dmsg2(400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+         Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
         break;
       }
    }
@@ -538,7 +538,7 @@ void lock_jcr_chain()
 {
    int errstat;
 #ifdef TRACE_JCR_CHAIN
-   Dmsg3(400, "Lock jcr chain %d from %s:%d\n", ++lock_count,
+   Dmsg3(3400, "Lock jcr chain %d from %s:%d\n", ++lock_count,
       fname, line);
 #endif
    if ((errstat=rwl_writelock(&lock)) != 0) {
@@ -558,7 +558,7 @@ void unlock_jcr_chain()
 {
    int errstat;
 #ifdef TRACE_JCR_CHAIN
-   Dmsg3(400, "Unlock jcr chain %d from %s:%d\n", lock_count--,
+   Dmsg3(3400, "Unlock jcr chain %d from %s:%d\n", lock_count--,
       fname, line);
 #endif
    if ((errstat=rwl_writeunlock(&lock)) != 0) {
@@ -581,7 +581,7 @@ JCR *get_next_jcr(JCR *prev_jcr)
       P(jcr->mutex);
       jcr->use_count++;
       V(jcr->mutex);
-      Dmsg2(400, "Inc get_next_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+      Dmsg2(3400, "Inc get_next_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
    }
    return jcr;
 }
@@ -606,7 +606,7 @@ static void jcr_timeout_check(watchdog_t *self)
    BSOCK *fd;
    time_t timer_start;
 
-   Dmsg0(400, "Start JCR timeout checks\n");
+   Dmsg0(3400, "Start JCR timeout checks\n");
 
    /* Walk through all JCRs checking if any one is
     * blocked for more than specified max time.
@@ -657,7 +657,7 @@ static void jcr_timeout_check(watchdog_t *self)
    }
    unlock_jcr_chain();
 
-   Dmsg0(400, "Finished JCR timeout checks\n");
+   Dmsg0(3400, "Finished JCR timeout checks\n");
 }
 
 /*
index b1e653cce47b106611386ab9fb85254a2986a726..d86280278cfbd0f9cdefb03eb5bea9f62fe6e23f 100755 (executable)
@@ -115,7 +115,7 @@ void my_name_is(int argc, char *argv[], const char *name)
    if (argc>0 && argv && argv[0]) {
       /* strip trailing filename and save exepath */
       for (l=p=argv[0]; *p; p++) {
-        if (*p == '/') {
+         if (*p == '/') {
            l = p;                       /* set pos of last slash */
         }
       }
@@ -125,7 +125,7 @@ void my_name_is(int argc, char *argv[], const char *name)
         l = argv[0];
 #if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
         /* On Windows allow c: junk */
-        if (l[1] == ':') {
+         if (l[1] == ':') {
            l += 2;
         }
 #endif
@@ -297,7 +297,7 @@ void add_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where, char *mai
    for (d=msg->dest_chain; d; d=d->next) {
       if (dest_code == d->dest_code && ((where == NULL && d->where == NULL) ||
                     (strcmp(where, d->where) == 0))) {
-        Dmsg4(200, "Add to existing d=%x msgtype=%d destcode=%d where=%s\n",
+         Dmsg4(850, "Add to existing d=%x msgtype=%d destcode=%d where=%s\n",
             d, msg_type, dest_code, NPRT(where));
         set_bit(msg_type, d->msg_types);
         set_bit(msg_type, msg->send_msg);  /* set msg_type bit in our local */
@@ -317,7 +317,7 @@ void add_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where, char *mai
    if (mail_cmd) {
       d->mail_cmd = bstrdup(mail_cmd);
    }
-   Dmsg5(200, "add new d=%x msgtype=%d destcode=%d where=%s mailcmd=%s\n",
+   Dmsg5(850, "add new d=%x msgtype=%d destcode=%d where=%s mailcmd=%s\n",
          d, msg_type, dest_code, NPRT(where), NPRT(d->mail_cmd));
    msg->dest_chain = d;
 }
@@ -332,14 +332,14 @@ void rem_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where)
    DEST *d;
 
    for (d=msg->dest_chain; d; d=d->next) {
-      Dmsg2(200, "Remove_msg_dest d=%x where=%s\n", d, NPRT(d->where));
+      Dmsg2(850, "Remove_msg_dest d=%x where=%s\n", d, NPRT(d->where));
       if (bit_is_set(msg_type, d->msg_types) && (dest_code == d->dest_code) &&
          ((where == NULL && d->where == NULL) ||
                     (strcmp(where, d->where) == 0))) {
-        Dmsg3(200, "Found for remove d=%x msgtype=%d destcode=%d\n",
+         Dmsg3(850, "Found for remove d=%x msgtype=%d destcode=%d\n",
               d, msg_type, dest_code);
         clear_bit(msg_type, d->msg_types);
-        Dmsg0(200, "Return rem_msg_dest\n");
+         Dmsg0(850, "Return rem_msg_dest\n");
         return;
       }
    }
@@ -358,7 +358,7 @@ static void make_unique_mail_filename(JCR *jcr, POOLMEM *&name, DEST *d)
       Mmsg(name, "%s/%s.mail.%s.%d", working_directory, my_name,
                 my_name, (int)(long)d);
    }
-   Dmsg1(200, "mailname=%s\n", name);
+   Dmsg1(850, "mailname=%s\n", name);
 }
 
 /*
@@ -401,7 +401,7 @@ void close_msg(JCR *jcr)
    POOLMEM *cmd, *line;
    int len, stat;
 
-   Dmsg1(350, "Close_msg jcr=0x%x\n", jcr);
+   Dmsg1(850, "Close_msg jcr=0x%x\n", jcr);
 
    if (jcr == NULL) {               /* NULL -> global chain */
       msgs = daemon_msgs;
@@ -413,7 +413,7 @@ void close_msg(JCR *jcr)
    if (msgs == NULL) {
       return;
    }
-   Dmsg1(350, "===Begin close msg resource at 0x%x\n", msgs);
+   Dmsg1(850, "===Begin close msg resource at 0x%x\n", msgs);
    cmd = get_pool_memory(PM_MESSAGE);
    for (d=msgs->dest_chain; d; ) {
       if (d->fd) {
@@ -426,7 +426,7 @@ void close_msg(JCR *jcr)
            break;
         case MD_MAIL:
         case MD_MAIL_ON_ERROR:
-           Dmsg0(350, "Got MD_MAIL or MD_MAIL_ON_ERROR\n");
+            Dmsg0(850, "Got MD_MAIL or MD_MAIL_ON_ERROR\n");
            if (!d->fd) {
               break;
            }
@@ -436,10 +436,10 @@ void close_msg(JCR *jcr)
            }
 
            if (!(bpipe=open_mail_pipe(jcr, cmd, d))) {
-              Pmsg0(000, "open mail pipe failed.\n");
+               Pmsg0(000, "open mail pipe failed.\n");
               goto rem_temp_file;
            }
-           Dmsg0(350, "Opened mail pipe\n");
+            Dmsg0(850, "Opened mail pipe\n");
            len = d->max_len+10;
            line = get_memory(len);
            rewind(d->fd);
@@ -448,18 +448,18 @@ void close_msg(JCR *jcr)
            }
            if (!close_wpipe(bpipe)) {       /* close write pipe sending mail */
               berrno be;
-              Pmsg1(000, "close error: ERR=%s\n", be.strerror());
+               Pmsg1(000, "close error: ERR=%s\n", be.strerror());
            }
 
            /*
-            * Since we are closing all messages, before "recursing"
+             * Since we are closing all messages, before "recursing"
             * make sure we are not closing the daemon messages, otherwise
             * kaboom.
             */
            if (msgs != daemon_msgs) {
               /* read what mail prog returned -- should be nothing */
               while (fgets(line, len, bpipe->rfd)) {
-                 Jmsg1(jcr, M_INFO, 0, _("Mail prog: %s"), line);
+                  Jmsg1(jcr, M_INFO, 0, _("Mail prog: %s"), line);
               }
            }
 
@@ -467,10 +467,10 @@ void close_msg(JCR *jcr)
            if (stat != 0 && msgs != daemon_msgs) {
               berrno be;
               be.set_errno(stat);
-              Dmsg1(350, "Calling emsg. CMD=%s\n", cmd);
-              Jmsg2(jcr, M_ERROR, 0, _("Mail program terminated in error.\n"
-                                       "CMD=%s\n"
-                                       "ERR=%s\n"), cmd, be.strerror());
+               Dmsg1(850, "Calling emsg. CMD=%s\n", cmd);
+               Jmsg2(jcr, M_ERROR, 0, _("Mail program terminated in error.\n"
+                                        "CMD=%s\n"
+                                        "ERR=%s\n"), cmd, be.strerror());
            }
            free_memory(line);
 rem_temp_file:
@@ -479,7 +479,7 @@ rem_temp_file:
            unlink(d->mail_filename);
            free_pool_memory(d->mail_filename);
            d->mail_filename = NULL;
-           Dmsg0(350, "end mail or mail on error\n");
+            Dmsg0(850, "end mail or mail on error\n");
            break;
         default:
            break;
@@ -489,14 +489,14 @@ rem_temp_file:
       d = d->next;                   /* point to next buffer */
    }
    free_pool_memory(cmd);
-   Dmsg0(350, "Done walking message chain.\n");
+   Dmsg0(850, "Done walking message chain.\n");
    if (jcr) {
       free_msgs_res(msgs);
       msgs = NULL;
    } else {
       V(mutex);
    }
-   Dmsg0(350, "===End close msg resource\n");
+   Dmsg0(850, "===End close msg resource\n");
 }
 
 /*
@@ -532,7 +532,7 @@ void free_msgs_res(MSGS *msgs)
  */
 void term_msg()
 {
-   Dmsg0(300, "Enter term_msg\n");
+   Dmsg0(850, "Enter term_msg\n");
    close_msg(NULL);                  /* close global chain */
    free_msgs_res(daemon_msgs);       /* free the resources */
    daemon_msgs = NULL;
@@ -570,7 +570,7 @@ void dispatch_message(JCR *jcr, int type, time_t mtime, char *msg)
     MSGS *msgs;
     BPIPE *bpipe;
 
-    Dmsg2(800, "Enter dispatch_msg type=%d msg=%s\n", type, msg);
+    Dmsg2(850, "Enter dispatch_msg type=%d msg=%s\n", type, msg);
 
     /*
      * Most messages are prefixed by a date and time. If mtime is
@@ -601,7 +601,7 @@ void dispatch_message(JCR *jcr, int type, time_t mtime, char *msg)
 #if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
        /* If we don't exit on error, error messages are parsed by UA */
        if (exit_on_error) {
-         MessageBox(NULL, msg, "Bacula", MB_OK);
+          MessageBox(NULL, msg, "Bacula", MB_OK);
        }
 #endif
 #endif
@@ -619,10 +619,10 @@ void dispatch_message(JCR *jcr, int type, time_t mtime, char *msg)
        if (bit_is_set(type, d->msg_types)) {
          switch (d->dest_code) {
             case MD_CONSOLE:
-               Dmsg1(800, "CONSOLE for following msg: %s", msg);
+                Dmsg1(850, "CONSOLE for following msg: %s", msg);
                if (!con_fd) {
-                  con_fd = fopen(con_fname, "a+");
-                  Dmsg0(800, "Console file not open.\n");
+                   con_fd = fopen(con_fname, "a+");
+                   Dmsg0(850, "Console file not open.\n");
                }
                if (con_fd) {
                   Pw(con_lock);      /* get write lock on console message file */
@@ -633,11 +633,11 @@ void dispatch_message(JCR *jcr, int type, time_t mtime, char *msg)
                   len = strlen(msg);
                   if (len > 0) {
                      fwrite(msg, len, 1, con_fd);
-                     if (msg[len-1] != '\n') {
-                        fwrite("\n", 2, 1, con_fd);
+                      if (msg[len-1] != '\n') {
+                         fwrite("\n", 2, 1, con_fd);
                      }
                   } else {
-                     fwrite("\n", 2, 1, con_fd);
+                      fwrite("\n", 2, 1, con_fd);
                   }
                   fflush(con_fd);
                   console_msg_pending = TRUE;
@@ -645,14 +645,14 @@ void dispatch_message(JCR *jcr, int type, time_t mtime, char *msg)
                }
                break;
             case MD_SYSLOG:
-               Dmsg1(800, "SYSLOG for collowing msg: %s\n", msg);
+                Dmsg1(850, "SYSLOG for collowing msg: %s\n", msg);
                /*
                 * We really should do an openlog() here.
                 */
-               syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
+                syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
                break;
             case MD_OPERATOR:
-               Dmsg1(800, "OPERATOR for following msg: %s\n", msg);
+                Dmsg1(850, "OPERATOR for following msg: %s\n", msg);
                mcmd = get_pool_memory(PM_MESSAGE);
                if ((bpipe=open_mail_pipe(jcr, mcmd, d))) {
                   int stat;
@@ -663,24 +663,24 @@ void dispatch_message(JCR *jcr, int type, time_t mtime, char *msg)
                   if (stat != 0) {
                      berrno be;
                      be.set_errno(stat);
-                     Qmsg2(jcr, M_ERROR, 0, _("Operator mail program terminated in error.\n"
-                           "CMD=%s\n"
-                           "ERR=%s\n"), mcmd, be.strerror());
+                      Qmsg2(jcr, M_ERROR, 0, _("Operator mail program terminated in error.\n"
+                            "CMD=%s\n"
+                            "ERR=%s\n"), mcmd, be.strerror());
                   }
                }
                free_pool_memory(mcmd);
                break;
             case MD_MAIL:
             case MD_MAIL_ON_ERROR:
-               Dmsg1(800, "MAIL for following msg: %s", msg);
+                Dmsg1(850, "MAIL for following msg: %s", msg);
                if (!d->fd) {
                   POOLMEM *name = get_pool_memory(PM_MESSAGE);
                   make_unique_mail_filename(jcr, name, d);
-                  d->fd = fopen(name, "w+");
+                   d->fd = fopen(name, "w+");
                   if (!d->fd) {
                      berrno be;
                      d->fd = stdout;
-                     Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", name,
+                      Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", name,
                            be.strerror());
                      d->fd = NULL;
                      free_pool_memory(name);
@@ -696,13 +696,13 @@ void dispatch_message(JCR *jcr, int type, time_t mtime, char *msg)
                fputs(msg, d->fd);
                break;
             case MD_FILE:
-               Dmsg1(800, "FILE for following msg: %s", msg);
+                Dmsg1(850, "FILE for following msg: %s", msg);
                if (!d->fd) {
-                  d->fd = fopen(d->where, "w+");
+                   d->fd = fopen(d->where, "w+");
                   if (!d->fd) {
                      berrno be;
                      d->fd = stdout;
-                     Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", d->where,
+                      Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", d->where,
                            be.strerror());
                      d->fd = NULL;
                      break;
@@ -712,13 +712,13 @@ void dispatch_message(JCR *jcr, int type, time_t mtime, char *msg)
                fputs(msg, d->fd);
                break;
             case MD_APPEND:
-               Dmsg1(800, "APPEND for following msg: %s", msg);
+                Dmsg1(850, "APPEND for following msg: %s", msg);
                if (!d->fd) {
-                  d->fd = fopen(d->where, "a");
+                   d->fd = fopen(d->where, "a");
                   if (!d->fd) {
                      berrno be;
                      d->fd = stdout;
-                     Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", d->where,
+                      Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", d->where,
                            be.strerror());
                      d->fd = NULL;
                      break;
@@ -728,21 +728,21 @@ void dispatch_message(JCR *jcr, int type, time_t mtime, char *msg)
                fputs(msg, d->fd);
                break;
             case MD_DIRECTOR:
-               Dmsg1(800, "DIRECTOR for following msg: %s", msg);
+                Dmsg1(850, "DIRECTOR for following msg: %s", msg);
                if (jcr && jcr->dir_bsock && !jcr->dir_bsock->errors) {
-                  bnet_fsend(jcr->dir_bsock, "Jmsg Job=%s type=%d level=%d %s",
+                   bnet_fsend(jcr->dir_bsock, "Jmsg Job=%s type=%d level=%d %s",
                      jcr->Job, type, mtime, msg);
                }
                break;
             case MD_STDOUT:
-               Dmsg1(800, "STDOUT for following msg: %s", msg);
+                Dmsg1(850, "STDOUT for following msg: %s", msg);
                if (type != M_ABORT && type != M_ERROR_TERM) { /* already printed */
                   fputs(dt, stdout);
                   fputs(msg, stdout);
                }
                break;
             case MD_STDERR:
-               Dmsg1(800, "STDERR for following msg: %s", msg);
+                Dmsg1(850, "STDERR for following msg: %s", msg);
                fputs(dt, stderr);
                fputs(msg, stderr);
                break;
@@ -783,9 +783,9 @@ d_msg(const char *file, int line, int level, const char *fmt,...)
          /* visual studio passes the whole path to the file as well
           * which makes for very long lines
           */
-         const char *f = strrchr(file, '\\');
+          const char *f = strrchr(file, '\\');
          if (f) file = f + 1;
-         len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line);
+          len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line);
        } else {
          len = 0;
        }
@@ -797,13 +797,13 @@ d_msg(const char *file, int line, int level, const char *fmt,...)
        va_end(arg_ptr);
 
        /*
-       * Used the "trace on" command in the console to turn on
-       *  output to the trace file.  "trace off" will close the file.
+        * Used the "trace on" command in the console to turn on
+        *  output to the trace file.  "trace off" will close the file.
        */
        if (trace) {
          if (!trace_fd) {
-            bsnprintf(buf, sizeof(buf), "%s/bacula.trace", working_directory ? working_directory : ".");
-            trace_fd = fopen(buf, "a+");
+             bsnprintf(buf, sizeof(buf), "%s/bacula.trace", working_directory ? working_directory : ".");
+             trace_fd = fopen(buf, "a+");
          }
          if (trace_fd) {
             fputs(buf, trace_fd);
@@ -895,13 +895,13 @@ t_msg(const char *file, int line, int level, const char *fmt,...)
 
     if (level <= debug_level) {
        if (!trace_fd) {
-         bsnprintf(buf, sizeof(buf), "%s/bacula.trace", working_directory);
-         trace_fd = fopen(buf, "a+");
+          bsnprintf(buf, sizeof(buf), "%s/bacula.trace", working_directory);
+          trace_fd = fopen(buf, "a+");
        }
 
 #ifdef FULL_LOCATION
        if (details) {
-         len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line);
+          len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line);
        } else {
          len = 0;
        }
@@ -951,15 +951,15 @@ e_msg(const char *file, int line, int type, int level, const char *fmt,...)
        break;
     case M_FATAL:
        if (level == -1)           /* skip details */
-         len = bsnprintf(buf, sizeof(buf), "%s: Fatal Error because: ", my_name);
+          len = bsnprintf(buf, sizeof(buf), "%s: Fatal Error because: ", my_name);
        else
-         len = bsnprintf(buf, sizeof(buf), "%s: Fatal Error at %s:%d because:\n", my_name, file, line);
+          len = bsnprintf(buf, sizeof(buf), "%s: Fatal Error at %s:%d because:\n", my_name, file, line);
        break;
     case M_ERROR:
        if (level == -1)           /* skip details */
-         len = bsnprintf(buf, sizeof(buf), "%s: ERROR: ", my_name);
+          len = bsnprintf(buf, sizeof(buf), "%s: ERROR: ", my_name);
        else
-         len = bsnprintf(buf, sizeof(buf), "%s: ERROR in %s:%d ", my_name, file, line);
+          len = bsnprintf(buf, sizeof(buf), "%s: ERROR in %s:%d ", my_name, file, line);
        break;
     case M_WARNING:
        len = bsnprintf(buf, sizeof(buf), "%s: Warning: ", my_name);
@@ -1002,7 +1002,7 @@ Jmsg(JCR *jcr, int type, time_t mtime, const char *fmt,...)
     const char *job;
 
 
-    Dmsg1(800, "Enter Jmsg type=%d\n", type);
+    Dmsg1(850, "Enter Jmsg type=%d\n", type);
 
     /* Special case for the console, which has a dir_bsock and JobId==0,
      * in that case, we send the message directly back to the
index f79e1b8fa21312b6e82598aba571d82cc1d7f7df..f8670f67b9b81107c5c68b8ce80a29d800bfb0cb 100755 (executable)
@@ -176,7 +176,7 @@ void init_resource(int type, RES_ITEM *items, int pass)
 
    for (i=0; items[i].name; i++) {
       Dmsg3(900, "Item=%s def=%s defval=%d\n", items[i].name,
-           (items[i].flags & ITEM_DEFAULT) ? "yes" : "no",
+            (items[i].flags & ITEM_DEFAULT) ? "yes" : "no",
            items[i].default_value);
       if (items[i].flags & ITEM_DEFAULT && items[i].default_value != 0) {
         if (items[i].handler == store_yesno) {
@@ -196,7 +196,7 @@ void init_resource(int type, RES_ITEM *items, int pass)
       }
       /* If this triggers, take a look at lib/parse_conf.h */
       if (i >= MAX_RES_ITEMS) {
-        Emsg1(M_ERROR_TERM, 0, _("Too many items in %s resource\n"), resources[rindex]);
+         Emsg1(M_ERROR_TERM, 0, _("Too many items in %s resource\n"), resources[rindex]);
       }
    }
 }
@@ -236,25 +236,25 @@ void store_msgs(LEX *lc, RES_ITEM *item, int index, int pass)
            token = lex_get_token(lc, T_NAME);   /* scan destination */
            dest = check_pool_memory_size(dest, dest_len + lc->str_len + 2);
            if (dest[0] != 0) {
-              pm_strcat(dest, " ");  /* separate multiple destinations with space */
+               pm_strcat(dest, " ");  /* separate multiple destinations with space */
               dest_len++;
            }
            pm_strcat(dest, lc->str);
            dest_len += lc->str_len;
-           Dmsg2(900, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest));
+            Dmsg2(900, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest));
            token = lex_get_token(lc, T_SKIP_EOL);
            if (token == T_COMMA) {
               continue;           /* get another destination */
            }
            if (token != T_EQUALS) {
-              scan_err1(lc, _("expected an =, got: %s"), lc->str);
+               scan_err1(lc, _("expected an =, got: %s"), lc->str);
            }
            break;
         }
-        Dmsg1(900, "mail_cmd=%s\n", NPRT(cmd));
+         Dmsg1(900, "mail_cmd=%s\n", NPRT(cmd));
         scan_types(lc, (MSGS *)(item->value), item->code, dest, cmd);
         free_pool_memory(dest);
-        Dmsg0(900, "done with dest codes\n");
+         Dmsg0(900, "done with dest codes\n");
         break;
       case MD_FILE:               /* file */
       case MD_APPEND:             /* append */
@@ -264,17 +264,17 @@ void store_msgs(LEX *lc, RES_ITEM *item, int index, int pass)
         pm_strcpy(dest, lc->str);
         dest_len = lc->str_len;
         token = lex_get_token(lc, T_SKIP_EOL);
-        Dmsg1(900, "store_msgs dest=%s:\n", NPRT(dest));
+         Dmsg1(900, "store_msgs dest=%s:\n", NPRT(dest));
         if (token != T_EQUALS) {
-           scan_err1(lc, _("expected an =, got: %s"), lc->str);
+            scan_err1(lc, _("expected an =, got: %s"), lc->str);
         }
         scan_types(lc, (MSGS *)(item->value), item->code, dest, NULL);
         free_pool_memory(dest);
-        Dmsg0(900, "done with dest codes\n");
+         Dmsg0(900, "done with dest codes\n");
         break;
 
       default:
-        scan_err1(lc, _("Unknown item code: %d\n"), item->code);
+         scan_err1(lc, _("Unknown item code: %d\n"), item->code);
         break;
       }
    }
@@ -313,7 +313,7 @@ static void scan_types(LEX *lc, MSGS *msg, int dest_code, char *where, char *cmd
         }
       }
       if (!found) {
-        scan_err1(lc, _("message type: %s not found"), str);
+         scan_err1(lc, _("message type: %s not found"), str);
         /* NOT REACHED */
       }
 
@@ -421,7 +421,7 @@ void store_password(LEX *lc, RES_ITEM *item, int index, int pass)
       MD5Update(&md5c, (unsigned char *) (lc->str), lc->str_len);
       MD5Final(signature, &md5c);
       for (i = j = 0; i < sizeof(signature); i++) {
-        sprintf(&sig[j], "%02x", signature[i]);
+         sprintf(&sig[j], "%02x", signature[i]);
         j += 2;
       }
       *(item->value) = bstrdup(sig);
@@ -443,11 +443,11 @@ void store_res(LEX *lc, RES_ITEM *item, int index, int pass)
    if (pass == 2) {
       res = GetResWithName(item->code, lc->str);
       if (res == NULL) {
-        scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n"),
+         scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n"),
            lc->str, lc->line_no, lc->line);
       }
       if (*(item->value)) {
-        scan_err3(lc, _("Attempt to redefine resource \"%s\" referenced on line %d : %s\n"),
+         scan_err3(lc, _("Attempt to redefine resource \"%s\" referenced on line %d : %s\n"),
            item->name, lc->line_no, lc->line);
       }
       *(item->value) = (char *)res;
@@ -457,7 +457,7 @@ void store_res(LEX *lc, RES_ITEM *item, int index, int pass)
 }
 
 /*
- * Store a resource in an alist. default_value indicates how many
+ * Store a resource pointer in an alist. default_value indicates how many
  *   times this routine can be called -- i.e. how many alists
  *   there are.
  * If we are in pass 2, do a lookup of the
@@ -471,24 +471,35 @@ void store_alist_res(LEX *lc, RES_ITEM *item, int index, int pass)
    alist *list;
 
    if (pass == 2) {
-      /* Find empty place to store this directive */
-      while ((item->value)[i] != NULL && i++ < count) { }
-      if (i >= count) {
-        scan_err3(lc, _("Too many Storage directives. Max. is %d. line %d: %s\n"),
-           count, lc->line_no, lc->line);
+      if (count == 0) {              /* always store in item->value */
+        i = 0;
+        if ((item->value)[i] == NULL) {
+           list = New(alist(10, not_owned_by_alist));
+        } else {
+           list = (alist *)(item->value)[i];
+        }
+      } else {
+        /* Find empty place to store this directive */
+        while ((item->value)[i] != NULL && i++ < count) { }
+        if (i >= count) {
+            scan_err4(lc, _("Too many %s directives. Max. is %d. line %d: %s\n"),
+              lc->str, count, lc->line_no, lc->line);
+        }
+        list = New(alist(10, not_owned_by_alist));
       }
-      list = New(alist(10, not_owned_by_alist));
 
       for (;;) {
         lex_get_token(lc, T_NAME);   /* scan next item */
         res = GetResWithName(item->code, lc->str);
         if (res == NULL) {
-           scan_err3(lc, _("Could not find config Resource \"%s\" referenced on line %d : %s\n"),
-              lc->str, lc->line_no, lc->line);
+            scan_err3(lc, _("Could not find config Resource \"%s\" referenced on line %d : %s\n"),
+              item->name, lc->line_no, lc->line);
         }
+         Dmsg5(900, "Append %p to alist %p size=%d i=%d %s\n", 
+              res, list, list->size(), i, item->name);
         list->append(res);
         (item->value)[i] = (char *)list;
-        if (lc->ch != ',') {         /* if no other item follows */
+         if (lc->ch != ',') {         /* if no other item follows */
            break;                    /* get out */
         }
         lex_get_token(lc, T_ALL);    /* eat comma */
@@ -517,16 +528,16 @@ void store_defs(LEX *lc, RES_ITEM *item, int index, int pass)
      Dmsg2(900, "Code=%d name=%s\n", item->code, lc->str);
      res = GetResWithName(item->code, lc->str);
      if (res == NULL) {
-       scan_err3(lc, _("Missing config Resource \"%s\" referenced on line %d : %s\n"),
+        scan_err3(lc, _("Missing config Resource \"%s\" referenced on line %d : %s\n"),
           lc->str, lc->line_no, lc->line);
      }
      /* for each item not set, we copy the field from res */
 #ifdef xxx
      for (int i=0; item->name;; i++, item++) {
        if (bit_is_set(i, res->item_present)) {
-          Dmsg2(900, "Item %d is present in %s\n", i, res->name);
+           Dmsg2(900, "Item %d is present in %s\n", i, res->name);
        } else {
-          Dmsg2(900, "Item %d is not present in %s\n", i, res->name);
+           Dmsg2(900, "Item %d is not present in %s\n", i, res->name);
        }
      }
      /* ***FIXME **** add code */
@@ -579,7 +590,7 @@ void store_size(LEX *lc, RES_ITEM *item, int index, int pass)
    case T_IDENTIFIER:
    case T_UNQUOTED_STRING:
       if (!size_to_uint64(lc->str, lc->str_len, &uvalue)) {
-        scan_err1(lc, _("expected a size number, got: %s"), lc->str);
+         scan_err1(lc, _("expected a size number, got: %s"), lc->str);
       }
       *(uint64_t *)(item->value) = uvalue;
       break;
@@ -617,7 +628,7 @@ void store_time(LEX *lc, RES_ITEM *item, int index, int pass)
         }
       }
       if (!duration_to_utime(period, &utime)) {
-        scan_err1(lc, _("expected a time period, got: %s"), period);
+         scan_err1(lc, _("expected a time period, got: %s"), period);
       }
       *(utime_t *)(item->value) = utime;
       break;
@@ -654,7 +665,7 @@ void b_LockRes(const char *file, int line)
 {
    int errstat;
 #ifdef TRACE_RES
-   Dmsg4(000, "LockRes   %d,%d at %s:%d\n", res_locked, res_lock.w_active,
+   Pmsg4(000, "LockRes   %d,%d at %s:%d\n", res_locked, res_lock.w_active,
         file, line);
 #endif
    if ((errstat=rwl_writelock(&res_lock)) != 0) {
@@ -669,7 +680,7 @@ void b_UnlockRes(const char *file, int line)
    int errstat;
    res_locked--;
 #ifdef TRACE_RES
-   Dmsg4(000, "UnLockRes %d,%d at %s:%d\n", res_locked, res_lock.w_active,
+   Pmsg4(000, "UnLockRes %d,%d at %s:%d\n", res_locked, res_lock.w_active,
         file, line);
 #endif
    if ((errstat=rwl_writeunlock(&res_lock)) != 0) {
@@ -758,14 +769,14 @@ parse_config(const char *cf, int exit_on_error)
         return 0;
       }
       while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
-        Dmsg1(900, "parse got token=%s\n", lex_tok_to_str(token));
+         Dmsg1(900, "parse got token=%s\n", lex_tok_to_str(token));
         switch (state) {
         case p_none:
            if (token == T_EOL) {
               break;
            }
            if (token != T_IDENTIFIER) {
-              scan_err1(lc, _("Expected a Resource name identifier, got: %s"), lc->str);
+               scan_err1(lc, _("Expected a Resource name identifier, got: %s"), lc->str);
               set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
               return 0;
            }
@@ -778,7 +789,7 @@ parse_config(const char *cf, int exit_on_error)
                  break;
               }
            if (state == p_none) {
-              scan_err1(lc, _("expected resource name, got: %s"), lc->str);
+               scan_err1(lc, _("expected resource name, got: %s"), lc->str);
               set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
               return 0;
            }
@@ -790,7 +801,7 @@ parse_config(const char *cf, int exit_on_error)
               break;
            case T_IDENTIFIER:
               if (level != 1) {
-                 scan_err1(lc, _("not in resource definition: %s"), lc->str);
+                  scan_err1(lc, _("not in resource definition: %s"), lc->str);
                  set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
                  return 0;
               }
@@ -800,14 +811,14 @@ parse_config(const char *cf, int exit_on_error)
                      *   scan for = after the keyword  */
                     if (!(items[i].flags & ITEM_NO_EQUALS)) {
                        token = lex_get_token(lc, T_SKIP_EOL);
-                       Dmsg1 (900, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
+                        Dmsg1 (900, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
                        if (token != T_EQUALS) {
-                          scan_err1(lc, _("expected an equals, got: %s"), lc->str);
+                           scan_err1(lc, _("expected an equals, got: %s"), lc->str);
                           set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
                           return 0;
                        }
                     }
-                    Dmsg1(900, "calling handler for %s\n", items[i].name);
+                     Dmsg1(900, "calling handler for %s\n", items[i].name);
                     /* Call item handler */
                     items[i].handler(lc, &items[i], i, pass);
                     i = -1;
@@ -815,10 +826,10 @@ parse_config(const char *cf, int exit_on_error)
                  }
               }
               if (i >= 0) {
-                 Dmsg2(900, "level=%d id=%s\n", level, lc->str);
-                 Dmsg1(900, "Keyword = %s\n", lc->str);
-                 scan_err1(lc, _("Keyword \"%s\" not permitted in this resource.\n"
-                    "Perhaps you left the trailing brace off of the previous resource."), lc->str);
+                  Dmsg2(900, "level=%d id=%s\n", level, lc->str);
+                  Dmsg1(900, "Keyword = %s\n", lc->str);
+                  scan_err1(lc, _("Keyword \"%s\" not permitted in this resource.\n"
+                     "Perhaps you left the trailing brace off of the previous resource."), lc->str);
                  set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
                  return 0;
               }
@@ -827,7 +838,7 @@ parse_config(const char *cf, int exit_on_error)
            case T_EOB:
               level--;
               state = p_none;
-              Dmsg0(900, "T_EOB => define new resource\n");
+               Dmsg0(900, "T_EOB => define new resource\n");
               save_resource(res_type, items, pass);  /* save resource */
               break;
 
@@ -835,20 +846,20 @@ parse_config(const char *cf, int exit_on_error)
               break;
 
            default:
-              scan_err2(lc, _("unexpected token %d %s in resource definition"),
+               scan_err2(lc, _("unexpected token %d %s in resource definition"),
                  token, lex_tok_to_str(token));
               set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
               return 0;
            }
            break;
         default:
-           scan_err1(lc, _("Unknown parser state %d\n"), state);
+            scan_err1(lc, _("Unknown parser state %d\n"), state);
            set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
            return 0;
         }
       }
       if (state != p_none) {
-        scan_err0(lc, _("End of conf file reached with unclosed resource."));
+         scan_err0(lc, _("End of conf file reached with unclosed resource."));
         set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
         return 0;
       }
index d1cc5cc99b6f297c0aae243687588b059eccb90a..f73f1a395e0910d2d3281e7d2e88f680a0bb8059 100644 (file)
@@ -4,7 +4,7 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   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
@@ -73,11 +73,11 @@ bool       bnet_sig              (BSOCK *bs, int sig);
 int        bnet_ssl_server       (BSOCK *bsock, char *password, int ssl_need, int ssl_has);
 int        bnet_ssl_client       (BSOCK *bsock, char *password, int ssl_need);
 BSOCK *    bnet_connect            (JCR *jcr, int retry_interval,
-              int max_retry_time, const char *name, char *host, char *service,
-              int port, int verbose);
+               int max_retry_time, const char *name, char *host, char *service,
+               int port, int verbose);
 void       bnet_close            (BSOCK *bsock);
 BSOCK *    init_bsock            (JCR *jcr, int sockfd, const char *who, const char *ip,
-                                 int port, struct sockaddr *client_addr);
+                                  int port, struct sockaddr *client_addr);
 BSOCK *    dup_bsock             (BSOCK *bsock);
 void       term_bsock            (BSOCK *bsock);
 const char *bnet_strerror         (BSOCK *bsock);
@@ -102,7 +102,7 @@ int              close_bpipe(BPIPE *bpipe);
 int cram_md5_get_auth(BSOCK *bs, char *password, int ssl_need);
 int cram_md5_auth(BSOCK *bs, char *password, int ssl_need);
 void hmac_md5(uint8_t* text, int text_len, uint8_t*  key,
-             int key_len, uint8_t *hmac);
+              int key_len, uint8_t *hmac);
 
 /* crc32.c */
 
@@ -117,6 +117,7 @@ int64_t          str_to_int64(char *str);
 char *           edit_uint64_with_commas   (uint64_t val, char *buf);
 char *           add_commas              (char *val, char *buf);
 char *           edit_uint64             (uint64_t val, char *buf);
+char *           edit_int64              (int64_t val, char *buf);
 int              duration_to_utime       (char *str, utime_t *value);
 int              size_to_uint64(char *str, int str_len, uint64_t *rtn_value);
 char             *edit_utime             (utime_t val, char *buf, int buf_len);
@@ -160,7 +161,7 @@ void       set_exit_on_error     (int value);
 
 /* bnet_server.c */
 void       bnet_thread_server(dlist *addr, int max_clients, workq_t *client_wq,
-                  void *handle_client_request(void *bsock));
+                   void *handle_client_request(void *bsock));
 void       bnet_stop_thread_server(pthread_t tid);
 void             bnet_server             (int port, void handle_client_request(BSOCK *bsock));
 int              net_connect             (int port);
@@ -191,9 +192,9 @@ bool             skip_nonspaces          (char **msg);
 int              fstrsch                 (const char *a, const char *b);
 char            *next_arg(char **s);
 int              parse_args(POOLMEM *cmd, POOLMEM **args, int *argc,
-                       char **argk, char **argv, int max_args);
+                        char **argk, char **argv, int max_args);
 void            split_path_and_filename(const char *fname, POOLMEM **path,
-                       int *pnl, POOLMEM **file, int *fnl);
+                        int *pnl, POOLMEM **file, int *fnl);
 int             bsscanf(const char *buf, const char *fmt, ...);
 
 
index 70d567fc33fc691c7086253fb5f008fa17f0e893..1e54ec95afdbe2bea6b1a0ece21a104b08abe061 100644 (file)
@@ -135,7 +135,7 @@ char *next_arg(char **s)
    for (p=*s; *p && B_ISSPACE(*p); ) {
       p++;
    }
-   Dmsg1(400, "Next arg=%s\n", p);
+   Dmsg1(900, "Next arg=%s\n", p);
    for (n = q = p; *p ; ) {
       if (*p == '\\') {
         p++;
@@ -164,7 +164,7 @@ char *next_arg(char **s)
    }
    *q = 0;
    *s = p;
-   Dmsg2(400, "End arg=%s next=%s\n", n, p);
+   Dmsg2(900, "End arg=%s next=%s\n", n, p);
    return n;
 }
 
@@ -213,9 +213,9 @@ int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc,
       if (p) {
         *p++ = 0;                    /* terminate keyword and point to value */
         /* Unquote quoted values */
-        if (*p == '"') {
-           for (n = q = ++p; *p && *p != '"'; ) {
-              if (*p == '\\') {
+         if (*p == '"') {
+            for (n = q = ++p; *p && *p != '"'; ) {
+               if (*p == '\\') {
                  p++;
               }
               *q++ = *p++;
@@ -314,11 +314,11 @@ int bsscanf(const char *buf, const char *fmt, ...)
 //       Dmsg1(000, "Got %% nxt=%c\n", *fmt);
 switch_top:
         switch (*fmt++) {
-        case 'u':
-        case 'd':
+         case 'u':
+         case 'd':
            value = 0;
            while (B_ISDIGIT(*buf)) {
-              value = B_TIMES10(value) + *buf++ - '0';
+               value = B_TIMES10(value) + *buf++ - '0';
            }
            vp = (void *)va_arg(ap, void *);
 //          Dmsg2(000, "val=%lld at 0x%lx\n", value, (long unsigned)vp);
@@ -332,28 +332,28 @@ switch_top:
            count++;
            l = 0;
            break;
-        case 'l':
+         case 'l':
 //          Dmsg0(000, "got l\n");
            l = 1;
-           if (*fmt == 'l') {
+            if (*fmt == 'l') {
               l++;
               fmt++;
            }
-           if (*fmt == 'd' || *fmt == 'u') {
+            if (*fmt == 'd' || *fmt == 'u') {
               goto switch_top;
            }
 //          Dmsg1(000, "fmt=%c !=d,u\n", *fmt);
            error = true;
            break;
-        case 'q':
+         case 'q':
            l = 2;
-           if (*fmt == 'd' || *fmt == 'u') {
+            if (*fmt == 'd' || *fmt == 'u') {
               goto switch_top;
            }
 //          Dmsg1(000, "fmt=%c !=d,u\n", *fmt);
            error = true;
            break;
-        case 's':
+         case 's':
 //          Dmsg1(000, "Store string max_len=%d\n", max_len);
            cp = (char *)va_arg(ap, char *);
            while (*buf && !B_ISSPACE(*buf) && max_len-- > 0) {
@@ -363,13 +363,13 @@ switch_top:
            count++;
            max_len = BIG;
            break;
-        case 'c':
+         case 'c':
            cp = (char *)va_arg(ap, char *);
            *cp = *buf++;
            count++;
            break;
-        case '%':
-           if (*buf++ != '%') {
+         case '%':
+            if (*buf++ != '%') {
               error = true;
            }
            break;
@@ -377,10 +377,10 @@ switch_top:
            fmt--;
            max_len = 0;
            while (B_ISDIGIT(*fmt)) {
-              max_len = B_TIMES10(max_len) + *fmt++ - '0';
+               max_len = B_TIMES10(max_len) + *fmt++ - '0';
            }
 //          Dmsg1(000, "Default max_len=%d\n", max_len);
-           if (*fmt == 's') {
+            if (*fmt == 's') {
               goto switch_top;
            }
 //          Dmsg1(000, "Default c=%c\n", *fmt);
index ec6bc848a5ea8c25491470774f80ea3554afdc36..a08e51ed55244f2854d3a52541b0610c11a3377c 100755 (executable)
@@ -68,7 +68,7 @@ int start_watchdog(void)
    if (wd_is_init) {
       return 0;
    }
-   Dmsg0(400, "Initialising NicB-hacked watchdog thread\n");
+   Dmsg0(800, "Initialising NicB-hacked watchdog thread\n");
    watchdog_time = time(NULL);
 
    if ((errstat=rwl_init(&lock)) != 0) {
@@ -180,8 +180,8 @@ bool register_watchdog(watchdog_t *wd)
    wd_lock();
    wd->next_fire = watchdog_time + wd->interval;
    wd_queue->append(wd);
-   Dmsg3(400, "Registered watchdog %p, interval %d%s\n",
-        wd, wd->interval, wd->one_shot ? " one shot" : "");
+   Dmsg3(800, "Registered watchdog %p, interval %d%s\n",
+         wd, wd->interval, wd->one_shot ? " one shot" : "");
    wd_unlock();
    ping_watchdog();
 
@@ -201,7 +201,7 @@ bool unregister_watchdog(watchdog_t *wd)
    foreach_dlist(p, wd_queue) {
       if (wd == p) {
         wd_queue->remove(wd);
-        Dmsg1(400, "Unregistered watchdog %p\n", wd);
+         Dmsg1(800, "Unregistered watchdog %p\n", wd);
         ok = true;
         goto get_out;
       }
@@ -210,13 +210,13 @@ bool unregister_watchdog(watchdog_t *wd)
    foreach_dlist(p, wd_inactive) {
       if (wd == p) {
         wd_inactive->remove(wd);
-        Dmsg1(400, "Unregistered inactive watchdog %p\n", wd);
+         Dmsg1(800, "Unregistered inactive watchdog %p\n", wd);
         ok = true;
         goto get_out;
       }
    }
 
-   Dmsg1(400, "Failed to unregister watchdog %p\n", wd);
+   Dmsg1(800, "Failed to unregister watchdog %p\n", wd);
 
 get_out:
    wd_unlock();
@@ -231,7 +231,7 @@ extern "C" void *watchdog_thread(void *arg)
    struct timezone tz;
    time_t next_time;
 
-   Dmsg0(400, "NicB-reworked watchdog thread entered\n");
+   Dmsg0(800, "NicB-reworked watchdog thread entered\n");
 
    while (!quit) {
       watchdog_t *p;
@@ -256,7 +256,7 @@ walk_list:
            /* Run the callback */
            p->callback(p);
 
-           /* Reschedule (or move to inactive list if it's a one-shot timer) */
+            /* Reschedule (or move to inactive list if it's a one-shot timer) */
            if (p->one_shot) {
               wd_queue->remove(p);
               wd_inactive->append(p);
@@ -290,7 +290,7 @@ walk_list:
       V(timer_mutex);
    }
 
-   Dmsg0(400, "NicB-reworked watchdog thread exited\n");
+   Dmsg0(800, "NicB-reworked watchdog thread exited\n");
    return NULL;
 }
 
index 4611e6ce541de672eef30fa63ccafa2a589c5230..91f812bc5fd0176588c399dbbc7c07319e7929e2 100755 (executable)
@@ -149,7 +149,7 @@ int workq_add(workq_t *wq, void *element, workq_ele_t **work_item, int priority)
    workq_ele_t *item;
    pthread_t id;
 
-   Dmsg0(400, "workq_add\n");
+   Dmsg0(1400, "workq_add\n");
    if (wq->valid != WORKQ_VALID) {
       return EINVAL;
    }
@@ -164,7 +164,7 @@ int workq_add(workq_t *wq, void *element, workq_ele_t **work_item, int priority)
       return stat;
    }
 
-   Dmsg0(400, "add item to queue\n");
+   Dmsg0(1400, "add item to queue\n");
    if (priority) {
       /* Add to head of queue */
       if (wq->first == NULL) {
@@ -186,13 +186,13 @@ int workq_add(workq_t *wq, void *element, workq_ele_t **work_item, int priority)
 
    /* if any threads are idle, wake one */
    if (wq->idle_workers > 0) {
-      Dmsg0(400, "Signal worker\n");
+      Dmsg0(1400, "Signal worker\n");
       if ((stat = pthread_cond_signal(&wq->work)) != 0) {
         pthread_mutex_unlock(&wq->mutex);
         return stat;
       }
    } else if (wq->num_workers < wq->max_workers) {
-      Dmsg0(400, "Create worker thread\n");
+      Dmsg0(1400, "Create worker thread\n");
       /* No idle threads so create a new one */
       set_thread_concurrency(wq->max_workers + 1);
       if ((stat = pthread_create(&id, &wq->attr, workq_server, (void *)wq)) != 0) {
@@ -202,7 +202,7 @@ int workq_add(workq_t *wq, void *element, workq_ele_t **work_item, int priority)
       wq->num_workers++;
    }
    pthread_mutex_unlock(&wq->mutex);
-   Dmsg0(400, "Return workq_add\n");
+   Dmsg0(1400, "Return workq_add\n");
    /* Return work_item if requested */
    if (work_item) {
       *work_item = item;
@@ -225,7 +225,7 @@ int workq_remove(workq_t *wq, workq_ele_t *work_item)
    pthread_t id;
    workq_ele_t *item, *prev;
 
-   Dmsg0(400, "workq_remove\n");
+   Dmsg0(1400, "workq_remove\n");
    if (wq->valid != WORKQ_VALID) {
       return EINVAL;
    }
@@ -257,13 +257,13 @@ int workq_remove(workq_t *wq, workq_ele_t *work_item)
 
    /* if any threads are idle, wake one */
    if (wq->idle_workers > 0) {
-      Dmsg0(400, "Signal worker\n");
+      Dmsg0(1400, "Signal worker\n");
       if ((stat = pthread_cond_signal(&wq->work)) != 0) {
         pthread_mutex_unlock(&wq->mutex);
         return stat;
       }
    } else {
-      Dmsg0(400, "Create worker thread\n");
+      Dmsg0(1400, "Create worker thread\n");
       /* No idle threads so create a new one */
       set_thread_concurrency(wq->max_workers + 1);
       if ((stat = pthread_create(&id, &wq->attr, workq_server, (void *)wq)) != 0) {
@@ -273,7 +273,7 @@ int workq_remove(workq_t *wq, workq_ele_t *work_item)
       wq->num_workers++;
    }
    pthread_mutex_unlock(&wq->mutex);
-   Dmsg0(400, "Return workq_remove\n");
+   Dmsg0(1400, "Return workq_remove\n");
    return stat;
 }
 
@@ -290,7 +290,7 @@ void *workq_server(void *arg)
    workq_ele_t *we;
    int stat, timedout;
 
-   Dmsg0(400, "Start workq_server\n");
+   Dmsg0(1400, "Start workq_server\n");
    if ((stat = pthread_mutex_lock(&wq->mutex)) != 0) {
       return NULL;
    }
@@ -299,9 +299,9 @@ void *workq_server(void *arg)
       struct timeval tv;
       struct timezone tz;
 
-      Dmsg0(400, "Top of for loop\n");
+      Dmsg0(1400, "Top of for loop\n");
       timedout = 0;
-      Dmsg0(400, "gettimeofday()\n");
+      Dmsg0(1400, "gettimeofday()\n");
       gettimeofday(&tv, &tz);
       timeout.tv_nsec = 0;
       timeout.tv_sec = tv.tv_sec + 2;
@@ -310,7 +310,7 @@ void *workq_server(void *arg)
         /*
          * Wait 2 seconds, then if no more work, exit
          */
-        Dmsg0(400, "pthread_cond_timedwait()\n");
+         Dmsg0(1400, "pthread_cond_timedwait()\n");
 #ifdef xxxxxxxxxxxxxxxx_was_HAVE_CYGWIN
         /* CYGWIN dies with a page fault the second
          * time that pthread_cond_timedwait() is called
@@ -321,13 +321,13 @@ void *workq_server(void *arg)
 #else
         stat = pthread_cond_timedwait(&wq->work, &wq->mutex, &timeout);
 #endif
-        Dmsg1(400, "timedwait=%d\n", stat);
+         Dmsg1(1400, "timedwait=%d\n", stat);
         if (stat == ETIMEDOUT) {
            timedout = 1;
            break;
         } else if (stat != 0) {
-           /* This shouldn't happen */
-           Dmsg0(400, "This shouldn't happen\n");
+            /* This shouldn't happen */
+            Dmsg0(1400, "This shouldn't happen\n");
            wq->num_workers--;
            pthread_mutex_unlock(&wq->mutex);
            return NULL;
@@ -342,16 +342,16 @@ void *workq_server(void *arg)
         if ((stat = pthread_mutex_unlock(&wq->mutex)) != 0) {
            return NULL;
         }
-        /* Call user's routine here */
-        Dmsg0(400, "Calling user engine.\n");
+         /* Call user's routine here */
+         Dmsg0(1400, "Calling user engine.\n");
         wq->engine(we->data);
-        Dmsg0(400, "Back from user engine.\n");
+         Dmsg0(1400, "Back from user engine.\n");
         free(we);                    /* release work entry */
-        Dmsg0(400, "relock mutex\n");
+         Dmsg0(1400, "relock mutex\n");
         if ((stat = pthread_mutex_lock(&wq->mutex)) != 0) {
            return NULL;
         }
-        Dmsg0(400, "Done lock mutex\n");
+         Dmsg0(1400, "Done lock mutex\n");
       }
       /*
        * If no more work request, and we are asked to quit, then do it
@@ -359,31 +359,31 @@ void *workq_server(void *arg)
       if (wq->first == NULL && wq->quit) {
         wq->num_workers--;
         if (wq->num_workers == 0) {
-           Dmsg0(400, "Wake up destroy routine\n");
+            Dmsg0(1400, "Wake up destroy routine\n");
            /* Wake up destroy routine if he is waiting */
            pthread_cond_broadcast(&wq->work);
         }
-        Dmsg0(400, "Unlock mutex\n");
+         Dmsg0(1400, "Unlock mutex\n");
         pthread_mutex_unlock(&wq->mutex);
-        Dmsg0(400, "Return from workq_server\n");
+         Dmsg0(1400, "Return from workq_server\n");
         return NULL;
       }
-      Dmsg0(400, "Check for work request\n");
+      Dmsg0(1400, "Check for work request\n");
       /*
        * If no more work requests, and we waited long enough, quit
        */
-      Dmsg1(400, "wq->first==NULL = %d\n", wq->first==NULL);
-      Dmsg1(400, "timedout=%d\n", timedout);
+      Dmsg1(1400, "wq->first==NULL = %d\n", wq->first==NULL);
+      Dmsg1(1400, "timedout=%d\n", timedout);
       if (wq->first == NULL && timedout) {
-        Dmsg0(400, "break big loop\n");
+         Dmsg0(1400, "break big loop\n");
         wq->num_workers--;
         break;
       }
-      Dmsg0(400, "Loop again\n");
+      Dmsg0(1400, "Loop again\n");
    } /* end of big for loop */
 
-   Dmsg0(400, "unlock mutex\n");
+   Dmsg0(1400, "unlock mutex\n");
    pthread_mutex_unlock(&wq->mutex);
-   Dmsg0(400, "End workq_server\n");
+   Dmsg0(1400, "End workq_server\n");
    return NULL;
 }
index 67a40872d805d86eb2d5631f801d40e196efaf2c..94ddeb09769a34bcabc9c3c5607df268faaf229a 100644 (file)
 #include "bacula.h"                   /* pull in global headers */
 #include "stored.h"                   /* pull in Storage Deamon headers */
 
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-
+/*
+ * Create a new Device Control Record and attach
+ *   it to the device (if this is a real job).
+ */
 DCR *new_dcr(JCR *jcr, DEVICE *dev)
 {
    if (jcr && jcr->dcr) {
@@ -42,6 +44,9 @@ DCR *new_dcr(JCR *jcr, DEVICE *dev)
    }
    dcr->jcr = jcr;
    dcr->dev = dev;
+   if (dev) {
+      dcr->device = dev->device;
+   }
    dcr->block = new_block(dev);
    dcr->rec = new_record();
    dcr->spool_fd = -1;
@@ -58,6 +63,16 @@ void free_dcr(DCR *dcr)
    JCR *jcr = dcr->jcr;
    DEVICE *dev = dcr->dev;
 
+   /*
+    * If we reserved the device, we must decrement the
+    *  number of writers.
+    */
+   if (dcr->reserved_device) {
+      lock_device(dev);
+      dev->num_writers--;
+      unlock_device(dev);
+   }
+
    /* Detach this dcr only if the dev is initialized */
    if (dev->fd != 0 && jcr && jcr->JobType != JT_SYSTEM) {
       dcr->dev->attached_dcrs->remove(dcr);
@@ -74,16 +89,58 @@ void free_dcr(DCR *dcr)
    free(dcr);
 }
 
+/*
+ * We "reserve" the drive by setting the ST_READ bit. No one else
+ *  should touch the drive until that is cleared.
+ *  This allows the DIR to "reserve" the device before actually
+ *  starting the job. If the device is not available, the DIR
+ *  can wait (to be implemented 1/05).
+ */
+bool reserve_device_for_read(JCR *jcr, DEVICE *dev)
+{
+   DCR *dcr = jcr->dcr;
+   bool ok = false;
+
+   ASSERT(dcr);
+   if (device_is_unmounted(dev)) {
+      Jmsg(jcr, M_WARNING, 0, _("device %s is BLOCKED due to user unmount.\n"),
+        dev_name(dev));
+      return false;
+   }
+   lock_device(dev);
+   block_device(dev, BST_DOING_ACQUIRE);
+   unlock_device(dev);
+
+   if (dev->can_read() || dev->num_writers > 0) {
+      Jmsg2(jcr, M_FATAL, 0, _("Device %s is busy. Job %d canceled.\n"),
+           dev_name(dev), jcr->JobId);
+      goto get_out;
+   }
+   if (!dcr) {
+      dcr = new_dcr(jcr, dev);
+   }
+   dev->state &= ~ST_APPEND;         /* clear any previous append mode */
+   dev->state |= ST_READ;            /* set read mode */
+   ok = true;
+
+get_out:
+   P(dev->mutex);
+   unblock_device(dev);
+   V(dev->mutex);
+   return ok;
+}
+
 
 /*********************************************************************
- * Acquire device for reading. We permit (for the moment)
- *  only one reader.  We read the Volume label from the block and
+ * Acquire device for reading. 
+ *  The drive should have previously been reserved by calling 
+ *  reserve_device_for_read(). We read the Volume label from the block and
  *  leave the block pointers just after the label.
  *
  *  Returns: NULL if failed for any reason
  *          dcr  if successful
  */
-DCR *acquire_device_for_read(JCR *jcr)
+DCR *acquire_device_for_read(JCR *jcr, DEVICE *dev)
 {
    bool vol_ok = false;
    bool tape_previously_mounted;
@@ -92,32 +149,17 @@ DCR *acquire_device_for_read(JCR *jcr)
    bool try_autochanger = true;
    int i;
    DCR *dcr = jcr->dcr;
-   DEVICE *dev;
    int vol_label_status;
    
-   /* Called for each volume */
-   if (!dcr) {
-      dcr = new_dcr(jcr, jcr->device->dev);
-   }
-   dev = dcr->dev;
-   if (device_is_unmounted(dev)) {
-      Jmsg(jcr, M_WARNING, 0, _("device %s is BLOCKED due to user unmount.\n"),
-        dev_name(dev));
-   }
    lock_device(dev);
    block_device(dev, BST_DOING_ACQUIRE);
    unlock_device(dev);
 
    init_dev_wait_timers(dev);
-   if (dev_state(dev, ST_READ) || dev->num_writers > 0) {
-      Jmsg2(jcr, M_FATAL, 0, _("Device %s is busy. Job %d canceled.\n"),
-           dev_name(dev), jcr->JobId);
-      goto get_out;
-   }
 
-   tape_previously_mounted = dev_state(dev, ST_READ) ||
-                            dev_state(dev, ST_APPEND) ||
-                            dev_state(dev, ST_LABEL);
+   tape_previously_mounted = dev->can_read() ||
+                            dev->can_append() ||
+                            dev->is_labeled();
    tape_initially_mounted = tape_previously_mounted;
 
    /* Find next Volume, if any */
@@ -138,10 +180,10 @@ DCR *acquire_device_for_read(JCR *jcr)
       Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
    }
    
-   dcr->dev->num_parts = dcr->VolCatInfo.VolCatParts;
+   dev->num_parts = dcr->VolCatInfo.VolCatParts;
    
    for (i=0; i<5; i++) {
-      dcr->dev->state &= ~ST_LABEL;          /* force reread of label */
+      dev->state &= ~ST_LABEL;          /* force reread of label */
       if (job_canceled(jcr)) {
          Mmsg1(dev->errmsg, _("Job %d canceled.\n"), jcr->JobId);
         goto get_out;                /* error return */
@@ -151,17 +193,17 @@ DCR *acquire_device_for_read(JCR *jcr)
        * reading. If it is a file, it opens it.
        * If it is a tape, it checks the volume name
        */
-      for ( ; !(dev->state & ST_OPENED); ) {
+      for ( ; !dev->is_open(); ) {
          Dmsg1(120, "bstored: open vol=%s\n", dcr->VolumeName);
         if (open_dev(dev, dcr->VolumeName, OPEN_READ_ONLY) < 0) {
            if (dev->dev_errno == EIO) {   /* no tape loaded */
               goto default_path;
            }
            
-           /* If we have a device that requires mount, 
+           /* If we have a dvd that requires mount, 
             * we need to try to open the label, so the info can be reported
             * if a wrong volume has been mounted. */
-           if (dev_cap(dev, CAP_REQMOUNT) && (dcr->VolCatInfo.VolCatParts > 0)) {
+           if (dev->is_dvd() && (dcr->VolCatInfo.VolCatParts > 0)) {
               break;
            }
            
@@ -172,10 +214,9 @@ DCR *acquire_device_for_read(JCR *jcr)
          Dmsg1(129, "open_dev %s OK\n", dev_name(dev));
       }
       
-      if (dev_cap(dev, CAP_REQMOUNT)) {
+      if (dev->is_dvd()) {
         vol_label_status = read_dev_volume_label_guess(dcr, 0);
-      }
-      else {
+      } else {
         vol_label_status = read_dev_volume_label(dcr);
       }
       
@@ -262,36 +303,115 @@ get_out:
    return dcr;
 }
 
+/*
+ * We reserve the device for appending by incrementing the 
+ *  reserved_device. We do virtually all the same work that
+ *  is done in acquire_device_for_append(), but we do
+ *  not attempt to mount the device. This routine allows
+ *  the DIR to reserve multiple devices before *really* 
+ *  starting the job. It also permits the SD to refuse 
+ *  certain devices (not up, ...).
+ */
+bool reserve_device_for_append(JCR *jcr, DEVICE *dev)
+{
+   DCR *dcr = jcr->dcr;
+   bool recycle;
+   bool ok = false;
+
+   ASSERT(dcr);
+
+   lock_device(dev);
+   block_device(dev, BST_DOING_ACQUIRE);
+   unlock_device(dev);
+   if (device_is_unmounted(dev)) {
+      Jmsg(jcr, M_WARNING, 0, _("device %s is BLOCKED due to user unmount.\n"),
+        dev_name(dev));
+      goto get_out;
+   }
+   Dmsg1(190, "reserve_append device is %s\n", dev_is_tape(dev)?"tape":"disk");
+   if (dev->can_append()) {
+      Dmsg0(190, "device already in append.\n");
+      /*
+       * Device already in append mode
+       *
+       * Check if we have the right Volume mounted
+       *   OK if current volume info OK
+       *   OK if next volume matches current volume
+       */
+      bstrncpy(dcr->VolumeName, dev->VolHdr.VolName, sizeof(dcr->VolumeName));
+      if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
+         !(dir_find_next_appendable_volume(dcr) &&
+           strcmp(dev->VolHdr.VolName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
+         Dmsg0(190, "Wrong tape mounted.\n");
+        if (dev->num_writers != 0 || dev->reserved_device) {
+            Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing on another Volume.\n"), dev_name(dev));
+           goto get_out;
+        }
+      } else {
+        /*
+         * At this point, the correct tape is already mounted, so
+         *   we do not need to do mount_next_write_volume(), unless
+         *   we need to recycle the tape.
+         */
+          recycle = strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0;
+          Dmsg1(190, "Correct tape mounted. recycle=%d\n", recycle);
+         if (recycle && dev->num_writers != 0) {
+             Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\""
+                  " because it is in use by another job.\n"));
+            goto get_out;
+         }
+         if (dev->num_writers == 0) {
+            memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
+         }
+       }
+   } else {
+      if (dev->can_read()) {
+         Jmsg(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev_name(dev));
+        goto get_out;
+      }
+      ASSERT(dev->num_writers == 0);
+   }
+
+   dev->reserved_device++;
+   dcr->reserved_device = true;
+   ok = true;
+
+get_out:
+   P(dev->mutex);
+   unblock_device(dev);
+   V(dev->mutex);
+   return ok;
+}
+
 /*
  * Acquire device for writing. We permit multiple writers.
  *  If this is the first one, we read the label.
  *
  *  Returns: NULL if failed for any reason
- *          dev if successful (may change if new dev opened)
- *  This routine must be single threaded because we may create
- *   multiple devices (for files), thus we have our own mutex
- *   on top of the device mutex.
+ *          dcr if successful.
+ *   Note, normally reserve_device_for_append() is called
+ *   before this routine.
  */
-DCR *acquire_device_for_append(JCR *jcr)
+DCR *acquire_device_for_append(JCR *jcr, DEVICE *dev)
 {
    bool release = false;
    bool recycle = false;
    bool do_mount = false;
-   DCR *dcr;
-   DEVICE *dev = jcr->device->dev;
+   DCR *dcr = jcr->dcr;
 
-   dcr = new_dcr(jcr, dev);
-   if (device_is_unmounted(dev)) {
-      Jmsg(jcr, M_WARNING, 0, _("device %s is BLOCKED due to user unmount.\n"),
-        dev_name(dev));
+   if (!dcr) {
+      dcr = new_dcr(jcr, dev);
    }
    lock_device(dev);
    block_device(dev, BST_DOING_ACQUIRE);
    unlock_device(dev);
-   P(mutex);                        /* lock all devices */
    Dmsg1(190, "acquire_append device is %s\n", dev_is_tape(dev)?"tape":"disk");
 
-   if (dev_state(dev, ST_APPEND)) {
+   if (dcr->reserved_device) {
+      dev->reserved_device--;
+      dcr->reserved_device = false;
+   }
+   if (dev->can_append()) {
       Dmsg0(190, "device already in append.\n");
       /*
        * Device already in append mode
@@ -307,32 +427,9 @@ DCR *acquire_device_for_append(JCR *jcr)
          !(dir_find_next_appendable_volume(dcr) &&
            strcmp(dev->VolHdr.VolName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
          Dmsg0(190, "Wrong tape mounted.\n");
-        if (dev->num_writers != 0) {
-           DEVICE *d = ((DEVRES *)dev->device)->dev;
-           uint32_t open_vols = 0;
-           for ( ; d; d=d->next) {
-              open_vols++;
-           }
-           if (dev_state(dev, ST_FILE) && dev->max_open_vols > open_vols) {
-              d = init_dev(NULL, (DEVRES *)dev->device); /* init new device */
-              d->prev = dev;                   /* chain in new device */
-              d->next = dev->next;
-              dev->next = d;
-              /* Release old device */
-              P(dev->mutex);
-              unblock_device(dev);
-              V(dev->mutex);
-              free_dcr(dcr);         /* release dcr pointing to old dev */
-              /* Make new device current device and lock it */
-              dev = d;
-              dcr = new_dcr(jcr, dev); /* get new dcr for new device */
-              lock_device(dev);
-              block_device(dev, BST_DOING_ACQUIRE);
-              unlock_device(dev);
-           } else {
-               Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing on another Volume.\n"), dev_name(dev));
-              goto get_out;
-           }
+        if (dev->num_writers != 0 || dev->reserved_device) {
+            Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing on another Volume.\n"), dev_name(dev));
+           goto get_out;
         }
         /* Wrong tape mounted, release it, then fall through to get correct one */
          Dmsg0(190, "Wrong tape mounted, release and try mount.\n");
@@ -358,7 +455,7 @@ DCR *acquire_device_for_append(JCR *jcr)
    } else {
       /* Not already in append mode, so mount the device */
       Dmsg0(190, "Not in append mode, try mount.\n");
-      if (dev_state(dev, ST_READ)) {
+      if (dev->can_read()) {
          Jmsg(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev_name(dev));
         goto get_out;
       }
@@ -368,9 +465,7 @@ DCR *acquire_device_for_append(JCR *jcr)
 
    if (do_mount || recycle) {
       Dmsg0(190, "Do mount_next_write_vol\n");
-      V(mutex);                       /* don't lock everything during mount */
       bool mounted = mount_next_write_volume(dcr, release);
-      P(mutex);                      /* re-lock */
       if (!mounted) {
         if (!job_canceled(jcr)) {
             /* Reduce "noise" -- don't print if job canceled */
@@ -385,8 +480,6 @@ DCR *acquire_device_for_append(JCR *jcr)
    if (jcr->NumVolumes == 0) {
       jcr->NumVolumes = 1;
    }
-   set_jcr_job_status(jcr, JS_Running);
-   dir_send_job_status(jcr);
    goto ok_out;
 
 /*
@@ -400,7 +493,6 @@ ok_out:
    P(dev->mutex);
    unblock_device(dev);
    V(dev->mutex);
-   V(mutex);                         /* unlock other threads */
    return dcr;
 }
 
@@ -426,7 +518,7 @@ bool release_device(JCR *jcr)
    } else if (dev->num_writers > 0) {
       dev->num_writers--;
       Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers);
-      if (dev_state(dev, ST_LABEL)) {
+      if (dev->is_labeled()) {
          Dmsg0(100, "dir_create_jobmedia_record. Release\n");
         if (!dir_create_jobmedia_record(dcr)) {
             Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
@@ -443,7 +535,7 @@ bool release_device(JCR *jcr)
         dir_update_volume_info(dcr, false); /* send Volume info to Director */
       }
 
-      if (!dev->num_writers && (!dev_is_tape(dev) || !dev_cap(dev, CAP_ALWAYSOPEN))) {
+      if (!dev->num_writers && (!dev->is_tape() || !dev_cap(dev, CAP_ALWAYSOPEN))) {
         offline_or_rewind_dev(dev);
         close_dev(dev);
       }
@@ -454,13 +546,13 @@ bool release_device(JCR *jcr)
    }
 
    /* Fire off Alert command and include any output */
-   if (!job_canceled(jcr) && jcr->device->alert_command) {
+   if (!job_canceled(jcr) && dcr->device->alert_command) {
       POOLMEM *alert;
       int status = 1;
       BPIPE *bpipe;
       char line[MAXSTRING];
       alert = get_pool_memory(PM_FNAME);
-      alert = edit_device_codes(jcr, alert, jcr->device->alert_command, "");
+      alert = edit_device_codes(dcr, alert, "");
       bpipe = open_bpipe(alert, 0, "r");
       if (bpipe) {
         while (fgets(line, sizeof(line), bpipe->rfd)) {
@@ -479,15 +571,7 @@ bool release_device(JCR *jcr)
       Dmsg1(400, "alert status=%d\n", status);
       free_pool_memory(alert);
    }
-   if (dev->prev && !dev_state(dev, ST_READ) && !dev->num_writers) {
-      P(mutex);
-      unlock_device(dev);
-      dev->prev->next = dev->next;    /* dechain */
-      term_dev(dev);
-      V(mutex);
-   } else {
-      unlock_device(dev);
-   }
+   unlock_device(dev);
    free_dcr(jcr->dcr);
    jcr->dcr = NULL;
    return true;
index c188c4d409329b6e0e473de7a1e83b18a1763504..59f8502d315e4607877189d186fd8528126fc405 100644 (file)
@@ -44,33 +44,31 @@ bool do_append_data(JCR *jcr)
    BSOCK *ds;
    BSOCK *fd_sock = jcr->file_bsock;
    bool ok = true;
-   DEVICE *dev;
    DEV_RECORD rec;
-   DCR *dcr;
+   DCR *dcr = jcr->dcr;
+   DEVICE *dev = dcr->dev;
+
 
    Dmsg0(10, "Start append data.\n");
 
    ds = fd_sock;
 
-   if (!bnet_set_buffer_size(ds, jcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) {
+   if (!bnet_set_buffer_size(ds, dcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) {
       set_jcr_job_status(jcr, JS_ErrorTerminated);
       Jmsg(jcr, M_FATAL, 0, _("Unable to set network buffer size.\n"));
       return false;
    }
 
-   /*
-    * Acquire output device for writing.  Note, after acquiring a
-    *  device, we MUST release it, which is done at the end of this
-    *  subroutine.
-    */
-   Dmsg0(100, "just before acquire_device\n");
-   if (!(dcr=acquire_device_for_append(jcr))) {
+   if (!acquire_device_for_append(jcr, dev)) {
       set_jcr_job_status(jcr, JS_ErrorTerminated);
       return false;
    }
-   dev = dcr->dev;
+
    memset(&rec, 0, sizeof(rec));
 
+   set_jcr_job_status(jcr, JS_Running);
+   dir_send_job_status(jcr);
+
    if (dev->VolCatInfo.VolCatName[0] == 0) {
       Dmsg0(000, "NULL Volume name. This shouldn't happen!!!\n");
    }
@@ -283,27 +281,27 @@ bool do_append_data(JCR *jcr)
       commit_data_spool(jcr);
    }
    
-   /* If the device is nor a tape, nor a fifo, and WritePartAfterJob
+   /* If the device is nor a dvd and WritePartAfterJob
     * is set to yes, open the next part, so, in case of a device
     * that requires mount, it will be written to the device.
     */
-   if (!(dcr->dev->state & (ST_TAPE|ST_FIFO)) && (jcr->write_part_after_job) && (dcr->dev->part_size > 0)) {
+   if (dev->is_dvd() && jcr->write_part_after_job && (dev->part_size > 0)) {
       Dmsg0(100, "Writing last part because write_part_after_job is set.\n");
-      if (dcr->dev->part < dcr->dev->num_parts) {
-         Jmsg3(dcr->jcr, M_FATAL, 0, _("Error while writing, current part number is less than the total number of parts (%d/%d, device=%s)\n"),
+      if (dev->part < dev->num_parts) {
+         Jmsg3(jcr, M_FATAL, 0, _("Error while writing, current part number is less than the total number of parts (%d/%d, device=%s)\n"),
               dev->part, dev->num_parts, dev_name(dev));
-        dcr->dev->dev_errno = EIO;
+        dev->dev_errno = EIO;
         ok = false;
       }
       
-      if (ok && (open_next_part(dcr->dev) < 0)) {
+      if (ok && (open_next_part(dev) < 0)) {
          Jmsg2(jcr, M_FATAL, 0, _("Unable to open device next part %s. ERR=%s\n"),
-              dev_name(dcr->dev), strerror_dev(dcr->dev));
-        dcr->dev->dev_errno = EIO;
+              dev_name(dev), strerror_dev(dev));
+        dev->dev_errno = EIO;
         ok = false;
       }
       
-      dcr->dev->VolCatInfo.VolCatParts = dcr->dev->num_parts;
+      dev->VolCatInfo.VolCatParts = dev->num_parts;
    }
 
    Dmsg1(200, "calling release device JobStatus=%d\n", jcr->JobStatus);
index 645993c72c3ecb2ec81583f46ddc36e681fda08a..7706e0458acaccb93f21b6bd6526b34a637e386f 100644 (file)
@@ -41,7 +41,7 @@ static char Create_job_media[] = "CatReq Job=%s CreateJobMedia"
    " FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u"
    " StartBlock=%u EndBlock=%u\n";
 static char FileAttributes[] = "UpdCat Job=%s FileAttributes ";
-static char Job_status[]     = "3012 Job %s jobstatus %d\n";
+static char Job_status[]     = "Status Job=%s JobStatus=%d\n";
 
 
 /* Responses received from the Director */
@@ -49,7 +49,8 @@ static char OK_media[] = "1000 OK VolName=%127s VolJobs=%u VolFiles=%u"
    " VolBlocks=%u VolBytes=%" lld " VolMounts=%u VolErrors=%u VolWrites=%u"
    " MaxVolBytes=%" lld " VolCapacityBytes=%" lld " VolStatus=%20s"
    " Slot=%d MaxVolJobs=%u MaxVolFiles=%u InChanger=%d"
-   " VolReadTime=%" lld " VolWriteTime=%" lld " EndFile=%u EndBlock=%u VolParts=%u";
+   " VolReadTime=%" lld " VolWriteTime=%" lld " EndFile=%u EndBlock=%u"
+   " VolParts=%u LabelType=%d";
 
 
 static char OK_create[] = "1000 OK CreateJobMedia\n";
@@ -98,8 +99,9 @@ static bool do_get_volume_info(DCR *dcr)
               &vol.VolCatCapacityBytes, vol.VolCatStatus,
               &vol.Slot, &vol.VolCatMaxJobs, &vol.VolCatMaxFiles,
               &InChanger, &vol.VolReadTime, &vol.VolWriteTime,
-              &vol.EndFile, &vol.EndBlock, &vol.VolCatParts);
-    if (n != 20) {
+              &vol.EndFile, &vol.EndBlock, &vol.VolCatParts,
+              &vol.LabelType);
+    if (n != 21) {
        Dmsg2(100, "Bad response from Dir fields=%d: %s\n", n, dir->msg);
        Mmsg(jcr->errmsg, _("Error getting Volume info: %s\n"), dir->msg);
        return false;
@@ -215,13 +217,14 @@ bool dir_update_volume_info(DCR *dcr, bool label)
    char ed1[50], ed2[50], ed3[50], ed4[50];
    VOLUME_CAT_INFO *vol = &dev->VolCatInfo;
    int InChanger;
+   POOL_MEM VolumeName;
 
    if (vol->VolCatName[0] == 0) {
       Jmsg0(jcr, M_FATAL, 0, _("NULL Volume name. This shouldn't happen!!!\n"));
       Dmsg0(000, "NULL Volume name. This shouldn't happen!!!\n");
       return false;
    }
-   if (dev_state(dev, ST_READ)) {
+   if (dev->can_read()) {
       Jmsg0(jcr, M_FATAL, 0, _("Attempt to update_volume_info in read mode!!!\n"));
       Dmsg0(000, "Attempt to update_volume_info in read mode!!!\n");
       return false;
@@ -233,10 +236,11 @@ bool dir_update_volume_info(DCR *dcr, bool label)
       bstrncpy(vol->VolCatStatus, "Append", sizeof(vol->VolCatStatus));
       vol->VolCatBytes = 1;          /* indicates tape labeled */
    }
-   bash_spaces(vol->VolCatName);
+   pm_strcpy(VolumeName, vol->VolCatName);
+   bash_spaces(VolumeName);
    InChanger = vol->InChanger;
    bnet_fsend(dir, Update_media, jcr->Job,
-      vol->VolCatName, vol->VolCatJobs, vol->VolCatFiles,
+      VolumeName.c_str(), vol->VolCatJobs, vol->VolCatFiles,
       vol->VolCatBlocks, edit_uint64(vol->VolCatBytes, ed1),
       vol->VolCatMounts, vol->VolCatErrors,
       vol->VolCatWrites, edit_uint64(vol->VolCatMaxBytes, ed2),
@@ -244,14 +248,14 @@ bool dir_update_volume_info(DCR *dcr, bool label)
       InChanger,                     /* bool in structure */
       edit_uint64(vol->VolReadTime, ed3),
       edit_uint64(vol->VolWriteTime, ed4),
-      vol->VolCatParts );
+      vol->VolCatParts);
 
    Dmsg1(300, "update_volume_info(): %s", dir->msg);
-   unbash_spaces(vol->VolCatName);
 
    if (!do_get_volume_info(dcr)) {
       Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
-      Dmsg1(000, "Didn't get vol info: %s", jcr->errmsg);
+      Dmsg2(000, "Didn't get vol info vol=%s: ERR=%s", 
+        vol->VolCatName, jcr->errmsg);
       return false;
    }
    Dmsg1(420, "get_volume_info(): %s", dir->msg);
index 9eee899b6c566b7ae706f38c8218c5a078b7b2af..b9d4779e9d1f04c7de149396ab16c4c58d0abaed 100644 (file)
@@ -30,8 +30,8 @@
 #include "stored.h"                   /* pull in Storage Deamon headers */
 
 /* Forward referenced functions */
-char *edit_device_codes(JCR *jcr, char *omsg, const char *imsg, const char *cmd);
-static int get_autochanger_loaded_slot(JCR *jcr);
+char *edit_device_codes(DCR *dcr, char *omsg, const char *cmd);
+static int get_autochanger_loaded_slot(DCR *dcr);
 
 
 /*
@@ -53,7 +53,7 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir)
    JCR *jcr = dcr->jcr;
    DEVICE *dev = dcr->dev;
    int slot;
-   int drive = jcr->device->drive_index;
+   int drive = dev->device->drive_index;
    int rtn_stat = -1;                /* error status */
 
    slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0;
@@ -73,14 +73,14 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir)
    }
    Dmsg1(400, "Want changer slot=%d\n", slot);
 
-   if (slot > 0 && jcr->device->changer_name && jcr->device->changer_command) {
-      uint32_t timeout = jcr->device->max_changer_wait;
+   if (slot > 0 && dcr->device->changer_name && dcr->device->changer_command) {
+      uint32_t timeout = dcr->device->max_changer_wait;
       POOLMEM *changer;
       int loaded, status;
 
       changer = get_pool_memory(PM_FNAME);
 
-      loaded = get_autochanger_loaded_slot(jcr);
+      loaded = get_autochanger_loaded_slot(dcr);
 
       /* If tape we want is not loaded, load it. */
       if (loaded != slot) {
@@ -88,44 +88,42 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir)
         /* We are going to load a new tape, so close the device */
         force_close_dev(dev);
         if (loaded != 0 && loaded != -1) {        /* must unload drive */
-           Dmsg0(400, "Doing changer unload.\n");
+            Dmsg0(400, "Doing changer unload.\n");
            Jmsg(jcr, M_INFO, 0,
-                _("3303 Issuing autochanger \"unload slot %d, drive %d\" command.\n"),
+                 _("3303 Issuing autochanger \"unload slot %d, drive %d\" command.\n"),
                 loaded, drive);
            dcr->VolCatInfo.Slot = loaded;   /* slot to be unloaded */
-           changer = edit_device_codes(jcr, changer,
-                       jcr->device->changer_command, "unload");
+            changer = edit_device_codes(dcr, changer, "unload");
            status = run_program(changer, timeout, NULL);
            if (status != 0) {
               berrno be;
               be.set_errno(status);
-              Jmsg(jcr, M_INFO, 0, _("3992 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"),
+               Jmsg(jcr, M_INFO, 0, _("3992 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"),
                    slot, drive, be.strerror());
            }
 
-           Dmsg1(400, "unload status=%d\n", status);
+            Dmsg1(400, "unload status=%d\n", status);
         }
         /*
          * Load the desired cassette
          */
-        Dmsg1(400, "Doing changer load slot %d\n", slot);
+         Dmsg1(400, "Doing changer load slot %d\n", slot);
         Jmsg(jcr, M_INFO, 0,
-             _("3304 Issuing autochanger \"load slot %d, drive %d\" command.\n"),
+              _("3304 Issuing autochanger \"load slot %d, drive %d\" command.\n"),
              slot, drive);
         dcr->VolCatInfo.Slot = slot;    /* slot to be loaded */
-        changer = edit_device_codes(jcr, changer,
-                     jcr->device->changer_command, "load");
+         changer = edit_device_codes(dcr, changer, "load");
         status = run_program(changer, timeout, NULL);
         if (status == 0) {
-           Jmsg(jcr, M_INFO, 0, _("3305 Autochanger \"load slot %d, drive %d\", status is OK.\n"),
+            Jmsg(jcr, M_INFO, 0, _("3305 Autochanger \"load slot %d, drive %d\", status is OK.\n"),
                    slot, drive);
         } else {
           berrno be;
           be.set_errno(status);
-           Jmsg(jcr, M_INFO, 0, _("3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n"),
+            Jmsg(jcr, M_INFO, 0, _("3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n"),
                    slot, drive, be.strerror());
         }
-        Dmsg2(400, "load slot %d status=%d\n", slot, status);
+         Dmsg2(400, "load slot %d status=%d\n", slot, status);
       } else {
         status = 0;                  /* we got what we want */
       }
@@ -140,12 +138,13 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir)
    return rtn_stat;
 }
 
-static int get_autochanger_loaded_slot(JCR *jcr)
+static int get_autochanger_loaded_slot(DCR *dcr)
 {
+   JCR *jcr = dcr->jcr;
    POOLMEM *changer, *results;
    int status, loaded;
-   uint32_t timeout = jcr->device->max_changer_wait;
-   int drive = jcr->device->drive_index;
+   uint32_t timeout = dcr->device->max_changer_wait;
+   int drive = dcr->device->drive_index;
 
    results = get_pool_memory(PM_MESSAGE);
    changer = get_pool_memory(PM_FNAME);
@@ -153,8 +152,7 @@ static int get_autochanger_loaded_slot(JCR *jcr)
    /* Find out what is loaded, zero means device is unloaded */
    Jmsg(jcr, M_INFO, 0, _("3301 Issuing autochanger \"loaded drive %d\" command.\n"),
        drive);
-   changer = edit_device_codes(jcr, changer, jcr->device->changer_command,
-                "loaded");
+   changer = edit_device_codes(dcr, changer, "loaded");
    status = run_program(changer, timeout, results);
    Dmsg3(50, "run_prog: %s stat=%d result=%s\n", changer, status, results);
    if (status == 0) {
@@ -204,14 +202,14 @@ bool autochanger_list(DCR *dcr, BSOCK *dir)
 {
    DEVICE *dev = dcr->dev;
    JCR *jcr = dcr->jcr;
-   uint32_t timeout = jcr->device->max_changer_wait;
+   uint32_t timeout = dcr->device->max_changer_wait;
    POOLMEM *changer;
    BPIPE *bpipe;
    int slot, loaded;
    int len = sizeof_pool_memory(dir->msg) - 1;
 
-   if (!dev_cap(dev, CAP_AUTOCHANGER) || !jcr->device->changer_name ||
-       !jcr->device->changer_command) {
+   if (!dev_cap(dev, CAP_AUTOCHANGER) || !dcr->device->changer_name ||
+       !dcr->device->changer_command) {
       bnet_fsend(dir, _("3993 Not a autochanger device.\n"));
       return false;
    }
@@ -222,24 +220,24 @@ bool autochanger_list(DCR *dcr, BSOCK *dir)
    force_close_dev(dev);
 
    /* First unload any tape */
-   loaded = get_autochanger_loaded_slot(jcr);
+   loaded = get_autochanger_loaded_slot(dcr);
    if (loaded > 0) {
       bnet_fsend(dir, _("3305 Issuing autochanger \"unload slot %d\" command.\n"), loaded);
       slot = dcr->VolCatInfo.Slot;
       dcr->VolCatInfo.Slot = loaded;
-      changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "unload");
+      changer = edit_device_codes(dcr, changer, "unload");
       int stat = run_program(changer, timeout, NULL);
       if (stat != 0) {
         berrno be;
         be.set_errno(stat);
-        Jmsg(jcr, M_INFO, 0, _("3995 Bad autochanger \"unload slot %d\" command: ERR=%s.\n"),
+         Jmsg(jcr, M_INFO, 0, _("3995 Bad autochanger \"unload slot %d\" command: ERR=%s.\n"),
              loaded, be.strerror());
       }
       dcr->VolCatInfo.Slot = slot;
    }
 
    /* Now list slots occupied */
-   changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "list");
+   changer = edit_device_codes(dcr, changer, "list");
    bnet_fsend(dir, _("3306 Issuing autochanger \"list\" command.\n"));
    bpipe = open_bpipe(changer, timeout, "r");
    if (!bpipe) {
@@ -284,53 +282,54 @@ bool autochanger_list(DCR *dcr, BSOCK *dir)
  *  cmd = command string (load, unload, ...)
  *
  */
-char *edit_device_codes(JCR *jcr, char *omsg, const char *imsg, const char *cmd)
+char *edit_device_codes(DCR *dcr, char *omsg, const char *cmd)
 {
    const char *p;
    const char *str;
    char add[20];
+   const char *imsg = dcr->device->changer_command;
 
    *omsg = 0;
    Dmsg1(800, "edit_device_codes: %s\n", imsg);
    for (p=imsg; *p; p++) {
       if (*p == '%') {
         switch (*++p) {
-        case '%':
-           str = "%";
+         case '%':
+            str = "%";
            break;
-        case 'a':
-           str = dev_name(jcr->device->dev);
+         case 'a':
+           str = dev_name(dcr->dev);
            break;
-        case 'c':
-           str = NPRT(jcr->device->changer_name);
+         case 'c':
+           str = NPRT(dcr->device->changer_name);
            break;
-        case 'd':
-           sprintf(add, "%d", jcr->device->dev->drive_index);
+         case 'd':
+            sprintf(add, "%d", dcr->dev->drive_index);
            str = add;
            break;
-        case 'o':
+         case 'o':
            str = NPRT(cmd);
            break;
-        case 's':
-           sprintf(add, "%d", jcr->dcr->VolCatInfo.Slot - 1);
+         case 's':
+            sprintf(add, "%d", dcr->VolCatInfo.Slot - 1);
            str = add;
            break;
-        case 'S':
-           sprintf(add, "%d", jcr->dcr->VolCatInfo.Slot);
+         case 'S':
+            sprintf(add, "%d", dcr->VolCatInfo.Slot);
            str = add;
            break;
-        case 'j':                    /* Job name */
-           str = jcr->Job;
+         case 'j':                    /* Job name */
+           str = dcr->jcr->Job;
            break;
-        case 'v':
-           str = NPRT(jcr->dcr->VolumeName);
+         case 'v':
+           str = NPRT(dcr->VolumeName);
            break;
-        case 'f':
-           str = NPRT(jcr->client_name);
+         case 'f':
+           str = NPRT(dcr->jcr->client_name);
            break;
 
         default:
-           add[0] = '%';
+            add[0] = '%';
            add[1] = *p;
            add[2] = 0;
            str = add;
index 9b51f9f3690ff9db4132a69fbf0e489381c425e9..54f0d82da89a2258fecbccbacb3394576d6ff3eb 100644 (file)
@@ -169,7 +169,7 @@ int main (int argc, char *argv[])
       exit(1);
    }
    unlock_device(out_dev);
-   if (!acquire_device_for_append(out_jcr)) {
+   if (!acquire_device_for_append(out_jcr, out_dev)) {
       free_jcr(in_jcr);
       exit(1);
    }
@@ -212,37 +212,37 @@ static bool record_cb(DCR *in_dcr, DEV_RECORD *rec)
       }
       switch (rec->FileIndex) {
       case PRE_LABEL:
-        Pmsg0(000, "Volume is prelabeled. This volume cannot be copied.\n");
+         Pmsg0(000, "Volume is prelabeled. This volume cannot be copied.\n");
         return false;
       case VOL_LABEL:
-        Pmsg0(000, "Volume label not copied.\n");
+         Pmsg0(000, "Volume label not copied.\n");
         return true;
       case SOS_LABEL:
         jobs++;
         break;
       case EOS_LABEL:
         while (!write_record_to_block(out_block, rec)) {
-           Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len,
+            Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len,
                       rec->remainder);
            if (!write_block_to_device(out_jcr->dcr)) {
-              Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
+               Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
                  dev_name(out_dev), strerror_dev(out_dev));
-              Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
+               Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
                     strerror_dev(out_dev));
            }
         }
         if (!write_block_to_device(out_jcr->dcr)) {
-           Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
+            Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
               dev_name(out_dev), strerror_dev(out_dev));
-           Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
+            Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
                  strerror_dev(out_dev));
         }
         break;
       case EOM_LABEL:
-        Pmsg0(000, "EOM label not copied.\n");
+         Pmsg0(000, "EOM label not copied.\n");
         return true;
       case EOT_LABEL:             /* end of all tapes */
-        Pmsg0(000, "EOT label not copied.\n");
+         Pmsg0(000, "EOT label not copied.\n");
         return true;
       default:
         break;
@@ -255,9 +255,9 @@ static bool record_cb(DCR *in_dcr, DEV_RECORD *rec)
       Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len,
                 rec->remainder);
       if (!write_block_to_device(out_jcr->dcr)) {
-        Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
+         Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
            dev_name(out_dev), strerror_dev(out_dev));
-        Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
+         Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
               strerror_dev(out_dev));
         break;
       }
index 8747e02e9131064e78688bea7e53ad18fb8a0c96..420ce09c616bd28ec2bcff006c98e9f2270ca61e 100644 (file)
@@ -8,7 +8,7 @@
  *
  */
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -70,7 +70,7 @@ bool forge_on = false;
 static void usage()
 {
    fprintf(stderr,
-"Copyright (C) 2000-2004 Kern Sibbald and John Walker.\n"
+"Copyright (C) 2000-2005 Kern Sibbald.\n"
 "\nVersion: " VERSION " (" BDATE ")\n\n"
 "Usage: bextract <options> <bacula-archive-device-name> <directory-to-store-files>\n"
 "       -b <file>       specify a bootstrap file\n"
@@ -122,30 +122,30 @@ int main (int argc, char *argv[])
         break;
 
       case 'e':                    /* exclude list */
-        if ((fd = fopen(optarg, "r")) == NULL) {
+         if ((fd = fopen(optarg, "r")) == NULL) {
            berrno be;
-           Pmsg2(0, "Could not open exclude file: %s, ERR=%s\n",
+            Pmsg2(0, "Could not open exclude file: %s, ERR=%s\n",
               optarg, be.strerror());
            exit(1);
         }
         while (fgets(line, sizeof(line), fd) != NULL) {
            strip_trailing_junk(line);
-           Dmsg1(900, "add_exclude %s\n", line);
+            Dmsg1(900, "add_exclude %s\n", line);
            add_fname_to_exclude_list(ff, line);
         }
         fclose(fd);
         break;
 
       case 'i':                    /* include list */
-        if ((fd = fopen(optarg, "r")) == NULL) {
+         if ((fd = fopen(optarg, "r")) == NULL) {
            berrno be;
-           Pmsg2(0, "Could not open include file: %s, ERR=%s\n",
+            Pmsg2(0, "Could not open include file: %s, ERR=%s\n",
               optarg, be.strerror());
            exit(1);
         }
         while (fgets(line, sizeof(line), fd) != NULL) {
            strip_trailing_junk(line);
-           Dmsg1(900, "add_include %s\n", line);
+            Dmsg1(900, "add_include %s\n", line);
            add_fname_to_include_list(ff, 0, line);
         }
         fclose(fd);
@@ -273,18 +273,18 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
        */
       if (extract) {
         if (!is_bopen(&bfd)) {
-           Emsg0(M_ERROR, 0, _("Logic error output file should be open but is not.\n"));
+            Emsg0(M_ERROR, 0, _("Logic error output file should be open but is not.\n"));
         }
         set_attributes(jcr, attr, &bfd);
         extract = false;
       }
 
       if (!unpack_attributes_record(jcr, rec->Stream, rec->data, attr)) {
-        Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n"));
+         Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n"));
       }
 
       if (attr->file_index != rec->FileIndex) {
-        Emsg2(M_ERROR_TERM, 0, _("Record header file index %ld not equal record index %ld\n"),
+         Emsg2(M_ERROR_TERM, 0, _("Record header file index %ld not equal record index %ld\n"),
            rec->FileIndex, attr->file_index);
       }
 
@@ -293,7 +293,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
         attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
         if (!is_stream_supported(attr->data_stream)) {
            if (!non_support_data++) {
-              Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
+               Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
                  stream_to_ascii(attr->data_stream));
            }
            extract = false;
@@ -342,7 +342,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
               fileAddr = faddr;
               if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
                  berrno be;
-                 Emsg2(M_ERROR_TERM, 0, _("Seek error on %s: %s\n"),
+                  Emsg2(M_ERROR_TERM, 0, _("Seek error on %s: %s\n"),
                     attr->ofname, be.strerror());
               }
            }
@@ -351,10 +351,10 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
            wsize = rec->data_len;
         }
         total += wsize;
-        Dmsg2(8, "Write %u bytes, total=%u\n", wsize, total);
+         Dmsg2(8, "Write %u bytes, total=%u\n", wsize, total);
         if ((uint32_t)bwrite(&bfd, wbuf, wsize) != wsize) {
            berrno be;
-           Emsg2(M_ERROR_TERM, 0, _("Write error on %s: %s\n"),
+            Emsg2(M_ERROR_TERM, 0, _("Write error on %s: %s\n"),
               attr->ofname, be.strerror());
         }
         fileAddr += wsize;
@@ -382,7 +382,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
               fileAddr = faddr;
               if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
                  berrno be;
-                 Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
+                  Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
                     edit_uint64(fileAddr, ec1), attr->ofname, be.strerror());
                  extract = false;
                  return true;
@@ -395,28 +395,28 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
         compress_len = compress_buf_size;
         if ((stat=uncompress((Bytef *)compress_buf, &compress_len,
               (const Bytef *)wbuf, (uLong)wsize) != Z_OK)) {
-           Emsg1(M_ERROR, 0, _("Uncompression error. ERR=%d\n"), stat);
+            Emsg1(M_ERROR, 0, _("Uncompression error. ERR=%d\n"), stat);
            extract = false;
            return true;
         }
 
-        Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total);
+         Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total);
         if ((uLongf)bwrite(&bfd, compress_buf, (size_t)compress_len) != compress_len) {
            berrno be;
-           Pmsg0(0, "===Write error===\n");
-           Emsg2(M_ERROR, 0, _("Write error on %s: %s\n"),
+            Pmsg0(0, "===Write error===\n");
+            Emsg2(M_ERROR, 0, _("Write error on %s: %s\n"),
               attr->ofname, be.strerror());
            extract = false;
            return true;
         }
         total += compress_len;
         fileAddr += compress_len;
-        Dmsg2(100, "Compress len=%d uncompressed=%d\n", rec->data_len,
+         Dmsg2(100, "Compress len=%d uncompressed=%d\n", rec->data_len,
            compress_len);
       }
 #else
       if (extract) {
-        Emsg0(M_ERROR, 0, "GZIP data stream found, but GZIP not configured!\n");
+         Emsg0(M_ERROR, 0, "GZIP data stream found, but GZIP not configured!\n");
         extract = false;
         return true;
       }
@@ -430,7 +430,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
    case STREAM_PROGRAM_NAMES:
    case STREAM_PROGRAM_DATA:
       if (!prog_name_msg) {
-        Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
+         Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
         prog_name_msg++;
       }
       break;
@@ -439,7 +439,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
       /* If extracting, wierd stream (not 1 or 2), close output file anyway */
       if (extract) {
         if (!is_bopen(&bfd)) {
-           Emsg0(M_ERROR, 0, "Logic error output file should be open but is not.\n");
+            Emsg0(M_ERROR, 0, "Logic error output file should be open but is not.\n");
         }
         set_attributes(jcr, attr, &bfd);
         extract = false;
index 8fb8a2681566bf028525646d35ee764199984a1a..cc88da62ec194fd6349361db591cbc40b9a7abd9 100644 (file)
@@ -300,8 +300,10 @@ static bool unser_block_header(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
                         block_len-BLKHDR_CS_LENGTH);
       if (BlockCheckSum != CheckSum) {
         dev->dev_errno = EIO;
-         Mmsg5(dev->errmsg, _("Volume data error at %u:%u! Block checksum mismatch in block %u: calc=%x blk=%x\n"),
-           dev->file, dev->block_num, (unsigned)BlockNumber, BlockCheckSum, CheckSum);
+         Mmsg6(dev->errmsg, _("Volume data error at %u:%u!\n" 
+            "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n"),
+           dev->file, dev->block_num, (unsigned)BlockNumber, 
+           block_len, BlockCheckSum, CheckSum);
         if (block->read_errors == 0 || verbose >= 2) {
             Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
         }
@@ -545,8 +547,7 @@ bool write_block_to_dev(DCR *dcr)
    }
    
    if (dev->free_space_errno < 0) { /* Error while getting free space */
-      char ed1[50];
-      char ed2[50];
+      char ed1[50], ed2[50];
       Dmsg1(10, "Cannot get free space on the device ERR=%s.\n", dev->errmsg);
       Jmsg(jcr, M_FATAL, 0, _("End of Volume \"%s\" at %u:%u on device %s (part_size=%s, free_space=%s, free_space_errno=%d, errmsg=%s).\n"),
           dev->VolCatInfo.VolCatName,
@@ -558,8 +559,7 @@ bool write_block_to_dev(DCR *dcr)
    }
    
    if (((dev->free_space_errno > 0) && ((dev->part_size + block->binbuf) >= dev->free_space))) {
-      char ed1[50];
-      char ed2[50];
+      char ed1[50], ed2[50];
       Dmsg0(10, "==== Just enough free space on the device to write the current part...\n");
       Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %u:%u on device %s (part_size=%s, free_space=%s, free_space_errno=%d).\n"),
            dev->VolCatInfo.VolCatName,
@@ -736,7 +736,7 @@ static bool terminate_writing_volume(DCR *dcr)
    }
    dev->VolCatInfo.VolCatFiles = dev->file;
    
-   if (dev_cap(dev, CAP_REQMOUNT)) { /* Write the current (and last) part. */
+   if (dev->is_dvd()) { /* Write the current (and last) part. */
       open_next_part(dev);
    }
    
@@ -820,14 +820,14 @@ reread:
       return false;
    }
    
-   /*Dmsg1(200, "dev.c 111->file_size=%u\n",(unsigned int)dev->file_size);
-   Dmsg1(200, "dev.c          lseek=%u\n",(unsigned int)lseek(dev->fd, 0, SEEK_CUR));
-   Dmsg1(200, "dev.c dev->part_start=%u\n",(unsigned int)dev->part_start);
-   Dmsg1(200, "dev.c dev->file_size-dev->part_start=%u\n",(unsigned int)dev->file_size-dev->part_start);
-   Dmsg1(200, "dev.c dev->part_size=%u\n", (unsigned int)dev->part_size);
-   Dmsg1(200, "dev.c dev->part=%u\n", (unsigned int)dev->part);
-   Dmsg1(200, "dev.c dev->VolCatInfo.VolCatParts=%u\n", (unsigned int)dev->VolCatInfo.VolCatParts);
-   Dmsg3(200, "dev.c Tests : %d %d %d\n", (dev->VolCatInfo.VolCatParts > 0), ((dev->file_size-dev->part_start) == dev->part_size), (dev->part <= dev->VolCatInfo.VolCatParts));*/
+   /*Dmsg1(200, "dev->file_size=%u\n",(unsigned int)dev->file_size);
+   Dmsg1(200, "lseek=%u\n",(unsigned int)lseek(dev->fd, 0, SEEK_CUR));
+   Dmsg1(200, "dev->part_start=%u\n",(unsigned int)dev->part_start);
+   Dmsg1(200, "dev->file_size-dev->part_start=%u\n",(unsigned int)dev->file_size-dev->part_start);
+   Dmsg1(200, "dev->part_size=%u\n", (unsigned int)dev->part_size);
+   Dmsg1(200, "dev->part=%u\n", (unsigned int)dev->part);
+   Dmsg1(200, "dev->VolCatInfo.VolCatParts=%u\n", (unsigned int)dev->VolCatInfo.VolCatParts);
+   Dmsg3(200, "Tests : %d %d %d\n", (dev->VolCatInfo.VolCatParts > 0), ((dev->file_size-dev->part_start) == dev->part_size), (dev->part <= dev->VolCatInfo.VolCatParts));*/
    /* Check for part file end */
    if ((dev->num_parts > 0) &&
        ((dev->file_size-dev->part_start) == dev->part_size) && 
@@ -862,17 +862,18 @@ reread:
       Mmsg4(dev->errmsg, _("Read error at file:blk %u:%u on device %s. ERR=%s.\n"),
         dev->file, dev->block_num, dev->dev_name, be.strerror());
       Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
-      if (dev->state & ST_EOF) {  /* EOF just seen? */
+      if (dev->at_eof()) {       /* EOF just seen? */
         dev->state |= ST_EOT;    /* yes, error => EOT */
       }
       return false;
    }
-   Dmsg1(200, "Read device got %d bytes\n", stat);
+   Dmsg3(200, "Read device got %d bytes at %u:%u\n", stat,
+      dev->file, dev->block_num);
    if (stat == 0) {            /* Got EOF ! */
       dev->block_num = block->read_len = 0;
       Mmsg3(dev->errmsg, _("Read zero bytes at %u:%u on device %s.\n"),
         dev->file, dev->block_num, dev->dev_name);
-      if (dev->state & ST_EOF) { /* EOF already read? */
+      if (dev->at_eof()) {      /* EOF already read? */
         dev->state |= ST_EOT;  /* yes, 2 EOFs => EOT */
         block->read_len = 0;
         return 0;
@@ -990,11 +991,13 @@ reread:
     *  absolute positioning -- so much for efficiency.  KES Sep 02.
     */
    Dmsg0(200, "At end of read block\n");
-   if (block->read_len > block->block_len && !(dev->state & ST_TAPE)) {
+   if (block->read_len > block->block_len && !dev->is_tape()) {
+      char ed1[50];
       off_t pos = lseek_dev(dev, (off_t)0, SEEK_CUR); /* get curr pos */
       pos -= (block->read_len - block->block_len);
       lseek_dev(dev, pos, SEEK_SET);
-      Dmsg2(200, "Did lseek blk_size=%d rdlen=%d\n", block->block_len,
+      Dmsg3(200, "Did lseek pos=%s blk_size=%d rdlen=%d\n", 
+        edit_uint64(pos, ed1), block->block_len,
            block->read_len);
       dev->file_addr = pos;
       dev->file_size = pos;
index 4df807342a2029fe65759f9e000196efa6281b9f..d230fedf7a86705e0fab2cb1bcac00e5d965e21b 100644 (file)
@@ -73,6 +73,8 @@
    uint32_t VolSessionTime;
  */
 
+class DEVICE;                         /* for forward reference */
+
 /*
  * DEV_BLOCK for reading and writing blocks.
  * This is the basic unit that is written to the device, and
@@ -84,7 +86,7 @@
  */
 struct DEV_BLOCK {
    DEV_BLOCK *next;                   /* pointer to next one */
-   void *dev;                         /* pointer to device (DEVICE not defined yet) */
+   DEVICE *dev;                       /* pointer to device */
    /* binbuf is the number of bytes remaining in the buffer.
     *   For writes, it is bytes not yet written.
     *   For reads, it is remaining bytes not yet read.
index debd882ea459a8252a8c48b2f5e96dd0b9cea8d9..68474d9cb85ddcdb3290af952e44e7328913249b 100644 (file)
@@ -5,7 +5,7 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000-2004 Kern Sibbald
+   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
@@ -65,9 +65,9 @@ static BSR *bsr = NULL;
 static void usage()
 {
    fprintf(stderr,
-"Copyright (C) 2000-2004 Kern Sibbald and John Walker.\n"
+"Copyright (C) 2000-2005 Kern Sibbald.\n"
 "\nVersion: " VERSION " (" BDATE ")\n\n"
-"Usage: bls [-d debug_level] <physical-device-name>\n"
+"Usage: bls [options] <device-name>\n"
 "       -b <file>       specify a bootstrap file\n"
 "       -c <file>       specify a config file\n"
 "       -d <level>      specify debug level\n"
@@ -254,14 +254,10 @@ static void do_close(JCR *jcr)
 /* List just block information */
 static void do_blocks(char *infname)
 {
-   if (verbose) {
-      dump_volume_label(dev);
-      rec = new_record();
-   }
    for ( ;; ) {
       if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
-         Dmsg1(100, "!read_block(): ERR=%s\n", strerror_dev(dev));
-        if (dev->state & ST_EOT) {
+         Dmsg1(100, "!read_block(): ERR=%s\n", dev->strerror());
+        if (dev->at_eom()) {
            if (!mount_next_read_volume(dcr)) {
                Jmsg(jcr, M_INFO, 0, _("Got EOM at file %u on device %s, Volume \"%s\"\n"),
                  dev->file, dev_name(dev), dcr->VolumeName);
@@ -275,8 +271,7 @@ static void do_blocks(char *infname)
            get_session_record(dev, record, &sessrec);
            free_record(record);
             Jmsg(jcr, M_INFO, 0, _("Mounted Volume \"%s\".\n"), dcr->VolumeName);
-
-        } else if (dev->state & ST_EOF) {
+        } else if (dev->at_eof()) {
             Jmsg(jcr, M_INFO, 0, _("Got EOF at file %u on device %s, Volume \"%s\"\n"),
               dev->file, dev_name(dev), dcr->VolumeName);
             Dmsg0(20, "read_record got eof. try again\n");
@@ -359,11 +354,6 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
    if (rec->Stream == STREAM_UNIX_ATTRIBUTES ||
        rec->Stream == STREAM_UNIX_ATTRIBUTES_EX) {
 
-      if (verbose > 1) {
-         const char *rtype = "Attributes";
-         Pmsg5(-1, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n",
-              rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
-      }
       if (!unpack_attributes_record(jcr, rec->Stream, rec->data, attr)) {
         if (!forge_on) {
             Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n"));
@@ -381,6 +371,10 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
       build_attr_output_fnames(jcr, attr);
 
       if (file_is_included(&ff, attr->fname) && !file_is_excluded(&ff, attr->fname)) {
+        if (verbose) {
+            Pmsg5(-1, "FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n",
+                 rec->FileIndex, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
+        }
         print_ls_output(jcr, attr);
         num_files++;
       }
index dfafe13b917e31b1d06e5f580ce0302ed4141c25..9d18ea0b903c7f47f004baad8ebc4012ab85935a 100644 (file)
@@ -7,7 +7,7 @@
  *
  */
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -37,6 +37,7 @@
 struct VOL_LIST {
    VOL_LIST *next;
    char VolumeName[MAX_NAME_LENGTH];
+   char MediaType[MAX_NAME_LENGTH];
    int Slot;
    uint32_t start_file;
 };
@@ -54,6 +55,7 @@ struct VOL_LIST {
 struct BSR_VOLUME {
    BSR_VOLUME *next;
    char VolumeName[MAX_NAME_LENGTH];
+   char MediaType[MAX_NAME_LENGTH];
 };
 
 struct BSR_CLIENT {
index a661374c2facc9c786ab00cb1786aece886bffcb..460c0ae93772c6d94fabdcd570046d14ccbc25a7 100644 (file)
@@ -323,10 +323,10 @@ static bool open_the_device()
 
    block = new_block(dev);
    lock_device(dev);
-   if (!(dev->state & ST_OPENED)) {
+   if (!dev->is_open()) {
       Dmsg1(200, "Opening device %s\n", dcr->VolumeName);
       if (open_dev(dev, dcr->VolumeName, OPEN_READ_WRITE) < 0) {
-        Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
+         Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
         unlock_device(dev);
         free_block(block);
         return false;
@@ -358,9 +358,9 @@ static void labelcmd()
       }
    }
 
-   if (!(dev->state & ST_OPENED)) {
+   if (!dev->is_open()) {
       if (!first_open_device(dev)) {
-        Pmsg1(0, "Device open failed. ERR=%s\n", strerror_dev(dev));
+         Pmsg1(0, "Device open failed. ERR=%s\n", strerror_dev(dev));
       }
    }
    rewind_dev(dev);
@@ -556,15 +556,15 @@ static void capcmd()
    printf("\n");
 
    printf(_("Device status:\n"));
-   printf("%sOPENED ", dev->state & ST_OPENED ? "" : "!");
-   printf("%sTAPE ", dev->state & ST_TAPE ? "" : "!");
-   printf("%sLABEL ", dev->state & ST_LABEL ? "" : "!");
+   printf("%sOPENED ", dev->is_open() ? "" : "!");
+   printf("%sTAPE ", dev->is_tape() ? "" : "!");
+   printf("%sLABEL ", dev->is_labeled() ? "" : "!");
    printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
-   printf("%sAPPEND ", dev->state & ST_APPEND ? "" : "!");
-   printf("%sREAD ", dev->state & ST_READ ? "" : "!");
-   printf("%sEOT ", dev->state & ST_EOT ? "" : "!");
+   printf("%sAPPEND ", dev->can_append() ? "" : "!");
+   printf("%sREAD ", dev->can_read() ? "" : "!");
+   printf("%sEOT ", dev->at_eom() ? "" : "!");
    printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
-   printf("%sEOF ", dev->state & ST_EOF ? "" : "!");
+   printf("%sEOF ", dev->at_eof() ? "" : "!");
    printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
    printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
    printf("\n");
@@ -613,7 +613,7 @@ static void rectestcmd()
       if (write_record_to_block(block, rec)) {
         empty_block(block);
         blkno++;
-        Pmsg2(0, "Block %d i=%d\n", blkno, i);
+         Pmsg2(0, "Block %d i=%d\n", blkno, i);
       } else {
         break;
       }
@@ -697,7 +697,7 @@ static int re_read_block_test()
    }
    if (dev_cap(dev, CAP_TWOEOF)) {
       if (!bsf_dev(dev, 1)) {
-        Pmsg1(0, _("Backspace file failed! ERR=%s\n"), strerror_dev(dev));
+         Pmsg1(0, _("Backspace file failed! ERR=%s\n"), strerror_dev(dev));
         goto bail_out;
       }
    }
@@ -720,7 +720,7 @@ static int re_read_block_test()
    }
    for (int i=0; i<len; i++) {
       if (rec->data[i] != 3) {
-        Pmsg0(0, _("Bad data in record. Test failed!\n"));
+         Pmsg0(0, _("Bad data in record. Test failed!\n"));
         goto bail_out;
       }
    }
@@ -733,11 +733,11 @@ bail_out:
    free_record(rec);
    if (stat == 0) {
       Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
-                "this function to verify the last block written to the\n"
-                "tape. Bacula will skip the last block verification\n"
-                "if you add:\n\n"
-                 "Backward Space Record = No\n\n"
-                 "to your Storage daemon's Device resource definition.\n"));
+                 "this function to verify the last block written to the\n"
+                 "tape. Bacula will skip the last block verification\n"
+                 "if you add:\n\n"
+                  "Backward Space Record = No\n\n"
+                  "to your Storage daemon's Device resource definition.\n"));
    }
    return stat;
 }
@@ -776,11 +776,11 @@ static int write_read_test()
         *p++ = i;
       }
       if (!write_record_to_block(block, rec)) {
-        Pmsg0(0, _("Error writing record to block.\n"));
+         Pmsg0(0, _("Error writing record to block.\n"));
         goto bail_out;
       }
       if (!write_block_to_dev(dcr)) {
-        Pmsg0(0, _("Error writing block to device.\n"));
+         Pmsg0(0, _("Error writing block to device.\n"));
         goto bail_out;
       }
    }
@@ -792,11 +792,11 @@ static int write_read_test()
         *p++ = i;
       }
       if (!write_record_to_block(block, rec)) {
-        Pmsg0(0, _("Error writing record to block.\n"));
+         Pmsg0(0, _("Error writing record to block.\n"));
         goto bail_out;
       }
       if (!write_block_to_dev(dcr)) {
-        Pmsg0(0, _("Error writing block to device.\n"));
+         Pmsg0(0, _("Error writing block to device.\n"));
         goto bail_out;
       }
    }
@@ -816,31 +816,31 @@ read_again:
       if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
         berrno be;
         if (dev_state(dev, ST_EOF)) {
-           Pmsg0(-1, _("Got EOF on tape.\n"));
+            Pmsg0(-1, _("Got EOF on tape.\n"));
            if (i == 1001) {
               goto read_again;
            }
         }
-        Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.strerror(dev->dev_errno));
+         Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.strerror(dev->dev_errno));
         goto bail_out;
       }
       memset(rec->data, 0, rec->data_len);
       if (!read_record_from_block(block, rec)) {
         berrno be;
-        Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.strerror(dev->dev_errno));
+         Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.strerror(dev->dev_errno));
         goto bail_out;
       }
       p = (int *)rec->data;
       for (j=0; j<len; j++) {
         if (*p != i) {
-           Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
+            Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
               i, *p, j);
            goto bail_out;
         }
         p++;
       }
       if (i == 1000 || i == 2000) {
-        Pmsg0(-1, _("1000 blocks re-read correctly.\n"));
+         Pmsg0(-1, _("1000 blocks re-read correctly.\n"));
       }
    }
    Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
@@ -888,11 +888,11 @@ static int position_test()
         *p++ = i;
       }
       if (!write_record_to_block(block, rec)) {
-        Pmsg0(0, _("Error writing record to block.\n"));
+         Pmsg0(0, _("Error writing record to block.\n"));
         goto bail_out;
       }
       if (!write_block_to_dev(dcr)) {
-        Pmsg0(0, _("Error writing block to device.\n"));
+         Pmsg0(0, _("Error writing block to device.\n"));
         goto bail_out;
       }
    }
@@ -904,11 +904,11 @@ static int position_test()
         *p++ = i;
       }
       if (!write_record_to_block(block, rec)) {
-        Pmsg0(0, _("Error writing record to block.\n"));
+         Pmsg0(0, _("Error writing record to block.\n"));
         goto bail_out;
       }
       if (!write_block_to_dev(dcr)) {
-        Pmsg0(0, _("Error writing block to device.\n"));
+         Pmsg0(0, _("Error writing block to device.\n"));
         goto bail_out;
       }
    }
@@ -963,44 +963,44 @@ static int position_test()
       }
       Pmsg2(-1, "Reposition to file:block %d:%d\n", file, blk);
       if (!reposition_dev(dev, file, blk)) {
-        Pmsg0(0, "Reposition error.\n");
+         Pmsg0(0, "Reposition error.\n");
         goto bail_out;
       }
 read_again:
       if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
         berrno be;
         if (dev_state(dev, ST_EOF)) {
-           Pmsg0(-1, _("Got EOF on tape.\n"));
+            Pmsg0(-1, _("Got EOF on tape.\n"));
            if (!got_eof) {
               got_eof = true;
               goto read_again;
            }
         }
-        Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
+         Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
            recno, file, blk, be.strerror(dev->dev_errno));
-        Pmsg0(0, _("This may be because the tape drive block size is not\n"
-                   " set to variable blocking as normally used by Bacula.\n"
-                   " Please see the Tape Testing chapter in the manual and \n"
-                   " look for using mt with defblksize and setoptions\n"
-                   "If your tape drive block size is correct, then perhaps\n"
-                   " your SCSI driver is *really* stupid and does not\n"
-                   " correctly report the file:block after a FSF. In this\n"
-                   " case try setting:\n"
-                   "    Fast Forward Space File = no\n"
-                   " in your Device resource.\n"));
+         Pmsg0(0, _("This may be because the tape drive block size is not\n"
+                    " set to variable blocking as normally used by Bacula.\n"
+                    " Please see the Tape Testing chapter in the manual and \n"
+                    " look for using mt with defblksize and setoptions\n"
+                    "If your tape drive block size is correct, then perhaps\n"
+                    " your SCSI driver is *really* stupid and does not\n"
+                    " correctly report the file:block after a FSF. In this\n"
+                    " case try setting:\n"
+                    "    Fast Forward Space File = no\n"
+                    " in your Device resource.\n"));
 
         goto bail_out;
       }
       memset(rec->data, 0, rec->data_len);
       if (!read_record_from_block(block, rec)) {
         berrno be;
-        Pmsg1(0, _("Read record failed! ERR=%s\n"), be.strerror(dev->dev_errno));
+         Pmsg1(0, _("Read record failed! ERR=%s\n"), be.strerror(dev->dev_errno));
         goto bail_out;
       }
       p = (int *)rec->data;
       for (j=0; j<len; j++) {
         if (p[j] != recno) {
-           Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
+            Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
               recno, p[j], j);
            goto bail_out;
         }
@@ -1027,7 +1027,7 @@ bail_out:
 static int append_test()
 {
    Pmsg0(-1, _("\n\n=== Append files test ===\n\n"
-              "This test is essential to Bacula.\n\n"
+               "This test is essential to Bacula.\n\n"
 "I'm going to write one record  in file 0,\n"
 "                   two records in file 1,\n"
 "             and three records in file 2\n\n"));
@@ -1087,21 +1087,21 @@ static int autochanger_test()
 {
    POOLMEM *results, *changer;
    int slot, status, loaded;
-   int timeout = jcr->device->max_changer_wait;
+   int timeout = dcr->device->max_changer_wait;
    int sleep_time = 0;
 
    Dmsg1(100, "Max changer wait = %d sec\n", timeout);
    if (!dev_cap(dev, CAP_AUTOCHANGER)) {
       return 1;
    }
-   if (!(jcr->device && jcr->device->changer_name && jcr->device->changer_command)) {
+   if (!(dcr->device && dcr->device->changer_name && dcr->device->changer_command)) {
       Pmsg0(-1, "\nAutochanger enabled, but no name or no command device specified.\n");
       return 1;
    }
 
    Pmsg0(-1, "\nAh, I see you have an autochanger configured.\n"
-            "To test the autochanger you must have a blank tape\n"
-            " that I can write on in Slot 1.\n");
+             "To test the autochanger you must have a blank tape\n"
+             " that I can write on in Slot 1.\n");
    if (!get_cmd("\nDo you wish to continue with the Autochanger test? (y/n): ")) {
       return 0;
    }
@@ -1119,8 +1119,7 @@ try_again:
    dcr->VolCatInfo.Slot = slot;
    /* Find out what is loaded, zero means device is unloaded */
    Pmsg0(-1, _("3301 Issuing autochanger \"loaded\" command.\n"));
-   changer = edit_device_codes(jcr, changer, jcr->device->changer_command,
-               "loaded");
+   changer = edit_device_codes(dcr, changer, "loaded");
    status = run_program(changer, timeout, results);
    Dmsg3(100, "run_prog: %s stat=%d result=\"%s\"\n", changer, status, results);
    if (status == 0) {
@@ -1144,14 +1143,13 @@ try_again:
       force_close_dev(dev);
       Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"),
         loaded, dev->drive_index);
-      changer = edit_device_codes(jcr, changer,
-                    jcr->device->changer_command, "unload");
+      changer = edit_device_codes(dcr, changer, "unload");
       status = run_program(changer, timeout, results);
       Pmsg2(-1, "unload status=%s %d\n", status==0?"OK":"Bad", status);
       if (status != 0) {
         berrno be;
-        Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer);
-        Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.strerror(status));
+         Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer);
+         Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.strerror(status));
       }
    }
 
@@ -1163,7 +1161,7 @@ try_again:
    dcr->VolCatInfo.Slot = slot;
    Pmsg2(-1, _("3303 Issuing autochanger \"load slot %d %d\" command.\n"),
       slot, dev->drive_index);
-   changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "load");
+   changer = edit_device_codes(dcr, changer, "load");
    Dmsg1(100, "Changer=%s\n", changer);
    force_close_dev(dev);
    status = run_program(changer, timeout, results);
@@ -1189,8 +1187,8 @@ try_again:
       Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
       clrerror_dev(dev, -1);
       Pmsg0(-1, "\nThe test failed, probably because you need to put\n"
-               "a longer sleep time in the mtx-script in the load) case.\n"
-               "Adding a 30 second sleep and trying again ...\n");
+                "a longer sleep time in the mtx-script in the load) case.\n"
+                "Adding a 30 second sleep and trying again ...\n");
       sleep_time += 30;
       goto try_again;
    } else {
@@ -1206,8 +1204,8 @@ try_again:
 
    if (sleep_time) {
       Pmsg1(-1, "\nThe test worked this time. Please add:\n\n"
-               "   sleep %d\n\n"
-               "to your mtx-changer script in the load) case.\n\n",
+                "   sleep %d\n\n"
+                "to your mtx-changer script in the load) case.\n\n",
                sleep_time);
    } else {
       Pmsg0(-1, "\nThe test autochanger worked!!\n\n");
@@ -1240,8 +1238,8 @@ static int fsf_test()
    bool set_off = false;
 
    Pmsg0(-1, _("\n\n=== Forward space files test ===\n\n"
-              "This test is essential to Bacula.\n\n"
-              "I'm going to write five files then test forward spacing\n\n"));
+               "This test is essential to Bacula.\n\n"
+               "I'm going to write five files then test forward spacing\n\n"));
    argc = 1;
    rewindcmd();
    wrcmd();
@@ -1302,8 +1300,8 @@ test_again:
    }
    if (set_off) {
       Pmsg0(-1, "The test worked this time. Please add:\n\n"
-               "   Fast Forward Space File = no\n\n"
-               "to your Device resource for this drive.\n");
+                "   Fast Forward Space File = no\n\n"
+                "to your Device resource for this drive.\n");
    }
 
    Pmsg0(-1, "\n");
@@ -1323,15 +1321,15 @@ bail_out:
    Pmsg0(-1, _("\nThe forward space file test failed.\n"));
    if (dev_cap(dev, CAP_FASTFSF)) {
       Pmsg0(-1, "You have Fast Forward Space File enabled.\n"
-             "I am turning it off then retrying the test.\n");
+              "I am turning it off then retrying the test.\n");
       dev->capabilities &= ~CAP_FASTFSF;
       set_off = true;
       goto test_again;
    }
    Pmsg0(-1, "You must correct this error or Bacula will not work.\n"
-           "Some systems, e.g. OpenBSD, require you to set\n"
-           "   Use MTIOCGET= no\n"
-           "in your device resource. Use with caution.\n");
+            "Some systems, e.g. OpenBSD, require you to set\n"
+            "   Use MTIOCGET= no\n"
+            "in your device resource. Use with caution.\n");
    return -2;
 }
 
@@ -1360,36 +1358,36 @@ static void testcmd()
    }
    if (stat == -1) {                 /* first test failed */
       if (dev_cap(dev, CAP_EOM) || dev_cap(dev, CAP_FASTFSF)) {
-        Pmsg0(-1, "\nAppend test failed. Attempting again.\n"
-                  "Setting \"Hardware End of Medium = no\n"
-                  "    and \"Fast Forward Space File = no\n"
-                  "and retrying append test.\n\n");
+         Pmsg0(-1, "\nAppend test failed. Attempting again.\n"
+                   "Setting \"Hardware End of Medium = no\n"
+                   "    and \"Fast Forward Space File = no\n"
+                   "and retrying append test.\n\n");
         dev->capabilities &= ~CAP_EOM; /* turn off eom */
         dev->capabilities &= ~CAP_FASTFSF; /* turn off fast fsf */
         stat = append_test();
         if (stat == 1) {
-           Pmsg0(-1, "\n\nIt looks like the test worked this time, please add:\n\n"
-                    "    Hardware End of Medium = No\n\n"
-                    "    Fast Forward Space File = No\n"
-                    "to your Device resource in the Storage conf file.\n");
+            Pmsg0(-1, "\n\nIt looks like the test worked this time, please add:\n\n"
+                     "    Hardware End of Medium = No\n\n"
+                     "    Fast Forward Space File = No\n"
+                     "to your Device resource in the Storage conf file.\n");
            goto all_done;
         }
         if (stat == -1) {
-           Pmsg0(-1, "\n\nThat appears *NOT* to have corrected the problem.\n");
+            Pmsg0(-1, "\n\nThat appears *NOT* to have corrected the problem.\n");
            goto failed;
         }
         /* Wrong count after append */
         if (stat == -2) {
-           Pmsg0(-1, "\n\nIt looks like the append failed. Attempting again.\n"
-                    "Setting \"BSF at EOM = yes\" and retrying append test.\n");
+            Pmsg0(-1, "\n\nIt looks like the append failed. Attempting again.\n"
+                     "Setting \"BSF at EOM = yes\" and retrying append test.\n");
            dev->capabilities |= CAP_BSFATEOM; /* backspace on eom */
            stat = append_test();
            if (stat == 1) {
-              Pmsg0(-1, "\n\nIt looks like the test worked this time, please add:\n\n"
-                    "    Hardware End of Medium = No\n"
-                    "    Fast Forward Space File = No\n"
-                    "    BSF at EOM = yes\n\n"
-                    "to your Device resource in the Storage conf file.\n");
+               Pmsg0(-1, "\n\nIt looks like the test worked this time, please add:\n\n"
+                     "    Hardware End of Medium = No\n"
+                     "    Fast Forward Space File = No\n"
+                     "    BSF at EOM = yes\n\n"
+                     "to your Device resource in the Storage conf file.\n");
               goto all_done;
            }
         }
@@ -1398,43 +1396,43 @@ static void testcmd()
 failed:
       Pmsg0(-1, "\nAppend test failed.\n\n");
       Pmsg0(-1, "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
-           "Unable to correct the problem. You MUST fix this\n"
-            "problem before Bacula can use your tape drive correctly\n");
+            "Unable to correct the problem. You MUST fix this\n"
+             "problem before Bacula can use your tape drive correctly\n");
       Pmsg0(-1, "\nPerhaps running Bacula in fixed block mode will work.\n"
-           "Do so by setting:\n\n"
-           "Minimum Block Size = nnn\n"
-           "Maximum Block Size = nnn\n\n"
-           "in your Storage daemon's Device definition.\n"
-           "nnn must match your tape driver's block size, which\n"
-           "can be determined by reading your tape manufacturers\n"
-           "information, and the information on your kernel dirver.\n"
-           "Fixed block sizes, however, are not normally an ideal solution.\n"
-           "\n"
-           "Some systems, e.g. OpenBSD, require you to set\n"
-           "   Use MTIOCGET= no\n"
-           "in your device resource. Use with caution.\n");
+            "Do so by setting:\n\n"
+            "Minimum Block Size = nnn\n"
+            "Maximum Block Size = nnn\n\n"
+            "in your Storage daemon's Device definition.\n"
+            "nnn must match your tape driver's block size, which\n"
+            "can be determined by reading your tape manufacturers\n"
+            "information, and the information on your kernel dirver.\n"
+            "Fixed block sizes, however, are not normally an ideal solution.\n"
+            "\n"
+            "Some systems, e.g. OpenBSD, require you to set\n"
+            "   Use MTIOCGET= no\n"
+            "in your device resource. Use with caution.\n");
        return;
    }
 
 all_done:
    Pmsg0(-1, _("\nThe above Bacula scan should have output identical to what follows.\n"
-       "Please double check it ...\n"
-       "=== Sample correct output ===\n"
-       "1 block of 64448 bytes in file 1\n"
-       "End of File mark.\n"
-       "2 blocks of 64448 bytes in file 2\n"
-       "End of File mark.\n"
-       "3 blocks of 64448 bytes in file 3\n"
-       "End of File mark.\n"
-       "1 block of 64448 bytes in file 4\n"
-       "End of File mark.\n"
-       "Total files=4, blocks=7, bytes = 451,136\n"
-       "=== End sample correct output ===\n\n"));
+        "Please double check it ...\n"
+        "=== Sample correct output ===\n"
+        "1 block of 64448 bytes in file 1\n"
+        "End of File mark.\n"
+        "2 blocks of 64448 bytes in file 2\n"
+        "End of File mark.\n"
+        "3 blocks of 64448 bytes in file 3\n"
+        "End of File mark.\n"
+        "1 block of 64448 bytes in file 4\n"
+        "End of File mark.\n"
+        "Total files=4, blocks=7, bytes = 451,136\n"
+        "=== End sample correct output ===\n\n"));
 
    Pmsg0(-1, _("If the above scan output is not identical to the\n"
-              "sample output, you MUST correct the problem\n"
-              "or Bacula will not be able to write multiple Jobs to \n"
-              "the tape.\n\n"));
+               "sample output, you MUST correct the problem\n"
+               "or Bacula will not be able to write multiple Jobs to \n"
+               "the tape.\n\n"));
 
    if (stat == 1) {
       re_read_block_test();
@@ -1574,12 +1572,12 @@ static void scancmd()
       if ((stat = read(dev->fd, buf, sizeof(buf))) < 0) {
         berrno be;
         clrerror_dev(dev, -1);
-        Mmsg2(dev->errmsg, "read error on %s. ERR=%s.\n",
+         Mmsg2(dev->errmsg, "read error on %s. ERR=%s.\n",
            dev->dev_name, be.strerror());
-        Pmsg2(0, "Bad status from read %d. ERR=%s\n", stat, strerror_dev(dev));
+         Pmsg2(0, "Bad status from read %d. ERR=%s\n", stat, strerror_dev(dev));
         if (blocks > 0)
-           printf("%d block%s of %d bytes in file %d\n",
-                   blocks, blocks>1?"s":"", block_size, dev->file);
+            printf("%d block%s of %d bytes in file %d\n",
+                    blocks, blocks>1?"s":"", block_size, dev->file);
         return;
       }
       Dmsg1(200, "read status = %d\n", stat);
@@ -1587,15 +1585,15 @@ static void scancmd()
       if (stat != block_size) {
         update_pos_dev(dev);
         if (blocks > 0) {
-           printf("%d block%s of %d bytes in file %d\n",
-                blocks, blocks>1?"s":"", block_size, dev->file);
+            printf("%d block%s of %d bytes in file %d\n",
+                 blocks, blocks>1?"s":"", block_size, dev->file);
            blocks = 0;
         }
         block_size = stat;
       }
       if (stat == 0) {               /* EOF */
         update_pos_dev(dev);
-        printf("End of File mark.\n");
+         printf("End of File mark.\n");
         /* Two reads of zero means end of tape */
         if (dev->state & ST_EOF)
            dev->state |= ST_EOT;
@@ -1604,7 +1602,7 @@ static void scancmd()
            dev->file++;
         }
         if (dev->state & ST_EOT) {
-           printf("End of tape\n");
+            printf("End of tape\n");
            break;
         }
       } else {                       /* Got data */
@@ -1643,40 +1641,40 @@ static void scan_blocks()
    tot_files = dev->file;
    for (;;) {
       if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
-        Dmsg1(100, "!read_block(): ERR=%s\n", strerror_dev(dev));
+         Dmsg1(100, "!read_block(): ERR=%s\n", strerror_dev(dev));
         if (dev->state & ST_EOT) {
            if (blocks > 0) {
-              printf("%d block%s of %d bytes in file %d\n",
-                   blocks, blocks>1?"s":"", block_size, dev->file);
+               printf("%d block%s of %d bytes in file %d\n",
+                    blocks, blocks>1?"s":"", block_size, dev->file);
               blocks = 0;
            }
            goto bail_out;
         }
         if (dev->state & ST_EOF) {
            if (blocks > 0) {
-              printf("%d block%s of %d bytes in file %d\n",
-                      blocks, blocks>1?"s":"", block_size, dev->file);
+               printf("%d block%s of %d bytes in file %d\n",
+                       blocks, blocks>1?"s":"", block_size, dev->file);
               blocks = 0;
            }
-           printf(_("End of File mark.\n"));
+            printf(_("End of File mark.\n"));
            continue;
         }
         if (dev->state & ST_SHORT) {
            if (blocks > 0) {
-              printf("%d block%s of %d bytes in file %d\n",
-                      blocks, blocks>1?"s":"", block_size, dev->file);
+               printf("%d block%s of %d bytes in file %d\n",
+                       blocks, blocks>1?"s":"", block_size, dev->file);
               blocks = 0;
            }
-           printf(_("Short block read.\n"));
+            printf(_("Short block read.\n"));
            continue;
         }
-        printf(_("Error reading block. ERR=%s\n"), strerror_dev(dev));
+         printf(_("Error reading block. ERR=%s\n"), strerror_dev(dev));
         goto bail_out;
       }
       if (block->block_len != block_size) {
         if (blocks > 0) {
-           printf("%d block%s of %d bytes in file %d\n",
-                   blocks, blocks>1?"s":"", block_size, dev->file);
+            printf("%d block%s of %d bytes in file %d\n",
+                    blocks, blocks>1?"s":"", block_size, dev->file);
            blocks = 0;
         }
         block_size = block->block_len;
@@ -1690,14 +1688,14 @@ static void scan_blocks()
       if (verbose == 1) {
         DEV_RECORD *rec = new_record();
         read_record_from_block(block, rec);
-        Pmsg8(-1, "Blk_block: %u dev_blk=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n",
+         Pmsg8(-1, "Blk_block: %u dev_blk=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n",
              block->BlockNumber, dev->block_num, block->block_len,
              FI_to_ascii(rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
              stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len);
         rec->remainder = 0;
         free_record(rec);
       } else if (verbose > 1) {
-        dump_block(block, "");
+         dump_block(block, "");
       }
 
    }
@@ -1758,7 +1756,7 @@ static void fillcmd()
 "This may take a long time -- hours! ...\n\n");
 
    get_cmd("Do you want to run the simplified test (s) with one tape\n"
-          "or the complete multiple tape (m) test: (s/m) ");
+           "or the complete multiple tape (m) test: (s/m) ");
    if (cmd[0] == 's') {
       Pmsg0(-1, "Simple test (single tape) selected.\n");
       simple = true;
@@ -1789,7 +1787,7 @@ static void fillcmd()
     *  subroutine.
     */
    Dmsg0(100, "just before acquire_device\n");
-   if (!acquire_device_for_append(jcr)) {
+   if (!acquire_device_for_append(jcr, dev)) {
       set_jcr_job_status(jcr, JS_ErrorTerminated);
       return;
    }
@@ -1859,7 +1857,7 @@ static void fillcmd()
         /*
          * When we get here we have just filled a block
          */
-        Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
+         Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
                    rec.remainder);
 
         /* Write block to tape */
@@ -1876,14 +1874,14 @@ static void fillcmd()
               now = 1;          /* prevent divide error */
            }
            kbs = (double)dev->VolCatInfo.VolCatBytes / (1000.0 * (double)now);
-           Pmsg4(-1, "Wrote blk_block=%u, dev_blk_num=%u VolBytes=%s rate=%.1f KB/s\n",
+            Pmsg4(-1, "Wrote blk_block=%u, dev_blk_num=%u VolBytes=%s rate=%.1f KB/s\n",
               block->BlockNumber, dev->block_num,
               edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), (float)kbs);
         }
         /* Every 15000 blocks (approx 1GB) write an EOF.
          */
         if ((block->BlockNumber % 15000) == 0) {
-           Pmsg0(-1, "Flush block, write EOF\n");
+            Pmsg0(-1, "Flush block, write EOF\n");
            flush_block(block, 0);
            weof_dev(dev, 1);
         }
@@ -1894,7 +1892,7 @@ static void fillcmd()
         }
       }
       if (!ok) {
-        Pmsg0(000, _("Not OK\n"));
+         Pmsg0(000, _("Not OK\n"));
         break;
       }
       jcr->JobBytes += rec.data_len;   /* increment bytes this job */
@@ -1904,7 +1902,7 @@ static void fillcmd()
 
       /* Get out after writing 10 blocks to the second tape */
       if (BlockNumber > 10 && stop != 0) {     /* get out */
-        Pmsg0(-1, "Done writing ...\n");
+         Pmsg0(-1, "Done writing ...\n");
         break;
       }
    }
@@ -1917,12 +1915,12 @@ static void fillcmd()
         set_jcr_job_status(jcr, JS_ErrorTerminated);
       }
       if (!write_session_label(dcr, EOS_LABEL)) {
-        Pmsg1(000, _("Error writting end session label. ERR=%s\n"), strerror_dev(dev));
+         Pmsg1(000, _("Error writting end session label. ERR=%s\n"), strerror_dev(dev));
         ok = false;
       }
       /* Write out final block of this session */
       if (!write_block_to_device(dcr)) {
-        Pmsg0(-1, _("Set ok=false after write_block_to_device.\n"));
+         Pmsg0(-1, _("Set ok=false after write_block_to_device.\n"));
         ok = false;
       }
       Pmsg0(-1, _("Wrote End of Session label.\n"));
@@ -2001,14 +1999,14 @@ static void unfillcmd()
       read(fd, first_block->buf, first_block->buf_len);
       close(fd);
       if (state_level != btape_state_level) {
-         Pmsg0(-1, "\nThe state file level has changed. You must redo\n"
-                 "the fill command.\n");
+          Pmsg0(-1, "\nThe state file level has changed. You must redo\n"
+                  "the fill command.\n");
          return;
        }
    } else {
       berrno be;
       Pmsg2(-1, "\nCould not find the state file: %s ERR=%s\n"
-            "You must redo the fill command.\n", buf, be.strerror());
+             "You must redo the fill command.\n", buf, be.strerror());
       return;
    }
    do_unfill();
@@ -2049,7 +2047,7 @@ static void do_unfill()
       autochanger = autoload_device(dcr, 1, NULL);
       if (!autochanger) {
         force_close_dev(dev);
-        get_cmd(_("Mount first tape. Press enter when ready: "));
+         get_cmd(_("Mount first tape. Press enter when ready: "));
       }
       free_vol_list(jcr);
       jcr->dcr = new_dcr(jcr, dev);
@@ -2059,8 +2057,8 @@ static void do_unfill()
       close_dev(dev);
       dev->state &= ~(ST_READ|ST_APPEND);
       dev->num_writers = 0;
-      if (!acquire_device_for_read(jcr)) {
-        Pmsg1(-1, "%s", dev->errmsg);
+      if (!acquire_device_for_read(jcr, dev)) {
+         Pmsg1(-1, "%s", dev->errmsg);
         goto bail_out;
       }
    }
@@ -2089,9 +2087,9 @@ static void do_unfill()
    }
    if (compare_blocks(last_block, block)) {
       if (simple) {
-        Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
+         Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
       } else {
-        Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
+         Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
       }
    }
    if (simple) {
@@ -2120,7 +2118,7 @@ static void do_unfill()
    }
 
    dev->state &= ~ST_READ;
-   if (!acquire_device_for_read(jcr)) {
+   if (!acquire_device_for_read(jcr, dev)) {
       Pmsg1(-1, "%s", dev->errmsg);
       goto bail_out;
    }
@@ -2203,9 +2201,9 @@ static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block)
       dump_block(block, _("Block read back"));
       Pmsg1(-1, "\n\nThe blocks differ at byte %u\n", p - last_block->buf);
       Pmsg0(-1, "\n\n!!!! The last block written and the block\n"
-               "that was read back differ. The test FAILED !!!!\n"
-               "This must be corrected before you use Bacula\n"
-               "to write multi-tape Volumes.!!!!\n");
+                "that was read back differ. The test FAILED !!!!\n"
+                "This must be corrected before you use Bacula\n"
+                "to write multi-tape Volumes.!!!!\n");
       return false;
    }
    if (verbose) {
@@ -2255,11 +2253,11 @@ static int flush_block(DEV_BLOCK *block, int dump)
         first_block = dup_block(block); /* first block second tape */
       }
       if (verbose) {
-        Pmsg3(000, "Block not written: FileIndex=%u blk_block=%u Size=%u\n",
+         Pmsg3(000, "Block not written: FileIndex=%u blk_block=%u Size=%u\n",
            (unsigned)file_index, block->BlockNumber, block->block_len);
-        dump_block(last_block, "Last block written");
-        Pmsg0(-1, "\n");
-        dump_block(block, "Block not written");
+         dump_block(last_block, "Last block written");
+         Pmsg0(-1, "\n");
+         dump_block(block, "Block not written");
       }
       if (stop == 0) {
         eot_block = block->BlockNumber;
@@ -2270,7 +2268,7 @@ static int flush_block(DEV_BLOCK *block, int dump)
       now = time(NULL);
       now -= jcr->run_time;
       if (now <= 0) {
-        now = 1;                     /* don't divide by zero */
+         now = 1;                     /* don't divide by zero */
       }
       kbs = (double)dev->VolCatInfo.VolCatBytes / (1000 * now);
       vol_size = dev->VolCatInfo.VolCatBytes;
@@ -2283,7 +2281,7 @@ static int flush_block(DEV_BLOCK *block, int dump)
       } else {
         /* Full test in progress */
         if (!fixup_device_block_write_error(jcr->dcr)) {
-           Pmsg1(000, _("Cannot fixup device error. %s\n"), strerror_dev(dev));
+            Pmsg1(000, _("Cannot fixup device error. %s\n"), strerror_dev(dev));
            ok = false;
            unlock_device(dev);
            return 0;
@@ -2344,15 +2342,15 @@ static void qfillcmd()
    Pmsg1(0, "Begin writing %d Bacula blocks to tape ...\n", count);
    for (i=0; i < count; i++) {
       if (i % 100 == 0) {
-        printf("+");
+         printf("+");
         fflush(stdout);
       }
       if (!write_record_to_block(block, rec)) {
-        Pmsg0(0, _("Error writing record to block.\n"));
+         Pmsg0(0, _("Error writing record to block.\n"));
         goto bail_out;
       }
       if (!write_block_to_dev(dcr)) {
-        Pmsg0(0, _("Error writing block to device.\n"));
+         Pmsg0(0, _("Error writing block to device.\n"));
         goto bail_out;
       }
    }
@@ -2399,7 +2397,7 @@ static void rawfill_cmd()
       stat = write(dev->fd, block->buf, block->buf_len);
       if (stat == (int)block->buf_len) {
         if ((block_num++ % 100) == 0) {
-           printf("+");
+            printf("+");
            fflush(stdout);
         }
         p[0] += p[13];
@@ -2452,7 +2450,7 @@ static void bfill_cmd()
         break;
       }
       if ((block_num++ % 100) == 0) {
-        printf("+");
+         printf("+");
         fflush(stdout);
       }
       p[0] += p[13];
@@ -2517,7 +2515,7 @@ do_tape_cmds()
            break;
         }
       if (!found)
-        Pmsg1(0, _("%s is an illegal command\n"), cmd);
+         Pmsg1(0, _("%s is an illegal command\n"), cmd);
       if (quit)
         break;
    }
@@ -2699,7 +2697,7 @@ static bool my_mount_next_read_volume(DCR *dcr)
    create_vol_list(jcr);
    close_dev(dev);
    dev->state &= ~ST_READ;
-   if (!acquire_device_for_read(jcr)) {
+   if (!acquire_device_for_read(jcr, dev)) {
       Pmsg2(0, "Cannot open Dev=%s, Vol=%s\n", dev_name(dev), dcr->VolumeName);
       return false;
    }
index 2fae0494d3cae600f6d184821c7472c2e473d9f5..a63dd2829de8566ad876a2435221035dab60bd3c 100644 (file)
@@ -104,8 +104,8 @@ JCR *setup_jcr(const char *name, char *dev_name, BSR *bsr,
    if (!bsr && VolumeName) {
       bstrncpy(dcr->VolumeName, VolumeName, sizeof(dcr->VolumeName));
    }
-   strcpy(dcr->pool_name, "Default");
-   strcpy(dcr->pool_type, "Backup");
+   bstrncpy(dcr->pool_name, "Default", sizeof(dcr->pool_name));
+   bstrncpy(dcr->pool_type, "Backup", sizeof(dcr->pool_type));
    return jcr;
 }
 
@@ -136,9 +136,9 @@ static DCR *setup_to_access_device(JCR *jcr, char *dev_name, const char *VolumeN
         /* Try stripping file part */
         p = dev_name + strlen(dev_name);
 
-        while (p >= dev_name && *p != '/')
+         while (p >= dev_name && *p != '/')
            p--;
-        if (*p == '/') {
+         if (*p == '/') {
            bstrncpy(VolName, p+1, sizeof(VolName));
            *p = 0;
         }
@@ -150,7 +150,6 @@ static DCR *setup_to_access_device(JCR *jcr, char *dev_name, const char *VolumeN
           dev_name, configfile);
       return NULL;
    }
-   jcr->device = device;
 
    dev = init_dev(NULL, device);
    if (!dev) {
@@ -172,7 +171,7 @@ static DCR *setup_to_access_device(JCR *jcr, char *dev_name, const char *VolumeN
    create_vol_list(jcr);
 
    if (mode) {                       /* read only access? */
-      if (!acquire_device_for_read(jcr)) {
+      if (!acquire_device_for_read(jcr, dev)) {
         return NULL;
       }
    }
@@ -235,10 +234,11 @@ static DEVRES *find_device_res(char *device_name, int read_access)
    if (!found) {
       /* Search for name of Device resource rather than archive name */
       if (device_name[0] == '"') {
-        strcpy(device_name, device_name+1);
         int len = strlen(device_name);
+        bstrncpy(device_name, device_name+1, len+1);
+        len--;
         if (len > 0) {
-           device_name[len-1] = 0;   /* zap trailing " */
+            device_name[len-1] = 0;   /* zap trailing " */
         }
       }
       foreach_res(device, R_DEVICE) {
@@ -255,7 +255,7 @@ static DEVRES *find_device_res(char *device_name, int read_access)
       return NULL;
    }
    Pmsg2(0, _("Using device: \"%s\" for %s.\n"), device_name,
-            read_access?"reading":"writing");
+             read_access?"reading":"writing");
    return device;
 }
 
index 4fff2ba2f576279d03483d8cdca307d70f20e1ed..b1bb1e0db73cbbdca447a9f702ec1508a7bf489a 100644 (file)
@@ -86,8 +86,8 @@ int mount_dev(DEVICE* dev, int timeout);
 int unmount_dev(DEVICE* dev, int timeout);
 int write_part(DEVICE *dev);
 char *edit_device_codes_dev(DEVICE* dev, char *omsg, const char *imsg);
-void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name);
-void update_free_space_dev(DEVICE* dev);
+static void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name);
+static void update_free_space_dev(DEVICE* dev);
 
 /*
  * Allocate and initialize the DEVICE structure
@@ -114,34 +114,11 @@ init_dev(DEVICE *dev, DEVRES *device)
       if (dev) {
         dev->dev_errno = errno;
       }
-      Emsg2(M_FATAL, 0, "Unable to stat device %s : %s\n", device->device_name,
-        be.strerror());
+      Jmsg2(NULL, M_FATAL, 0, _("Unable to stat device %s: ERR=%s\n"), 
+        device->device_name, be.strerror());
       return NULL;
    }
    
-   /* If the device requires mount :
-    * - Check that the mount point is available 
-    * - Check that (un)mount commands are defined
-    */
-   if (device->cap_bits & CAP_REQMOUNT) {
-      if (stat(device->mount_point, &statp) < 0) {
-        berrno be;
-        if (dev) {
-           dev->dev_errno = errno;
-        }
-         Emsg2(M_FATAL, 0, "Unable to stat mount point %s : %s\n", device->mount_point,
-           be.strerror());
-        return NULL;
-      }
-      if (!device->mount_command || !device->unmount_command) {
-         Emsg0(M_FATAL, 0, "Mount and unmount commands must defined for a device which requires mount.\n");
-        return NULL;
-      }
-      if (!device->write_part_command) {
-         Emsg0(M_FATAL, 0, "Write part command must be defined for a device which requires mount.\n");
-        return NULL;
-      }
-   }
    
    tape = false;
    fifo = false;
@@ -169,7 +146,7 @@ init_dev(DEVICE *dev, DEVRES *device)
 
    /* Copy user supplied device parameters from Resource */
    dev->dev_name = get_memory(strlen(device->device_name)+1);
-   strcpy(dev->dev_name, device->device_name);
+   pm_strcpy(dev->dev_name, device->device_name);
    dev->capabilities = device->cap_bits;
    dev->min_block_size = device->min_block_size;
    dev->max_block_size = device->max_block_size;
@@ -203,6 +180,27 @@ init_dev(DEVICE *dev, DEVRES *device)
       dev->state |= ST_FILE;
    }
 
+   /* If the device requires mount :
+    * - Check that the mount point is available 
+    * - Check that (un)mount commands are defined
+    */
+   if (dev->is_file() && device->cap_bits & CAP_REQMOUNT) {
+      if (stat(device->mount_point, &statp) < 0) {
+        berrno be;
+        dev->dev_errno = errno;
+         Jmsg2(NULL, M_FATAL, 0, _("Unable to stat mount point %s: ERR=%s\n"), 
+           device->mount_point, be.strerror());
+        return NULL;
+      }
+      if (!device->mount_command || !device->unmount_command) {
+         Jmsg0(NULL, M_ERROR_TERM, 0, _("Mount and unmount commands must defined for a device which requires mount.\n"));
+      }
+      if (!device->write_part_command) {
+         Jmsg0(NULL, M_ERROR_TERM, 0, _("Write part command must be defined for a device which requires mount.\n"));
+      }
+      dev->state |= ST_DVD;
+   }
+
    if (dev->max_block_size > 1000000) {
       Emsg3(M_ERROR, 0, _("Block size %u on device %s is too large, using default %u\n"),
         dev->max_block_size, dev->dev_name, DEFAULT_BLOCK_SIZE);
@@ -226,25 +224,25 @@ init_dev(DEVICE *dev, DEVRES *device)
       berrno be;
       dev->dev_errno = errstat;
       Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), be.strerror(errstat));
-      Emsg0(M_FATAL, 0, dev->errmsg);
+      Emsg0(M_ERROR_TERM, 0, dev->errmsg);
    }
    if ((errstat = pthread_cond_init(&dev->wait_next_vol, NULL)) != 0) {
       berrno be;
       dev->dev_errno = errstat;
       Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), be.strerror(errstat));
-      Emsg0(M_FATAL, 0, dev->errmsg);
+      Emsg0(M_ERROR_TERM, 0, dev->errmsg);
    }
    if ((errstat = pthread_mutex_init(&dev->spool_mutex, NULL)) != 0) {
       berrno be;
       dev->dev_errno = errstat;
       Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.strerror(errstat));
-      Emsg0(M_FATAL, 0, dev->errmsg);
+      Emsg0(M_ERROR_TERM, 0, dev->errmsg);
    }
    if ((errstat = rwl_init(&dev->lock)) != 0) {
       berrno be;
       dev->dev_errno = errstat;
       Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.strerror(errstat));
-      Emsg0(M_FATAL, 0, dev->errmsg);
+      Emsg0(M_ERROR_TERM, 0, dev->errmsg);
    }
 
    dev->fd = -1;
@@ -257,17 +255,16 @@ init_dev(DEVICE *dev, DEVRES *device)
 /* 
  * Write the current volume/part filename to archive_name.
  */
-
-void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name) {
+static void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name) 
+{
    char partnumber[20];
    
-   if (dev_cap(dev, CAP_REQMOUNT)) {
+   if (dev->is_dvd()) {
         /* If we try to open the last part, just open it from disk, 
         * otherwise, open it from the spooling directory */
       if (dev->part < dev->num_parts) {
         pm_strcpy(archive_name, dev->device->mount_point);
-      }
-      else {
+      } else {
         /* Use the working directory if spool directory is not defined */
         if (dev->device->spool_directory) {
            pm_strcpy(archive_name, dev->device->spool_directory);
@@ -275,8 +272,7 @@ void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name) {
            pm_strcpy(archive_name, working_directory);
         }
       }
-   }
-   else {
+   } else {
       pm_strcpy(archive_name, dev->dev_name);
    }
       
@@ -285,16 +281,20 @@ void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name) {
    }
    pm_strcat(archive_name, VolName);
    /* if part != 0, append .# to the filename (where # is the part number) */
-   if (dev->part != 0) {
+   if (dev->is_dvd() && dev->part != 0) {
       pm_strcat(archive_name, ".");
       bsnprintf(partnumber, sizeof(partnumber), "%d", dev->part);
       pm_strcat(archive_name, partnumber);
    }
 }  
 
-/* Open the device with the operating system and
+/*
+ * Open the device with the operating system and
  * initialize buffer pointers.
  *
+ * Returns:  -1  on error
+ *          fd  on success
+ *
  * Note, for a tape, the VolName is the name we give to the
  *    volume (not really used here), but for a file, the
  *    VolName represents the name of the file to be created/opened.
@@ -304,7 +304,7 @@ void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name) {
 int
 open_dev(DEVICE *dev, char *VolName, int mode)
 {
-   if (dev->state & ST_OPENED) {
+   if (dev->is_open()) {
       /*
        *  *****FIXME***** how to handle two threads wanting
        *  different volumes mounted???? E.g. one is waiting
@@ -327,7 +327,7 @@ open_dev(DEVICE *dev, char *VolName, int mode)
    Dmsg3(29, "open_dev: tape=%d dev_name=%s vol=%s\n", dev_is_tape(dev),
         dev->dev_name, dev->VolCatInfo.VolCatName);
    dev->state &= ~(ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
-   if (dev->state & (ST_TAPE|ST_FIFO)) {
+   if (dev->is_tape() || dev->is_fifo()) {
       dev->file_size = 0;
       int timeout;
       Dmsg0(29, "open_dev: device is tape\n");
@@ -342,7 +342,7 @@ open_dev(DEVICE *dev, char *VolName, int mode)
       }
       timeout = dev->max_open_wait;
       errno = 0;
-      if (dev->state & ST_FIFO && timeout) {
+      if (dev->is_fifo() && timeout) {
         /* Set open timer */
         dev->tid = start_thread_timer(pthread_self(), timeout);
       }
@@ -405,9 +405,9 @@ open_dev(DEVICE *dev, char *VolName, int mode)
       }
       get_filename(dev, VolName, archive_name);
 
-      if (dev_cap(dev, CAP_REQMOUNT) && (dev->num_parts > 0)) {
+      if (dev->is_dvd()) {
         if (mount_dev(dev, 1) < 0) {
-            Mmsg(dev->errmsg, _("Could not mount device %s.\n"),
+            Mmsg(dev->errmsg, _("Could not mount archive device %s.\n"),
                 dev->dev_name);
            Emsg0(M_FATAL, 0, dev->errmsg);
            dev->fd = -1;
@@ -418,8 +418,9 @@ open_dev(DEVICE *dev, char *VolName, int mode)
       Dmsg2(29, "open_dev: device is disk %s (mode:%d)\n", archive_name.c_str(), mode);
       dev->openmode = mode;
       
-      /* If we are not trying to access the last part, set mode to OPEN_READ_ONLY,
-       * as writing would be an error.
+      /*
+       * If we are not trying to access the last part, set mode to 
+       *   OPEN_READ_ONLY as writing would be an error.
        */
       if (dev->part < dev->num_parts) {
         mode = OPEN_READ_ONLY;
@@ -448,15 +449,15 @@ open_dev(DEVICE *dev, char *VolName, int mode)
         if (fstat(dev->fd, &filestat) < 0) {
            berrno be;
            dev->dev_errno = errno;
-            Mmsg2(&dev->errmsg, _("Could not open: %s, ERR=%s\n"), archive_name.c_str(), be.strerror());
+            Mmsg2(&dev->errmsg, _("Could not fstat: %s, ERR=%s\n"), archive_name.c_str(), be.strerror());
            Emsg0(M_FATAL, 0, dev->errmsg);
-        }
-        else {
+        } else {
            dev->part_size = filestat.st_size;
         }
       }
       Dmsg4(29, "open_dev: disk fd=%d opened, part=%d/%d, part_size=%u\n", dev->fd, dev->part, dev->num_parts, dev->part_size);
-      if ((dev->mode != OPEN_READ_ONLY) && ((dev->free_space_errno == 0) || (dev->num_parts == dev->part))) {
+      if (dev->is_dvd() && (dev->mode != OPEN_READ_ONLY) && 
+         ((dev->free_space_errno == 0) || (dev->num_parts == dev->part))) {
         update_free_space_dev(dev);
       }
    }
@@ -540,7 +541,8 @@ int do_mount_dev(DEVICE* dev, int mount, int dotimeout) {
  * Note that if the right volume is mounted, open_guess_name_dev returns the same
  * result as an usual open_dev.
  */
-int open_guess_name_dev(DEVICE *dev) {
+int open_guess_name_dev(DEVICE *dev) 
+{
    Dmsg1(29, "open_guess_name_dev: dev=%s\n", dev->dev_name);
    POOL_MEM guessedname(PM_FNAME);
    DIR* dp;
@@ -549,7 +551,7 @@ int open_guess_name_dev(DEVICE *dev) {
    int index;
    int name_max;
    
-   if (!dev_cap(dev, CAP_REQMOUNT)) {
+   if (!dev->is_dvd()) {
       Dmsg1(100, "open_guess_name_dev: device does not require mount, returning 0. dev=%s\n", dev->dev_name);
       return 0;
    }
@@ -566,8 +568,7 @@ int open_guess_name_dev(DEVICE *dev) {
       if (dev->free_space_errno >= 0) {
          Dmsg1(100, "open_guess_name_dev: device cannot be mounted, but it seems to be writable, returning 0. dev=%s\n", dev->dev_name);
         return 0;
-      }
-      else {
+      } else {
          Dmsg1(100, "open_guess_name_dev: device cannot be mounted, and is not writable, returning 0. dev=%s\n", dev->dev_name);
         /* read_dev_volume_label_guess must now check dev->free_space_errno to understand that the media is not writable. */
         return 0;
@@ -682,12 +683,12 @@ int open_guess_name_dev(DEVICE *dev) {
  * If timeout, wait until the mount command returns 0.
  * If !timeout, try to mount the device only once.
  */
-int mount_dev(DEVICE* dev, int timeout) {
+int mount_dev(DEVICE* dev, int timeout) 
+{
    if (dev->state & ST_MOUNTED) {
       Dmsg0(100, "mount_dev: Device already mounted\n");
       return 0;
-   }
-   else {
+   } else {
       return do_mount_dev(dev, 1, timeout);
    }
 }
@@ -696,23 +697,23 @@ int mount_dev(DEVICE* dev, int timeout) {
  * If timeout, wait until the unmount command returns 0.
  * If !timeout, try to unmount the device only once.
  */
-int unmount_dev(DEVICE* dev, int timeout) {
+int unmount_dev(DEVICE* dev, int timeout) 
+{
    if (dev->state & ST_MOUNTED) {
       return do_mount_dev(dev, 0, timeout);
-   }
-   else {
+   } else {
       Dmsg0(100, "mount_dev: Device already unmounted\n");
       return 0;
    }
 }
 
 /* Update the free space on the device */
-void update_free_space_dev(DEVICE* dev) {
+static void update_free_space_dev(DEVICE* dev) 
+{
    POOL_MEM ocmd(PM_FNAME);
    POOLMEM* results;
    char* icmd;
    int timeout;
-   char* statstr;
    long long int free;
    
    icmd = dev->device->free_space_command;
@@ -734,61 +735,45 @@ void update_free_space_dev(DEVICE* dev) {
    timeout = 3;
    
    while (1) {
+      char ed1[50];
       if (run_program_full_output(ocmd.c_str(), dev->max_open_wait/2, results) == 0) {
          Dmsg1(100, "Free space program run : %s\n", results);
-         /* We also need negatives values, so we can't use dev->free_space, which is unsigned */
-        free = strtoll(results, &statstr, 10);
-        if (results != statstr) { /* Something parsed */
-           if (free >= 0) {
-              dev->free_space = free;
-              dev->free_space_errno = 1;
-               Mmsg0(dev->errmsg, "");
-              break;
-           }
-           else {
-              dev->free_space_errno = free;
-              dev->free_space = 0;
-               if (*statstr == '\n') {
-                 statstr++;
-              }
-               if (statstr[strlen(statstr)-1] == '\n') {
-                 statstr[strlen(statstr)-1] = 0;
-              }
-               Mmsg1(dev->errmsg, "Error while getting free space (%s)", statstr);
-           }
-        }
-        else {
-           dev->free_space = 0;
-           dev->free_space_errno = -EPIPE;
-            Mmsg1(dev->errmsg, "Error while getting free space (output=%s)", results);
+        free = str_to_int64(results);
+        if (free >= 0) {
+           dev->free_space = free;
+           dev->free_space_errno = 1;
+            Mmsg0(dev->errmsg, "");
+           break;
         }
       }
-      else {
-        dev->free_space = 0;
-        dev->free_space_errno = -EPIPE;
-         Mmsg1(dev->errmsg, "Cannot run free space command (%s)", results);
-      }
+      dev->free_space = 0;
+      dev->free_space_errno = -EPIPE;
+      Mmsg1(dev->errmsg, "Cannot run free space command (%s)\n", results);
       
       if (--timeout > 0) {
-         Dmsg4(40, "Cannot get free space on device %s. free_space=%lld, free_space_errno=%d ERR=%s\n", dev->dev_name, 
-              dev->free_space, dev->free_space_errno, dev->errmsg);
+         Dmsg4(40, "Cannot get free space on device %s. free_space=%s, "
+            "free_space_errno=%d ERR=%s\n", dev->dev_name, 
+              edit_uint64(dev->free_space, ed1), dev->free_space_errno, 
+              dev->errmsg);
         bmicrosleep(1, 0);
         continue;
       }
 
       dev->dev_errno = -dev->free_space_errno;
-      Dmsg4(40, "Cannot get free space on device %s. free_space=%lld, free_space_errno=%d ERR=%s\n",
-           dev->dev_name, dev->free_space, dev->free_space_errno, dev->errmsg);
-      free_pool_memory(results);
-      return;
+      Dmsg4(40, "Cannot get free space on device %s. free_space=%s, "
+         "free_space_errno=%d ERR=%s\n",
+           dev->dev_name, edit_uint64(dev->free_space, ed1),
+           dev->free_space_errno, dev->errmsg);
+      break;
    }
    
    free_pool_memory(results);
-   
    Dmsg2(29, "update_free_space_dev: free_space=%lld, free_space_errno=%d\n", dev->free_space, dev->free_space_errno);
+   return;
 }
 
-int write_part(DEVICE *dev) {
+int write_part(DEVICE *dev) 
+{
    Dmsg1(29, "write_part: device is %s\n", dev->dev_name);
    
    if (unmount_dev(dev, 1) < 0) {
@@ -840,8 +825,9 @@ int open_next_part(DEVICE *dev) {
       
    Dmsg3(29, "open_next_part %s %s %d\n", dev->dev_name, dev->VolCatInfo.VolCatName, dev->openmode);
    /* When appending, do not open a new part if the current is empty */
-   if ((dev->state & ST_APPEND) && (dev->part == dev->num_parts) && (dev->part_size == 0)) {
-      Dmsg0(29, "open_next_part exited immediatly (dev->part_size == 0).\n");
+   if (dev->can_append() && (dev->part == dev->num_parts) && 
+       (dev->part_size == 0)) {
+      Dmsg0(29, "open_next_part exited immediately (dev->part_size == 0).\n");
       return dev->fd;
    }
    
@@ -854,7 +840,7 @@ int open_next_part(DEVICE *dev) {
    state = dev->state;
    dev->state &= ~ST_OPENED;
    
-   if ((dev_cap(dev, CAP_REQMOUNT)) && (dev->part == dev->num_parts) && (dev->state & ST_APPEND)) {
+   if (dev->is_dvd() && (dev->part == dev->num_parts) && dev->can_append()) {
       if (write_part(dev) < 0) {
         return -1;
       }
@@ -901,8 +887,7 @@ int open_next_part(DEVICE *dev) {
    
    if (open_dev(dev, dev->VolCatInfo.VolCatName, dev->openmode) < 0) {
       return -1;
-   }
-   else {
+   } else {
       dev->state = state;
       return dev->fd;
    }
@@ -930,8 +915,7 @@ int open_first_part(DEVICE *dev) {
    if (open_dev(dev, dev->VolCatInfo.VolCatName, dev->openmode)) {
       dev->state = state;
       return dev->fd;
-   }
-   else {
+   } else {
       return 0;
    }
 }
@@ -946,7 +930,8 @@ bool _rewind_dev(char *file, int line, DEVICE *dev)
 #endif
 
 /* Protected version of lseek, which opens the right part if necessary */
-off_t lseek_dev(DEVICE *dev, off_t offset, int whence) {
+off_t lseek_dev(DEVICE *dev, off_t offset, int whence)
+{
    int pos, openmode;
    
    if (dev->num_parts == 0) { /* If there is only one part, simply call lseek. */
@@ -954,97 +939,92 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence) {
    }
       
    switch(whence) {
-      case SEEK_SET:
-         Dmsg1(100, "lseek_dev SEEK_SET called %d\n", offset);
-        if ((uint64_t)offset >= dev->part_start) {
-           if ((uint64_t)(offset - dev->part_start) < dev->part_size) {
-              /* We are staying in the current part, just seek */
-              if ((pos = lseek(dev->fd, (off_t)(offset-dev->part_start), SEEK_SET)) < 0) {
-                 return pos;   
-              }
-              else {
-                 return pos + dev->part_start;
-              }
-           }
-           else {
-              /* Load next part, and start again */
-              if (open_next_part(dev) < 0) {
-                  Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
-                 return -1;
-              }
-              return lseek_dev(dev, offset, SEEK_SET);
+   case SEEK_SET:
+      Dmsg1(100, "lseek_dev SEEK_SET called %d\n", offset);
+      if ((uint64_t)offset >= dev->part_start) {
+        if ((uint64_t)(offset - dev->part_start) < dev->part_size) {
+           /* We are staying in the current part, just seek */
+           if ((pos = lseek(dev->fd, (off_t)(offset-dev->part_start), SEEK_SET)) < 0) {
+              return pos;   
+           } else {
+              return pos + dev->part_start;
            }
-        }
-        else {
-           /* pos < dev->part_start :
-            * We need to access a previous part, 
-            * so just load the first one, and seek again
-            * until the right one is loaded */
-           if (open_first_part(dev) < 0) {
-               Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
+        } else {
+           /* Load next part, and start again */
+           if (open_next_part(dev) < 0) {
+               Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
               return -1;
            }
            return lseek_dev(dev, offset, SEEK_SET);
         }
-        break;
-      case SEEK_CUR:
-         Dmsg1(100, "lseek_dev SEEK_CUR called %d\n", offset);
-        if ((pos = lseek(dev->fd, (off_t)0, SEEK_CUR)) < 0) {
-           return pos;   
-        }
-        pos += dev->part_start;
-        if (offset == 0) {
-           return pos;
-        }
-        else { /* Not used in Bacula, but should work */
-           return lseek_dev(dev, pos, SEEK_SET);
-        }
-        break;
-      case SEEK_END:
-         Dmsg1(100, "lseek_dev SEEK_END called %d\n", offset);
-        if (offset > 0) { /* Not used by bacula */
-            Dmsg1(100, "lseek_dev SEEK_END called with an invalid offset %d\n", offset);
-           errno = EINVAL;
+      } else {
+        /* pos < dev->part_start :
+         * We need to access a previous part, 
+         * so just load the first one, and seek again
+         * until the right one is loaded */
+        if (open_first_part(dev) < 0) {
+            Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
            return -1;
         }
+        return lseek_dev(dev, offset, SEEK_SET);
+      }
+      break;
+   case SEEK_CUR:
+      Dmsg1(100, "lseek_dev SEEK_CUR called %d\n", offset);
+      if ((pos = lseek(dev->fd, (off_t)0, SEEK_CUR)) < 0) {
+        return pos;   
+      }
+      pos += dev->part_start;
+      if (offset == 0) {
+        return pos;
+      }
+      else { /* Not used in Bacula, but should work */
+        return lseek_dev(dev, pos, SEEK_SET);
+      }
+      break;
+   case SEEK_END:
+      Dmsg1(100, "lseek_dev SEEK_END called %d\n", offset);
+      if (offset > 0) { /* Not used by bacula */
+         Dmsg1(100, "lseek_dev SEEK_END called with an invalid offset %d\n", offset);
+        errno = EINVAL;
+        return -1;
+      }
+      
+      if (dev->part == dev->num_parts) { /* The right part is already loaded */
+        if ((pos = lseek(dev->fd, (off_t)0, SEEK_END)) < 0) {
+           return pos;   
+        } else {
+           return pos + dev->part_start;
+        }
+      } else {
+        /* Load the first part, then load the next until we reach the last one.
+         * This is the only way to be sure we compute the right file address. */
+        /* Save previous openmode, and open all but last part read-only (useful for DVDs) */
+        openmode = dev->openmode;
+        dev->openmode = OPEN_READ_ONLY;
         
-        if (dev->part == dev->num_parts) { /* The right part is already loaded */
-           if ((pos = lseek(dev->fd, (off_t)0, SEEK_END)) < 0) {
-              return pos;   
-           }
-           else {
-              return pos + dev->part_start;
-           }
+        /* Works because num_parts > 0. */
+        if (open_first_part(dev) < 0) {
+            Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
+           return -1;
         }
-        else {
-           /* Load the first part, then load the next until we reach the last one.
-            * This is the only way to be sure we compute the right file address. */
-           /* Save previous openmode, and open all but last part read-only (useful for DVDs) */
-           openmode = dev->openmode;
-           dev->openmode = OPEN_READ_ONLY;
-           
-           /* Works because num_parts > 0. */
-           if (open_first_part(dev) < 0) {
-               Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
-              return -1;
-           }
-           while (dev->part < (dev->num_parts-1)) {
-              if (open_next_part(dev) < 0) {
-                  Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
-                 return -1;
-              }
-           }
-           dev->openmode = openmode;
+        while (dev->part < (dev->num_parts-1)) {
            if (open_next_part(dev) < 0) {
                Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
               return -1;
            }
-           return lseek_dev(dev, 0, SEEK_END);
         }
-        break;
-      default:
-        errno = EINVAL;
-        return -1;
+        dev->openmode = openmode;
+        if (open_next_part(dev) < 0) {
+            Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
+           return -1;
+        }
+        return lseek_dev(dev, 0, SEEK_END);
+      }
+      break;
+   default:
+      errno = EINVAL;
+      return -1;
    }
 }
 
@@ -1070,7 +1050,7 @@ bool rewind_dev(DEVICE *dev)
    dev->block_num = dev->file = 0;
    dev->file_size = 0;
    dev->file_addr = 0;
-   if (dev->state & ST_TAPE) {
+   if (dev->is_tape()) {
       mt_com.mt_op = MTREW;
       mt_com.mt_count = 1;
       /* If we get an I/O error on rewind, it is probably because
@@ -1095,7 +1075,7 @@ bool rewind_dev(DEVICE *dev)
         }
         break;
       }
-   } else if (dev->state & ST_FILE) {     
+   } else if (dev->is_file()) {      
       if (lseek_dev(dev, (off_t)0, SEEK_SET) < 0) {
         berrno be;
         dev->dev_errno = errno;
@@ -1131,7 +1111,7 @@ eod_dev(DEVICE *dev)
    if (dev->state & (ST_FIFO | ST_PROG)) {
       return 1;
    }
-   if (!(dev->state & ST_TAPE)) {
+   if (!(dev->is_tape())) {
       pos = lseek_dev(dev, (off_t)0, SEEK_END);
 //    Dmsg1(100, "====== Seek to %lld\n", pos);
       if (pos >= 0) {
@@ -1147,7 +1127,8 @@ eod_dev(DEVICE *dev)
    }
 #ifdef MTEOM
 
-   if (dev_cap(dev, CAP_MTIOCGET) && dev_cap(dev, CAP_FASTFSF) && !dev_cap(dev, CAP_EOM)) {
+   if (dev_cap(dev, CAP_MTIOCGET) && dev_cap(dev, CAP_FASTFSF) && 
+      !dev_cap(dev, CAP_EOM)) {
       struct mtget mt_stat;
       Dmsg0(100,"Using FAST FSF for EOM\n");
       if (ioctl(dev->fd, MTIOCGET, (char *)&mt_stat) == 0 && mt_stat.mt_fileno <= 0) {
@@ -1273,7 +1254,7 @@ bool update_pos_dev(DEVICE *dev)
    }
 
    /* Find out where we are */
-   if (dev->state & ST_FILE) {
+   if (dev->is_file()) {
       dev->file = 0;
       dev->file_addr = 0;
       pos = lseek_dev(dev, (off_t)0, SEEK_CUR);
@@ -1314,7 +1295,7 @@ uint32_t status_dev(DEVICE *dev)
       stat |= BMT_EOF;
       Dmsg0(-20, " EOF");
    }
-   if (dev->state & ST_TAPE) {
+   if (dev->is_tape()) {
       stat |= BMT_TAPE;
       Dmsg0(-20," Bacula status:");
       Dmsg2(-20," file=%d block=%d\n", dev->file, dev->block_num);
@@ -1394,7 +1375,7 @@ bool load_dev(DEVICE *dev)
       Emsg0(M_FATAL, 0, dev->errmsg);
       return false;
    }
-   if (!(dev->state & ST_TAPE)) {
+   if (!(dev->is_tape())) {
       return true;
    }
 #ifndef MTLOAD
@@ -1437,7 +1418,7 @@ bool offline_dev(DEVICE *dev)
       Emsg0(M_FATAL, 0, dev->errmsg);
       return false;
    }
-   if (!(dev->state & ST_TAPE)) {
+   if (!(dev->is_tape())) {
       return true;
    }
 
@@ -2032,7 +2013,7 @@ static void do_close(DEVICE *dev)
    }
    
    /* Remove the last part file if it is empty */
-   if ((dev->state & ST_APPEND) && (dev->num_parts > 0)) {
+   if (dev->can_append() && (dev->num_parts > 0)) {
       struct stat statp;
       POOL_MEM archive_name(PM_FNAME);
       dev->part = dev->num_parts;
@@ -2148,8 +2129,8 @@ dev_is_tape(DEVICE *dev)
 bool
 dev_can_write(DEVICE *dev)
 {
-   if ((dev->state & ST_OPENED) &&  (dev->state & ST_APPEND) &&
-       (dev->state & ST_LABEL) && !(dev->state & ST_WEOT)) {
+   if (dev->is_open() &&  dev->can_append() &&
+       dev->is_labeled()  && !(dev->state & ST_WEOT)) {
       return true;
    } else {
       return false;
index 181398c6307d9dd48742ec6ccff16475ea4885f3..e6fb96b11c966dea7acff7efed88b8e99f2900c1 100644 (file)
 #ifndef __DEV_H
 #define __DEV_H 1
 
-#undef DCR                           /* used by Bacula */
+#undef DCR                            /* used by Bacula */
 
 /* #define NEW_LOCK 1 */
 
-#define new_lock_device(dev)            _new_lock_device(__FILE__, __LINE__, (dev))
+#define new_lock_device(dev)             _new_lock_device(__FILE__, __LINE__, (dev))
 #define new_lock_device_state(dev,state) _new_lock_device(__FILE__, __LINE__, (dev), (state))
-#define new_unlock_device(dev)          _new_unlock_device(__FILE__, __LINE__, (dev))
+#define new_unlock_device(dev)           _new_unlock_device(__FILE__, __LINE__, (dev))
 
 #define lock_device(d) _lock_device(__FILE__, __LINE__, (d))
 #define unlock_device(d) _unlock_device(__FILE__, __LINE__, (d))
@@ -54,228 +54,261 @@ enum {
 };
 
 /* Generic status bits returned from status_dev() */
-#define BMT_TAPE          (1<<0)     /* is tape device */
-#define BMT_EOF           (1<<1)     /* just read EOF */
-#define BMT_BOT           (1<<2)     /* at beginning of tape */
-#define BMT_EOT           (1<<3)     /* end of tape reached */
-#define BMT_SM            (1<<4)     /* DDS setmark */
-#define BMT_EOD           (1<<5)     /* DDS at end of data */
-#define BMT_WR_PROT       (1<<6)     /* tape write protected */
-#define BMT_ONLINE        (1<<7)     /* tape online */
-#define BMT_DR_OPEN       (1<<8)     /* tape door open */
-#define BMT_IM_REP_EN     (1<<9)     /* immediate report enabled */
+#define BMT_TAPE           (1<<0)     /* is tape device */
+#define BMT_EOF            (1<<1)     /* just read EOF */
+#define BMT_BOT            (1<<2)     /* at beginning of tape */
+#define BMT_EOT            (1<<3)     /* end of tape reached */
+#define BMT_SM             (1<<4)     /* DDS setmark */
+#define BMT_EOD            (1<<5)     /* DDS at end of data */
+#define BMT_WR_PROT        (1<<6)     /* tape write protected */
+#define BMT_ONLINE         (1<<7)     /* tape online */
+#define BMT_DR_OPEN        (1<<8)     /* tape door open */
+#define BMT_IM_REP_EN      (1<<9)     /* immediate report enabled */
 
 
 /* Test capabilities */
 #define dev_cap(dev, cap) ((dev)->capabilities & (cap))
 
 /* Bits for device capabilities */
-#define CAP_EOF           (1<<0)     /* has MTWEOF */
-#define CAP_BSR           (1<<1)     /* has MTBSR */
-#define CAP_BSF           (1<<2)     /* has MTBSF */
-#define CAP_FSR           (1<<3)     /* has MTFSR */
-#define CAP_FSF           (1<<4)     /* has MTFSF */
-#define CAP_EOM           (1<<5)     /* has MTEOM */
-#define CAP_REM           (1<<6)     /* is removable media */
-#define CAP_RACCESS       (1<<7)     /* is random access device */
-#define CAP_AUTOMOUNT     (1<<8)     /* Read device at start to see what is there */
-#define CAP_LABEL         (1<<9)     /* Label blank tapes */
-#define CAP_ANONVOLS      (1<<10)    /* Mount without knowing volume name */
-#define CAP_ALWAYSOPEN    (1<<11)    /* always keep device open */
+#define CAP_EOF            (1<<0)     /* has MTWEOF */
+#define CAP_BSR            (1<<1)     /* has MTBSR */
+#define CAP_BSF            (1<<2)     /* has MTBSF */
+#define CAP_FSR            (1<<3)     /* has MTFSR */
+#define CAP_FSF            (1<<4)     /* has MTFSF */
+#define CAP_EOM            (1<<5)     /* has MTEOM */
+#define CAP_REM            (1<<6)     /* is removable media */
+#define CAP_RACCESS        (1<<7)     /* is random access device */
+#define CAP_AUTOMOUNT      (1<<8)     /* Read device at start to see what is there */
+#define CAP_LABEL          (1<<9)     /* Label blank tapes */
+#define CAP_ANONVOLS       (1<<10)    /* Mount without knowing volume name */
+#define CAP_ALWAYSOPEN     (1<<11)    /* always keep device open */
 #define CAP_AUTOCHANGER    (1<<12)    /* AutoChanger */
 #define CAP_OFFLINEUNMOUNT (1<<13)    /* Offline before unmount */
-#define CAP_STREAM        (1<<14)    /* Stream device */
-#define CAP_BSFATEOM      (1<<15)    /* Backspace file at EOM */
-#define CAP_FASTFSF       (1<<16)    /* Fast forward space file */
-#define CAP_TWOEOF        (1<<17)    /* Write two eofs for EOM */
+#define CAP_STREAM         (1<<14)    /* Stream device */
+#define CAP_BSFATEOM       (1<<15)    /* Backspace file at EOM */
+#define CAP_FASTFSF        (1<<16)    /* Fast forward space file */
+#define CAP_TWOEOF         (1<<17)    /* Write two eofs for EOM */
 #define CAP_CLOSEONPOLL    (1<<18)    /* Close device on polling */
 #define CAP_POSITIONBLOCKS (1<<19)    /* Use block positioning */
-#define CAP_MTIOCGET      (1<<20)    /* Basic support for fileno and blkno */
-#define CAP_REQMOUNT      (1<<21)    /* Require mount to read files back (typically: DVD) */
+#define CAP_MTIOCGET       (1<<20)    /* Basic support for fileno and blkno */
+#define CAP_REQMOUNT       (1<<21)    /* Require mount to read files back (typically: DVD) */
 
 /* Test state */
 #define dev_state(dev, st_state) ((dev)->state & (st_state))
 
 /* Device state bits */
-#define ST_OPENED         (1<<0)     /* set when device opened */
-#define ST_TAPE           (1<<1)     /* is a tape device */
-#define ST_FILE           (1<<2)     /* is a file device */
-#define ST_FIFO           (1<<3)     /* is a fifo device */
-#define ST_PROG           (1<<4)     /* is a program device */
-#define ST_LABEL          (1<<5)     /* label found */
-#define ST_MALLOC          (1<<6)     /* dev packet malloc'ed in init_dev() */
-#define ST_APPEND         (1<<7)     /* ready for Bacula append */
-#define ST_READ           (1<<8)     /* ready for Bacula read */
-#define ST_EOT            (1<<9)     /* at end of tape */
-#define ST_WEOT           (1<<10)    /* Got EOT on write */
-#define ST_EOF            (1<<11)    /* Read EOF i.e. zero bytes */
-#define ST_NEXTVOL        (1<<12)    /* Start writing on next volume */
-#define ST_SHORT          (1<<13)    /* Short block read */
-#define ST_MOUNTED        (1<<14)    /* the device is mounted to the mount point */
+#define ST_OPENED          (1<<0)     /* set when device opened */
+#define ST_TAPE            (1<<1)     /* is a tape device */
+#define ST_FILE            (1<<2)     /* is a file device */
+#define ST_FIFO            (1<<3)     /* is a fifo device */
+#define ST_DVD             (1<<4)     /* is a DVD device */  
+#define ST_PROG            (1<<5)     /* is a program device */
+#define ST_LABEL           (1<<6)     /* label found */
+#define ST_MALLOC          (1<<7)     /* dev packet malloc'ed in init_dev() */
+#define ST_APPEND          (1<<8)     /* ready for Bacula append */
+#define ST_READ            (1<<9)     /* ready for Bacula read */
+#define ST_EOT             (1<<10)    /* at end of tape */
+#define ST_WEOT            (1<<11)    /* Got EOT on write */
+#define ST_EOF             (1<<12)    /* Read EOF i.e. zero bytes */
+#define ST_NEXTVOL         (1<<13)    /* Start writing on next volume */
+#define ST_SHORT           (1<<14)    /* Short block read */
+#define ST_MOUNTED         (1<<15)    /* the device is mounted to the mount point */
 
 /* dev_blocked states (mutually exclusive) */
 enum {
-   BST_NOT_BLOCKED = 0,              /* not blocked */
-   BST_UNMOUNTED,                    /* User unmounted device */
-   BST_WAITING_FOR_SYSOP,            /* Waiting for operator to mount tape */
-   BST_DOING_ACQUIRE,                /* Opening/validating/moving tape */
-   BST_WRITING_LABEL,                 /* Labeling a tape */
+   BST_NOT_BLOCKED = 0,               /* not blocked */
+   BST_UNMOUNTED,                     /* User unmounted device */
+   BST_WAITING_FOR_SYSOP,             /* Waiting for operator to mount tape */
+   BST_DOING_ACQUIRE,                 /* Opening/validating/moving tape */
+   BST_WRITING_LABEL,                  /* Labeling a tape */
    BST_UNMOUNTED_WAITING_FOR_SYSOP,    /* Closed by user during mount request */
-   BST_MOUNT                          /* Mount request */
+   BST_MOUNT                           /* Mount request */
 };
 
 /* Volume Catalog Information structure definition */
 struct VOLUME_CAT_INFO {
    /* Media info for the current Volume */
-   uint32_t VolCatJobs;              /* number of jobs on this Volume */
-   uint32_t VolCatFiles;             /* Number of files */
-   uint32_t VolCatBlocks;            /* Number of blocks */
-   uint64_t VolCatBytes;             /* Number of bytes written */
-   uint32_t VolCatParts;             /* Number of parts written */
-   uint32_t VolCatMounts;            /* Number of mounts this volume */
-   uint32_t VolCatErrors;            /* Number of errors this volume */
-   uint32_t VolCatWrites;            /* Number of writes this volume */
-   uint32_t VolCatReads;             /* Number of reads this volume */
-   uint64_t VolCatRBytes;            /* Number of bytes read */
-   uint32_t VolCatRecycles;          /* Number of recycles this volume */
-   uint32_t EndFile;                 /* Last file number */
-   uint32_t EndBlock;                /* Last block number */
-   int32_t  Slot;                    /* Slot in changer */
-   bool     InChanger;               /* Set if vol in current magazine */
-   uint32_t VolCatMaxJobs;           /* Maximum Jobs to write to volume */
-   uint32_t VolCatMaxFiles;          /* Maximum files to write to volume */
-   uint64_t VolCatMaxBytes;          /* Max bytes to write to volume */
+   uint32_t VolCatJobs;               /* number of jobs on this Volume */
+   uint32_t VolCatFiles;              /* Number of files */
+   uint32_t VolCatBlocks;             /* Number of blocks */
+   uint64_t VolCatBytes;              /* Number of bytes written */
+   uint32_t VolCatParts;              /* Number of parts written */
+   uint32_t VolCatMounts;             /* Number of mounts this volume */
+   uint32_t VolCatErrors;             /* Number of errors this volume */
+   uint32_t VolCatWrites;             /* Number of writes this volume */
+   uint32_t VolCatReads;              /* Number of reads this volume */
+   uint64_t VolCatRBytes;             /* Number of bytes read */
+   uint32_t VolCatRecycles;           /* Number of recycles this volume */
+   uint32_t EndFile;                  /* Last file number */
+   uint32_t EndBlock;                 /* Last block number */
+   int32_t  LabelType;                /* Bacula/ANSI/IBM */
+   int32_t  Slot;                     /* Slot in changer */
+   bool     InChanger;                /* Set if vol in current magazine */
+   uint32_t VolCatMaxJobs;            /* Maximum Jobs to write to volume */
+   uint32_t VolCatMaxFiles;           /* Maximum files to write to volume */
+   uint64_t VolCatMaxBytes;           /* Max bytes to write to volume */
    uint64_t VolCatCapacityBytes;      /* capacity estimate */
-   uint64_t VolReadTime;             /* time spent reading */
-   uint64_t VolWriteTime;            /* time spent writing this Volume */
-   char VolCatStatus[20];            /* Volume status */
+   uint64_t VolReadTime;              /* time spent reading */
+   uint64_t VolWriteTime;             /* time spent writing this Volume */
+   char VolCatStatus[20];             /* Volume status */
    char VolCatName[MAX_NAME_LENGTH];  /* Desired volume to mount */
 };
 
 
 typedef struct s_steal_lock {
-   pthread_t  no_wait_id;            /* id of no wait thread */
-   int       dev_blocked;            /* state */
-   int       dev_prev_blocked;       /* previous blocked state */
+   pthread_t  no_wait_id;             /* id of no wait thread */
+   int        dev_blocked;            /* state */
+   int        dev_prev_blocked;       /* previous blocked state */
 } bsteal_lock_t;
 
-struct DEVRES;                       /* Device resource defined in stored_conf.h */
+struct DEVRES;                        /* Device resource defined in stored_conf.h */
 
 /*
  * Device structure definition. There is one of these for
  *  each physical device. Everything here is "global" to
  *  that device and effects all jobs using the device.
  */
-struct DEVICE {
+class DEVICE {
 public:
-   DEVICE *next;                     /* pointer to next open device */
-   DEVICE *prev;                     /* pointer to prev open device */
-   JCR *attached_jcrs;               /* attached JCR list */
-   dlist *attached_dcrs;             /* attached DCR list */
-   pthread_mutex_t mutex;            /* access control */
+   dlist *attached_dcrs;              /* attached DCR list */
+   pthread_mutex_t mutex;             /* access control */
    pthread_mutex_t spool_mutex;       /* mutex for updating spool_size */
-   pthread_cond_t wait;              /* thread wait variable */
+   pthread_cond_t wait;               /* thread wait variable */
    pthread_cond_t wait_next_vol;      /* wait for tape to be mounted */
-   pthread_t no_wait_id;             /* this thread must not wait */
-   int dev_blocked;                  /* set if we must wait (i.e. change tape) */
-   int dev_prev_blocked;             /* previous blocked state */
-   int num_waiting;                  /* number of threads waiting */
-   int num_writers;                  /* number of writing threads */
+   pthread_t no_wait_id;              /* this thread must not wait */
+   int dev_blocked;                   /* set if we must wait (i.e. change tape) */
+   int dev_prev_blocked;              /* previous blocked state */
+   int num_waiting;                   /* number of threads waiting */
+   int num_writers;                   /* number of writing threads */
+   int reserved_device;               /* number of device reservations */
 
    /* New access control in process of being implemented */
-   brwlock_t lock;                   /* New mutual exclusion lock */
-
-   int use_count;                    /* usage count on this device */
-   int fd;                           /* file descriptor */
-   int capabilities;                 /* capabilities mask */
-   int state;                        /* state mask */
-   int dev_errno;                    /* Our own errno */
-   int mode;                         /* read/write modes */
-   int openmode;                     /* parameter passed to open_dev (useful to reopen the device) */
-   uint32_t drive_index;             /* Autochanger drive index */
-   POOLMEM *dev_name;                /* device name */
-   char *errmsg;                     /* nicely edited error message */
-   uint32_t block_num;               /* current block number base 0 */
-   uint32_t file;                    /* current file number base 0 */
-   uint64_t file_addr;               /* Current file read/write address */
-   uint64_t file_size;               /* Current file size */
-   uint32_t EndBlock;                /* last block written */
-   uint32_t EndFile;                 /* last file written */
-   uint32_t min_block_size;          /* min block size */
-   uint32_t max_block_size;          /* max block size */
-   uint64_t max_volume_size;         /* max bytes to put on one volume */
-   uint64_t max_file_size;           /* max file size to put in one file on volume */
-   uint64_t volume_capacity;         /* advisory capacity */
-   uint64_t max_spool_size;          /* maximum spool file size */
-   uint64_t spool_size;              /* current spool size */
-   uint32_t max_rewind_wait;         /* max secs to allow for rewind */
-   uint32_t max_open_wait;           /* max secs to allow for open */
-   uint32_t max_open_vols;           /* max simultaneous open volumes */
+   brwlock_t lock;                    /* New mutual exclusion lock */
+
+   int use_count;                     /* usage count on this device */
+   int fd;                            /* file descriptor */
+   int capabilities;                  /* capabilities mask */
+   int state;                         /* state mask */
+   int dev_errno;                     /* Our own errno */
+   int mode;                          /* read/write modes */
+   int openmode;                      /* parameter passed to open_dev (useful to reopen the device) */
+   uint32_t drive_index;              /* Autochanger drive index */
+   POOLMEM *dev_name;                 /* device name */
+   char *errmsg;                      /* nicely edited error message */
+   uint32_t block_num;                /* current block number base 0 */
+   uint32_t file;                     /* current file number base 0 */
+   uint64_t file_addr;                /* Current file read/write address */
+   uint64_t file_size;                /* Current file size */
+   uint32_t EndBlock;                 /* last block written */
+   uint32_t EndFile;                  /* last file written */
+   uint32_t min_block_size;           /* min block size */
+   uint32_t max_block_size;           /* max block size */
+   uint64_t max_volume_size;          /* max bytes to put on one volume */
+   uint64_t max_file_size;            /* max file size to put in one file on volume */
+   uint64_t volume_capacity;          /* advisory capacity */
+   uint64_t max_spool_size;           /* maximum spool file size */
+   uint64_t spool_size;               /* current spool size */
+   uint32_t max_rewind_wait;          /* max secs to allow for rewind */
+   uint32_t max_open_wait;            /* max secs to allow for open */
+   uint32_t max_open_vols;            /* max simultaneous open volumes */
    
-   uint64_t max_part_size;           /* max part size */
-   uint64_t part_size;               /* current part size */
-   uint32_t part;                    /* current part number */
-   uint64_t part_start;              /* current part start address (relative to the whole volume) */
-   uint32_t num_parts;               /* number of parts (total) */
-   uint64_t free_space;              /* current free space on medium (without the current part) */
-   int free_space_errno;             /* indicates:
-                                      * - free_space_errno == 0: ignore free_space.
-                                      * - free_space_errno < 0: an error occured. 
-                                      * - free_space_errno > 0: free_space is valid. */
+   uint64_t max_part_size;            /* max part size */
+   uint64_t part_size;                /* current part size */
+   uint32_t part;                     /* current part number */
+   uint64_t part_start;               /* current part start address (relative to the whole volume) */
+   uint32_t num_parts;                /* number of parts (total) */
+   uint64_t free_space;               /* current free space on medium (without the current part) */
+   int free_space_errno;              /* indicates:
+                                       * - free_space_errno == 0: ignore free_space.
+                                       * - free_space_errno < 0: an error occured. 
+                                       * - free_space_errno > 0: free_space is valid. */
    
-   utime_t  vol_poll_interval;       /* interval between polling Vol mount */
-   DEVRES *device;                   /* pointer to Device Resource */
-   btimer_t *tid;                    /* timer id */
+   utime_t  vol_poll_interval;        /* interval between polling Vol mount */
+   DEVRES *device;                    /* pointer to Device Resource */
+   btimer_t *tid;                     /* timer id */
 
-   VOLUME_CAT_INFO VolCatInfo;       /* Volume Catalog Information */
-   VOLUME_LABEL VolHdr;              /* Actual volume label */
+   VOLUME_CAT_INFO VolCatInfo;        /* Volume Catalog Information */
+   VOLUME_LABEL VolHdr;               /* Actual volume label */
 
    /* Device wait times ***FIXME*** look at durations */
    char BadVolName[MAX_NAME_LENGTH];  /* Last wrong Volume mounted */
-   bool poll;                        /* set to poll Volume */
+   bool poll;                         /* set to poll Volume */
    int min_wait;
    int max_wait;
    int max_num_wait;
    int wait_sec;
    int rem_wait_sec;
    int num_wait;
+
+   int is_tape() const;
+   int is_file() const;
+   int is_fifo() const;
+   int is_dvd() const;
+   int is_open() const;
+   int is_labeled() const;
+   int at_eof() const;
+   int at_eom() const;
+   int can_append() const;
+   int can_read() const;
+   const char *strerror() const;
+   const char *archive_name() const;
 };
 
+/* Note, these return int not bool! */
+inline int DEVICE::is_tape() const { return state & ST_TAPE; }
+inline int DEVICE::is_file() const { return state & ST_FILE; }
+inline int DEVICE::is_fifo() const { return state & ST_FIFO; }
+inline int DEVICE::is_dvd()  const { return state & ST_DVD; }
+inline int DEVICE::is_open() const { return state & ST_OPENED; }
+inline int DEVICE::is_labeled() const { return state & ST_LABEL; }
+inline int DEVICE::at_eof() const { return state & ST_EOF; }
+inline int DEVICE::at_eom() const { return state & ST_EOT; }
+inline int DEVICE::can_append() const { return state & ST_APPEND; }
+inline int DEVICE::can_read() const { return state & ST_READ; }
+inline const char *DEVICE::strerror() const { return errmsg; }
+inline const char *DEVICE::archive_name() const { return dev_name; }
+
+
+
 /*
  * Device Context (or Control) Record.
  *  There is one of these records for each Job that is using
  *  the device. Items in this record are "local" to the Job and
- *  do not affect other Jobs.
+ *  do not affect other Jobs. Note, a job can have multiple
+ *  DCRs open, each pointing to a different device. 
  */
 class DCR {
 public:
-   dlink dev_link;                   /* link to attach to dev */
-   JCR *jcr;                         /* pointer to JCR */
-   DEVICE *dev;                      /* pointer to device */
-   DEV_BLOCK *block;                 /* pointer to block */
-   DEV_RECORD *rec;                  /* pointer to record */
-   int spool_fd;                     /* fd if spooling */
-   bool spool_data;                  /* set to spool data */
-   bool spooling;                    /* set when actually spooling */
-   bool dev_locked;                  /* set if dev already locked */
-   bool NewVol;                      /* set if new Volume mounted */
-   bool WroteVol;                    /* set if Volume written */
-   bool NewFile;                     /* set when EOF written */
-   uint32_t VolFirstIndex;           /* First file index this Volume */
-   uint32_t VolLastIndex;            /* Last file index this Volume */
-   uint32_t FileIndex;               /* Current File Index */
-   uint32_t EndFile;                 /* End file written */
-   uint32_t StartFile;               /* Start write file */
-   uint32_t StartBlock;              /* Start write block */
-   uint32_t EndBlock;                /* Ending block written */
-   int64_t spool_size;               /* Current spool size */
-   int64_t max_spool_size;           /* Max job spool size */
+   dlink dev_link;                    /* link to attach to dev */
+   JCR *jcr;                          /* pointer to JCR */
+   DEVICE *dev;                       /* pointer to device */
+   DEVRES *device;                    /* pointer to device resource */
+   DEV_BLOCK *block;                  /* pointer to block */
+   DEV_RECORD *rec;                   /* pointer to record */
+   int spool_fd;                      /* fd if spooling */
+   bool spool_data;                   /* set to spool data */
+   bool spooling;                     /* set when actually spooling */
+   bool dev_locked;                   /* set if dev already locked */
+   bool NewVol;                       /* set if new Volume mounted */
+   bool WroteVol;                     /* set if Volume written */
+   bool NewFile;                      /* set when EOF written */
+   bool reserved_device;              /* set if reserve done */
+   uint32_t VolFirstIndex;            /* First file index this Volume */
+   uint32_t VolLastIndex;             /* Last file index this Volume */
+   uint32_t FileIndex;                /* Current File Index */
+   uint32_t EndFile;                  /* End file written */
+   uint32_t StartFile;                /* Start write file */
+   uint32_t StartBlock;               /* Start write block */
+   uint32_t EndBlock;                 /* Ending block written */
+   int64_t spool_size;                /* Current spool size */
+   int64_t max_spool_size;            /* Max job spool size */
    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
    char pool_name[MAX_NAME_LENGTH];   /* pool name */
    char pool_type[MAX_NAME_LENGTH];   /* pool type */
    char media_type[MAX_NAME_LENGTH];  /* media type */
    char dev_name[MAX_NAME_LENGTH];    /* dev name */
-   VOLUME_CAT_INFO VolCatInfo;       /* Catalog info for desired volume */
+   VOLUME_CAT_INFO VolCatInfo;        /* Catalog info for desired volume */
 };
 
 
@@ -284,7 +317,7 @@ public:
  *  dependent. Arrgggg!
  */
 #ifndef MTEOM
-#ifdef MTSEOD
+#ifdef  MTSEOD
 #define MTEOM MTSEOD
 #endif
 #ifdef MTEOD
index b14f64c125e279ca68ba70d9e193cf1918c91c88..682ce6e0a4c1d1c0526cfdd9600585644af0472e 100644 (file)
@@ -276,7 +276,7 @@ bool first_open_device(DEVICE *dev)
       return true;
    }
 
-   if (!(dev->state & ST_OPENED)) {
+   if (!dev->is_open()) {
        int mode;
        if (dev_cap(dev, CAP_STREAM)) {
          mode = OPEN_WRITE_ONLY;
@@ -285,7 +285,7 @@ bool first_open_device(DEVICE *dev)
        }
       Dmsg0(129, "Opening device.\n");
       if (open_dev(dev, NULL, mode) < 0) {
-        Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
+         Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
         unlock_device(dev);
         return false;
       }
@@ -303,21 +303,23 @@ bool open_device(DCR *dcr)
 {
    DEVICE *dev = dcr->dev;
    /* Open device */
-   if  (!(dev_state(dev, ST_OPENED))) {
-       int mode;
-       if (dev_cap(dev, CAP_STREAM)) {
-         mode = OPEN_WRITE_ONLY;
-       } else {
-         mode = OPEN_READ_WRITE;
-       }
-       if (open_dev(dev, dcr->VolCatInfo.VolCatName, mode) < 0) {
-         /* If polling, ignore the error */
-         if (!dev->poll) {
-            Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s. ERR=%s\n"),
-               dev_name(dev), strerror_dev(dev));
-         }
-         return false;
-       }
+   if  (!dev->is_open()) {
+      int mode;
+      if (dev_cap(dev, CAP_STREAM)) {
+        mode = OPEN_WRITE_ONLY;
+      } else {
+        mode = OPEN_READ_WRITE;
+      }
+      if (open_dev(dev, dcr->VolCatInfo.VolCatName, mode) < 0) {
+        /* If polling, ignore the error */
+        if (!dev->poll) {
+            Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open archive %s. ERR=%s\n"),
+              dev_name(dev), strerror_dev(dev));
+            Dmsg2(000, "Unable to open archive %s. ERR=%s\n", 
+              dev_name(dev), strerror_dev(dev));
+        }
+        return false;
+      }
    }
    return true;
 }
@@ -353,7 +355,7 @@ void _lock_device(const char *file, int line, DEVICE *dev)
       while (dev->dev_blocked) {
         if ((stat = pthread_cond_wait(&dev->wait, &dev->mutex)) != 0) {
            V(dev->mutex);
-           Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
+            Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
               strerror(stat));
         }
       }
index 12c67cb156946e1ee5b9fb17e93454a9e0df7dfa..c4a97757251f903215fba78e9f462bea17663643 100644 (file)
@@ -52,15 +52,18 @@ extern time_t daemon_start_time;
 extern struct s_last_job last_job;
 
 /* Static variables */
-static char derrmsg[]       = "3900 Invalid command\n";
-static char OKsetdebug[]   = "3000 OK setdebug=%d\n";
+static char derrmsg[]     = "3900 Invalid command\n";
+static char OKsetdebug[]  = "3000 OK setdebug=%d\n";
 static char illegal_cmd[] = "3997 Illegal command for a Director with Monitor directive enabled\n";
 
 /* Imported functions */
 extern void terminate_child();
 extern bool job_cmd(JCR *jcr);
+extern bool use_cmd(JCR *jcr);
+extern bool run_cmd(JCR *jcr);
 extern bool status_cmd(JCR *sjcr);
 extern bool qstatus_cmd(JCR *jcr);
+extern bool query_cmd(JCR *jcr);
 
 /* Forward referenced functions */
 static bool label_cmd(JCR *jcr);
@@ -103,6 +106,9 @@ static struct s_cmds cmds[] = {
    {"status",      status_cmd,      1},
    {".status",     qstatus_cmd,     1},
    {"unmount",     unmount_cmd,     0},
+   {"use device=", use_cmd,         0},
+   {"run",         run_cmd,         0},
+   {"query",       query_cmd,       0},
    {NULL,       NULL}                      /* list terminator */
 };
 
@@ -178,7 +184,7 @@ void *handle_connection_request(void *arg)
    }
    Dmsg0(90, "Message channel init completed.\n");
 
-   for (quit=0; !quit;) {
+   for (quit=false; !quit;) {
       /* Read command */
       if ((bnet_stat = bnet_recv(bs)) <= 0) {
         break;               /* connection terminated */
@@ -193,6 +199,7 @@ void *handle_connection_request(void *arg)
              bnet_sig(bs, BNET_EOD);
              break;
           }
+           Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
           if (!cmds[i].func(jcr)) { /* do command */
              quit = true; /* error, get out */
               Dmsg1(190, "Command %s requsts quit\n", cmds[i].cmd);
@@ -322,7 +329,7 @@ static bool do_label(JCR *jcr, int relabel)
       if (dev) {
         /******FIXME**** compare MediaTypes */
         P(dev->mutex);               /* Use P to avoid indefinite block */
-        if (!(dev->state & ST_OPENED)) {
+        if (!dev->is_open()) {
            label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel);
            force_close_dev(dev);
          /* Under certain "safe" conditions, we can steal the lock */
@@ -382,12 +389,9 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
    }
 
    /* See what we have for a Volume */
-   label_status = read_dev_volume_label(dcr);
-   
-   if (dev_cap(dev, CAP_REQMOUNT)) {
+   if (dev->is_dvd()) {
       label_status = read_dev_volume_label_guess(dcr, 1);
-   }
-   else {
+   } else {
       label_status = read_dev_volume_label(dcr);
    }
    
@@ -477,7 +481,6 @@ static DEVICE *find_device(JCR *jcr, POOL_MEM &dname)
       /* Find resource, and make sure we were able to open it */
       if (strcmp(device->hdr.name, dname.c_str()) == 0 && device->dev) {
          Dmsg1(20, "Found device %s\n", device->hdr.name);
-        jcr->device = device;
         found = true;
         break;
       }
@@ -489,6 +492,7 @@ static DEVICE *find_device(JCR *jcr, POOL_MEM &dname)
        */
       jcr->dcr = new_dcr(jcr, device->dev);
       UnlockRes();
+      jcr->dcr->device = device;
       return jcr->dcr->dev;
    }
    UnlockRes();
@@ -539,7 +543,7 @@ static bool mount_cmd(JCR *jcr)
                Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
               dev->dev_blocked = BST_MOUNT;
            }
-           if (dev_state(dev, ST_LABEL)) {
+           if (dev->is_labeled()) {
                bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
                  dev_name(dev), dev->VolHdr.VolName);
            } else {
@@ -560,8 +564,8 @@ static bool mount_cmd(JCR *jcr)
            break;
 
         case BST_NOT_BLOCKED:
-           if (dev_state(dev, ST_OPENED)) {
-              if (dev_state(dev, ST_LABEL)) {
+           if (dev->is_open()) {
+              if (dev->is_labeled()) {
                   bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
                     dev_name(dev), dev->VolHdr.VolName);
               } else {
@@ -580,7 +584,7 @@ static bool mount_cmd(JCR *jcr)
                  break;
               }
               read_label(dcr);
-              if (dev_state(dev, ST_LABEL)) {
+              if (dev->is_labeled()) {
                   bnet_fsend(dir, _("3001 Device %s is already mounted with Volume \"%s\"\n"),
                     dev_name(dev), dev->VolHdr.VolName);
               } else {
@@ -620,7 +624,7 @@ static bool unmount_cmd(JCR *jcr)
       dev = find_device(jcr, dname);
       if (dev) {
         P(dev->mutex);               /* Use P to avoid indefinite block */
-        if (!(dev->state & ST_OPENED)) {
+        if (!dev->is_open()) {
             Dmsg0(90, "Device already unmounted\n");
             bnet_fsend(dir, _("3901 Device \"%s\" is already unmounted.\n"), dev_name(dev));
 
@@ -694,7 +698,7 @@ static bool release_cmd(JCR *jcr)
       dev = find_device(jcr, dname);
       if (dev) {
         P(dev->mutex);               /* Use P to avoid indefinite block */
-        if (!(dev->state & ST_OPENED)) {
+        if (!dev->is_open()) {
             Dmsg0(90, "Device already released\n");
             bnet_fsend(dir, _("3911 Device %s already released.\n"), dev_name(dev));
 
@@ -757,7 +761,7 @@ static bool autochanger_cmd(JCR *jcr)
         P(dev->mutex);               /* Use P to avoid indefinite block */
         if (!dev_is_tape(dev)) {
             bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"), dev_name(dev));
-        } else if (!(dev->state & ST_OPENED)) {
+        } else if (!dev->is_open()) {
            autochanger_list(dcr, dir);
          /* Under certain "safe" conditions, we can steal the lock */
         } else if (dev->dev_blocked &&
@@ -802,7 +806,7 @@ static bool readlabel_cmd(JCR *jcr)
       dev = find_device(jcr, dname);
       if (dev) {
         P(dev->mutex);               /* Use P to avoid indefinite block */
-        if (!dev_state(dev, ST_OPENED)) {
+        if (!dev->is_open()) {
            read_volume_label(jcr, dev, Slot);
            force_close_dev(dev);
          /* Under certain "safe" conditions, we can steal the lock */
@@ -884,10 +888,10 @@ static bool try_autoload_device(JCR *jcr, int slot, const char *VolName)
    }
 
    /* Ensure that the device is open -- autoload_device() closes it */
-   for ( ; !(dev->state & ST_OPENED); ) {
+   for ( ; !dev->is_open(); ) {
       if (open_dev(dev, dcr->VolumeName, OPEN_READ_WRITE) < 0) {
          bnet_fsend(dir, _("3910 Unable to open device %s. ERR=%s\n"),
-           dev_name(dev), strerror_dev(dev));
+           dev_name(dev), dev->strerror());
         return false;
       }
    }
index 122dca6da03a89029f651dad348678af192699eb..71a75615cd94f4a122ce70311531927894b8cddb 100644 (file)
@@ -13,7 +13,7 @@
  *
  */
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -145,7 +145,7 @@ void run_job(JCR *jcr)
         }
       }
       if (!found) {                  /* command not found */
-        Dmsg1(110, "<filed: Command not found: %s\n", fd->msg);
+         Dmsg1(110, "<filed: Command not found: %s\n", fd->msg);
         bnet_fsend(fd, ferrmsg);
         break;
       }
@@ -214,8 +214,7 @@ static bool append_open_session(JCR *jcr)
       return false;
    }
 
-   Dmsg1(110, "Append open session: %s\n", dev_name(jcr->device->dev));
-   jcr->session_opened = TRUE;
+   jcr->session_opened = true;
 
    /* Send "Ticket" to File Daemon */
    bnet_fsend(fd, OK_open, jcr->VolSessionId);
@@ -244,8 +243,6 @@ static bool append_close_session(JCR *jcr)
 
    bnet_sig(fd, BNET_EOD);           /* send EOD to File daemon */
 
-   Dmsg1(110, "Append close session: %s\n", dev_name(jcr->device->dev));
-
    jcr->session_opened = false;
    return true;
 }
@@ -301,9 +298,7 @@ static bool read_open_session(JCR *jcr)
         jcr->read_EndBlock);
    }
 
-   Dmsg1(110, "Read open session: %s\n", dev_name(jcr->device->dev));
-
-   jcr->session_opened = TRUE;
+   jcr->session_opened = true;
    jcr->JobType = JT_RESTORE;
 
    /* Send "Ticket" to File Daemon */
@@ -380,6 +375,6 @@ static bool read_close_session(JCR *jcr)
 
    bnet_sig(fd, BNET_EOD);         /* send EOD to File daemon */
 
-   jcr->session_opened = FALSE;
+   jcr->session_opened = false;
    return true;
 }
index 1be408cfeb4e44df096496f779c3c9d1bbc84ff4..660d6adb9a8cd6d61f0dc2fb19ec2726f17da0f4 100644 (file)
@@ -42,8 +42,10 @@ static bool use_device_cmd(JCR *jcr);
 static char jobcmd[] = "JobId=%d job=%127s job_name=%127s client_name=%127s "
       "type=%d level=%d FileSet=%127s NoAttr=%d SpoolAttr=%d FileSetMD5=%127s "
       "SpoolData=%d  WritePartAfterJob=%d";
-static char use_device[]  = "use device=%127s media_type=%127s pool_name=%127s pool_type=%127s\n";
-static char use_devices[] = "use devices=%127s media_type=%127s pool_name=%127s pool_type=%127s\n";
+static char use_device[]  = "use device=%127s media_type=%127s "
+   "pool_name=%127s pool_type=%127s append=%d";
+static char query_device[] = "query device=%127s";
+
 
 /* Responses sent to Director daemon */
 static char OKjob[]     = "3000 OK Job SDid=%u SDtime=%u Authorization=%s\n";
@@ -51,6 +53,10 @@ static char OK_device[] = "3000 OK use device\n";
 static char NO_device[] = "3914 Device \"%s\" not in SD Device resources.\n";
 static char BAD_use[]   = "3913 Bad use command: %s\n";
 static char BAD_job[]   = "3915 Bad Job command: %s\n";
+static char OK_query[]  = "3001 OK query append=%d read=%d num_writers=%d "
+   "num_waiting=%d open=%d use_count=%d labeled=%d "
+   "media_type=%s volume_name=%s";
+static char BAD_query[]   = "3917 Bad query command: %s\n";
 
 /*
  * Director requests us to start a job
@@ -64,14 +70,11 @@ static char BAD_job[]   = "3915 Bad Job command: %s\n";
  */
 bool job_cmd(JCR *jcr)
 {
-   int JobId, errstat;
+   int JobId;
    char auth_key[100];
    BSOCK *dir = jcr->dir_bsock;
    POOL_MEM job_name, client_name, job, fileset_name, fileset_md5;
    int JobType, level, spool_attributes, no_attributes, spool_data, write_part_after_job;
-   struct timeval tv;
-   struct timezone tz;
-   struct timespec timeout;
    JCR *ojcr;
 
    /*
@@ -130,7 +133,11 @@ bool job_cmd(JCR *jcr)
    Dmsg1(110, ">dird: %s", dir->msg);
    jcr->sd_auth_key = bstrdup(auth_key);
    memset(auth_key, 0, sizeof(auth_key));
+   return true;
+}
 
+bool use_cmd(JCR *jcr) 
+{
    /*
     * Wait for the device, media, and pool information
     */
@@ -139,6 +146,15 @@ bool job_cmd(JCR *jcr)
       memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
       return false;
    }
+   return true;
+}
+
+bool run_cmd(JCR *jcr)
+{
+   struct timeval tv;
+   struct timezone tz;
+   struct timespec timeout;
+   int errstat;
 
    /* The following jobs don't need the FD */
    switch (jcr->JobType) {
@@ -243,81 +259,131 @@ static bool use_device_cmd(JCR *jcr)
    POOL_MEM dev_name, media_type, pool_name, pool_type;
    BSOCK *dir = jcr->dir_bsock;
    DEVRES *device;
-   bool quit = false;
-
-   while (!quit) {
-      bool ok;
-      if (bnet_recv(dir) <= 0) {
-         Jmsg0(jcr, M_FATAL, 0, _("No Device from Director\n"));
-        return false;
-      }
+   int append;
+   bool ok;
 
-      Dmsg1(120, "Use device: %s", dir->msg);
-      /*
-       * If there are multiple devices, the director sends us
-       *   use_devices (note plurel) until the last one, at which
-       *   time, it sends us a use_device command (note singlular)
-       *   so we stop looking after getting the use_device.
-       */
-      ok = sscanf(dir->msg, use_device, dev_name.c_str(), media_type.c_str(),
-                 pool_name.c_str(), pool_type.c_str()) == 4;
-      if (ok) {
-        quit = true;                 /* got last device */
-      } else {
-        ok = sscanf(dir->msg, use_devices, dev_name.c_str(), media_type.c_str(),
-                    pool_name.c_str(), pool_type.c_str()) == 4;
-      }
-      if (ok) {
-        unbash_spaces(dev_name);
-        unbash_spaces(media_type);
-        unbash_spaces(pool_name);
-        unbash_spaces(pool_type);
-        LockRes();
-        foreach_res(device, R_DEVICE) {
-           /* Find resource, and make sure we were able to open it */
-           if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0 &&
-               device->dev && strcmp(device->media_type, media_type.c_str()) == 0) {
-              const int name_len = MAX_NAME_LENGTH;
-              DCR *dcr;
-              UnlockRes();
-              dcr = new_dcr(jcr, device->dev);
-              if (!dcr) {
-                 return false;
-              }
-               Dmsg1(120, "Found device %s\n", device->hdr.name);
-              bstrncpy(dcr->pool_name, pool_name, name_len);
-              bstrncpy(dcr->pool_type, pool_type, name_len);
-              bstrncpy(dcr->media_type, media_type, name_len);
-              bstrncpy(dcr->dev_name, dev_name, name_len);
-              jcr->device = device;
-               Dmsg1(220, "Got: %s", dir->msg);
-              return bnet_fsend(dir, OK_device);
+   Dmsg1(120, "Use device: %s", dir->msg);
+   /*
+    * If there are multiple devices, the director sends us
+    *  use_device for each device that it wants to use.
+    */
+   ok = sscanf(dir->msg, use_device, dev_name.c_str(), media_type.c_str(),
+              pool_name.c_str(), pool_type.c_str(), &append) == 5;
+   if (ok) {
+      unbash_spaces(dev_name);
+      unbash_spaces(media_type);
+      unbash_spaces(pool_name);
+      unbash_spaces(pool_type);
+      LockRes();
+      foreach_res(device, R_DEVICE) {
+        /* Find resource, and make sure we were able to open it */
+        if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0 &&
+            device->dev && strcmp(device->media_type, media_type.c_str()) == 0) {
+           const int name_len = MAX_NAME_LENGTH;
+           DCR *dcr = new_dcr(jcr, device->dev);
+           UnlockRes();
+            Dmsg1(120, "Found device %s\n", device->hdr.name);
+           bstrncpy(dcr->pool_name, pool_name, name_len);
+           bstrncpy(dcr->pool_type, pool_type, name_len);
+           bstrncpy(dcr->media_type, media_type, name_len);
+           bstrncpy(dcr->dev_name, dev_name, name_len);
+           jcr->dcr = dcr;
+           if (!dcr) {
+               bnet_fsend(dir, _("Could not get dcr for device: %s\n"), dev_name.c_str());
+              return false;
            }
+           if (append == SD_APPEND) {
+              ok = reserve_device_for_append(jcr, device->dev);
+           } else {
+              ok = reserve_device_for_read(jcr, device->dev);
+           }
+           if (!ok) {
+               bnet_fsend(dir, _("Could not get dcr for device: %s\n"), dev_name.c_str());
+              free_dcr(jcr->dcr);
+              return false;
+           }
+            Dmsg1(220, "Got: %s", dir->msg);
+           return bnet_fsend(dir, OK_device);
         }
-        UnlockRes();
-        if (verbose) {
-           unbash_spaces(dir->msg);
-           pm_strcpy(jcr->errmsg, dir->msg);
-            Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
-        }
-         Jmsg(jcr, M_FATAL, 0, _("\n"
-            "     Device \"%s\" with MediaType \"%s\" requested by Dir not found in SD Device resources.\n"),
-             dev_name.c_str(), media_type.c_str());
-        bnet_fsend(dir, NO_device, dev_name.c_str());
-      } else {
+      }
+      UnlockRes();
+      if (verbose) {
         unbash_spaces(dir->msg);
         pm_strcpy(jcr->errmsg, dir->msg);
-        if (verbose) {
-            Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
-        }
-         Jmsg(jcr, M_FATAL, 0, _("Bad Use Device command: %s\n"), jcr->errmsg);
-        bnet_fsend(dir, BAD_use, jcr->errmsg);
+         Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
       }
+      Jmsg(jcr, M_FATAL, 0, _("\n"
+         "     Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
+          dev_name.c_str(), media_type.c_str());
+      bnet_fsend(dir, NO_device, dev_name.c_str());
+   } else {
+      unbash_spaces(dir->msg);
+      pm_strcpy(jcr->errmsg, dir->msg);
+      if (verbose) {
+         Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
+      }
+      Jmsg(jcr, M_FATAL, 0, _("Bad Use Device command: %s\n"), jcr->errmsg);
+      bnet_fsend(dir, BAD_use, jcr->errmsg);
    }
 
    return false;                     /* ERROR return */
 }
 
+/*
+ *   Query Device command from Director
+ *   Sends Storage Daemon's information on the device to the
+ *    caller (presumably the Director).
+ *   This command always returns "true" so that the line is
+ *    not closed on an error.
+ *
+ */
+bool query_cmd(JCR *jcr)
+{
+   POOL_MEM dev_name;
+   BSOCK *dir = jcr->dir_bsock;
+   DEVRES *device;
+   bool ok;
+
+   Dmsg1(120, "Query: %s", dir->msg);
+
+   ok = sscanf(dir->msg, query_device, dev_name.c_str()) == 1;
+   if (ok) {
+      unbash_spaces(dev_name);
+      LockRes();
+      foreach_res(device, R_DEVICE) {
+        /* Find resource, and make sure we were able to open it */
+        if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0 &&
+            device->dev) {
+           DEVICE *dev = device->dev;
+           POOL_MEM VolumeName, MediaType;
+           UnlockRes();
+           if (dev->is_labeled()) {
+              pm_strcpy(VolumeName, dev->VolHdr.VolName);
+           } else {
+               pm_strcpy(VolumeName, "");
+           }
+           bash_spaces(VolumeName);
+           pm_strcpy(MediaType, device->media_type);
+           bash_spaces(MediaType);
+           return bnet_fsend(dir, OK_query, dev->can_append()!=0,
+              dev->can_read()!=0, dev->num_writers, dev->num_waiting,
+              dev->is_open()!=0, dev->use_count, dev->is_labeled()!=0,
+              MediaType.c_str(), VolumeName.c_str());
+        }
+      }
+      UnlockRes();
+      unbash_spaces(dir->msg);
+      pm_strcpy(jcr->errmsg, dir->msg);
+      bnet_fsend(dir, NO_device, dev_name.c_str());
+   } else {
+      unbash_spaces(dir->msg);
+      pm_strcpy(jcr->errmsg, dir->msg);
+      bnet_fsend(dir, BAD_query, jcr->errmsg);
+   }
+   return true;
+}
+
+
 /*
  * Destroy the Job Control Record and associated
  * resources (sockets).
index 9b5e03aba2265b660722cb6c488fcc997d0d51ab..7e10a4b7194e608eaf882e650f7b3a0e4473c336 100644 (file)
@@ -32,6 +32,8 @@
 
 /* Forward referenced functions */
 static void create_volume_label_record(DCR *dcr, DEV_RECORD *rec);
+static int read_ansi_ibm_label(DCR *dcr);
+static char *ansi_date(time_t td, char *buf);
 
 extern char my_name[];
 extern int debug_level;
@@ -68,7 +70,10 @@ int read_dev_volume_label(DCR *dcr)
    Dmsg3(100, "Enter read_volume_label device=%s vol=%s dev_Vol=%s\n",
       dev_name(dev), VolName, dev->VolHdr.VolName);
 
-   if (dev_state(dev, ST_LABEL)) {      /* did we already read label? */
+   if (!dev->is_open()) {
+      Emsg0(M_ABORT, 0, _("BAD call to read_dev_volume_label\n"));
+   }
+   if (dev->is_labeled()) {             /* did we already read label? */
       /* Compare Volume Names allow special wild card */
       if (VolName && *VolName && *VolName != '*' && strcmp(dev->VolHdr.VolName, VolName) != 0) {
          Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"),
@@ -95,6 +100,12 @@ int read_dev_volume_label(DCR *dcr)
       return VOL_NO_MEDIA;
    }
    bstrncpy(dev->VolHdr.Id, "**error**", sizeof(dev->VolHdr.Id));
+
+  /* Read ANSI/IBM label if so requested */
+  int stat = read_ansi_ibm_label(dcr);           
+  if (stat != VOL_OK) {
+      return stat;
+   }
   
    /* Read the Volume label block */
    record = new_record();
@@ -190,12 +201,15 @@ int read_dev_volume_label(DCR *dcr)
  *  Writing : returns the label of the current file (on the harddisk).
  *  Reading : returns an error
  */
-int read_dev_volume_label_guess(DCR *dcr, bool write) {
+int read_dev_volume_label_guess(DCR *dcr, bool write) 
+{
    int vol_label_status;
+   DEVICE *dev = dcr->dev;
+   JCR *jcr = dcr->jcr;
    Dmsg3(100, "Enter read_dev_volume_label_guess device=%s vol=%s dev_Vol=%s\n",
-        dev_name(dcr->dev), dcr->VolumeName, dcr->dev->VolHdr.VolName);
+        dev_name(dev), dcr->VolumeName, dev->VolHdr.VolName);
    
-   if (!dev_cap(dcr->dev, CAP_REQMOUNT)) {
+   if (!dev->is_dvd()) {
       Dmsg0(100, "Leave read_dev_volume_label_guess !CAP_REQMOUNT\n");
       return read_dev_volume_label(dcr);
    }
@@ -207,38 +221,37 @@ int read_dev_volume_label_guess(DCR *dcr, bool write) {
    
    /* For mounted devices, tries to guess the volume name, and read the label if possible.
    */
-   if (open_guess_name_dev(dcr->dev) < 0) {    
+   if (open_guess_name_dev(dev) < 0) {    
       if ((!write) || (dcr->VolCatInfo.VolCatParts > 0)) {
-         Mmsg2(dcr->jcr->errmsg, _("Requested Volume \"%s\" on %s is not a Bacula labeled Volume."),
-              dev_name(dcr->dev), dcr->VolumeName);
+         Mmsg2(jcr->errmsg, _("Requested Volume \"%s\" on %s is not a Bacula labeled Volume."),
+              dev_name(dev), dcr->VolumeName);
          Dmsg0(100, "Leave read_dev_volume_label_guess VOL_IO_ERROR (!open_guess_name_dev)\n");
         return VOL_NO_LABEL;
       }
       
-      if (write && (dcr->dev->free_space_errno < 0)) {
+      if (write && (dev->free_space_errno < 0)) {
          Dmsg0(100, "Leave read_dev_volume_label_guess !free_space VOL_NO_MEDIA\n");
-         Mmsg2(dcr->jcr->errmsg, _("free_space error on %s. The current medium is probably not writable. ERR=%s.\n"),
-              dcr->dev->dev_name, dcr->dev->errmsg);
+         Mmsg2(jcr->errmsg, _("free_space error on %s. The current medium is probably not writable. ERR=%s.\n"),
+              dev->dev_name, dev->errmsg);
         return VOL_NO_MEDIA;
       }
       
       /* If we can't guess the name, and we are writing, just reopen the right file with open_first_part. */
-      if (open_first_part(dcr->dev) < 0) {
+      if (open_first_part(dev) < 0) {
         berrno be;
-         Mmsg2(dcr->jcr->errmsg, _("open_first_part error on %s. ERR=%s.\n"),
-              dcr->dev->dev_name, be.strerror());
+         Mmsg2(jcr->errmsg, _("open_first_part error on %s. ERR=%s.\n"),
+              dev->dev_name, be.strerror());
          Dmsg0(100, "Leave read_dev_volume_label_guess VOL_IO_ERROR (!open_guess_name_dev && !open_first_part)\n");
         return VOL_IO_ERROR;
       }
       
       Dmsg0(100, "Leave read_dev_volume_label_guess !open_guess_name_dev\n");
       return read_dev_volume_label(dcr);
-   }
-   else {
+   } else {
       if (write && (dcr->dev->free_space_errno < 0)) {
          Dmsg0(100, "Leave read_dev_volume_label_guess !free_space VOL_NO_MEDIA\n");
-         Mmsg2(dcr->jcr->errmsg, _("free_space error on %s. The current medium is probably not writable. ERR=%s.\n"),
-              dcr->dev->dev_name, dcr->dev->errmsg);
+         Mmsg2(jcr->errmsg, _("free_space error on %s. The current medium is probably not writable. ERR=%s.\n"),
+              dev->dev_name, dev->errmsg);
         return VOL_NO_MEDIA;
       }
       
@@ -251,8 +264,8 @@ int read_dev_volume_label_guess(DCR *dcr, bool write) {
       
       if (open_first_part(dcr->dev) < 0) {
         berrno be;
-         Mmsg2(dcr->jcr->errmsg, _("open_first_part error on %s. ERR=%s.\n"),
-              dcr->dev->dev_name, be.strerror());
+         Mmsg2(jcr->errmsg, _("open_first_part error on %s. ERR=%s.\n"),
+              dev->dev_name, be.strerror());
          Dmsg0(100, "Leave read_dev_volume_label_guess VOL_IO_ERROR (open_guess_name_dev && !open_first_part)\n");
         return VOL_IO_ERROR;
       }
@@ -262,7 +275,7 @@ int read_dev_volume_label_guess(DCR *dcr, bool write) {
        */
       if (vol_label_status != VOL_NAME_ERROR) {
          Dmsg0(100, "Leave read_dev_volume_label_guess (open_guess_name_dev && !VOL_NAME_ERROR)\n");
-        dcr->dev->state &= ~ST_LABEL;
+        dev->state &= ~ST_LABEL;
         return read_dev_volume_label(dcr);
       }
       else {
@@ -274,7 +287,7 @@ int read_dev_volume_label_guess(DCR *dcr, bool write) {
 
 /*  unser_volume_label
  *
- * Unserialize the Volume label into the device Volume_Label
+ * Unserialize the Bacula Volume label into the device Volume_Label
  * structure.
  *
  * Assumes that the record is already read.
@@ -497,6 +510,11 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *Po
       }
    }
 
+   /* Write ANSI/IBM label if so requested */
+   if (!write_ansi_ibm_label(dcr, VolName)) {
+      goto bail_out;
+   }
+
    create_volume_label_record(dcr, dcr->rec);
    dcr->rec->Stream = 0;
 
@@ -674,30 +692,29 @@ void dump_volume_label(DEVICE *dev)
    debug_level = 1;
    File = dev->file;
    switch (dev->VolHdr.LabelType) {
-      case PRE_LABEL:
-         LabelType = "PRE_LABEL";
-        break;
-      case VOL_LABEL:
-         LabelType = "VOL_LABEL";
-        break;
-      case EOM_LABEL:
-         LabelType = "EOM_LABEL";
-        break;
-      case SOS_LABEL:
-         LabelType = "SOS_LABEL";
-        break;
-      case EOS_LABEL:
-         LabelType = "EOS_LABEL";
-        break;
-      case EOT_LABEL:
-        goto bail_out;
-      default:
-        LabelType = buf;
-         sprintf(buf, "Unknown %d", dev->VolHdr.LabelType);
-        break;
+   case PRE_LABEL:
+      LabelType = "PRE_LABEL";
+      break;
+   case VOL_LABEL:
+      LabelType = "VOL_LABEL";
+      break;
+   case EOM_LABEL:
+      LabelType = "EOM_LABEL";
+      break;
+   case SOS_LABEL:
+      LabelType = "SOS_LABEL";
+      break;
+   case EOS_LABEL:
+      LabelType = "EOS_LABEL";
+      break;
+   case EOT_LABEL:
+      goto bail_out;
+   default:
+      LabelType = buf;
+      sprintf(buf, "Unknown %d", dev->VolHdr.LabelType);
+      break;
    }
 
-
    Pmsg11(-1, "\nVolume Label:\n"
 "Id                : %s"
 "VerNo             : %d\n"
@@ -937,3 +954,152 @@ void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose)
    }
    debug_level = dbl;
 }
+
+/*
+ * Write an ANSI or IBM 80 character tape label
+ *   Assume we are positioned at the beginning of the tape.
+ *   Returns:  true of OK
+ *            false if error
+ */
+bool write_ansi_ibm_label(DCR *dcr, const char *VolName)
+{
+   DEVICE *dev = dcr->dev;
+   JCR *jcr = dcr->jcr;
+   char label[80];                   /* tape label */
+   char date[20];                    /* ansi date buffer */
+   time_t now;
+   int len;
+   int stat;
+
+   switch (dcr->VolCatInfo.LabelType) {
+   case B_BACULA_LABEL:
+      return true;
+   case B_ANSI_LABEL:
+   case B_IBM_LABEL:
+      ser_declare;
+      Dmsg0(000, "Write ansi label.\n");
+      len = strlen(VolName);
+      if (len > 6) {
+        len = 6;                        /* max len ANSI label */
+      }
+      memset(label, ' ', sizeof(label));
+      ser_begin(label, sizeof(label));
+      ser_bytes("VOL1", 4);
+      ser_bytes(VolName, len);
+      label[79] = '1';                /* ANSI label flag */
+      /* Write VOL1 label */
+      stat = write(dev->fd, label, sizeof(label));
+      if (stat != sizeof(label)) {
+        berrno be;
+         Jmsg1(jcr, M_FATAL, 0,  _("Could not write ANSI VOL1 label. ERR=%s\n"),
+           be.strerror());
+        return false;
+      }
+      /* Now construct HDR1 label */
+      ser_begin(label, sizeof(label));
+      ser_bytes("HDR1", 4);
+      len = strlen(VolName);
+      if (len > 17) {
+        len = 17;                    /* Max filename len */
+      }
+      ser_bytes(VolName, len);       /* stick Volume name in Filename field */
+      if (len > 6) {
+        len = 6;
+      }
+      ser_begin(&label[21], sizeof(label)-21);
+      ser_bytes(VolName, len);       /* write Vol Ser No. */
+      ser_begin(&label[27], sizeof(label)-27);
+      ser_bytes("000100010001", 12);  /* File section, File seq no, Generation no */
+      now = time(NULL);
+      ser_bytes(ansi_date(now, date), 6); /* current date */
+      ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */
+      ser_bytes(" 000000BACULA              ", 27);
+      /* Write HDR1 label */
+      stat = write(dev->fd, label, sizeof(label));
+      if (stat != sizeof(label)) {
+        berrno be;
+         Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
+           be.strerror());
+        return false;
+      }
+      /* Now construct HDR2 label */
+      memset(label, ' ', sizeof(label));
+      ser_begin(label, sizeof(label));
+      ser_bytes("HDR2F3200032000", 15);
+      /* Write HDR1 label */
+      stat = write(dev->fd, label, sizeof(label));
+      if (stat != sizeof(label)) {
+        berrno be;
+         Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
+           be.strerror());
+        return false;
+      }
+      if (weof_dev(dev, 1) < 0) {
+         Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
+        return false;
+      }
+      return true;
+   default:
+      Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
+      return false; /* should not get here */
+   }
+}
+
+static int read_ansi_ibm_label(DCR *dcr) 
+{
+   DEVICE *dev = dcr->dev;
+   JCR *jcr = dcr->jcr;
+   char label[80];                   /* tape label */
+   int retry, stat, i, num_rec;
+
+   if (dcr->VolCatInfo.LabelType == B_BACULA_LABEL) {
+      return VOL_OK;
+   }
+   /*
+    * Read VOL1, HDR1, HDR2 labels, but ignore the data
+    *  If tape read the following EOF mark, on disk do
+    *  not read.
+    */
+   Dmsg0(000, "Read ansi label.\n");
+   if (dev->state & ST_TAPE) {
+      num_rec = 4;
+   } else {
+      num_rec = 3;
+   }
+   for (i=0; i < num_rec; i++) {
+      retry = 0;
+      do {
+        stat = read(dev->fd, label, sizeof(label));
+        if (retry == 1) {
+           dev->VolCatInfo.VolCatErrors++;
+        }
+      } while (stat == -1 && (errno == EINTR || errno == EIO) && retry++ < 11);
+      if (stat < 0) {
+        berrno be;
+        clrerror_dev(dev, -1);
+         Dmsg1(200, "Read device got: ERR=%s\n", be.strerror());
+         Mmsg2(dev->errmsg, _("Read error on device %s in ANSI/IBM label. ERR=%s\n"),
+           dev->dev_name, be.strerror());
+         Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
+        if (dev->state & ST_EOF) {  /* EOF just seen? */
+           dev->state |= ST_EOT;    /* yes, error => EOT */
+        }
+        return VOL_IO_ERROR;
+      }
+      Dmsg1(000, "ANSI label=%80s\n", label);
+   }
+   return VOL_OK;
+}  
+
+
+static char *ansi_date(time_t td, char *buf)
+{
+   struct tm *tm;
+
+   if (td == 0) {
+      td = time(NULL);
+   }
+   tm = gmtime(&td);
+   bsnprintf(buf, 6, "%d", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday);
+   return buf;
+}
index 4b58a57aab6cd6effd64958d4a689a72ae8ed60a..fb6103eeebb4761026f58e8dba507b8f435e4540 100644 (file)
@@ -156,23 +156,24 @@ mount_next_vol:
    }
 
    /* Ensure the device is open */
-   /* If we have a device that requires mount, we first want to guess
-    * which device is loaded, so we continue (if the wrong device is
+   /* If we have a dvd that requires mount, we first want to guess
+    * which Volume is loaded, so we continue (if the wrong device is
     * loaded, open_device would fail). */
-   if (!dev_cap(dev, CAP_REQMOUNT)) {
+   if (!dev->is_dvd()) {
       if (!open_device(dcr)) {
         if (dev->poll) {
            goto mount_next_vol;
-        } 
-        else {
+        } else {
            return false;
         }
       }
-   }
-   else {
-      /* Just copy the VolCatName in the device resource (usually done by open_dev).
-       * It is necessary so we can open the real files later. */
-      bstrncpy(dcr->dev->VolCatInfo.VolCatName, dcr->VolCatInfo.VolCatName, sizeof(dcr->dev->VolCatInfo.VolCatName));
+   } else {
+      /*
+       * Just copy the VolCatName in the device resource 
+       *   (usually done by open_dev).
+       * It is necessary so we can open the real files later.  
+       */
+      bstrncpy(dev->VolCatInfo.VolCatName, dcr->VolCatInfo.VolCatName, sizeof(dev->VolCatInfo.VolCatName));
    }
 
    /*
@@ -187,10 +188,9 @@ read_volume:
       vol_label_status = VOL_OK;
       create_volume_label(dev, dcr->VolumeName, "Default");
       dev->VolHdr.LabelType = PRE_LABEL;
-   } else if (dev_cap(dev, CAP_REQMOUNT)) {
+   } else if (dev->is_dvd()) {
       vol_label_status = read_dev_volume_label_guess(dcr, 1);
-   }
-   else {
+   } else {
       vol_label_status = read_dev_volume_label(dcr);
    }
    if (job_canceled(jcr)) {
@@ -410,6 +410,9 @@ static bool rewrite_volume_label(DCR *dcr, bool recycle)
       }
       /* Attempt write to check write permission */
       Dmsg0(200, "Attempt to write to device.\n");
+      if (!write_ansi_ibm_label(dcr, dev->VolHdr.VolName)) {
+        return false;
+      }
       if (!write_block_to_dev(dcr)) {
          Jmsg2(jcr, M_ERROR, 0, _("Unable to write device \"%s\". ERR=%s\n"),
            dev_name(dev), strerror_dev(dev));
@@ -482,7 +485,7 @@ bool mount_next_read_volume(DCR *dcr)
    if (jcr->NumVolumes > 1 && jcr->CurVolume < jcr->NumVolumes) {
       close_dev(dev);
       dev->state &= ~ST_READ;
-      if (!acquire_device_for_read(jcr)) {
+      if (!acquire_device_for_read(jcr, dev)) {
          Jmsg2(jcr, M_FATAL, 0, "Cannot open Dev=%s, Vol=%s\n", dev_name(dev),
               dcr->VolumeName);
         return false;
@@ -517,14 +520,13 @@ void release_volume(DCR *dcr)
    dev->state &= ~(ST_LABEL|ST_READ|ST_APPEND);
    dcr->VolumeName[0] = 0;
 
-   if ((dev->state & ST_OPENED) &&
-       (!dev_is_tape(dev) || !dev_cap(dev, CAP_ALWAYSOPEN))) {
+   if (dev->is_open() && (!dev->is_tape() || !dev_cap(dev, CAP_ALWAYSOPEN))) {
       offline_or_rewind_dev(dev);
       close_dev(dev);
    }
 
    /* If we have not closed the device, then at least rewind the tape */
-   if (dev->state & ST_OPENED) {
+   if (dev->is_open()) {
       offline_or_rewind_dev(dev);
    }
    Dmsg0(190, "===== release_volume ---");
index b9a2e0e44b6769a1e904dc791984a978a5ca79fc..a1fbc6ba0751d9aadeef403cccec3262554ee807 100755 (executable)
@@ -7,7 +7,7 @@
  */
 
 /*
-   Copyright (C) 2002 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
@@ -32,6 +32,7 @@
 typedef BSR * (ITEM_HANDLER)(LEX *lc, BSR *bsr);
 
 static BSR *store_vol(LEX *lc, BSR *bsr);
+static BSR *store_mediatype(LEX *lc, BSR *bsr);
 static BSR *store_client(LEX *lc, BSR *bsr);
 static BSR *store_job(LEX *lc, BSR *bsr);
 static BSR *store_jobid(LEX *lc, BSR *bsr);
@@ -60,6 +61,7 @@ struct kw_items {
  */
 struct kw_items items[] = {
    {"volume", store_vol},
+   {"mediatype", store_mediatype},
    {"client", store_client},
    {"job", store_job},
    {"jobid", store_jobid},
@@ -137,13 +139,13 @@ BSR *parse_bsr(JCR *jcr, char *fname)
       for (i=0; items[i].name; i++) {
         if (strcasecmp(items[i].name, lc->str) == 0) {
            token = lex_get_token(lc, T_ALL);
-           Dmsg1 (200, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
+            Dmsg1 (200, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
            if (token != T_EQUALS) {
-              scan_err1(lc, "expected an equals, got: %s", lc->str);
+               scan_err1(lc, "expected an equals, got: %s", lc->str);
               bsr = NULL;
               break;
            }
-           Dmsg1(200, "calling handler for %s\n", items[i].name);
+            Dmsg1(200, "calling handler for %s\n", items[i].name);
            /* Call item handler */
            bsr = items[i].handler(lc, bsr);
            i = -1;
@@ -151,8 +153,8 @@ BSR *parse_bsr(JCR *jcr, char *fname)
         }
       }
       if (i >= 0) {
-        Dmsg1(200, "Keyword = %s\n", lc->str);
-        scan_err1(lc, "Keyword %s not found", lc->str);
+         Dmsg1(200, "Keyword = %s\n", lc->str);
+         scan_err1(lc, "Keyword %s not found", lc->str);
         bsr = NULL;
         break;
       }
@@ -247,6 +249,28 @@ static BSR *store_vol(LEX *lc, BSR *bsr)
    return bsr;
 }
 
+/* Shove the MediaType in each Volume in the current bsr */
+static BSR *store_mediatype(LEX *lc, BSR *bsr)
+{
+   int token;
+
+   token = lex_get_token(lc, T_STRING);
+   if (token == T_ERROR) {
+      return NULL;
+   }
+   if (!bsr->volume) {
+      Emsg1(M_ERROR,0, _("MediaType %s in bsr at inappropriate place.\n"),
+        lc->str);
+      return bsr;
+   }
+   BSR_VOLUME *bv;
+   for (bv=bsr->volume; bv; bv=bv->next) {
+      bstrncpy(bv->MediaType, lc->str, sizeof(bv->MediaType));
+   }
+   return bsr;
+}
+
+
 static BSR *store_client(LEX *lc, BSR *bsr)
 {
    int token;
@@ -619,9 +643,9 @@ void dump_findex(BSR_FINDEX *FileIndex)
 {
    if (FileIndex) {
       if (FileIndex->findex == FileIndex->findex2) {
-        Dmsg1(-1, "FileIndex   : %u\n", FileIndex->findex);
+         Dmsg1(-1, "FileIndex   : %u\n", FileIndex->findex);
       } else {
-        Dmsg2(-1, "FileIndex   : %u-%u\n", FileIndex->findex, FileIndex->findex2);
+         Dmsg2(-1, "FileIndex   : %u-%u\n", FileIndex->findex, FileIndex->findex2);
       }
       dump_findex(FileIndex->next);
    }
@@ -631,9 +655,9 @@ void dump_jobid(BSR_JOBID *jobid)
 {
    if (jobid) {
       if (jobid->JobId == jobid->JobId2) {
-        Dmsg1(-1, "JobId       : %u\n", jobid->JobId);
+         Dmsg1(-1, "JobId       : %u\n", jobid->JobId);
       } else {
-        Dmsg2(-1, "JobId       : %u-%u\n", jobid->JobId, jobid->JobId2);
+         Dmsg2(-1, "JobId       : %u-%u\n", jobid->JobId, jobid->JobId2);
       }
       dump_jobid(jobid->next);
    }
@@ -643,9 +667,9 @@ void dump_sessid(BSR_SESSID *sessid)
 {
    if (sessid) {
       if (sessid->sessid == sessid->sessid2) {
-        Dmsg1(-1, "SessId      : %u\n", sessid->sessid);
+         Dmsg1(-1, "SessId      : %u\n", sessid->sessid);
       } else {
-        Dmsg2(-1, "SessId      : %u-%u\n", sessid->sessid, sessid->sessid2);
+         Dmsg2(-1, "SessId      : %u-%u\n", sessid->sessid, sessid->sessid2);
       }
       dump_sessid(sessid->next);
    }
@@ -852,12 +876,14 @@ void create_vol_list(JCR *jcr)
         for (bsrvol = bsr->volume; bsrvol; bsrvol=bsrvol->next) {
            vol = new_vol();
            bstrncpy(vol->VolumeName, bsrvol->VolumeName, sizeof(vol->VolumeName));
+           bstrncpy(vol->MediaType,  bsrvol->MediaType,  sizeof(vol->MediaType));
            vol->start_file = sfile;
            if (add_vol(jcr, vol)) {
               jcr->NumVolumes++;
-              Dmsg1(400, "Added volume %s\n", vol->VolumeName);
+               Dmsg2(400, "Added volume=%s mediatype=%s\n", vol->VolumeName,
+                 vol->MediaType);
            } else {
-              Dmsg1(400, "Duplicate volume %s\n", vol->VolumeName);
+               Dmsg1(400, "Duplicate volume %s\n", vol->VolumeName);
               free((char *)vol);
            }
            sfile = 0;                /* start at beginning of second volume */
@@ -866,12 +892,13 @@ void create_vol_list(JCR *jcr)
    } else {
       /* This is the old way -- deprecated */
       for (p = jcr->dcr->VolumeName; p && *p; ) {
-        n = strchr(p, '|');             /* volume name separator */
+         n = strchr(p, '|');             /* volume name separator */
         if (n) {
            *n++ = 0;                    /* Terminate name */
         }
         vol = new_vol();
         bstrncpy(vol->VolumeName, p, sizeof(vol->VolumeName));
+        bstrncpy(vol->MediaType, jcr->dcr->media_type, sizeof(vol->MediaType));
         if (add_vol(jcr, vol)) {
            jcr->NumVolumes++;
         } else {
index dc3e1eda071a7a2961cb13d6d835ddff001d5366..f5ab5defe5521a9656e3b3c6347a3799730e38d6 100644 (file)
 uint32_t new_VolSessionId();
 
 /* From acquire.c */
-DCR    *acquire_device_for_append(JCR *jcr);
-DCR    *acquire_device_for_read(JCR *jcr);
-bool    release_device(JCR *jcr);
-DCR    *new_dcr(JCR *jcr, DEVICE *dev);
-void    free_dcr(DCR *dcr);
+bool     reserve_device_for_append(JCR *jcr, DEVICE *dev);
+DCR     *acquire_device_for_append(JCR *jcr, DEVICE *dev);
+bool     reserve_device_for_read(JCR *jcr, DEVICE *dev);
+DCR     *acquire_device_for_read(JCR *jcr, DEVICE *dev);
+bool     release_device(JCR *jcr);
+DCR     *new_dcr(JCR *jcr, DEVICE *dev);
+void     free_dcr(DCR *dcr);
 
 /* From askdir.c */
 enum get_vol_info_rw {
    GET_VOL_INFO_FOR_WRITE,
    GET_VOL_INFO_FOR_READ
 };
-bool   dir_get_volume_info(DCR *dcr, enum get_vol_info_rw);
-bool   dir_find_next_appendable_volume(DCR *dcr);
-bool   dir_update_volume_info(DCR *dcr, bool label);
-bool   dir_ask_sysop_to_create_appendable_volume(DCR *dcr);
-bool   dir_ask_sysop_to_mount_volume(DCR *dcr);
-bool   dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec);
-bool   dir_send_job_status(JCR *jcr);
-bool   dir_create_jobmedia_record(DCR *dcr);
+bool    dir_get_volume_info(DCR *dcr, enum get_vol_info_rw);
+bool    dir_find_next_appendable_volume(DCR *dcr);
+bool    dir_update_volume_info(DCR *dcr, bool label);
+bool    dir_ask_sysop_to_create_appendable_volume(DCR *dcr);
+bool    dir_ask_sysop_to_mount_volume(DCR *dcr);
+bool    dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec);
+bool    dir_send_job_status(JCR *jcr);
+bool    dir_create_jobmedia_record(DCR *dcr);
 
 /* authenticate.c */
-int    authenticate_director(JCR *jcr);
-int    authenticate_filed(JCR *jcr);
+int     authenticate_director(JCR *jcr);
+int     authenticate_filed(JCR *jcr);
 
 /* From autochanger.c */
-int     autoload_device(DCR *dcr, int writing, BSOCK *dir);
-bool    autochanger_list(DCR *dcr, BSOCK *dir);
-void    invalidate_slot_in_catalog(DCR *dcr);
-char   *edit_device_codes(JCR *jcr, char *omsg, const char *imsg, const char *cmd);
+int      autoload_device(DCR *dcr, int writing, BSOCK *dir);
+bool     autochanger_list(DCR *dcr, BSOCK *dir);
+void     invalidate_slot_in_catalog(DCR *dcr);
+char    *edit_device_codes(DCR *dcr, char *omsg, const char *cmd);
 
 /* From block.c */
-void   dump_block(DEV_BLOCK *b, const char *msg);
+void    dump_block(DEV_BLOCK *b, const char *msg);
 DEV_BLOCK *new_block(DEVICE *dev);
 DEV_BLOCK *dup_block(DEV_BLOCK *eblock);
-void   init_block_write(DEV_BLOCK *block);
-void   empty_block(DEV_BLOCK *block);
-void   free_block(DEV_BLOCK *block);
-bool   write_block_to_device(DCR *dcr);
-bool   write_block_to_dev(DCR *dcr);
-void   print_block_read_errors(JCR *jcr, DEV_BLOCK *block);
-void   ser_block_header(DEV_BLOCK *block);
+void    init_block_write(DEV_BLOCK *block);
+void    empty_block(DEV_BLOCK *block);
+void    free_block(DEV_BLOCK *block);
+bool    write_block_to_device(DCR *dcr);
+bool    write_block_to_dev(DCR *dcr);
+void    print_block_read_errors(JCR *jcr, DEV_BLOCK *block);
+void    ser_block_header(DEV_BLOCK *block);
 
 #define CHECK_BLOCK_NUMBERS    true
 #define NO_BLOCK_NUMBER_CHECK  false
-bool   read_block_from_device(DCR *dcr, bool check_block_numbers);
-bool   read_block_from_dev(DCR *dcr, bool check_block_numbers);
+bool    read_block_from_device(DCR *dcr, bool check_block_numbers);
+bool    read_block_from_dev(DCR *dcr, bool check_block_numbers);
 
 /* From butil.c -- utilities for SD tool programs */
-void   print_ls_output(const char *fname, const char *link, int type, struct stat *statp);
+void    print_ls_output(const char *fname, const char *link, int type, struct stat *statp);
 JCR    *setup_jcr(const char *name, char *dev_name, BSR *bsr,
-                 const char *VolumeName, int mode);
-void   display_tape_error_status(JCR *jcr, DEVICE *dev);
+                  const char *VolumeName, int mode);
+void    display_tape_error_status(JCR *jcr, DEVICE *dev);
 
 
 /* From dev.c */
-DEVICE *init_dev(DEVICE *dev, DEVRES *device);
-int     open_dev(DEVICE *dev, char *VolName, int mode);
-off_t   lseek_dev(DEVICE *dev, off_t offset, int whence);
-int     open_first_part(DEVICE *dev);
-int     open_next_part(DEVICE *dev);
-int     open_guess_name_dev(DEVICE *dev);
-void    close_dev(DEVICE *dev);
-void    force_close_dev(DEVICE *dev);
-bool    truncate_dev(DEVICE *dev);
-void    term_dev(DEVICE *dev);
-char *  strerror_dev(DEVICE *dev);
-void    clrerror_dev(DEVICE *dev, int func);
-bool    update_pos_dev(DEVICE *dev);
-bool    rewind_dev(DEVICE *dev);
-bool    load_dev(DEVICE *dev);
-bool    offline_dev(DEVICE *dev);
-int     flush_dev(DEVICE *dev);
-int     weof_dev(DEVICE *dev, int num);
-int     write_block(DEVICE *dev);
+DEVICE  *init_dev(DEVICE *dev, DEVRES *device);
+int      open_dev(DEVICE *dev, char *VolName, int mode);
+off_t    lseek_dev(DEVICE *dev, off_t offset, int whence);
+int      open_first_part(DEVICE *dev);
+int      open_next_part(DEVICE *dev);
+int      open_guess_name_dev(DEVICE *dev);
+void     close_dev(DEVICE *dev);
+void     force_close_dev(DEVICE *dev);
+bool     truncate_dev(DEVICE *dev);
+void     term_dev(DEVICE *dev);
+char *   strerror_dev(DEVICE *dev);
+void     clrerror_dev(DEVICE *dev, int func);
+bool     update_pos_dev(DEVICE *dev);
+bool     rewind_dev(DEVICE *dev);
+bool     load_dev(DEVICE *dev);
+bool     offline_dev(DEVICE *dev);
+int      flush_dev(DEVICE *dev);
+int      weof_dev(DEVICE *dev, int num);
+int      write_block(DEVICE *dev);
 uint32_t status_dev(DEVICE *dev);
-int     eod_dev(DEVICE *dev);
-bool    fsf_dev(DEVICE *dev, int num);
-bool    fsr_dev(DEVICE *dev, int num);
-bool    bsf_dev(DEVICE *dev, int num);
-bool    bsr_dev(DEVICE *dev, int num);
-void    attach_jcr_to_device(DEVICE *dev, JCR *jcr);
-void    detach_jcr_from_device(DEVICE *dev, JCR *jcr);
-JCR    *next_attached_jcr(DEVICE *dev, JCR *jcr);
-bool    dev_can_write(DEVICE *dev);
-bool    offline_or_rewind_dev(DEVICE *dev);
-bool    reposition_dev(DEVICE *dev, uint32_t file, uint32_t block);
-void    init_dev_wait_timers(DEVICE *dev);
-bool    double_dev_wait_time(DEVICE *dev);
+int      eod_dev(DEVICE *dev);
+bool     fsf_dev(DEVICE *dev, int num);
+bool     fsr_dev(DEVICE *dev, int num);
+bool     bsf_dev(DEVICE *dev, int num);
+bool     bsr_dev(DEVICE *dev, int num);
+void     attach_jcr_to_device(DEVICE *dev, JCR *jcr);
+void     detach_jcr_from_device(DEVICE *dev, JCR *jcr);
+JCR     *next_attached_jcr(DEVICE *dev, JCR *jcr);
+bool     dev_can_write(DEVICE *dev);
+bool     offline_or_rewind_dev(DEVICE *dev);
+bool     reposition_dev(DEVICE *dev, uint32_t file, uint32_t block);
+void     init_dev_wait_timers(DEVICE *dev);
+bool     double_dev_wait_time(DEVICE *dev);
 
 /* Get info about device */
-char *  dev_name(DEVICE *dev);
-char *  dev_vol_name(DEVICE *dev);
+char *   dev_name(DEVICE *dev);
+char *   dev_vol_name(DEVICE *dev);
 uint32_t dev_block(DEVICE *dev);
 uint32_t dev_file(DEVICE *dev);
-bool    dev_is_tape(DEVICE *dev);
+bool     dev_is_tape(DEVICE *dev);
 
 /* From device.c */
-bool    open_device(DCR *dcr);
-bool    first_open_device(DEVICE *dev);
-bool    fixup_device_block_write_error(DCR *dcr);
-void    _lock_device(const char *file, int line, DEVICE *dev);
-void    _unlock_device(const char *file, int line, DEVICE *dev);
-void    _block_device(const char *file, int line, DEVICE *dev, int state);
-void    _unblock_device(const char *file, int line, DEVICE *dev);
-void    _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state);
-void    _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold);
-void    set_new_volume_parameters(DCR *dcr);
-void    set_new_file_parameters(DCR *dcr);
-bool    device_is_unmounted(DEVICE *dev);
-void    dev_lock(DEVICE *dev);
-void    dev_unlock(DEVICE *dev);
+bool     open_device(DCR *dcr);
+bool     first_open_device(DEVICE *dev);
+bool     fixup_device_block_write_error(DCR *dcr);
+void     _lock_device(const char *file, int line, DEVICE *dev);
+void     _unlock_device(const char *file, int line, DEVICE *dev);
+void     _block_device(const char *file, int line, DEVICE *dev, int state);
+void     _unblock_device(const char *file, int line, DEVICE *dev);
+void     _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state);
+void     _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold);
+void     set_new_volume_parameters(DCR *dcr);
+void     set_new_file_parameters(DCR *dcr);
+bool     device_is_unmounted(DEVICE *dev);
+void     dev_lock(DEVICE *dev);
+void     dev_unlock(DEVICE *dev);
 const char *edit_blocked_reason(DEVICE *dev);
 
 /* From dircmd.c */
-void    *handle_connection_request(void *arg);
+void     *handle_connection_request(void *arg);
 
 
 /* From fd_cmds.c */
-void    run_job(JCR *jcr);
-bool    bootstrap_cmd(JCR *jcr);
+void     run_job(JCR *jcr);
+bool     bootstrap_cmd(JCR *jcr);
 
 /* From job.c */
-void    stored_free_jcr(JCR *jcr);
-void    connection_from_filed(void *arg);
-void    handle_filed_connection(BSOCK *fd, char *job_name);
+void     stored_free_jcr(JCR *jcr);
+void     connection_from_filed(void *arg);
+void     handle_filed_connection(BSOCK *fd, char *job_name);
 
 /* From label.c */
-int     read_dev_volume_label(DCR *dcr);
-int     read_dev_volume_label_guess(DCR *dcr, bool write);
-void    create_session_label(DCR *dcr, DEV_RECORD *rec, int label);
-void    create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName);
-bool    write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName);
-bool    write_session_label(DCR *dcr, int label);
-bool    write_volume_label_to_block(DCR *dcr);
-void    dump_volume_label(DEVICE *dev);
-void    dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
-bool    unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
-bool    unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
+int      read_dev_volume_label(DCR *dcr);
+int      read_dev_volume_label_guess(DCR *dcr, bool write);
+void     create_session_label(DCR *dcr, DEV_RECORD *rec, int label);
+void     create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName);
+bool     write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName);
+bool     write_ansi_ibm_label(DCR *dcr, const char *VolName);
+bool     write_session_label(DCR *dcr, int label);
+bool     write_volume_label_to_block(DCR *dcr);
+void     dump_volume_label(DEVICE *dev);
+void     dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
+bool     unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
+bool     unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
 
 /* From match_bsr.c */
-int     match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
-             SESSION_LABEL *sesrec);
-int     match_bsr_block(BSR *bsr, DEV_BLOCK *block);
-void    position_bsr_block(BSR *bsr, DEV_BLOCK *block);
-BSR    *find_next_bsr(BSR *root_bsr, DEVICE *dev);
-bool    match_set_eof(BSR *bsr, DEV_RECORD *rec);
+int      match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
+              SESSION_LABEL *sesrec);
+int      match_bsr_block(BSR *bsr, DEV_BLOCK *block);
+void     position_bsr_block(BSR *bsr, DEV_BLOCK *block);
+BSR     *find_next_bsr(BSR *root_bsr, DEVICE *dev);
+bool     match_set_eof(BSR *bsr, DEV_RECORD *rec);
 
 /* From mount.c */
-bool    mount_next_write_volume(DCR *dcr, bool release);
-bool    mount_next_read_volume(DCR *dcr);
-void    release_volume(DCR *ddr);
-void    mark_volume_in_error(DCR *dcr);
+bool     mount_next_write_volume(DCR *dcr, bool release);
+bool     mount_next_read_volume(DCR *dcr);
+void     release_volume(DCR *ddr);
+void     mark_volume_in_error(DCR *dcr);
 
 /* From parse_bsr.c */
-BSR    *parse_bsr(JCR *jcr, char *lf);
-void    dump_bsr(BSR *bsr, bool recurse);
-void    free_bsr(BSR *bsr);
+BSR     *parse_bsr(JCR *jcr, char *lf);
+void     dump_bsr(BSR *bsr, bool recurse);
+void     free_bsr(BSR *bsr);
 VOL_LIST *new_vol();
-int     add_vol(JCR *jcr, VOL_LIST *vol);
-void    free_vol_list(JCR *jcr);
-void    create_vol_list(JCR *jcr);
+int      add_vol(JCR *jcr, VOL_LIST *vol);
+void     free_vol_list(JCR *jcr);
+void     create_vol_list(JCR *jcr);
 
 /* From record.c */
 const char *FI_to_ascii(int fi);
 const char *stream_to_ascii(int stream, int fi);
-bool       write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-bool       can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-bool       read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool        write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool        can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool        read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec);
 DEV_RECORD *new_record();
-void       free_record(DEV_RECORD *rec);
-void       empty_record(DEV_RECORD *rec);
+void        free_record(DEV_RECORD *rec);
+void        empty_record(DEV_RECORD *rec);
 
 /* From read_record.c */
 bool read_records(DCR *dcr,
@@ -206,12 +209,12 @@ bool read_records(DCR *dcr,
        bool mount_cb(DCR *dcr));
 
 /* From spool.c */
-bool   begin_data_spool          (JCR *jcr);
-bool   discard_data_spool        (JCR *jcr);
-bool   commit_data_spool         (JCR *jcr);
-bool   are_attributes_spooled    (JCR *jcr);
-bool   begin_attribute_spool     (JCR *jcr);
-bool   discard_attribute_spool   (JCR *jcr);
-bool   commit_attribute_spool    (JCR *jcr);
-bool   write_block_to_spool_file (DCR *dcr);
-void   list_spool_stats          (BSOCK *bs);
+bool    begin_data_spool          (JCR *jcr);
+bool    discard_data_spool        (JCR *jcr);
+bool    commit_data_spool         (JCR *jcr);
+bool    are_attributes_spooled    (JCR *jcr);
+bool    begin_attribute_spool     (JCR *jcr);
+bool    discard_attribute_spool   (JCR *jcr);
+bool    commit_attribute_spool    (JCR *jcr);
+bool    write_block_to_spool_file (DCR *dcr);
+void    list_spool_stats          (BSOCK *bs);
index 6bceb324b1c57215df59d25efc1fc45f1a089922..ec0cdc18b08848bd064bf9cf6c9664f7b138232d 100644 (file)
@@ -46,11 +46,11 @@ bool do_read_data(JCR *jcr)
 {
    BSOCK *fd = jcr->file_bsock;
    bool ok = true;
-   DCR *dcr;
+   DCR *dcr = jcr->dcr;
 
    Dmsg0(20, "Start read data.\n");
 
-   if (!bnet_set_buffer_size(fd, jcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) {
+   if (!bnet_set_buffer_size(fd, dcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) {
       return false;
    }
 
@@ -66,11 +66,10 @@ bool do_read_data(JCR *jcr)
    Dmsg2(200, "Found %d volumes names to restore. First=%s\n", jcr->NumVolumes,
       jcr->VolList->VolumeName);
 
-   /*
-    * Ready device for reading, and read records
-    */
-   if (!(dcr=acquire_device_for_read(jcr))) {
+   /* Ready device for reading */
+   if (!acquire_device_for_read(jcr, dcr->dev)) {
       free_vol_list(jcr);
+      bnet_fsend(fd, FD_error);
       return false;
    }
 
index 6a6c6db381cc5d605fb9c2e78c1f91a0de469fff..4a4d91ef221ecceb40ca2b40bfbb4bd49daeec3a 100644 (file)
@@ -67,10 +67,10 @@ bool read_records(DCR *dcr,
         if (dev_state(dev, ST_EOT)) {
            DEV_RECORD *trec = new_record();
 
-           Jmsg(jcr, M_INFO, 0, "End of Volume at file %u on device %s, Volume \"%s\"\n",
+            Jmsg(jcr, M_INFO, 0, "End of Volume at file %u on device %s, Volume \"%s\"\n",
                 dev->file, dev_name(dev), dcr->VolumeName);
            if (!mount_cb(dcr)) {
-              Jmsg(jcr, M_INFO, 0, "End of all volumes.\n");
+               Jmsg(jcr, M_INFO, 0, "End of all volumes.\n");
               ok = false;
               /*
                * Create EOT Label so that Media record may
@@ -99,21 +99,21 @@ bool read_records(DCR *dcr,
 
         } else if (dev_state(dev, ST_EOF)) {
            if (verbose) {
-              Jmsg(jcr, M_INFO, 0, "Got EOF at file %u  on device %s, Volume \"%s\"\n",
+               Jmsg(jcr, M_INFO, 0, "Got EOF at file %u  on device %s, Volume \"%s\"\n",
                  dev->file, dev_name(dev), dcr->VolumeName);
            }
-           Dmsg3(200, "Got EOF at file %u  on device %s, Volume \"%s\"\n",
+            Dmsg3(200, "Got EOF at file %u  on device %s, Volume \"%s\"\n",
                  dev->file, dev_name(dev), dcr->VolumeName);
            continue;
         } else if (dev_state(dev, ST_SHORT)) {
-           Jmsg1(jcr, M_ERROR, 0, "%s", dev->errmsg);
+            Jmsg1(jcr, M_ERROR, 0, "%s", dev->errmsg);
            continue;
         } else {
            /* I/O error or strange end of tape */
            display_tape_error_status(jcr, dev);
            if (forge_on || jcr->ignore_label_errors) {
               fsr_dev(dev, 1);       /* try skipping bad record */
-              Dmsg0(000, "Did fsr\n");
+               Dmsg0(000, "Did fsr\n");
               continue;              /* try to continue */
            }
            ok = false;
@@ -146,15 +146,8 @@ bool read_records(DCR *dcr,
       if (!found) {
         rec = new_record();
         recs->prepend(rec);
-        Dmsg2(300, "New record for SI=%d ST=%d\n",
+         Dmsg2(300, "New record for SI=%d ST=%d\n",
             block->VolSessionId, block->VolSessionTime);
-      } else {
-#ifdef xxx
-        if (rec->Block != 0 && (rec->Block+1) != block->BlockNumber) {
-           Jmsg(jcr, M_ERROR, 0, _("Invalid block number. Expected %u, got %u\n"),
-                rec->Block+1, block->BlockNumber);
-        }
-#endif
       }
       Dmsg3(300, "After mount next vol. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec),
            block->BlockNumber, rec->remainder);
@@ -163,11 +156,11 @@ bool read_records(DCR *dcr,
       Dmsg1(300, "Block empty %d\n", is_block_empty(rec));
       for (rec->state=0; !is_block_empty(rec); ) {
         if (!read_record_from_block(block, rec)) {
-           Dmsg3(400, "!read-break. state=%s blk=%d rem=%d\n", rec_state_to_str(rec),
+            Dmsg3(400, "!read-break. state=%s blk=%d rem=%d\n", rec_state_to_str(rec),
                  block->BlockNumber, rec->remainder);
            break;
         }
-        Dmsg5(300, "read-OK. state=%s blk=%d rem=%d file:block=%d:%d\n",
+         Dmsg5(300, "read-OK. state=%s blk=%d rem=%d file:block=%d:%d\n",
                 rec_state_to_str(rec), block->BlockNumber, rec->remainder,
                 dev->file, dev->block_num);
         /*
@@ -177,12 +170,12 @@ bool read_records(DCR *dcr,
          *  get all the data.
          */
         record++;
-        Dmsg6(300, "recno=%d state=%s blk=%d SI=%d ST=%d FI=%d\n", record,
+         Dmsg6(300, "recno=%d state=%s blk=%d SI=%d ST=%d FI=%d\n", record,
            rec_state_to_str(rec), block->BlockNumber,
            rec->VolSessionId, rec->VolSessionTime, rec->FileIndex);
 
         if (rec->FileIndex == EOM_LABEL) { /* end of tape? */
-           Dmsg0(40, "Get EOM LABEL\n");
+            Dmsg0(40, "Get EOM LABEL\n");
            break;                         /* yes, get out */
         }
 
@@ -191,7 +184,7 @@ bool read_records(DCR *dcr,
            handle_session_record(dev, rec, &sessrec);
            ok = record_cb(dcr, rec);
            if (rec->FileIndex == EOS_LABEL) {
-              Dmsg2(300, "Remove rec. SI=%d ST=%d\n", rec->VolSessionId,
+               Dmsg2(300, "Remove rec. SI=%d ST=%d\n", rec->VolSessionId,
                  rec->VolSessionTime);
               recs->remove(rec);
               free_record(rec);
@@ -206,35 +199,35 @@ bool read_records(DCR *dcr,
            int stat = match_bsr(jcr->bsr, rec, &dev->VolHdr, &sessrec);
            if (stat == -1) { /* no more possible matches */
               done = true;   /* all items found, stop */
-              Dmsg2(300, "All done=(file:block) %d:%d\n", dev->file, dev->block_num);
+               Dmsg2(300, "All done=(file:block) %d:%d\n", dev->file, dev->block_num);
               break;
            } else if (stat == 0) {  /* no match */
-              Dmsg4(300, "Clear rem=%d FI=%d before set_eof pos %d:%d\n",
+               Dmsg4(300, "Clear rem=%d FI=%d before set_eof pos %d:%d\n",
                  rec->remainder, rec->FileIndex, dev->file, dev->block_num);
               rec->remainder = 0;
               rec->state &= ~REC_PARTIAL_RECORD;
               if (try_repositioning(jcr, rec, dev)) {
                  break;
               }
-              continue;              /* we don't want record, read next one */
+               continue;              /* we don't want record, read next one */
            }
         }
         if (is_partial_record(rec)) {
-           Dmsg6(300, "Partial, break. recno=%d state=%s blk=%d SI=%d ST=%d FI=%d\n", record,
+            Dmsg6(300, "Partial, break. recno=%d state=%s blk=%d SI=%d ST=%d FI=%d\n", record,
               rec_state_to_str(rec), block->BlockNumber,
               rec->VolSessionId, rec->VolSessionTime, rec->FileIndex);
            break;                    /* read second part of record */
         }
         ok = record_cb(dcr, rec);
         if (rec->Stream == STREAM_MD5_SIGNATURE || rec->Stream == STREAM_SHA1_SIGNATURE) {
-           Dmsg3(300, "Done FI=%d before set_eof pos %d:%d\n", rec->FileIndex,
+            Dmsg3(300, "Done FI=%d before set_eof pos %d:%d\n", rec->FileIndex,
                  dev->file, dev->block_num);
            if (match_set_eof(jcr->bsr, rec) && try_repositioning(jcr, rec, dev)) {
-              Dmsg2(300, "Break after match_set_eof pos %d:%d\n",
+               Dmsg2(300, "Break after match_set_eof pos %d:%d\n",
                     dev->file, dev->block_num);
               break;
            }
-           Dmsg2(300, "After set_eof pos %d:%d\n", dev->file, dev->block_num);
+            Dmsg2(300, "After set_eof pos %d:%d\n", dev->file, dev->block_num);
         }
       } /* end for loop over records */
       Dmsg2(300, "After end records position=(file:block) %d:%d\n", dev->file, dev->block_num);
@@ -272,7 +265,7 @@ static int try_repositioning(JCR *jcr, DEV_RECORD *rec, DEVICE *dev)
    }
    if (bsr) {
       if (verbose) {
-        Jmsg(jcr, M_INFO, 0, "Reposition from (file:block) %d:%d to %d:%d\n",
+         Jmsg(jcr, M_INFO, 0, "Reposition from (file:block) %d:%d to %d:%d\n",
            dev->file, dev->block_num, bsr->volfile->sfile,
            bsr->volblock->sblock);
       }
@@ -299,9 +292,9 @@ static BSR *position_to_first_file(JCR *jcr, DEVICE *dev)
       jcr->bsr->reposition = true;    /* force repositioning */
       bsr = find_next_bsr(jcr->bsr, dev);
       if (bsr && (bsr->volfile->sfile != 0 || bsr->volblock->sblock != 0)) {
-        Jmsg(jcr, M_INFO, 0, _("Forward spacing to file:block %u:%u.\n"),
+         Jmsg(jcr, M_INFO, 0, _("Forward spacing to file:block %u:%u.\n"),
            bsr->volfile->sfile, bsr->volblock->sblock);
-        Dmsg2(300, "Forward spacing to file:block %u:%u.\n",
+         Dmsg2(300, "Forward spacing to file:block %u:%u.\n",
            bsr->volfile->sfile, bsr->volblock->sblock);
         reposition_dev(dev, bsr->volfile->sfile, bsr->volblock->sblock);
       }
index dce3c1c9c57c23b7f861bb85365f5372623e45b1..6b3d23dc1207e6a9d46c53c350ba064e4e9564f9 100644 (file)
@@ -323,18 +323,18 @@ bool write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec)
 #ifdef xxxxxSMCHECK
         if (!sm_check_rtn(__FILE__, __LINE__, False)) {
            /* We damaged a buffer */
-           Dmsg6(0, "Damaged block FI=%s SessId=%d Strm=%s len=%d\n"
+            Dmsg6(0, "Damaged block FI=%s SessId=%d Strm=%s len=%d\n"
 "rem=%d remainder=%d\n",
               FI_to_ascii(rec->FileIndex), rec->VolSessionId,
               stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len,
               remlen, rec->remainder);
-           Dmsg5(0, "Damaged block: bufp=%x binbuf=%d buf_len=%d rem=%d moved=%d\n",
+            Dmsg5(0, "Damaged block: bufp=%x binbuf=%d buf_len=%d rem=%d moved=%d\n",
               block->bufp, block->binbuf, block->buf_len, block->buf_len-block->binbuf,
               remlen);
-           Dmsg2(0, "Damaged block: buf=%x binbuffrombuf=%d \n",
+            Dmsg2(0, "Damaged block: buf=%x binbuffrombuf=%d \n",
               block->buf, block->bufp-block->buf);
 
-              Emsg0(M_ABORT, 0, "Damaged buffer\n");
+               Emsg0(M_ABORT, 0, "Damaged buffer\n");
         }
 #endif
 
@@ -402,7 +402,7 @@ bool read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
 
    /* Clear state flags */
    rec->state = 0;
-   if (((DEVICE *)block->dev)->state & ST_TAPE) {
+   if (block->dev->is_tape()) {
       rec->state |= REC_ISTAPE;
    }
 
@@ -444,7 +444,7 @@ bool read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
       if (rec->remainder && (rec->VolSessionId != VolSessionId ||
                             rec->VolSessionTime != VolSessionTime)) {
         rec->state |= REC_NO_MATCH;
-        Dmsg0(450, "remainder and VolSession doesn't match\n");
+         Dmsg0(450, "remainder and VolSession doesn't match\n");
         return false;             /* This is from some other Session */
       }
 
@@ -452,10 +452,10 @@ bool read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
        * of a previous partially written record.
        */
       if (Stream < 0) {              /* continuation record? */
-        Dmsg1(500, "Got negative Stream => continuation. remainder=%d\n",
+         Dmsg1(500, "Got negative Stream => continuation. remainder=%d\n",
            rec->remainder);
         rec->state |= REC_CONTINUATION;
-        if (!rec->remainder) {       /* if we didn't read previously */
+         if (!rec->remainder) {       /* if we didn't read previously */
            rec->data_len = 0;        /* return data as if no continuation */
         } else if (rec->Stream != -Stream) {
            rec->state |= REC_NO_MATCH;
@@ -477,7 +477,7 @@ bool read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
       }
 
       Dmsg6(450, "rd_rec_blk() got FI=%s SessId=%d Strm=%s len=%u\n"
-                "remlen=%d data_len=%d\n",
+                 "remlen=%d data_len=%d\n",
         FI_to_ascii(rec->FileIndex), rec->VolSessionId,
         stream_to_ascii(rec->Stream, rec->FileIndex), data_bytes, remlen,
         rec->data_len);
@@ -491,12 +491,6 @@ bool read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
        * then reread.
        */
       Dmsg0(450, "read_record_block: nothing\n");
-#ifdef xxx
-      if (!rec->remainder) {
-        rec->remainder = 1;          /* set to expect continuation */
-        rec->data_len = 0;           /* no data transferred */
-      }
-#endif
       rec->state |= (REC_NO_HEADER | REC_BLOCK_EMPTY);
       empty_block(block);                     /* mark block empty */
       return false;
index 89a774f64cdd70c335416723f70cad157a521ac0..ac7bd0f3223deda94a0935017e1d3ca5399c57a5 100644 (file)
@@ -93,7 +93,7 @@ bool begin_data_spool(JCR *jcr)
       stat = open_data_spool_file(jcr);
       if (stat) {
         jcr->dcr->spooling = true;
-        Jmsg(jcr, M_INFO, 0, _("Spooling data ...\n"));
+         Jmsg(jcr, M_INFO, 0, _("Spooling data ...\n"));
         P(mutex);
         spool_stats.data_jobs++;
         V(mutex);
@@ -119,7 +119,7 @@ bool commit_data_spool(JCR *jcr)
       Dmsg0(100, "Committing spooled data\n");
       stat = despool_data(jcr->dcr, true /*commit*/);
       if (!stat) {
-        Pmsg1(000, "Bad return from despool WroteVol=%d\n", jcr->dcr->WroteVol);
+         Pmsg1(000, "Bad return from despool WroteVol=%d\n", jcr->dcr->WroteVol);
         close_data_spool_file(jcr);
         return false;
       }
@@ -136,7 +136,8 @@ static void make_unique_data_spool_filename(JCR *jcr, POOLMEM **name)
    } else {
       dir = working_directory;
    }
-   Mmsg(name, "%s/%s.data.spool.%s.%s", dir, my_name, jcr->Job, jcr->device->hdr.name);
+   Mmsg(name, "%s/%s.data.spool.%s.%s", dir, my_name, jcr->Job, 
+       jcr->dcr->device->hdr.name);
 }
 
 
@@ -300,11 +301,11 @@ static int read_block_from_spool_file(DCR *dcr)
    } else if (stat != (ssize_t)rlen) {
       if (stat == -1) {
         berrno be;
-        Jmsg(dcr->jcr, M_FATAL, 0, _("Spool header read error. ERR=%s\n"),
+         Jmsg(dcr->jcr, M_FATAL, 0, _("Spool header read error. ERR=%s\n"),
              be.strerror());
       } else {
-        Pmsg2(000, "Spool read error. Wanted %u bytes, got %u\n", rlen, stat);
-        Jmsg2(dcr->jcr, M_FATAL, 0, _("Spool header read error. Wanted %u bytes, got %u\n"), rlen, stat);
+         Pmsg2(000, "Spool read error. Wanted %u bytes, got %u\n", rlen, stat);
+         Jmsg2(dcr->jcr, M_FATAL, 0, _("Spool header read error. Wanted %u bytes, got %u\n"), rlen, stat);
       }
       return RB_ERROR;
    }
@@ -368,7 +369,7 @@ bool write_block_to_spool_file(DCR *dcr)
 #ifdef xDEBUG
       char ec1[30], ec2[30], ec3[30], ec4[30];
       Dmsg4(100, "Despool in write_block_to_spool_file max_size=%s size=%s "
-           "max_job_size=%s job_size=%s\n",
+            "max_job_size=%s job_size=%s\n",
            edit_uint64_with_commas(dcr->max_spool_size, ec1),
            edit_uint64_with_commas(dcr->spool_size, ec2),
            edit_uint64_with_commas(dcr->dev->max_spool_size, ec3),
@@ -376,7 +377,7 @@ bool write_block_to_spool_file(DCR *dcr)
 #endif
       Jmsg(dcr->jcr, M_INFO, 0, _("User specified spool size reached.\n"));
       if (!despool_data(dcr, false)) {
-        Pmsg0(000, "Bad return from despool in write_block.\n");
+         Pmsg0(000, "Bad return from despool in write_block.\n");
         return false;
       }
       /* Despooling cleared these variables so reset them */
@@ -415,7 +416,7 @@ static bool write_spool_header(DCR *dcr)
       stat = write(dcr->spool_fd, (char*)&hdr, sizeof(hdr));
       if (stat == -1) {
         berrno be;
-        Jmsg(dcr->jcr, M_FATAL, 0, _("Error writing header to spool file. ERR=%s\n"),
+         Jmsg(dcr->jcr, M_FATAL, 0, _("Error writing header to spool file. ERR=%s\n"),
              be.strerror());
       }
       if (stat != (ssize_t)sizeof(hdr)) {
@@ -423,13 +424,13 @@ static bool write_spool_header(DCR *dcr)
         if (stat != -1) {
            if (ftruncate(dcr->spool_fd, lseek(dcr->spool_fd, (off_t)0, SEEK_CUR) - stat) != 0) {
               berrno be;
-              Jmsg(dcr->jcr, M_FATAL, 0, _("Ftruncate spool file failed: ERR=%s\n"),
+               Jmsg(dcr->jcr, M_FATAL, 0, _("Ftruncate spool file failed: ERR=%s\n"),
                  be.strerror());
               return false;
            }
         }
         if (!despool_data(dcr, false)) {
-           Jmsg(dcr->jcr, M_FATAL, 0, _("Fatal despooling error."));
+            Jmsg(dcr->jcr, M_FATAL, 0, _("Fatal despooling error."));
            return false;
         }
         continue;                    /* try again */
@@ -450,7 +451,7 @@ static bool write_spool_data(DCR *dcr)
       stat = write(dcr->spool_fd, block->buf, (size_t)block->binbuf);
       if (stat == -1) {
         berrno be;
-        Jmsg(dcr->jcr, M_FATAL, 0, _("Error writing data to spool file. ERR=%s\n"),
+         Jmsg(dcr->jcr, M_FATAL, 0, _("Error writing data to spool file. ERR=%s\n"),
              be.strerror());
       }
       if (stat != (ssize_t)block->binbuf) {
@@ -461,13 +462,13 @@ static bool write_spool_data(DCR *dcr)
            if (ftruncate(dcr->spool_fd, lseek(dcr->spool_fd, (off_t)0, SEEK_CUR)
                      - stat - sizeof(spool_hdr)) != 0) {
               berrno be;
-              Jmsg(dcr->jcr, M_FATAL, 0, _("Ftruncate spool file failed: ERR=%s\n"),
+               Jmsg(dcr->jcr, M_FATAL, 0, _("Ftruncate spool file failed: ERR=%s\n"),
                  be.strerror());
               return false;
            }
         }
         if (!despool_data(dcr, false)) {
-           Jmsg(dcr->jcr, M_FATAL, 0, _("Fatal despooling error."));
+            Jmsg(dcr->jcr, M_FATAL, 0, _("Fatal despooling error."));
            return false;
         }
         if (!write_spool_header(dcr)) {
@@ -532,7 +533,7 @@ bool commit_attribute_spool(JCR *jcr)
    if (are_attributes_spooled(jcr)) {
       if (fseek(jcr->dir_bsock->spool_fd, 0, SEEK_END) != 0) {
         berrno be;
-        Jmsg(jcr, M_FATAL, 0, _("Fseek on attributes file failed: ERR=%s\n"),
+         Jmsg(jcr, M_FATAL, 0, _("Fseek on attributes file failed: ERR=%s\n"),
              be.strerror());
       }
       size = ftell(jcr->dir_bsock->spool_fd);
index a9c0bf9146a111f4f58bcbf11d72769883792bb0..59196f3c9ba1153499ed6c30d0c86410345f8b41 100644 (file)
@@ -97,48 +97,47 @@ bool status_cmd(JCR *jcr)
    bnet_fsend(user, _("\nDevice status:\n"));
    LockRes();
    foreach_res(device, R_DEVICE) {
-      for (dev=device->dev; dev; dev=dev->next) {
-        if (dev_state(dev, ST_OPENED)) {
-           if (dev_state(dev, ST_LABEL)) {
-               bnet_fsend(user, _("Device \"%s\" is mounted with Volume \"%s\"\n"),
-                 dev_name(dev), dev->VolHdr.VolName);
-           } else {
-               bnet_fsend(user, _("Device \"%s\" open but no Bacula volume is mounted.\n"), dev_name(dev));
+      dev = device->dev;
+      if (dev->is_open()) {
+        if (dev->is_labeled()) {
+            bnet_fsend(user, _("Device \"%s\" is mounted with Volume \"%s\"\n"),
+              dev_name(dev), dev->VolHdr.VolName);
+        } else {
+            bnet_fsend(user, _("Device \"%s\" open but no Bacula volume is mounted.\n"), dev_name(dev));
+        }
+        send_blocked_status(jcr, dev);
+        if (dev_state(dev, ST_APPEND)) {
+           bpb = dev->VolCatInfo.VolCatBlocks;
+           if (bpb <= 0) {
+              bpb = 1;
            }
-           send_blocked_status(jcr, dev);
-           if (dev_state(dev, ST_APPEND)) {
-              bpb = dev->VolCatInfo.VolCatBlocks;
-              if (bpb <= 0) {
-                 bpb = 1;
-              }
-              bpb = dev->VolCatInfo.VolCatBytes / bpb;
-               bnet_fsend(user, _("    Total Bytes=%s Blocks=%s Bytes/block=%s\n"),
-                 edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
-                 edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
-                 edit_uint64_with_commas(bpb, b3));
-           } else {  /* reading */
-              bpb = dev->VolCatInfo.VolCatReads;
-              if (bpb <= 0) {
-                 bpb = 1;
-              }
-              if (dev->VolCatInfo.VolCatRBytes > 0) {
-                 bpb = dev->VolCatInfo.VolCatRBytes / bpb;
-              } else {
-                 bpb = 0;
-              }
-               bnet_fsend(user, _("    Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n"),
-                 edit_uint64_with_commas(dev->VolCatInfo.VolCatRBytes, b1),
-                 edit_uint64_with_commas(dev->VolCatInfo.VolCatReads, b2),
-                 edit_uint64_with_commas(bpb, b3));
+           bpb = dev->VolCatInfo.VolCatBytes / bpb;
+            bnet_fsend(user, _("    Total Bytes=%s Blocks=%s Bytes/block=%s\n"),
+              edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
+              edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
+              edit_uint64_with_commas(bpb, b3));
+        } else {  /* reading */
+           bpb = dev->VolCatInfo.VolCatReads;
+           if (bpb <= 0) {
+              bpb = 1;
            }
-            bnet_fsend(user, _("    Positioned at File=%s Block=%s\n"),
-              edit_uint64_with_commas(dev->file, b1),
-              edit_uint64_with_commas(dev->block_num, b2));
-
-        } else {
-            bnet_fsend(user, _("Device \"%s\" is not open.\n"), dev_name(dev));
-           send_blocked_status(jcr, dev);
+           if (dev->VolCatInfo.VolCatRBytes > 0) {
+              bpb = dev->VolCatInfo.VolCatRBytes / bpb;
+           } else {
+              bpb = 0;
+           }
+            bnet_fsend(user, _("    Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n"),
+              edit_uint64_with_commas(dev->VolCatInfo.VolCatRBytes, b1),
+              edit_uint64_with_commas(dev->VolCatInfo.VolCatReads, b2),
+              edit_uint64_with_commas(bpb, b3));
         }
+         bnet_fsend(user, _("    Positioned at File=%s Block=%s\n"),
+           edit_uint64_with_commas(dev->file, b1),
+           edit_uint64_with_commas(dev->block_num, b2));
+
+      } else {
+         bnet_fsend(user, _("Device \"%s\" is not open.\n"), dev_name(dev));
+        send_blocked_status(jcr, dev);
       }
    }
    UnlockRes();
@@ -202,22 +201,23 @@ static void send_blocked_status(JCR *jcr, DEVICE *dev)
       bnet_fsend(user, "\n");
 
       bnet_fsend(user, _("Device status:\n"));
-      bnet_fsend(user, "%sOPENED ", dev->state & ST_OPENED ? "" : "!");
-      bnet_fsend(user, "%sTAPE ", dev->state & ST_TAPE ? "" : "!");
-      bnet_fsend(user, "%sLABEL ", dev->state & ST_LABEL ? "" : "!");
+      bnet_fsend(user, "%sOPENED ", dev->is_open() ? "" : "!");
+      bnet_fsend(user, "%sTAPE ", dev->is_tape() ? "" : "!");
+      bnet_fsend(user, "%sLABEL ", dev->is_labeled() ? "" : "!");
       bnet_fsend(user, "%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
-      bnet_fsend(user, "%sAPPEND ", dev->state & ST_APPEND ? "" : "!");
-      bnet_fsend(user, "%sREAD ", dev->state & ST_READ ? "" : "!");
-      bnet_fsend(user, "%sEOT ", dev->state & ST_EOT ? "" : "!");
+      bnet_fsend(user, "%sAPPEND ", dev->can_append() ? "" : "!");
+      bnet_fsend(user, "%sREAD ", dev->can_read() ? "" : "!");
+      bnet_fsend(user, "%sEOT ", dev->at_eom() ? "" : "!");
       bnet_fsend(user, "%sWEOT ", dev->state & ST_WEOT ? "" : "!");
-      bnet_fsend(user, "%sEOF ", dev->state & ST_EOF ? "" : "!");
+      bnet_fsend(user, "%sEOF ", dev->at_eof() ? "" : "!");
       bnet_fsend(user, "%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
       bnet_fsend(user, "%sSHORT ", dev->state & ST_SHORT ? "" : "!");
       bnet_fsend(user, "%sMOUNTED ", dev->state & ST_MOUNTED ? "" : "!");
       bnet_fsend(user, "\n");
 
       bnet_fsend(user, _("Device parameters:\n"));
-      bnet_fsend(user, "Device name: %s\n", dev->dev_name);
+      bnet_fsend(user, "Archive name: %s Device name: %s\n", dev->dev_name,
+        dev->device->hdr.name);
       bnet_fsend(user, "File=%u block=%u\n", dev->file, dev->block_num);
       bnet_fsend(user, "Min block=%u Max block=%u\n", dev->min_block_size, dev->max_block_size);
    }
@@ -239,7 +239,7 @@ static void list_running_jobs(BSOCK *user)
          bnet_fsend(user, _("%s Job %s waiting for Client connection.\n"),
            job_type_to_str(jcr->JobType), jcr->Job);
       }
-      if (jcr->device) {
+      if (jcr->dcr && jcr->dcr->device) {
         bstrncpy(JobName, jcr->Job, sizeof(JobName));
         /* There are three periods after the Job name */
         char *p;
@@ -253,8 +253,8 @@ static void list_running_jobs(BSOCK *user)
                   job_type_to_str(jcr->JobType),
                   JobName,
                   jcr->JobId,
-                   jcr->dcr?jcr->dcr->VolumeName:"*none*",
-                   jcr->device?jcr->device->device_name:"none");
+                  jcr->dcr->VolumeName,
+                  jcr->dcr->device->device_name);
         sec = time(NULL) - jcr->run_time;
         if (sec <= 0) {
            sec = 1;
index 017fa608e3e13839a054a08f2e6740ec2d59c443..afe1ee9d42d4e96b2d6656ba4d7e48ce5bef2c22 100644 (file)
@@ -10,7 +10,7 @@
  *
  */
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   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
@@ -65,7 +65,7 @@ static workq_t dird_workq;          /* queue for processing connections */
 static void usage()
 {
    fprintf(stderr, _(
-"Copyright (C) 2000-2004 Kern Sibbald and John Walker.\n"
+"Copyright (C) 2000-2005 Kern Sibbald.\n"
 "\nVersion: " VERSION " (" BDATE ")\n\n"
 "Usage: stored [options] [-c config_file] [config_file]\n"
 "        -c <file>   use <file> as configuration file\n"
@@ -179,7 +179,6 @@ int main (int argc, char *argv[])
       init_signals(terminate_stored);
    }
 
-
    if (configfile == NULL) {
       configfile = bstrdup(CONFIG_FILE);
    }
@@ -206,7 +205,7 @@ int main (int argc, char *argv[])
     */
    VolSessionTime = (long)daemon_start_time;
    if (VolSessionTime == 0) { /* paranoid */
-      Emsg0(M_ABORT, 0, _("Volume Session Time is ZERO!\n"));
+      Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n"));
    }
 
    /* Make sure on Solaris we can run concurrent, watch dog + servers + misc */
@@ -254,7 +253,7 @@ static void check_config()
    me = (STORES *)GetNextRes(R_STORAGE, NULL);
    if (!me) {
       UnlockRes();
-      Emsg1(M_ERROR_TERM, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
+      Jmsg1(NULL, M_ERROR_TERM, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
         configfile);
    }
 
@@ -262,23 +261,23 @@ static void check_config()
 
    if (GetNextRes(R_STORAGE, (RES *)me) != NULL) {
       UnlockRes();
-      Emsg1(M_ERROR_TERM, 0, _("Only one Storage resource permitted in %s\n"),
+      Jmsg1(NULL, M_ERROR_TERM, 0, _("Only one Storage resource permitted in %s\n"),
         configfile);
    }
    if (GetNextRes(R_DIRECTOR, NULL) == NULL) {
       UnlockRes();
-      Emsg1(M_ERROR_TERM, 0, _("No Director resource defined in %s. Cannot continue.\n"),
+      Jmsg1(NULL, M_ERROR_TERM, 0, _("No Director resource defined in %s. Cannot continue.\n"),
         configfile);
    }
    if (GetNextRes(R_DEVICE, NULL) == NULL){
       UnlockRes();
-      Emsg1(M_ERROR_TERM, 0, _("No Device resource defined in %s. Cannot continue.\n"),
+      Jmsg1(NULL, M_ERROR_TERM, 0, _("No Device resource defined in %s. Cannot continue.\n"),
           configfile);
    }
    if (!me->messages) {
       me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
       if (!me->messages) {
-        Emsg1(M_ERROR_TERM, 0, _("No Messages resource defined in %s. Cannot continue.\n"),
+         Jmsg1(NULL, M_ERROR_TERM, 0, _("No Messages resource defined in %s. Cannot continue.\n"),
            configfile);
       }
    }
@@ -288,7 +287,7 @@ static void check_config()
    UnlockRes();
 
    if (!me->working_directory) {
-      Emsg1(M_ERROR_TERM, 0, _("No Working Directory defined in %s. Cannot continue.\n"),
+      Jmsg1(NULL, M_ERROR_TERM, 0, _("No Working Directory defined in %s. Cannot continue.\n"),
         configfile);
    }
 
@@ -296,8 +295,8 @@ static void check_config()
 }
 
 /*
- * We are started as a separate thread.  The
- *  resources are alread locked.
+ * Here we attempt to init and open each device. This is done
+ *  once at startup in a separate thread.
  */
 extern "C"
 void *device_allocation(void *arg)
@@ -312,14 +311,14 @@ void *device_allocation(void *arg)
       device->dev = init_dev(NULL, device);
       Dmsg1(10, "SD init done %s\n", device->device_name);
       if (!device->dev) {
-        Emsg1(M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
+         Jmsg1(NULL, M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
         continue;
       }
 
       if (device->cap_bits & CAP_ALWAYSOPEN) {
-        Dmsg1(20, "calling first_open_device %s\n", device->device_name);
+         Dmsg1(20, "calling first_open_device %s\n", device->device_name);
         if (!first_open_device(device->dev)) {
-           Emsg1(M_ERROR, 0, _("Could not open device %s\n"), device->device_name);
+            Jmsg1(NULL, M_ERROR, 0, _("Could not open device %s\n"), device->device_name);
         }
       }
       if (device->cap_bits & CAP_AUTOMOUNT && device->dev &&
@@ -331,17 +330,16 @@ void *device_allocation(void *arg)
         /* Initialize FD start condition variable */
         int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
         if (errstat != 0) {
-           Jmsg1(jcr, M_ABORT, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
+            Jmsg1(jcr, M_ABORT, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
         }
-        jcr->device = device;
         dcr = new_dcr(jcr, device->dev);
         switch (read_dev_volume_label(dcr)) {
-           case VOL_OK:
-              memcpy(&dcr->dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dcr->dev->VolCatInfo));
-              break;
-           default:
-              Emsg1(M_WARNING, 0, _("Could not mount device %s\n"), device->device_name);
-              break;
+        case VOL_OK:
+           memcpy(&dcr->dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dcr->dev->VolCatInfo));
+           break;
+        default:
+            Jmsg1(NULL, M_WARNING, 0, _("Could not mount device %s\n"), device->device_name);
+           break;
         }
         free_jcr(jcr);
       }
@@ -381,10 +379,11 @@ void terminate_stored(int sig)
         fd = jcr->file_bsock;
         if (fd) {
            fd->timed_out = true;
-           Dmsg1(100, "term_stored killing JobId=%d\n", jcr->JobId);
+            Dmsg1(100, "term_stored killing JobId=%d\n", jcr->JobId);
            pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
-           if (jcr->device && jcr->device->dev && jcr->device->dev->dev_blocked) {
-              pthread_cond_signal(&jcr->device->dev->wait_next_vol);
+           /* ***FIXME*** wiffle through all dcrs */
+           if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->dev_blocked) {
+              pthread_cond_signal(&jcr->dcr->dev->wait_next_vol);
            }
            bmicrosleep(0, 50000);
          }
index 00c7b2df588487379a6f752b54f6cc999ad064ae..6169057ca145a96d7f630b0ad3a5b9f475e17278 100644 (file)
@@ -132,6 +132,17 @@ static RES_ITEM dev_items[] = {
    {NULL, NULL, 0, 0, 0, 0}
 };
 
+/* Autochanger definition */
+static RES_ITEM changer_items[] = {
+   {"name",              store_name,      ITEM(res_changer.hdr.name),        0, ITEM_REQUIRED, 0},
+   {"description",       store_str,       ITEM(res_changer.hdr.desc),        0, 0, 0},
+   {"device",            store_alist_res, ITEM(res_changer.device),   R_DEVICE, ITEM_REQUIRED, 0},
+   {"changerdevice",     store_strname,   ITEM(res_changer.changer_name),    0, 0, 0},
+   {"changercommand",    store_strname,   ITEM(res_changer.changer_command), 0, 0, 0},
+   {NULL, NULL, 0, 0, 0, 0}
+};
+
+
 // {"mountanonymousvolumes", store_yesno,  ITEM(res_dev.cap_bits), CAP_ANONVOLS,   ITEM_DEFAULT, 0},
 
 
@@ -141,11 +152,12 @@ extern RES_ITEM msgs_items[];
 
 /* This is the master resource definition */
 RES_TABLE resources[] = {
-   {"director",      dir_items,   R_DIRECTOR},
-   {"storage",       store_items, R_STORAGE},
-   {"device",        dev_items,   R_DEVICE},
-   {"messages",      msgs_items,  R_MSGS},
-   {NULL,           NULL,        0}
+   {"director",      dir_items,     R_DIRECTOR},
+   {"storage",       store_items,   R_STORAGE},
+   {"device",        dev_items,     R_DEVICE},
+   {"messages",      msgs_items,    R_MSGS},
+   {"autochanger",   changer_items, R_AUTOCHANGER},
+   {NULL,           NULL,          0}
 };
 
 
@@ -202,7 +214,7 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
       sendit(sock, "         spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
       sendit(sock, "         max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
         res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
-      strcpy(buf, "        ");
+      bstrncpy(buf, "        ", sizeof(buf));
       if (res->res_dev.cap_bits & CAP_EOF) {
          bstrncat(buf, "CAP_EOF ", sizeof(buf));
       }
@@ -242,6 +254,17 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
       bstrncat(buf, "\n", sizeof(buf));
       sendit(sock, buf);
       break;
+   case R_AUTOCHANGER:
+      DEVRES *dev;
+      sendit(sock, "Changer: name=%s Changer_devname=%s Changer_cmd=%s\n",
+        res->res_changer.hdr.name,
+        res->res_changer.changer_name, res->res_changer.changer_command);
+      foreach_alist(dev, res->res_changer.device) {
+         sendit(sock, "   --->Device: name=%s\n", dev->hdr.name);
+      }
+      bstrncat(buf, "\n", sizeof(buf));
+      sendit(sock, buf);
+      break;
    case R_MSGS:
       sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name);
       if (res->res_msgs.mail_cmd)
@@ -283,79 +306,86 @@ void free_resource(RES *sres, int type)
 
 
    switch (type) {
-      case R_DIRECTOR:
-        if (res->res_dir.password) {
-           free(res->res_dir.password);
-        }
-        if (res->res_dir.address) {
-           free(res->res_dir.address);
-        }
-        break;
-      case R_STORAGE:
-        if (res->res_store.sdaddrs) {
-           free_addresses(res->res_store.sdaddrs);
-        }
-        if (res->res_store.sddaddrs) {
-           free_addresses(res->res_store.sddaddrs);
-        }
-        if (res->res_store.working_directory) {
-           free(res->res_store.working_directory);
-        }
-        if (res->res_store.pid_directory) {
-           free(res->res_store.pid_directory);
-        }
-        if (res->res_store.subsys_directory) {
-           free(res->res_store.subsys_directory);
-        }
-        break;
-      case R_DEVICE:
-        if (res->res_dev.media_type) {
-           free(res->res_dev.media_type);
-        }
-        if (res->res_dev.device_name) {
-           free(res->res_dev.device_name);
-        }
-        if (res->res_dev.changer_name) {
-           free(res->res_dev.changer_name);
-        }
-        if (res->res_dev.changer_command) {
-           free(res->res_dev.changer_command);
-        }
-        if (res->res_dev.alert_command) {
-           free(res->res_dev.alert_command);
-        }
-        if (res->res_dev.spool_directory) {
-           free(res->res_dev.spool_directory);
-        }
-        if (res->res_dev.mount_point) {
-           free(res->res_dev.mount_point);
-        }
-        if (res->res_dev.mount_command) {
-           free(res->res_dev.mount_command);
-        }
-        if (res->res_dev.unmount_command) {
-           free(res->res_dev.unmount_command);
-        }
-        if (res->res_dev.write_part_command) {
-           free(res->res_dev.write_part_command);
-        }
-        if (res->res_dev.free_space_command) {
-           free(res->res_dev.free_space_command);
-        }
-        break;
-      case R_MSGS:
-        if (res->res_msgs.mail_cmd) {
-           free(res->res_msgs.mail_cmd);
-        }
-        if (res->res_msgs.operator_cmd) {
-           free(res->res_msgs.operator_cmd);
-        }
-        free_msgs_res((MSGS *)res);  /* free message resource */
-        res = NULL;
-        break;
-      default:
-         Dmsg1(0, "Unknown resource type %d\n", type);
-        break;
+   case R_DIRECTOR:
+      if (res->res_dir.password) {
+        free(res->res_dir.password);
+      }
+      if (res->res_dir.address) {
+        free(res->res_dir.address);
+      }
+      break;
+   case R_AUTOCHANGER:
+      if (res->res_changer.changer_name) {
+        free(res->res_changer.changer_name);
+      }
+      if (res->res_changer.changer_command) {
+        free(res->res_changer.changer_command);
+      }
+   case R_STORAGE:
+      if (res->res_store.sdaddrs) {
+        free_addresses(res->res_store.sdaddrs);
+      }
+      if (res->res_store.sddaddrs) {
+        free_addresses(res->res_store.sddaddrs);
+      }
+      if (res->res_store.working_directory) {
+        free(res->res_store.working_directory);
+      }
+      if (res->res_store.pid_directory) {
+        free(res->res_store.pid_directory);
+      }
+      if (res->res_store.subsys_directory) {
+        free(res->res_store.subsys_directory);
+      }
+      break;
+   case R_DEVICE:
+      if (res->res_dev.media_type) {
+        free(res->res_dev.media_type);
+      }
+      if (res->res_dev.device_name) {
+        free(res->res_dev.device_name);
+      }
+      if (res->res_dev.changer_name) {
+        free(res->res_dev.changer_name);
+      }
+      if (res->res_dev.changer_command) {
+        free(res->res_dev.changer_command);
+      }
+      if (res->res_dev.alert_command) {
+        free(res->res_dev.alert_command);
+      }
+      if (res->res_dev.spool_directory) {
+        free(res->res_dev.spool_directory);
+      }
+      if (res->res_dev.mount_point) {
+        free(res->res_dev.mount_point);
+      }
+      if (res->res_dev.mount_command) {
+        free(res->res_dev.mount_command);
+      }
+      if (res->res_dev.unmount_command) {
+        free(res->res_dev.unmount_command);
+      }
+      if (res->res_dev.write_part_command) {
+        free(res->res_dev.write_part_command);
+      }
+      if (res->res_dev.free_space_command) {
+        free(res->res_dev.free_space_command);
+      }
+      break;
+   case R_MSGS:
+      if (res->res_msgs.mail_cmd) {
+        free(res->res_msgs.mail_cmd);
+      }
+      if (res->res_msgs.operator_cmd) {
+        free(res->res_msgs.operator_cmd);
+      }
+      free_msgs_res((MSGS *)res);  /* free message resource */
+      res = NULL;
+      break;
+   default:
+      Dmsg1(0, "Unknown resource type %d\n", type);
+      break;
    }
    /* Common stuff again -- free the resource, recurse to next one */
    if (res) {
@@ -368,7 +398,7 @@ void free_resource(RES *sres, int type)
 
 /* Save the new resource by chaining it into the head list for
  * the resource. If this is pass 2, we update any resource
- * pointers (currently only in the Job resource).
+ * or alist pointers.  
  */
 void save_resource(int type, RES_ITEM *items, int pass)
 {
@@ -400,23 +430,31 @@ void save_resource(int type, RES_ITEM *items, int pass)
     */
    if (pass == 2) {
       switch (type) {
-        /* Resources not containing a resource */
-        case R_DIRECTOR:
-        case R_DEVICE:
-        case R_MSGS:
-           break;
-
-        /* Resources containing a resource */
-        case R_STORAGE:
-           if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) {
-               Emsg1(M_ERROR_TERM, 0, "Cannot find Storage resource \"%s\"\n", res_all.res_dir.hdr.name);
-           }
-           res->res_store.messages = res_all.res_store.messages;
-           break;
-        default:
-            printf("Unknown resource type %d\n", type);
-           error = 1;
-           break;
+      /* Resources not containing a resource */
+      case R_DIRECTOR:
+      case R_DEVICE:
+      case R_MSGS:
+        break;
+
+      /* Resources containing a resource or an alist */
+      case R_STORAGE:
+        if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) {
+            Emsg1(M_ERROR_TERM, 0, "Cannot find Storage resource \"%s\"\n", res_all.res_dir.hdr.name);
+        }
+        res->res_store.messages = res_all.res_store.messages;
+        break;
+      case R_AUTOCHANGER:
+        if ((res = (URES *)GetResWithName(type, res_all.res_changer.hdr.name)) == NULL) {
+            Emsg1(M_ERROR_TERM, 0, "Cannot find AutoChanger resource %s\n",
+                 res_all.res_changer.hdr.name);
+        }
+        /* we must explicitly copy the device alist pointer */
+        res->res_changer.device   = res_all.res_changer.device;
+        break;
+      default:
+         printf("Unknown resource type %d\n", type);
+        error = 1;
+        break;
       }
 
 
@@ -445,6 +483,9 @@ void save_resource(int type, RES_ITEM *items, int pass)
       case R_MSGS:
         size = sizeof(MSGS);
         break;
+      case R_AUTOCHANGER:
+        size = sizeof(AUTOCHANGER);
+        break;
       default:
          printf("Unknown resource type %d\n", type);
         error = 1;
index 4e68d83d696a4787a652e634933a84db71cea80b..7f92e20d3885c8ef72833986955a13f43a1a20bd 100644 (file)
@@ -28,8 +28,9 @@ enum {
    R_STORAGE,
    R_DEVICE,
    R_MSGS,
+   R_AUTOCHANGER,
    R_FIRST = R_DIRECTOR,
-   R_LAST  = R_MSGS                  /* keep this updated */
+   R_LAST  = R_AUTOCHANGER            /* keep this updated */
 };
 
 enum {
@@ -42,74 +43,86 @@ enum {
 
 
 /* Definition of the contents of each Resource */
-struct DIRRES {
-   RES  hdr;
+class DIRRES {
+public:
+   RES   hdr;
 
-   char *password;                   /* Director password */
-   char *address;                    /* Director IP address or zero */
-   int enable_ssl;                   /* Use SSL with this Director */
-   int monitor;                      /* Have only access to status and .status functions */
+   char *password;                    /* Director password */
+   char *address;                     /* Director IP address or zero */
+   int enable_ssl;                    /* Use SSL with this Director */
+   int monitor;                       /* Have only access to status and .status functions */
 };
 
 
 /* Storage daemon "global" definitions */
-struct s_res_store {
-   RES  hdr;
+class s_res_store {
+public:
+   RES   hdr;
 
    dlist *sdaddrs;
    dlist *sddaddrs;
-   char *working_directory;          /* working directory for checkpoints */
+   char *working_directory;           /* working directory for checkpoints */
    char *pid_directory;
    char *subsys_directory;
-   int require_ssl;                  /* Require SSL on all connections */
+   int require_ssl;                   /* Require SSL on all connections */
    uint32_t max_concurrent_jobs;      /* maximum concurrent jobs to run */
-   MSGS *messages;                   /* Daemon message handler */
-   utime_t heartbeat_interval;       /* Interval to send hb to FD */
+   MSGS *messages;                    /* Daemon message handler */
+   utime_t heartbeat_interval;        /* Interval to send hb to FD */
 };
 typedef struct s_res_store STORES;
 
 /* Device specific definitions */
-struct DEVRES {
-   RES  hdr;
-
-   char *media_type;                 /* User assigned media type */
-   char *device_name;                /* Archive device name */
-   char *changer_name;               /* Changer device name */
-   char *changer_command;            /* Changer command  -- external program */
-   char *alert_command;              /* Alert command -- external program */
-   char *spool_directory;            /* Spool file directory */
-   uint32_t drive_index;             /* Autochanger drive index */
-   uint32_t cap_bits;                /* Capabilities of this device */
-   uint32_t max_changer_wait;        /* Changer timeout */
-   uint32_t max_rewind_wait;         /* maximum secs to wait for rewind */
-   uint32_t max_open_wait;           /* maximum secs to wait for open */
-   uint32_t max_open_vols;           /* maximum simultaneous open volumes */
-   uint32_t min_block_size;          /* min block size */
-   uint32_t max_block_size;          /* max block size */
-   uint32_t max_volume_jobs;         /* max jobs to put on one volume */
+class DEVRES {
+public:
+   RES   hdr;
+
+   char *media_type;                  /* User assigned media type */
+   char *device_name;                 /* Archive device name */
+   char *changer_name;                /* Changer device name */
+   char *changer_command;             /* Changer command  -- external program */
+   char *alert_command;               /* Alert command -- external program */
+   char *spool_directory;             /* Spool file directory */
+   uint32_t drive_index;              /* Autochanger drive index */
+   uint32_t cap_bits;                 /* Capabilities of this device */
+   uint32_t max_changer_wait;         /* Changer timeout */
+   uint32_t max_rewind_wait;          /* maximum secs to wait for rewind */
+   uint32_t max_open_wait;            /* maximum secs to wait for open */
+   uint32_t max_open_vols;            /* maximum simultaneous open volumes */
+   uint32_t min_block_size;           /* min block size */
+   uint32_t max_block_size;           /* max block size */
+   uint32_t max_volume_jobs;          /* max jobs to put on one volume */
    uint32_t max_network_buffer_size;  /* max network buf size */
-   utime_t  vol_poll_interval;       /* interval between polling volume during mount */
-   int64_t max_volume_files;         /* max files to put on one volume */
-   int64_t max_volume_size;          /* max bytes to put on one volume */
-   int64_t max_file_size;            /* max file size in bytes */
-   int64_t volume_capacity;          /* advisory capacity */
-   int64_t max_spool_size;           /* Max spool size for all jobs */
-   int64_t max_job_spool_size;       /* Max spool size for any single job */
+   utime_t  vol_poll_interval;        /* interval between polling volume during mount */
+   int64_t max_volume_files;          /* max files to put on one volume */
+   int64_t max_volume_size;           /* max bytes to put on one volume */
+   int64_t max_file_size;             /* max file size in bytes */
+   int64_t volume_capacity;           /* advisory capacity */
+   int64_t max_spool_size;            /* Max spool size for all jobs */
+   int64_t max_job_spool_size;        /* Max spool size for any single job */
    
-   int64_t max_part_size;            /* Max part size */
-   char *mount_point;                /* Mount point for require mount devices */
-   char *mount_command;              /* Mount command */
-   char *unmount_command;            /* Unmount command */
-   char *write_part_command;         /* Write part command */
-   char *free_space_command;         /* Free space command */
+   int64_t max_part_size;             /* Max part size */
+   char *mount_point;                 /* Mount point for require mount devices */
+   char *mount_command;               /* Mount command */
+   char *unmount_command;             /* Unmount command */
+   char *write_part_command;          /* Write part command */
+   char *free_space_command;          /* Free space command */
    
-   DEVICE *dev;                      /* Pointer to phyical dev -- set at runtime */
+   DEVICE *dev;                       /* Pointer to phyical dev -- set at runtime */
+};
+
+class AUTOCHANGER {
+public:
+   RES hdr;
+   alist *device;
+   char *changer_name;                /* Changer device name */
+   char *changer_command;             /* Changer command  -- external program */
 };
 
 union URES {
-   DIRRES res_dir;
-   STORES res_store;
-   DEVRES res_dev;
-   MSGS   res_msgs;
-   RES   hdr;
+   DIRRES      res_dir;
+   STORES      res_store;
+   DEVRES      res_dev;
+   MSGS        res_msgs;
+   AUTOCHANGER res_changer;
+   RES         hdr;
 };
index 12dcce9cdec4e372946612eda0b9d5bf24076afa..b24b17e1d163e91d378f9f638d8f43b516d4e09c 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #undef  VERSION
-#define VERSION "1.37.2"
-#define BDATE   "12 January 2005"
-#define LSMDATE "12Jan05"
+#define VERSION "1.37.3"
+#define BDATE   "28 January 2005"
+#define LSMDATE "28Jan05"
 
 /* Debug flags */
 #undef  DEBUG