]> git.sur5r.net Git - bacula/bacula/commitdiff
First cut 1.27 see kes23Oct02
authorKern Sibbald <kern@sibbald.com>
Wed, 23 Oct 2002 09:16:06 +0000 (09:16 +0000)
committerKern Sibbald <kern@sibbald.com>
Wed, 23 Oct 2002 09:16:06 +0000 (09:16 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@172 91ce42f0-d328-0410-95d8-f526ca767f89

79 files changed:
bacula/ChangeLog
bacula/Makefile.in
bacula/autoconf/config.h.in
bacula/autoconf/configure.in
bacula/configure
bacula/kernstodo
bacula/src/baconfig.h
bacula/src/cats/sql_create.c
bacula/src/cl [new file with mode: 0644]
bacula/src/dird/Makefile.in
bacula/src/dird/authenticate.c
bacula/src/dird/backup.c
bacula/src/dird/bacula-dir.conf.in
bacula/src/dird/catreq.c
bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/dird/getmsg.c
bacula/src/dird/msgchan.c
bacula/src/dird/ua_restore.c
bacula/src/dird/verify.c
bacula/src/filed/authenticate.c
bacula/src/filed/backup.c
bacula/src/filed/filed.h
bacula/src/filed/protos.h
bacula/src/filed/restore.c
bacula/src/filed/win32/winmain.cpp
bacula/src/findlib/Makefile.in
bacula/src/findlib/attribs.c [new file with mode: 0755]
bacula/src/findlib/create_file.c [new file with mode: 0644]
bacula/src/findlib/find.c
bacula/src/findlib/find.h
bacula/src/findlib/find_one.c
bacula/src/findlib/makepath.c [new file with mode: 0644]
bacula/src/findlib/match.c
bacula/src/findlib/protos.h [new file with mode: 0644]
bacula/src/findlib/save-cwd.c [new file with mode: 0644]
bacula/src/findlib/save-cwd.h [new file with mode: 0644]
bacula/src/jcr.h
bacula/src/lib/Makefile.in
bacula/src/lib/base64.c
bacula/src/lib/bnet.c
bacula/src/lib/bsock.h
bacula/src/lib/btime.c
bacula/src/lib/btime.h
bacula/src/lib/cram-md5.c
bacula/src/lib/crc32.c
bacula/src/lib/hmac.c
bacula/src/lib/lex.c
bacula/src/lib/md5.h
bacula/src/lib/parse_conf.c
bacula/src/lib/protos.h
bacula/src/lib/tree.c
bacula/src/lib/util.c
bacula/src/stored/Makefile.in
bacula/src/stored/acquire.c
bacula/src/stored/append.c
bacula/src/stored/askdir.c
bacula/src/stored/authenticate.c
bacula/src/stored/bextract.c
bacula/src/stored/block.c
bacula/src/stored/block.h
bacula/src/stored/bls.c
bacula/src/stored/bscan.c
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/job.c
bacula/src/stored/label.c
bacula/src/stored/mount.c
bacula/src/stored/protos.h
bacula/src/stored/read_record.c
bacula/src/stored/record.c
bacula/src/stored/record.h
bacula/src/stored/stored.c
bacula/src/tools/testfind.c
bacula/src/version.h

index ef7dfc497f8c838c916774574e805f2d9c5d5cff..48b5ec82f435394f44586c50152cf719ce4f06da 100644 (file)
@@ -1,4 +1,58 @@
 
+2002-mm-dd Version 1.27 (22Oct02) not yet released
+General: from kes23Oct02
+- I have mainly worked on getting all the details of a Restore
+  to work correctly (new tape format, support for Win32 
+  attributes, ...)
+- Trademarked name Bacula.
+- Implement Bacula tape format 11 (1.0 Immortal). This format
+  will be maintained forever.
+- Accept Any Volume is yes by default. This modifies Bacula's behavior
+  when writing tapes.
+
+Changes submitted this submission:
+- Corrected a bug on FreeBSD where CFLAGS would get a "yes". I was
+  unable to reproduce this, but a user confirmed the correction.
+  It was a problem with detection of largefile support, which FreeBSD 
+  has by default.
+- Added a new "license" chapter in the manual. Re-licensed a number of
+  library routines (bnet.c, hmac.c md5.c, cram-md5, ...) with LGPL so that they
+  can be used in proprietary software to access Bacula if so desired.
+- Move Director's AutoChanger doc to correct location (in Storage      
+  resource). 
+- Document why trademark (to protect compatibility).
+- Implement and turned on Bacula tape format 11 (also BB02). This
+  format moves the VolSessionId and VolSessionTime from each record 
+  header into the Block header. This is MUCH more efficient when reading
+  records as now whole blocks can be skipped.   
+  Also added JobStatus in End Of Session record, and added MD5 for
+  FileSet, which is necessary to insure uniqueness.
+- Implement a new Bacula time format for btime_t. It is Epoch time
+  in microseconds (i.e. base 1 Jan 1970 in microseconds).
+  This replaces previous floating point times.
+- Added Win32 extended attributes. In doing so, I moved all attribute
+  handling from src/lib into src/findlib.  Added new streams for 
+  Win32 attributes and for GZIP Win32 attributes.
+- Modified "Accept Any Volume" so that it really permits any volume
+  in the pool to be mounted.  
+- Removed "Mount Anonymous Volumes" from Storage daemon config.
+- Implemented sparse files. You must add "sparse=yes" on the include line
+  for it to be enabled.
+- Print "None" in backup summary rather than 0.0% if there is no compression
+  enabled.
+- Improved error checking in daemon connection/authentication code to prevent
+  garbage data from harming a Bacula daemon.
+- All daemon tools MUST have a config file.
+- Completely strip drive specification on Win32 if a Where prefix is specified.
+- Corrected DB info for writing to files. Now the File Address is stored
+  in File-Block variables in the catalog.
+- All Storage daemon tools now use common code for acquiring/reading
+  Volumes.
+- If a device is unmounted, report it even if the device is not open. This
+  will help inform users who have BLOCKED Bacula by unmounting a drive.
+
+
+=============================================================================
 2002-10-12 Version 1.26 (10Oct02)
 General: from kes10Oct02
 - Changed Job name conventions to avoid : which is an illegal
@@ -150,11 +204,12 @@ Changes submitted this submission:
 - Fix Volume in bsr.
 - Move autochanger code to new subroutine in mount.c
 
-
+=============================================================================
 2002-09-05 Version 1.25a (05Sep02) Released
 - Fix unitialized stack variable in bextract so it
   will always read the currently mounted tape.
 
+=============================================================================
 2002-09-04 Version 1.25 (01Sep02) Released
   General:
 - Added .cvsignore files in each directory to cut down on the
index a625f74472b309d0ea15f8d6042fae91809b73e2..eff60474a4aac5e841e3e575c54e9b9c545a7ff2 100755 (executable)
@@ -145,11 +145,7 @@ clean:
        @$(RMF) *~ 1 2 3 core core.* config.guess console.log console.sum
 
 
-# distclean goal is for making a clean source tree, but if you have run
-# configure from a different directory, then doesn't destroy all your
-# hardly compiled and linked stuff. That's why there is always $(srcdir)/
-# In that case most of those commands do nothing, except cleaning *~
-# and cleaning source links.
+# clean for distribution
 distclean:
        @for I in $(subdirs); do (cd $$I; $(MAKE) $@ || exit 1); done
        @for I in $(subdirs); do (cd $$I; $(RMF) startit stopit btraceback btraceback.gdb); done
index ac49e7547078a9f621dcf5722211985a26f4827c..a10fc39d97ad19220b0397d24d8a3efd27c4f83f 100644 (file)
 
 #undef HAVE_GETOPT_LONG
 
+#undef HAVE_INET_PTON
+
 /* The number of bytes in a char.  */
 #undef SIZEOF_CHAR
 
 
 /* Define for large files, on AIX-style hosts. */
 #undef _LARGE_FILES
+
index 2a86c7028678d0099b3568b5dd43e5fd8675d4ae..6a3f7cdcde19c88c1a606b902c13b036e4b3dc78 100644 (file)
@@ -681,6 +681,7 @@ dnl A few others
 AC_EXEEXT
 
 dnl See if we can use 64 bit file addresses
+largefile_support="no"
 AC_SYS_LARGEFILE
 
 
@@ -1094,7 +1095,7 @@ freebsd)
            platforms/freebsd/bacula-sd \
            platforms/freebsd/bacula-dir"
        hostname=`hostname -s`
-       ac_cv_sys_largefile_CFLAGS="yes"
+       largefile_support="yes"
   ;;
 hpux)
        DISTVER=`uname -r`
@@ -1263,7 +1264,7 @@ chmod 755 src/cats/make_bdb_tables src/cats/drop_bdb_tables
 chmod 755 src/cats/create_bdb_database
 
 if test "x$ac_cv_sys_largefile_CFLAGS" != "xno" ; then
-   ac_cv_sys_largefile_CFLAGS="yes"
+   largefile_support="yes"
 fi
 
 
@@ -1294,7 +1295,7 @@ Configuration on `date`:
   Working directory          ${working_dir}
   SQL binaries Directory      ${SQL_BINDIR}
 
-  Large file support:        $ac_cv_sys_largefile_CFLAGS
+  Large file support:        $largefile_support
   readline support:          ${got_readline} ${PRTREADLINE_SRC}
   cweb support:              ${got_cweb} ${CWEB_SRC}
   TCP Wrappers support:       ${TCPW_MSG}
index f909a8e4fcae774ef6a4ee85bb79197e0a6f3de4..74e5b4ff3935650f9f08a42dc57fc5aa2f065d46 100755 (executable)
@@ -4124,8 +4124,9 @@ echo "$ac_t""${ac_cv_exeext}" 1>&6
 ac_exeext=$EXEEXT
 
 
+largefile_support="no"
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:4129: checking build system type" >&5
+echo "configure:4130: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -4159,7 +4160,7 @@ fi
      # Extract the first word of "${ac_tool_prefix}getconf", so it can be a program name with args.
 set dummy ${ac_tool_prefix}getconf; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4163: checking for $ac_word" >&5
+echo "configure:4164: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_GETCONF'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4189,7 +4190,7 @@ fi
 
 
      echo $ac_n "checking for CFLAGS value to request large file support""... $ac_c" 1>&6
-echo "configure:4193: checking for CFLAGS value to request large file support" >&5
+echo "configure:4194: checking for CFLAGS value to request large file support" >&5
 if eval "test \"`echo '$''{'ac_cv_sys_largefile_CFLAGS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4204,14 +4205,14 @@ else
              ac_save_CC="$CC"
              CC="$CC $ac_cv_sys_largefile_CFLAGS"
              cat > conftest.$ac_ext <<EOF
-#line 4208 "configure"
+#line 4209 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:4215: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4216: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   :
 else
   echo "configure: failed program was:" >&5
@@ -4227,7 +4228,7 @@ fi
 
 echo "$ac_t""$ac_cv_sys_largefile_CFLAGS" 1>&6
      echo $ac_n "checking for LDFLAGS value to request large file support""... $ac_c" 1>&6
-echo "configure:4231: checking for LDFLAGS value to request large file support" >&5
+echo "configure:4232: checking for LDFLAGS value to request large file support" >&5
 if eval "test \"`echo '$''{'ac_cv_sys_largefile_LDFLAGS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4239,7 +4240,7 @@ fi
 
 echo "$ac_t""$ac_cv_sys_largefile_LDFLAGS" 1>&6
      echo $ac_n "checking for LIBS value to request large file support""... $ac_c" 1>&6
-echo "configure:4243: checking for LIBS value to request large file support" >&5
+echo "configure:4244: checking for LIBS value to request large file support" >&5
 if eval "test \"`echo '$''{'ac_cv_sys_largefile_LIBS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4294,7 +4295,7 @@ echo "$ac_t""$ac_cv_sys_largefile_LIBS" 1>&6
      esac ;;
    esac
      echo $ac_n "checking for _FILE_OFFSET_BITS""... $ac_c" 1>&6
-echo "configure:4298: checking for _FILE_OFFSET_BITS" >&5
+echo "configure:4299: checking for _FILE_OFFSET_BITS" >&5
 if eval "test \"`echo '$''{'ac_cv_sys_file_offset_bits'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4323,7 +4324,7 @@ EOF
 
    fi
      echo $ac_n "checking for _LARGEFILE_SOURCE""... $ac_c" 1>&6
-echo "configure:4327: checking for _LARGEFILE_SOURCE" >&5
+echo "configure:4328: checking for _LARGEFILE_SOURCE" >&5
 if eval "test \"`echo '$''{'ac_cv_sys_largefile_source'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4352,7 +4353,7 @@ EOF
 
    fi
      echo $ac_n "checking for _LARGE_FILES""... $ac_c" 1>&6
-echo "configure:4356: checking for _LARGE_FILES" >&5
+echo "configure:4357: checking for _LARGE_FILES" >&5
 if eval "test \"`echo '$''{'ac_cv_sys_large_files'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4389,7 +4390,7 @@ EOF
 # Uses ac_ vars as temps to allow command line to override cache and checks.
 # --without-x overrides everything else, but does not touch the cache.
 echo $ac_n "checking for X""... $ac_c" 1>&6
-echo "configure:4393: checking for X" >&5
+echo "configure:4394: checking for X" >&5
 
 # Check whether --with-x or --without-x was given.
 if test "${with_x+set}" = set; then
@@ -4451,12 +4452,12 @@ if test "$ac_x_includes" = NO; then
 
   # First, try using that file with no special directory specified.
 cat > conftest.$ac_ext <<EOF
-#line 4455 "configure"
+#line 4456 "configure"
 #include "confdefs.h"
 #include <$x_direct_test_include>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4460: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4461: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -4525,14 +4526,14 @@ if test "$ac_x_libraries" = NO; then
   ac_save_LIBS="$LIBS"
   LIBS="-l$x_direct_test_library $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4529 "configure"
+#line 4530 "configure"
 #include "confdefs.h"
 
 int main() {
 ${x_direct_test_function}()
 ; return 0; }
 EOF
-if { (eval echo configure:4536: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4537: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   LIBS="$ac_save_LIBS"
 # We can link X programs with no special library path.
@@ -4638,17 +4639,17 @@ else
     case "`(uname -sr) 2>/dev/null`" in
     "SunOS 5"*)
       echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6
-echo "configure:4642: checking whether -R must be followed by a space" >&5
+echo "configure:4643: checking whether -R must be followed by a space" >&5
       ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries"
       cat > conftest.$ac_ext <<EOF
-#line 4645 "configure"
+#line 4646 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:4652: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_R_nospace=yes
 else
@@ -4664,14 +4665,14 @@ rm -f conftest*
       else
        LIBS="$ac_xsave_LIBS -R $x_libraries"
        cat > conftest.$ac_ext <<EOF
-#line 4668 "configure"
+#line 4669 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:4675: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_R_space=yes
 else
@@ -4703,7 +4704,7 @@ rm -f conftest*
     # libraries were built with DECnet support.  And karl@cs.umb.edu says
     # the Alpha needs dnet_stub (dnet does not exist).
     echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6
-echo "configure:4707: checking for dnet_ntoa in -ldnet" >&5
+echo "configure:4708: checking for dnet_ntoa in -ldnet" >&5
 ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -4711,7 +4712,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldnet  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4715 "configure"
+#line 4716 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -4722,7 +4723,7 @@ int main() {
 dnet_ntoa()
 ; return 0; }
 EOF
-if { (eval echo configure:4726: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4727: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4744,7 +4745,7 @@ fi
 
     if test $ac_cv_lib_dnet_dnet_ntoa = no; then
       echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6
-echo "configure:4748: checking for dnet_ntoa in -ldnet_stub" >&5
+echo "configure:4749: checking for dnet_ntoa in -ldnet_stub" >&5
 ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -4752,7 +4753,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldnet_stub  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4756 "configure"
+#line 4757 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -4763,7 +4764,7 @@ int main() {
 dnet_ntoa()
 ; return 0; }
 EOF
-if { (eval echo configure:4767: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4768: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4792,12 +4793,12 @@ fi
     # The nsl library prevents programs from opening the X display
     # on Irix 5.2, according to dickey@clark.net.
     echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
-echo "configure:4796: checking for gethostbyname" >&5
+echo "configure:4797: checking for gethostbyname" >&5
 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4801 "configure"
+#line 4802 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char gethostbyname(); below.  */
@@ -4820,7 +4821,7 @@ gethostbyname();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4824: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_gethostbyname=yes"
 else
@@ -4841,7 +4842,7 @@ fi
 
     if test $ac_cv_func_gethostbyname = no; then
       echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
-echo "configure:4845: checking for gethostbyname in -lnsl" >&5
+echo "configure:4846: checking for gethostbyname in -lnsl" >&5
 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -4849,7 +4850,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4853 "configure"
+#line 4854 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -4860,7 +4861,7 @@ int main() {
 gethostbyname()
 ; return 0; }
 EOF
-if { (eval echo configure:4864: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4865: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4890,12 +4891,12 @@ fi
     # -lsocket must be given before -lnsl if both are needed.
     # We assume that if connect needs -lnsl, so does gethostbyname.
     echo $ac_n "checking for connect""... $ac_c" 1>&6
-echo "configure:4894: checking for connect" >&5
+echo "configure:4895: checking for connect" >&5
 if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4899 "configure"
+#line 4900 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char connect(); below.  */
@@ -4918,7 +4919,7 @@ connect();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4922: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4923: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_connect=yes"
 else
@@ -4939,7 +4940,7 @@ fi
 
     if test $ac_cv_func_connect = no; then
       echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
-echo "configure:4943: checking for connect in -lsocket" >&5
+echo "configure:4944: checking for connect in -lsocket" >&5
 ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -4947,7 +4948,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4951 "configure"
+#line 4952 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -4958,7 +4959,7 @@ int main() {
 connect()
 ; return 0; }
 EOF
-if { (eval echo configure:4962: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4963: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4982,12 +4983,12 @@ fi
 
     # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX.
     echo $ac_n "checking for remove""... $ac_c" 1>&6
-echo "configure:4986: checking for remove" >&5
+echo "configure:4987: checking for remove" >&5
 if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4991 "configure"
+#line 4992 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char remove(); below.  */
@@ -5010,7 +5011,7 @@ remove();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5014: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5015: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_remove=yes"
 else
@@ -5031,7 +5032,7 @@ fi
 
     if test $ac_cv_func_remove = no; then
       echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6
-echo "configure:5035: checking for remove in -lposix" >&5
+echo "configure:5036: checking for remove in -lposix" >&5
 ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -5039,7 +5040,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lposix  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5043 "configure"
+#line 5044 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5050,7 +5051,7 @@ int main() {
 remove()
 ; return 0; }
 EOF
-if { (eval echo configure:5054: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5055: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5074,12 +5075,12 @@ fi
 
     # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
     echo $ac_n "checking for shmat""... $ac_c" 1>&6
-echo "configure:5078: checking for shmat" >&5
+echo "configure:5079: checking for shmat" >&5
 if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5083 "configure"
+#line 5084 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char shmat(); below.  */
@@ -5102,7 +5103,7 @@ shmat();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5106: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5107: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_shmat=yes"
 else
@@ -5123,7 +5124,7 @@ fi
 
     if test $ac_cv_func_shmat = no; then
       echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6
-echo "configure:5127: checking for shmat in -lipc" >&5
+echo "configure:5128: checking for shmat in -lipc" >&5
 ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -5131,7 +5132,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lipc  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5135 "configure"
+#line 5136 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5142,7 +5143,7 @@ int main() {
 shmat()
 ; return 0; }
 EOF
-if { (eval echo configure:5146: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5147: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5175,7 +5176,7 @@ fi
   # libraries we check for below, so use a different variable.
   #  --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
   echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6
-echo "configure:5179: checking for IceConnectionNumber in -lICE" >&5
+echo "configure:5180: checking for IceConnectionNumber in -lICE" >&5
 ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -5183,7 +5184,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lICE $X_EXTRA_LIBS $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5187 "configure"
+#line 5188 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5194,7 +5195,7 @@ int main() {
 IceConnectionNumber()
 ; return 0; }
 EOF
-if { (eval echo configure:5198: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5199: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5239,17 +5240,17 @@ for ac_hdr in \
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:5243: checking for $ac_hdr" >&5
+echo "configure:5244: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5248 "configure"
+#line 5249 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5253: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5254: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -5276,12 +5277,12 @@ fi
 done
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:5280: checking for ANSI C header files" >&5
+echo "configure:5281: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5285 "configure"
+#line 5286 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -5289,7 +5290,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5293: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5294: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -5306,7 +5307,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 5310 "configure"
+#line 5311 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -5324,7 +5325,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 5328 "configure"
+#line 5329 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -5345,7 +5346,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 5349 "configure"
+#line 5350 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -5356,7 +5357,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:5360: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5361: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -5380,19 +5381,19 @@ EOF
 fi
 
 echo $ac_n "checking whether sys/types.h defines makedev""... $ac_c" 1>&6
-echo "configure:5384: checking whether sys/types.h defines makedev" >&5
+echo "configure:5385: checking whether sys/types.h defines makedev" >&5
 if eval "test \"`echo '$''{'ac_cv_header_sys_types_h_makedev'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5389 "configure"
+#line 5390 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 int main() {
 return makedev(0, 0);
 ; return 0; }
 EOF
-if { (eval echo configure:5396: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5397: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_header_sys_types_h_makedev=yes
 else
@@ -5410,17 +5411,17 @@ echo "$ac_t""$ac_cv_header_sys_types_h_makedev" 1>&6
 if test $ac_cv_header_sys_types_h_makedev = no; then
 ac_safe=`echo "sys/mkdev.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for sys/mkdev.h""... $ac_c" 1>&6
-echo "configure:5414: checking for sys/mkdev.h" >&5
+echo "configure:5415: checking for sys/mkdev.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5419 "configure"
+#line 5420 "configure"
 #include "confdefs.h"
 #include <sys/mkdev.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5424: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5425: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -5448,17 +5449,17 @@ fi
   if test $ac_cv_header_sys_mkdev_h = no; then
 ac_safe=`echo "sys/sysmacros.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for sys/sysmacros.h""... $ac_c" 1>&6
-echo "configure:5452: checking for sys/sysmacros.h" >&5
+echo "configure:5453: checking for sys/sysmacros.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5457 "configure"
+#line 5458 "configure"
 #include "confdefs.h"
 #include <sys/sysmacros.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5462: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5463: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -5490,12 +5491,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
-echo "configure:5494: checking for $ac_hdr that defines DIR" >&5
+echo "configure:5495: checking for $ac_hdr that defines DIR" >&5
 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5499 "configure"
+#line 5500 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <$ac_hdr>
@@ -5503,7 +5504,7 @@ int main() {
 DIR *dirp = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:5507: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5508: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_header_dirent_$ac_safe=yes"
 else
@@ -5528,7 +5529,7 @@ done
 # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
 if test $ac_header_dirent = dirent.h; then
 echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
-echo "configure:5532: checking for opendir in -ldir" >&5
+echo "configure:5533: checking for opendir in -ldir" >&5
 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -5536,7 +5537,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldir  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5540 "configure"
+#line 5541 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5547,7 +5548,7 @@ int main() {
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:5551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5552: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5569,7 +5570,7 @@ fi
 
 else
 echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:5573: checking for opendir in -lx" >&5
+echo "configure:5574: checking for opendir in -lx" >&5
 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -5577,7 +5578,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lx  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5581 "configure"
+#line 5582 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5588,7 +5589,7 @@ int main() {
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:5592: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5593: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5611,12 +5612,12 @@ fi
 fi
 
 echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
-echo "configure:5615: checking whether stat file-mode macros are broken" >&5
+echo "configure:5616: checking whether stat file-mode macros are broken" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5620 "configure"
+#line 5621 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -5667,12 +5668,12 @@ EOF
 fi
 
 echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:5671: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo "configure:5672: checking for sys/wait.h that is POSIX.1 compatible" >&5
 if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5676 "configure"
+#line 5677 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -5688,7 +5689,7 @@ wait (&s);
 s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
 ; return 0; }
 EOF
-if { (eval echo configure:5692: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5693: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_sys_wait_h=yes
 else
@@ -5709,12 +5710,12 @@ EOF
 fi
 
 echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:5713: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:5714: checking whether time.h and sys/time.h may both be included" >&5
 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5718 "configure"
+#line 5719 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/time.h>
@@ -5723,7 +5724,7 @@ int main() {
 struct tm *tp;
 ; return 0; }
 EOF
-if { (eval echo configure:5727: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5728: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_time=yes
 else
@@ -5744,12 +5745,12 @@ EOF
 fi
 
 echo $ac_n "checking for st_blksize in struct stat""... $ac_c" 1>&6
-echo "configure:5748: checking for st_blksize in struct stat" >&5
+echo "configure:5749: checking for st_blksize in struct stat" >&5
 if eval "test \"`echo '$''{'ac_cv_struct_st_blksize'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5753 "configure"
+#line 5754 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -5757,7 +5758,7 @@ int main() {
 struct stat s; s.st_blksize;
 ; return 0; }
 EOF
-if { (eval echo configure:5761: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5762: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_st_blksize=yes
 else
@@ -5778,12 +5779,12 @@ EOF
 fi
 
 echo $ac_n "checking for st_blocks in struct stat""... $ac_c" 1>&6
-echo "configure:5782: checking for st_blocks in struct stat" >&5
+echo "configure:5783: checking for st_blocks in struct stat" >&5
 if eval "test \"`echo '$''{'ac_cv_struct_st_blocks'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5787 "configure"
+#line 5788 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -5791,7 +5792,7 @@ int main() {
 struct stat s; s.st_blocks;
 ; return 0; }
 EOF
-if { (eval echo configure:5795: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5796: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_st_blocks=yes
 else
@@ -5814,12 +5815,12 @@ else
 fi
 
 echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
-echo "configure:5818: checking whether struct tm is in sys/time.h or time.h" >&5
+echo "configure:5819: checking whether struct tm is in sys/time.h or time.h" >&5
 if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5823 "configure"
+#line 5824 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <time.h>
@@ -5827,7 +5828,7 @@ int main() {
 struct tm *tp; tp->tm_sec;
 ; return 0; }
 EOF
-if { (eval echo configure:5831: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5832: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_tm=time.h
 else
@@ -5848,12 +5849,12 @@ EOF
 fi
 
 echo $ac_n "checking for tm_zone in struct tm""... $ac_c" 1>&6
-echo "configure:5852: checking for tm_zone in struct tm" >&5
+echo "configure:5853: checking for tm_zone in struct tm" >&5
 if eval "test \"`echo '$''{'ac_cv_struct_tm_zone'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5857 "configure"
+#line 5858 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <$ac_cv_struct_tm>
@@ -5861,7 +5862,7 @@ int main() {
 struct tm tm; tm.tm_zone;
 ; return 0; }
 EOF
-if { (eval echo configure:5865: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5866: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_tm_zone=yes
 else
@@ -5881,12 +5882,12 @@ EOF
 
 else
   echo $ac_n "checking for tzname""... $ac_c" 1>&6
-echo "configure:5885: checking for tzname" >&5
+echo "configure:5886: checking for tzname" >&5
 if eval "test \"`echo '$''{'ac_cv_var_tzname'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5890 "configure"
+#line 5891 "configure"
 #include "confdefs.h"
 #include <time.h>
 #ifndef tzname /* For SGI.  */
@@ -5896,7 +5897,7 @@ int main() {
 atoi(*tzname);
 ; return 0; }
 EOF
-if { (eval echo configure:5900: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5901: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_var_tzname=yes
 else
@@ -5923,12 +5924,12 @@ fi
 # be POSIX, POSIX_C, ALL, HPUX or whatever, depending on the machine.
 
 echo $ac_n "checking for utime.h""... $ac_c" 1>&6
-echo "configure:5927: checking for utime.h" >&5
+echo "configure:5928: checking for utime.h" >&5
 if eval "test \"`echo '$''{'tar_cv_header_utime_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5932 "configure"
+#line 5933 "configure"
 #include "confdefs.h"
 
 #include <sys/types.h>
@@ -5937,7 +5938,7 @@ int main() {
 struct utimbuf foo
 ; return 0; }
 EOF
-if { (eval echo configure:5941: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5942: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   tar_cv_header_utime_h=yes
 else
@@ -5956,12 +5957,12 @@ EOF
 
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:5960: checking for working const" >&5
+echo "configure:5961: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5965 "configure"
+#line 5966 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -6010,7 +6011,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if { (eval echo configure:6014: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6015: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -6033,17 +6034,17 @@ fi
 
 
 echo $ac_n "checking how to get filesystem type""... $ac_c" 1>&6
-echo "configure:6037: checking how to get filesystem type" >&5
+echo "configure:6038: checking how to get filesystem type" >&5
 fstype=no
 # The order of these tests is important.
 cat > conftest.$ac_ext <<EOF
-#line 6041 "configure"
+#line 6042 "configure"
 #include "confdefs.h"
 #include <sys/statvfs.h>
 #include <sys/fstyp.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6047: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6048: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -6059,13 +6060,13 @@ fi
 rm -f conftest*
 if test $fstype = no; then
 cat > conftest.$ac_ext <<EOF
-#line 6063 "configure"
+#line 6064 "configure"
 #include "confdefs.h"
 #include <sys/statfs.h>
 #include <sys/fstyp.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6069: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6070: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -6082,13 +6083,13 @@ rm -f conftest*
 fi
 if test $fstype = no; then
 cat > conftest.$ac_ext <<EOF
-#line 6086 "configure"
+#line 6087 "configure"
 #include "confdefs.h"
 #include <sys/statfs.h>
 #include <sys/vmount.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6092: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6093: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -6105,12 +6106,12 @@ rm -f conftest*
 fi
 if test $fstype = no; then  
 cat > conftest.$ac_ext <<EOF
-#line 6109 "configure"
+#line 6110 "configure"
 #include "confdefs.h"
 #include <mntent.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6114: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6115: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -6127,7 +6128,7 @@ rm -f conftest*
 fi
 if test $fstype = no; then  
 cat > conftest.$ac_ext <<EOF
-#line 6131 "configure"
+#line 6132 "configure"
 #include "confdefs.h"
 #include <sys/mount.h>
 EOF
@@ -6144,13 +6145,13 @@ rm -f conftest*
 fi
 if test $fstype = no; then  
 cat > conftest.$ac_ext <<EOF
-#line 6148 "configure"
+#line 6149 "configure"
 #include "confdefs.h"
 #include <sys/mount.h>
 #include <sys/fs_types.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6154: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6155: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -6168,12 +6169,12 @@ fi
 echo "$ac_t""$fstype" 1>&6
 
 echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:6172: checking return type of signal handlers" >&5
+echo "configure:6173: checking return type of signal handlers" >&5
 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6177 "configure"
+#line 6178 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <signal.h>
@@ -6190,7 +6191,7 @@ int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:6194: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6195: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_signal=void
 else
@@ -6210,13 +6211,13 @@ EOF
 
 
 echo $ac_n "checking for type of signal functions""... $ac_c" 1>&6
-echo "configure:6214: checking for type of signal functions" >&5
+echo "configure:6215: checking for type of signal functions" >&5
 if eval "test \"`echo '$''{'bash_cv_signal_vintage'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 6220 "configure"
+#line 6221 "configure"
 #include "confdefs.h"
 #include <signal.h>
 int main() {
@@ -6229,7 +6230,7 @@ int main() {
   
 ; return 0; }
 EOF
-if { (eval echo configure:6233: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   bash_cv_signal_vintage=posix
 else
@@ -6238,7 +6239,7 @@ else
   rm -rf conftest*
   
     cat > conftest.$ac_ext <<EOF
-#line 6242 "configure"
+#line 6243 "configure"
 #include "confdefs.h"
 #include <signal.h>
 int main() {
@@ -6248,7 +6249,7 @@ int main() {
     
 ; return 0; }
 EOF
-if { (eval echo configure:6252: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6253: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   bash_cv_signal_vintage=4.2bsd
 else
@@ -6257,7 +6258,7 @@ else
   rm -rf conftest*
   
       cat > conftest.$ac_ext <<EOF
-#line 6261 "configure"
+#line 6262 "configure"
 #include "confdefs.h"
 
         #include <signal.h>
@@ -6270,7 +6271,7 @@ int main() {
         
 ; return 0; }
 EOF
-if { (eval echo configure:6274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6275: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   bash_cv_signal_vintage=svr3
 else
@@ -6309,12 +6310,12 @@ EOF
 fi
 
 echo $ac_n "checking for mode_t""... $ac_c" 1>&6
-echo "configure:6313: checking for mode_t" >&5
+echo "configure:6314: checking for mode_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6318 "configure"
+#line 6319 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6342,12 +6343,12 @@ EOF
 fi
 
 echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-echo "configure:6346: checking for uid_t in sys/types.h" >&5
+echo "configure:6347: checking for uid_t in sys/types.h" >&5
 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6351 "configure"
+#line 6352 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 EOF
@@ -6376,12 +6377,12 @@ EOF
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:6380: checking for size_t" >&5
+echo "configure:6381: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6385 "configure"
+#line 6386 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6409,12 +6410,12 @@ EOF
 fi
 
 echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:6413: checking for pid_t" >&5
+echo "configure:6414: checking for pid_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6418 "configure"
+#line 6419 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6442,12 +6443,12 @@ EOF
 fi
 
 echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:6446: checking for off_t" >&5
+echo "configure:6447: checking for off_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6451 "configure"
+#line 6452 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6475,12 +6476,12 @@ EOF
 fi
 
 echo $ac_n "checking for ino_t""... $ac_c" 1>&6
-echo "configure:6479: checking for ino_t" >&5
+echo "configure:6480: checking for ino_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_ino_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6484 "configure"
+#line 6485 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6508,12 +6509,12 @@ EOF
 fi
 
 echo $ac_n "checking for dev_t""... $ac_c" 1>&6
-echo "configure:6512: checking for dev_t" >&5
+echo "configure:6513: checking for dev_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_dev_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6517 "configure"
+#line 6518 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6541,12 +6542,12 @@ EOF
 fi
 
 echo $ac_n "checking for daddr_t""... $ac_c" 1>&6
-echo "configure:6545: checking for daddr_t" >&5
+echo "configure:6546: checking for daddr_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_daddr_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6550 "configure"
+#line 6551 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6574,12 +6575,12 @@ EOF
 fi
 
 echo $ac_n "checking for major_t""... $ac_c" 1>&6
-echo "configure:6578: checking for major_t" >&5
+echo "configure:6579: checking for major_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_major_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6583 "configure"
+#line 6584 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6607,12 +6608,12 @@ EOF
 fi
 
 echo $ac_n "checking for minor_t""... $ac_c" 1>&6
-echo "configure:6611: checking for minor_t" >&5
+echo "configure:6612: checking for minor_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_minor_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6616 "configure"
+#line 6617 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6640,12 +6641,12 @@ EOF
 fi
 
 echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
-echo "configure:6644: checking for ssize_t" >&5
+echo "configure:6645: checking for ssize_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6649 "configure"
+#line 6650 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6673,12 +6674,12 @@ EOF
 fi
 
 echo $ac_n "checking for st_blocks in struct stat""... $ac_c" 1>&6
-echo "configure:6677: checking for st_blocks in struct stat" >&5
+echo "configure:6678: checking for st_blocks in struct stat" >&5
 if eval "test \"`echo '$''{'ac_cv_struct_st_blocks'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6682 "configure"
+#line 6683 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -6686,7 +6687,7 @@ int main() {
 struct stat s; s.st_blocks;
 ; return 0; }
 EOF
-if { (eval echo configure:6690: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6691: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_st_blocks=yes
 else
@@ -6709,12 +6710,12 @@ else
 fi
 
 echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6
-echo "configure:6713: checking for st_rdev in struct stat" >&5
+echo "configure:6714: checking for st_rdev in struct stat" >&5
 if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6718 "configure"
+#line 6719 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -6722,7 +6723,7 @@ int main() {
 struct stat s; s.st_rdev;
 ; return 0; }
 EOF
-if { (eval echo configure:6726: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6727: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_st_rdev=yes
 else
@@ -6743,12 +6744,12 @@ EOF
 fi
 
 echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
-echo "configure:6747: checking whether struct tm is in sys/time.h or time.h" >&5
+echo "configure:6748: checking whether struct tm is in sys/time.h or time.h" >&5
 if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6752 "configure"
+#line 6753 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <time.h>
@@ -6756,7 +6757,7 @@ int main() {
 struct tm *tp; tp->tm_sec;
 ; return 0; }
 EOF
-if { (eval echo configure:6760: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6761: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_tm=time.h
 else
@@ -6777,12 +6778,12 @@ EOF
 fi
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:6781: checking for working const" >&5
+echo "configure:6782: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6786 "configure"
+#line 6787 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -6831,7 +6832,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if { (eval echo configure:6835: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6836: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -6854,7 +6855,7 @@ fi
 
 
 echo $ac_n "checking size of char""... $ac_c" 1>&6
-echo "configure:6858: checking size of char" >&5
+echo "configure:6859: checking size of char" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_char'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6862,7 +6863,7 @@ else
   ac_cv_sizeof_char=1
 else
   cat > conftest.$ac_ext <<EOF
-#line 6866 "configure"
+#line 6867 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 int main()
@@ -6873,7 +6874,7 @@ int main()
   return(0);
 }
 EOF
-if { (eval echo configure:6877: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6878: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_char=`cat conftestval`
 else
@@ -6893,7 +6894,7 @@ EOF
 
 
 echo $ac_n "checking size of short int""... $ac_c" 1>&6
-echo "configure:6897: checking size of short int" >&5
+echo "configure:6898: checking size of short int" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_short_int'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6901,7 +6902,7 @@ else
   ac_cv_sizeof_short_int=2
 else
   cat > conftest.$ac_ext <<EOF
-#line 6905 "configure"
+#line 6906 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 int main()
@@ -6912,7 +6913,7 @@ int main()
   return(0);
 }
 EOF
-if { (eval echo configure:6916: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6917: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_short_int=`cat conftestval`
 else
@@ -6932,7 +6933,7 @@ EOF
 
 
 echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:6936: checking size of int" >&5
+echo "configure:6937: checking size of int" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6940,7 +6941,7 @@ else
   ac_cv_sizeof_int=4
 else
   cat > conftest.$ac_ext <<EOF
-#line 6944 "configure"
+#line 6945 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 int main()
@@ -6951,7 +6952,7 @@ int main()
   return(0);
 }
 EOF
-if { (eval echo configure:6955: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6956: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_int=`cat conftestval`
 else
@@ -6971,7 +6972,7 @@ EOF
 
 
 echo $ac_n "checking size of long int""... $ac_c" 1>&6
-echo "configure:6975: checking size of long int" >&5
+echo "configure:6976: checking size of long int" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_long_int'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6979,7 +6980,7 @@ else
   ac_cv_sizeof_long_int=4
 else
   cat > conftest.$ac_ext <<EOF
-#line 6983 "configure"
+#line 6984 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 int main()
@@ -6990,7 +6991,7 @@ int main()
   return(0);
 }
 EOF
-if { (eval echo configure:6994: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6995: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long_int=`cat conftestval`
 else
@@ -7010,7 +7011,7 @@ EOF
 
 
 echo $ac_n "checking size of long long int""... $ac_c" 1>&6
-echo "configure:7014: checking size of long long int" >&5
+echo "configure:7015: checking size of long long int" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_long_long_int'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7018,7 +7019,7 @@ else
   ac_cv_sizeof_long_long_int=8
 else
   cat > conftest.$ac_ext <<EOF
-#line 7022 "configure"
+#line 7023 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 int main()
@@ -7029,7 +7030,7 @@ int main()
   return(0);
 }
 EOF
-if { (eval echo configure:7033: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7034: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long_long_int=`cat conftestval`
 else
@@ -7049,7 +7050,7 @@ EOF
 
 
 echo $ac_n "checking size of int *""... $ac_c" 1>&6
-echo "configure:7053: checking size of int *" >&5
+echo "configure:7054: checking size of int *" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_int_p'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7057,7 +7058,7 @@ else
   ac_cv_sizeof_int_p=4
 else
   cat > conftest.$ac_ext <<EOF
-#line 7061 "configure"
+#line 7062 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 int main()
@@ -7068,7 +7069,7 @@ int main()
   return(0);
 }
 EOF
-if { (eval echo configure:7072: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7073: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_int_p=`cat conftestval`
 else
@@ -7090,20 +7091,20 @@ EOF
 
 # Check for sys/types.h types
 echo $ac_n "checking for u_int type""... $ac_c" 1>&6
-echo "configure:7094: checking for u_int type" >&5
+echo "configure:7095: checking for u_int type" >&5
 if eval "test \"`echo '$''{'ac_cv_have_u_int'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
     cat > conftest.$ac_ext <<EOF
-#line 7100 "configure"
+#line 7101 "configure"
 #include "confdefs.h"
  #include <sys/types.h> 
 int main() {
  u_int a; a = 1;
 ; return 0; }
 EOF
-if { (eval echo configure:7107: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7108: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
    ac_cv_have_u_int="yes" 
 else
@@ -7127,20 +7128,20 @@ EOF
 fi
 
 echo $ac_n "checking for intmax_t type""... $ac_c" 1>&6
-echo "configure:7131: checking for intmax_t type" >&5
+echo "configure:7132: checking for intmax_t type" >&5
 if eval "test \"`echo '$''{'ac_cv_have_intmax_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
    cat > conftest.$ac_ext <<EOF
-#line 7137 "configure"
+#line 7138 "configure"
 #include "confdefs.h"
  #include <sys/types.h> 
 int main() {
  intmax_t a; a = 1;
 ; return 0; }
 EOF
-if { (eval echo configure:7144: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7145: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
    ac_cv_have_intmax_t="yes" 
 else
@@ -7149,14 +7150,14 @@ else
   rm -rf conftest*
    
         cat > conftest.$ac_ext <<EOF
-#line 7153 "configure"
+#line 7154 "configure"
 #include "confdefs.h"
  #include <stdint.h> 
 int main() {
  intmax_t a; a = 1;
 ; return 0; }
 EOF
-if { (eval echo configure:7160: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7161: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
    ac_cv_have_intmax_t="yes" 
 else
@@ -7186,20 +7187,20 @@ fi
 
 
 echo $ac_n "checking for u_intmax_t type""... $ac_c" 1>&6
-echo "configure:7190: checking for u_intmax_t type" >&5
+echo "configure:7191: checking for u_intmax_t type" >&5
 if eval "test \"`echo '$''{'ac_cv_have_u_intmax_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
    cat > conftest.$ac_ext <<EOF
-#line 7196 "configure"
+#line 7197 "configure"
 #include "confdefs.h"
  #include <sys/types.h> 
 int main() {
  u_intmax_t a; a = 1;
 ; return 0; }
 EOF
-if { (eval echo configure:7203: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7204: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
    ac_cv_have_u_intmax_t="yes" 
 else
@@ -7208,14 +7209,14 @@ else
   rm -rf conftest*
    
         cat > conftest.$ac_ext <<EOF
-#line 7212 "configure"
+#line 7213 "configure"
 #include "confdefs.h"
  #include <stdint.h> 
 int main() {
  u_intmax_t a; a = 1;
 ; return 0; }
 EOF
-if { (eval echo configure:7219: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7220: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
    ac_cv_have_u_intmax_t="yes" 
 else
@@ -7244,20 +7245,20 @@ fi
 
 
 echo $ac_n "checking for intXX_t types""... $ac_c" 1>&6
-echo "configure:7248: checking for intXX_t types" >&5
+echo "configure:7249: checking for intXX_t types" >&5
 if eval "test \"`echo '$''{'ac_cv_have_intxx_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
    cat > conftest.$ac_ext <<EOF
-#line 7254 "configure"
+#line 7255 "configure"
 #include "confdefs.h"
  #include <sys/types.h> 
 int main() {
  int8_t a; int16_t b; int32_t c; a = b = c = 1;
 ; return 0; }
 EOF
-if { (eval echo configure:7261: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7262: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
    ac_cv_have_intxx_t="yes" 
 else
@@ -7281,20 +7282,20 @@ EOF
 fi
        
 echo $ac_n "checking for int64_t type""... $ac_c" 1>&6
-echo "configure:7285: checking for int64_t type" >&5
+echo "configure:7286: checking for int64_t type" >&5
 if eval "test \"`echo '$''{'ac_cv_have_int64_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
    cat > conftest.$ac_ext <<EOF
-#line 7291 "configure"
+#line 7292 "configure"
 #include "confdefs.h"
  #include <sys/types.h> 
 int main() {
  int64_t a; a = 1;
 ; return 0; }
 EOF
-if { (eval echo configure:7298: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7299: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
    ac_cv_have_int64_t="yes" 
 else
@@ -7318,20 +7319,20 @@ EOF
 fi
        
 echo $ac_n "checking for u_intXX_t types""... $ac_c" 1>&6
-echo "configure:7322: checking for u_intXX_t types" >&5
+echo "configure:7323: checking for u_intXX_t types" >&5
 if eval "test \"`echo '$''{'ac_cv_have_u_intxx_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
    cat > conftest.$ac_ext <<EOF
-#line 7328 "configure"
+#line 7329 "configure"
 #include "confdefs.h"
  #include <sys/types.h> 
 int main() {
  u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;
 ; return 0; }
 EOF
-if { (eval echo configure:7335: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7336: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
    ac_cv_have_u_intxx_t="yes" 
 else
@@ -7355,20 +7356,20 @@ EOF
 fi
 
 echo $ac_n "checking for u_int64_t types""... $ac_c" 1>&6
-echo "configure:7359: checking for u_int64_t types" >&5
+echo "configure:7360: checking for u_int64_t types" >&5
 if eval "test \"`echo '$''{'ac_cv_have_u_int64_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
    cat > conftest.$ac_ext <<EOF
-#line 7365 "configure"
+#line 7366 "configure"
 #include "confdefs.h"
  #include <sys/types.h> 
 int main() {
  u_int64_t a; a = 1;
 ; return 0; }
 EOF
-if { (eval echo configure:7372: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7373: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
    ac_cv_have_u_int64_t="yes" 
 else
@@ -7395,9 +7396,9 @@ if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \
           test "x$ac_cv_header_sys_bitypes_h" = "xyes")
 then
    echo $ac_n "checking for intXX_t and u_intXX_t types in sys/bitypes.h""... $ac_c" 1>&6
-echo "configure:7399: checking for intXX_t and u_intXX_t types in sys/bitypes.h" >&5
+echo "configure:7400: checking for intXX_t and u_intXX_t types in sys/bitypes.h" >&5
    cat > conftest.$ac_ext <<EOF
-#line 7401 "configure"
+#line 7402 "configure"
 #include "confdefs.h"
  #include <sys/bitypes.h>  
 int main() {
@@ -7406,7 +7407,7 @@ int main() {
        a = b = c = e = f = g = 1;  
 ; return 0; }
 EOF
-if { (eval echo configure:7410: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7411: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
    cat >> confdefs.h <<\EOF
 #define HAVE_U_INTXX_T 1
@@ -7433,13 +7434,13 @@ fi
 
 if test -z "$have_u_intxx_t" ; then
    echo $ac_n "checking for uintXX_t types""... $ac_c" 1>&6
-echo "configure:7437: checking for uintXX_t types" >&5
+echo "configure:7438: checking for uintXX_t types" >&5
 if eval "test \"`echo '$''{'ac_cv_have_uintxx_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
       cat > conftest.$ac_ext <<EOF
-#line 7443 "configure"
+#line 7444 "configure"
 #include "confdefs.h"
  #include <sys/types.h> 
 int main() {
@@ -7447,7 +7448,7 @@ int main() {
           uint32_t c; a = b = c = 1; 
 ; return 0; }
 EOF
-if { (eval echo configure:7451: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7452: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
    ac_cv_have_uintxx_t="yes" 
 else
@@ -7487,12 +7488,12 @@ for ac_func in \
        
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7491: checking for $ac_func" >&5
+echo "configure:7492: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7496 "configure"
+#line 7497 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7515,7 +7516,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:7519: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7520: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7545,12 +7546,12 @@ done
 for ac_func in fchdir
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7549: checking for $ac_func" >&5
+echo "configure:7550: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7554 "configure"
+#line 7555 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7573,7 +7574,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:7577: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7578: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7604,12 +7605,12 @@ done
 for ac_func in snprintf vsnprintf gethostid getdomainname
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7608: checking for $ac_func" >&5
+echo "configure:7609: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7613 "configure"
+#line 7614 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7632,7 +7633,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:7636: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7637: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7660,12 +7661,12 @@ done
 for ac_func in localtime_r readdir_r strerror_r gethostbyname_r
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7664: checking for $ac_func" >&5
+echo "configure:7665: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7669 "configure"
+#line 7670 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7688,7 +7689,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:7692: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7693: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7715,12 +7716,12 @@ done
 
 # If resolver functions are not in libc check for -lnsl or -lresolv.
 echo $ac_n "checking for gethostbyname_r""... $ac_c" 1>&6
-echo "configure:7719: checking for gethostbyname_r" >&5
+echo "configure:7720: checking for gethostbyname_r" >&5
 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname_r'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7724 "configure"
+#line 7725 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char gethostbyname_r(); below.  */
@@ -7743,7 +7744,7 @@ gethostbyname_r();
 
 ; return 0; }
 EOF
-if { (eval echo configure:7747: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7748: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_gethostbyname_r=yes"
 else
@@ -7761,7 +7762,7 @@ if eval "test \"`echo '$ac_cv_func_'gethostbyname_r`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for gethostbyname_r in -lnsl""... $ac_c" 1>&6
-echo "configure:7765: checking for gethostbyname_r in -lnsl" >&5
+echo "configure:7766: checking for gethostbyname_r in -lnsl" >&5
 ac_lib_var=`echo nsl'_'gethostbyname_r | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7769,7 +7770,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7773 "configure"
+#line 7774 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7780,7 +7781,7 @@ int main() {
 gethostbyname_r()
 ; return 0; }
 EOF
-if { (eval echo configure:7784: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7785: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7808,7 +7809,7 @@ else
 fi
 
     echo $ac_n "checking for gethostbyname_r in -lresolv""... $ac_c" 1>&6
-echo "configure:7812: checking for gethostbyname_r in -lresolv" >&5
+echo "configure:7813: checking for gethostbyname_r in -lresolv" >&5
 ac_lib_var=`echo resolv'_'gethostbyname_r | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7816,7 +7817,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lresolv  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7820 "configure"
+#line 7821 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7827,7 +7828,7 @@ int main() {
 gethostbyname_r()
 ; return 0; }
 EOF
-if { (eval echo configure:7831: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7832: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7860,12 +7861,12 @@ fi
 
 # Find where sockets are (especially for Solaris)
 echo $ac_n "checking for socket""... $ac_c" 1>&6
-echo "configure:7864: checking for socket" >&5
+echo "configure:7865: checking for socket" >&5
 if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7869 "configure"
+#line 7870 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char socket(); below.  */
@@ -7888,7 +7889,7 @@ socket();
 
 ; return 0; }
 EOF
-if { (eval echo configure:7892: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7893: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_socket=yes"
 else
@@ -7906,7 +7907,7 @@ if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for socket in -lxnet""... $ac_c" 1>&6
-echo "configure:7910: checking for socket in -lxnet" >&5
+echo "configure:7911: checking for socket in -lxnet" >&5
 ac_lib_var=`echo xnet'_'socket | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7914,7 +7915,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lxnet  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7918 "configure"
+#line 7919 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7925,7 +7926,7 @@ int main() {
 socket()
 ; return 0; }
 EOF
-if { (eval echo configure:7929: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7930: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7953,7 +7954,7 @@ else
 fi
 
     echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6
-echo "configure:7957: checking for socket in -lsocket" >&5
+echo "configure:7958: checking for socket in -lsocket" >&5
 ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7961,7 +7962,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7965 "configure"
+#line 7966 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7972,7 +7973,7 @@ int main() {
 socket()
 ; return 0; }
 EOF
-if { (eval echo configure:7976: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7977: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8000,7 +8001,7 @@ else
 fi
 
     echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6
-echo "configure:8004: checking for socket in -linet" >&5
+echo "configure:8005: checking for socket in -linet" >&5
 ac_lib_var=`echo inet'_'socket | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -8008,7 +8009,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-linet  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8012 "configure"
+#line 8013 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8019,7 +8020,7 @@ int main() {
 socket()
 ; return 0; }
 EOF
-if { (eval echo configure:8023: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8024: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8052,12 +8053,12 @@ fi
 for ac_func in inet_pton
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:8056: checking for $ac_func" >&5
+echo "configure:8057: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8061 "configure"
+#line 8062 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -8080,7 +8081,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:8084: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8085: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -8109,12 +8110,12 @@ done
 
 
 echo $ac_n "checking for strftime""... $ac_c" 1>&6
-echo "configure:8113: checking for strftime" >&5
+echo "configure:8114: checking for strftime" >&5
 if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8118 "configure"
+#line 8119 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char strftime(); below.  */
@@ -8137,7 +8138,7 @@ strftime();
 
 ; return 0; }
 EOF
-if { (eval echo configure:8141: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8142: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_strftime=yes"
 else
@@ -8159,7 +8160,7 @@ else
   echo "$ac_t""no" 1>&6
 # strftime is in -lintl on SCO UNIX.
 echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6
-echo "configure:8163: checking for strftime in -lintl" >&5
+echo "configure:8164: checking for strftime in -lintl" >&5
 ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -8167,7 +8168,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lintl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8171 "configure"
+#line 8172 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8178,7 +8179,7 @@ int main() {
 strftime()
 ; return 0; }
 EOF
-if { (eval echo configure:8182: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8183: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8205,12 +8206,12 @@ fi
 fi
 
 echo $ac_n "checking for vprintf""... $ac_c" 1>&6
-echo "configure:8209: checking for vprintf" >&5
+echo "configure:8210: checking for vprintf" >&5
 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8214 "configure"
+#line 8215 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char vprintf(); below.  */
@@ -8233,7 +8234,7 @@ vprintf();
 
 ; return 0; }
 EOF
-if { (eval echo configure:8237: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8238: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_vprintf=yes"
 else
@@ -8257,12 +8258,12 @@ fi
 
 if test "$ac_cv_func_vprintf" != yes; then
 echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
-echo "configure:8261: checking for _doprnt" >&5
+echo "configure:8262: checking for _doprnt" >&5
 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8266 "configure"
+#line 8267 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char _doprnt(); below.  */
@@ -8285,7 +8286,7 @@ _doprnt();
 
 ; return 0; }
 EOF
-if { (eval echo configure:8289: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8290: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func__doprnt=yes"
 else
@@ -8312,19 +8313,19 @@ fi
 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
 echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:8316: checking for working alloca.h" >&5
+echo "configure:8317: checking for working alloca.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8321 "configure"
+#line 8322 "configure"
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
 char *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
-if { (eval echo configure:8328: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8329: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_header_alloca_h=yes
 else
@@ -8345,12 +8346,12 @@ EOF
 fi
 
 echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:8349: checking for alloca" >&5
+echo "configure:8350: checking for alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8354 "configure"
+#line 8355 "configure"
 #include "confdefs.h"
 
 #ifdef __GNUC__
@@ -8378,7 +8379,7 @@ int main() {
 char *p = (char *) alloca(1);
 ; return 0; }
 EOF
-if { (eval echo configure:8382: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8383: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_func_alloca_works=yes
 else
@@ -8410,12 +8411,12 @@ EOF
 
 
 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:8414: checking whether alloca needs Cray hooks" >&5
+echo "configure:8415: checking whether alloca needs Cray hooks" >&5
 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8419 "configure"
+#line 8420 "configure"
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
@@ -8440,12 +8441,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6
 if test $ac_cv_os_cray = yes; then
 for ac_func in _getb67 GETB67 getb67; do
   echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:8444: checking for $ac_func" >&5
+echo "configure:8445: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8449 "configure"
+#line 8450 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -8468,7 +8469,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:8472: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8473: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -8495,7 +8496,7 @@ done
 fi
 
 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:8499: checking stack direction for C alloca" >&5
+echo "configure:8500: checking stack direction for C alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8503,7 +8504,7 @@ else
   ac_cv_c_stack_direction=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 8507 "configure"
+#line 8508 "configure"
 #include "confdefs.h"
 find_stack_direction ()
 {
@@ -8522,7 +8523,7 @@ main ()
   exit (find_stack_direction() < 0);
 }
 EOF
-if { (eval echo configure:8526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8527: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_stack_direction=1
 else
@@ -8545,7 +8546,7 @@ fi
 
 # getmntent is in -lsun on Irix 4, -lseq on Dynix/PTX, -lgen on Unixware.
 echo $ac_n "checking for getmntent in -lsun""... $ac_c" 1>&6
-echo "configure:8549: checking for getmntent in -lsun" >&5
+echo "configure:8550: checking for getmntent in -lsun" >&5
 ac_lib_var=`echo sun'_'getmntent | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -8553,7 +8554,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsun  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8557 "configure"
+#line 8558 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8564,7 +8565,7 @@ int main() {
 getmntent()
 ; return 0; }
 EOF
-if { (eval echo configure:8568: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8569: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8583,7 +8584,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for getmntent in -lseq""... $ac_c" 1>&6
-echo "configure:8587: checking for getmntent in -lseq" >&5
+echo "configure:8588: checking for getmntent in -lseq" >&5
 ac_lib_var=`echo seq'_'getmntent | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -8591,7 +8592,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lseq  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8595 "configure"
+#line 8596 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8602,7 +8603,7 @@ int main() {
 getmntent()
 ; return 0; }
 EOF
-if { (eval echo configure:8606: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8607: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8621,7 +8622,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for getmntent in -lgen""... $ac_c" 1>&6
-echo "configure:8625: checking for getmntent in -lgen" >&5
+echo "configure:8626: checking for getmntent in -lgen" >&5
 ac_lib_var=`echo gen'_'getmntent | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -8629,7 +8630,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lgen  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8633 "configure"
+#line 8634 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8640,7 +8641,7 @@ int main() {
 getmntent()
 ; return 0; }
 EOF
-if { (eval echo configure:8644: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8645: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8665,12 +8666,12 @@ fi
 fi
 
 echo $ac_n "checking for getmntent""... $ac_c" 1>&6
-echo "configure:8669: checking for getmntent" >&5
+echo "configure:8670: checking for getmntent" >&5
 if eval "test \"`echo '$''{'ac_cv_func_getmntent'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8674 "configure"
+#line 8675 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char getmntent(); below.  */
@@ -8693,7 +8694,7 @@ getmntent();
 
 ; return 0; }
 EOF
-if { (eval echo configure:8697: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8698: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_getmntent=yes"
 else
@@ -8716,7 +8717,7 @@ else
 fi
 
 echo $ac_n "checking whether closedir returns void""... $ac_c" 1>&6
-echo "configure:8720: checking whether closedir returns void" >&5
+echo "configure:8721: checking whether closedir returns void" >&5
 if eval "test \"`echo '$''{'ac_cv_func_closedir_void'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8724,13 +8725,13 @@ else
   ac_cv_func_closedir_void=yes
 else
   cat > conftest.$ac_ext <<EOF
-#line 8728 "configure"
+#line 8729 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <$ac_header_dirent>
 int closedir(); main() { exit(closedir(opendir(".")) != 0); }
 EOF
-if { (eval echo configure:8734: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8735: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_closedir_void=no
 else
@@ -8753,7 +8754,7 @@ EOF
 fi
 
 echo $ac_n "checking whether setpgrp takes no argument""... $ac_c" 1>&6
-echo "configure:8757: checking whether setpgrp takes no argument" >&5
+echo "configure:8758: checking whether setpgrp takes no argument" >&5
 if eval "test \"`echo '$''{'ac_cv_func_setpgrp_void'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8761,7 +8762,7 @@ else
   { echo "configure: error: cannot check setpgrp if cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 8765 "configure"
+#line 8766 "configure"
 #include "confdefs.h"
 
 #ifdef HAVE_UNISTD_H
@@ -8781,7 +8782,7 @@ main()
 }
 
 EOF
-if { (eval echo configure:8785: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8786: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_setpgrp_void=no
 else
@@ -8804,7 +8805,7 @@ EOF
 
 fi
                      echo $ac_n "checking for working fnmatch""... $ac_c" 1>&6
-echo "configure:8808: checking for working fnmatch" >&5
+echo "configure:8809: checking for working fnmatch" >&5
 if eval "test \"`echo '$''{'ac_cv_func_fnmatch_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8815,11 +8816,11 @@ if test "$cross_compiling" = yes; then
   ac_cv_func_fnmatch_works=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 8819 "configure"
+#line 8820 "configure"
 #include "confdefs.h"
 main() { exit (fnmatch ("a*", "abc", 0) != 0); }
 EOF
-if { (eval echo configure:8823: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8824: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_fnmatch_works=yes
 else
@@ -8844,7 +8845,7 @@ fi
 
 
 echo $ac_n "checking for setlocale in -lxpg4""... $ac_c" 1>&6
-echo "configure:8848: checking for setlocale in -lxpg4" >&5
+echo "configure:8849: checking for setlocale in -lxpg4" >&5
 ac_lib_var=`echo xpg4'_'setlocale | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -8852,7 +8853,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lxpg4  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8856 "configure"
+#line 8857 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8863,7 +8864,7 @@ int main() {
 setlocale()
 ; return 0; }
 EOF
-if { (eval echo configure:8867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8868: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8886,7 +8887,7 @@ fi
 
 
 echo $ac_n "checking for getpwnam in -lsun""... $ac_c" 1>&6
-echo "configure:8890: checking for getpwnam in -lsun" >&5
+echo "configure:8891: checking for getpwnam in -lsun" >&5
 ac_lib_var=`echo sun'_'getpwnam | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -8894,7 +8895,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsun  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8898 "configure"
+#line 8899 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8905,7 +8906,7 @@ int main() {
 getpwnam()
 ; return 0; }
 EOF
-if { (eval echo configure:8909: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8910: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8937,17 +8938,17 @@ for ac_hdr in zlib.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:8941: checking for $ac_hdr" >&5
+echo "configure:8942: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8946 "configure"
+#line 8947 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8951: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8952: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -8974,7 +8975,7 @@ fi
 done
 
 echo $ac_n "checking for deflate in -lz""... $ac_c" 1>&6
-echo "configure:8978: checking for deflate in -lz" >&5
+echo "configure:8979: checking for deflate in -lz" >&5
 ac_lib_var=`echo z'_'deflate | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -8982,7 +8983,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lz  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8986 "configure"
+#line 8987 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8993,7 +8994,7 @@ int main() {
 deflate()
 ; return 0; }
 EOF
-if { (eval echo configure:8997: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8998: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -9024,7 +9025,7 @@ fi
 
 PTHREAD_LIB=""
 echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
-echo "configure:9028: checking for pthread_create in -lpthread" >&5
+echo "configure:9029: checking for pthread_create in -lpthread" >&5
 ac_lib_var=`echo pthread'_'pthread_create | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -9032,7 +9033,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lpthread  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 9036 "configure"
+#line 9037 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -9043,7 +9044,7 @@ int main() {
 pthread_create()
 ; return 0; }
 EOF
-if { (eval echo configure:9047: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:9048: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -9062,7 +9063,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for pthread_create in -lpthreads""... $ac_c" 1>&6
-echo "configure:9066: checking for pthread_create in -lpthreads" >&5
+echo "configure:9067: checking for pthread_create in -lpthreads" >&5
 ac_lib_var=`echo pthreads'_'pthread_create | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -9070,7 +9071,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lpthreads  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 9074 "configure"
+#line 9075 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -9081,7 +9082,7 @@ int main() {
 pthread_create()
 ; return 0; }
 EOF
-if { (eval echo configure:9085: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:9086: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -9100,7 +9101,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for pthread_create in -lc_r""... $ac_c" 1>&6
-echo "configure:9104: checking for pthread_create in -lc_r" >&5
+echo "configure:9105: checking for pthread_create in -lc_r" >&5
 ac_lib_var=`echo c_r'_'pthread_create | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -9108,7 +9109,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lc_r  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 9112 "configure"
+#line 9113 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -9119,7 +9120,7 @@ int main() {
 pthread_create()
 ; return 0; }
 EOF
-if { (eval echo configure:9123: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:9124: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -9138,12 +9139,12 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for pthread_create""... $ac_c" 1>&6
-echo "configure:9142: checking for pthread_create" >&5
+echo "configure:9143: checking for pthread_create" >&5
 if eval "test \"`echo '$''{'ac_cv_func_pthread_create'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 9147 "configure"
+#line 9148 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char pthread_create(); below.  */
@@ -9166,7 +9167,7 @@ pthread_create();
 
 ; return 0; }
 EOF
-if { (eval echo configure:9170: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:9171: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_pthread_create=yes"
 else
@@ -9284,7 +9285,7 @@ freebsd)
            platforms/freebsd/bacula-sd \
            platforms/freebsd/bacula-dir"
        hostname=`hostname -s`
-       ac_cv_sys_largefile_CFLAGS="yes"
+       largefile_support="yes"
   ;;
 hpux)
        DISTVER=`uname -r`
@@ -9992,7 +9993,7 @@ chmod 755 src/cats/make_bdb_tables src/cats/drop_bdb_tables
 chmod 755 src/cats/create_bdb_database
 
 if test "x$ac_cv_sys_largefile_CFLAGS" != "xno" ; then
-   ac_cv_sys_largefile_CFLAGS="yes"
+   largefile_support="yes"
 fi
 
 
@@ -10023,7 +10024,7 @@ Configuration on `date`:
   Working directory          ${working_dir}
   SQL binaries Directory      ${SQL_BINDIR}
 
-  Large file support:        $ac_cv_sys_largefile_CFLAGS
+  Large file support:        $largefile_support
   readline support:          ${got_readline} ${PRTREADLINE_SRC}
   cweb support:              ${got_cweb} ${CWEB_SRC}
   TCP Wrappers support:       ${TCPW_MSG}
index bf80aa79e1b7dcfda60704d282db305c5c13eccb..93d95f18abedde5105d1893abe9eb6992f5e665d 100644 (file)
@@ -1,38 +1,43 @@
                  Kern's ToDo List
-                 7 October 2002
+                 23 October 2002
 
-Irix conversion notes:
-- no uuencode
-- no hostname
 To do:    
-- Document passwords.
-- Document running multiple Jobs
 - Document that two Verifys at same time on same client do not work.
 - Document how to recycle a tape in 7 days even if the backup takes a long time.
 - Document default config file locations.
-- Document better includes (does it cross file systems ?).
+- Document better Include  (does it cross file systems ?).
 - Document specifically how to add new File daemon to config files.
-- Document forcing a new tape to be used.
-- Document "Error in message.c:500 Mail program terminated in error.
-
-From Chuck:
---bindir is wrong and does not reflect prefix= in the *_sqlite_* scripts
-  (src/cats)
---top level configure options are not passed to the depkgs, particularly
-  prefix=
---Also, it might be better to split the depkgs location from the --with-sqlite
-  location. 
---should be able to specify e.g. --with-sqlite=/opt/local and have it find
-  lib, bin, sbin for itself
-  I tried this and it didn't find sqlite.h
-=======
-
-- Figure out why my Catalog size keeps growing.
 
+- Figure out why my Catalog size keeps growing (Filename and Path
+  tables keep growing) -- fix it.
+
+- Label (asks for slot, return and it stops).
+
+- Document buffer size considerations with Sparse files --
+- Document all daemon tools MUST have a config file.
+- Move block size code from block.c to init_dev().
+- Add code to fast seek to proper place on tape/file
+  when doing Restore. If it doesn't work, try linear
+  search as before.
+- Add code to reject whole blocks if not wanted on restore.
+- Why does btape error when pointed to a file?
+- Possibly add email to Watchdog if drive is unmounted too
+  long and a job is waiting on the drive.
+- Add configure for gettimeofday.
+- Disallow compile if long long not 64 bits.
+- What to do with btime and JobTDate?
+- Add FileSet MD5 to bscan.
+- Finish implementation of restore "replace" options, and document.
+- Strip trailing slashes from Include directory names in the FD.
 - Use read_record.c in SD code.
-- Implement Sparce files, change ownership of files, restore
-  all Windows attributes, restore options, FSM for program
-  files.
+- Allow changing ownership/group of files on restore.
+- Restore options (overwrite, ...)
+- Program files (i.e. execute a program to read/write files).
+  Pass read date of last backup, size of file last time.
+- Try bare metal Windows restore
+- Recovery of a bad tape.
+- EOM records?????????????????
 - Why don't we get an error message from Win32 FD when bootstrap 
   file cannot be created for restore command?
 - At line 51 of ua_input.c, why is = 0 necessary. Previously without
@@ -41,8 +46,6 @@ From Chuck:
 - Make SD disallow writing on Volume with fewer files than in
   the catalog.
 - Put MaximumVolumeSize in Director.
-- Document how to cancel a job that is waiting on a Volume. 
-  Must "cancel" then "mount".
 - Document to have patience when SD first starts.
 - Document running a test version.
 - When Marking a file in Restore that is a hard link, also
@@ -53,11 +56,12 @@ From Chuck:
 - Make BSR return next_block when it knows record is not
   in block, done when count is reached, and possibly other
   optimizations. I.e. add a state word.
+
+
 - After unmount, if restore job started, ask to mount.
 - Fix db_get_fileset in cats/sql_get.c for multiple records.
 - Fix start/end blocks for File devices
 - Add new code to scheduler.c and run_conf.c
-- Volume Bytes shows bytes on last volume written in Job summary.
 - Fix catalog filename truncation in sql_get and sql_create. Use
   only a single filename split routine.
 - Add command to reset VolFiles to a larger value (don't allow
@@ -563,3 +567,16 @@ Done: (see kernsdone for more)
 - Document bscan.
 - Document Restore.
 - Check if GZIP1 is working -- check speed.
+- Document forcing a new tape to be used.
+- Ensure that AcceptAnyVolume works.
+- Document running multiple Jobs
+- Preserve block number when EOT and writing on next tape.
+- Document how to cancel a job that is waiting on a Volume. 
+  Must "cancel" then "mount".
+- Document Volume Bytes shows bytes on last volume written in Job summary.
+- Restore all Windows attributes. Leave hooks for ACLs and security.
+  (Handle x = (HANDLE)get_osfhandle(fd);
+- Test Windows restore.
+- Look into MinGW
+- Implement sparse files.
+- Document sparse files.
index e03d0c1ee8b9512429422bd28ea698aa37500b11..627dc0fdbbc2c3e324e9722adf7691ee4ed8e1c0 100644 (file)
 #define MAX_NETWORK_BUFFER_SIZE (32 * 1024)
 
 /* Stream definitions.  Once defined these must NEVER
- * change as they go on the storage media
+ *   change as they go on the storage media.
  */
-#define STREAM_UNIX_ATTRIBUTES  1     /* Generic Unix attributes */
-#define STREAM_FILE_DATA        2     /* Standard uncompressed data */
-#define STREAM_MD5_SIGNATURE    3     /* MD5 signature for the file */
-#define STREAM_GZIP_DATA        4     /* GZip compressed file data */
+#define STREAM_UNIX_ATTRIBUTES   1    /* Generic Unix attributes */
+#define STREAM_FILE_DATA         2    /* Standard uncompressed data */
+#define STREAM_MD5_SIGNATURE     3    /* MD5 signature for the file */
+#define STREAM_GZIP_DATA         4    /* GZip compressed file data */
+#define STREAM_WIN32_ATTRIBUTES  5    /* Windows attributes (superset of Unix) */
+#define STREAM_SPARSE_DATA       6    /* Sparse data stream */
+#define STREAM_SPARSE_GZIP_DATA  7
+#define STREAM_PROGRAM_NAMES     8    /* program names for program data */
+#define STREAM_PROGRAM_DATA      9    /* Data needing program */
 
+/* Size of File Address stored in STREAM_SPARSE_DATA. Do NOT change! */
+#define SPARSE_FADDR_SIZE (sizeof(uint64_t))
 
-/* This is for dumb compilers like Solaris. Linux GCC
+
+/* This is for dumb compilers/libraries like Solaris. Linux GCC
  * does it correctly, so it might be worthwhile
  * to remove the isascii(c) with ifdefs on such
  * "smart" systems.
  */
-#undef  ISSPACE
-#undef  ISALPHA
-#undef  ISUPPER
-#undef  ISDIGIT
-#define ISSPACE(c) (isascii((int)(c)) && isspace((int)(c)))
-#define ISALPHA(c) (isascii((int)(c)) && isalpha((int)(c)))
-#define ISUPPER(c) (isascii((int)(c)) && isupper((int)(c)))
-#define ISDIGIT(c) (isascii((int)(c)) && isdigit((int)(c)))
+#define B_ISSPACE(c) (isascii((int)(c)) && isspace((int)(c)))
+#define B_ISALPHA(c) (isascii((int)(c)) && isalpha((int)(c)))
+#define B_ISUPPER(c) (isascii((int)(c)) && isupper((int)(c)))
+#define B_ISDIGIT(c) (isascii((int)(c)) && isdigit((int)(c)))
 
 
 typedef void (HANDLER)();
@@ -127,6 +131,11 @@ typedef int (INTHANDLER)();
 #define S_ISLNK(m) (((m) & S_IFM) == S_IFLNK)
 #endif
 
+/* Added by KES to deal with Win32 systems */
+#ifndef S_ISWIN32
+#define S_ISWIN32 020000
+#endif
+
 #ifndef INADDR_NONE
 #define INADDR_NONE ((unsigned long) -1)
 #endif
index 16370169a163567eb547de2f6bd7570b9fbc1938..19b002781fb4a9982300e5dcf1cc003b9dcc027d 100644 (file)
@@ -430,7 +430,7 @@ int db_create_file_attributes_record(B_DB *mdb, ATTR_DBR *ar)
    /* For the moment, we only handle Unix attributes.  Note, we are
     * also getting any MD5 signature that was computed.
     */
-   if (ar->Stream != STREAM_UNIX_ATTRIBUTES) {
+   if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES || ar->Stream == STREAM_WIN32_ATTRIBUTES)) {
       Mmsg0(&mdb->errmsg, _("Attempt to put non-attributes into catalog\n"));
       Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
       return 0;
diff --git a/bacula/src/cl b/bacula/src/cl
new file mode 100644 (file)
index 0000000..c5431ee
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
index f1fbcf3597356f18a62f7e5654b009d011b6b0c4..d12e4d958c5978f87ca9ab5e834966007012a895 100644 (file)
@@ -64,9 +64,9 @@ all: Makefile bacula-dir
        @echo "==== Make of dird is good ===="
        @echo " "
 
-bacula-dir:  $(SVROBJS) ../lib/libbac.a ../cats/libsql.a
-       $(CXX) $(LDFLAGS) -L../lib -L../cats -o $@ $(SVROBJS) \
-             -lsql -lbac -lm $(LIBS) $(DLIB) $(DB_LIBS)
+bacula-dir:  $(SVROBJS) ../lib/libbac.a ../cats/libsql.a ../findlib/libfind.a
+       $(CXX) $(LDFLAGS) -L../lib -L../cats -L../findlib -o $@ $(SVROBJS) \
+             -lsql -lbac -lfind -lm $(LIBS) $(DLIB) $(DB_LIBS)
 
 Makefile: $(srcdir)/Makefile.in $(topdir)/config.status
        cd $(topdir) \
index 1ce4f0a05c9e3a6ce7fbcdc875c65d3b458817eb..81cf4538a4d5a91678be6236b9c2aba19afa35b8 100644 (file)
@@ -131,7 +131,8 @@ int authenticate_user_agent(BSOCK *ua)
 
 
    if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) {
-      Emsg1(M_FATAL, 0, _("Authentication failure: %s"), ua->msg);
+      ua->msg[100] = 0;              /* terminate string */
+      Emsg1(M_ERROR, 0, _("Authentication failure: %s"), ua->msg);
       return 0;
    }
 
index decff941a936845d50b56b8eb9995b9b78361619..094c2b9a5043de5ec49ee4850581ce62c3bb9835 100644 (file)
@@ -92,6 +92,7 @@ int do_backup(JCR *jcr)
       memcpy(&md5c, &jcr->fileset->md5c, sizeof(md5c));
       MD5Final(signature, &md5c);
       bin_to_base64(fsr.MD5, (char *)signature, 16); /* encode 16 bytes */
+      strcpy(jcr->fileset->MD5, fsr.MD5);
    } else {
       Jmsg(jcr, M_WARNING, 0, _("FileSet MD5 signature not found.\n"));
    }
@@ -301,7 +302,7 @@ static int wait_for_job_termination(JCR *jcr)
 static void backup_cleanup(JCR *jcr, int TermCode, char *since)
 {
    char sdt[50], edt[50];
-   char ec1[30], ec2[30], ec3[30];
+   char ec1[30], ec2[30], ec3[30], compress[50];
    char term_code[100];
    char *term_msg;
    int msg_type;
@@ -356,18 +357,32 @@ static void backup_cleanup(JCR *jcr, int TermCode, char *since)
    bstrftime(edt, sizeof(edt), jcr->jr.EndTime);
    RunTime = jcr->jr.EndTime - jcr->jr.StartTime;
    if (RunTime <= 0) {
-      RunTime = 1;
+      kbps = 0;
+   } else {
+      kbps = (double)jcr->jr.JobBytes / (1000 * RunTime);
    }
-   kbps = (double)jcr->jr.JobBytes / (1000 * RunTime);
    if (!db_get_job_volume_names(jcr->db, jcr->jr.JobId, &jcr->VolumeName)) {
-      Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
+      /*
+       * Note, if the job has erred, most likely it did not write any
+       *  tape, so suppress this "error" message since in that case
+       *  it is normal.  Or look at it the other way, only for a
+       *  normal exit should we complain about this error.
+       */
+      if (TermCode == JS_Terminated) {                               
+         Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
+      }
       jcr->VolumeName[0] = 0;        /* none */
    }
 
    if (jcr->ReadBytes == 0) {
-      compression = 0.0;
+      strcpy(compress, "None");
    } else {
       compression = (double)100 - 100.0 * ((double)jcr->JobBytes / (double)jcr->ReadBytes);
+      if (compression < 0.5) {
+         strcpy(compress, "None");
+      } else {
+         sprintf(compress, "%.1f %%", (float)compression);
+      }
    }
 
    Jmsg(jcr, msg_type, 0, _("%s\n\
@@ -381,7 +396,7 @@ End time:               %s\n\
 Files Written:          %s\n\
 Bytes Written:          %s\n\
 Rate:                   %.1f KB/s\n\
-Software Compression:   %.1f %%\n\
+Software Compression:   %s\n\
 Volume names(s):        %s\n\
 Volume Session Id:      %d\n\
 Volume Session Time:    %d\n\
@@ -398,7 +413,7 @@ Termination:            %s\n\n"),
        edit_uint64_with_commas(jcr->jr.JobFiles, ec1),
        edit_uint64_with_commas(jcr->jr.JobBytes, ec2),
        (float)kbps,
-       (float)compression,
+       compress,
        jcr->VolumeName,
        jcr->VolSessionId,
        jcr->VolSessionTime,
index fbed8024614b09f22c4a8faeb7a3c6d54d04ee6f..2fde3b5c9b0572bc2e937adb28adc5701b71509f 100644 (file)
@@ -152,4 +152,5 @@ Pool {
   Recycle = yes                       # Bacula can automatically recycle Volumes
   AutoPrune = yes                     # Prune expired volumes
   Volume Retention = 365d             # one year
+  Accept Any Volume = yes             # write on any volume in the pool
 }
index 2aaae00f78ef6faf337fe775c0b7b471dba75674..1e967cd25e5062e0d0d75986e9d0546a94eaef9d 100644 (file)
@@ -137,12 +137,14 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
         } else {
            /* 
             * Make sure this volume is suitable for this job, i.e.
-            *  it is either Append or Recycle and Media Type matches.
+            *  it is either Append or Recycle and Media Type matches 
+            *  and Pool allows any volume.
             */
            if (mr.PoolId == jcr->PoolId && 
                 (strcmp(mr.VolStatus, "Append") == 0 ||
-                 strcmp(mr.VolStatus, "Recycle") == 0 ||
-                strcmp(mr.MediaType, jcr->store->media_type) == 0)) {
+                 strcmp(mr.VolStatus, "Recycle") == 0) &&
+                strcmp(mr.MediaType, jcr->store->media_type) == 0 &&
+                jcr->pool->accept_any_volume) {
               VolSuitable = 1;
            }
         }
@@ -263,7 +265,7 @@ void catalog_update(JCR *jcr, BSOCK *bs, char *msg)
    Dmsg5(99, "UpdCat VolSessId=%d VolSessT=%d FI=%d Strm=%d data_len=%d\n",
       VolSessionId, VolSessionTime, FileIndex, Stream, data_len);
 
-   if (Stream == STREAM_UNIX_ATTRIBUTES) {
+   if (Stream == STREAM_UNIX_ATTRIBUTES || Stream == STREAM_WIN32_ATTRIBUTES) {
       skip_nonspaces(&p);            /* skip FileIndex */
       skip_spaces(&p);
       skip_nonspaces(&p);            /* skip FileType */
@@ -284,7 +286,6 @@ void catalog_update(JCR *jcr, BSOCK *bs, char *msg)
       Dmsg2(111, "dird<filed: stream=%d %s\n", Stream, fname);
       Dmsg1(120, "dird<filed: attr=%s\n", attr);
 
-      /* ***FIXME*** fix link field */
       if (!db_create_file_attributes_record(jcr->db, &ar)) {
          Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db));
       }
index 1fd62959b6c6bd47ad6a9def041c6d86d91c3d9e..473fdada45368bd04f49c8e811bef5494290ec2a 100644 (file)
@@ -232,7 +232,7 @@ static struct res_items pool_items[] = {
    {"usecatalog",      store_yesno, ITEM(res_pool.use_catalog),     1, ITEM_DEFAULT,  1},
    {"usevolumeonce",   store_yesno, ITEM(res_pool.use_volume_once), 1, 0,       0},
    {"maximumvolumes",  store_pint,  ITEM(res_pool.max_volumes),     0, 0,             0},
-   {"acceptanyvolume", store_yesno, ITEM(res_pool.accept_any_volume), 1, 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},
    {"autoprune",       store_yesno, ITEM(res_pool.AutoPrune), 1, ITEM_DEFAULT, 1},
@@ -348,6 +348,7 @@ static struct s_kw ReplaceOptions[] = {
 #define FS_KW_VERIFY      4
 #define FS_KW_ONEFS       5
 #define FS_KW_RECURSE     6
+#define FS_KW_SPARSE      7
 
 /* FileSet keywords */
 static struct s_kw FS_option_kw[] = {
@@ -357,6 +358,7 @@ static struct s_kw FS_option_kw[] = {
    {"verify",      FS_KW_VERIFY},
    {"onefs",       FS_KW_ONEFS},
    {"recurse",     FS_KW_RECURSE},
+   {"sparse",      FS_KW_SPARSE},
    {NULL,         0}
 };
 
@@ -387,6 +389,8 @@ static struct s_fs_opt FS_options[] = {
    {"no",       FS_KW_ONEFS,         "f"},
    {"yes",      FS_KW_RECURSE,       "0"},
    {"no",       FS_KW_RECURSE,       "h"},
+   {"yes",      FS_KW_SPARSE,        "s"},
+   {"no",       FS_KW_SPARSE,        "0"},
    {NULL,      0,                   0}
 };
 
index 11c47bdfc303ee79883130f400fc958f51875a03..22c38264a6c97531378b3e713fcf1ddf0f66a018 100644 (file)
 /*
  * Resource codes -- they must be sequential for indexing   
  */
-#define R_FIRST                      1001
-
-#define R_DIRECTOR                   1001
-#define R_CLIENT                     1002
-#define R_JOB                        1003
-#define R_STORAGE                    1004
-#define R_CATALOG                    1005
-#define R_SCHEDULE                   1006
-#define R_FILESET                    1007
-#define R_GROUP                      1008
-#define R_POOL                       1009
-#define R_MSGS                       1010
-#define R_COUNTER                    1011
-
-#define R_LAST                       R_COUNTER
+#define R_FIRST                       1001
+
+#define R_DIRECTOR                    1001
+#define R_CLIENT                      1002
+#define R_JOB                         1003
+#define R_STORAGE                     1004
+#define R_CATALOG                     1005
+#define R_SCHEDULE                    1006
+#define R_FILESET                     1007
+#define R_GROUP                       1008
+#define R_POOL                        1009
+#define R_MSGS                        1010
+#define R_COUNTER                     1011
+
+#define R_LAST                        R_COUNTER
 
 /*
  * Some resource attributes
  */
-#define R_NAME                       1020
-#define R_ADDRESS                    1021
-#define R_PASSWORD                   1022
-#define R_TYPE                       1023
-#define R_BACKUP                     1024
+#define R_NAME                        1020
+#define R_ADDRESS                     1021
+#define R_PASSWORD                    1022
+#define R_TYPE                        1023
+#define R_BACKUP                      1024
 
 
 /* Used for certain KeyWord tables */
-struct s_kw {      
+struct s_kw {       
    char *name;
-   int token;  
+   int token;   
 };
 
 /* Job Level keyword structure */
 struct s_jl {
-   char *level_name;                 /* level keyword */
-   int level;                        /* level */
-   int job_type;                     /* JobType permitting this level */
+   char *level_name;                  /* level keyword */
+   int  level;                        /* level */
+   int  job_type;                     /* JobType permitting this level */
 };
 
 /* Job Type keyword structure */
@@ -78,22 +78,22 @@ struct s_jt {
 /* Definition of the contents of each Resource */
 
 /* 
- *   Director Resource 
+ *   Director Resource  
  *
  */
 struct s_res_dir {
-   RES  hdr;
-   int  DIRport;                     /* where we listen -- UA port server port */
-   char *DIRaddr;                    /* bind address */
-   char *password;                   /* Password for UA access */
-   char *query_file;                 /* SQL query file */
-   char *working_directory;          /* WorkingDirectory */
-   char *pid_directory;              /* PidDirectory */
-   char *subsys_directory;           /* SubsysDirectory */
+   RES   hdr;
+   int   DIRport;                     /* where we listen -- UA port server port */
+   char *DIRaddr;                     /* bind address */
+   char *password;                    /* Password for UA access */
+   char *query_file;                  /* SQL query file */
+   char *working_directory;           /* WorkingDirectory */
+   char *pid_directory;               /* PidDirectory */
+   char *subsys_directory;            /* SubsysDirectory */
    struct s_res_msgs *messages;       /* Daemon message handler */
-   int  MaxConcurrentJobs;
-   btime_t FDConnectTimeout;         /* timeout for connect in seconds */
-   btime_t SDConnectTimeout;         /* timeout in seconds */
+   int   MaxConcurrentJobs;
+   btime_t FDConnectTimeout;          /* timeout for connect in seconds */
+   btime_t SDConnectTimeout;          /* timeout in seconds */
 };
 typedef struct s_res_dir DIRRES;
 
@@ -102,12 +102,12 @@ typedef struct s_res_dir DIRRES;
  *
  */
 struct s_res_client {
-   RES  hdr;
+   RES   hdr;
 
-   int  FDport;                      /* Where File daemon listens */
-   int  AutoPrune;                   /* Do automatic pruning? */
-   btime_t FileRetention;            /* file retention period in seconds */
-   btime_t JobRetention;             /* job retention period in seconds */
+   int   FDport;                      /* Where File daemon listens */
+   int   AutoPrune;                   /* Do automatic pruning? */
+   btime_t FileRetention;             /* file retention period in seconds */
+   btime_t JobRetention;              /* job retention period in seconds */
    char *address;
    char *password;
    struct s_res_cat    *catalog;       /* Catalog resource */
@@ -119,15 +119,15 @@ typedef struct s_res_client CLIENT;
  * 
  */
 struct s_res_store {
-   RES  hdr;
+   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 */
+   int  autochanger;                  /* set if autochanger */
 };
 typedef struct s_res_store STORE;
 
@@ -136,9 +136,9 @@ typedef struct s_res_store STORE;
  *
  */
 struct s_res_cat {
-   RES  hdr;
+   RES   hdr;
 
-   int  DBport;                      /* Port -- not yet implemented */
+   int   DBport;                      /* Port -- not yet implemented */
    char *address;
    char *db_password;
    char *db_user;
@@ -151,30 +151,30 @@ typedef struct s_res_cat CAT;
  *
  */
 struct s_res_job {
-   RES  hdr;
-
-   int  JobType;                     /* job type (backup, verify, restore */
-   int  level;                       /* default backup/verify level */
-   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 *WriteBootstrap;             /* Where to write bootstrap Job updates */
-   int  RestoreOptions;              /* How (overwrite, ..) */
-   btime_t MaxRunTime;               /* max run time in seconds */
-   btime_t MaxStartDelay;            /* max start delay in seconds */
-   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 */
+   RES   hdr;
+
+   int   JobType;                     /* job type (backup, verify, restore */
+   int   level;                       /* default backup/verify level */
+   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 *WriteBootstrap;              /* Where to write bootstrap Job updates */
+   int   RestoreOptions;              /* How (overwrite, ..) */
+   btime_t MaxRunTime;                /* max run time in seconds */
+   btime_t MaxStartDelay;             /* max start delay in seconds */
+   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 */
 
    struct s_res_msgs   *messages;     /* How and where to send messages */
    struct s_res_sch    *schedule;     /* When -- Automatic schedule */
    struct s_res_client *client;       /* Who to backup */
    struct s_res_fs     *fileset;      /* What to backup -- Fileset */
    struct s_res_store  *storage;      /* Where is device -- Storage daemon */
-   struct s_res_pool   *pool;        /* Where is media -- Media Pool */
+   struct s_res_pool   *pool;         /* Where is media -- Media Pool */
 };
 typedef struct s_res_job JOB;
 
@@ -183,7 +183,7 @@ typedef struct s_res_job JOB;
  *
  */
 struct s_res_fs {
-   RES  hdr;
+   RES   hdr;
 
    char **include_array;
    int num_includes;
@@ -191,8 +191,9 @@ struct s_res_fs {
    char **exclude_array;
    int num_excludes;
    int exclude_size;
-   int have_MD5;                     /* set if MD5 initialized */
-   struct MD5Context md5c;           /* MD5 of include/exclude */
+   int have_MD5;                      /* set if MD5 initialized */
+   struct MD5Context md5c;            /* MD5 of include/exclude */
+   char MD5[50];                      /* base 64 representation of MD5 */
 };
 typedef struct s_res_fs FILESET;
  
@@ -202,7 +203,7 @@ typedef struct s_res_fs FILESET;
  *
  */
 struct s_res_sch {
-   RES  hdr;
+   RES   hdr;
 
    struct s_run *run;
 };
@@ -213,7 +214,7 @@ typedef struct s_res_sch SCHED;
  *
  */
 struct s_res_group {
-   RES  hdr;
+   RES   hdr;
 };
 typedef struct s_res_group GROUP;
 
@@ -221,12 +222,12 @@ typedef struct s_res_group GROUP;
  *   Counter Resource
  */
 struct s_res_counter {
-   RES  hdr;
+   RES   hdr;
 
-   int32_t MinValue;                 /* Minimum value */
-   int32_t MaxValue;                 /* Maximum value */
-   int    Global;                    /* global/local */
-   char  *WrapCounter;               /* Wrap counter name */
+   int32_t MinValue;                  /* Minimum value */
+   int32_t MaxValue;                  /* Maximum value */
+   int     Global;                    /* global/local */
+   char  *WrapCounter;                /* Wrap counter name */
 };
 typedef struct s_res_counter COUNTER;
 
@@ -235,19 +236,19 @@ typedef struct s_res_counter COUNTER;
  *
  */
 struct s_res_pool {
-   RES  hdr;
+   RES   hdr;
 
    struct s_res_counter counter;      /* Counter resources */
-   char *pool_type;                  /* Pool type */
-   char *label_format;               /* Label format string */
-   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  max_volumes;                 /* max number of volumes */
-   btime_t VolRetention;             /* volume retention period in seconds */
-   int  AutoPrune;                   /* default for pool auto prune */
-   int  Recycle;                     /* default for media recycle yes/no */
+   char *pool_type;                   /* Pool type */
+   char *label_format;                /* Label format string */
+   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   max_volumes;                 /* max number of volumes */
+   btime_t VolRetention;              /* volume retention period in seconds */
+   int   AutoPrune;                   /* default for pool auto prune */
+   int   Recycle;                     /* default for media recycle yes/no */
 };
 typedef struct s_res_pool POOL;
 
@@ -256,16 +257,16 @@ typedef struct s_res_pool POOL;
  * resource structure definitions.
  */
 union u_res {
-   struct s_res_dir    res_dir;
-   struct s_res_client res_client;
-   struct s_res_store  res_store;
-   struct s_res_cat    res_cat;
-   struct s_res_job    res_job;
-   struct s_res_fs     res_fs;
-   struct s_res_sch    res_sch;
-   struct s_res_group  res_group;
-   struct s_res_pool   res_pool;
-   struct s_res_msgs   res_msgs;
+   struct s_res_dir     res_dir;
+   struct s_res_client  res_client;
+   struct s_res_store   res_store;
+   struct s_res_cat     res_cat;
+   struct s_res_job     res_job;
+   struct s_res_fs      res_fs;
+   struct s_res_sch     res_sch;
+   struct s_res_group   res_group;
+   struct s_res_pool    res_pool;
+   struct s_res_msgs    res_msgs;
    struct s_res_counter res_counter;
    RES hdr;
 };
@@ -275,17 +276,17 @@ typedef union u_res URES;
 
 /* Run structure contained in Schedule Resource */
 struct s_run {
-   struct s_run *next;               /* points to next run record */
-   int level;                        /* level override */
+   struct s_run *next;                /* points to next run record */
+   int level;                         /* level override */
    int job_type;  
-   POOL *pool;                       /* Pool override */
-   STORE *storage;                   /* Storage override */
-   MSGS *msgs;                       /* Messages override */
+   POOL *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 abf81e5d53f92cbe1033b82cf0b664899670a7eb..3370f771cb0918afcd30a48cec9d2a2491fc4899 100644 (file)
@@ -112,7 +112,7 @@ int32_t bget_msg(BSOCK *bs, int rtn)
      
       /* Handle normal data */
 
-      if (ISDIGIT(bs->msg[0])) {      /* response? */
+      if (B_ISDIGIT(bs->msg[0])) {     /* response? */
         return n;                    /* yes, return it */
       }
        
index 70176ff7fefcc95b00c1199e3373fbe8189f75f0..ff713c9d37b91af202591543aec1c8d91eb9c38b 100644 (file)
@@ -40,7 +40,7 @@
 
 /* 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\n";
+type=%d level=%d FileSet=%s NoAttr=%d SpoolAttr=%d FileSetMD5=%s\n";
 static char use_device[] = "use device=%s media_type=%s pool_name=%s pool_type=%s\n";
 
 /* Response from Storage daemon */
@@ -108,7 +108,7 @@ int start_storage_daemon_job(JCR *jcr)
    bnet_fsend(sd, jobcmd, jcr->JobId, jcr->Job, jcr->job->hdr.name, 
              jcr->client->hdr.name, jcr->JobType, jcr->JobLevel, 
              jcr->fileset->hdr.name, !jcr->pool->catalog_files,
-             jcr->job->SpoolAttributes);
+             jcr->job->SpoolAttributes, jcr->fileset->MD5);
    unbash_spaces(jcr->job->hdr.name);
    unbash_spaces(jcr->client->hdr.name);
    unbash_spaces(jcr->fileset->hdr.name);
index 807efa13db37b380a0c8b891e4678623fafb1b0a..13ac6a99b9e4a6880f1297e315bddd0fc62a1d8f 100644 (file)
@@ -32,6 +32,7 @@
 #include "dird.h"
 #include "ua.h"
 #include <fnmatch.h>
+#include "findlib/find.h"
 
 
 
index 3e52b7d12589545406d075c38b2ec9e307089e0d..2e29fac82c013e912766b5383e73efc8ea5d5a3e 100644 (file)
@@ -42,6 +42,7 @@
 
 #include "bacula.h"
 #include "dird.h"
+#include "findlib/find.h"
 
 /* Imported Global Variables */
 extern int debug_level;
index aed54ac44cb8c86c03ab8320f1373430c87e73bf..bd9fde945eeba4cfdbe1eb09059b2233a375e1d4 100644 (file)
@@ -45,11 +45,15 @@ static int authenticate(int rcode, BSOCK *bs)
       Emsg1(M_FATAL, 0, _("I only authenticate directors, not %d\n"), rcode);
       return 0;
    }
+   if (bs->msglen > 200) {
+      bs->msglen = 200;
+   }
    dirname = get_pool_memory(PM_MESSAGE);
    dirname = check_pool_memory_size(dirname, bs->msglen);
 
    if (sscanf(bs->msg, "Hello Director %s calling\n", dirname) != 1) {
       free_pool_memory(dirname);
+      bs->msg[100] = 0;
       Emsg1(M_FATAL, 0, _("Bad Hello command from Director: %s"), bs->msg);
       return 0;
    }
index b91a6911f922f14f285c3ebb69b05c1c24f77c95..bab03e15fc896512eb35fc472e5282b77e09d22c 100644 (file)
@@ -94,7 +94,8 @@ int blast_data_to_storage_daemon(JCR *jcr, char *addr)
 static int save_file(FF_PKT *ff_pkt, void *ijcr)
 {
    char attribs[MAXSTRING];
-   int fid, stat, stream, len;
+   char attribsEx[MAXSTRING];
+   int stat, stream; 
    struct MD5Context md5c;
    int gotMD5 = 0;
    unsigned char signature[16];
@@ -166,32 +167,31 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
 
    if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode) && 
         ff_pkt->statp.st_size > 0) {
-      if ((fid = open(ff_pkt->fname, O_RDONLY | O_BINARY)) < 0) {
+      if ((ff_pkt->fid = open(ff_pkt->fname, O_RDONLY | O_BINARY)) < 0) {
         ff_pkt->ff_errno = errno;
          Jmsg(jcr, M_NOTSAVED, -1, _("     Cannot open %s: ERR=%s.\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
         return 1;
       }
    } else {
-      fid = -1;
+      ff_pkt->fid = -1;
    }
 
    Dmsg1(130, "bfiled: sending %s to stored\n", ff_pkt->fname);
    encode_stat(attribs, &ff_pkt->statp);
+   stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
+   Dmsg3(200, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
      
    jcr->JobFiles++;                   /* increment number of files sent */
-   len = strlen(ff_pkt->fname);
-   jcr->last_fname = check_pool_memory_size(jcr->last_fname, len + 1);
-   jcr->last_fname[len] = 0;         /* terminate properly before copy */
-   strcpy(jcr->last_fname, ff_pkt->fname);
+   pm_strcpy(&jcr->last_fname, ff_pkt->fname);
     
    /*
     * Send Attributes header to Storage daemon
     *   <file-index> <stream> <info>
     */
 #ifndef NO_FD_SEND_TEST
-   if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES)) {
-      if (fid >= 0) {
-        close(fid);
+   if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
+      if (ff_pkt->fid >= 0) {
+        close(ff_pkt->fid);
       }
       return 0;
    }
@@ -203,38 +203,41 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
     *  File type
     *  Filename (full path)
     *  Encoded attributes
-    *  Link name (if type==FT_LNK)
+    *  Link name (if type==FT_LNK or FT_LNKSAVED)
+    *  Encoded extended-attributes (for Win32)
+    *
     * For a directory, link is the same as fname, but with trailing
     * slash. For a linked file, link is the link.
     */
    if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
       Dmsg2(100, "Link %s to %s\n", ff_pkt->fname, ff_pkt->link);
-      stat = bnet_fsend(sd, "%ld %d %s%c%s%c%s%c", jcr->JobFiles, 
-              ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0);
+      stat = bnet_fsend(sd, "%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles, 
+              ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0,
+              attribsEx, 0);
    } else if (ff_pkt->type == FT_DIR) {
-      stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c", jcr->JobFiles, 
-              ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0);
+      /* Here link is the canonical filename (i.e. with trailing slash) */
+      stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles, 
+              ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0);
    } else {
-      stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c", jcr->JobFiles, 
-              ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0);
+      stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles, 
+              ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0);
    }
 
    Dmsg2(100, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
    if (!stat) {
-      if (fid >= 0) {
-        close(fid);
+      if (ff_pkt->fid >= 0) {
+        close(ff_pkt->fid);
       }
       return 0;
    }
-   /* send data termination sentinel */
-   bnet_sig(sd, BNET_EOD);
+   bnet_sig(sd, BNET_EOD);           /* indicate end of attributes data */
 #endif
 
    /* 
     * If the file has data, read it and send to the Storage daemon
     *
     */
-   if (fid >= 0) {
+   if (ff_pkt->fid >= 0) {
 
       Dmsg1(100, "Saving data, type=%d\n", ff_pkt->type);
       /*
@@ -242,17 +245,36 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
        *    <file-index> <stream> <info>
        */
 
-      stream = STREAM_FILE_DATA;
+      if (ff_pkt->flags & FO_SPARSE) {
+        stream = STREAM_SPARSE_DATA;
+      } else {
+        stream = STREAM_FILE_DATA;
+      }
 
 #ifdef HAVE_LIBZ
+      uLong compress_len;   
+      const Bytef *cbuf = NULL;
+
       if (ff_pkt->flags & FO_GZIP) {
-        stream = STREAM_GZIP_DATA;
+        if (stream == STREAM_FILE_DATA) {
+           stream = STREAM_GZIP_DATA;
+        } else {
+           stream = STREAM_SPARSE_GZIP_DATA;
+        }
+
+        if (ff_pkt->flags & FO_SPARSE) {
+           cbuf = (Bytef *)jcr->compress_buf + SPARSE_FADDR_SIZE;
+           compress_len = jcr->compress_buf_size - SPARSE_FADDR_SIZE;
+        } else {
+           cbuf = (Bytef *)jcr->compress_buf;
+           compress_len = jcr->compress_buf_size; /* set max length */
+        }
       }
 #endif
 
 #ifndef NO_FD_SEND_TEST
       if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
-        close(fid);
+        close(ff_pkt->fid);
         return 0;
       }
       Dmsg1(100, ">stored: datahdr %s\n", sd->msg);
@@ -263,24 +285,53 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
       }
 
       msgsave = sd->msg;
-      while ((sd->msglen=read(fid, sd->msg, jcr->buf_size)) > 0) {
-        jcr->ReadBytes += sd->msglen; /* count bytes read */
+      uint64_t fileAddr = 0;         /* file address */
+      char *rbuf = sd->msg;          /* read buffer */             
+      int rsize = jcr->buf_size;      /* read size */
+
+      /* Make space at beginning of buffer for fileAddr */
+      if (ff_pkt->flags & FO_SPARSE) {
+        rbuf += SPARSE_FADDR_SIZE;
+        rsize -= SPARSE_FADDR_SIZE;
+      }
+
+      /* 
+       * Read the file data
+       */
+      while ((sd->msglen=read(ff_pkt->fid, rbuf, rsize)) > 0) {
+        int sparseBlock = 0;
+
+        /* Check for sparse blocks */
+        if (ff_pkt->flags & FO_SPARSE) {
+           ser_declare;
+           if (sd->msglen == rsize && 
+               (fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size)) {
+              sparseBlock = is_buf_zero(rbuf, rsize);
+           }
+              
+           ser_begin(sd->msg, SPARSE_FADDR_SIZE);
+           ser_uint64(fileAddr);     /* store fileAddr in begin of buffer */
+        } 
+
+        jcr->ReadBytes += sd->msglen;      /* count bytes read */
+        fileAddr += sd->msglen;
+
+        /* Update MD5 if requested */
         if (ff_pkt->flags & FO_MD5) {
-           MD5Update(&md5c, (unsigned char *)(sd->msg), sd->msglen);
+           MD5Update(&md5c, (unsigned char *)rbuf, sd->msglen);
            gotMD5 = 1;
         }
+
 #ifdef HAVE_LIBZ
-        /* ***FIXME*** add compression level options */
-        if (ff_pkt->flags & FO_GZIP) {
-           uLong compress_len;
-           compress_len = jcr->compress_buf_size; /* set max length */
-           if (compress2((Bytef *)jcr->compress_buf, &compress_len, 
-                 (const Bytef *)sd->msg, (uLong)sd->msglen,
+        /* Do compression if turned on */
+        if (!sparseBlock && ff_pkt->flags & FO_GZIP) {
+           if (compress2((Bytef *)cbuf, &compress_len, 
+                 (const Bytef *)rbuf, (uLong)sd->msglen,
                  ff_pkt->GZIP_level)  != Z_OK) {
                Jmsg(jcr, M_FATAL, 0, _("Compression error\n"));
               sd->msg = msgsave;
               sd->msglen = 0;
-              close(fid);
+              close(ff_pkt->fid);
               return 0;
            }
             Dmsg2(100, "compressed len=%d uncompressed len=%d\n", 
@@ -288,59 +339,37 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
 
            sd->msg = jcr->compress_buf; /* write compressed buffer */
            sd->msglen = compress_len;
+        }
+#endif
+
 #ifndef NO_FD_SEND_TEST
+        /* Send the buffer to the Storage daemon */
+        if (!sparseBlock) {
+           if (ff_pkt->flags & FO_SPARSE) {
+              sd->msglen += SPARSE_FADDR_SIZE; /* include fileAddr in size */
+           }
            if (!bnet_send(sd)) {
               sd->msg = msgsave;     /* restore read buffer */
               sd->msglen = 0;
-              close(fid);
+              close(ff_pkt->fid);
               return 0;
            }
-            Dmsg1(130, "Send data to FD len=%d\n", sd->msglen);
-#endif
-           jcr->JobBytes += sd->msglen; /* count compressed bytes saved */
-           sd->msg = msgsave;        /* restore read buffer */
-           continue;
-        }
-#endif
-#ifndef NO_FD_SEND_TEST
-        if (!bnet_send(sd)) {
-           close(fid);
-           return 0;
         }
          Dmsg1(130, "Send data to FD len=%d\n", sd->msglen);
 #endif
-        jcr->JobBytes += sd->msglen;   /* count bytes saved */
-      } /* end while */
+        jcr->JobBytes += sd->msglen;   /* count bytes saved possibly compressed */
+        sd->msg = msgsave;             /* restore read buffer */
+
+      } /* end while read file data */
 
       if (sd->msglen < 0) {
          Jmsg(jcr, M_ERROR, 0, _("Network error. ERR=%s\n"), bnet_strerror(sd));
       }
 
-      /* Send data termination poll signal to Storage daemon.
-       *  NOTE possibly put this poll on a counter as specified
-       *  by the user to improve efficiency (i.e. poll every
-       *  other file, every third file, ... 
-       */
 #ifndef NO_FD_SEND_TEST
-#ifndef NO_POLL_TEST
-      bnet_sig(sd, BNET_EOD_POLL);
-      Dmsg0(130, "Send EndData_Poll\n");
-      /* ***FIXME**** change to use bget_msg() */
-      if (bnet_recv(sd) <= 0) {
-        close(fid);
-        return 0;
-      } else {
-         if (strcmp(sd->msg, "3000 OK\n") != 0) {
-           Jmsg1(jcr, M_FATAL, 0, _("Job aborted by Storage daemon: %s\n"), sd->msg);
-          close(fid);
-          return 0;
-        }
-      }
-#else 
-      bnet_sig(sd, BNET_EOD);
-#endif
+      bnet_sig(sd, BNET_EOD);        /* indicate end of file data */
 #endif /* NO_FD_SEND_TEST */
-      close(fid);                       /* close file */
+      close(ff_pkt->fid);            /* close file */
    }
 
 
@@ -357,12 +386,5 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
 #endif
       gotMD5 = 0;
    }
-#ifdef really_needed
-   if (ff_pkt->type == FT_DIR) {
-      Jmsg(jcr, M_SAVED, -1, _("     Directory saved normally: %s\n"), ff_pkt->link);
-   } else {
-      Jmsg(jcr, M_SAVED, -1, _("     File saved normally: %s\n"), ff_pkt->fname);
-   }
-#endif
    return 1;
 }
index 7c9a1ae70374fafbb3977b7ad951b0c32122870b..e16d10318dfa2df4def5388ae7c2f732e9628a1d 100644 (file)
@@ -26,7 +26,6 @@
  */
 
 #include "findlib/find.h"
-#include "lib/save-cwd.h"
 #define FILE_DAEMON 1
 #include "jcr.h"
 #include "protos.h"                   /* file daemon prototypes */
index 4e51e27f7fbfb8aaefd7083c95015d8b360425cf..5f1b7a038c34861635ab59d870f4de3cb357b22e 100644 (file)
@@ -29,3 +29,4 @@ extern void do_restore(JCR *jcr);
 extern int authenticate_director(JCR *jcr);
 extern int authenticate_storagedaemon(JCR *jcr);
 extern int make_estimate(JCR *jcr);
+
index 14f9c775012460068aaf84ae9393196c1cbb143a..43bba98fcef28f080dfa85a3aafb96f5bfbca9d8 100644 (file)
@@ -48,6 +48,7 @@ void do_restore(JCR *jcr)
    POOLMEM *fname;                   /* original file name */
    POOLMEM *ofile;                   /* output name with possible prefix */
    POOLMEM *lname;                   /* link name with possible prefix */
+   POOLMEM *attribsEx;               /* Extended attributes (Win32) */
    int32_t stream;
    uint32_t size;
    uint32_t VolSessionId, VolSessionTime, file_index;
@@ -56,7 +57,10 @@ void do_restore(JCR *jcr)
    int extract = FALSE;
    int ofd = -1;
    int type;
-   uint32_t total = 0;
+   uint32_t total = 0;               /* Job total but only 32 bits for debug */
+   char *wbuf;                       /* write buffer */
+   uint32_t wsize;                   /* write size */
+   uint64_t fileAddr = 0;            /* file write address */
    
    wherelen = strlen(jcr->where);
 
@@ -71,6 +75,7 @@ void do_restore(JCR *jcr)
    fname = get_pool_memory(PM_FNAME);
    ofile = get_pool_memory(PM_FNAME);
    lname = get_pool_memory(PM_FNAME);
+   attribsEx = get_pool_memory(PM_FNAME);
 
 #ifdef HAVE_LIBZ
    uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
@@ -78,7 +83,14 @@ void do_restore(JCR *jcr)
 #endif
 
    /* 
-    * Get a record from the Storage daemon
+    * Get a record from the Storage daemon. We are guaranteed to 
+    *  receive records in the following order:
+    *  1. Stream record header
+    *  2. Stream data
+    *       a. Attributes (Unix or Win32)
+    *   or  b. File data for the file
+    *   or  c. Possibly MD5 record
+    *  3. Repeat step 1
     */
    while (bnet_recv(sd) > 0 && !job_cancelled(jcr)) {
       /*
@@ -97,15 +109,15 @@ void do_restore(JCR *jcr)
       if (bnet_recv(sd) < 0 && !job_cancelled(jcr)) {
          Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
       }
-      if (size != ((uint32_t) sd->msglen)) {
+      if (size != (uint32_t)sd->msglen) {
          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);
 
       /* File Attributes stream */
-      if (stream == STREAM_UNIX_ATTRIBUTES) {
-        char *ap, *lp, *fp;
+      if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_WIN32_ATTRIBUTES) {
+        char *ap, *lp, *fp, *apex;
 
          Dmsg1(30, "Stream=Unix Attributes. extract=%d\n", extract);
         /* If extracting, it was from previous stream, so
@@ -113,12 +125,11 @@ void do_restore(JCR *jcr)
          */
         if (extract) {
            if (ofd < 0) {
-               Emsg0(M_ABORT, 0, _("Logic error output file should be open\n"));
+               Emsg0(M_ERROR, 0, _("Logic error output file should be open\n"));
            }
-           close(ofd);
-           ofd = -1;
+           set_attributes(jcr, fname, ofile, lname, type, stream, 
+                          &statp, attribsEx, &ofd);
            extract = FALSE;
-           set_statp(jcr, fname, ofile, lname, type, &statp);
             Dmsg0(30, "Stop extracting.\n");
         }
 
@@ -141,19 +152,20 @@ void do_restore(JCR *jcr)
          *    Filename
          *    Attributes
          *    Link name (if file linked i.e. FT_LNK)
+         *    Extended attributes (Win32)
          *
          */
          Dmsg1(100, "Attr: %s\n", sd->msg);
          if (sscanf(sd->msg, "%d %d", &record_file_index, &type) != 2) {
             Jmsg(jcr, M_FATAL, 0, _("Error scanning attributes: %s\n"), sd->msg);
-            Dmsg1(000, "\nError scanning attributes. %s\n", sd->msg);
+            Dmsg1(100, "\nError scanning attributes. %s\n", sd->msg);
            goto bail_out;
         }
          Dmsg2(100, "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"),
               file_index, record_file_index);
-            Dmsg0(000, "File index error\n");
+            Dmsg0(100, "File index error\n");
            goto bail_out;
         }
         ap = sd->msg;
@@ -178,15 +190,22 @@ void do_restore(JCR *jcr)
             lp = "";
         }
 
+        if (stream == STREAM_WIN32_ATTRIBUTES) {
+           apex = ap;                   /* start at attributes */
+           while (*apex++ != 0) {       /* skip attributes */
+              ;
+           }
+           while (*apex++ != 0) {       /* skip link name */
+              ;
+           }
+           pm_strcpy(&attribsEx, apex); /* make a copy */
+        } else {
+           *attribsEx = 0;              /* no extended attributes */
+        }
+
+         Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", fname, ap, attribsEx);
+
         decode_stat(ap, &statp);
-        /* 
-         *   ***FIXME***  add REAL Win32 code to backup.c
-         * Temp kludge so that low level routines (set_statp) know
-         *   we are dealing with a Win32 system.
-         */
-#ifdef HAVE_CYGWIN
-           statp.st_mode |= S_ISWIN32;
-#endif
         /*
          * Prepend the where directory so that the
          * files are put where the user wants.
@@ -228,37 +247,75 @@ void do_restore(JCR *jcr)
          Dmsg1(30, "Outfile=%s\n", ofile);
         print_ls_output(jcr, ofile, lname, type, &statp);
 
-        extract = create_file(jcr, fname, ofile, lname, type, &statp, &ofd);
+        extract = create_file(jcr, fname, ofile, lname, type, 
+                              stream, &statp, attribsEx, &ofd);
          Dmsg1(40, "Extract=%d\n", extract);
         if (extract) {
            jcr->JobFiles++;
+           fileAddr = 0;
         }
         jcr->num_files_examined++;
 
       /* Data stream */
-      } else if (stream == STREAM_FILE_DATA) {
+      } else if (stream == STREAM_FILE_DATA || stream == STREAM_SPARSE_DATA) {
         if (extract) {
-            Dmsg2(30, "Write %d bytes, total before write=%d\n", sd->msglen, total);
-           if (write(ofd, sd->msg, sd->msglen) != sd->msglen) {
+           if (stream == STREAM_SPARSE_DATA) {
+              ser_declare;
+              uint64_t faddr;
+              char ec1[50];
+
+              wbuf = sd->msg + SPARSE_FADDR_SIZE;
+              wsize = sd->msglen - SPARSE_FADDR_SIZE;
+              ser_begin(sd->msg, SPARSE_FADDR_SIZE);
+              unser_uint64(faddr);
+              if (fileAddr != faddr) {
+                 fileAddr = faddr;
+                 if (lseek(ofd, (off_t)fileAddr, SEEK_SET) < 0) {
+                     Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
+                        edit_uint64(fileAddr, ec1), ofile, strerror(errno));
+                    goto bail_out;
+                 }
+              }
+           } else {
+              wbuf = sd->msg;
+              wsize = sd->msglen;
+           }
+            Dmsg2(30, "Write %u bytes, total before write=%u\n", wsize, total);
+           if ((uint32_t)write(ofd, wbuf, wsize) != wsize) {
                Dmsg0(0, "===Write error===\n");
-               Jmsg2(jcr, M_ERROR, 0, "Write error on %s: %s\n", ofile, strerror(errno));
+               Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), ofile, strerror(errno));
               goto bail_out;
            }
-           total += sd->msglen;
-           jcr->JobBytes += sd->msglen;
+           total += wsize;
+           jcr->JobBytes += wsize;
+           fileAddr += wsize;
         }
        
       /* GZIP data stream */
-      } else if (stream == STREAM_GZIP_DATA) {
+      } else if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA) {
 #ifdef HAVE_LIBZ
         if (extract) {
            uLong compress_len;
            int stat;
 
+           if (stream == STREAM_SPARSE_GZIP_DATA) {
+              wbuf = sd->msg + SPARSE_FADDR_SIZE;
+              wsize = sd->msglen - SPARSE_FADDR_SIZE;
+              if (fileAddr != *((uint64_t *)sd->msg)) {
+                 fileAddr = *((uint64_t *)sd->msg);
+                 if (lseek(ofd, (off_t)fileAddr, SEEK_SET) < 0) {
+                     Jmsg2(jcr, M_ERROR, 0, "Seek error on %s: %s\n", ofile, strerror(errno));
+                    goto bail_out;
+                 }
+              }
+           } else {
+              wbuf = sd->msg;
+              wsize = sd->msglen;
+           }
            compress_len = compress_buf_size;
-            Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, sd->msglen);
+            Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, wsize);
            if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len, 
-                 (const Byte *)sd->msg, (uLong)sd->msglen)) != Z_OK) {
+                 (const Byte *)wbuf, (uLong)wsize)) != Z_OK) {
                Jmsg(jcr, M_ERROR, 0, _("Uncompression error. ERR=%d\n"), stat);
               goto bail_out;
            }
@@ -271,6 +328,7 @@ void do_restore(JCR *jcr)
            }
            total += compress_len;
            jcr->JobBytes += compress_len;
+           fileAddr += compress_len;
         }
 #else
         if (extract) {
@@ -282,12 +340,11 @@ void do_restore(JCR *jcr)
       } else if (extract) {
          Dmsg1(30, "Found wierd stream %d\n", stream);
         if (ofd < 0) {
-            Emsg0(M_ABORT, 0, _("Logic error output file should be open\n"));
+            Emsg0(M_ERROR, 0, _("Logic error output file should be open\n"));
         }
-        close(ofd);
-        ofd = -1;
+        set_attributes(jcr, fname, ofile, lname, type, stream, 
+                       &statp, attribsEx, &ofd);
         extract = FALSE;
-        set_statp(jcr, fname, ofile, lname, type, &statp);
       } else if (stream != STREAM_MD5_SIGNATURE) {
          Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
       }
@@ -297,8 +354,8 @@ void do_restore(JCR *jcr)
     * archive since we just hit an end of file, so close the file. 
     */
    if (ofd >= 0) {
-      close(ofd);
-      set_statp(jcr, fname, ofile, lname, type, &statp);
+      set_attributes(jcr, fname, ofile, lname, type, stream, 
+                    &statp, attribsEx, &ofd);
    }
    jcr->JobStatus = JS_Terminated;
    goto ok_out;
@@ -313,6 +370,7 @@ ok_out:
    free_pool_memory(fname);
    free_pool_memory(ofile);
    free_pool_memory(lname);
+   free_pool_memory(attribsEx);
    Dmsg2(10, "End Do Restore. Files=%d Bytes=%" lld "\n", jcr->JobFiles,
       jcr->JobBytes);
 }         
index 938aba1d633cf9199e35cc01971f32ca41b07be3..ddb3d1d04c59f3f94d0098f48853bd9df4d75535 100755 (executable)
@@ -21,6 +21,7 @@
    Copyright (2000) Kern E. Sibbald
 */
 
+#include <unistd.h>
 #include <lmcons.h>
 #include <ctype.h>
 #include "winbacula.h"
index 6b84dac1a4a0c161091dba699a92a59f6e6044d9..12fbd39543ffdd2044ba27bc59f78f75f40f9490 100644 (file)
@@ -20,8 +20,10 @@ first_rule: all
 dummy:
 
 #
-LIBSRCS = find.c match.c find_one.c
-LIBOBJS = find.o match.o find_one.o
+LIBSRCS = find.c match.c find_one.c attibs.c create_file.c \
+         makepath.c save-cwd.c
+LIBOBJS = find.o match.o find_one.o attribs.o create_file.o \
+         makepath.o save-cwd.o
 
 .SUFFIXES:     .c .o
 .PHONY:
diff --git a/bacula/src/findlib/attribs.c b/bacula/src/findlib/attribs.c
new file mode 100755 (executable)
index 0000000..ad8bedd
--- /dev/null
@@ -0,0 +1,407 @@
+/*
+ *  Encode and decode standard Unix attributes and
+ *   Extended attributes for Win32 and
+ *   other non-Unix systems, or Unix systems with ACLs, ...
+ *
+ *    Kern Sibbald, October MMII
+ *
+ *   Version $Id$
+ *
+ */
+/*
+   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+#include "bacula.h"
+#include "find.h"
+#include "jcr.h"
+
+#ifdef HAVE_CYGWIN
+#include <windows.h>
+
+/* Forward referenced subroutines */
+static
+int set_win32_attributes(void *jcr, char *fname, char *ofile, char *lname, 
+                        int type, int stream, struct stat *statp,
+                        char *attribsEx, int *ofd);
+void unix_name_to_win32(char *name);
+extern "C" HANDLE get_osfhandle(int fd);
+void win_error(void *jcr, char *prefix, char *ofile);
+#endif
+
+
+/*=============================================================*/
+/*                                                            */
+/*            ***  A l l  S y s t e m s ***                   */
+/*                                                            */
+/*=============================================================*/
+
+
+/* Encode a stat structure into a base64 character string */
+void encode_stat(char *buf, struct stat *statp)
+{
+   char *p = buf;
+   /*
+    * NOTE: we should use rdev as major and minor device if
+    * it is a block or char device (S_ISCHR(statp->st_mode)
+    * or S_ISBLK(statp->st_mode)).  In all other cases,
+    * it is not used.  
+    *
+    */
+   p += to_base64((int64_t)statp->st_dev, p);
+   *p++ = ' ';                        /* separate fields with a space */
+   p += to_base64((int64_t)statp->st_ino, p);
+   *p++ = ' ';
+   p += to_base64((int64_t)statp->st_mode, p);
+   *p++ = ' ';
+   p += to_base64((int64_t)statp->st_nlink, p);
+   *p++ = ' ';
+   p += to_base64((int64_t)statp->st_uid, p);
+   *p++ = ' ';
+   p += to_base64((int64_t)statp->st_gid, p);
+   *p++ = ' ';
+   p += to_base64((int64_t)statp->st_rdev, p);
+   *p++ = ' ';
+   p += to_base64((int64_t)statp->st_size, p);
+   *p++ = ' ';
+   p += to_base64((int64_t)statp->st_blksize, p);
+   *p++ = ' ';
+   p += to_base64((int64_t)statp->st_blocks, p);
+   *p++ = ' ';
+   p += to_base64((int64_t)statp->st_atime, p);
+   *p++ = ' ';
+   p += to_base64((int64_t)statp->st_mtime, p);
+   *p++ = ' ';
+   p += to_base64((int64_t)statp->st_ctime, p);
+   *p = 0;
+   return;
+}
+
+
+
+/* Decode a stat packet from base64 characters */
+void
+decode_stat(char *buf, struct stat *statp)
+{
+   char *p = buf;
+   int64_t val;
+
+   p += from_base64(&val, p);
+   statp->st_dev = val;
+   p++;                              /* skip space */
+   p += from_base64(&val, p);
+   statp->st_ino = val;
+   p++;
+   p += from_base64(&val, p);
+   statp->st_mode = val;
+   p++;
+   p += from_base64(&val, p);
+   statp->st_nlink = val;
+   p++;
+   p += from_base64(&val, p);
+   statp->st_uid = val;
+   p++;
+   p += from_base64(&val, p);
+   statp->st_gid = val;
+   p++;
+   p += from_base64(&val, p);
+   statp->st_rdev = val;
+   p++;
+   p += from_base64(&val, p);
+   statp->st_size = val;
+   p++;
+   p += from_base64(&val, p);
+   statp->st_blksize = val;
+   p++;
+   p += from_base64(&val, p);
+   statp->st_blocks = val;
+   p++;
+   p += from_base64(&val, p);
+   statp->st_atime = val;
+   p++;
+   p += from_base64(&val, p);
+   statp->st_mtime = val;
+   p++;
+   p += from_base64(&val, p);
+   statp->st_ctime = val;
+}
+
+/*
+ * Set file modes, permissions and times
+ *
+ *  fname is the original filename  
+ *  ofile is the output filename (may be in a different directory)
+ *
+ * Returns:  1 on success
+ *          0 on failure
+ */
+int set_attributes(void *jcr, char *fname, char *ofile, char *lname, 
+                  int type, int stream, struct stat *statp,
+                  char *attribsEx, int *ofd)
+{
+   struct utimbuf ut;   
+
+#ifdef HAVE_CYGWIN
+   if (set_win32_attributes(jcr, fname, ofile, lname, type, stream,
+                           statp, attribsEx, ofd)) {
+      return 1;
+   }
+   /*
+    * If Windows stuff failed, e.g. attempt to restore Unix file
+    *  to Windows, simply fall through and we will do it the    
+    *  universal way.
+    */
+#endif
+
+   if (*ofd != -1) {
+      close(*ofd);                   /* first close file */
+      *ofd = -1;
+   }
+
+   ut.actime = statp->st_atime;
+   ut.modtime = statp->st_mtime;
+
+   /* ***FIXME**** optimize -- don't do if already correct */
+   if (type == FT_LNK) {
+      if (lchown(ofile, statp->st_uid, statp->st_gid) < 0) {
+         Jmsg2(jcr, M_ERROR, 0, "Unable to set file owner %s: ERR=%s\n",
+           ofile, strerror(errno));
+        return 0;
+      }
+   } else {
+      if (chown(ofile, statp->st_uid, statp->st_gid) < 0) {
+         Jmsg2(jcr, M_ERROR, 0, "Unable to set file owner %s: ERR=%s\n",
+           ofile, strerror(errno));
+        return 0;
+      }
+   }
+   if (chmod(ofile, statp->st_mode) < 0) {
+      Jmsg2(jcr, M_ERROR, 0, "Unable to set file modes %s: ERR=%s\n",
+        ofile, strerror(errno));
+      return 0;
+   }
+
+   /*
+    * Update file times.
+    */
+   if (utime(ofile, &ut) < 0) {
+      Jmsg2(jcr, M_ERROR, 0, "Unable to set file times %s: ERR=%s\n",
+        ofile, strerror(errno));
+      return 0;
+   }
+   return 1;
+}
+
+
+/*=============================================================*/
+/*                                                            */
+/*                * * *  U n i x * * * *                      */
+/*                                                            */
+/*=============================================================*/
+
+#ifndef HAVE_CYGWIN
+    
+/*
+ * If you have a Unix system with extended attributes (e.g.
+ *  ACLs for Solaris, do it here.
+ */
+int encode_attribsEx(void *jcr, char *attribsEx, FF_PKT *ff_pkt)
+{
+   *attribsEx = 0;                   /* no extended attributes */
+   return STREAM_UNIX_ATTRIBUTES;
+}
+
+#endif
+
+
+
+/*=============================================================*/
+/*                                                            */
+/*                * * *  W i n 3 2 * * * *                    */
+/*                                                            */
+/*=============================================================*/
+
+#ifdef HAVE_CYGWIN
+
+int encode_attribsEx(void *jcr, char *attribsEx, FF_PKT *ff_pkt)
+{
+   char *p = attribsEx;
+   WIN32_FILE_ATTRIBUTE_DATA atts;
+   ULARGE_INTEGER li;
+
+   attribsEx[0] = 0;                 /* no extended attributes */
+
+   pm_strcpy(&ff_pkt->sys_fname, ff_pkt->fname);
+   unix_name_to_win32(ff_pkt->sys_fname);
+   if (!GetFileAttributesEx(ff_pkt->sys_fname, GetFileExInfoStandard,
+                           (LPVOID)&atts)) {
+      win_error(jcr, "GetFileAttributesEx:", ff_pkt->sys_fname);
+      return STREAM_WIN32_ATTRIBUTES;
+   }
+
+   p += to_base64((uint64_t)atts.dwFileAttributes, p);
+   *p++ = ' ';                        /* separate fields with a space */
+   li.LowPart = atts.ftCreationTime.dwLowDateTime;
+   li.HighPart = atts.ftCreationTime.dwHighDateTime;
+   p += to_base64((uint64_t)li.QuadPart, p);
+   *p++ = ' ';
+   li.LowPart = atts.ftLastAccessTime.dwLowDateTime;
+   li.HighPart = atts.ftLastAccessTime.dwHighDateTime;
+   p += to_base64((uint64_t)li.QuadPart, p);
+   *p++ = ' ';
+   li.LowPart = atts.ftLastWriteTime.dwLowDateTime;
+   li.HighPart = atts.ftLastWriteTime.dwHighDateTime;
+   p += to_base64((uint64_t)li.QuadPart, p);
+   *p++ = ' ';
+   p += to_base64((uint64_t)atts.nFileSizeHigh, p);
+   *p++ = ' ';
+   p += to_base64((uint64_t)atts.nFileSizeLow, p);
+   *p = 0;
+   return STREAM_WIN32_ATTRIBUTES;
+}
+
+/* Define attributes that are legal to set with SetFileAttributes() */
+#define SET_ATTRS ( \
+         FILE_ATTRIBUTE_ARCHIVE| \
+         FILE_ATTRIBUTE_HIDDEN| \
+         FILE_ATTRIBUTE_NORMAL| \
+         FILE_ATTRIBUTE_NOT_CONTENT_INDEXED| \
+         FILE_ATTRIBUTE_OFFLINE| \
+         FILE_ATTRIBUTE_READONLY| \
+         FILE_ATTRIBUTE_SYSTEM| \
+        FILE_ATTRIBUTE_TEMPORARY)
+
+
+/*
+ * Set Extended File Attributes for Win32
+ *
+ *  fname is the original filename  
+ *  ofile is the output filename (may be in a different directory)
+ *
+ * Returns:  1 on success
+ *          0 on failure
+ */
+static
+int set_win32_attributes(void *jcr, char *fname, char *ofile, char *lname, 
+                        int type, int stream, struct stat *statp,
+                        char *attribsEx, int *ofd)
+{
+   char *p = attribsEx;
+   int64_t val;
+   WIN32_FILE_ATTRIBUTE_DATA atts;
+   ULARGE_INTEGER li;
+   int fid, stat;
+
+   if (!p || !*p) {                  /* we should have attributes */
+      Dmsg2(100, "Attributes missing. of=%s ofd=%d\n", ofile, *ofd);
+      if (*ofd != -1) {
+        close(*ofd);
+        *ofd = -1;
+      }
+      return 0;
+   } else {
+      Dmsg2(100, "Attribs %s = %s\n", ofile, attribsEx);
+   }
+
+   p += from_base64(&val, p);
+   atts.dwFileAttributes = val;
+   p++;                              /* skip space */
+   p += from_base64(&val, p);
+   li.QuadPart = val;
+   atts.ftCreationTime.dwLowDateTime = li.LowPart;
+   atts.ftCreationTime.dwHighDateTime = li.HighPart;
+   p++;                              /* skip space */
+   p += from_base64(&val, p);
+   li.QuadPart = val;
+   atts.ftLastAccessTime.dwLowDateTime = li.LowPart;
+   atts.ftLastAccessTime.dwHighDateTime = li.HighPart;
+   p++;                              /* skip space */
+   p += from_base64(&val, p);
+   li.QuadPart = val;
+   atts.ftLastWriteTime.dwLowDateTime = li.LowPart;
+   atts.ftLastWriteTime.dwHighDateTime = li.HighPart;
+   p++;   
+   p += from_base64(&val, p);
+   atts.nFileSizeHigh = val;
+   p++;
+   p += from_base64(&val, p);
+   atts.nFileSizeLow = val;
+
+   /* At this point, we have reconstructed the WIN32_FILE_ATTRIBUTE_DATA pkt */
+
+   if (*ofd == -1) {
+      Dmsg1(100, "File not open: %s\n", ofile);
+      fid = open(ofile, O_RDWR);     /* attempt to open the file */
+      if (fid >= 0) {
+        *ofd = fid;
+      }
+   }
+
+   if (*ofd != -1) {
+      Dmsg1(100, "SetFileTime %s\n", ofile);
+      stat = SetFileTime(get_osfhandle(*ofd),
+                        &atts.ftCreationTime,
+                        &atts.ftLastAccessTime,
+                        &atts.ftLastWriteTime);
+      if (stat != 1) {
+         win_error(jcr, "SetFileTime:", ofile);
+      }
+      close(*ofd);
+      *ofd = -1;
+   }
+
+   /* Bash name to Windows format */
+   unix_name_to_win32(ofile);
+   Dmsg1(100, "SetFileAtts %s\n", ofile);
+   stat = SetFileAttributes(ofile, atts.dwFileAttributes & SET_ATTRS);
+   if (stat != 1) {
+      win_error(jcr, "SetFileAttributes:", ofile);
+   }
+   return 1;
+}
+
+void win_error(void *vjcr, char *prefix, char *ofile)
+{
+   JCR *jcr = (JCR *)vjcr; 
+   DWORD lerror = GetLastError();
+   LPTSTR msg;
+   FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
+                FORMAT_MESSAGE_FROM_SYSTEM,
+                NULL,
+                lerror,
+                0,
+                (LPTSTR)&msg,
+                0,
+                NULL);
+   Dmsg3(100, "Error in %s on file %s: ERR=%s\n", prefix, ofile, msg);
+   Jmsg3(jcr, M_INFO, 0, "Error in %s file %s: ERR=%s\n", prefix, ofile, msg);
+   LocalFree(msg);
+}
+
+void unix_name_to_win32(char *name)
+{
+   char *p;
+   for (p=name; *p; p++) {
+      if (*p == '/') {
+         *p = '\\';
+      }
+   }
+}
+
+#endif /* HAVE_CYGWIN */
diff --git a/bacula/src/findlib/create_file.c b/bacula/src/findlib/create_file.c
new file mode 100644 (file)
index 0000000..66e4921
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ *  Create a file, and reset the modes
+ *
+ *    Kern Sibbald, November MM
+ *
+ *   Version $Id$
+ *
+ */
+/*
+   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+#include "bacula.h"
+#include "find.h"
+
+#ifndef S_IRWXUGO
+#define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO)
+#endif
+
+#ifndef IS_CTG
+#define IS_CTG(x) 0
+#define O_CTG 0
+#endif
+
+
+/*
+ * Create the file, or the directory
+ *
+ *  fname is the original filename  
+ *  ofile is the output filename (may be in a different directory)
+ *
+ * Returns:  1 on success
+ *          0 on failure
+ *
+ *   Note, we create the file here, except for special files,
+ *     we do not set the attributes because we want to first 
+ *     write the file, then when the writing is done, set the
+ *     attributes.
+ *   So, we return with the file descriptor open for normal 
+ *     files.
+ *
+ */
+int create_file(void *jcr, char *fname, char *ofile, char *lname,
+               int type, int stream, struct stat *statp, 
+               char *attribsEx, int *ofd)
+{
+   int new_mode, parent_mode, mode;
+   uid_t uid;
+   gid_t gid;
+   int stat = 0;
+   int fnl, pnl;
+   char *f, *p, savechr;
+
+   *ofd = -1;
+/*
+ * new_mode = S_IRWXUGO & ~umask(0);
+ */
+   new_mode = statp->st_mode;
+   Dmsg2(300, "newmode=%x file=%s\n", new_mode, ofile);
+   parent_mode = S_IWUSR | S_IXUSR | new_mode;
+   gid = statp->st_gid;
+   uid = statp->st_uid;
+
+   switch (type) {
+   case FT_LNKSAVED:                 /* Hard linked, file already saved */
+      Dmsg2(130, "Hard link %s => %s\n", ofile, lname);
+      if (link(lname, ofile) != 0) {
+         Jmsg3(jcr, M_ERROR, 0, "Could not hard link %s ==> %s: ERR=%s\n", 
+              ofile, lname, strerror(errno));
+      }
+      break;
+   case FT_REGE:                     /* empty file */
+   case FT_REG:                      /* regular file */
+      /* Separate pathname and filename */
+      for (p=f=ofile; *p; p++) {
+         if (*p == '/') {
+           f = p;                    /* possible filename */
+        }
+      }
+      if (*f == '/') {
+        f++;
+      }
+
+      fnl = p - f;
+      if (fnl == 0) {
+         Jmsg1(jcr, M_ERROR, 0, "Zero length filename: %s\n", fname);
+        return 0;
+      }
+
+      pnl = f - ofile - 1;    
+      if (pnl <= 0) {
+         Jmsg1(jcr, M_ERROR, 0, "Zero length path: %s\n", fname);
+        return 0;
+      }
+      savechr = ofile[pnl];
+      ofile[pnl] = 0;                /* terminate path */
+
+      Dmsg1(50, "Make path %s\n", ofile);
+      /*
+       * If we need to make the directory, ensure that it is with
+       * execute bit set (i.e. parent_mode), and preserve what already
+       * exists. Normally, this should do nothing.
+       */
+      stat = !make_path(jcr, ofile, parent_mode, parent_mode, uid, gid, 1, NULL);
+      if (stat == 0) {
+         Dmsg1(0, "Could not make path. %s\n", ofile);
+        return 0;
+      }
+      
+      ofile[pnl] = savechr;          /* restore full name */
+      Dmsg1(100, "Create file %s\n", ofile);
+      mode =  O_WRONLY | O_CREAT | O_TRUNC;
+      if (IS_CTG(statp->st_mode)) {
+        mode |= O_CTG;               /* set contiguous bit if needed */
+      }
+      Dmsg1(50, "Create file: %s\n", ofile);
+      if ((*ofd = open(ofile, mode, S_IRUSR | S_IWUSR)) < 0) {
+         Jmsg2(jcr, M_ERROR, 0, "Could not create %s: ERR=%s\n", ofile, strerror(errno));
+        return 0;
+      }
+      return 1;
+   case FT_LNK:
+      Dmsg2(130, "FT_LNK should restore: %s -> %s\n", ofile, lname);
+      if (symlink(lname, ofile) != 0 && errno != EEXIST) {
+         Jmsg3(jcr, M_ERROR, 0, "Could not symlink %s -> %s: ERR=%s\n", 
+           ofile, lname, strerror(errno));
+      }
+      return 0;
+   case FT_DIR:
+      Dmsg2(300, "Make dir mode=%o dir=%s\n", new_mode, ofile);
+      if (make_path(jcr, ofile, new_mode, parent_mode, uid, gid, 0, NULL) != 0) {
+         Jmsg1(jcr, M_ERROR, 0, "Could not make directory: %s\n", ofile);
+      }
+      return 0;
+   case FT_SPEC:
+      if (S_ISFIFO(statp->st_mode)) {
+         Dmsg1(0, "Restore fifo: %s\n", ofile);
+        if (mkfifo(ofile, statp->st_mode) != 0) {
+            Jmsg2(jcr, M_ERROR, 0, "Cannot make fifo %s: ERR=%s\n", ofile, strerror(errno));
+           return 0;
+        }
+      } else {         
+         Dmsg1(0, "Restore node: %s\n", ofile);
+        if (mknod(ofile, statp->st_mode, statp->st_rdev) != 0) {
+            Jmsg2(jcr, M_ERROR, 0, "Cannot make node %s: ERR=%s\n", ofile, strerror(errno));
+           return 0;
+        }
+      }       
+      Dmsg1(0, "FT_SPEC %s\n", ofile);
+      return 0;
+
+   /* The following should not occur */
+   case FT_NOACCESS:
+   case FT_NOFOLLOW:
+   case FT_NOSTAT:
+   case FT_DIRNOCHG:
+   case FT_NOCHG:
+   case FT_ISARCH:
+   case FT_NORECURSE:
+   case FT_NOFSCHG:
+   case FT_NOOPEN:
+      Jmsg2(jcr, M_ERROR, 0, "Original file %s not saved. Stat=%d\n", fname, type);
+      return 0;
+   default:
+      Jmsg2(jcr, M_ERROR, 0, "Unknown file type %d; not restored: %s\n", type, fname);
+      return 0;
+   }
+
+   return 0;
+}
index 02b433932cbb0257bc4f3d5f4a2c7f6bbdc0b502..06f85ae800fbe14667c99642951fd22c6f17cd5a 100644 (file)
@@ -52,6 +52,8 @@ FF_PKT *init_find_files()
   ff = (FF_PKT *) bmalloc(sizeof(FF_PKT));
   memset(ff, 0, sizeof(FF_PKT));
 
+  ff->sys_fname = get_pool_memory(PM_FNAME);
+
   init_include_exclude_files(ff);          /* init lists */
   ff->mtime_only = 1;
   ff->one_file_system = 1;
@@ -132,6 +134,7 @@ term_find_files(FF_PKT *ff)
 {
   term_include_exclude_files(ff);
   term_find_one(ff);
+  free_pool_memory(ff->sys_fname);
   free(ff);
   return;
 }
index 2c5d1a07412c776fba683ad0e3c2ef17297a6d40..50fd5d0f6ef768a68cd78111d027465f6eea4e4b 100755 (executable)
@@ -4,32 +4,47 @@
  *     Kern Sibbald MIM
  */
 /*
-   Copyright (C) 2000, 2001 Kern Sibbald and John Walker
+   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License
-   as published by the Free Software Foundation; either version 2
-   of the License, or (at your option) any later version.
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef __FILES_H
 #define __FILES_H
 
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#define NAMELEN(dirent) (strlen((dirent)->d_name))
+#endif
+#include <sys/file.h>
+#include <utime.h>
+
+#define MODE_RALL (S_IRUSR|S_IRGRP|S_IROTH)
+
+#define DEFAULT_NAMEBUF_LEN 150       /* default filename buffer length */
+
 #ifdef HAVE_FNMATCH
 #include <fnmatch.h>
 #else
 #include "lib/fnmatch.h"
 #endif
 
+#include "save-cwd.h"
+
 
 /* 
  *  NOTE!!! These go on the tape, so don't change them. If 
 #define FT_NOFSCHG   14               /* Different file system, prohibited */
 #define FT_NOOPEN    15               /* Could not open directory */
 
-/* FileSet options */     
-#define FO_MD5      0x1               /* Do MD5 checksum */
-#define FO_GZIP     0x2               /* Do Zlib compression */
-
+/* Options saved in "flag" of ff packet */
+#define FO_MD5          0x01          /* Do MD5 checksum */
+#define FO_GZIP         0x02          /* Do Zlib compression */
+#define FO_NO_RECURSION 0x04          /* no recursion in directories */
+#define FO_MULTIFS      0x08          /* multiple file systems */
+#define FO_SPARSE       0x10          /* do sparse file checking */
 
+/* Options saved in "options" of include list */
+/* ****FIXME**** replace OPT_ flags with FO_ */
 #define OPT_compute_MD5       0x01    /* compute MD5 of file's data */
 #define OPT_GZIP_compression  0x02    /* use GZIP compression */
 #define OPT_no_recursion      0x04    /* no recursion in directories */
 #define OPT_multifs           0x08    /* multiple file systems */
+#define OPT_sparse            0x10    /* do sparse file checking */
 
 
 struct s_included_file {
@@ -86,8 +106,10 @@ struct s_excluded_file {
 typedef struct ff {
    char *fname;                       /* filename */
    char *link;                        /* link if file linked */
+   POOLMEM *sys_fname;                /* system filename */
    struct stat statp;                 /* stat packet */
    int type;                          /* FT_ type from above */
+   int fid;                           /* file id if opened */
    int flags;                         /* control flags */
    int ff_errno;                      /* errno */
    int incremental;                   /* do incremental save */
@@ -109,20 +131,6 @@ typedef struct ff {
    struct f_link *linklist;           /* hard linked files */
 } FF_PKT;
 
-/* From find.c */
-FF_PKT *init_find_files();
-void set_find_options(FF_PKT *ff, int incremental, time_t mtime);
-int find_files(FF_PKT *ff, int sub(FF_PKT *ff_pkt, void *hpkt), void *pkt);
-void term_find_files(FF_PKT *ff);
-
-/* From match.c */
-void init_include_exclude_files(FF_PKT *ff);
-void term_include_exclude_files(FF_PKT *ff);
-void add_fname_to_include_list(FF_PKT *ff, int prefixed, char *fname);
-void add_fname_to_exclude_list(FF_PKT *ff, char *fname);
-struct s_included_file *get_next_included_file(
-    FF_PKT *ff, struct s_included_file *inc);
-int file_is_excluded(FF_PKT *ff, char *file);
-int file_is_included(FF_PKT *ff, char *file);
+#include "protos.h"
 
 #endif /* __FILES_H */
index 937c3dcf281103d5ba085c5c0ebe879a4abaa34d..3a62a6b766cc26bd47bf0fbeffb2bfc2c423a287 100755 (executable)
@@ -27,7 +27,7 @@
 
 #include "bacula.h"
 #include "find.h"
-#include "system.h"
+/*#include "system.h" */
 
 
 extern size_t name_max;              /* filename max length */
@@ -71,12 +71,12 @@ struct utimbuf
  */
 int
 find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt, 
-                           char *p, dev_t parent_device, int top_level)
+              char *fname, dev_t parent_device, int top_level)
 {
    struct utimbuf restore_times;
    int rtn_stat;
 
-   ff_pkt->fname = ff_pkt->link = p;
+   ff_pkt->fname = ff_pkt->link = fname;
    if (ff_pkt->compute_MD5) {
       ff_pkt->flags |= FO_MD5;
    }
@@ -84,17 +84,17 @@ find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt
       ff_pkt->flags |= FO_GZIP;
    }
 
-   if (lstat(p, &ff_pkt->statp) != 0) {
+   if (lstat(fname, &ff_pkt->statp) != 0) {
        /* Cannot stat file */
        ff_pkt->type = FT_NOSTAT;
        ff_pkt->ff_errno = errno;
        return handle_file(ff_pkt, pkt);
    }
 
-   Dmsg1(60, "File ----: %s\n", p);
+   Dmsg1(60, "File ----: %s\n", fname);
 #ifdef DEBUG
    if (S_ISLNK(ff_pkt->statp.st_mode))
-      Dmsg1(60, "Link-------------: %s \n", p);
+      Dmsg1(60, "Link-------------: %s \n", fname);
 #endif
 
    /* Save current times of this directory in case we need to
@@ -158,10 +158,10 @@ find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt
          }
 
        /* File not previously dumped. Chain it into our list. */
-       lp = (struct f_link *)bmalloc(sizeof (struct f_link) + strlen(p));
+       lp = (struct f_link *)bmalloc(sizeof (struct f_link) + strlen(fname));
        lp->ino = ff_pkt->statp.st_ino;
        lp->dev = ff_pkt->statp.st_dev;
-       strcpy (lp->name, p);
+       strcpy (lp->name, fname);
        lp->next = ff_pkt->linklist;
        ff_pkt->linklist = lp;
    }
@@ -175,7 +175,7 @@ find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt
        /* Don't bother opening empty, world readable files.  Also do not open
          files when archive is meant for /dev/null.  */
        if (ff_pkt->null_output_device || (sizeleft == 0
-              && MODE_R == (MODE_R & ff_pkt->statp.st_mode))) {
+              && MODE_RALL == (MODE_RALL & ff_pkt->statp.st_mode))) {
          ff_pkt->type = FT_REGE;
        } else {
          ff_pkt->type = FT_REG;
@@ -186,14 +186,14 @@ find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt
        int size;
        char *buffer = (char *)alloca(PATH_MAX + 1);
 
-       size = readlink(p, buffer, PATH_MAX + 1);
+       size = readlink(fname, buffer, PATH_MAX + 1);
        if (size < 0) {
           /* Could not follow link */                             
           ff_pkt->type = FT_NOFOLLOW;
           ff_pkt->ff_errno = errno;
           return handle_file(ff_pkt, pkt);
        }
-       buffer[size] = '\0';
+       buffer[size] = 0;
        ff_pkt->link = buffer;
        ff_pkt->type = FT_LNK;          /* got a real link */
        return handle_file(ff_pkt, pkt);
@@ -202,23 +202,23 @@ find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt
        DIR *directory;
        struct dirent *entry, *result;
        char *namebuf;
-       size_t buflen;
+       size_t namebuf_len;
        size_t len;
        int status;
        dev_t our_device = ff_pkt->statp.st_dev;
 
-       if (access(p, R_OK) == -1 && geteuid() != 0) {
+       if (access(fname, R_OK) == -1 && geteuid() != 0) {
           /* Could not access() directory */
           ff_pkt->type = FT_NOACCESS;
           ff_pkt->ff_errno = errno;
           return handle_file(ff_pkt, pkt);
        }
 
-       /* Build new prototype name.  Ensure exactly one trailing slash.  */
-       len = strlen(p);
-       buflen = len + NAME_FIELD_SIZE;
-       namebuf = (char *)bmalloc(buflen + 2);
-       strncpy(namebuf, p, buflen);
+       /* Build a canonical directory name with a trailing slash. */
+       len = strlen(fname);
+       namebuf_len = len + DEFAULT_NAMEBUF_LEN;
+       namebuf = (char *)bmalloc(namebuf_len + 2);
+       strncpy(namebuf, fname, namebuf_len);
        while (len >= 1 && namebuf[len - 1] == '/')
         len--;
        namebuf[len++] = '/';
@@ -263,7 +263,7 @@ find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt
        * Now process the files in this directory.
        */
        errno = 0;
-       if ((directory = opendir(p)) == NULL) {
+       if ((directory = opendir(fname)) == NULL) {
          free(namebuf);
          ff_pkt->type = FT_NOOPEN;
          ff_pkt->ff_errno = errno;
@@ -271,7 +271,7 @@ find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt
        }
 
        /*
-       * This could possibly run faster if we chdir to the directory
+       * This would possibly run faster if we chdir to the directory
        * before traversing it.
        */
        rtn_stat = 1;
@@ -292,9 +292,9 @@ find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt
              continue;
           }
 
-          if ((int)NAMLEN(entry) + len >= buflen) {
-              buflen = len + NAMLEN(entry);
-              namebuf = (char *)brealloc(namebuf, buflen + 2);
+          if ((int)NAMELEN(entry) + len >= namebuf_len) {
+              namebuf_len = len + NAMELEN(entry);
+              namebuf = (char *)brealloc(namebuf, namebuf_len + 2);
           }
           strcpy(namebuf + len, entry->d_name);
           if (!file_is_excluded(ff_pkt, namebuf)) {
@@ -305,7 +305,7 @@ find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt
        free(namebuf);
        free(entry);
        if (ff_pkt->atime_preserve) {
-         utime(p, &restore_times);
+         utime(fname, &restore_times);
        }
        return rtn_stat;
    } /* end check for directory */
diff --git a/bacula/src/findlib/makepath.c b/bacula/src/findlib/makepath.c
new file mode 100644 (file)
index 0000000..53fa1cc
--- /dev/null
@@ -0,0 +1,396 @@
+/* makepath.c -- Ensure that a directory path exists.
+
+   Copyright (C) 1990, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* Written by David MacKenzie <djm@gnu.ai.mit.edu> and Jim Meyering.  */
+
+/* 
+ *   Modified by Kern Sibbald for use in Bacula, December 2000
+ *
+ *   Version $Id$
+ */
+
+#include "bacula.h"
+#include "jcr.h"
+#include "save-cwd.h"
+
+
+#if !defined(S_ISDIR) && defined(S_IFDIR)
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+#ifndef S_IRWXUGO
+# define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO)
+#endif
+
+
+#ifndef S_ISUID
+# define S_ISUID 04000
+#endif
+#ifndef S_ISGID
+# define S_ISGID 02000
+#endif
+#ifndef S_ISVTX
+# define S_ISVTX 01000
+#endif
+#ifndef S_IRUSR
+# define S_IRUSR 0200
+#endif
+#ifndef S_IWUSR
+# define S_IWUSR 0200
+#endif
+#ifndef S_IXUSR
+# define S_IXUSR 0100
+#endif
+
+#ifndef S_IRWXU
+# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
+#endif
+
+#define WX_USR (S_IWUSR | S_IXUSR)
+
+#define quote(path) path
+
+extern void strip_trailing_slashes();
+
+static int
+cleanup(struct saved_cwd *cwd)
+{
+   if (cwd->do_chdir) {
+      int _fail = restore_cwd(cwd, NULL, NULL);
+      free_cwd(cwd);
+      if (_fail)
+        return 1;
+   }
+   return 0;
+}
+
+
+/* Attempt to create directory DIR (aka DIRPATH) with the specified MODE.
+   If CREATED_DIR_P is non-NULL, set *CREATED_DIR_P to non-zero if this
+   function creates DIR and to zero otherwise. Give a diagnostic and
+   return non-zero if DIR cannot be created or cannot be determined to
+   exist already.  Use DIRPATH in any diagnostic, not DIR.
+   Note that if DIR already exists, this function will return zero
+   (indicating success) and will set *CREATED_DIR_P to zero.  */
+
+static int
+make_dir(void *jcr, const char *dir, const char *dirpath, mode_t mode, int *created_dir_p)
+{
+  int fail = 0;
+  int created_dir;
+
+  Dmsg2(300, "make_dir mode=%o dir=%s\n", mode, dir);
+  created_dir = (mkdir(dir, mode) == 0);
+
+  if (!created_dir) {
+      struct stat stats;
+
+      /* The mkdir and stat calls below may appear to be reversed.
+        They are not.  It is important to call mkdir first and then to
+        call stat (to distinguish the three cases) only if mkdir fails.
+         The alternative to this approach is to `stat' each directory,
+         then to call mkdir if it doesn't exist.  But if some other process
+        were to create the directory between the stat & mkdir, the mkdir
+        would fail with EEXIST.  */
+
+      if (stat(dir, &stats)) {
+          Jmsg(jcr, M_ERROR, 0, "Cannot create directory %s: %s\n", 
+                 dirpath, strerror(errno));
+         fail = 1;
+      } else if (!S_ISDIR(stats.st_mode)) {
+          Jmsg(jcr, M_ERROR, 0, "%s exists but is not a directory\n", quote(dirpath));
+         fail = 1;
+      } else {
+         /* DIR (aka DIRPATH) already exists and is a directory. */
+      }
+  }
+
+  if (created_dir_p) {
+     *created_dir_p = created_dir;
+  }
+
+  return fail;
+}
+
+/* Ensure that the directory ARGPATH exists.
+   Remove any trailing slashes from ARGPATH before calling this function.
+
+   Create any leading directories that don't already exist, with
+   permissions PARENT_MODE.
+    
+   If the last element of ARGPATH does not exist, create it as
+   a new directory with permissions MODE.
+
+   If OWNER and GROUP are non-negative, use them to set the UID and GID of
+   any created directories.
+
+   If VERBOSE_FMT_STRING is nonzero, use it as a printf format
+   string for printing a message after successfully making a directory,
+   with the name of the directory that was just made as an argument.
+
+   If PRESERVE_EXISTING is non-zero and ARGPATH is an existing directory,
+   then do not attempt to set its permissions and ownership.
+
+   Return 0 if ARGPATH exists as a directory with the proper
+   ownership and permissions when done, otherwise 1.  */
+
+int
+make_path(
+          void *jcr,
+          const char *argpath,
+          int mode,
+          int parent_mode,
+          uid_t owner,
+          gid_t group,
+          int preserve_existing,
+          char *verbose_fmt_string)
+{
+  struct stat stats;
+  int retval = 0;
+
+  if (stat(argpath, &stats)) {
+      char *slash;
+      int tmp_mode;            /* Initial perms for leading dirs.  */
+      int re_protect;          /* Should leading dirs be unwritable? */
+      struct ptr_list {
+       char *dirname_end;
+       struct ptr_list *next;
+      };
+      struct ptr_list *p, *leading_dirs = NULL;
+      struct saved_cwd cwd;
+      char *basename_dir;
+      char *dirpath;
+
+      /* Temporarily relax umask in case it's overly restrictive.  */
+      mode_t oldmask = umask (0);
+
+      /* Make a copy of ARGPATH that we can scribble NULs on.  */
+      dirpath = (char *)alloca(strlen(argpath) + 1);
+      strcpy (dirpath, argpath);
+      strip_trailing_slashes(dirpath);
+
+      /* If leading directories shouldn't be writable or executable,
+        or should have set[ug]id or sticky bits set and we are setting
+        their owners, we need to fix their permissions after making them.  */
+      if (((parent_mode & WX_USR) != WX_USR)
+         || ((owner != (uid_t) -1 || group != (gid_t) -1)
+             && (parent_mode & (S_ISUID | S_ISGID | S_ISVTX)) != 0))
+       {
+         tmp_mode = S_IRWXU;
+         re_protect = 1;
+       }
+      else {
+         tmp_mode = parent_mode;
+         re_protect = 0;
+      }
+
+      /* If we can record the current working directory, we may be able
+        to do the chdir optimization.  */
+      cwd.do_chdir = !save_cwd(&cwd);
+
+      /* If we've saved the cwd and DIRPATH is an absolute pathname,
+         we must chdir to `/' in order to enable the chdir optimization.
+         So if chdir ("/") fails, turn off the optimization.  */
+      if (cwd.do_chdir && *dirpath == '/' && chdir ("/") < 0) {
+        cwd.do_chdir = 0;
+      }
+
+      slash = dirpath;
+
+      /* Skip over leading slashes.  */
+      while (*slash == '/')
+        slash++;
+
+      while (1) {
+         int newly_created_dir;
+         int fail;
+
+         /* slash points to the leftmost unprocessed component of dirpath.  */
+         basename_dir = slash;
+
+          slash = strchr (slash, '/');
+         if (slash == NULL) {
+            break;
+         }
+
+          /* If we're *not* doing chdir before each mkdir, then we have to refer
+            to the target using the full (multi-component) directory name.  */
+         if (!cwd.do_chdir) {
+            basename_dir = dirpath;
+         }
+
+          *slash = '\0';
+         fail = make_dir(jcr, basename_dir, dirpath, tmp_mode, &newly_created_dir);
+         if (fail) {
+             umask(oldmask);
+             cleanup(&cwd);
+             return 1;
+         }
+
+         if (newly_created_dir) {
+              Dmsg0(300, "newly_created_dir\n");
+             if (verbose_fmt_string) {
+                Jmsg(jcr, M_ERROR, 0, verbose_fmt_string, quote(dirpath));
+             }
+
+             if ((owner != (uid_t) -1 || group != (gid_t) -1)
+                 && chown (basename_dir, owner, group)
+#if defined(AFS) && defined (EPERM)
+                 && errno != EPERM
+#endif
+                 ) {
+                 Jmsg(jcr, M_ERROR, 0, "Cannot change owner and/or group of %s: %s\n",
+                     quote (dirpath), strerror(errno));
+                umask(oldmask);
+                cleanup(&cwd);
+                return 1;
+             }
+              Dmsg0(300, "Chown done.\n");
+
+             if (re_protect) {
+                struct ptr_list *pnew = (struct ptr_list *)
+                   alloca (sizeof (struct ptr_list));
+                pnew->dirname_end = slash;
+                pnew->next = leading_dirs;
+                leading_dirs = pnew;
+                 Dmsg0(300, "re_protect\n");
+             }
+         }
+
+         /* If we were able to save the initial working directory,
+            then we can use chdir to change into each directory before
+            creating an entry in that directory.  This avoids making
+            stat and mkdir process O(n^2) file name components.  */
+         if (cwd.do_chdir && chdir(basename_dir) < 0) {
+              Jmsg(jcr, M_ERROR, 0, "Cannot chdir to directory, %s: %s\n",
+                    quote (dirpath), strerror(errno));
+             umask(oldmask);
+             cleanup(&cwd);
+             return 1;
+         }
+
+          *slash++ = '/';
+
+          /* Avoid unnecessary calls to `stat' when given
+            pathnames containing multiple adjacent slashes.  */
+          while (*slash == '/')
+            slash++;
+      } /* end while (1) */
+
+      if (!cwd.do_chdir) {
+        basename_dir = dirpath;
+      }
+
+      /* We're done making leading directories.
+        Create the final component of the path.  */
+
+      Dmsg1(300, "Create final component. mode=%o\n", mode);
+      if (make_dir(jcr, basename_dir, dirpath, mode, NULL)) {
+         umask(oldmask);
+         cleanup(&cwd);
+         return 1;
+      }
+
+      /* Done creating directories.  Restore original umask.  */
+      umask (oldmask);
+
+      if (verbose_fmt_string != NULL) {
+        Jmsg(jcr, M_ERROR, 0, verbose_fmt_string, dirpath);
+      }
+
+      if (owner != (uid_t) -1 || group != (gid_t) -1) {
+         if (chown(basename_dir, owner, group)
+#ifdef AFS
+             && errno != EPERM
+#endif
+             )
+           {
+              Jmsg(jcr, M_ERROR, 0, "Cannot change owner and/or group of %s: %s\n",
+                    quote (dirpath), strerror(errno));
+             retval = 1;
+           }
+      }
+
+      /* The above chown may have turned off some permission bits in MODE.
+        Another reason we may have to use chmod here is that mkdir(2) is
+        required to honor only the file permission bits.  In particular,
+         it need not honor the `special' bits, so if MODE includes any
+        special bits, set them here.  */
+      if (mode & ~S_IRWXUGO) {
+         Dmsg1(300, "Final chmod mode=%o\n", mode);
+      }
+      if ((mode & ~S_IRWXUGO) && chmod(basename_dir, mode)) {
+          Jmsg(jcr, M_ERROR, 0, "Cannot change permissions of %s: %s\n", 
+            quote(dirpath), strerror(errno));
+         retval = 1;
+      }
+
+     if (cleanup(&cwd))
+       return 1;
+
+      /* If the mode for leading directories didn't include owner "wx"
+        privileges, we have to reset their protections to the correct
+        value.  */
+      for (p = leading_dirs; p != NULL; p = p->next) {
+          *(p->dirname_end) = '\0';
+          Dmsg2(300, "Reset parent mode=%o dir=%s\n", parent_mode, dirpath);
+         if (chmod(dirpath, parent_mode)) {
+              Jmsg(jcr, M_ERROR, 0, "Cannot change permissions of %s: %s\n",
+                    quote (dirpath), strerror(errno));
+             retval = 1;
+         }
+      }
+  } else {
+      /* We get here if the entire path already exists.  */
+
+      const char *dirpath = argpath;
+
+      if (!S_ISDIR(stats.st_mode)) {
+          Jmsg(jcr, M_ERROR, 0, "%s exists but is not a directory\n", quote(dirpath));
+         return 1;
+      }
+
+      if (!preserve_existing) {
+          Dmsg0(300, "Do not preserve existing.\n");
+         /* chown must precede chmod because on some systems,
+            chown clears the set[ug]id bits for non-superusers,
+            resulting in incorrect permissions.
+            On System V, users can give away files with chown and then not
+             be able to chmod them.  So don't give files away.  */
+
+         if ((owner != (uid_t) -1 || group != (gid_t) -1)
+             && chown(dirpath, owner, group)
+#ifdef AFS
+             && errno != EPERM
+#endif
+             )
+           {
+              Jmsg(jcr, M_ERROR, 0, "Cannot change owner and/or group of %s: %s\n",
+                    quote(dirpath), strerror(errno));
+             retval = 1;
+           }
+         if (chmod(dirpath, mode)) {
+              Jmsg(jcr, M_ERROR, 0, "Cannot change permissions of %s: %s\n",
+                                quote(dirpath), strerror(errno));
+             retval = 1;
+         }
+          Dmsg2(300, "pathexists chmod mode=%o dir=%s\n", mode, dirpath);
+      }
+  }
+  return retval;
+}
index 2b01f3d10041afe83ed6c9158bedb8eafd25052e..318781ddb924c3f7d633439655a9cbc58af4bc57 100644 (file)
@@ -120,6 +120,9 @@ void add_fname_to_include_list(FF_PKT *ff, int prefixed, char *fname)
             case 'f':
               inc->options |= OPT_multifs;
               break;
+            case 's':
+              inc->options |= OPT_sparse;
+              break;
             case 'V':                  /* verify options */
               /* Copy Verify Options */
                for (j=0; *p && *p != ':'; p++) {
@@ -203,6 +206,7 @@ struct s_included_file *get_next_included_file(FF_PKT *ff, struct s_included_fil
       inc = ainc->next;
    }
    if (inc) {
+      ff->flags = inc->options;
       if (inc->options & OPT_compute_MD5) {
         ff->compute_MD5 = 1;
       } else {
diff --git a/bacula/src/findlib/protos.h b/bacula/src/findlib/protos.h
new file mode 100644 (file)
index 0000000..69b5c2b
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Prototypes for finlib directory of Bacula
+ *
+ *   Version $Id$
+ */
+/*
+   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+/* from attribs.c */
+void      encode_stat            (char *buf, struct stat *statp);
+void      decode_stat            (char *buf, struct stat *statp);
+int       encode_attribsEx       (void *jcr, char *attribsEx, FF_PKT *ff_pkt);
+int set_attributes(void *jcr, char *fname, char *ofile, char *lname,
+                   int type, int stream, struct stat *statp, 
+                   char *attribsEx, int *ofd);
+
+/* from create_file.c */
+int create_file(void *jcr, char *fname, char *ofile, char *lname,
+                int type, int stream, struct stat *statp, 
+                char *attribsEx, int *ofd);
+
+/* From find.c */
+FF_PKT *init_find_files();
+void set_find_options(FF_PKT *ff, int incremental, time_t mtime);
+int find_files(FF_PKT *ff, int sub(FF_PKT *ff_pkt, void *hpkt), void *pkt);
+void term_find_files(FF_PKT *ff);
+
+/* From match.c */
+void init_include_exclude_files(FF_PKT *ff);
+void term_include_exclude_files(FF_PKT *ff);
+void add_fname_to_include_list(FF_PKT *ff, int prefixed, char *fname);
+void add_fname_to_exclude_list(FF_PKT *ff, char *fname);
+int file_is_excluded(FF_PKT *ff, char *file);
+int file_is_included(FF_PKT *ff, char *file);
+struct s_included_file *get_next_included_file(FF_PKT *ff, 
+                           struct s_included_file *inc);
+
+
+/* from makepath.c */
+int make_path(void *jcr, const char *argpath, int mode,
+           int parent_mode, uid_t owner, gid_t group,
+           int preserve_existing, char *verbose_fmt_string);
diff --git a/bacula/src/findlib/save-cwd.c b/bacula/src/findlib/save-cwd.c
new file mode 100644 (file)
index 0000000..89746ee
--- /dev/null
@@ -0,0 +1,115 @@
+/* save-cwd.c -- Save and restore current working directory.
+
+   Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* Written by Jim Meyering <meyering@na-net.ornl.gov>. */
+
+#include "bacula.h"
+#include "save-cwd.h"
+
+
+
+/* Record the location of the current working directory in CWD so that
+   the program may change to other directories and later use restore_cwd
+   to return to the recorded location. This function may allocate
+   space using malloc (via xgetcwd) or leave a file descriptor open;
+   use free_cwd to perform the necessary free or close.  Upon failure,
+   no memory is allocated, any locally opened file descriptors are
+   closed;  return non-zero -- in that case, free_cwd need not be
+   called, but doing so is ok. Otherwise, return zero.  */
+
+int
+save_cwd (struct saved_cwd *cwd)
+{
+  static int have_working_fchdir = 1;
+
+  cwd->desc = -1;
+  cwd->name = NULL;
+
+  if (have_working_fchdir) {
+#if HAVE_FCHDIR
+      cwd->desc = open(".", O_RDONLY);
+      if (cwd->desc < 0) {
+          Emsg1(M_ERROR, 0, "Cannot open current directory: %s\n", strerror(errno));
+         return 1;
+       }
+
+# if __sun__ || sun
+      /* On SunOS 4, fchdir returns EINVAL if accounting is enabled,
+        so we have to fall back to chdir.  */
+      if (fchdir (cwd->desc)) {
+         if (errno == EINVAL) {
+             close(cwd->desc);
+             cwd->desc = -1;
+             have_working_fchdir = 0;
+         } else {
+              Emsg1(M_ERROR, 0, "Current directory: %s\n", strerror(errno));
+             close(cwd->desc);
+             cwd->desc = -1;
+             return 1;
+         }
+      }
+# endif /* __sun__ || sun */
+#else
+# define fchdir(x) (abort (), 0)
+      have_working_fchdir = 0;
+#endif
+    }
+
+  if (!have_working_fchdir) {
+      POOLMEM *buf = get_pool_memory(PM_FNAME);
+      cwd->name = (POOLMEM *)getcwd(buf, sizeof_pool_memory(buf));
+      if (cwd->name == NULL) {
+          Emsg1(M_ERROR, 0, "Cannot get current directory: %s\n", strerror(errno));
+         free_pool_memory(buf);
+         return 1;
+      }
+  }
+  return 0;
+}
+
+/* Change to recorded location, CWD, in directory hierarchy.
+   If "saved working directory", NULL))
+   */
+
+int
+restore_cwd(const struct saved_cwd *cwd, const char *dest, const char *from)
+{
+  int fail = 0;
+  if (cwd->desc >= 0) {
+      if (fchdir(cwd->desc)) {
+          Emsg4(M_ERROR, 0, "Cannot return to %s%s%s: %s\n", 
+                 (dest ? dest : "saved working directory"),
+                 (from ? " from " : ""),
+                 (from ? from : ""), strerror(errno));
+         fail = 1;
+      }
+  } else if (chdir(cwd->name) < 0) {
+      Emsg2(M_ERROR, 0, "%s: %s\n", cwd->name, strerror(errno));
+      fail = 1;
+  }
+  return fail;
+}
+
+void
+free_cwd(struct saved_cwd *cwd)
+{
+  if (cwd->desc >= 0)
+     close(cwd->desc);
+  if (cwd->name)
+     free_pool_memory(cwd->name);
+}
diff --git a/bacula/src/findlib/save-cwd.h b/bacula/src/findlib/save-cwd.h
new file mode 100644 (file)
index 0000000..0af93ec
--- /dev/null
@@ -0,0 +1,18 @@
+
+
+#ifndef SAVE_CWD_H
+# define SAVE_CWD_H 1
+
+struct saved_cwd
+  {
+    int do_chdir;
+    int desc;
+    char *name;
+  };
+
+int save_cwd(struct saved_cwd *cwd);
+int restore_cwd(const struct saved_cwd *cwd, const char *dest,
+                         const char *from);
+void free_cwd(struct saved_cwd *cwd);
+
+#endif
index 9533105b8a977187af661555a1726bef9f19f917..dbf685cd4bcc5d507c904fe24f053fe6cf0c966f 100644 (file)
@@ -176,6 +176,7 @@ struct s_jcr {
    VOLUME_CAT_INFO VolCatInfo;        /* Catalog info for desired volume */
    POOLMEM *job_name;                 /* base Job name (not unique) */
    POOLMEM *fileset_name;             /* FileSet */
+   POOLMEM *fileset_md5;              /* MD5 for FileSet */
    POOLMEM *pool_name;                /* pool to use */
    POOLMEM *pool_type;                /* pool type to use */
    POOLMEM *media_type;               /* media type */
index 7c288c4e9db7a7fe7af70ed62af853e5312e3669..1cf4e0736381555bc68e8f8b3136bf7bc3057d8f 100644 (file)
@@ -33,22 +33,20 @@ dummy:
 
 LIBSRCS = alloc.c base64.c bmisc.c bnet.c bnet_server.c \
          bshm.c btime.c \
-         cram-md5.c crc32.c create_file.c daemon.c fnmatch.c \
+         cram-md5.c crc32.c daemon.c fnmatch.c \
          hmac.c idcache.c jcr.c lex.c  \
-         makepath.c \
          md5.c message.c mem_pool.c parse_conf.c \
-         queue.c rwlock.c save-cwd.c serial.c \
+         queue.c rwlock.c serial.c \
          signal.c smartall.c tree.c util.c watchdog.c workq.c  
 
 #        immortal.c filesys.c
 
 LIBOBJS = alloc.o base64.o bmisc.o bnet.o bnet_server.o \
          bshm.o btime.o \
-         cram-md5.o crc32.o create_file.o daemon.o fnmatch.o \
+         cram-md5.o crc32.o daemon.o fnmatch.o \
          hmac.o idcache.o jcr.o lex.o  \
-         makepath.o \
          md5.o message.o mem_pool.o parse_conf.o \
-         queue.o rwlock.o save-cwd.o serial.o \
+         queue.o rwlock.o serial.o \
          signal.o smartall.o tree.o util.o watchdog.o workq.o
 
 #        immortal.o filesys.o
index b4459f5cbf306ed61eba17d139b4a4750f9bce1a..ae8e2bfd65b620f18379e337dcc4990bf9a303be 100644 (file)
@@ -127,95 +127,6 @@ from_base64(intmax_t *value, char *where)
    return i;
 }
 
-/* Encode a stat structure into a base64 character string */
-void
-encode_stat(char *buf, struct stat *statp)
-{
-   char *p = buf;
-   /*
-    * NOTE: we should use rdev as major and minor device if
-    * it is a block or char device (S_ISCHR(statp->st_mode)
-    * or S_ISBLK(statp->st_mode)).  In all other cases,
-    * it is not used.  
-    *
-    */
-   p += to_base64((intmax_t)statp->st_dev, p);
-   *p++ = ' ';                        /* separate fields with a space */
-   p += to_base64((intmax_t)statp->st_ino, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_mode, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_nlink, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_uid, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_gid, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_rdev, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_size, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_blksize, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_blocks, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_atime, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_mtime, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_ctime, p);
-   *p++ = 0;
-   return;
-}
-
-
-/* Decode a stat packet from base64 characters */
-void
-decode_stat(char *buf, struct stat *statp)
-{
-   char *p = buf;
-   intmax_t val;
-
-   p += from_base64(&val, p);
-   statp->st_dev = val;
-   p++;                              /* skip space */
-   p += from_base64(&val, p);
-   statp->st_ino = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_mode = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_nlink = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_uid = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_gid = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_rdev = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_size = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_blksize = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_blocks = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_atime = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_mtime = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_ctime = val;
-   p++;
-}
 
 /*
  * Encode binary data in bin of len bytes into
@@ -285,7 +196,7 @@ int main(int argc, char *argv[])
 #ifdef TEST_MODE
 static int errfunc(const char *epath, int eernoo)
 {
-  Dmsg0(-1, "in errfunc\n");
+  printf("in errfunc\n");
   return 1;
 }
 
@@ -321,13 +232,16 @@ int main(int argc, char *argv[])
         continue;
       }
       encode_stat(where, &statp);
+
+      printf("Encoded stat=%s\n", where);
+     
+#ifdef xxx
       p = where;
       p += to_base64((intmax_t)(statp.st_atime), p);
       *p++ = ' ';
       p += to_base64((intmax_t)t, p);
       printf("%s %s\n", fname, where);
 
-#ifdef xxxx
       printf("%s %lld\n", "st_dev", (intmax_t)statp.st_dev);
       printf("%s %lld\n", "st_ino", (intmax_t)statp.st_ino);
       printf("%s %lld\n", "st_mode", (intmax_t)statp.st_mode);
@@ -343,13 +257,11 @@ int main(int argc, char *argv[])
       printf("%s %lld\n", "st_ctime", (intmax_t)statp.st_ctime);
 #endif
 
-
       if (debug_level)
          printf("%s: len=%d val=%s\n", fname, strlen(where), where);
       
       decode_stat(where, &statn);
 
-#ifdef xxx
       if (statp.st_dev != statn.st_dev || 
          statp.st_ino != statn.st_ino ||
          statp.st_mode != statn.st_mode ||
@@ -369,13 +281,15 @@ int main(int argc, char *argv[])
          printf("%s: %s\n", fname, where);
          printf("NOT EQAL\n");
       }
-#endif
 
    }
    globfree(&my_glob);
 
    printf("%d files examined\n", i);
 
+   to_base64(UINT32_MAX, where);
+   printf("UINT32_MAX=%s\n", where);
+
    return 0;
 }   
 #endif
index 80b1a53cda0536d3585aceff7ebf6929254cb0f6..403c5f83e59ba23b7232dd23d28ae1ca5fb2e4f5 100644 (file)
 /*
    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
 
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
    MA 02111-1307, USA.
 
  */
@@ -116,6 +116,7 @@ bnet_recv(BSOCK *bsock)
    int32_t nbytes;
    int32_t pktsiz;
 
+   bsock->msg[0] = 0;
    if (bsock->errors || bsock->terminated) {
       return -2;
    }
index 54d1ed3d5c80e6ac8a54e2d0ec97aff021521001..d73782a3c369cf8376ec173d6bc017d93b0ac351 100644 (file)
 /*
    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
 
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
    MA 02111-1307, USA.
 
  */
index 3ad074a8b1dfd915b25620544fe1a0af18eb334c..a0325e6cc4c373bb712ee291b340c27cbad7c1e8 100644 (file)
@@ -55,9 +55,25 @@ void get_current_time(struct date_time *dt)
 #endif
 }
 
+/*
+ * Bacula's time (btime_t) is an unsigned 64 bit integer that contains
+ *   the number of microseconds since Epoch Time (1 Jan 1970).
+ */
+
 btime_t get_current_btime()
 {
-   return (btime_t)time(NULL);
+   struct timeval tv;
+   if (gettimeofday(&tv, NULL) != 0) {
+      tv.tv_sec = (long)time(NULL);   /* fall back to old method */
+      tv.tv_usec = 0;
+   }
+   return ((btime_t)tv.tv_sec) * 1000000 + (btime_t)tv.tv_usec;
+}
+
+/* Convert btime to Unix time */
+time_t btime_to_etime(btime_t bt)
+{
+   return (time_t)(bt/1000000);                   
 }
 
 
index ced7cae2cc6bcdbae4376074277852f9d82d8446..6012b12303fdc14daa4a670e4c1b590e6a98c694 100644 (file)
 #ifndef __btime_INCLUDED
 #define __btime_INCLUDED
 
-typedef float64_t fdate_t;             /* Date type */
-typedef float64_t ftime_t;             /* Time type */
+/* New btime definition -- use this */
+extern btime_t get_current_btime(void);
+extern time_t btime_to_etime(btime_t bt);
+
+extern void bstrftime(char *dt, int maxlen, uint32_t tim);
+
+
+/* =========================================================== */
+/*       old code deprecated below. Do not use.               */
+
+typedef float64_t fdate_t;            /* Date type */
+typedef float64_t ftime_t;            /* Time type */
 
 struct date_time {
-    fdate_t julian_day_number;         /* Julian day number */
+    fdate_t julian_day_number;        /* Julian day number */
     ftime_t julian_day_fraction;       /* Julian day fraction */
 };
 
 /*  In arguments and results of the following functions,
     quantities are expressed as follows.
 
-        year    Year in the Common Era.  The canonical
-                date of adoption of the Gregorian calendar
-                (October 5, 1582 in the Julian calendar)
-                is assumed.
+       year    Year in the Common Era.  The canonical
+               date of adoption of the Gregorian calendar
+               (October 5, 1582 in the Julian calendar)
+               is assumed.
 
-        month   Month index with January 0, December 11.
+       month   Month index with January 0, December 11.
 
-        day     Day number of month, 1 to 31.
+       day     Day number of month, 1 to 31.
 
 */
 
-extern void bstrftime(char *dt, int maxlen, uint32_t tim);
 
 extern fdate_t date_encode(uint32_t year, uint8_t month, uint8_t day);
 extern ftime_t time_encode(uint8_t hour, uint8_t minute, uint8_t second,
-                          float32_t second_fraction);
+                         float32_t second_fraction);
 extern void date_time_encode(struct date_time *dt,
-                             uint32_t year, uint8_t month, uint8_t day,
-                             uint8_t hour, uint8_t minute, uint8_t second,
-                             float32_t second_fraction);
+                            uint32_t year, uint8_t month, uint8_t day,
+                            uint8_t hour, uint8_t minute, uint8_t second,
+                            float32_t second_fraction);
 
 extern void date_decode(fdate_t date, uint32_t *year, uint8_t *month,
-                        uint8_t *day);
+                       uint8_t *day);
 extern void time_decode(ftime_t time, uint8_t *hour, uint8_t *minute,
-                        uint8_t *second, float32_t *second_fraction);
+                       uint8_t *second, float32_t *second_fraction);
 extern void date_time_decode(struct date_time *dt,
-                             uint32_t *year, uint8_t *month, uint8_t *day,
-                             uint8_t *hour, uint8_t *minute, uint8_t *second,
-                             float32_t *second_fraction);
+                            uint32_t *year, uint8_t *month, uint8_t *day,
+                            uint8_t *hour, uint8_t *minute, uint8_t *second,
+                            float32_t *second_fraction);
 
 extern int date_time_compare(struct date_time *dt1, struct date_time *dt2);
 
@@ -83,6 +92,5 @@ extern void tm_encode(struct date_time *dt, struct tm *tm);
 extern void tm_decode(struct date_time *dt, struct tm *tm);
 extern void get_current_time(struct date_time *dt);
 
-extern btime_t get_current_btime(void);
 
 #endif /* __btime_INCLUDED */
index f40b35dffff0d5c8fac9e98658abeb50d25f0c3b..90310dbacdc3f5100ef1a92891828d6d857f6a42 100644 (file)
 /*
    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
 
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
    MA 02111-1307, USA.
 
  */
index 4f69f3cada1eef0f0dbaf8fcaa8994ab926f72e4..412499dc3d9b4eed18aee060dbcad0fb15022649 100644 (file)
@@ -9,19 +9,19 @@
 /*
    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
 
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
    MA 02111-1307, USA.
 
  */
index 40432aa51e006e7dc8081f3e8d8f9691e783c0e9..8c79f98c2bcc6069a1353516eeadf14996b76274 100644 (file)
 /*
    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
 
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
    MA 02111-1307, USA.
 
  */
index d1c94f26eee3500f961d7adb57b61dd09529cf17..6e9118d054cbb383a36a4aa1af4d69280f54ad52 100644 (file)
@@ -291,9 +291,9 @@ lex_get_token(LEX *lf, int expect)
       switch (lf->state) {
         case lex_none:
             Dmsg2(290, "Lex state lex_none ch=%d,%x\n", ch, ch);
-           if (ISSPACE(ch))  
+           if (B_ISSPACE(ch))  
               break;
-           if (ISALPHA(ch)) {
+           if (B_ISALPHA(ch)) {
               if (lf->options & LOPT_NO_IDENT)
                  lf->state = lex_string;
               else
@@ -301,7 +301,7 @@ lex_get_token(LEX *lf, int expect)
               begin_str(lf, ch);
               break;
            }
-           if (ISDIGIT(ch)) {
+           if (B_ISDIGIT(ch)) {
               lf->state = lex_number;
               begin_str(lf, ch);
               break;
@@ -362,13 +362,13 @@ lex_get_token(LEX *lf, int expect)
         case lex_number:
             Dmsg2(290, "Lex state lex_number ch=%x %c\n", ch, ch);
            /* Might want to allow trailing specifications here */
-           if (ISDIGIT(ch)) {
+           if (B_ISDIGIT(ch)) {
               add_str(lf, ch);
               break;
            }
 
            /* A valid number can be terminated by the following */
-            if (ISSPACE(ch) || ch == L_EOL || ch == ',' || ch == ';') {
+            if (B_ISSPACE(ch) || ch == L_EOL || ch == ',' || ch == ';') {
               token = T_NUMBER;
               lf->state = lex_none;
            } else {
@@ -382,7 +382,7 @@ lex_get_token(LEX *lf, int expect)
         case lex_string:
             Dmsg1(290, "Lex state lex_string ch=%x\n", ch);
             if (ch == '\n' || ch == L_EOL || ch == '=' || ch == '}' || ch == '{' ||
-                ch == ';' || ch == ',' || ch == '#' || (ISSPACE(ch)) ) {
+                ch == ';' || ch == ',' || ch == '#' || (B_ISSPACE(ch)) ) {
               lex_unget_char(lf);    
               token = T_UNQUOTED_STRING;
               lf->state = lex_none;
@@ -392,10 +392,10 @@ lex_get_token(LEX *lf, int expect)
            break;
         case lex_identifier:
             Dmsg2(290, "Lex state lex_identifier ch=%x %c\n", ch, ch);
-           if (ISALPHA(ch)) {
+           if (B_ISALPHA(ch)) {
               add_str(lf, ch);
               break;
-           } else if (ISSPACE(ch)) {
+           } else if (B_ISSPACE(ch)) {
               break;
             } else if (ch == '\n' || ch == L_EOL || ch == '=' || ch == '}' || ch == '{' ||
                        ch == ';' || ch == ','   || ch == '"' || ch == '#') {
@@ -436,7 +436,7 @@ lex_get_token(LEX *lf, int expect)
            add_str(lf, ch);
            break;
         case lex_include:            /* scanning a filename */
-            if (ISSPACE(ch) || ch == '\n' || ch == L_EOL || ch == '}' || ch == '{' ||
+            if (B_ISSPACE(ch) || ch == '\n' || ch == L_EOL || ch == '}' || ch == '{' ||
                 ch == ';' || ch == ','   || ch == '"' || ch == '#') {
               lf->state = lex_none;
               lf = lex_open_file(lf, lf->str, NULL);
index 53faa028b64db40238350ff39349d9fb0cf206ea..a927064be58dc25853c3a9a5ddcb72a5e66b970f 100644 (file)
@@ -8,19 +8,19 @@
 /*
    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
 
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
    MA 02111-1307, USA.
 
  */
index a0453f647af3289a2cc4cd7eb68a9da8c661d2ea..1a78def5a7d10707f19788013928d11bac1fc259 100755 (executable)
@@ -488,8 +488,8 @@ void store_size(LEX *lc, struct res_items *item, int index, int pass)
       /* Look for modifier */
       ch = lc->str[lc->str_len - 1];
       i = 0;
-      if (ISALPHA(ch)) {
-        if (ISUPPER(ch)) {
+      if (B_ISALPHA(ch)) {
+        if (B_ISUPPER(ch)) {
            ch = tolower(ch);
         }
         while (mod[++i] != 0) {
index 390b207829aeccb352db48ccf39f47128c5c37f7..4ec45a0cfef7c84538668ae434ecf81d3346eb29 100644 (file)
@@ -27,8 +27,6 @@
 void      base64_init            (void);
 int       to_base64              (intmax_t value, char *where);
 int       from_base64            (intmax_t *value, char *where);
-void      encode_stat            (char *buf, struct stat *statp);
-void      decode_stat            (char *buf, struct stat *statp);
 int       bin_to_base64          (char *buf, char *bin, int len);
 
 /* bmisc.c */
@@ -44,9 +42,6 @@ int       bvsnprintf             (char *str, size_t size, const char  *format, v
 int       pool_sprintf           (char *pool_buf, char *fmt, ...);
 void      create_pid_file        (char *dir, char *progname, int port);
 int       delete_pid_file        (char *dir, char *progname, int port);
-#ifndef HAVE_STRERROR_R
-int       strerror_r             (int errnum, char *buf, size_t bufsiz);
-#endif
 
 
 /* bnet.c */
@@ -75,13 +70,6 @@ int cram_md5_auth(BSOCK *bs, char *password);
 void hmac_md5(uint8_t* text, int text_len, uint8_t*  key,
               int key_len, uint8_t *hmac);
 
-/* create_file.c */
-int create_file(void *jcr, char *fname, char *ofile, char *lname,
-                       int type, struct stat *statp, int *ofd);
-int set_statp(void *jcr, char *fname, char *ofile, char *lname, int type, 
-                       struct stat *statp);
-
-
 /* crc32.c */
 uint32_t bcrc32(uint8_t *buf, int len);
 
@@ -96,18 +84,6 @@ void      lex_unget_char         (LEX *lf);
 char *    lex_tok_to_str         (int token);
 int       lex_get_token          (LEX *lf, int expect);
 
-/* makepath.c */
-int make_path(
-           void *jcr,
-           const char *argpath,
-           int mode,
-           int parent_mode,
-           uid_t owner,
-           gid_t group,
-           int preserve_existing,
-           char *verbose_fmt_string);
-
-
 /* message.c */
 void       my_name_is            (int argc, char *argv[], char *name);
 void       init_msg              (void *jcr, MSGS *msg);
@@ -151,6 +127,7 @@ char *           add_commas              (char *val, char *buf);
 char *           edit_uint64             (uint64_t val, char *buf);
 int              do_shell_expansion      (char *name);
 int              is_a_number             (const char *num);
+int              is_buf_zero             (char *buf, int len);
 int              string_to_btime         (char *str, btime_t *value);
 char             *edit_btime             (btime_t val, char *buf);
 void             jobstatus_to_ascii      (int JobStatus, char *msg, int maxlen);
index 959529e155acc5b50e2285280bbdaea8a362734b..407cf21111b15d737f0caa31ed81fb02579eb541 100755 (executable)
@@ -27,7 +27,6 @@
 
 #include "bacula.h"
 #include "findlib/find.h"
-#include "findlib/system.h"
             
 #ifndef MAXPATHLEN
 #define MAXPATHLEN 1000
index 4c9e03e6b3195d96c12b0df9d275d302a9291fd4..d702a45f2fa681f4e30a4ae32e57147fde4127bd 100644 (file)
  *
  */
 
+/* Return true of buffer has all zero bytes */
+int is_buf_zero(char *buf, int len)
+{
+   uint64_t *ip = (uint64_t *)buf;
+   char *p;
+   int i, len64, done, rem;
+
+   /* Optimize by checking uint64_t for zero */
+   len64 = len >> sizeof(uint64_t);
+   for (i=0; i < len64; i++) {
+      if (ip[i] != 0) {
+        return 0;
+      }
+   }
+   done = len64 << sizeof(uint64_t);  /* bytes already checked */
+   p = buf + done;
+   rem = len - done;
+   for (i = 0; i < rem; i++) {
+      if (p[i] != 0) {
+        return 0;
+      }
+   }
+   return 1;
+}
+
 /*
  * Convert a string duration to btime_t (64 bit seconds)
  * Returns 0: if error
@@ -52,8 +77,8 @@ int string_to_btime(char *str, btime_t *value)
    len = strlen(str);
    ch = str[len - 1];
    i = 0;
-   if (ISALPHA(ch)) {
-      if (ISUPPER(ch)) {
+   if (B_ISALPHA(ch)) {
+      if (B_ISUPPER(ch)) {
         ch = tolower(ch);
       }
       while (mod[++i] != 0) {
@@ -116,18 +141,18 @@ int is_a_number(const char *n)
    if( *n == '-' || *n == '+' ) {
       n++;
    }
-   while (ISDIGIT(*n)) {
+   while (B_ISDIGIT(*n)) {
       digit_seen = 1;
       n++;
    }
    if (digit_seen && *n == '.') {
       n++;
-      while (ISDIGIT(*n)) { n++; }
+      while (B_ISDIGIT(*n)) { n++; }
    }
    if (digit_seen && (*n == 'e' || *n == 'E')
-       && (ISDIGIT(n[1]) || ((n[1]=='-' || n[1] == '+') && ISDIGIT(n[2])))) {
+       && (B_ISDIGIT(n[1]) || ((n[1]=='-' || n[1] == '+') && B_ISDIGIT(n[2])))) {
       n += 2;                        /* skip e- or e+ or e digit */
-      while (ISDIGIT(*n)) { n++; }
+      while (B_ISDIGIT(*n)) { n++; }
    }
    return digit_seen && *n==0;
 }
@@ -191,7 +216,7 @@ char *add_commas(char *val, char *buf)
 void lcase(char *str)
 {
    while (*str) {
-      if (ISUPPER(*str))
+      if (B_ISUPPER(*str))
         *str = tolower((int)(*str));
        str++;
    }
@@ -296,10 +321,10 @@ fstrsch(char *a, char *b)   /* folded case search */
         return 0;                    /* failed */
    }
    while (*a) {                      /* do it over the correct slow way */
-      if (ISUPPER(c1 = *a)) {
+      if (B_ISUPPER(c1 = *a)) {
         c1 = tolower((int)c1);
       }
-      if (ISUPPER(c2 = *b)) {
+      if (B_ISUPPER(c2 = *b)) {
         c2 = tolower((int)c2);
       }
       if (c1 != c2) {
index 0b7a996eb3af4c5ddff0d111bc875b796cb80177..5216ca33c72532da82e55fa4afdcab16f22adac4 100644 (file)
@@ -38,19 +38,19 @@ TAPEOBJS = btape.o block.o butil.o dev.o device.o label.o \
           stored_conf.o match_bsr.o parse_bsr.o
 
 # bls
-BLSOBJS = bls.o block.o device.o dev.o label.o match_bsr.o \
-         acquire.o mount.o parse_bsr.o record.o butil.o \
-         read_record.o 
+BLSOBJS = bls.o block.o butil.o device.o dev.o label.o match_bsr.o \
+         acquire.o mount.o parse_bsr.o record.o  \
+         read_record.o stored_conf.o
 
 # bextract
 BEXTOBJS = bextract.o block.o device.o dev.o label.o record.o \
           acquire.o mount.o match_bsr.o parse_bsr.o butil.o \
-          read_record.o
+          read_record.o stored_conf.o
 
 # bscan
 SCNOBJS = bscan.o block.o device.o dev.o label.o \
          acquire.o mount.o record.o match_bsr.o parse_bsr.o \
-         butil.o read_record.o
+         butil.o read_record.o stored_conf.o
 
 
 # bpool is deprecated
@@ -91,13 +91,13 @@ btape:      $(TAPEOBJS) ../lib/libbac.a ../cats/libsql.a
        $(CXX) $(TTOOL_LDFLSGS) $(LDFLAGS) -L../lib -L../cats  -o $@ $(TAPEOBJS) -lsql $(LIBS) $(DLIB) -lbac -lm
 
 bls:   ../findlib/libfind.a $(BLSOBJS) ../lib/libbac.a
-       $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../findlib -o $@ $(BLSOBJS) $(LIBS) $(DLIB) -lbac -lfind -lm
+       $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../findlib -o $@ $(BLSOBJS) $(LIBS) $(DLIB) -lfind -lbac -lm
 
 bextract: ../findlib/libfind.a $(BEXTOBJS) ../lib/libbac.a
-       $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../findlib -o $@ $(BEXTOBJS) $(LIBS) $(DLIB) $(FDLIBS) -lbac -lfind -lm
+       $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../findlib -o $@ $(BEXTOBJS) $(LIBS) $(DLIB) $(FDLIBS) -lfind -lbac -lm
 
 bscan: ../findlib/libfind.a $(SCNOBJS) ../cats/libsql.a
-       $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../cats -L../findlib -o $@ $(SCNOBJS) -lsql $(LIBS) $(DB_LIBS) $(FDLIBS) -lbac -lfind -lm
+       $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../cats -L../findlib -o $@ $(SCNOBJS) -lsql $(LIBS) $(DB_LIBS) $(FDLIBS) -lfind -lbac -lm
 
 
 
index 2ba9addb4586790ce658a2e600c191257b77e9dd..95938dae0d0fdcc16efc2e9fa6b16c5ba0b6ac79 100644 (file)
@@ -93,7 +93,7 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
 default_path:
            tape_previously_mounted = 0;
             Dmsg0(200, "dir_get_volume_info\n");
-           dir_get_volume_info(jcr, 0);
+           dir_get_volume_info(jcr, 0);         /* Get info for reading */
             Dmsg2(200, "calling autoload Vol=%s Slot=%d\n",
               jcr->VolumeName, jcr->VolCatInfo.Slot);                         
            if (autoload_device(jcr, dev, 0, NULL)) {
@@ -144,16 +144,15 @@ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
        * Device already in append mode  
        *
        * Check if we have the right Volume mounted   
-       *  OK if AnonVols and volume info OK
-       *  OK if next volume matches current volume
-       *  otherwise mount desired volume obtained from
+       *   OK if current volume info OK
+       *   OK if next volume matches current volume
+       *   otherwise mount desired volume obtained from
        *    dir_find_next_appendable_volume
        */
       strcpy(jcr->VolumeName, dev->VolHdr.VolName);
-      if (((dev->capabilities & CAP_ANONVOLS) &&
-           !dir_get_volume_info(jcr, 1)) ||
-         (!dir_find_next_appendable_volume(jcr) || 
-           strcmp(dev->VolHdr.VolName, jcr->VolumeName) != 0)) { /* wrong tape mounted */
+      if (!dir_get_volume_info(jcr, 1) ||
+         !(dir_find_next_appendable_volume(jcr) &&
+           strcmp(dev->VolHdr.VolName, jcr->VolumeName) == 0)) { /* wrong tape mounted */
         if (dev->num_writers != 0) {
             Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing with another Volume.\n"), dev_name(dev));
            goto get_out;
index 70e97574d9f064f40c6843a091c4769f6589be1c..1a47a3ba4ec96c0728700246fe7cea8b7468d7cc 100644 (file)
@@ -98,7 +98,21 @@ int do_append_data(JCR *jcr)
    memset(&rec, 0, sizeof(rec));
 
    /* 
-    * Get Data from File daemon, write to device   
+    * Get Data from File daemon, write to device.  To clarify what is
+    *  going on here.  We expect:        
+    *    - A stream header
+    *    - Multiple records of data
+    *    - EOD record
+    *
+    *   The Stream header is just used to sychronize things, and
+    *   none of the stream header is written to tape.
+    *   The Multiple records of data, contain first the Attributes,
+    *   then after another stream header, the file data, then
+    *   after another stream header, the MD5 data if any.  
+    *
+    *  So we get the (stream header, data, EOD) three time for each
+    *  file. 1. for the Attributes, 2. for the file data if any, 
+    *  and 3. for the MD5 if any.
     */
    jcr->VolFirstFile = 0;
    time(&jcr->run_time);             /* start counting time for rates */
@@ -110,6 +124,7 @@ int do_append_data(JCR *jcr)
        *    file_index (sequential Bacula file index)
        *    stream     (arbitrary Bacula number to distinguish parts of data)
        *    info       (Info for Storage daemon -- compressed, encryped, ...)
+       *       info is not currently used, so is read, but ignored!
        */
       if ((n=bget_msg(ds)) < 0) { 
          Jmsg1(jcr, M_FATAL, 0, _("Error reading data header from FD. ERR=%s\n"),
@@ -158,7 +173,7 @@ int do_append_data(JCR *jcr)
         rec.data = ds->msg;            /* use message buffer */
 
          Dmsg4(250, "before writ_rec FI=%d SessId=%d Strm=%s len=%d\n",
-           rec.FileIndex, rec.VolSessionId, stream_to_ascii(rec.Stream), 
+           rec.FileIndex, rec.VolSessionId, stream_to_ascii(rec.Stream,rec.FileIndex), 
            rec.data_len);
          
         while (!write_record_to_block(block, &rec)) {
@@ -179,15 +194,18 @@ int do_append_data(JCR *jcr)
            break;
         }
         jcr->JobBytes += rec.data_len;   /* increment bytes this job */
-         Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
+         Dmsg4(200, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
            FI_to_ascii(rec.FileIndex), rec.VolSessionId, 
-           stream_to_ascii(rec.Stream), rec.data_len);
+           stream_to_ascii(rec.Stream, rec.FileIndex), rec.data_len);
+
         /* Send attributes and MD5 to Director for Catalog */
-        if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_MD5_SIGNATURE) {
+        if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_MD5_SIGNATURE ||
+            stream == STREAM_WIN32_ATTRIBUTES) { 
            if (!jcr->no_attributes) {
               if (jcr->spool_attributes && jcr->dir_bsock->spool_fd) {
                  jcr->dir_bsock->spool = 1;
               }
+               Dmsg0(200, "Send attributes.\n");
               if (!dir_update_file_attributes(jcr, &rec)) {
                   Jmsg(jcr, M_FATAL, 0, _("Error updating file attributes. ERR=%s\n"),
                     bnet_strerror(jcr->dir_bsock));
index 73120bf44b4937afd4c98e6e7ca2bb738b13df4c..00e66120845f5e1323bb28b5bb97dc6c23bfaefc 100644 (file)
@@ -254,7 +254,6 @@ int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev)
    int wait_sec;
    int num_wait = 0;
    int dev_blocked;
-   char *msg;
 
    Dmsg0(130, "enter dir_ask_sysop_to_mount_next_volume\n");
    ASSERT(dev->dev_blocked);
@@ -278,15 +277,10 @@ int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev)
             Dmsg0(190, "Return 1 from mount without wait.\n");
            return 1;
         }
-        if (dev->capabilities & CAP_ANONVOLS) {
-            msg = "Suggest mounting";
-        } else {
-            msg = "Please mount";
-        }
         Jmsg(jcr, M_MOUNT, 0, _(
-"%s Volume \"%s\" on Storage Device \"%s\" for Job %s\n"
+"Please mount Volume \"%s\" on Storage Device \"%s\" for Job %s\n"
 "Use \"mount\" command to release Job.\n"),
-             msg, jcr->VolumeName, jcr->dev_name, jcr->Job);
+             jcr->VolumeName, jcr->dev_name, jcr->Job);
          Dmsg3(190, "Mount %s on %s for Job %s\n",
                jcr->VolumeName, jcr->dev_name, jcr->Job);
       } else {
index 90926e0889ffd43457d1fc7cb2ac784a1b6ef65c..df7bb393dcdc7d66dbdf59f232e9b864ccee3390 100644 (file)
@@ -46,10 +46,14 @@ static int authenticate(int rcode, BSOCK *bs)
       Emsg1(M_FATAL, 0, _("I only authenticate Directors, not %d\n"), rcode);
       return 0;
    }
+   if (bs->msglen > 200) {
+      bs->msglen = 200;
+   }
    dirname = get_pool_memory(PM_MESSAGE);
    dirname = check_pool_memory_size(dirname, bs->msglen);
 
    if (sscanf(bs->msg, "Hello Director %127s calling\n", dirname) != 1) {
+      bs->msg[100] = 0;
       Emsg1(M_FATAL, 0, _("Bad Hello command from Director: %s\n"), bs->msg);
       return 0;
    }
index 5bab15516b745ecfe522df25355367125b5bac41..70f474d1ec0abc5340dfc5e5cbaff28ef338ae90 100644 (file)
@@ -53,6 +53,7 @@ static long total = 0;
 static POOLMEM *fname;                   /* original file name */
 static POOLMEM *ofile;                   /* output name with prefix */
 static POOLMEM *lname;                   /* link name */
+static POOLMEM *attribsEx;               /* extended attributes (Win32) */
 static char *where;
 static int wherelen;                     /* prefix length */
 static uint32_t num_files = 0;
@@ -60,6 +61,16 @@ static struct stat statp;
 static uint32_t compress_buf_size = 70000;
 static POOLMEM *compress_buf;
 static int type;
+static int stream;
+static int prog_name_msg = 0;
+
+static char *wbuf;                   /* write buffer address */
+static uint32_t wsize;               /* write size */
+static uint64_t fileAddr = 0;        /* file write address */
+
+#define CONFIG_FILE "bacula-sd.conf"
+char *configfile;
+
 
 static void usage()
 {
@@ -67,6 +78,7 @@ static void usage()
 "\nVersion: " VERSION " (" DATE ")\n\n"
 "Usage: bextract [-d debug_level] <bacula-archive> <directory-to-store-files>\n"
 "       -b <file>       specify a bootstrap file\n"
+"       -c <file>       specify a configuration file\n"
 "       -dnn            set debug level to nn\n"
 "       -e <file>       exclude list\n"
 "       -i <file>       include list\n"
@@ -89,13 +101,20 @@ int main (int argc, char *argv[])
    memset(ff, 0, sizeof(FF_PKT));
    init_include_exclude_files(ff);
 
-   while ((ch = getopt(argc, argv, "b:d:e:i:?")) != -1) {
+   while ((ch = getopt(argc, argv, "b:c:d:e:i:?")) != -1) {
       switch (ch) {
          case 'b':                    /* bootstrap file */
            bsr = parse_bsr(NULL, optarg);
 //         dump_bsr(bsr);
            break;
 
+         case 'c':                    /* specify config file */
+           if (configfile != NULL) {
+              free(configfile);
+           }
+           configfile = bstrdup(optarg);
+           break;
+
          case 'd':                    /* debug level */
            debug_level = atoi(optarg);
            if (debug_level <= 0)
@@ -144,6 +163,13 @@ int main (int argc, char *argv[])
       Pmsg0(0, "Wrong number of arguments: \n");
       usage();
    }
+
+   if (configfile == NULL) {
+      configfile = bstrdup(CONFIG_FILE);
+   }
+
+   parse_config(configfile);
+
    if (!got_inc) {                           /* If no include file, */
       add_fname_to_include_list(ff, 0, "/");  /*   include everything */
    }
@@ -161,7 +187,7 @@ static void do_extract(char *devname)
 {
 
    jcr = setup_jcr("bextract", devname, bsr);
-   dev = setup_to_read_device(jcr);
+   dev = setup_to_access_device(jcr, 1);    /* acquire for read */
    if (!dev) {
       exit(1);
    }
@@ -179,9 +205,7 @@ static void do_extract(char *devname)
    fname = get_pool_memory(PM_FNAME);
    ofile = get_pool_memory(PM_FNAME);
    lname = get_pool_memory(PM_FNAME);
-
-
-
+   attribsEx = get_pool_memory(PM_FNAME);
 
    compress_buf = get_memory(compress_buf_size);
 
@@ -190,8 +214,8 @@ static void do_extract(char *devname)
     * archive since we just hit an end of file, so close the file. 
     */
    if (ofd >= 0) {
-      close(ofd);
-      set_statp(jcr, fname, ofile, lname, type, &statp);
+      set_attributes(jcr, fname, ofile, lname, type, stream, &statp,
+                    attribsEx, &ofd);
    }
    release_device(jcr, dev);
 
@@ -210,25 +234,27 @@ static void do_extract(char *devname)
  */
 static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
 {
+
    if (rec->FileIndex < 0) {
       return;                         /* we don't want labels */
    }
 
    /* File Attributes stream */
-   if (rec->Stream == STREAM_UNIX_ATTRIBUTES) {
-      char *ap, *lp, *fp;
+   if (rec->Stream == STREAM_UNIX_ATTRIBUTES || rec->Stream == STREAM_WIN32_ATTRIBUTES) {
+      char *ap, *lp, *fp, *apex;
+
+      stream = rec->Stream;
 
       /* If extracting, it was from previous stream, so
        * close the output file.
        */
       if (extract) {
         if (ofd < 0) {
-            Emsg0(M_ERROR_TERM, 0, "Logic error output file should be open\n");
+            Emsg0(M_ERROR, 0, "Logic error output file should be open\n");
         }
-        close(ofd);
-        ofd = -1;
         extract = FALSE;
-        set_statp(jcr, fname, ofile, lname, type, &statp);
+        set_attributes(jcr, fname, ofile, lname, type, stream, &statp,
+                       attribsEx, &ofd);
       }
 
       if (sizeof_pool_memory(fname) < rec->data_len) {
@@ -250,6 +276,7 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
        *    Filename
        *    Attributes
        *    Link name (if file linked i.e. FT_LNK)
+       *    Extended Attributes (Win32) 
        *
        */
       sscanf(rec->data, "%ld %d", &record_file_index, &type);
@@ -278,6 +305,19 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
          lp = "";
       }
 
+      if (rec->Stream == STREAM_WIN32_ATTRIBUTES) {
+        apex = ap;                   /* start at attributes */
+        while (*apex++ != 0) {       /* skip attributes */
+           ;
+        }
+        while (*apex++ != 0) {      /* skip link name */
+           ;
+        }
+        pm_strcpy(&attribsEx, apex);  /* make a copy of Extended attributes */
+      } else {
+        *attribsEx = 0;              /* no extended attributes */
+      }
+
         
       if (file_is_included(ff, fname) && !file_is_excluded(ff, fname)) {
 
@@ -287,84 +327,120 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
          * files are put where the user wants.
          *
          * We do a little jig here to handle Win32 files with
-         * a drive letter.  
-         *   If where is null and we are running on a win32 client,
-         *      change nothing.
-         *   Otherwise, if the second character of the filename is a
-         *   colon (:), change it into a slash (/) -- this creates
-         *   a reasonable pathname on most systems.
+         *   a drive letter -- we simply strip the drive: from
+         *   every filename if a prefix is supplied.
          */
-        if (where[0] == 0 && win32_client) {
+        if (where[0] == 0) {
            strcpy(ofile, fname);
            strcpy(lname, lp);
         } else {
+           char *fn;
            strcpy(ofile, where);
-            if (fname[1] == ':') {
-               fname[1] = '/';
-              strcat(ofile, fname);
-               fname[1] = ':';
+            if (win32_client && fname[1] == ':') {
+              fn = fname+2;          /* skip over drive: */
            } else {
-              strcat(ofile, fname);
+              fn = fname;            /* take whole name */
+           }
+           /* Ensure where is terminated with a slash */
+            if (where[wherelen-1] != '/' && fn[0] != '/') {
+               strcat(ofile, "/");
            }
+           strcat(ofile, fn);        /* copy rest of name */
            /* Fixup link name */
            if (type == FT_LNK || type == FT_LNKSAVED) {
                if (lp[0] == '/') {      /* if absolute path */
                  strcpy(lname, where);
               }       
-               /* ***FIXME**** we shouldn't have links on Windoz */
-               if (lp[1] == ':') {
-                  lp[1] = '/';
-                 strcat(lname, lp);
-                  lp[1] = ':';
+               if (win32_client && lp[1] == ':') {
+                 strcat(lname, lp+2); /* copy rest of name */
               } else {
-                 strcat(lname, lp);
+                 strcat(lname, lp);   /* On Unix systems we take everything */
               }
            }
         }
 
-           /*          Pmsg1(000, "Restoring: %s\n", ofile); */
+         /*          Pmsg1(000, "Restoring: %s\n", ofile); */
 
-        extract = create_file(jcr, fname, ofile, lname, type, &statp, &ofd);
+        extract = create_file(jcr, fname, ofile, lname, type, stream,
+                              &statp, attribsEx, &ofd);
         num_files++;
 
         if (extract) {
             print_ls_output(ofile, lname, type, &statp);   
+            fileAddr = 0;
         }
       }
 
    /* Data stream and extracting */
-   } else if (rec->Stream == STREAM_FILE_DATA) {
+   } else if (rec->Stream == STREAM_FILE_DATA || rec->Stream == STREAM_SPARSE_DATA) {
       if (extract) {
-        total += rec->data_len;
-         Dmsg2(8, "Write %ld bytes, total=%ld\n", rec->data_len, total);
-        if ((uint32_t)write(ofd, rec->data, rec->data_len) != rec->data_len) {
-            Emsg1(M_ERROR_TERM, 0, "Write error: %s\n", strerror(errno));
+        if (rec->Stream == STREAM_SPARSE_DATA) {
+           ser_declare;
+           uint64_t faddr;
+           wbuf = rec->data + SPARSE_FADDR_SIZE;
+           wsize = rec->data_len - SPARSE_FADDR_SIZE;
+           ser_begin(rec->data, SPARSE_FADDR_SIZE);
+           unser_uint64(faddr);
+           if (fileAddr != faddr) {
+              fileAddr = faddr;
+              if (lseek(ofd, (off_t)fileAddr, SEEK_SET) < 0) {
+                  Emsg2(M_ERROR_TERM, 0, _("Seek error on %s: %s\n"), ofile, strerror(errno));
+              }
+           }
+        } else {
+           wbuf = rec->data;
+           wsize = rec->data_len;
+        }
+        total += wsize;
+         Dmsg2(8, "Write %u bytes, total=%u\n", wsize, total);
+        if ((uint32_t)write(ofd, wbuf, wsize) != wsize) {
+            Emsg2(M_ERROR_TERM, 0, _("Write error on %s: %s\n"), ofile, strerror(errno));
         }
+        fileAddr += wsize;
       }
 
    } else if (rec->Stream == STREAM_GZIP_DATA) {
 #ifdef HAVE_LIBZ
       if (extract) {
         uLongf compress_len;
-
+        int stat;
+
+        if (rec->Stream == STREAM_SPARSE_GZIP_DATA) {
+           ser_declare;
+           uint64_t faddr;
+           wbuf = rec->data + SPARSE_FADDR_SIZE;
+           wsize = rec->data_len - SPARSE_FADDR_SIZE;
+           ser_begin(rec->data, SPARSE_FADDR_SIZE);
+           unser_uint64(faddr);
+           if (fileAddr != faddr) {
+              fileAddr = faddr;
+              if (lseek(ofd, (off_t)fileAddr, SEEK_SET) < 0) {
+                  Emsg2(M_ERROR, 0, _("Seek error on %s: %s\n"), ofile, strerror(errno));
+              }
+           }
+        } else {
+           wbuf = rec->data;
+           wsize = rec->data_len;
+        }
         compress_len = compress_buf_size;
-        if (uncompress((Bytef *)compress_buf, &compress_len, 
-              (const Bytef *)rec->data, (uLong)rec->data_len) != Z_OK) {
-            Emsg0(M_ERROR_TERM, 0, _("Uncompression error.\n"));
+        if ((stat=uncompress((Bytef *)compress_buf, &compress_len, 
+              (const Bytef *)wbuf, (uLong)wsize) != Z_OK)) {
+            Emsg1(M_ERROR_TERM, 0, _("Uncompression error. ERR=%d\n"), stat);
         }
 
          Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total);
         if ((uLongf)write(ofd, compress_buf, (size_t)compress_len) != compress_len) {
             Pmsg0(0, "===Write error===\n");
-            Emsg2(M_ERROR_TERM, 0, "Write error on %s: %s\n", ofile, strerror(errno));
+            Emsg2(M_ERROR_TERM, 0, _("Write error on %s: %s\n"), ofile, strerror(errno));
         }
         total += compress_len;
+        fileAddr += compress_len;
          Dmsg2(100, "Compress len=%d uncompressed=%d\n", rec->data_len,
            compress_len);
       }
 #else
       if (extract) {
-         Emsg0(M_ERROR_TERM, 0, "GZIP data stream found, but GZIP not configured!\n");
+         Emsg0(M_ERROR, 0, "GZIP data stream found, but GZIP not configured!\n");
       }
 #endif
 
@@ -372,12 +448,16 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
    /* If extracting, wierd stream (not 1 or 2), close output file anyway */
    } else if (extract) {
       if (ofd < 0) {
-         Emsg0(M_ERROR_TERM, 0, "Logic error output file should be open\n");
+         Emsg0(M_ERROR, 0, "Logic error output file should be open\n");
       }
-      close(ofd);
-      ofd = -1;
       extract = FALSE;
-      set_statp(jcr, fname, ofile, lname, type, &statp);
+      set_attributes(jcr, fname, ofile, lname, type, stream, &statp,
+                    attribsEx, &ofd);
+   } else if (rec->Stream == STREAM_PROGRAM_NAMES || rec->Stream == STREAM_PROGRAM_DATA) {
+      if (!prog_name_msg) {
+         Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
+        prog_name_msg = 1;
+      }
    } else if (rec->Stream != STREAM_MD5_SIGNATURE) {
       Pmsg2(0, "None of above!!! stream=%d data=%s\n", rec->Stream, rec->data);
    }
index cd6a0a10641a1898eeafe94ed250f77e9ef39d78..6d1df90b4dcf141dfdda4247a7525a0e6b3d9251 100644 (file)
@@ -3,6 +3,7 @@
  *   block.c -- tape block handling functions
  *
  *             Kern Sibbald, March MMI
+ *                added BB02 format October MMII
  *
  *   Version $Id$
  *
@@ -69,28 +70,28 @@ void dump_block(DEV_BLOCK *b, char *msg)
    }
 
    if (block_len > 100000) {
-      Dmsg3(20, "Dump block %s %s blocksize too big %d\n", msg, b, block_len);
+      Dmsg3(20, "Dump block %s 0x%x blocksize too big %u\n", msg, b, block_len);
       return;
    }
 
    BlockCheckSum = bcrc32((uint8_t *)b->buf+BLKHDR_CS_LENGTH,
                         block_len-BLKHDR_CS_LENGTH);
-   Dmsg6(10, "Dump block %s %x: size=%d BlkNum=%d\n\
+   Pmsg6(000, "Dump block %s %x: size=%d BlkNum=%d\n\
                Hdrcksum=%x cksum=%x\n",
       msg, b, block_len, BlockNumber, CheckSum, BlockCheckSum);
    p = b->buf + bhl;
    while (p < (b->buf + block_len+WRITE_RECHDR_LENGTH)) { 
       unser_begin(p, WRITE_RECHDR_LENGTH);
       if (rhl == RECHDR1_LENGTH) {
-      unser_uint32(VolSessionId);
-      unser_uint32(VolSessionTime);
+        unser_uint32(VolSessionId);
+        unser_uint32(VolSessionTime);
       }
       unser_int32(FileIndex);
       unser_int32(Stream);
       unser_uint32(data_len);
-      Dmsg6(10, "   Rec: VId=%d VT=%d FI=%s Strm=%s len=%d p=%x\n",
-          VolSessionId, VolSessionTime, FI_to_ascii(FileIndex), stream_to_ascii(Stream),
-          data_len, p);
+      Pmsg6(000, "   Rec: VId=%u VT=%u FI=%s Strm=%s len=%d p=%x\n",
+          VolSessionId, VolSessionTime, FI_to_ascii(FileIndex), 
+          stream_to_ascii(Stream, FileIndex), data_len, p);
       p += data_len + rhl;
   }
 }
@@ -111,11 +112,14 @@ DEV_BLOCK *new_block(DEVICE *dev)
    } else {
       block->buf_len = dev->max_block_size;
    }
+   /* ****FIXME***** move this up to init_dev() */
    if (block->buf_len % TAPE_BSIZE != 0) {
-      Mmsg2(&dev->errmsg, _("Block size %d forced to be multiple of %d\n"), 
-        block->buf_len, TAPE_BSIZE);
+      uint32_t old_len = block->buf_len;
+      block->buf_len = ((old_len + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
+      Mmsg3(&dev->errmsg, _("Block size %u forced to %u to be multiple of %d\n"), 
+        old_len, block->buf_len, TAPE_BSIZE);
       Emsg0(M_WARNING, 0, dev->errmsg);
-      block->buf_len = ((block->buf_len + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
+      dev->max_block_size = block->buf_len;  /* force block size */
    }
    block->block_len = block->buf_len;  /* default block size */
    block->buf = get_memory(block->buf_len); 
@@ -332,8 +336,6 @@ int write_block_to_dev(DEVICE *dev, DEV_BLOCK *block)
       }
    }  
 
-   dev->block_num++;
-   block->BlockNumber = dev->block_num;
    ser_block_header(block);
 
    /* Limit maximum Volume size to value specified by user */
@@ -351,7 +353,7 @@ int write_block_to_dev(DEVICE *dev, DEV_BLOCK *block)
    }
 
    dev->VolCatInfo.VolCatWrites++;
-// Dmsg1(000, "Pos before write=%lld\n", lseek(dev->fd, (off_t)0, SEEK_CUR));
+   Dmsg1(500, "Write block of %u bytes\n", wlen);      
    if ((uint32_t) (stat=write(dev->fd, block->buf, (size_t)wlen)) != wlen) {
       /* We should check for errno == ENOSPC, BUT many 
        * devices simply report EIO when it is full.
@@ -368,11 +370,11 @@ int write_block_to_dev(DEVICE *dev, DEV_BLOCK *block)
         dev->dev_errno = ENOSPC;        /* out of space */
       }
 
-      Dmsg2(0, "=== Write error errno=%d: ERR=%s\n", dev->dev_errno,
-        strerror(dev->dev_errno));
+      Dmsg4(10, "=== Write error. size=%u rtn=%d  errno=%d: ERR=%s\n", 
+        wlen, stat, dev->dev_errno, strerror(dev->dev_errno));
 
-      Mmsg2(&dev->errmsg, _("Write error on device %s. ERR=%s.\n"), 
-        dev->dev_name, strerror(dev->dev_errno));
+      Mmsg4(&dev->errmsg, _("Write error on device %s. Write of %u bytes got %d. ERR=%s.\n"), 
+        dev->dev_name, wlen, stat, strerror(dev->dev_errno));
       block->failed_write = TRUE;
       weof_dev(dev, 1);              /* end the tape */
       weof_dev(dev, 1);              /* write second eof */
@@ -381,15 +383,17 @@ int write_block_to_dev(DEVICE *dev, DEV_BLOCK *block)
 // Dmsg1(000, "Pos after write=%lld\n", lseek(dev->fd, (off_t)0, SEEK_CUR));
    dev->VolCatInfo.VolCatBytes += block->binbuf;
    dev->VolCatInfo.VolCatBlocks++;   
-   dev->file_bytes += block->binbuf;
+   dev->file_addr += wlen;
 
    /* Limit maximum File size on volume to user specified value */
    if (dev->state & ST_TAPE) {
-      if ((dev->max_file_size > 0) && dev->file_bytes >= dev->max_file_size) {
-      weof_dev(dev, 1);              /* write eof */
-   }
+      if ((dev->max_file_size > 0) && dev->file_addr >= dev->max_file_size) {
+        weof_dev(dev, 1);               /* write eof */
+      }
    }
 
+   dev->block_num++;
+   block->BlockNumber++;
    Dmsg2(190, "write_block: wrote block %d bytes=%d\n", dev->block_num,
       wlen);
    empty_block(block);
index ca265dea7c41f642784abd05ac25ecf5e7206dd3..90f10a06ddc7d86328806857b1823a031d2cdbd3 100644 (file)
 #define BLKHDR1_LENGTH   16             /* Total length */
 #define BLKHDR2_LENGTH   24             /* Total length */
 
-#define WRITE_BLKHDR_ID     BLKHDR1_ID
-#define WRITE_BLKHDR_LENGTH BLKHDR1_LENGTH
-#define BLOCK_VER               1
+#define WRITE_BLKHDR_ID     BLKHDR2_ID
+#define WRITE_BLKHDR_LENGTH BLKHDR2_LENGTH
+#define BLOCK_VER               2
 
 /* Record header definitions */
 #define RECHDR1_LENGTH      20
 #define RECHDR2_LENGTH      12
-#define WRITE_RECHDR_LENGTH RECHDR1_LENGTH
+#define WRITE_RECHDR_LENGTH RECHDR2_LENGTH
 
 /* Tape label and version definitions */
-#define BaculaId "Bacula 0.9 mortal\n"
-#define BaculaTapeVersion 10
+#define BaculaId    "Bacula 1.0 immortal\n"
+#define OldBaculaId "Bacula 0.9 mortal\n"
+#define BaculaTapeVersion 11
 #define OldCompatibleBaculaTapeVersion1  10
 #define OldCompatibleBaculaTapeVersion2   9
 
index 3cac57d2f7b99bace28d1097b713a4f83384e19b..231fae8315d9d752253283f7752e25f5f5e47291 100644 (file)
@@ -36,7 +36,6 @@ static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sess
 static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec);
 
 static DEVICE *dev;
-static int default_tape = FALSE;
 static int dump_label = FALSE;
 static int list_blocks = FALSE;
 static int list_jobs = FALSE;
@@ -48,6 +47,10 @@ static SESSION_LABEL sessrec;
 static uint32_t num_files = 0;
 static long record_file_index;
 
+#define CONFIG_FILE "bacula-sd.conf"
+char *configfile;
+
+
 static FF_PKT ff;
 
 static BSR *bsr = NULL;
@@ -58,6 +61,7 @@ static void usage()
 "\nVersion: " VERSION " (" DATE ")\n\n"
 "Usage: bls [-d debug_level] <physical-device-name>\n"
 "       -b <file>       specify a bootstrap file\n"
+"       -c <file>       specify a config file\n"
 "       -d <level>      specify debug level\n"
 "       -e <file>       exclude list\n"
 "       -i <file>       include list\n"
@@ -65,7 +69,6 @@ static void usage()
 "       -k              list blocks\n"
 "       -L              list tape label\n"
 "    (none of above)    list saved files\n"
-"       -t              use default tape device\n"
 "       -v              be verbose\n"
 "       -?              print this message\n\n");
    exit(1);
@@ -85,13 +88,20 @@ int main (int argc, char *argv[])
    memset(&ff, 0, sizeof(ff));
    init_include_exclude_files(&ff);
 
-   while ((ch = getopt(argc, argv, "b:d:e:i:jkLtv?")) != -1) {
+   while ((ch = getopt(argc, argv, "b:c:d:e:i:jkLtv?")) != -1) {
       switch (ch) {
          case 'b':
            bsr = parse_bsr(NULL, optarg);
 //         dump_bsr(bsr);
            break;
 
+         case 'c':                    /* specify config file */
+           if (configfile != NULL) {
+              free(configfile);
+           }
+           configfile = bstrdup(optarg);
+           break;
+
          case 'd':                    /* debug level */
            debug_level = atoi(optarg);
            if (debug_level <= 0)
@@ -138,10 +148,6 @@ int main (int argc, char *argv[])
            dump_label = TRUE;
            break;
 
-         case 't':
-           default_tape = TRUE;
-           break;
-
          case 'v':
            verbose++;
            break;
@@ -155,24 +161,25 @@ int main (int argc, char *argv[])
    argc -= optind;
    argv += optind;
 
-   if (!argc && !default_tape) {
+   if (!argc) {
       Pmsg0(0, "No archive name specified\n");
       usage();
    }
 
-   if (ff.included_files_list == NULL) {
-      add_fname_to_include_list(&ff, 0, "/");
+   if (configfile == NULL) {
+      configfile = bstrdup(CONFIG_FILE);
    }
 
-   /* Try default device */
-   if (default_tape) {
-      do_ls(DEFAULT_TAPE_DRIVE);
-      return 0;
+   parse_config(configfile);
+
+
+   if (ff.included_files_list == NULL) {
+      add_fname_to_include_list(&ff, 0, "/");
    }
 
    for (i=0; i < argc; i++) {
       jcr = setup_jcr("bls", argv[i], bsr);
-      dev = setup_to_read_device(jcr);
+      dev = setup_to_access_device(jcr, 1);   /* acquire for read */
       if (!dev) {
         exit(1);
       }
@@ -217,10 +224,8 @@ static void do_close(JCR *jcr)
 /* List just block information */
 static void do_blocks(char *infname)
 {
-
-   dump_volume_label(dev);
-
    if (verbose) {
+      dump_volume_label(dev);
       rec = new_record();
    }
    for ( ;; ) {
@@ -252,15 +257,15 @@ static void do_blocks(char *infname)
         display_error_status(dev);
         break;
       }
-      Dmsg5(100, "Blk=%u blen=%u bVer=%d SessId=%d SessTim=%d\n",
+      Dmsg5(100, "Blk=%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
         block->BlockNumber, block->block_len, block->BlockVer,
         block->VolSessionId, block->VolSessionTime);
       if (verbose == 1) {
         read_record_from_block(block, rec);
-         Pmsg6(-1, "Block: %u blen=%u First rec FI=%s SessId=%d Strm=%s rlen=%d\n",
+         Pmsg7(-1, "Block: %u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n",
              block->BlockNumber, block->block_len,
-             FI_to_ascii(rec->FileIndex), rec->VolSessionId, 
-             stream_to_ascii(rec->Stream), rec->data_len);
+             FI_to_ascii(rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
+             stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len);
         rec->remainder = 0;
       } else if (verbose > 1) {
          dump_block(block, "");
@@ -298,6 +303,7 @@ static void do_ls(char *infname)
    }
 
    read_records(jcr, dev, record_cb, mount_next_read_volume);
+   printf("%u files found.\n", num_files);
 }
 
 /*
@@ -314,7 +320,7 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
       return;
    }
    /* File Attributes stream */
-   if (rec->Stream == STREAM_UNIX_ATTRIBUTES) {
+   if (rec->Stream == STREAM_UNIX_ATTRIBUTES || rec->Stream == STREAM_WIN32_ATTRIBUTES) {
       char *ap, *fp;
       sscanf(rec->data, "%ld %d", &record_file_index, &type);
       if (record_file_index != rec->FileIndex) {
@@ -343,9 +349,6 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
         num_files++;
       }
    }
-   if (verbose) {
-      printf("%u files found.\n", num_files);
-   }
    return;
 }
 
index 7f674276cdb3f9920029b8b2272131dcf91a13cd..9ab112e5315598bbba1b274fbd875841fbc81e85 100644 (file)
@@ -35,7 +35,7 @@
 #include "cats/cats.h"
 
 /* Forward referenced functions */
-static void do_scan(char *fname);
+static void do_scan(void);
 static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec);
 static int  create_file_attributes_record(B_DB *db, JCR *mjcr, 
                               char *fname, char *lname, int type,
@@ -57,7 +57,7 @@ static int update_MD5_record(B_DB *db, char *MD5buf, DEV_RECORD *rec);
 static DEVICE *dev = NULL;
 static B_DB *db;
 static JCR *bjcr;                    /* jcr for bscan */
-static BSR *bsr;
+static BSR *bsr = NULL;
 static struct stat statp;
 static int type;
 static long record_file_index;
@@ -85,12 +85,17 @@ static int update_db = 0;
 static int update_vol_info = 0;
 static int list_records = 0;
 
+#define CONFIG_FILE "bacula-sd.conf"
+char *configfile;
+
+
 static void usage()
 {
    fprintf(stderr, _(
 "\nVersion: " VERSION " (" DATE ")\n\n"
 "Usage: bscan [-d debug_level] <bacula-archive>\n"
 "       -b bootstrap      specify a bootstrap file\n"
+"       -c <file>         specify configuration file\n"
 "       -dnn              set debug level to nn\n"
 "       -m                update media info in database\n"
 "       -n name           specify the database name (default bacula)\n"
@@ -112,11 +117,19 @@ int main (int argc, char *argv[])
    init_msg(NULL, NULL);
 
 
-   while ((ch = getopt(argc, argv, "b:d:mn:p:rsu:vw:?")) != -1) {
+   while ((ch = getopt(argc, argv, "b:c:d:mn:p:rsu:vw:?")) != -1) {
       switch (ch) {
          case 'b':
            bsr = parse_bsr(NULL, optarg);
            break;
+
+         case 'c':                    /* specify config file */
+           if (configfile != NULL) {
+              free(configfile);
+           }
+           configfile = bstrdup(optarg);
+           break;
+
          case 'd':                    /* debug level */
            debug_level = atoi(optarg);
            if (debug_level <= 0)
@@ -171,7 +184,17 @@ int main (int argc, char *argv[])
 
    working_directory = wd;
 
+   if (configfile == NULL) {
+      configfile = bstrdup(CONFIG_FILE);
+   }
+
+   parse_config(configfile);
+
    bjcr = setup_jcr("bscan", argv[0], bsr);
+   dev = setup_to_access_device(bjcr, 0);   /* read device */
+   if (!dev) { 
+      exit(1);
+   }
 
    if ((db=db_init_database(NULL, db_name, db_user, db_password)) == NULL) {
       Emsg0(M_ERROR_TERM, 0, _("Could not init Bacula database\n"));
@@ -184,21 +207,15 @@ int main (int argc, char *argv[])
       Pmsg2(000, _("Using Database: %s, User: %s\n"), db_name, db_user);
    }
 
-   do_scan(argv[0]);
+   do_scan();
 
    free_jcr(bjcr);
    return 0;
 }
   
 
-static void do_scan(char *devname)            
+static void do_scan()            
 {
-
-   dev = setup_to_read_device(bjcr);
-   if (!dev) { 
-      exit(1);
-   }
-
    fname = get_pool_memory(PM_FNAME);
    ofile = get_pool_memory(PM_FNAME);
    lname = get_pool_memory(PM_FNAME);
@@ -336,10 +353,15 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
            mjcr = create_job_record(db, &jr, &label, rec);
            update_db = save_update_db;
 
-              jr.PoolId = pr.PoolId;
-              /* Set start positions into JCR */
-           mjcr->StartBlock = dev->block_num;
-           mjcr->StartFile = dev->file;
+           jr.PoolId = pr.PoolId;
+           /* Set start positions into JCR */
+           if (dev->state & ST_TAPE) {
+              mjcr->StartBlock = dev->block_num;
+              mjcr->StartFile = dev->file;
+           } else {
+              mjcr->StartBlock = (uint32_t)dev->file_addr;
+              mjcr->StartFile = (uint32_t)(dev->file_addr >> 32);
+           }
            mjcr->start_time = jr.StartTime;
            mjcr->JobLevel = jr.Level;
 
@@ -438,7 +460,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
 
 
    /* File Attributes stream */
-   if (rec->Stream == STREAM_UNIX_ATTRIBUTES) {
+   if (rec->Stream == STREAM_UNIX_ATTRIBUTES || rec->Stream == STREAM_WIN32_ATTRIBUTES) {
       char *ap, *lp, *fp;
 
       if (sizeof_pool_memory(fname) < rec->data_len) {
@@ -504,7 +526,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
       }
       free_jcr(mjcr);
 
-   /* Data stream and extracting */
+   /* Data stream */
    } else if (rec->Stream == STREAM_FILE_DATA) {
       mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
       if (!mjcr) {
@@ -515,6 +537,16 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
       mjcr->JobBytes += rec->data_len;
       free_jcr(mjcr);                /* done using JCR */
 
+   } else if (rec->Stream == STREAM_SPARSE_DATA) {
+      mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
+      if (!mjcr) {
+         Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Attributes record.\n"),
+                     rec->VolSessionId, rec->VolSessionTime);
+        return;
+      }
+      mjcr->JobBytes += rec->data_len - sizeof(uint64_t);
+      free_jcr(mjcr);                /* done using JCR */
+
    } else if (rec->Stream == STREAM_GZIP_DATA) {
       mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
       if (!mjcr) {
@@ -522,9 +554,20 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
                      rec->VolSessionId, rec->VolSessionTime);
         return;
       }
-      mjcr->JobBytes += rec->data_len;
+      mjcr->JobBytes += rec->data_len; /* No correct, we should expand it */
       free_jcr(mjcr);                /* done using JCR */
 
+   } else if (rec->Stream == STREAM_SPARSE_GZIP_DATA) {
+      mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
+      if (!mjcr) {
+         Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Attributes record.\n"),
+                     rec->VolSessionId, rec->VolSessionTime);
+        return;
+      }
+      mjcr->JobBytes += rec->data_len - sizeof(uint64_t); /* No correct, we should expand it */
+      free_jcr(mjcr);                /* done using JCR */
+
+
    } else if (rec->Stream == STREAM_MD5_SIGNATURE) {
       char MD5buf[30];
       bin_to_base64(MD5buf, (char *)rec->data, 16); /* encode 16 bytes */
@@ -532,6 +575,15 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
          Pmsg1(000, _("Got MD5 record: %s\n"), MD5buf);
       }
       update_MD5_record(db, MD5buf, rec);
+
+   } else if (rec->Stream == STREAM_PROGRAM_NAMES) {
+      if (verbose) {
+         Pmsg1(000, _("Got Prog Names Stream: %s\n"), rec->data);
+      }
+   } else if (rec->Stream == STREAM_PROGRAM_DATA) {
+      if (verbose > 1) {
+         Pmsg0(000, _("Got Prog Data Stream record.\n"));
+      }
    } else {
       Pmsg2(0, _("Unknown stream type!!! stream=%d data=%s\n"), rec->Stream, rec->data);
    }
@@ -608,11 +660,12 @@ static int create_media_record(B_DB *db, MEDIA_DBR *mr, VOLUME_LABEL *vl)
    struct tm tm;
 
    strcpy(mr->VolStatus, "Full");
-   mr->VolRetention = 355 * 3600 * 24; /* 1 year */
+   mr->VolRetention = 365 * 3600 * 24; /* 1 year */
    if (vl->VerNum >= 11) {
-      mr->FirstWritten = (time_t)vl->write_btime;
-      mr->LabelDate    = (time_t)vl->label_btime;
+      mr->FirstWritten = btime_to_etime(vl->write_btime);
+      mr->LabelDate    = btime_to_etime(vl->label_btime);
    } else {
+      /* DEPRECATED DO NOT USE */
       dt.julian_day_number = vl->write_date;
       dt.julian_day_fraction = vl->write_time;
       tm_decode(&dt, &tm);
@@ -748,7 +801,7 @@ static JCR *create_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *label,
    strcpy(jr->Name, label->JobName);
    strcpy(jr->Job, label->Job);
    if (label->VerNum >= 11) {
-      jr->SchedTime = (time_t)label->write_btime;
+      jr->SchedTime = btime_to_etime(label->write_btime);
    } else {
       dt.julian_day_number = label->write_date;
       dt.julian_day_fraction = label->write_time;
@@ -805,7 +858,7 @@ static int update_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *elabel,
       return 0;
    }
    if (elabel->VerNum >= 11) {
-      jr->EndTime = (time_t)elabel->write_btime;
+      jr->EndTime = btime_to_etime(elabel->write_btime);
    } else {
       dt.julian_day_number = elabel->write_date;
       dt.julian_day_fraction = elabel->write_time;
@@ -899,8 +952,13 @@ static int create_jobmedia_record(B_DB *db, JCR *mjcr)
 {
    JOBMEDIA_DBR jmr;
 
-   mjcr->EndBlock = dev->block_num;
-   mjcr->EndFile = dev->file;
+   if (dev->state & ST_TAPE) {
+      mjcr->EndBlock = dev->block_num;
+      mjcr->EndFile = dev->file;
+   } else {
+      mjcr->EndBlock = (uint32_t)dev->file_addr;
+      mjcr->EndFile = (uint32_t)(dev->file_addr >> 32);
+   }
 
    memset(&jmr, 0, sizeof(jmr));
    jmr.JobId = mjcr->JobId;
@@ -1007,8 +1065,13 @@ int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev)
       if (verbose) {
          Pmsg1(000, "create JobMedia for Job %s\n", mjcr->Job);
       }
-      mjcr->EndBlock = dev->block_num;
-      mjcr->EndFile = dev->file;
+      if (dev->state & ST_TAPE) {
+        mjcr->EndBlock = dev->block_num;
+        mjcr->EndFile = dev->file;
+      } else {
+        mjcr->EndBlock = (uint32_t)dev->file_addr;
+        mjcr->StartBlock = (uint32_t)(dev->file_addr >> 32);
+      }
       if (!create_jobmedia_record(db, mjcr)) {
          Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"),
            dev->VolCatInfo.VolCatName, mjcr->Job);
index 8c0df2384d907d598c50925ba519801b3b4c00be..c079ae7ae009d1fa3b78edacc1890e763693ea23 100644 (file)
@@ -58,19 +58,20 @@ static void rewindcmd();
 static void clearcmd();
 static void wrcmd();
 static void eodcmd();
-static int find_device_res();
 static void fillcmd();
 static void unfillcmd();
-static int flush_block(DEV_BLOCK *block);
+static int flush_block(DEV_BLOCK *block, int dump);
 static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec);
 static int my_mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
 
-#define CONFIG_FILE "stored.conf"
 
-static char *configfile;
+/* Static variables */
+#define CONFIG_FILE "bacula-sd.conf"
+char *configfile;
+
+static BSR *bsr = NULL;
 static char cmd[1000];
 static int signals = TRUE;
-static int default_tape = FALSE;
 static int ok;
 static int stop;
 static uint64_t vol_size;
@@ -81,6 +82,10 @@ static long file_index;
 static int verbose = 0;
 static int end_of_tape = 0;
 static uint32_t LastBlock = 0;
+static uint32_t eot_block;
+static uint32_t eot_block_len;
+static uint32_t eot_FileIndex;
+static int dumped = 0;
 
 static char *VolumeName = NULL;
 
@@ -91,31 +96,6 @@ static void usage();
 static void terminate_btape(int sig);
 int get_cmd(char *prompt);
 
-static void my_free_jcr(JCR *jcr)
-{
-   if (jcr->pool_name) {
-      free_pool_memory(jcr->pool_name);
-      jcr->pool_name = NULL;
-   }
-   if (jcr->pool_type) {
-      free_pool_memory(jcr->pool_type);
-      jcr->pool_type = NULL;
-   }
-   if (jcr->job_name) {
-      free_pool_memory(jcr->job_name);
-      jcr->job_name = NULL;
-   }
-   if (jcr->client_name) {
-      free_pool_memory(jcr->client_name);
-      jcr->client_name = NULL;
-   }
-   if (jcr->fileset_name) {
-      free_pool_memory(jcr->fileset_name);
-      jcr->fileset_name = NULL;
-   }
-     
-   return;
-}
 
 int write_dev(DEVICE *dev, char *buf, size_t len) 
 {
@@ -154,8 +134,13 @@ int main(int argc, char *argv[])
    my_name_is(argc, argv, "btape");
    init_msg(NULL, NULL);
 
-   while ((ch = getopt(argc, argv, "c:d:stv?")) != -1) {
+   while ((ch = getopt(argc, argv, "b:c:d:sv?")) != -1) {
       switch (ch) {
+         case 'b':                    /* bootstrap file */
+           bsr = parse_bsr(NULL, optarg);
+//         dump_bsr(bsr);
+           break;
+
          case 'c':                    /* specify config file */
            if (configfile != NULL) {
               free(configfile);
@@ -174,10 +159,6 @@ int main(int argc, char *argv[])
            signals = FALSE;
            break;
 
-         case 't':
-           default_tape = TRUE;
-           break;
-
          case 'v':
            verbose++;
            break;
@@ -208,51 +189,22 @@ int main(int argc, char *argv[])
 
 
    /* See if we can open a device */
-   if (argc) {
-      if (!(dev = init_dev(NULL, *argv))) {
-        usage();
-        exit(1);
-      }
-   }
-
-   /* Try default device */
-   if (!dev && default_tape) {
-      dev = init_dev(NULL, DEFAULT_TAPE_DRIVE);
-   }
-
-   if (dev) {
-      if (!find_device_res()) {
-        exit(1);
-      }
-      if (!open_device(dev)) {
-         Pmsg1(0, "Warning could not open device. ERR=%s", strerror_dev(dev));
-        term_dev(dev);
-        dev = NULL;
-      }
+   if (argc == 0) {
+      Pmsg0(000, "No archive name specified.\n");
+      usage();
+      exit(1);
+   } else if (argc != 1) {
+      Pmsg0(000, "Improper number of arguments specified.\n");
+      usage();
+      exit(1);
+   }
+
+   jcr = setup_jcr("btape", argv[0], bsr);
+   dev = setup_to_access_device(jcr, 0);     /* acquire for write */
+   if (!dev) {
+      exit(1);
    }
 
-   /* Setup a "dummy" JCR that should work for most everything */
-   jcr = new_jcr(sizeof(JCR), my_free_jcr);
-   jcr->VolSessionId = 1;
-   jcr->VolSessionTime = (uint32_t)time(NULL);
-   jcr->NumVolumes = 1;
-   jcr->pool_name = get_pool_memory(PM_FNAME);
-   strcpy(jcr->pool_name, "Default");
-   jcr->pool_type = get_pool_memory(PM_FNAME);
-   strcpy(jcr->pool_type, "Backup");
-   jcr->job_name = get_pool_memory(PM_FNAME);
-   strcpy(jcr->job_name, "Dummy.Job.Name");
-   jcr->client_name = get_pool_memory(PM_FNAME);
-   strcpy(jcr->client_name, "Dummy.Client.Name");
-   strcpy(jcr->Job, "Dummy.Job");
-   jcr->fileset_name = get_pool_memory(PM_FNAME);
-   strcpy(jcr->fileset_name, "Dummy.fileset.name");
-   jcr->JobId = 1;
-   jcr->JobType = JT_BACKUP;
-   jcr->JobLevel = L_FULL;
-   jcr->JobStatus = JS_Terminated;
-
-
    Dmsg0(200, "Do tape commands\n");
    do_tape_cmds();
   
@@ -279,6 +231,10 @@ static void terminate_btape(int stat)
    free_jcr(jcr);
    jcr = NULL;
 
+   if (bsr) {
+      free_bsr(bsr);
+   }
+
    term_msg();
    close_memory_pool();              /* free memory in pool */
 
@@ -291,32 +247,6 @@ void quitcmd()
    quit = 1;
 }
 
-/*
- * Get a new device name 
- *  Normally given on the command line
- */
-static void devicecmd()
-{
-   if (dev) {
-      term_dev(dev);
-      dev = NULL;
-   }
-   if (!get_cmd("Enter Device Name: ")) {
-      return;
-   }
-   dev = init_dev(NULL, cmd);
-   if (dev) {
-      if (!find_device_res()) {
-        return;
-      }
-      if (!open_device(dev)) {
-         Pmsg1(0, "Device open failed. ERR=%s\n", strerror_dev(dev));
-      }
-   } else {
-      Pmsg0(0, "Device init failed.\n");                          
-   }
-}
-
 /*
  * Write a label to the tape   
  */
@@ -325,11 +255,6 @@ static void labelcmd()
    DEVRES *device;
    int found = 0;
 
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
-
    LockRes();
    for (device=NULL; (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) {
       if (strcmp(device->device_name, dev->dev_name) == 0) {
@@ -371,10 +296,6 @@ static void readlabelcmd()
    int stat;
    DEV_BLOCK *block;
 
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
    block = new_block(dev);
    stat = read_dev_volume_label(jcr, dev, block);
    switch (stat) {
@@ -411,35 +332,6 @@ static void readlabelcmd()
 }
 
 
-/*
- * Search for device resource that corresponds to 
- * device name on command line (or default).
- *      
- * Returns: 0 on failure
- *         1 on success
- */
-static int find_device_res()
-{
-   int found = 0;
-
-   LockRes();
-   for (device=NULL; (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) {
-      if (strcmp(device->device_name, dev->dev_name) == 0) {
-        device->dev = dev;
-        dev->capabilities = device->cap_bits;
-        found = 1;
-        break;
-      }
-   } 
-   UnlockRes();
-   if (!found) {
-      Pmsg2(0, "Could not find device %s in %s\n", dev->dev_name, configfile);
-      return 0;
-   }
-   Pmsg1(0, "Using device: %s\n", dev->dev_name);
-   return 1;
-}
-
 /*
  * Load the tape should have prevously been taken
  * off line, otherwise this command is not necessary.
@@ -447,10 +339,6 @@ static int find_device_res()
 static void loadcmd()
 {
 
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
    if (!load_dev(dev)) {
       Pmsg1(0, "Bad status from load. ERR=%s\n", strerror_dev(dev));
    } else
@@ -462,15 +350,12 @@ static void loadcmd()
  */
 static void rewindcmd()
 {
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
    if (!rewind_dev(dev)) {
       Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
       clrerror_dev(dev, -1);
-   } else
+   } else {
       Pmsg1(0, "Rewound %s\n", dev_name(dev));
+   }
 }
 
 /*
@@ -478,10 +363,6 @@ static void rewindcmd()
  */
 static void clearcmd()
 {
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
    clrerror_dev(dev, -1);
 }
 
@@ -492,10 +373,6 @@ static void weofcmd()
 {
    int stat;
 
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
    if ((stat = weof_dev(dev, 1)) < 0) {
       Pmsg2(0, "Bad status from weof %d. ERR=%s\n", stat, strerror_dev(dev));
       return;
@@ -513,10 +390,6 @@ static void weofcmd()
  */
 static void eomcmd()
 {
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
    if (!eod_dev(dev)) {
       Pmsg1(0, "Bad status from eod. ERR=%s\n", strerror_dev(dev));
       return;
@@ -540,10 +413,7 @@ static void eodcmd()
 static void bsfcmd()
 {
    int stat;
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
+
    if ((stat=bsf_dev(dev, 1)) < 0) {
       Pmsg1(0, "Bad status from bsf. ERR=%s\n", strerror(errno));
    } else {
@@ -557,10 +427,7 @@ static void bsfcmd()
 static void bsrcmd()
 {
    int stat;
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
+
    if ((stat=bsr_dev(dev, 1)) < 0) {
       Pmsg1(0, "Bad status from bsr. ERR=%s\n", strerror(errno));
    } else {
@@ -574,10 +441,6 @@ static void bsrcmd()
  */
 static void capcmd()
 {
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
    Pmsg0(0, "Device capabilities: ");
    printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
    printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
@@ -604,11 +467,6 @@ static void rectestcmd()
    DEV_RECORD *rec;
    int i, blkno = 0;
 
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
-
    Pmsg0(0, "Test writting larger and larger records.\n\
 This is a torture test for records.\nI am going to write\n\
 larger and larger records. It will stop when the record size\n\
@@ -650,10 +508,6 @@ plus the header exceeds the block size (by default about 64K\n");
  */
 static void testcmd()
 {
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
    Pmsg0(0, "Append files test.\n\n\
 I'm going to write one record  in file 0,\n\
                    two records in file 1,\n\
@@ -714,10 +568,7 @@ block in the first file.\n\n");
 static void fsfcmd()
 {
    int stat;
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
+
    if ((stat=fsf_dev(dev, 1)) < 0) {
       Pmsg2(0, "Bad status from fsf %d. ERR=%s\n", stat, strerror_dev(dev));
       return;
@@ -728,10 +579,7 @@ static void fsfcmd()
 static void fsrcmd()
 {
    int stat;
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
+
    if ((stat=fsr_dev(dev, 1)) < 0) {
       Pmsg2(0, "Bad status from fsr %d. ERR=%s\n", stat, strerror_dev(dev));
       return;
@@ -744,10 +592,6 @@ static void rdcmd()
 #ifdef xxxxx
    int stat;
 
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
    if (!read_dev(dev, buf, 512*126)) {
       Pmsg1(0, "Bad status from read. ERR=%s\n", strerror_dev(dev));
       return;
@@ -765,36 +609,35 @@ static void wrcmd()
    DEV_RECORD *rec;
    int i;
 
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
    sm_check(__FILE__, __LINE__, False);
    block = new_block(dev);
    rec = new_record();
+   dump_block(block, "test");
 
-   i = 32001;
-   rec->data = (char *) check_pool_memory_size(rec->data, i);
+   i = block->buf_len - 100;
+   ASSERT (i > 0);
+   rec->data = check_pool_memory_size(rec->data, i);
    memset(rec->data, i & 0xFF, i);
    rec->data_len = i;
    sm_check(__FILE__, __LINE__, False);
    if (!write_record_to_block(block, rec)) {
       Pmsg0(0, "Error writing record to block.\n"); 
-      return;
+      goto bail_out;
    }
    if (!write_block_to_dev(dev, block)) {
       Pmsg0(0, "Error writing block to device.\n"); 
-      return;
+      goto bail_out;
    } else {
       Pmsg1(0, "Wrote one record of %d bytes.\n",
         ((i+TAPE_BSIZE-1)/TAPE_BSIZE) * TAPE_BSIZE);
    }
+   Pmsg0(0, "Wrote block to device.\n");
 
+bail_out:
    sm_check(__FILE__, __LINE__, False);
    free_record(rec);
    free_block(block);
    sm_check(__FILE__, __LINE__, False);
-   Pmsg0(0, "Wrote block to device.\n");
 }
 
 
@@ -809,10 +652,6 @@ static void scancmd()
    int block_size;
    uint64_t bytes;
 
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
 
    blocks = block_size = tot_blocks = 0;
    bytes = 0;
@@ -876,10 +715,6 @@ static void statcmd()
    int debug;
    uint32_t status;
 
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
    debug = debug_level;
    debug_level = 30;
    if (!status_dev(dev, &status)) {
@@ -903,11 +738,6 @@ static void fillcmd()
    char ec1[50];
    char *p;
 
-   if (!dev) {
-      Pmsg0(0, "No device: Use device command.\n");
-      return;
-   }
-
    ok = TRUE;
    stop = FALSE;
 
@@ -920,7 +750,7 @@ fills, it will ask for a second, and after writing a few \n\
 blocks, it will stop.  Then it will begin re-reading the\n\
 This may take a long time. I.e. hours! ...\n\n");
 
-   get_cmd("Do you wish to continue? (y/n): ");
+   get_cmd("Insert a blank tape then answer. Do you wish to continue? (y/n): ");
    if (cmd[0] != 'y') {
       Pmsg0(000, "Command aborted.\n");
       return;
@@ -988,13 +818,15 @@ This may take a long time. I.e. hours! ...\n\n");
       *lp = (uint64_t)file_index;
 
       Dmsg4(250, "before writ_rec FI=%d SessId=%d Strm=%s len=%d\n",
-        rec.FileIndex, rec.VolSessionId, stream_to_ascii(rec.Stream), 
+        rec.FileIndex, rec.VolSessionId, stream_to_ascii(rec.Stream, rec.FileIndex), 
         rec.data_len);
        
       if (!write_record_to_block(block, &rec)) {
          Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
                    rec.remainder);
-        if (!flush_block(block)) {
+
+        /* Write block to tape */
+        if (!flush_block(block, 1)) {
            return;
         }
 
@@ -1014,7 +846,7 @@ This may take a long time. I.e. hours! ...\n\n");
          */
         if ((block->BlockNumber % 50000) == 0) {
             Pmsg0(000, "Flush block, write EOF\n");
-           flush_block(block);
+           flush_block(block, 0);
            weof_dev(dev, 1);
            /* The weof resets the block number */
         }
@@ -1030,7 +862,7 @@ This may take a long time. I.e. hours! ...\n\n");
       jcr->JobBytes += rec.data_len;   /* increment bytes this job */
       Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
         FI_to_ascii(rec.FileIndex), rec.VolSessionId, 
-        stream_to_ascii(rec.Stream), rec.data_len);
+        stream_to_ascii(rec.Stream, rec.FileIndex), rec.data_len);
    }
    Dmsg0(000, "Write_end_session_label()\n");
    /* Create Job status for end of session label */
@@ -1056,6 +888,7 @@ This may take a long time. I.e. hours! ...\n\n");
    }
 
    free_block(block);
+   free_memory(rec.data);
    Pmsg0(000, "Done with fill command. Now beginning re-read of tapes...\n");
 
    unfillcmd();
@@ -1069,6 +902,7 @@ static void unfillcmd()
 {
    DEV_BLOCK *block;
 
+   dumped = 0;
    VolBytes = 0;
    LastBlock = 0;
    block = new_block(dev);
@@ -1088,6 +922,8 @@ static void unfillcmd()
    }
 
    time(&jcr->run_time);             /* start counting time for rates */
+   stop = 0;
+   file_index = 0;
    read_records(jcr, dev, record_cb, my_mount_next_read_volume);
    free_block(block);
 
@@ -1095,9 +931,27 @@ static void unfillcmd()
 }
 
 
+/* 
+ * We are called here from "unfill" for each record on the
+ *   tape.
+ */
 static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
 {
+
    SESSION_LABEL label;
+   if (stop > 1) {                   /* on second tape */
+      Pmsg4(000, "Blk: FileIndex=%d: block=%u size=%d vol=%s\n", 
+          rec->FileIndex, block->BlockNumber, block->block_len, dev->VolHdr.VolName);
+      Pmsg6(000, "   Rec: VId=%d VT=%d FI=%s Strm=%s len=%d state=%x\n",
+          rec->VolSessionId, rec->VolSessionTime, 
+          FI_to_ascii(rec->FileIndex), stream_to_ascii(rec->Stream, rec->FileIndex),
+          rec->data_len, rec->state);
+
+      if (!dumped) {
+        dumped = 1;
+         dump_block(block, "Block not written to previous tape");
+      }
+   }
    if (rec->FileIndex < 0) {
       if (verbose > 1) {
         dump_label_record(dev, rec, 1);
@@ -1108,8 +962,9 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
            return;
         case VOL_LABEL:
            unser_volume_label(dev, rec);
-            Pmsg2(000, "VOL_LABEL: block=%u vol=%s\n", block->BlockNumber, 
-              dev->VolHdr.VolName);
+            Pmsg3(000, "VOL_LABEL: block=%u size=%d vol=%s\n", block->BlockNumber, 
+              block->block_len, dev->VolHdr.VolName);
+           stop++;
            break;
         case SOS_LABEL:
            unser_session_label(&label, rec);
@@ -1174,13 +1029,22 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
  *   not it is full. If the tape fills, attempt to
  *   acquire another tape.
  */
-static int flush_block(DEV_BLOCK *block)
+static int flush_block(DEV_BLOCK *block, int dump)
 {
    char ec1[50];
    lock_device(dev);
    if (!write_block_to_dev(dev, block)) {
-      Pmsg2(000, "Doing fixup device error. FileIndex=%u Block=%u\n", 
-        (unsigned)file_index, block->BlockNumber);
+      Pmsg0(000, strerror_dev(dev));           
+      Pmsg3(000, "Block not written: FileIndex=%u Block=%u Size=%u\n", 
+        (unsigned)file_index, block->BlockNumber, block->block_len);
+      if (dump) {
+         dump_block(block, "Block not written");
+      }
+      if (!stop) {
+        eot_block = block->BlockNumber;
+        eot_block_len = block->block_len;
+        eot_FileIndex = file_index;
+      }
       now = time(NULL);
       now -= jcr->run_time;
       if (now <= 0) {
@@ -1196,7 +1060,6 @@ static int flush_block(DEV_BLOCK *block)
         unlock_device(dev);
         return 0;
       }
-      Pmsg1(000, "Changed tapes. Block=%u\n", block->BlockNumber);
       stop = 1;                                                    
       unlock_device(dev);
       return 1;     /* write one more block to next tape then stop */
@@ -1212,7 +1075,6 @@ static struct cmdstruct commands[] = {
  {"bsr",        bsrcmd,       "backspace record"},
  {"cap",        capcmd,       "list device capabilities"},
  {"clear",      clearcmd,     "clear tape errors"},
- {"device",     devicecmd,    "specify the tape device name"},
  {"eod",        eodcmd,       "go to end of Bacula data for append"},
  {"test",       testcmd,      "General test Bacula tape functions"},
  {"eom",        eomcmd,       "go to the physical end of medium"},
@@ -1325,6 +1187,7 @@ int       dir_send_job_status(JCR *jcr) {return 1;}
 
 int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev)
 {
+   Pmsg0(000, dev->errmsg);          /* print reason */
    fprintf(stderr, "Mount Volume \"%s\" on device %s and press return when ready: ",
       jcr->VolumeName, dev_name(dev));
    getchar();  
index 323e714ec86037460671703cef540d05ebbb2254..68b2b9365fa4ded13838646d960f7580c6e33a4d 100644 (file)
@@ -32,6 +32,8 @@
 #include "bacula.h"
 #include "stored.h"
 
+/* Imported variables -- eliminate some day */
+extern char *configfile;
 
 #ifdef DEBUG
 char *rec_state_to_str(DEV_RECORD *rec)
@@ -62,13 +64,16 @@ char *rec_state_to_str(DEV_RECORD *rec)
 
 
 /*
- * Setup device, jcr, and prepare to read
+ * Setup device, jcr, and prepare to access device.
+ *   If the caller wants read access, acquire the device, otherwise,
+ *     the caller will do it.
  */
-DEVICE *setup_to_read_device(JCR *jcr)
+DEVICE *setup_to_access_device(JCR *jcr, int read_access)
 {
    DEVICE *dev;
    DEV_BLOCK *block;
    char *p;
+   DEVRES *device;
 
    jcr->VolumeName[0] = 0;
    if (strncmp(jcr->dev_name, "/dev/", 5) != 0) {
@@ -82,12 +87,17 @@ DEVICE *setup_to_read_device(JCR *jcr)
       }
    }
 
-   dev = init_dev(NULL, jcr->dev_name);
+   if ((device=find_device_res(jcr->dev_name)) == NULL) {
+      Emsg2(M_FATAL, 0, "Cannot find device %s in config file %s.\n", 
+          jcr->dev_name, configfile);
+      return NULL;
+   }
+   
+   dev = init_dev(NULL, device);
    if (!dev) {
       Emsg1(M_FATAL, 0, "Cannot open %s\n", jcr->dev_name);
       return NULL;
    }
-   /* ***FIXME**** init capabilities */
    if (!open_device(dev)) {
       Emsg1(M_FATAL, 0, "Cannot open %s\n", jcr->dev_name);
       return NULL;
@@ -99,17 +109,79 @@ DEVICE *setup_to_read_device(JCR *jcr)
    create_vol_list(jcr);
 
    Dmsg1(100, "Volume=%s\n", jcr->VolumeName);
-   if (!acquire_device_for_read(jcr, dev, block)) {
-      Emsg0(M_ERROR, 0, dev->errmsg);
-      return NULL;
+   if (read_access) {
+      if (!acquire_device_for_read(jcr, dev, block)) {
+        Emsg0(M_ERROR, 0, dev->errmsg);
+        return NULL;
+      }
    }
    free_block(block);
    return dev;
 }
 
 
+/*
+ * Search for device resource that corresponds to 
+ * device name on command line (or default).
+ *      
+ * Returns: NULL on failure
+ *         Device resource pointer on success
+ */
+DEVRES *find_device_res(char *device_name)
+{
+   int found = 0;
+   DEVRES *device;
+
+   LockRes();
+   for (device=NULL; (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) {
+      if (strcmp(device->device_name, device_name) == 0) {
+        found = 1;
+        break;
+      }
+   } 
+   UnlockRes();
+   if (!found) {
+      Pmsg2(0, "Could not find device %s in config file %s.\n", device_name,
+           configfile);
+      return NULL;
+   }
+   Pmsg1(0, "Using device: %s\n", device_name);
+   return device;
+}
+
+
+
+/*
+ * Called here when freeing JCR so that we can get rid 
+ *  of "daemon" specific memory allocated.
+ */
 static void my_free_jcr(JCR *jcr)
 {
+   if (jcr->pool_name) {
+      free_pool_memory(jcr->pool_name);
+      jcr->pool_name = NULL;
+   }
+   if (jcr->pool_type) {
+      free_pool_memory(jcr->pool_type);
+      jcr->pool_type = NULL;
+   }
+   if (jcr->job_name) {
+      free_pool_memory(jcr->job_name);
+      jcr->job_name = NULL;
+   }
+   if (jcr->client_name) {
+      free_pool_memory(jcr->client_name);
+      jcr->client_name = NULL;
+   }
+   if (jcr->fileset_name) {
+      free_pool_memory(jcr->fileset_name);
+      jcr->fileset_name = NULL;
+   }
+   if (jcr->dev_name) {
+      free_pool_memory(jcr->dev_name);
+      jcr->dev_name = NULL;
+   }
+     
    return;
 }
 
@@ -123,9 +195,24 @@ JCR *setup_jcr(char *name, char *device, BSR *bsr)
    jcr->VolSessionId = 1;
    jcr->VolSessionTime = (uint32_t)time(NULL);
    jcr->bsr = bsr;
+   jcr->NumVolumes = 1;
+   jcr->pool_name = get_pool_memory(PM_FNAME);
+   strcpy(jcr->pool_name, "Default");
+   jcr->pool_type = get_pool_memory(PM_FNAME);
+   strcpy(jcr->pool_type, "Backup");
+   jcr->job_name = get_pool_memory(PM_FNAME);
+   strcpy(jcr->job_name, "Dummy.Job.Name");
+   jcr->client_name = get_pool_memory(PM_FNAME);
+   strcpy(jcr->client_name, "Dummy.Client.Name");
    strcpy(jcr->Job, name);
+   jcr->fileset_name = get_pool_memory(PM_FNAME);
+   strcpy(jcr->fileset_name, "Dummy.fileset.name");
+   jcr->JobId = 1;
+   jcr->JobType = JT_BACKUP;
+   jcr->JobLevel = L_FULL;
+   jcr->JobStatus = JS_Terminated;
    jcr->dev_name = get_pool_memory(PM_FNAME);
-   strcpy(jcr->dev_name, device);
+   pm_strcpy(&jcr->dev_name, device);
    return jcr;
 }
 
index 1ed4cf398bf727cdd8c071eb91303e6dc4904035..6a9ab69d1e10d93c5e52b9ea4e656ca29d79db6d 100644 (file)
@@ -95,24 +95,25 @@ extern int debug_level;
  * thus we neither allocate it nor free it. This allows
  * the caller to put the packet in shared memory.
  *
- *  Note, for a tape, the dev_name is the device name
+ *  Note, for a tape, the device->device_name is the device name
  *     (e.g. /dev/nst0), and for a file, the device name
  *     is the directory in which the file will be placed.
  *
  */
 DEVICE *
-init_dev(DEVICE *dev, char *dev_name)
+init_dev(DEVICE *dev, DEVRES *device)
 {
    struct stat statp;
    int tape;
    int errstat;
 
    /* Check that device is available */
-   if (stat(dev_name, &statp) < 0) {
+   if (stat(device->device_name, &statp) < 0) {
       if (dev) {
         dev->dev_errno = errno;
       } 
-      Emsg2(M_FATAL, 0, "Unable to stat device %s : %s\n", dev_name, strerror(errno));
+      Emsg2(M_FATAL, 0, "Unable to stat device %s : %s\n", device->device_name, 
+           strerror(errno));
       return NULL;
    }
    tape = FALSE;
@@ -138,19 +139,26 @@ init_dev(DEVICE *dev, char *dev_name)
    if (tape) {
       dev->state |= ST_TAPE;
    }
-   dev->dev_name = get_memory(strlen(dev_name)+1);
-   strcpy(dev->dev_name, dev_name);
+
+   /* Copy user supplied device parameters from Resource */
+   dev->dev_name = get_memory(strlen(device->device_name)+1);
+   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;
+   dev->max_volume_jobs = device->max_volume_jobs;
+   dev->max_volume_files = device->max_volume_files;
+   dev->max_volume_size = device->max_volume_size;
+   dev->max_file_size = device->max_file_size;
+   dev->volume_capacity = device->volume_capacity;
+   dev->max_rewind_wait = device->max_rewind_wait;
+   dev->max_open_wait = device->max_open_wait;
+   dev->device = device;
+
 
    dev->errmsg = get_pool_memory(PM_EMSG);
    *dev->errmsg = 0;
 
-#ifdef NEW_LOCK
-   if ((errstat=rwl_init(&dev->lock)) != 0) {
-      Mmsg1(&dev->errmsg, _("Unable to initialize dev lock. ERR=%s\n"), strerror(errstat));
-      Emsg0(M_FATAL, 0, dev->errmsg);
-   }
-#endif
-
    if ((errstat = pthread_mutex_init(&dev->mutex, NULL)) != 0) {
       dev->dev_errno = errstat;
       Mmsg1(&dev->errmsg, _("Unable to init mutex: ERR=%s\n"), strerror(errstat));
@@ -289,7 +297,7 @@ int rewind_dev(DEVICE *dev)
    }
    dev->state &= ~(ST_APPEND|ST_READ|ST_EOT | ST_EOF | ST_WEOT);  /* remove EOF/EOT flags */
    dev->block_num = dev->file = 0;
-   dev->file_bytes = 0;
+   dev->file_addr = 0;
    if (dev->state & ST_TAPE) {
       mt_com.mt_op = MTREW;
       mt_com.mt_count = 1;
@@ -344,7 +352,7 @@ eod_dev(DEVICE *dev)
    }
    dev->state &= ~(ST_EOF);  /* remove EOF flags */
    dev->block_num = dev->file = 0;
-   dev->file_bytes = 0;
+   dev->file_addr = 0;
    if (!(dev->state & ST_TAPE)) {
       pos = lseek(dev->fd, (off_t)0, SEEK_END);
 //    Dmsg1(000, "====== Seek to %lld\n", pos);
@@ -418,7 +426,7 @@ int update_pos_dev(DEVICE *dev)
    /* Find out where we are */
    if (!(dev->state & ST_TAPE)) {
       dev->file = 0;
-      dev->file_bytes = 0;
+      dev->file_addr = 0;
       pos = lseek(dev->fd, (off_t)0, SEEK_CUR);
       if (pos < 0) {
          Dmsg1(000, "Seek error: ERR=%s\n", strerror(dev->dev_errno));
@@ -427,7 +435,7 @@ int update_pos_dev(DEVICE *dev)
            dev->dev_name, strerror(dev->dev_errno));
       } else {
         stat = 1;
-        dev->file_bytes = pos;
+        dev->file_addr = pos;
       }
       return stat;
    }
@@ -559,7 +567,7 @@ int load_dev(DEVICE *dev)
 #else
 
    dev->block_num = dev->file = 0;
-   dev->file_bytes = 0;
+   dev->file_addr = 0;
    mt_com.mt_op = MTLOAD;
    mt_com.mt_count = 1;
    if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
@@ -591,7 +599,7 @@ int offline_dev(DEVICE *dev)
    }
 
    dev->block_num = dev->file = 0;
-   dev->file_bytes = 0;
+   dev->file_addr = 0;
 #ifdef MTUNLOCK
    mt_com.mt_op = MTUNLOCK;
    mt_com.mt_count = 1;
@@ -672,7 +680,7 @@ fsf_dev(DEVICE *dev, int num)
            } else {
               dev->state |= ST_EOF;
               dev->file++;
-              dev->file_bytes = 0;
+              dev->file_addr = 0;
               continue;
            }
         } else {                        /* Got data */
@@ -692,7 +700,7 @@ fsf_dev(DEVICE *dev, int num)
         } else {
            dev->state |= ST_EOF;     /* just read EOF */
            dev->file++;
-           dev->file_bytes = 0;
+           dev->file_addr = 0;
         }   
       }
    
@@ -744,7 +752,7 @@ bsf_dev(DEVICE *dev, int num)
    Dmsg0(29, "bsf_dev\n");
    dev->state &= ~(ST_EOT|ST_EOF);
    dev->file -= num;
-   dev->file_bytes = 0;
+   dev->file_addr = 0;
    mt_com.mt_op = MTBSF;
    mt_com.mt_count = num;
    stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
@@ -790,7 +798,7 @@ fsr_dev(DEVICE *dev, int num)
       } else {
         dev->state |= ST_EOF;           /* assume EOF */
         dev->file++;
-        dev->file_bytes = 0;
+        dev->file_addr = 0;
       }
       clrerror_dev(dev, MTFSR);
       Mmsg2(&dev->errmsg, _("ioctl MTFSR error on %s. ERR=%s.\n"),
@@ -863,7 +871,7 @@ weof_dev(DEVICE *dev, int num)
    stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
    if (stat == 0) {
       dev->file++;
-      dev->file_bytes = 0;
+      dev->file_addr = 0;
    } else {
       clrerror_dev(dev, MTWEOF);
       Mmsg2(&dev->errmsg, _("ioctl MTWEOF error on %s. ERR=%s.\n"),
@@ -972,7 +980,7 @@ static void do_close(DEVICE *dev)
    dev->state &= ~(ST_OPENED|ST_LABEL|ST_READ|ST_APPEND|ST_EOT|ST_WEOT|ST_EOF);
    dev->block_num = 0;
    dev->file = 0;
-   dev->file_bytes = 0;
+   dev->file_addr = 0;
    dev->LastBlockNumWritten = 0;
    memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo));
    memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
index 83e794c1b24f8e8dae03190aa68cd7f8253a1847..252b932ca4d97fb5db2d4ce556d263f5efe10676 100644 (file)
@@ -147,7 +147,7 @@ typedef struct s_device {
    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_bytes;               /* bytes in this file */
+   uint64_t file_addr;                /* Current file read/write address */
    uint32_t LastBlockNumWritten;      /* last block written */
    uint32_t min_block_size;           /* min block size */
    uint32_t max_block_size;           /* max block size */
index e4cfe076b7be7a303e5c8623ec4423ef7480ba84..794c32178644a6d64c3446bb253ecd45290d4f58 100644 (file)
@@ -92,8 +92,13 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
       Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
       for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
          Dmsg1(100, "create JobMedia for Job %s\n", mjcr->Job);
-        mjcr->EndBlock = dev->block_num;
-        mjcr->EndFile = dev->file;
+        if (dev->state & ST_TAPE) {
+           mjcr->EndBlock = dev->block_num;
+           mjcr->EndFile = dev->file;
+        } else {
+           mjcr->EndBlock = (uint32_t)dev->file_addr;
+           mjcr->EndFile = (uint32_t)(dev->file_addr >> 32);
+        }
         if (!dir_create_jobmedia_record(mjcr)) {
             Jmsg(mjcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=%s Job=%s\n"),
               dev->VolCatInfo.VolCatName, mjcr->Job);
@@ -165,8 +170,13 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
       free_block(label_blk);
       for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
         /* Set new start/end positions */
-        mjcr->StartBlock = dev->block_num;
-        mjcr->StartFile = dev->file;
+        if (dev->state & ST_TAPE) {
+           mjcr->StartBlock = dev->block_num;
+           mjcr->StartFile = dev->file;
+        } else {
+           mjcr->StartBlock = (uint32_t)dev->file_addr;
+           mjcr->StartFile  = (uint32_t)(dev->file_addr >> 32);
+        }
         mjcr->VolFirstFile = mjcr->JobFiles;
         mjcr->run_time += time(NULL) - wait_time; /* correct run time */
       }
index 8e9e01cb64c0fc2cd10467efb77c0932f7af582a..210f30b8b9606f0be89ba1eb3f92be11e9229cc0 100644 (file)
@@ -69,6 +69,7 @@ static int unmount_cmd(JCR *jcr);
 static int status_cmd(JCR *sjcr);
 static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *vname, char *poolname, 
                               int Slot);
+static void send_blocked_status(JCR *jcr, DEVICE *dev);
 
 struct s_cmds {
    char *cmd;
@@ -654,29 +655,7 @@ static int status_cmd(JCR *jcr)
            } else {
                bnet_fsend(user, _("Device %s open but no Bacula volume is mounted.\n"), dev_name(dev));
            }
-           switch (dev->dev_blocked) {
-              case BST_UNMOUNTED:
-                  bnet_fsend(user, _("    Deviced is blocked. User unmounted.\n"));
-                 break;
-              case BST_UNMOUNTED_WAITING_FOR_SYSOP:
-                  bnet_fsend(user, _("    Deviced is blocked. User unmounted during wait for media/mount.\n"));
-                 break;
-              case BST_WAITING_FOR_SYSOP:
-                 if (jcr->JobStatus == JS_WaitMount) {
-                     bnet_fsend(user, _("    Device is blocked waiting for mount.\n"));
-                 } else {
-                     bnet_fsend(user, _("    Device is blocked waiting for appendable media.\n"));
-                 }
-                 break;
-              case BST_DOING_ACQUIRE:
-                  bnet_fsend(user, _("    Device is being initialized.\n"));
-                 break;
-              case BST_WRITING_LABEL:
-                  bnet_fsend(user, _("    Device is blocked labeling a Volume.\n"));
-                 break;
-              default:
-                 break;
-           }
+           send_blocked_status(jcr, dev);
            bpb = dev->VolCatInfo.VolCatBlocks;
            if (bpb <= 0) {
               bpb = 1;
@@ -692,6 +671,7 @@ static int status_cmd(JCR *jcr)
 
         } else {
             bnet_fsend(user, _("Device %s is not open.\n"), dev_name(dev));
+           send_blocked_status(jcr, dev);
         }
       }
    }
@@ -745,3 +725,32 @@ static int status_cmd(JCR *jcr)
    bnet_sig(user, BNET_EOD);
    return 1;
 }
+
+static void send_blocked_status(JCR *jcr, DEVICE *dev) 
+{
+   BSOCK *user = jcr->dir_bsock;
+
+   switch (dev->dev_blocked) {
+      case BST_UNMOUNTED:
+         bnet_fsend(user, _("    Device is BLOCKED. User unmounted.\n"));
+        break;
+      case BST_UNMOUNTED_WAITING_FOR_SYSOP:
+         bnet_fsend(user, _("    Device is BLOCKED. User unmounted during wait for media/mount.\n"));
+        break;
+      case BST_WAITING_FOR_SYSOP:
+        if (jcr->JobStatus == JS_WaitMount) {
+            bnet_fsend(user, _("    Device is BLOCKED waiting for mount.\n"));
+        } else {
+            bnet_fsend(user, _("    Device is BLOCKED waiting for appendable media.\n"));
+        }
+        break;
+      case BST_DOING_ACQUIRE:
+         bnet_fsend(user, _("    Device is being initialized.\n"));
+        break;
+      case BST_WRITING_LABEL:
+         bnet_fsend(user, _("    Device is blocked labeling a Volume.\n"));
+        break;
+      default:
+        break;
+   }
+}
index c97203f7be19f32861889f2702269442e2ec1984..3de4d1c69ab1a0be7b9f1143600ecbd99b80a4a0 100644 (file)
@@ -38,7 +38,7 @@ static int use_device_cmd(JCR *jcr);
 
 /* Requests from the Director daemon */
 static char jobcmd[]     = "JobId=%d job=%127s job_name=%127s client_name=%127s \
-type=%d level=%d FileSet=%127s NoAttr=%d SpoolAttr=%d\n";
+type=%d level=%d FileSet=%127s NoAttr=%d SpoolAttr=%d FileSetMD5=%127s\n";
 static char use_device[] = "use device=%s media_type=%s pool_name=%s pool_type=%s\n";
 
 /* Responses sent to Director daemon */
@@ -65,7 +65,7 @@ int job_cmd(JCR *jcr)
    int JobId, errstat;
    char auth_key[100];
    BSOCK *dir = jcr->dir_bsock;
-   POOLMEM *job_name, *client_name, *job, *fileset_name;
+   POOLMEM *job_name, *client_name, *job, *fileset_name, *fileset_md5;
    int JobType, level, spool_attributes, no_attributes;
    struct timeval tv;
    struct timezone tz;
@@ -80,15 +80,17 @@ int job_cmd(JCR *jcr)
    job_name = get_memory(dir->msglen);
    client_name = get_memory(dir->msglen);
    fileset_name = get_memory(dir->msglen);
+   fileset_md5 = get_memory(dir->msglen);
    if (sscanf(dir->msg, jobcmd, &JobId, job, job_name, client_name,
              &JobType, &level, fileset_name, &no_attributes,
-             &spool_attributes) != 9) {
+             &spool_attributes, fileset_md5) != 10) {
       bnet_fsend(dir, BAD_job, dir->msg);
       Emsg1(M_FATAL, 0, _("Bad Job Command from Director: %s\n"), dir->msg);
       free_memory(job);
       free_memory(job_name);
       free_memory(client_name);
       free_memory(fileset_name);
+      free_memory(fileset_md5);
       jcr->JobStatus = JS_ErrorTerminated;
       return 0;
    }
@@ -109,10 +111,13 @@ int job_cmd(JCR *jcr)
    jcr->JobLevel = level;
    jcr->no_attributes = no_attributes;
    jcr->spool_attributes = spool_attributes;
+   jcr->fileset_md5 = get_memory(strlen(fileset_md5) + 1);
+   strcpy(jcr->fileset_md5, fileset_md5);
    free_memory(job);
    free_memory(job_name);
    free_memory(client_name);
    free_memory(fileset_name);
+   free_memory(fileset_md5);
 
    /* Initialize FD start condition variable */
    if ((errstat = pthread_cond_init(&jcr->job_start_wait, NULL)) != 0) {
@@ -339,6 +344,9 @@ void stored_free_jcr(JCR *jcr)
    if (jcr->fileset_name) {
       free_memory(jcr->fileset_name);
    }
+   if (jcr->fileset_md5) {
+      free_memory(jcr->fileset_md5);
+   }
    if (jcr->bsr) {
       free_bsr(jcr->bsr);
       jcr->bsr = NULL;
index 92a34507ff29e88010f393936ec15f5a1c581d0c..137ea73e24b4b7e68fa36570adb5c0e464c3efad 100644 (file)
@@ -104,7 +104,8 @@ because:\n   %s"), dev_name(dev), strerror_dev(dev));
    } else if (!unser_volume_label(dev, record)) {
       Mmsg(&jcr->errmsg, _("Could not unserialize Volume label: %s\n"),
         strerror_dev(dev));
-   } else if (strcmp(dev->VolHdr.Id, BaculaId) != 0) {
+   } else if (strcmp(dev->VolHdr.Id, BaculaId) != 0 && 
+             strcmp(dev->VolHdr.Id, OldBaculaId) != 0) {
       Mmsg(&jcr->errmsg, _("Volume Header Id bad: %s\n"), dev->VolHdr.Id);
    } else {
       ok = 1;
@@ -179,7 +180,8 @@ int unser_volume_label(DEVICE *dev, DEV_RECORD *rec)
 
    if (rec->FileIndex != VOL_LABEL && rec->FileIndex != PRE_LABEL) {
       Mmsg3(&dev->errmsg, _("Expecting Volume Label, got FI=%s Stream=%s len=%d\n"), 
-             FI_to_ascii(rec->FileIndex), stream_to_ascii(rec->Stream), 
+             FI_to_ascii(rec->FileIndex), 
+             stream_to_ascii(rec->Stream, rec->FileIndex),
              rec->data_len);
       return 0;
    }
@@ -280,15 +282,15 @@ static void create_volume_label_record(JCR *jcr, DEVICE *dev, DEV_RECORD *rec)
       Fld(write_date) = 0;
       Fld(write_time) = 0;
    } else {
-   ser_float64(Fld(label_date));
-   ser_float64(Fld(label_time));
-   get_current_time(&dt);
-   Fld(write_date) = dt.julian_day_number;
-   Fld(write_time) = dt.julian_day_fraction;
+      /* OLD WAY DEPRECATED */
+      ser_float64(Fld(label_date));
+      ser_float64(Fld(label_time));
+      get_current_time(&dt);
+      Fld(write_date) = dt.julian_day_number;
+      Fld(write_time) = dt.julian_day_fraction;
    }
-
-   ser_float64(Fld(write_date));   /* unused if VerNum >= 11 */
-   ser_float64(Fld(write_time));   /* unused if VerNum >= 11 */
+   ser_float64(Fld(write_date));   /* 0 if VerNum >= 11 */
+   ser_float64(Fld(write_time));   /* 0  if VerNum >= 11 */
 
    ser_string(Fld(VolName));
    ser_string(Fld(PrevVolName));
@@ -347,9 +349,10 @@ static int create_volume_label(DEVICE *dev, char *VolName)
       dev->VolHdr.label_date = 0;
       dev->VolHdr.label_time = 0;
    } else {
-   get_current_time(&dt);
-   dev->VolHdr.label_date = dt.julian_day_number;
-   dev->VolHdr.label_time = dt.julian_day_fraction;
+      /* OLD WAY DEPRECATED */
+      get_current_time(&dt);
+      dev->VolHdr.label_date = dt.julian_day_number;
+      dev->VolHdr.label_time = dt.julian_day_fraction;
    }
 
    strcpy(dev->VolHdr.LabelProg, my_name);
@@ -453,6 +456,7 @@ void create_session_label(JCR *jcr, DEV_RECORD *rec, int label)
       ser_btime(get_current_btime());
       ser_float64(0);
    } else {
+      /* OLD WAY DEPRECATED */
       get_current_time(&dt);
       ser_float64(dt.julian_day_number);
       ser_float64(dt.julian_day_fraction);
@@ -468,6 +472,9 @@ void create_session_label(JCR *jcr, DEV_RECORD *rec, int label)
    ser_string(jcr->fileset_name);
    ser_uint32(jcr->JobType);
    ser_uint32(jcr->JobLevel);
+   if (BaculaTapeVersion >= 11) {
+      ser_string(jcr->fileset_md5);
+   }
 
    if (label == EOS_LABEL) {
       ser_uint32(jcr->JobFiles);
@@ -498,12 +505,22 @@ int write_session_label(JCR *jcr, DEV_BLOCK *block, int label)
    Dmsg1(90, "session_label record=%x\n", rec);
    switch (label) {
       case SOS_LABEL:
-        jcr->StartBlock = dev->block_num;
-        jcr->StartFile  = dev->file;
+        if (dev->state & ST_TAPE) {
+           jcr->StartBlock = dev->block_num;
+           jcr->StartFile  = dev->file;
+        } else {
+           jcr->StartBlock = (uint32_t)dev->file_addr;
+           jcr->StartFile = (uint32_t)(dev->file_addr >> 32);
+        }
         break;
       case EOS_LABEL:
-        jcr->EndBlock = dev->block_num;
-        jcr->EndFile = dev->file;
+        if (dev->state & ST_TAPE) {
+           jcr->EndBlock = dev->block_num;
+           jcr->EndFile  = dev->file;
+        } else {
+           jcr->EndBlock = (uint32_t)dev->file_addr;
+           jcr->EndFile = (uint32_t)(dev->file_addr >> 32);
+        }
         break;
       default:
          Jmsg1(jcr, M_ABORT, 0, _("Bad session label = %d\n"), label);
@@ -539,7 +556,7 @@ int write_session_label(JCR *jcr, DEV_BLOCK *block, int label)
    Dmsg6(20, "Write sesson_label record JobId=%d FI=%s SessId=%d Strm=%s len=%d\n\
 remainder=%d\n", jcr->JobId,
       FI_to_ascii(rec->FileIndex), rec->VolSessionId, 
-      stream_to_ascii(rec->Stream), rec->data_len,
+      stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len,
       rec->remainder);
 
    free_record(rec);
@@ -604,7 +621,7 @@ HostName          : %s\n\
 
    if (dev->VolHdr.VerNum >= 11) {
       char dt[50];
-      bstrftime(dt, sizeof(dt), (time_t)dev->VolHdr.label_btime);
+      bstrftime(dt, sizeof(dt), btime_to_etime(dev->VolHdr.label_btime));
       Pmsg1(-1, "Date label written: %s\n", dt);
    } else {
    dt.julian_day_number   = dev->VolHdr.label_date;
@@ -643,6 +660,9 @@ int unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec)
       unser_uint32(label->JobType);
       unser_uint32(label->JobLevel);
    }
+   if (label->VerNum >= 11) {
+      unser_string(label->FileSetMD5);
+   }
    if (rec->FileIndex == EOS_LABEL) {
       unser_uint32(label->JobFiles);
       unser_uint64(label->JobBytes);
@@ -714,7 +734,7 @@ JobStatus         : %c\n\
    }
    if (label.VerNum >= 11) {
       char dt[50];
-      bstrftime(dt, sizeof(dt), (time_t)label.write_btime);
+      bstrftime(dt, sizeof(dt), btime_to_etime(label.write_btime));
       Pmsg1(-1, _("Date written      : %s\n"), dt);
    } else {
    dt.julian_day_number   = label.write_date;
index 33b01fc8cf2c74d0ba0ffa97620fcd4ea050f2ec..52dc067d079c4d234fda26f4ec5bfb5c6d41ae2a 100644 (file)
@@ -162,9 +162,9 @@ read_volume:
            break;                    /* got it */
         case VOL_NAME_ERROR:
             Dmsg1(500, "Vol NAME Error Name=%s\n", jcr->VolumeName);
-           /* Check if we can accept this as an anonymous volume */
+           /* Check if this is a valid Volume in the pool */
            strcpy(jcr->VolumeName, dev->VolHdr.VolName);
-           if (!dev->capabilities & CAP_ANONVOLS || !dir_get_volume_info(jcr, 1)) {
+           if (!dir_get_volume_info(jcr, 1)) {
               goto mount_next_vol;
            }
             Dmsg1(200, "want new name=%s\n", jcr->VolumeName);
index 46720315de1a41e1197fd33c3eafd4b31f35f0b6..d8cc8fd3d8658e7d75f6d340414b4f5242be2900 100644 (file)
@@ -57,15 +57,16 @@ int write_block_to_dev(DEVICE *dev, DEV_BLOCK *block);
 int    read_block_from_device(DEVICE *dev, DEV_BLOCK *block);
 int    read_block_from_dev(DEVICE *dev, DEV_BLOCK *block);
 
-/* From butil.c */
-void print_ls_output(char *fname, char *link, int type, struct stat *statp);
-JCR *setup_jcr(char *name, char *device, BSR *bsr); 
-DEVICE *setup_to_read_device(JCR *jcr);
-void display_error_status(DEVICE *dev);
+/* From butil.c -- utilities for SD tool programs */
+void   print_ls_output(char *fname, char *link, int type, struct stat *statp);
+JCR    *setup_jcr(char *name, char *device, BSR *bsr); 
+DEVICE *setup_to_access_device(JCR *jcr, int read_access);
+void   display_error_status(DEVICE *dev);
+DEVRES *find_device_res(char *device_name);
 
 
 /* From dev.c */
-DEVICE *init_dev(DEVICE *dev, char *device);
+DEVICE *init_dev(DEVICE *dev, DEVRES *device);
 int     open_dev(DEVICE *dev, char *VolName, int mode);
 void    close_dev(DEVICE *dev);
 void    force_close_dev(DEVICE *dev);
@@ -164,7 +165,7 @@ extern void create_vol_list(JCR *jcr);
 
 /* From record.c */
 char   *FI_to_ascii(int fi);
-char   *stream_to_ascii(int stream);
+char   *stream_to_ascii(int stream, int fi);
 int    write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
 int    can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
 int    read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec); 
index 90f508be80764801a10a190cd396213477973997..f747da67c20e22cfddad114a64f45d380894747b 100644 (file)
@@ -133,7 +133,8 @@ next_record:
         }
         if (debug_level >= 30) {
             Dmsg4(30, "VolSId=%ld FI=%s Strm=%s Size=%ld\n", rec->VolSessionId,
-                 FI_to_ascii(rec->FileIndex), stream_to_ascii(rec->Stream), 
+                 FI_to_ascii(rec->FileIndex), 
+                 stream_to_ascii(rec->Stream, rec->FileIndex), 
                  rec->data_len);
         }
 
index 991cc7ad9c062b703a32d8c9f6729fe2dd40a9f3..410daa54f55ed3b65e967bd4b58150ae02c23058 100644 (file)
@@ -3,6 +3,7 @@
  *   record.c -- tape record handling functions
  *
  *             Kern Sibbald, April MMI
+ *               added BB02 format October MMII
  *
  *   Version $Id$
  *
@@ -58,6 +59,9 @@ char *FI_to_ascii(int fi)
       return "SOS_LABEL";
    case EOS_LABEL:
       return "EOS_LABEL";
+   case EOT_LABEL:
+      return "EOT_LABEL";
+      break;
    default:
      sprintf(buf, "unknown: %d", fi);
      return buf;
@@ -68,10 +72,21 @@ char *FI_to_ascii(int fi)
 /* 
  * Convert a Stream ID into a printable
  * ASCII string.  Not reentrant.
+
+ * A negative stream number represents
+ *   stream data that is continued from a
+ *   record in the previous block.
+ * If the FileIndex is negative, we are
+ *   dealing with a Label, hence the
+ *   stream is the JobId.
  */
-char *stream_to_ascii(int stream)
+char *stream_to_ascii(int stream, int fi)
 {
     static char buf[20];
+    if (fi < 0) {
+       sprintf(buf, "%d", stream);
+       return buf;     
+    }
     switch (stream) {
     case STREAM_UNIX_ATTRIBUTES:
        return "UATTR";
@@ -81,6 +96,34 @@ char *stream_to_ascii(int stream)
        return "MD5";
     case STREAM_GZIP_DATA:
        return "GZIP";
+    case STREAM_WIN32_ATTRIBUTES:
+       return "WIN32-ATTR";
+    case STREAM_SPARSE_DATA:
+       return "SPARSE-DATA";
+    case STREAM_SPARSE_GZIP_DATA:
+       return "SPARSE-GZIP";
+    case STREAM_PROGRAM_NAMES:
+       return "PROG-NAMES";
+    case STREAM_PROGRAM_DATA:
+       return "PROG-DATA";
+    case -STREAM_UNIX_ATTRIBUTES:
+       return "contUATTR";
+    case -STREAM_FILE_DATA:
+       return "contDATA";
+    case -STREAM_MD5_SIGNATURE:
+       return "contMD5";
+    case -STREAM_GZIP_DATA:
+       return "contGZIP";
+    case -STREAM_WIN32_ATTRIBUTES:
+       return "contWIN32-ATTR";
+    case -STREAM_SPARSE_DATA:
+       return "contSPARSE-DATA";
+    case -STREAM_SPARSE_GZIP_DATA:
+       return "contSPARSE-GZIP";
+    case -STREAM_PROGRAM_NAMES:
+       return "contPROG-NAMES";
+    case -STREAM_PROGRAM_DATA:
+       return "contPROG-DATA";
     default:
        sprintf(buf, "%d", stream);
        return buf;     
@@ -144,7 +187,7 @@ int write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec)
    Dmsg6(190, "write_record_to_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->data_len,
+      stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len,
       remlen, rec->remainder);
 
    /*
@@ -182,8 +225,8 @@ rem=%d remainder=%d\n",
        * time. Presumably we have a new buffer (possibly 
        * containing a volume label), so the new header 
        * should be able to fit in the block -- otherwise we have
-       * an error.  Note, we may have to continue splitting the
-       * data record though.
+       * an error.  Note, we have to continue splitting the
+       * data record if it is longer than the block.
        * 
        * First, write the header, then write as much as 
        * possible of the data record.
@@ -237,12 +280,13 @@ rem=%d remainder=%d\n",
       } else {
         memcpy(block->bufp, rec->data+rec->data_len-rec->remainder, 
                remlen);
+#ifdef SMCHECK
         if (!sm_check_rtn(__FILE__, __LINE__, False)) {
            /* We damaged a buffer */
             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->data_len,
+              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",
               block->bufp, block->binbuf, block->buf_len, block->buf_len-block->binbuf,
@@ -252,6 +296,7 @@ rem=%d remainder=%d\n",
 
                Emsg0(M_ABORT, 0, "Damaged buffer\n");
         }
+#endif
 
         block->bufp += remlen;
         block->binbuf += remlen;
@@ -383,7 +428,8 @@ int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
       Dmsg6(100, "rd_rec_blk() got FI=%s SessId=%d Strm=%s len=%u\n\
 remlen=%d data_len=%d\n",
         FI_to_ascii(rec->FileIndex), rec->VolSessionId, 
-        stream_to_ascii(rec->Stream), data_bytes, remlen, rec->data_len);
+        stream_to_ascii(rec->Stream, rec->FileIndex), data_bytes, remlen, 
+        rec->data_len);
    } else {
       /*    
        * No more records in this block because the number   
@@ -436,6 +482,6 @@ remlen=%d data_len=%d\n",
    rec->remainder = 0;
    Dmsg4(90, "Rtn full rd_rec_blk FI=%s SessId=%d Strm=%s len=%d\n",
       FI_to_ascii(rec->FileIndex), rec->VolSessionId, 
-      stream_to_ascii(rec->Stream), rec->data_len);
+      stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len);
    return 1;                         /* transferred full record */
 }
index 2f300b1e6eac93164900a9854d1ccf52dbeb1aec..4c52729f3a10b9f5eae34de4df26b32ec5afd1f1 100644 (file)
 #define __RECORD_H 1
 
 /* Return codes from read_device_volume_label() */
-#define VOL_NOT_READ      0               /* Volume label not read */
-#define VOL_OK            1               /* volume name OK */
-#define VOL_NO_LABEL      2               /* volume not labeled */
-#define VOL_IO_ERROR      3               /* volume I/O error */
-#define VOL_NAME_ERROR    4               /* Volume name mismatch */
-#define VOL_CREATE_ERROR  5               /* Error creating label */
-#define VOL_VERSION_ERROR 6               /* Bacula version error */
-#define VOL_LABEL_ERROR   7               /* Bad label type */
+#define VOL_NOT_READ     0               /* Volume label not read */
+#define VOL_OK           1               /* volume name OK */
+#define VOL_NO_LABEL     2               /* volume not labeled */
+#define VOL_IO_ERROR     3               /* volume I/O error */
+#define VOL_NAME_ERROR   4               /* Volume name mismatch */
+#define VOL_CREATE_ERROR  5              /* Error creating label */
+#define VOL_VERSION_ERROR 6              /* Bacula version error */
+#define VOL_LABEL_ERROR   7              /* Bad label type */
 
 
 /*  See block.h for RECHDR_LENGTH */
  */
 
 /* Record state bit definitions */
-#define REC_NO_HEADER        0x01     /* No header read */
+#define REC_NO_HEADER       0x01     /* No header read */
 #define REC_PARTIAL_RECORD   0x02     /* returning partial record */
 #define REC_BLOCK_EMPTY      0x04     /* not enough data in block */
-#define REC_NO_MATCH         0x08     /* No match on continuation data */
+#define REC_NO_MATCH        0x08     /* No match on continuation data */
 #define REC_CONTINUATION     0x10     /* Continuation record found */
 
 #define is_partial_record(r) ((r)->state & REC_PARTIAL_RECORD)
  *  This is the memory structure for the record header.
  */
 typedef struct s_dev_rec {
-   int      sync;                     /* synchronous */
+   int     sync;                     /* synchronous */
    /* File and Block are always returned on reading records, but
     *  only returned on writing if sync is set (obviously).
     */
-   uint32_t File;                     /* File number */
-   uint32_t Block;                    /* Block number */
-   uint32_t VolSessionId;             /* sequential id within this session */
-   uint32_t VolSessionTime;           /* session start time */
-   int32_t  FileIndex;                /* sequential file number */
-   int32_t  Stream;                   /* stream number */
-   uint32_t data_len;                 /* current record length */
-   uint32_t remainder;                /* remaining bytes to read/write */
-   uint32_t state;                    /* state bits */
+   uint32_t File;                    /* File number */
+   uint32_t Block;                   /* Block number */
+   uint32_t VolSessionId;            /* sequential id within this session */
+   uint32_t VolSessionTime;          /* session start time */
+   int32_t  FileIndex;               /* sequential file number */
+   int32_t  Stream;                  /* stream number */
+   uint32_t data_len;                /* current record length */
+   uint32_t remainder;               /* remaining bytes to read/write */
+   uint32_t state;                   /* state bits */
    uint8_t  ser_buf[WRITE_RECHDR_LENGTH];   /* serialized record header goes here */
-   POOLMEM *data;                     /* Record data. This MUST be a memory pool item */
+   POOLMEM *data;                    /* Record data. This MUST be a memory pool item */
 } DEV_RECORD;
 
 
@@ -99,12 +99,12 @@ typedef struct s_dev_rec {
  * Note, these values are negative to distinguish them
  * from user records where the FileIndex is forced positive.
  */
-#define PRE_LABEL   -1                /* Vol label on unwritten tape */
-#define VOL_LABEL   -2                /* Volume label first file */
-#define EOM_LABEL   -3                /* Writen at end of tape */        
-#define SOS_LABEL   -4                /* Start of Session */
-#define EOS_LABEL   -5                /* End of Session */
-#define EOT_LABEL   -6                /* End of physical tape (2 eofs) */
+#define PRE_LABEL   -1               /* Vol label on unwritten tape */
+#define VOL_LABEL   -2               /* Volume label first file */
+#define EOM_LABEL   -3               /* Writen at end of tape */        
+#define SOS_LABEL   -4               /* Start of Session */
+#define EOS_LABEL   -5               /* End of Session */
+#define EOT_LABEL   -6               /* End of physical tape (2 eofs) */
 
 /* 
  *   Volume Label Record.  This is the in-memory definition. The
@@ -119,27 +119,27 @@ struct Volume_Label {
    * in the DEVICE buffer, but are not actually written
    * to the tape.
    */
-  int32_t LabelType;                  /* This is written in header only */
-  uint32_t LabelSize;                 /* length of serialized label */
+  int32_t LabelType;                 /* This is written in header only */
+  uint32_t LabelSize;                /* length of serialized label */
   /*
    * The items below this line are stored on 
    * the tape
    */
-  char Id[32];                        /* Bacula Immortal ... */
+  char Id[32];                       /* Bacula Immortal ... */
 
-  uint32_t VerNum;                    /* Label version number */
+  uint32_t VerNum;                   /* Label version number */
 
   /* VerNum <= 10 */
-  float64_t label_date;               /* Date tape labeled */
-  float64_t label_time;               /* Time tape labeled */
+  float64_t label_date;              /* Date tape labeled */
+  float64_t label_time;              /* Time tape labeled */
 
   /* VerNum >= 11 */
-  btime_t   label_btime;              /* tdate tape labeled */
-  btime_t   write_btime;              /* tdate tape written */
+  btime_t   label_btime;             /* tdate tape labeled */
+  btime_t   write_btime;             /* tdate tape written */
 
   /* Unused with VerNum >= 11 */
-  float64_t write_date;               /* Date this label written */
-  float64_t write_time;               /* Time this label written */
+  float64_t write_date;              /* Date this label written */
+  float64_t write_time;              /* Time this label written */
 
   char VolName[MAX_NAME_LENGTH];      /* Volume name */
   char PrevVolName[MAX_NAME_LENGTH];  /* Previous Volume Name */
@@ -148,9 +148,9 @@ struct Volume_Label {
   char MediaType[MAX_NAME_LENGTH];    /* Type of this media */
 
   char HostName[MAX_NAME_LENGTH];     /* Host name of writing computer */
-  char LabelProg[32];                 /* Label program name */
-  char ProgVersion[32];               /* Program version */
-  char ProgDate[32];                  /* Program build date/time */
+  char LabelProg[32];                /* Label program name */
+  char ProgVersion[32];              /* Program version */
+  char ProgDate[32];                 /* Program build date/time */
 };
 
 #define SER_LENGTH_Volume_Label 1024   /* max serialised length of volume label */
@@ -163,28 +163,29 @@ typedef struct Volume_Label VOLUME_LABEL;
  *  This record is at the beginning and end of each session
  */
 struct Session_Label {
-  char Id[32];                        /* Bacula Immortal ... */
+  char Id[32];                       /* Bacula Immortal ... */
 
-  uint32_t VerNum;                    /* Label version number */
+  uint32_t VerNum;                   /* Label version number */
 
-  uint32_t JobId;                     /* Job id */
-  uint32_t VolumeIndex;               /* Sequence no of volume for this job */
+  uint32_t JobId;                    /* Job id */
+  uint32_t VolumeIndex;              /* Sequence no of volume for this job */
 
   /* VerNum >= 11 */
-  btime_t   write_btime;              /* Tdate this label written */
+  btime_t   write_btime;             /* Tdate this label written */
 
   /* VerNum < 11 */
-  float64_t write_date;               /* Date this label written */
+  float64_t write_date;              /* Date this label written */
 
   /* Unused VerNum >= 11 */
-  float64_t write_time;               /* Time this label written */
+  float64_t write_time;              /* Time this label written */
 
   char PoolName[MAX_NAME_LENGTH];     /* Pool name */
   char PoolType[MAX_NAME_LENGTH];     /* Pool type */
   char JobName[MAX_NAME_LENGTH];      /* base Job name */
   char ClientName[MAX_NAME_LENGTH];
-  char Job[MAX_NAME_LENGTH];          /* Unique name of this Job */
+  char Job[MAX_NAME_LENGTH];         /* Unique name of this Job */
   char FileSetName[MAX_NAME_LENGTH];
+  char FileSetMD5[MAX_NAME_LENGTH];
   uint32_t JobType;
   uint32_t JobLevel;
   /* The remainder are part of EOS label only */
@@ -195,11 +196,11 @@ struct Session_Label {
   uint32_t StartFile;
   uint32_t EndFile;
   uint32_t JobErrors;
-  uint32_t JobStatus;                 /* Job status */
+  uint32_t JobStatus;                /* Job status */
 
 };
 typedef struct Session_Label SESSION_LABEL;
 
-#define SERIAL_BUFSIZE  1024          /* volume serialisation buffer size */
+#define SERIAL_BUFSIZE 1024          /* volume serialisation buffer size */
 
 #endif
index 43d21450342e6d7fb363e8e2de2ec48c6b3926a5..04571249b471d3c0b6808fe2a5dd232ec4dad770 100644 (file)
@@ -56,7 +56,7 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 static uint32_t VolSessionId = 0;
 uint32_t VolSessionTime;
 
-static char *configfile;
+char *configfile;
 static int foreground = 0;
 
 static workq_t dird_workq;           /* queue for processing connections */
@@ -201,21 +201,7 @@ int main (int argc, char *argv[])
          Emsg1(M_ABORT, 0, _("Too many Device Resources. Max=%d\n"), MAX_DEVICES);
       }
       Dmsg1(90, "calling init_dev %s\n", device->device_name);
-      device->dev = init_dev(&shm->dev[i], device->device_name);
-      /* Copy some attributes from the Device Resource to the DEV structure */
-      if (device->dev) {
-        device->dev->capabilities = device->cap_bits;
-        device->dev->min_block_size = device->min_block_size;
-        device->dev->max_block_size = device->max_block_size;
-        device->dev->max_volume_jobs = device->max_volume_jobs;
-        device->dev->max_volume_files = device->max_volume_files;
-        device->dev->max_volume_size = device->max_volume_size;
-        device->dev->max_file_size = device->max_file_size;
-        device->dev->volume_capacity = device->volume_capacity;
-        device->dev->max_rewind_wait = device->max_rewind_wait;
-        device->dev->max_open_wait = device->max_open_wait;
-        device->dev->device = device;
-      }
+      device->dev = init_dev(&shm->dev[i], 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);
index f98cf4297d199ffd08e1bbb97e583a2f5aa2a938..7182fdc22c59ccfcdc5cbbe7fb40e6925030499d 100644 (file)
@@ -13,6 +13,7 @@ static int max_file_len = 0;
 static int max_path_len = 0;
 static int trunc_fname = 0;
 static int trunc_path = 0;
+static int attrs = 0;
 
 
 static int print_file(FF_PKT *ff, void *pkt);
@@ -46,8 +47,12 @@ main (int argc, char *const *argv)
    char name[1000];
    int i, ch;
 
-   while ((ch = getopt(argc, argv, "d:?")) != -1) {
+   while ((ch = getopt(argc, argv, "ad:?")) != -1) {
       switch (ch) {
+         case 'a':                    /* print extended attributes *debug* */
+           attrs = 1;
+           break;
+
          case 'd':                    /* set debug level */
            debug_level = atoi(optarg);
            if (debug_level <= 0) {
@@ -98,6 +103,7 @@ Paths truncated: %d\n"),
 
 static int print_file(FF_PKT *ff, void *pkt)
 {
+
    switch (ff->type) {
    case FT_LNKSAVED:
       if (debug_level == 1) {
@@ -174,6 +180,14 @@ static int print_file(FF_PKT *ff, void *pkt)
       printf(_("Err: Unknown file ff->type %d: %s\n"), ff->type, ff->fname);
       break;
    }
+   if (attrs) {
+      char attr[200];
+      encode_attribsEx(NULL, attr, ff);
+      if (*attr != 0) {
+         printf("AttrEx=%s\n", attr);
+      }
+      set_attribsEx(NULL, ff->fname, NULL, NULL, ff->type, attr);
+   }
    return 1;
 }
 
index d68602ab23a40495eb2a93bc97c087e33a6c006b..4c0c418203c2af5a1ff9e2c983d2faf1fd48699c 100644 (file)
@@ -1,8 +1,8 @@
 /* */
-#define VERSION "1.26"
+#define VERSION "1.27"
 #define VSTRING "1"
-#define DATE    "10 October 2002"
-#define LSMDATE "10Oct02"
+#define DATE    "22 October 2002"
+#define LSMDATE "22Oct02"
 
 /* Debug flags */
 #define DEBUG 1