+2002-05-10 Release 1.19
+- Allow the user to select a new period for pruning.
+- Lots of additions to the manual -- prune and purge
+ commands documented.
+- Applied Phil's configure.in fix for --prefix, ...
+- Fixed bug found by Phil (patch supplied) in updating
+ MD5 signatures (revert to 32 bit FileId, move "static"
+ variables into JCR) (catreq.c fd-cmds.c).
+- Reverted to using INTEGER for FileId in make_sql_tables
+ due to a bug in MySQL.
+- Change editing code to %d for FileId.
+- Remove sqlite in make distclean in cats directory.
+- Remove console.conf in console during make distclean.
+- Remove gnome-console.conf during make distclean.
+- Remove bacula-dir.conf during make distclean.
+- Set default level when using Console if none specified.
+ Bug reported by Phil.
+- A simple . command from Console is ignored.
+- Change program named from filed to bacual-fd in winmain.cpp
+- Change default config file for Win32 in winmain.cpp
+- Free namebuf on early return from find_one.c. Bug reported by Phil.
+- Modify testfind.c to dump orphaned buffers.
+- Removed terabytes from parse_conf.c because of problems with
+ older gcc compilers.
+- Turn off gnome options in gnome-console by constructing empty argv.
+- Fixes to Verify when only MD5 differs.
+- Insert 0 for MD5 as default rather than space.
+- Allow .messages "transparent" command while reading input
+ in UserAgent server.
+- In dird/verify.c ensure that correct filename is printed if only
+ the MD5 differs. Minor reindenting caused large diff.
+- Delete unused code from backup.c
+- In filed/verify.c ensure that same algorithm as backup.c is used
+ to pass back MD5 signatures -- especially for directories and files
+ that cannot be read. Change dummy filename from X to *MD5-id*.
+ This dummy value should never be printed.
+- Make gnome-console poll Director every 5 seconds for output.
+ This means that queued up messages are displayed at reasonable
+ intervals. Delete some unused code hanging around from the tty
+ console program.
+- Begin implementation of prune commands.
+- Add command line history to gnome-console. Not yet saved across sessions.
+- Fixed some broken URLs in the manual.
+- Added JobId type.
+- Wrote first cut of "prune files" and "prune jobs".
+- Added command line history to gnome-console 2500 lines max.
+- Widened store_time() and associated variables to 64 bits using
+ new btime_t definition.
+- Removed GNOME about box and replaced it with
+ a somewhat crude Gtk+ about box in the gnome-console.
+- Widened StartDay in the Job DB record to be 64 bits.
+- Changed edit_uint_ to edit_uint64_ everywhere. Much more
+ descriptive of what is done.
+- Removed most llds and replaced them with %s and edit_uint64.
+ This makes the code a bit easier to read for beginners.
+- Added a btime_t typedef which is 64 bits wide.
+- Added most of the code needed to do Purge and Prune of
+ database. Not yet tested. Please do not use.
+- Additional config options for Console.
+- Started adding code for Automatic Recycling of Volumes.
+- Allow arbitrary length filenames in Verify code.
+- Fix incorrect filename in Verify code.
+- Significant enhancement to number scanning in config parser.
+- Requires initializing MySQL tables, or applying cats/alter.sql
+ to modify Media table.
+- Modified Makefile to printer a much more visible
+ message if the make ends in error.
+- Added the Purge value to the VolStatus in the Media table.
+ This value is set if the Volume is purged.
+- Enhanced the db_delete_media_record() routine to delete
+ all associated records in the database.
+- Modified Console to always write to the variable "output"
+ rather than stdout. This will permit directing output to a file.
+- Enhanced the Console configuration file to have a Console
+ resource. This will allow us to add an rcfile and history file.
+- Modified Find_next_vol in catreq.c to search for "Recycle"
+ volumes if there are none marked Append. Also made Get_Vol_info
+ return the VolStatus to the Storage daemon.
+- Allow upper/lower case match on job level names.
+- Added another warning message to the Console "delete media" command.
+- Corrected a number of FileId types from uint64_t to FileId_t in
+ ua_retention.c.
+- In ua server close database before freeing JCR (because pointer is
+ kept in ua and jcr structures).
+- parse all numbers as doubles. Do lots of checking for valid number
+ formats. Allow numbers in scientific form (e.g. 1.5e+10).
+- Remove terabyte modifier as it doesn't work in some compilers.
+- Fix bug in handling some modifiers.
+- Added all necessary code for Recycle to Storage daemon. A Volume
+ marked Recycle will now be overwritten.
+- Filled out the prune command a bit and did some testing.
+- Make console accept redirected input.
+- Altered the Table definitions to include Recycle,
+ FileRetention, JobRetention, and AutoPrune.
+- Widened StartDay to 64 bits.
+- Use JobId_t in more places.
+- Added the new table fields to the database record definitions.
+- Changed Recycle from string to a binary quantity.
+- Added a Version table with a VersionId to detect.
+ future changes in the database. This should prevent
+ a Bacula from working with a database that is not in sync.
+- Modify Console to accept input from a file. This will permit
+ the .read command and allow reading a .rc file.
+- Added new retention and recycle variables to the Director's configuration.
+- The UA subroutines or commands can now be called from core
+ code because the output routines detect the absence of a
+ UA socket and direct output to the Job.
+- Added a verbose flage to the ua packet to permit reduction of
+ output while running a UA command (prune) from a Job.
+- Did a fair amount of work on the prune command. Prune Volume now works.
+- Purge Volume now works.
+- Made last changes for integrating prune and purge commands.
+- Add -ltermcap to CONS_LIBS when readline is configured.
+ More work to be done to search for termcap.
+- Added cats/drop_sqlite_tables.in, which will delete the SQLite database.
+- Got CWEB working so that we can compile filesys.w and immortal.w
+- Modified depkgs to include cweb.
+- Note, CWEB is not yet used by the core Bacula code.
+- Made cats/alter.sql, which alters an old database to bring it
+ up to the new format. This only works with MySQL since SQLite does
+ not have the ALTER SQL command.
+- Changed the old StartDay field in the db to be JobTDate, which is
+ the latest time/date in widened Unix time format that the Job ran.
+ This value is used when doing pruning.
+- Added code in cats/sql.c to verify that the database internal version
+ corresponds to the db version compiled in Bacula. It is set to 1 currently.
+- Lots of changes to cats to bring the SQL up to date with the new
+ retention period changes.
+- Added Console command code to permit changing a Volume's retention period.
+- Removed old code that used date_encode() and replaced it with widened
+ Unix time().
+- Started modifying Message resource scanner so that we can have multiple
+ message resources. Much more work to be done.
+- Moved scanning for time into new library routine string_to_btime().
2002-04-22 Release 1.18
- Applied Phil's configure.in fix for --prefix, ...
#
+# $Id$
#
@MCOMMON@
all: Makefile
@for I in ${subdirs}; \
- do (cd $$I; echo "==>Entering directory `pwd`"; $(MAKE) $@ || exit 1); done
+ do (cd $$I; echo "==>Entering directory `pwd`"; \
+ $(MAKE) $@ || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \
+ echo ""; echo "";)); \
+ done
depend:
@for I in ${subdirs}; \
bacula-fd: Makefile
@for I in ${FDsubdirs}; \
- do (cd $$I; echo "==>Entering directory `pwd`"; $(MAKE) all || exit 1); done
+ do (cd $$I; echo "==>Entering directory `pwd`"; \
+ $(MAKE) all || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \
+ echo ""; echo "";)); \
+ done
#-------------------------------------------------------------------------
configure: autoconf/configure.in autoconf/aclocal.m4 autoconf/acconfig.h autoconf/config.h.in
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
-/* Define if you have the <termcap.h> header file. */
-#undef HAVE_TERMCAP_H
-
-/* Define if you have the <termio.h> header file. */
-#undef HAVE_TERMIO_H
-
/* Define if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
AC_CHECK_HEADER($with_readline/readline.h,
[ AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_READLINE)
- CONS_LIBS="-lreadline"
+ CONS_LIBS="-lreadline -ltermcap"
got_readline="yes"
],
[ AC_MSG_ERROR([*** readline library missing])
AC_DEFINE(HAVE_READLINE)
got_readline="yes"
CONS_INC="-I/usr/include/readline"
- CONS_LIBS="-lreadline"
+ CONS_LIBS="-lreadline -ltermcap"
], [
# Did not find starndard library, so user our own
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_READLINE)
got_readline="yes"
CONS_INC="-I${TOP_DIR}/depkgs"
- CONS_LIBS="-lreadline -lhistory"
+ CONS_LIBS="-lreadline -lhistory -ltermcap"
CONS_LDFLAGS="-L${TOP_DIR}/depkgs/readline"
READLINE_SRC="${TOP_DIR}/depkgs/readline"
])
AC_FUNC_STRCOLL
AC_CHECK_HEADERS(varargs.h \
- sys/ptem.h sys/pte.h sys/stream.h \
- termcap.h termio.h )
-
-TERMCAP_LIB=-ltermcap
-AC_SUBST(TERMCAP_LIB)
-
+ sys/ptem.h sys/pte.h sys/stream.h)
# End of readline stuff
# -----------------------------------------------------------------------
# Check for CWEB support/directory
# ---------------------------------------------------
CWEB_SRC=
+CWEB=/bin
local_cweb="no"
AC_ARG_WITH(cweb,
[ --with-cweb[=DIR] Specify cweb library directory],
AC_DEFINE(HAVE_CWEB)
got_cweb="yes"
local_cweb="yes"
+ CWEB=${TOP_DIR}/depkgs/cweb
CWEB_INC="-I${TOP_DIR}/depkgs/cweb"
CWEB_LIBS="-lcweb"
CWEB_LDFLAGS="-L${TOP_DIR}/depkgs/cweb"
])
]
)
+AC_SUBST(CWEB)
AC_SUBST(CWEB_INC)
AC_SUBST(CWEB_LIBS)
AC_SUBST(CWEB_LDFLAGS)
src/cats/create_mysql_database \
src/cats/grant_mysql_privileges \
src/cats/make_sqlite_tables \
+ src/cats/drop_sqlite_tables \
src/cats/sqlite \
src/findlib/Makefile \
$PFILES ],
chmod 755 src/cats/make_test_tables src/cats/drop_test_tables
chmod 755 src/cats/create_mysql_database
chmod 755 src/cats/grant_mysql_privileges
-chmod 755 src/cats/make_sqlite_tables
+chmod 755 src/cats/make_sqlite_tables src/cats/drop_sqlite_tables
chmod 755 src/cats/sqlite
#define HAVE_READLINE 1
EOF
- CONS_LIBS="-lreadline"
+ CONS_LIBS="-lreadline -ltermcap"
got_readline="yes"
else
got_readline="yes"
CONS_INC="-I/usr/include/readline"
- CONS_LIBS="-lreadline"
+ CONS_LIBS="-lreadline -ltermcap"
else
echo "$ac_t""no" 1>&6
got_readline="yes"
CONS_INC="-I${TOP_DIR}/depkgs"
- CONS_LIBS="-lreadline -lhistory"
+ CONS_LIBS="-lreadline -lhistory -ltermcap"
CONS_LDFLAGS="-L${TOP_DIR}/depkgs/readline"
READLINE_SRC="${TOP_DIR}/depkgs/readline"
for ac_hdr in varargs.h \
- sys/ptem.h sys/pte.h sys/stream.h \
- termcap.h termio.h
+ sys/ptem.h sys/pte.h sys/stream.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:3111: checking for $ac_hdr" >&5
+echo "configure:3110: 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 3116 "configure"
+#line 3115 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3121: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3120: \"$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*
echo "$ac_t""no" 1>&6
fi
done
-
-
-TERMCAP_LIB=-ltermcap
-
-
+
# End of readline stuff
# -----------------------------------------------------------------------
fi
ac_safe=`echo "$with_gmp/gmp.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $with_gmp/gmp.h""... $ac_c" 1>&6
-echo "configure:3177: checking for $with_gmp/gmp.h" >&5
+echo "configure:3172: checking for $with_gmp/gmp.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 3182 "configure"
+#line 3177 "configure"
#include "confdefs.h"
#include <$with_gmp/gmp.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3187: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3182: \"$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*
# check for standard gmp library
ac_safe=`echo "/usr/include/gmp.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for /usr/include/gmp.h""... $ac_c" 1>&6
-echo "configure:3226: checking for /usr/include/gmp.h" >&5
+echo "configure:3221: checking for /usr/include/gmp.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 3231 "configure"
+#line 3226 "configure"
#include "confdefs.h"
#include </usr/include/gmp.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3236: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3231: \"$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*
# Check for CWEB support/directory
# ---------------------------------------------------
CWEB_SRC=
+CWEB=/bin
local_cweb="no"
# Check whether --with-cweb or --without-cweb was given.
if test "${with_cweb+set}" = set; then
fi
ac_safe=`echo "$with_cweb/cweb.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $with_cweb/cweb.h""... $ac_c" 1>&6
-echo "configure:3313: checking for $with_cweb/cweb.h" >&5
+echo "configure:3309: checking for $with_cweb/cweb.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 3318 "configure"
+#line 3314 "configure"
#include "confdefs.h"
#include <$with_cweb/cweb.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3323: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3319: \"$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*
# check for standard cweb library
ac_safe=`echo "/usr/include/cweb.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for /usr/include/cweb.h""... $ac_c" 1>&6
-echo "configure:3362: checking for /usr/include/cweb.h" >&5
+echo "configure:3358: checking for /usr/include/cweb.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 3367 "configure"
+#line 3363 "configure"
#include "confdefs.h"
#include </usr/include/cweb.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3372: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3368: \"$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*
got_cweb="yes"
local_cweb="yes"
+ CWEB=${TOP_DIR}/depkgs/cweb
CWEB_INC="-I${TOP_DIR}/depkgs/cweb"
CWEB_LIBS="-lcweb"
CWEB_LDFLAGS="-L${TOP_DIR}/depkgs/cweb"
+
# End of CWEB stuff
# -----------------------------------------------------------------------
saved_LIBS="$LIBS"
LIBS="$LIBS -lwrap -lnsl"
echo $ac_n "checking for libwrap""... $ac_c" 1>&6
-echo "configure:3441: checking for libwrap" >&5
+echo "configure:3439: checking for libwrap" >&5
cat > conftest.$ac_ext <<EOF
-#line 3443 "configure"
+#line 3441 "configure"
#include "confdefs.h"
#include <tcpd.h>
int deny_severity = 0;
hosts_access(req);
; return 0; }
EOF
-if { (eval echo configure:3453: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3451: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
echo "$ac_t""yes" 1>&6
have_db=no
db_name=none
echo $ac_n "checking for MySQL support""... $ac_c" 1>&6
-echo "configure:3720: checking for MySQL support" >&5
+echo "configure:3718: checking for MySQL support" >&5
# Check whether --with-mysql or --without-mysql was given.
if test "${with_mysql+set}" = set; then
withval="$with_mysql"
have_db=no
db_name=none
echo $ac_n "checking for SQLite support""... $ac_c" 1>&6
-echo "configure:3802: checking for SQLite support" >&5
+echo "configure:3800: checking for SQLite support" >&5
# Check whether --with-sqlite or --without-sqlite was given.
if test "${with_sqlite+set}" = set; then
withval="$with_sqlite"
echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
-echo "configure:3875: checking for mingw32 environment" >&5
+echo "configure:3873: checking for mingw32 environment" >&5
if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3880 "configure"
+#line 3878 "configure"
#include "confdefs.h"
int main() {
return __MINGW32__;
; return 0; }
EOF
-if { (eval echo configure:3887: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3885: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_mingw32=yes
else
echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:3906: checking for executable suffix" >&5
+echo "configure:3904: checking for executable suffix" >&5
if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
rm -f conftest*
echo 'int main () { return 0; }' > conftest.$ac_ext
ac_cv_exeext=
- if { (eval echo configure:3916: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ if { (eval echo configure:3914: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
for file in conftest.*; do
case $file in
*.c | *.o | *.obj) ;;
# 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:3944: checking for X" >&5
+echo "configure:3942: checking for X" >&5
# Check whether --with-x or --without-x was given.
if test "${with_x+set}" = set; then
# First, try using that file with no special directory specified.
cat > conftest.$ac_ext <<EOF
-#line 4006 "configure"
+#line 4004 "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:4011: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4009: \"$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*
ac_save_LIBS="$LIBS"
LIBS="-l$x_direct_test_library $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4080 "configure"
+#line 4078 "configure"
#include "confdefs.h"
int main() {
${x_direct_test_function}()
; return 0; }
EOF
-if { (eval echo configure:4087: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4085: \"$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.
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:4193: checking whether -R must be followed by a space" >&5
+echo "configure:4191: 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 4196 "configure"
+#line 4194 "configure"
#include "confdefs.h"
int main() {
; return 0; }
EOF
-if { (eval echo configure:4203: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4201: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_R_nospace=yes
else
else
LIBS="$ac_xsave_LIBS -R $x_libraries"
cat > conftest.$ac_ext <<EOF
-#line 4219 "configure"
+#line 4217 "configure"
#include "confdefs.h"
int main() {
; return 0; }
EOF
-if { (eval echo configure:4226: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4224: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_R_space=yes
else
# 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:4258: checking for dnet_ntoa in -ldnet" >&5
+echo "configure:4256: 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
ac_save_LIBS="$LIBS"
LIBS="-ldnet $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4266 "configure"
+#line 4264 "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
dnet_ntoa()
; return 0; }
EOF
-if { (eval echo configure:4277: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4275: \"$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
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:4299: checking for dnet_ntoa in -ldnet_stub" >&5
+echo "configure:4297: 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
ac_save_LIBS="$LIBS"
LIBS="-ldnet_stub $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4307 "configure"
+#line 4305 "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
dnet_ntoa()
; return 0; }
EOF
-if { (eval echo configure:4318: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4316: \"$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
# 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:4347: checking for gethostbyname" >&5
+echo "configure:4345: 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 4352 "configure"
+#line 4350 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char gethostbyname(); below. */
; return 0; }
EOF
-if { (eval echo configure:4375: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4373: \"$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
if test $ac_cv_func_gethostbyname = no; then
echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
-echo "configure:4396: checking for gethostbyname in -lnsl" >&5
+echo "configure:4394: 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
ac_save_LIBS="$LIBS"
LIBS="-lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4404 "configure"
+#line 4402 "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
gethostbyname()
; return 0; }
EOF
-if { (eval echo configure:4415: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4413: \"$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
# -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:4445: checking for connect" >&5
+echo "configure:4443: 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 4450 "configure"
+#line 4448 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char connect(); below. */
; return 0; }
EOF
-if { (eval echo configure:4473: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4471: \"$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
if test $ac_cv_func_connect = no; then
echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
-echo "configure:4494: checking for connect in -lsocket" >&5
+echo "configure:4492: 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
ac_save_LIBS="$LIBS"
LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4502 "configure"
+#line 4500 "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
connect()
; return 0; }
EOF
-if { (eval echo configure:4513: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4511: \"$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
# gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX.
echo $ac_n "checking for remove""... $ac_c" 1>&6
-echo "configure:4537: checking for remove" >&5
+echo "configure:4535: 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 4542 "configure"
+#line 4540 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char remove(); below. */
; return 0; }
EOF
-if { (eval echo configure:4565: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4563: \"$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
if test $ac_cv_func_remove = no; then
echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6
-echo "configure:4586: checking for remove in -lposix" >&5
+echo "configure:4584: 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
ac_save_LIBS="$LIBS"
LIBS="-lposix $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4594 "configure"
+#line 4592 "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
remove()
; return 0; }
EOF
-if { (eval echo configure:4605: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4603: \"$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
# BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
echo $ac_n "checking for shmat""... $ac_c" 1>&6
-echo "configure:4629: checking for shmat" >&5
+echo "configure:4627: 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 4634 "configure"
+#line 4632 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char shmat(); below. */
; return 0; }
EOF
-if { (eval echo configure:4657: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4655: \"$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
if test $ac_cv_func_shmat = no; then
echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6
-echo "configure:4678: checking for shmat in -lipc" >&5
+echo "configure:4676: 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
ac_save_LIBS="$LIBS"
LIBS="-lipc $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4686 "configure"
+#line 4684 "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
shmat()
; return 0; }
EOF
-if { (eval echo configure:4697: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4695: \"$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
# 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:4730: checking for IceConnectionNumber in -lICE" >&5
+echo "configure:4728: 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
ac_save_LIBS="$LIBS"
LIBS="-lICE $X_EXTRA_LIBS $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4738 "configure"
+#line 4736 "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
IceConnectionNumber()
; return 0; }
EOF
-if { (eval echo configure:4749: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4747: \"$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
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:4794: checking for $ac_hdr" >&5
+echo "configure:4792: 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 4799 "configure"
+#line 4797 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4804: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4802: \"$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*
done
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:4831: checking for ANSI C header files" >&5
+echo "configure:4829: 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 4836 "configure"
+#line 4834 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4844: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4842: \"$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*
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 4861 "configure"
+#line 4859 "configure"
#include "confdefs.h"
#include <string.h>
EOF
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 4879 "configure"
+#line 4877 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
:
else
cat > conftest.$ac_ext <<EOF
-#line 4900 "configure"
+#line 4898 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
exit (0); }
EOF
-if { (eval echo configure:4911: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4909: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
fi
echo $ac_n "checking whether sys/types.h defines makedev""... $ac_c" 1>&6
-echo "configure:4935: checking whether sys/types.h defines makedev" >&5
+echo "configure:4933: 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 4940 "configure"
+#line 4938 "configure"
#include "confdefs.h"
#include <sys/types.h>
int main() {
return makedev(0, 0);
; return 0; }
EOF
-if { (eval echo configure:4947: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4945: \"$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
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:4965: checking for sys/mkdev.h" >&5
+echo "configure:4963: 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 4970 "configure"
+#line 4968 "configure"
#include "confdefs.h"
#include <sys/mkdev.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4975: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4973: \"$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*
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:5003: checking for sys/sysmacros.h" >&5
+echo "configure:5001: 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 5008 "configure"
+#line 5006 "configure"
#include "confdefs.h"
#include <sys/sysmacros.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5013: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5011: \"$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*
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:5045: checking for $ac_hdr that defines DIR" >&5
+echo "configure:5043: 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 5050 "configure"
+#line 5048 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <$ac_hdr>
DIR *dirp = 0;
; return 0; }
EOF
-if { (eval echo configure:5058: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5056: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_header_dirent_$ac_safe=yes"
else
# 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:5083: checking for opendir in -ldir" >&5
+echo "configure:5081: 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
ac_save_LIBS="$LIBS"
LIBS="-ldir $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 5091 "configure"
+#line 5089 "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
opendir()
; return 0; }
EOF
-if { (eval echo configure:5102: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5100: \"$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
else
echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:5124: checking for opendir in -lx" >&5
+echo "configure:5122: 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
ac_save_LIBS="$LIBS"
LIBS="-lx $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 5132 "configure"
+#line 5130 "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
opendir()
; return 0; }
EOF
-if { (eval echo configure:5143: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5141: \"$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
fi
echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
-echo "configure:5166: checking whether stat file-mode macros are broken" >&5
+echo "configure:5164: 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 5171 "configure"
+#line 5169 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
fi
echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:5222: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo "configure:5220: 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 5227 "configure"
+#line 5225 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/wait.h>
s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
; return 0; }
EOF
-if { (eval echo configure:5243: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5241: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_sys_wait_h=yes
else
fi
echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:5264: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:5262: 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 5269 "configure"
+#line 5267 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
struct tm *tp;
; return 0; }
EOF
-if { (eval echo configure:5278: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5276: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_time=yes
else
fi
echo $ac_n "checking for st_blksize in struct stat""... $ac_c" 1>&6
-echo "configure:5299: checking for st_blksize in struct stat" >&5
+echo "configure:5297: 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 5304 "configure"
+#line 5302 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
struct stat s; s.st_blksize;
; return 0; }
EOF
-if { (eval echo configure:5312: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5310: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_st_blksize=yes
else
fi
echo $ac_n "checking for st_blocks in struct stat""... $ac_c" 1>&6
-echo "configure:5333: checking for st_blocks in struct stat" >&5
+echo "configure:5331: 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 5338 "configure"
+#line 5336 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
struct stat s; s.st_blocks;
; return 0; }
EOF
-if { (eval echo configure:5346: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5344: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_st_blocks=yes
else
fi
echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
-echo "configure:5369: checking whether struct tm is in sys/time.h or time.h" >&5
+echo "configure:5367: 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 5374 "configure"
+#line 5372 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <time.h>
struct tm *tp; tp->tm_sec;
; return 0; }
EOF
-if { (eval echo configure:5382: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5380: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_tm=time.h
else
fi
echo $ac_n "checking for tm_zone in struct tm""... $ac_c" 1>&6
-echo "configure:5403: checking for tm_zone in struct tm" >&5
+echo "configure:5401: 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 5408 "configure"
+#line 5406 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <$ac_cv_struct_tm>
struct tm tm; tm.tm_zone;
; return 0; }
EOF
-if { (eval echo configure:5416: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5414: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_tm_zone=yes
else
else
echo $ac_n "checking for tzname""... $ac_c" 1>&6
-echo "configure:5436: checking for tzname" >&5
+echo "configure:5434: 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 5441 "configure"
+#line 5439 "configure"
#include "confdefs.h"
#include <time.h>
#ifndef tzname /* For SGI. */
atoi(*tzname);
; return 0; }
EOF
-if { (eval echo configure:5451: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5449: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_var_tzname=yes
else
# 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:5478: checking for utime.h" >&5
+echo "configure:5476: 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 5483 "configure"
+#line 5481 "configure"
#include "confdefs.h"
#include <sys/types.h>
struct utimbuf foo
; return 0; }
EOF
-if { (eval echo configure:5492: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5490: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
tar_cv_header_utime_h=yes
else
echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:5511: checking for working const" >&5
+echo "configure:5509: 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 5516 "configure"
+#line 5514 "configure"
#include "confdefs.h"
int main() {
; return 0; }
EOF
-if { (eval echo configure:5565: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5563: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_const=yes
else
echo $ac_n "checking how to get filesystem type""... $ac_c" 1>&6
-echo "configure:5588: checking how to get filesystem type" >&5
+echo "configure:5586: checking how to get filesystem type" >&5
fstype=no
# The order of these tests is important.
cat > conftest.$ac_ext <<EOF
-#line 5592 "configure"
+#line 5590 "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:5598: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5596: \"$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*
rm -f conftest*
if test $fstype = no; then
cat > conftest.$ac_ext <<EOF
-#line 5614 "configure"
+#line 5612 "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:5620: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5618: \"$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*
fi
if test $fstype = no; then
cat > conftest.$ac_ext <<EOF
-#line 5637 "configure"
+#line 5635 "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:5643: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5641: \"$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*
fi
if test $fstype = no; then
cat > conftest.$ac_ext <<EOF
-#line 5660 "configure"
+#line 5658 "configure"
#include "confdefs.h"
#include <mntent.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5665: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5663: \"$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*
fi
if test $fstype = no; then
cat > conftest.$ac_ext <<EOF
-#line 5682 "configure"
+#line 5680 "configure"
#include "confdefs.h"
#include <sys/mount.h>
EOF
fi
if test $fstype = no; then
cat > conftest.$ac_ext <<EOF
-#line 5699 "configure"
+#line 5697 "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:5705: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5703: \"$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*
echo "$ac_t""$fstype" 1>&6
echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:5723: checking return type of signal handlers" >&5
+echo "configure:5721: 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 5728 "configure"
+#line 5726 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
int i;
; return 0; }
EOF
-if { (eval echo configure:5745: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5743: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_type_signal=void
else
echo $ac_n "checking for type of signal functions""... $ac_c" 1>&6
-echo "configure:5765: checking for type of signal functions" >&5
+echo "configure:5763: 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 5771 "configure"
+#line 5769 "configure"
#include "confdefs.h"
#include <signal.h>
int main() {
; return 0; }
EOF
-if { (eval echo configure:5784: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5782: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
bash_cv_signal_vintage=posix
else
rm -rf conftest*
cat > conftest.$ac_ext <<EOF
-#line 5793 "configure"
+#line 5791 "configure"
#include "confdefs.h"
#include <signal.h>
int main() {
; return 0; }
EOF
-if { (eval echo configure:5803: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5801: \"$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
rm -rf conftest*
cat > conftest.$ac_ext <<EOF
-#line 5812 "configure"
+#line 5810 "configure"
#include "confdefs.h"
#include <signal.h>
; return 0; }
EOF
-if { (eval echo configure:5825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5823: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
bash_cv_signal_vintage=svr3
else
fi
echo $ac_n "checking for mode_t""... $ac_c" 1>&6
-echo "configure:5864: checking for mode_t" >&5
+echo "configure:5862: 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 5869 "configure"
+#line 5867 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-echo "configure:5897: checking for uid_t in sys/types.h" >&5
+echo "configure:5895: 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 5902 "configure"
+#line 5900 "configure"
#include "confdefs.h"
#include <sys/types.h>
EOF
fi
echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:5931: checking for size_t" >&5
+echo "configure:5929: 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 5936 "configure"
+#line 5934 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:5964: checking for pid_t" >&5
+echo "configure:5962: 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 5969 "configure"
+#line 5967 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:5997: checking for off_t" >&5
+echo "configure:5995: 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 6002 "configure"
+#line 6000 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for ino_t""... $ac_c" 1>&6
-echo "configure:6030: checking for ino_t" >&5
+echo "configure:6028: 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 6035 "configure"
+#line 6033 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for dev_t""... $ac_c" 1>&6
-echo "configure:6063: checking for dev_t" >&5
+echo "configure:6061: 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 6068 "configure"
+#line 6066 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for daddr_t""... $ac_c" 1>&6
-echo "configure:6096: checking for daddr_t" >&5
+echo "configure:6094: 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 6101 "configure"
+#line 6099 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for major_t""... $ac_c" 1>&6
-echo "configure:6129: checking for major_t" >&5
+echo "configure:6127: 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 6134 "configure"
+#line 6132 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for minor_t""... $ac_c" 1>&6
-echo "configure:6162: checking for minor_t" >&5
+echo "configure:6160: 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 6167 "configure"
+#line 6165 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
-echo "configure:6195: checking for ssize_t" >&5
+echo "configure:6193: 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 6200 "configure"
+#line 6198 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for st_blocks in struct stat""... $ac_c" 1>&6
-echo "configure:6228: checking for st_blocks in struct stat" >&5
+echo "configure:6226: 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 6233 "configure"
+#line 6231 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
struct stat s; s.st_blocks;
; return 0; }
EOF
-if { (eval echo configure:6241: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6239: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_st_blocks=yes
else
fi
echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6
-echo "configure:6264: checking for st_rdev in struct stat" >&5
+echo "configure:6262: 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 6269 "configure"
+#line 6267 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
struct stat s; s.st_rdev;
; return 0; }
EOF
-if { (eval echo configure:6277: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6275: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_st_rdev=yes
else
fi
echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
-echo "configure:6298: checking whether struct tm is in sys/time.h or time.h" >&5
+echo "configure:6296: 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 6303 "configure"
+#line 6301 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <time.h>
struct tm *tp; tp->tm_sec;
; return 0; }
EOF
-if { (eval echo configure:6311: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6309: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_tm=time.h
else
fi
echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:6332: checking for working const" >&5
+echo "configure:6330: 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 6337 "configure"
+#line 6335 "configure"
#include "confdefs.h"
int main() {
; return 0; }
EOF
-if { (eval echo configure:6386: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6384: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_const=yes
else
echo $ac_n "checking size of char""... $ac_c" 1>&6
-echo "configure:6409: checking size of char" >&5
+echo "configure:6407: 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
ac_cv_sizeof_char=1
else
cat > conftest.$ac_ext <<EOF
-#line 6417 "configure"
+#line 6415 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
exit(0);
}
EOF
-if { (eval echo configure:6428: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6426: \"$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
echo $ac_n "checking size of short int""... $ac_c" 1>&6
-echo "configure:6448: checking size of short int" >&5
+echo "configure:6446: 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
ac_cv_sizeof_short_int=2
else
cat > conftest.$ac_ext <<EOF
-#line 6456 "configure"
+#line 6454 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
exit(0);
}
EOF
-if { (eval echo configure:6467: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6465: \"$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
echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:6487: checking size of int" >&5
+echo "configure:6485: 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
ac_cv_sizeof_int=4
else
cat > conftest.$ac_ext <<EOF
-#line 6495 "configure"
+#line 6493 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
exit(0);
}
EOF
-if { (eval echo configure:6506: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6504: \"$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
echo $ac_n "checking size of long int""... $ac_c" 1>&6
-echo "configure:6526: checking size of long int" >&5
+echo "configure:6524: 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
ac_cv_sizeof_long_int=4
else
cat > conftest.$ac_ext <<EOF
-#line 6534 "configure"
+#line 6532 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
exit(0);
}
EOF
-if { (eval echo configure:6545: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6543: \"$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
echo $ac_n "checking size of long long int""... $ac_c" 1>&6
-echo "configure:6565: checking size of long long int" >&5
+echo "configure:6563: 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
ac_cv_sizeof_long_long_int=8
else
cat > conftest.$ac_ext <<EOF
-#line 6573 "configure"
+#line 6571 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
exit(0);
}
EOF
-if { (eval echo configure:6584: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6582: \"$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
echo $ac_n "checking size of int *""... $ac_c" 1>&6
-echo "configure:6604: checking size of int *" >&5
+echo "configure:6602: 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
ac_cv_sizeof_int_p=4
else
cat > conftest.$ac_ext <<EOF
-#line 6612 "configure"
+#line 6610 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
exit(0);
}
EOF
-if { (eval echo configure:6623: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6621: \"$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
# Check for sys/types.h types
echo $ac_n "checking for u_int type""... $ac_c" 1>&6
-echo "configure:6645: checking for u_int type" >&5
+echo "configure:6643: 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 6651 "configure"
+#line 6649 "configure"
#include "confdefs.h"
#include <sys/types.h>
int main() {
u_int a; a = 1;
; return 0; }
EOF
-if { (eval echo configure:6658: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6656: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_u_int="yes"
else
fi
echo $ac_n "checking for intmax_t type""... $ac_c" 1>&6
-echo "configure:6682: checking for intmax_t type" >&5
+echo "configure:6680: 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 6688 "configure"
+#line 6686 "configure"
#include "confdefs.h"
#include <sys/types.h>
int main() {
intmax_t a; a = 1;
; return 0; }
EOF
-if { (eval echo configure:6695: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6693: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_intmax_t="yes"
else
rm -rf conftest*
cat > conftest.$ac_ext <<EOF
-#line 6704 "configure"
+#line 6702 "configure"
#include "confdefs.h"
#include <stdint.h>
int main() {
intmax_t a; a = 1;
; return 0; }
EOF
-if { (eval echo configure:6711: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6709: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_intmax_t="yes"
else
echo $ac_n "checking for u_intmax_t type""... $ac_c" 1>&6
-echo "configure:6741: checking for u_intmax_t type" >&5
+echo "configure:6739: 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 6747 "configure"
+#line 6745 "configure"
#include "confdefs.h"
#include <sys/types.h>
int main() {
u_intmax_t a; a = 1;
; return 0; }
EOF
-if { (eval echo configure:6754: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6752: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_u_intmax_t="yes"
else
rm -rf conftest*
cat > conftest.$ac_ext <<EOF
-#line 6763 "configure"
+#line 6761 "configure"
#include "confdefs.h"
#include <stdint.h>
int main() {
u_intmax_t a; a = 1;
; return 0; }
EOF
-if { (eval echo configure:6770: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6768: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_u_intmax_t="yes"
else
echo $ac_n "checking for intXX_t types""... $ac_c" 1>&6
-echo "configure:6799: checking for intXX_t types" >&5
+echo "configure:6797: 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 6805 "configure"
+#line 6803 "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:6812: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6810: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_intxx_t="yes"
else
fi
echo $ac_n "checking for int64_t type""... $ac_c" 1>&6
-echo "configure:6836: checking for int64_t type" >&5
+echo "configure:6834: 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 6842 "configure"
+#line 6840 "configure"
#include "confdefs.h"
#include <sys/types.h>
int main() {
int64_t a; a = 1;
; return 0; }
EOF
-if { (eval echo configure:6849: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6847: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_int64_t="yes"
else
fi
echo $ac_n "checking for u_intXX_t types""... $ac_c" 1>&6
-echo "configure:6873: checking for u_intXX_t types" >&5
+echo "configure:6871: 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 6879 "configure"
+#line 6877 "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:6886: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6884: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_u_intxx_t="yes"
else
fi
echo $ac_n "checking for u_int64_t types""... $ac_c" 1>&6
-echo "configure:6910: checking for u_int64_t types" >&5
+echo "configure:6908: 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 6916 "configure"
+#line 6914 "configure"
#include "confdefs.h"
#include <sys/types.h>
int main() {
u_int64_t a; a = 1;
; return 0; }
EOF
-if { (eval echo configure:6923: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6921: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_u_int64_t="yes"
else
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:6950: checking for intXX_t and u_intXX_t types in sys/bitypes.h" >&5
+echo "configure:6948: checking for intXX_t and u_intXX_t types in sys/bitypes.h" >&5
cat > conftest.$ac_ext <<EOF
-#line 6952 "configure"
+#line 6950 "configure"
#include "confdefs.h"
#include <sys/bitypes.h>
int main() {
a = b = c = e = f = g = 1;
; return 0; }
EOF
-if { (eval echo configure:6961: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6959: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
cat >> confdefs.h <<\EOF
#define HAVE_U_INTXX_T 1
if test -z "$have_u_intxx_t" ; then
echo $ac_n "checking for uintXX_t types""... $ac_c" 1>&6
-echo "configure:6988: checking for uintXX_t types" >&5
+echo "configure:6986: 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 6994 "configure"
+#line 6992 "configure"
#include "confdefs.h"
#include <sys/types.h>
int main() {
uint32_t c; a = b = c = 1;
; return 0; }
EOF
-if { (eval echo configure:7002: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7000: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_uintxx_t="yes"
else
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7042: checking for $ac_func" >&5
+echo "configure:7040: 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 7047 "configure"
+#line 7045 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:7070: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7068: \"$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
for ac_func in fchdir
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7100: checking for $ac_func" >&5
+echo "configure:7098: 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 7105 "configure"
+#line 7103 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:7128: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7126: \"$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
for ac_func in snprintf vsnprintf
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7159: checking for $ac_func" >&5
+echo "configure:7157: 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 7164 "configure"
+#line 7162 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:7187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7185: \"$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
for ac_func in localtime_r
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7215: checking for $ac_func" >&5
+echo "configure:7213: 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 7220 "configure"
+#line 7218 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:7243: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7241: \"$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
for ac_func in readdir_r
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7274: checking for $ac_func" >&5
+echo "configure:7272: 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 7279 "configure"
+#line 7277 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:7302: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7300: \"$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
# Find where sockets are (especially for Solaris)
echo $ac_n "checking for socket""... $ac_c" 1>&6
-echo "configure:7332: checking for socket" >&5
+echo "configure:7330: 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 7337 "configure"
+#line 7335 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char socket(); below. */
; return 0; }
EOF
-if { (eval echo configure:7360: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7358: \"$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
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for socket in -lxnet""... $ac_c" 1>&6
-echo "configure:7378: checking for socket in -lxnet" >&5
+echo "configure:7376: 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
ac_save_LIBS="$LIBS"
LIBS="-lxnet $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7386 "configure"
+#line 7384 "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
socket()
; return 0; }
EOF
-if { (eval echo configure:7397: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7395: \"$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
fi
echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6
-echo "configure:7425: checking for socket in -lsocket" >&5
+echo "configure:7423: 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
ac_save_LIBS="$LIBS"
LIBS="-lsocket $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7433 "configure"
+#line 7431 "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
socket()
; return 0; }
EOF
-if { (eval echo configure:7444: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7442: \"$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
fi
echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6
-echo "configure:7472: checking for socket in -linet" >&5
+echo "configure:7470: 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
ac_save_LIBS="$LIBS"
LIBS="-linet $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7480 "configure"
+#line 7478 "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
socket()
; return 0; }
EOF
-if { (eval echo configure:7491: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7489: \"$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
# If resolver functions are not in libc check for -lnsl or -lresolv.
echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
-echo "configure:7523: checking for gethostbyname" >&5
+echo "configure:7521: 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 7528 "configure"
+#line 7526 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char gethostbyname(); below. */
; return 0; }
EOF
-if { (eval echo configure:7551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7549: \"$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
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
-echo "configure:7569: checking for gethostbyname in -lnsl" >&5
+echo "configure:7567: 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
ac_save_LIBS="$LIBS"
LIBS="-lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7577 "configure"
+#line 7575 "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
gethostbyname()
; return 0; }
EOF
-if { (eval echo configure:7588: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7586: \"$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
fi
echo $ac_n "checking for gethostbyname in -lresolv""... $ac_c" 1>&6
-echo "configure:7616: checking for gethostbyname in -lresolv" >&5
+echo "configure:7614: checking for gethostbyname in -lresolv" >&5
ac_lib_var=`echo resolv'_'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
ac_save_LIBS="$LIBS"
LIBS="-lresolv $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7624 "configure"
+#line 7622 "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
gethostbyname()
; return 0; }
EOF
-if { (eval echo configure:7635: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7633: \"$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
echo $ac_n "checking for strftime""... $ac_c" 1>&6
-echo "configure:7667: checking for strftime" >&5
+echo "configure:7665: 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 7672 "configure"
+#line 7670 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char strftime(); below. */
; return 0; }
EOF
-if { (eval echo configure:7695: \"$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_strftime=yes"
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:7717: checking for strftime in -lintl" >&5
+echo "configure:7715: 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
ac_save_LIBS="$LIBS"
LIBS="-lintl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7725 "configure"
+#line 7723 "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
strftime()
; return 0; }
EOF
-if { (eval echo configure:7736: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7734: \"$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
fi
echo $ac_n "checking for vprintf""... $ac_c" 1>&6
-echo "configure:7763: checking for vprintf" >&5
+echo "configure:7761: 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 7768 "configure"
+#line 7766 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char vprintf(); below. */
; return 0; }
EOF
-if { (eval echo configure:7791: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7789: \"$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
if test "$ac_cv_func_vprintf" != yes; then
echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
-echo "configure:7815: checking for _doprnt" >&5
+echo "configure:7813: 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 7820 "configure"
+#line 7818 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char _doprnt(); below. */
; return 0; }
EOF
-if { (eval echo configure:7843: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7841: \"$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
# 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:7870: checking for working alloca.h" >&5
+echo "configure:7868: 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 7875 "configure"
+#line 7873 "configure"
#include "confdefs.h"
#include <alloca.h>
int main() {
char *p = alloca(2 * sizeof(int));
; return 0; }
EOF
-if { (eval echo configure:7882: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7880: \"$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
fi
echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:7903: checking for alloca" >&5
+echo "configure:7901: 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 7908 "configure"
+#line 7906 "configure"
#include "confdefs.h"
#ifdef __GNUC__
char *p = (char *) alloca(1);
; return 0; }
EOF
-if { (eval echo configure:7936: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7934: \"$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
echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:7968: checking whether alloca needs Cray hooks" >&5
+echo "configure:7966: 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 7973 "configure"
+#line 7971 "configure"
#include "confdefs.h"
#if defined(CRAY) && ! defined(CRAY2)
webecray
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:7998: checking for $ac_func" >&5
+echo "configure:7996: 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 8003 "configure"
+#line 8001 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:8026: \"$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_func_$ac_func=yes"
else
fi
echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:8053: checking stack direction for C alloca" >&5
+echo "configure:8051: 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
ac_cv_c_stack_direction=0
else
cat > conftest.$ac_ext <<EOF
-#line 8061 "configure"
+#line 8059 "configure"
#include "confdefs.h"
find_stack_direction ()
{
exit (find_stack_direction() < 0);
}
EOF
-if { (eval echo configure:8080: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8078: \"$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
# 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:8103: checking for getmntent in -lsun" >&5
+echo "configure:8101: 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
ac_save_LIBS="$LIBS"
LIBS="-lsun $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 8111 "configure"
+#line 8109 "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
getmntent()
; return 0; }
EOF
-if { (eval echo configure:8122: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8120: \"$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
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for getmntent in -lseq""... $ac_c" 1>&6
-echo "configure:8141: checking for getmntent in -lseq" >&5
+echo "configure:8139: 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
ac_save_LIBS="$LIBS"
LIBS="-lseq $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 8149 "configure"
+#line 8147 "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
getmntent()
; return 0; }
EOF
-if { (eval echo configure:8160: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8158: \"$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
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for getmntent in -lgen""... $ac_c" 1>&6
-echo "configure:8179: checking for getmntent in -lgen" >&5
+echo "configure:8177: 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
ac_save_LIBS="$LIBS"
LIBS="-lgen $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 8187 "configure"
+#line 8185 "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
getmntent()
; return 0; }
EOF
-if { (eval echo configure:8198: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8196: \"$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
fi
echo $ac_n "checking for getmntent""... $ac_c" 1>&6
-echo "configure:8223: checking for getmntent" >&5
+echo "configure:8221: 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 8228 "configure"
+#line 8226 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char getmntent(); below. */
; return 0; }
EOF
-if { (eval echo configure:8251: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8249: \"$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
fi
echo $ac_n "checking whether closedir returns void""... $ac_c" 1>&6
-echo "configure:8274: checking whether closedir returns void" >&5
+echo "configure:8272: 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
ac_cv_func_closedir_void=yes
else
cat > conftest.$ac_ext <<EOF
-#line 8282 "configure"
+#line 8280 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <$ac_header_dirent>
int closedir(); main() { exit(closedir(opendir(".")) != 0); }
EOF
-if { (eval echo configure:8288: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8286: \"$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
fi
echo $ac_n "checking whether setpgrp takes no argument""... $ac_c" 1>&6
-echo "configure:8311: checking whether setpgrp takes no argument" >&5
+echo "configure:8309: 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
{ echo "configure: error: cannot check setpgrp if cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 8319 "configure"
+#line 8317 "configure"
#include "confdefs.h"
#ifdef HAVE_UNISTD_H
}
EOF
-if { (eval echo configure:8339: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8337: \"$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
fi
echo $ac_n "checking for working fnmatch""... $ac_c" 1>&6
-echo "configure:8362: checking for working fnmatch" >&5
+echo "configure:8360: 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
ac_cv_func_fnmatch_works=no
else
cat > conftest.$ac_ext <<EOF
-#line 8373 "configure"
+#line 8371 "configure"
#include "confdefs.h"
main() { exit (fnmatch ("a*", "abc", 0) != 0); }
EOF
-if { (eval echo configure:8377: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8375: \"$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
echo $ac_n "checking for setlocale in -lxpg4""... $ac_c" 1>&6
-echo "configure:8402: checking for setlocale in -lxpg4" >&5
+echo "configure:8400: 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
ac_save_LIBS="$LIBS"
LIBS="-lxpg4 $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 8410 "configure"
+#line 8408 "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
setlocale()
; return 0; }
EOF
-if { (eval echo configure:8421: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8419: \"$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
echo $ac_n "checking for getpwnam in -lsun""... $ac_c" 1>&6
-echo "configure:8444: checking for getpwnam in -lsun" >&5
+echo "configure:8442: 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
ac_save_LIBS="$LIBS"
LIBS="-lsun $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 8452 "configure"
+#line 8450 "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
getpwnam()
; return 0; }
EOF
-if { (eval echo configure:8463: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8461: \"$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
fi
echo $ac_n "checking for deflate in -lz""... $ac_c" 1>&6
-echo "configure:8491: checking for deflate in -lz" >&5
+echo "configure:8489: 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
ac_save_LIBS="$LIBS"
LIBS="-lz $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 8499 "configure"
+#line 8497 "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
deflate()
; return 0; }
EOF
-if { (eval echo configure:8510: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8508: \"$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
PTHREAD_LIB=""
echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
-echo "configure:8537: checking for pthread_create in -lpthread" >&5
+echo "configure:8535: 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
ac_save_LIBS="$LIBS"
LIBS="-lpthread $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 8545 "configure"
+#line 8543 "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
pthread_create()
; return 0; }
EOF
-if { (eval echo configure:8556: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8554: \"$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
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for pthread_create in -lpthreads""... $ac_c" 1>&6
-echo "configure:8575: checking for pthread_create in -lpthreads" >&5
+echo "configure:8573: 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
ac_save_LIBS="$LIBS"
LIBS="-lpthreads $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 8583 "configure"
+#line 8581 "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
pthread_create()
; return 0; }
EOF
-if { (eval echo configure:8594: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8592: \"$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
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for pthread_create in -lc_r""... $ac_c" 1>&6
-echo "configure:8613: checking for pthread_create in -lc_r" >&5
+echo "configure:8611: 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
ac_save_LIBS="$LIBS"
LIBS="-lc_r $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 8621 "configure"
+#line 8619 "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
pthread_create()
; return 0; }
EOF
-if { (eval echo configure:8632: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8630: \"$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
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for pthread_create""... $ac_c" 1>&6
-echo "configure:8651: checking for pthread_create" >&5
+echo "configure:8649: 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 8656 "configure"
+#line 8654 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char pthread_create(); below. */
; return 0; }
EOF
-if { (eval echo configure:8679: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8677: \"$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
src/cats/create_mysql_database \
src/cats/grant_mysql_privileges \
src/cats/make_sqlite_tables \
+ src/cats/drop_sqlite_tables \
src/cats/sqlite \
src/findlib/Makefile \
$PFILES src/config.h:autoconf/config.h.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
s%@CONS_LIBS@%$CONS_LIBS%g
s%@CONS_LDFLAGS@%$CONS_LDFLAGS%g
s%@READLINE_SRC@%$READLINE_SRC%g
-s%@TERMCAP_LIB@%$TERMCAP_LIB%g
s%@GMP_INC@%$GMP_INC%g
s%@GMP_LIBS@%$GMP_LIBS%g
s%@GMP_LDFLAGS@%$GMP_LDFLAGS%g
s%@GMP_SRC@%$GMP_SRC%g
+s%@CWEB@%$CWEB%g
s%@CWEB_INC@%$CWEB_INC%g
s%@CWEB_LIBS@%$CWEB_LIBS%g
s%@CWEB_LDFLAGS@%$CWEB_LDFLAGS%g
src/cats/create_mysql_database \
src/cats/grant_mysql_privileges \
src/cats/make_sqlite_tables \
+ src/cats/drop_sqlite_tables \
src/cats/sqlite \
src/findlib/Makefile \
$PFILES "}
chmod 755 src/cats/make_test_tables src/cats/drop_test_tables
chmod 755 src/cats/create_mysql_database
chmod 755 src/cats/grant_mysql_privileges
-chmod 755 src/cats/make_sqlite_tables
+chmod 755 src/cats/make_sqlite_tables src/cats/drop_sqlite_tables
chmod 755 src/cats/sqlite
#define uint64_t u_int64_t
#define uintmax_t u_intmax_t
+#define btime_t uint64_t
+
#ifdef HAVE_CYGWIN
#define socklen_t int
#endif
len = sizeof(mr);
while (fread(&mr, len, 1, mdb->mediafd) > 0) {
Mmsg(&mdb->cmd, " %-10s %17s %-15s %s\n",
- mr.VolStatus, edit_uint_with_commas(mr.VolBytes, ewc),
+ mr.VolStatus, edit_uint64_with_commas(mr.VolBytes, ewc),
mr.MediaType, mr.VolumeName);
sendit(ctx, mdb->cmd);
}
strftime(dt, sizeof(dt), "%m-%d %H:%M", &tm);
Mmsg(&mdb->cmd, " %7d %-10s %c %c %14s %10s %c %s\n",
ojr.JobId, dt, (char)ojr.Type, (char)ojr.Level,
- edit_uint_with_commas(ojr.JobBytes, ewc1),
- edit_uint_with_commas(ojr.JobFiles, ewc2),
+ edit_uint64_with_commas(ojr.JobBytes, ewc1),
+ edit_uint64_with_commas(ojr.JobFiles, ewc2),
(char)ojr.JobStatus, ojr.Name);
sendit(ctx, mdb->cmd);
}
total_jobs++;
}
Mmsg(&mdb->cmd, " %7s %10s %15s\n",
- edit_uint_with_commas(total_jobs, ewc1),
- edit_uint_with_commas(total_files, ewc2),
- edit_uint_with_commas(total_bytes, ewc3));
+ edit_uint64_with_commas(total_jobs, ewc1),
+ edit_uint64_with_commas(total_files, ewc2),
+ edit_uint64_with_commas(total_bytes, ewc3));
sendit(ctx, mdb->cmd);
sendit(ctx, "=======================================\n");
V(mdb->mutex);
* system.
*
* Kern Sibbald, January MMI
+ *
+ * $Id:
*/
/*
mr->PoolId = omr.PoolId;
mr->VolMaxBytes = omr.VolMaxBytes;
mr->VolCapacityBytes = omr.VolCapacityBytes;
- strcpy(mr->Recycle, omr.Recycle);
+ mr->Recycle = omr.Recycle;
fseek(mdb->mediafd, omr.rec_addr, SEEK_SET);
if (fwrite(mr, len, 1, mdb->mediafd) != 1) {
#ifdef HAVE_SQLITE
+#define BDB_VERSION 1
+
#include <sqlite.h>
/* Define opaque structure for sqlite */
#ifdef HAVE_MYSQL
+#define BDB_VERSION 1
+
#include <mysql.h>
/*
/* Change this each time there is some incompatible
* file format change!!!!
*/
-#define BDB_VERSION 7 /* file version number */
+#define BDB_VERSION 8 /* file version number */
struct s_control {
int bdb_version; /* Version number */
/* ***FIXME*** FileId_t should be uint64_t */
typedef uint32_t FileId_t;
typedef uint32_t DBId_t; /* general DB id type */
+typedef uint32_t JobId_t;
/* Job information passed to create job record and update
*/
/* Job record */
typedef struct {
- uint32_t JobId;
+ JobId_t JobId;
char Job[MAX_NAME_LENGTH]; /* Job unique name */
char Name[MAX_NAME_LENGTH]; /* Job base name */
int Type; /* actually char(1) */
time_t SchedTime; /* Time job scheduled */
time_t StartTime; /* Job start time */
time_t EndTime; /* Job termination time */
+ btime_t JobTDate; /* Backup time/date in seconds */
uint32_t VolSessionId;
uint32_t VolSessionTime;
uint32_t JobFiles;
/* JobMedia record */
typedef struct {
uint32_t JobMediaId; /* record id */
- uint32_t JobId; /* JobId */
+ JobId_t JobId; /* JobId */
uint32_t MediaId; /* MediaId */
uint32_t FirstIndex; /* First index this Volume */
uint32_t LastIndex; /* Last index this Volume */
} JOBMEDIA_DBR;
-
-
/* Attributes record -- NOT same as in database because
* in general, this "record" creates multiple database
* records (e.g. pathname, filename, fileattributes).
char *attr; /* attributes statp */
uint32_t FileIndex;
uint32_t Stream;
- uint32_t JobId;
+ JobId_t JobId;
uint32_t ClientId;
uint32_t PathId;
uint32_t FilenameId;
typedef struct {
FileId_t FileId;
uint32_t FileIndex;
- uint32_t JobId;
+ JobId_t JobId;
uint32_t FilenameId;
uint32_t PathId;
char LStat[256];
int UseOnce; /* set to use once only */
int UseCatalog; /* set to use catalog */
int AcceptAnyVolume; /* set to accept any volume sequence */
+ int AutoPrune; /* set to prune automatically */
+ int Recycle; /* default Vol recycle flag */
+ btime_t VolRetention; /* retention period in seconds */
char PoolType[MAX_NAME_LENGTH];
char LabelFormat[MAX_NAME_LENGTH];
/* Extra stuff not in DB */
uint64_t VolBytes; /* Number of bytes written */
uint64_t VolMaxBytes; /* max bytes to write */
uint64_t VolCapacityBytes; /* capacity estimate */
+ btime_t VolRetention; /* Volume retention in seconds */
+ int Recycle; /* recycle yes/no */
char VolStatus[20]; /* Volume status */
- char Recycle[20]; /* Recycle yes/no */
/* Extra stuff not in DB */
faddr_t rec_addr; /* found record address */
} MEDIA_DBR;
/* Client record -- same as the database */
typedef struct {
uint32_t ClientId; /* Unique Client id */
+ int AutoPrune;
+ btime_t FileRetention;
+ btime_t JobRetention;
char Name[MAX_NAME_LENGTH]; /* Client name */
char Uname[256]; /* Uname for client */
} CLIENT_DBR;
#!/bin/sh
#
-# shell script to delete Bacula tables
+# shell script to delete Bacula tables for MySQL
bindir=@SQL_BINDIR@
DROP TABLE IF EXISTS MultiVolume;
DROP TABLE IF EXISTS FileSave;
DROP TABLE IF EXISTS FileSet;
+DROP TABLE IF EXISTS Version;
END-OF-DATA
then
- echo "Deletion of Bacula tables succeeded."
+ echo "Deletion of Bacula MySQL tables succeeded."
else
- echo "Deletion of Bacula tables failed."
+ echo "Deletion of Bacula MySQL tables failed."
fi
exit 0
--- /dev/null
+#!/bin/sh
+#
+# shell script to Delete the SQLite Bacula database (same as deleting
+# the tables)
+#
+
+rm -f @working_dir@/bacula.db
SchedTime DATETIME NOT NULL,
StartTime DATETIME NOT NULL,
EndTime DATETIME NOT NULL,
- StartDay INTEGER UNSIGNED NOT NULL,
+ JobTDate BIGINT UNSIGNED NOT NULL,
VolSessionId INTEGER UNSIGNED NOT NULL,
VolSessionTime INTEGER UNSIGNED NOT NULL,
JobFiles INTEGER UNSIGNED NOT NULL,
VolWrites INTEGER UNSIGNED NOT NULL,
VolMaxBytes BIGINT UNSIGNED NOT NULL,
VolCapacityBytes BIGINT UNSIGNED NOT NULL,
- VolStatus ENUM('Full', 'Archive', 'Append', 'Recycle',
+ VolStatus ENUM('Full', 'Archive', 'Append', 'Recycle', 'Purged',
'Read-Only', 'Disabled', 'Error', 'Busy') NOT NULL,
- Recycle ENUM('No', 'Yes') NOT NULL,
+ Recycle TINYINT NOT NULL,
+ VolRetention BIGINT UNSIGNED NOT NULL,
PRIMARY KEY(MediaId),
INDEX (PoolId)
);
MaxVols INTEGER UNSIGNED NOT NULL,
UseOnce TINYINT NOT NULL,
UseCatalog TINYINT NOT NULL,
- AcceptAnyVolume TINYINT NOT NULL,
+ AcceptAnyVolume TINYINT DEFAULT 0,
+ VolRetention BIGINT UNSIGNED NOT NULL,
+ AutoPrune TINYINT DEFAULT 0,
+ Recycle TINYINT DEFAULT 0,
PoolType ENUM('Backup', 'Copy', 'Cloned', 'Archive', 'Migration') NOT NULL,
LabelFormat TINYBLOB,
UNIQUE (Name(128)),
ClientId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
Name TINYBLOB NOT NULL,
Uname TINYBLOB NOT NULL, /* full uname -a of client */
+ AutoPrune TINYINT DEFAULT 0,
+ FileRetention BIGINT UNSIGNED NOT NULL,
+ JobRetention BIGINT UNSIGNED NOT NULL,
UNIQUE (Name(128)),
PRIMARY KEY(ClientId)
);
+CREATE TABLE Version (
+ VersionId INTEGER UNSIGNED NOT NULL
+ );
+
+-- Initialize Version
+INSERT INTO Version (VersionId) VALUES (1);
+
+
## Experimental
#CREATE TABLE FileSave (
# FileSaveId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
SchedTime DATETIME NOT NULL,
StartTime DATETIME DEFAULT 0,
EndTime DATETIME DEFAULT 0,
- StartDay INTEGER UNSIGNED DEFAULT 0,
+ JobTDate BIGINT UNSIGNED DEFAULT 0,
VolSessionId INTEGER UNSIGNED DEFAULT 0,
VolSessionTime INTEGER UNSIGNED DEFAULT 0,
JobFiles INTEGER UNSIGNED DEFAULT 0,
VolMaxBytes BIGINT UNSIGNED DEFAULT 0,
VolCapacityBytes BIGINT UNSIGNED DEFAULT 0,
VolStatus VARCHAR(20) NOT NULL,
- Recycle VARCHAR(20) NOT NULL,
+ Recycle TINYINT DEFAULT 0,
+ VolRetention BIGINT UNSIGNED DEFAULT 0,
PRIMARY KEY(MediaId)
);
CREATE TABLE Pool (
PoolId INTEGER UNSIGNED AUTOINCREMENT,
Name VARCHAR(128) NOT NULL,
- NumVols INTEGER UNSIGNED NOT NULL,
- MaxVols INTEGER UNSIGNED NOT NULL,
- UseOnce TINYINT NOT NULL,
- UseCatalog TINYINT NOT NULL,
- AcceptAnyVolume TINYINT NOT NULL,
+ NumVols INTEGER UNSIGNED DEFAULT 0,
+ MaxVols INTEGER UNSIGNED DEFAULT 0,
+ UseOnce TINYINT DEFAULT 0,
+ UseCatalog TINYINT DEFAULT 1,
+ AcceptAnyVolume TINYINT DEFAULT 0,
+ VolRetention BIGINT UNSIGNED DEFAULT 0,
+ AutoPrune TINYINT DEFAULT 0,
+ Recycle TINYINT DEFAULT 0,
PoolType VARCHAR(20) NOT NULL,
LabelFormat VARCHAR(128) NOT NULL,
UNIQUE (Name),
ClientId INTEGER UNSIGNED AUTOINCREMENT,
Name VARCHAR(128) NOT NULL,
Uname VARCHAR(255) NOT NULL, -- uname -a field
+ AutoPrune TINYINT DEFAULT 0,
+ FileRetention BIGINT UNSIGNED DEFAULT 0,
+ JobRetention BIGINT UNSIGNED DEFAULT 0,
UNIQUE (Name),
PRIMARY KEY(ClientId)
);
-- Initialize JobId to start at 1
INSERT INTO NextId (id, TableName) VALUES (1, "Job");
+CREATE TABLE Version (
+ VersionId INTEGER UNSIGNED NOT NULL
+ );
+
+-- Initialize Version
+INSERT INTO Version (VersionId) VALUES (1);
+
+
-- Experimental stuff below. Not used.
-- Invariant part of File
CREATE TABLE BaseFile (
V(mutex);
return 0;
}
+
+ if (!check_tables_version(mdb)) {
+ V(mutex);
+ return 0;
+ }
+
mdb->connected = TRUE;
V(mutex);
return 1;
int get_sql_record_max(B_DB *mdb);
char *db_next_index(B_DB *mdb, char *table);
int db_sql_query(B_DB *mdb, char *cmd, DB_RESULT_HANDLER *result_handler, void *ctx);
+int check_tables_version(B_DB *mdb);
/* create.c */
int db_create_file_attributes_record(B_DB *mdb, ATTR_DBR *ar);
void print_dashes(B_DB *mdb);
void print_result(B_DB *mdb);
+/*
+ * Called here to retrieve an integer from the database
+ */
+static int int_handler(void *ctx, int num_fields, char **row)
+{
+ uint32_t *val = (uint32_t *)ctx;
+
+ if (row[0]) {
+ *val = atoi(row[0]);
+ } else {
+ *val = 0;
+ }
+ return 0;
+}
+
+
/* NOTE!!! The following routines expect that the
* calling subroutine sets and clears the mutex
*/
+/* Check that the tables conrrespond to the version we want */
+int check_tables_version(B_DB *mdb)
+{
+ uint32_t version;
+ char *query = "SELECT VersionId FROM Version";
+
+ version = 0;
+ db_sql_query(mdb, query, int_handler, (void *)&version);
+ if (version != BDB_VERSION) {
+ Mmsg(&mdb->errmsg, "Database version mismatch. Wanted %d, got %d\n",
+ BDB_VERSION, version);
+ return 0;
+ }
+ return 1;
+}
+
/* Utility routine for queries */
int
QueryDB(char *file, int line, B_DB *mdb, char *cmd)
mdb->num_rows = 1;
}
if (mdb->num_rows != 1) {
- m_msg(file, line, &mdb->errmsg, _("Insertion problem: affect_rows=%" lld "\n"), mdb->num_rows);
+ char ed1[30];
+ m_msg(file, line, &mdb->errmsg, _("Insertion problem: affect_rows=%s\n"),
+ edit_uint64(mdb->num_rows, ed1));
e_msg(file, line, M_FATAL, 0, mdb->errmsg); /* ***FIXME*** remove me */
return 0;
}
}
mdb->num_rows = sql_affected_rows(mdb);
if (mdb->num_rows != 1) {
- m_msg(file, line, &mdb->errmsg, _("Update problem: affect_rows=%" lld "\n"), mdb->num_rows);
+ char ed1[30];
+ m_msg(file, line, &mdb->errmsg, _("Update problem: affect_rows=%s\n"),
+ edit_uint64(mdb->num_rows, ed1));
e_msg(file, line, M_ERROR, 0, mdb->errmsg);
e_msg(file, line, M_ERROR, 0, "%s\n", cmd);
return 0;
struct tm tm;
int stat;
char *JobId;
- int32_t StartDay;
+ btime_t JobTDate;
+ char ed1[30];
stime = jr->SchedTime;
localtime_r(&stime, &tm);
strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
- StartDay = (int32_t)(date_encode(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday) -
- date_encode(2000, 1, 1));
+ JobTDate = (btime_t)stime;
P(mdb->mutex);
JobId = db_next_index(mdb, "Job");
}
/* Must create it */
Mmsg(&mdb->cmd,
-"INSERT INTO Job (JobId, Job, Name, Type, Level, SchedTime, StartDay) VALUES \
-(%s, \"%s\", \"%s\", \"%c\", \"%c\", \"%s\", %d)",
+"INSERT INTO Job (JobId, Job, Name, Type, Level, SchedTime, JobTDate) VALUES \
+(%s, \"%s\", \"%s\", \"%c\", \"%c\", \"%s\", %s)",
JobId, jr->Job, jr->Name, (char)(jr->Type), (char)(jr->Level), dt,
- StartDay);
+ edit_uint64(JobTDate, ed1));
if (!INSERT_DB(mdb, mdb->cmd)) {
Mmsg2(&mdb->errmsg, _("Create DB Job record %s failed. ERR=%s\n"),
* 1 on success
*/
int
-db_create_pool_record(B_DB *mdb, POOL_DBR *pool_dbr)
+db_create_pool_record(B_DB *mdb, POOL_DBR *pr)
{
int stat;
+ char ed1[30];
P(mdb->mutex);
- Mmsg(&mdb->cmd, "SELECT PoolId,Name FROM Pool WHERE Name=\"%s\"", pool_dbr->Name);
+ Mmsg(&mdb->cmd, "SELECT PoolId,Name FROM Pool WHERE Name=\"%s\"", pr->Name);
Dmsg1(20, "selectpool: %s\n", mdb->cmd);
if (QUERY_DB(mdb, mdb->cmd)) {
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 0) {
- Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pool_dbr->Name);
+ Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
sql_free_result(mdb);
V(mdb->mutex);
return 0;
/* Must create it */
Mmsg(&mdb->cmd,
"INSERT INTO Pool (Name, NumVols, MaxVols, UseOnce, UseCatalog, \
-AcceptAnyVolume, PoolType, LabelFormat) \
-VALUES (\"%s\", %d, %d, %d, %d, %d, \"%s\", \"%s\")",
- pool_dbr->Name,
- pool_dbr->NumVols, pool_dbr->MaxVols,
- pool_dbr->UseOnce, pool_dbr->UseCatalog,
- pool_dbr->AcceptAnyVolume,
- pool_dbr->PoolType, pool_dbr->LabelFormat);
-
+AcceptAnyVolume, AutoPrune, Recycle, VolRetention, PoolType, LabelFormat) \
+VALUES (\"%s\", %d, %d, %d, %d, %d, %d, %d, %s, \"%s\", \"%s\")",
+ pr->Name,
+ pr->NumVols, pr->MaxVols,
+ pr->UseOnce, pr->UseCatalog,
+ pr->AcceptAnyVolume,
+ pr->AutoPrune, pr->Recycle,
+ edit_uint64(pr->VolRetention, ed1),
+ pr->PoolType, pr->LabelFormat);
+ Dmsg1(500, "Create Pool: %s\n", mdb->cmd);
if (!INSERT_DB(mdb, mdb->cmd)) {
Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"),
mdb->cmd, sql_strerror(mdb));
- pool_dbr->PoolId = 0;
+ pr->PoolId = 0;
stat = 0;
} else {
- pool_dbr->PoolId = sql_insert_id(mdb);
+ pr->PoolId = sql_insert_id(mdb);
stat = 1;
}
V(mdb->mutex);
db_create_media_record(B_DB *mdb, MEDIA_DBR *mr)
{
int stat;
+ char ed1[30], ed2[30], ed3[30];
P(mdb->mutex);
Mmsg(&mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName=\"%s\"",
/* Must create it */
Mmsg(&mdb->cmd,
"INSERT INTO Media (VolumeName, MediaType, PoolId, VolMaxBytes, VolCapacityBytes, \
-VolStatus, Recycle) VALUES (\"%s\", \"%s\", %d, %" lld ", %" lld ", \"%s\", \"%s\")",
+Recycle, VolRetention, VolStatus) VALUES (\"%s\", \"%s\", %d, %s, %s, %d, %s, \"%s\")",
mr->VolumeName,
mr->MediaType, mr->PoolId,
- mr->VolMaxBytes, mr->VolCapacityBytes,
- mr->VolStatus, mr->Recycle);
+ edit_uint64(mr->VolMaxBytes,ed1),
+ edit_uint64(mr->VolCapacityBytes, ed2),
+ mr->Recycle,
+ edit_uint64(mr->VolRetention, ed3),
+ mr->VolStatus);
+ Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
if (!INSERT_DB(mdb, mdb->cmd)) {
Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"),
mdb->cmd, sql_strerror(mdb));
{
SQL_ROW row;
int stat;
+ char ed1[30], ed2[30];
P(mdb->mutex);
Mmsg(&mdb->cmd, "SELECT ClientId FROM Client WHERE Name=\"%s\"", cr->Name);
}
/* Must create it */
- Mmsg(&mdb->cmd, "INSERT INTO Client (Name, Uname) VALUES \
-(\"%s\", \"%s\")", cr->Name, cr->Uname);
+ Mmsg(&mdb->cmd, "INSERT INTO Client (Name, Uname, AutoPrune, \
+FileRetention, JobRetention) VALUES \
+(\"%s\", \"%s\", %d, %s, %s)", cr->Name, cr->Uname, cr->AutoPrune,
+ edit_uint64(cr->FileRetention, ed1),
+ edit_uint64(cr->JobRetention, ed2));
if (!INSERT_DB(mdb, mdb->cmd)) {
Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"),
/* Must create it */
Mmsg(&mdb->cmd,
"INSERT INTO File (FileIndex, JobId, PathId, FilenameId, \
-LStat, MD5) VALUES (%d, %d, %d, %d, \"%s\", \" \")",
+LStat, MD5) VALUES (%d, %d, %d, %d, \"%s\", \"0\")",
(int)ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId,
ar->attr);
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 1) {
- Mmsg2(&mdb->errmsg, _("More than one Path!: %" lld " for Path=%s\n"),
- mdb->num_rows, path);
+ char ed1[30];
+ Mmsg2(&mdb->errmsg, _("More than one Path!: %s for Path=%s\n"),
+ edit_uint64(mdb->num_rows, ed1), path);
Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
Emsg1(M_ERROR, 0, "%s\n", mdb->cmd);
}
return 1;
}
+#define MAX_DEL_LIST_LEN 1000000
-/* Delete Media record */
-int db_delete_media_record(B_DB *mdb, MEDIA_DBR *mr)
+struct s_del_ctx {
+ JobId_t *JobId;
+ int num_ids; /* ids stored */
+ int max_ids; /* size of array */
+ int num_del; /* number deleted */
+ int tot_ids; /* total to process */
+};
+
+/*
+ * Called here to make in memory list of JobIds to be
+ * deleted. The in memory list will then be transversed
+ * to issue the SQL DELETE commands. Note, the list
+ * is allowed to get to MAX_DEL_LIST_LEN to limit the
+ * maximum malloc'ed memory.
+ */
+static int delete_handler(void *ctx, int num_fields, char **row)
{
+ struct s_del_ctx *del = (struct s_del_ctx *)ctx;
- P(mdb->mutex);
- if (mr->MediaId == 0) {
- Mmsg(&mdb->cmd, "DELETE FROM Media WHERE VolumeName=\"%s\"",
- mr->VolumeName);
- } else {
- Mmsg(&mdb->cmd, "DELETE FROM Media WHERE MediaId=%d",
- mr->MediaId);
+ if (del->num_ids == MAX_DEL_LIST_LEN) {
+ return 1;
+ }
+ if (del->num_ids == del->max_ids) {
+ del->max_ids = (del->max_ids * 3) / 2;
+ del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) *
+ del->max_ids);
}
+ del->JobId[del->num_ids++] = (JobId_t)strtod(row[0], NULL);
+ return 0;
+}
- mr->MediaId = DELETE_DB(mdb, mdb->cmd);
- V(mdb->mutex);
+/*
+ * This routine will purge (delete) all records
+ * associated with a particular Volume. It will
+ * not delete the media record itself.
+ */
+static int do_media_purge(B_DB *mdb, MEDIA_DBR *mr)
+{
+ char *query = (char *)get_pool_memory(PM_MESSAGE);
+ struct s_del_ctx del;
+ int i;
+
+ del.num_ids = 0;
+ del.tot_ids = 0;
+ del.num_del = 0;
+ del.max_ids = 0;
+ Mmsg(&mdb->cmd, "SELECT JobId from JobMedia WHERE MediaId=%d", mr->MediaId);
+ del.max_ids = mr->VolJobs;
+ if (del.max_ids < 100) {
+ del.max_ids = 100;
+ } else if (del.max_ids > MAX_DEL_LIST_LEN) {
+ del.max_ids = MAX_DEL_LIST_LEN;
+ }
+ del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids);
+ db_sql_query(mdb, mdb->cmd, delete_handler, (void *)&del);
+
+ for (i=0; i < del.num_ids; i++) {
+ Dmsg1(400, "Delete JobId=%d\n", del.JobId[i]);
+ Mmsg(&query, "DELETE FROM Job WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(mdb, query, NULL, (void *)NULL);
+ Mmsg(&query, "DELETE FROM File WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(mdb, query, NULL, (void *)NULL);
+ Mmsg(&query, "DELETE FROM JobMedia WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(mdb, query, NULL, (void *)NULL);
+ }
+ free(del.JobId);
+ free_pool_memory(query);
return 1;
}
+/* Delete Media record and all records that
+ * are associated with it.
+ */
+int db_delete_media_record(B_DB *mdb, MEDIA_DBR *mr)
+{
+ if (mr->MediaId == 0 && !db_get_media_record(mdb, mr)) {
+ return 0;
+ }
+ /* Delete associated records */
+ do_media_purge(mdb, mr);
+
+ Mmsg(&mdb->cmd, "DELETE FROM Media WHERE MediaId=%d", mr->MediaId);
+ db_sql_query(mdb, mdb->cmd, NULL, (void *)NULL);
+ return 1;
+}
+
+/*
+ * Purge all records associated with a
+ * media record. This does not delete the
+ * media record itself. But the media status
+ * is changed to "Purged".
+ */
+int db_purge_media_record(B_DB *mdb, MEDIA_DBR *mr)
+{
+ if (mr->MediaId == 0 && !db_get_media_record(mdb, mr)) {
+ return 0;
+ }
+ /* Delete associated records */
+ do_media_purge(mdb, mr);
+
+ /* Mark Volume as purged */
+ strcpy(mr->VolStatus, "Purged");
+ if (!db_update_media_record(mdb, mr)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+
#endif /* HAVE_MYSQL || HAVE_SQLITE */
Mmsg(&mdb->cmd, "SELECT PathId FROM Path WHERE Path=\"%s\"", path);
if (QUERY_DB(mdb, mdb->cmd)) {
-
+ char ed1[30];
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 1) {
- Mmsg1(&mdb->errmsg, _("More than one Path!: %" lld "\n"), mdb->num_rows);
+ Mmsg1(&mdb->errmsg, _("More than one Path!: %s\n"),
+ edit_uint64(mdb->num_rows, ed1));
Emsg0(M_FATAL, 0, mdb->errmsg);
} else if (mdb->num_rows == 1) {
if ((row = sql_fetch_row(mdb)) == NULL) {
P(mdb->mutex);
if (jr->JobId == 0) {
Mmsg(&mdb->cmd, "SELECT VolSessionId, VolSessionTime, \
-PoolId, StartTime, EndTime, JobFiles, JobBytes, Job \
+PoolId, StartTime, EndTime, JobFiles, JobBytes, JobTDate, Job \
FROM Job WHERE Job=\"%s\"", jr->Job);
} else {
Mmsg(&mdb->cmd, "SELECT VolSessionId, VolSessionTime, \
-PoolId, StartTime, EndTime, JobFiles, JobBytes, Job \
+PoolId, StartTime, EndTime, JobFiles, JobBytes, JobTDate, Job \
FROM Job WHERE JobId=%d", jr->JobId);
}
strcpy(jr->cEndTime, row[4]);
jr->JobFiles = atol(row[5]);
jr->JobBytes = (uint64_t)strtod(row[6], NULL);
- strcpy(jr->Job, row[7]);
+ jr->JobTDate = (btime_t)strtod(row[7], NULL);
+ strcpy(jr->Job, row[8]);
sql_free_result(mdb);
V(mdb->mutex);
if (pdbr->PoolId != 0) { /* find by id */
Mmsg(&mdb->cmd,
"SELECT PoolId, Name, NumVols, MaxVols, UseOnce, UseCatalog, AcceptAnyVolume, \
+AutoPrune, Recycle, VolRetention, \
PoolType, LabelFormat FROM Pool WHERE Pool.PoolId=%d", pdbr->PoolId);
} else { /* find by name */
Mmsg(&mdb->cmd,
"SELECT PoolId, Name, NumVols, MaxVols, UseOnce, UseCatalog, AcceptAnyVolume, \
+AutoPrune, Recycle, VolRetention, \
PoolType, LabelFormat FROM Pool WHERE Pool.Name=\"%s\"", pdbr->Name);
}
if (QUERY_DB(mdb, mdb->cmd)) {
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 1) {
- Mmsg1(&mdb->errmsg, _("More than one Pool!: %" lld "\n"), mdb->num_rows);
+ char ed1[30];
+ Mmsg1(&mdb->errmsg, _("More than one Pool!: %s\n"),
+ edit_uint64(mdb->num_rows, ed1));
Emsg0(M_ERROR, 0, mdb->errmsg);
} else if (mdb->num_rows == 1) {
if ((row = sql_fetch_row(mdb)) == NULL) {
pdbr->UseOnce = atoi(row[4]);
pdbr->UseCatalog = atoi(row[5]);
pdbr->AcceptAnyVolume = atoi(row[6]);
- strcpy(pdbr->PoolType, row[7]);
- if (row[8]) {
- strcpy(pdbr->LabelFormat, row[8]);
+ pdbr->AutoPrune = atoi(row[7]);
+ pdbr->Recycle = atoi(row[8]);
+ pdbr->VolRetention = (btime_t)strtod(row[9], NULL);
+ strcpy(pdbr->PoolType, row[10]);
+ if (row[11]) {
+ strcpy(pdbr->LabelFormat, row[11]);
} else {
pdbr->LabelFormat[0] = 0;
}
if (mr->MediaId != 0) { /* find by id */
Mmsg(&mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,\
VolBytes,VolMounts,VolErrors,VolWrites,VolMaxBytes,VolCapacityBytes,\
-MediaType,VolStatus,PoolId \
+MediaType,VolStatus,PoolId,VoRetention,Recycle \
FROM Media WHERE MediaId=%d", mr->MediaId);
} else { /* find by name */
Mmsg(&mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,\
VolBytes,VolMounts,VolErrors,VolWrites,VolMaxBytes,VolCapacityBytes,\
-MediaType,VolStatus,PoolId \
+MediaType,VolStatus,PoolId,VolRetention,Recycle \
FROM Media WHERE VolumeName=\"%s\"", mr->VolumeName);
}
if (QUERY_DB(mdb, mdb->cmd)) {
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 1) {
- Mmsg1(&mdb->errmsg, _("More than one Volume!: %" lld "\n"), mdb->num_rows);
+ char ed1[30];
+ Mmsg1(&mdb->errmsg, _("More than one Volume!: %s\n"),
+ edit_uint64(mdb->num_rows, ed1));
Emsg0(M_ERROR, 0, mdb->errmsg);
} else if (mdb->num_rows == 1) {
if ((row = sql_fetch_row(mdb)) == NULL) {
strcpy(mr->MediaType, row[11]);
strcpy(mr->VolStatus, row[12]);
mr->PoolId = atoi(row[13]);
+ mr->VolRetention = (btime_t)strtod(row[14], NULL);
+ mr->Recycle = atoi(row[15]);
stat = mr->MediaId;
}
+ } else {
+ Mmsg0(&mdb->errmsg, _("Media record not found.\n"));
}
sql_free_result(mdb);
}
{
Mmsg(&mdb->cmd, "SELECT VolumeName,MediaType,VolStatus,\
-VolBytes,LastWritten \
+VolBytes,LastWritten,VolRetention,Recycle \
FROM Media WHERE Media.PoolId=%d ORDER BY MediaId", mdbr->PoolId);
P(mdb->mutex);
char dt[MAX_TIME_LENGTH];
time_t stime;
struct tm tm;
- int32_t StartDay;
+ btime_t JobTDate;
int stat;
+ char ed1[30];
stime = jr->StartTime;
localtime_r(&stime, &tm);
strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
- StartDay = (int32_t)(date_encode(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday) -
- date_encode(2000, 1, 1));
+ JobTDate = (btime_t)stime;
P(mdb->mutex);
Mmsg(&mdb->cmd, "UPDATE Job SET Level='%c', StartTime=\"%s\", \
-ClientId=%d, StartDay=%d WHERE JobId=%d",
- (char)(jr->Level), dt, jr->ClientId, StartDay, jr->JobId);
+ClientId=%d, JobTDate=%s WHERE JobId=%d",
+ (char)(jr->Level), dt, jr->ClientId, edit_uint64(JobTDate, ed1), jr->JobId);
stat = UPDATE_DB(mdb, mdb->cmd);
V(mdb->mutex);
return stat;
time_t ttime;
struct tm tm;
int stat;
+ char ed1[30], ed2[30];
+ btime_t JobTDate;
ttime = jr->EndTime;
localtime_r(&ttime, &tm);
strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
+ JobTDate = ttime;
P(mdb->mutex);
Mmsg(&mdb->cmd,
"UPDATE Job SET JobStatus='%c', EndTime='%s', \
-ClientId=%d, JobBytes=%" lld ", JobFiles=%d, JobErrors=%d, VolSessionId=%d, \
-VolSessionTime=%d, PoolId=%d, FileSetId=%d WHERE JobId=%d",
- (char)(jr->JobStatus), dt, jr->ClientId, jr->JobBytes, jr->JobFiles,
- jr->JobErrors, jr->VolSessionId, jr->VolSessionTime,
- jr->PoolId, jr->FileSetId, jr->JobId);
+ClientId=%d, JobBytes=%s, JobFiles=%d, JobErrors=%d, VolSessionId=%d, \
+VolSessionTime=%d, PoolId=%d, FileSetId=%d, JobTDate=%s WHERE JobId=%d",
+ (char)(jr->JobStatus), dt, jr->ClientId, edit_uint64(jr->JobBytes, ed1),
+ jr->JobFiles, jr->JobErrors, jr->VolSessionId, jr->VolSessionTime,
+ jr->PoolId, jr->FileSetId, edit_uint64(JobTDate, ed2), jr->JobId);
stat = UPDATE_DB(mdb, mdb->cmd);
V(mdb->mutex);
time_t ttime;
struct tm tm;
int stat;
+ char ed1[30], ed2[30];
ttime = mr->LastWritten;
localtime_r(&ttime, &tm);
strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
+ Dmsg1(000, "update_media: FirstWritte=%d\n", mr->FirstWritten);
P(mdb->mutex);
if (mr->VolMounts == 1) {
- Mmsg(&mdb->cmd, "UPDATE Media SET FirstWritten=\"%s\" WHERE \
- VolumeName=\"%s\"", dt, mr->VolumeName);
+ Mmsg(&mdb->cmd, "UPDATE Media SET FirstWritten=\"%s\"\
+ WHERE VolumeName=\"%s\"", dt, mr->VolumeName);
if (do_update(mdb, mdb->cmd) == 0) {
V(mdb->mutex);
return 0;
}
Mmsg(&mdb->cmd, "UPDATE Media SET VolJobs=%d,\
- VolFiles=%d, VolBlocks=%d, VolBytes=%" lld ", VolMounts=%d, VolErrors=%d,\
- VolWrites=%d, VolMaxBytes=%" lld ", LastWritten=\"%s\", VolStatus=\"%s\" \
+ VolFiles=%d, VolBlocks=%d, VolBytes=%s, VolMounts=%d, VolErrors=%d,\
+ VolWrites=%d, VolMaxBytes=%s, LastWritten=\"%s\", VolStatus=\"%s\" \
WHERE VolumeName=\"%s\"",
- mr->VolJobs, mr->VolFiles, mr->VolBlocks, mr->VolBytes, mr->VolMounts,
- mr->VolErrors, mr->VolWrites, mr->VolMaxBytes, dt, mr->VolStatus,
- mr->VolumeName);
+ mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1),
+ mr->VolMounts, mr->VolErrors, mr->VolWrites,
+ edit_uint64(mr->VolMaxBytes, ed2), dt,
+ mr->VolStatus, mr->VolumeName);
stat = UPDATE_DB(mdb, mdb->cmd);
V(mdb->mutex);
return 0;
}
free(db_name);
+ if (!check_tables_version(mdb)) {
+ V(mutex);
+ return 0;
+ }
+
mdb->connected = TRUE;
V(mutex);
return 1;
#
# shell script to invoke SQLite on Bacula database
-@bindir@/sqlite @working_dir@/bacula.db
+bindir=@SQL_BINDIR@
+$bindir/sqlite @working_dir@/bacula.db
<output_build_files>False</output_build_files>
</project>
-<widget>
- <class>GnomeAbout</class>
- <name>about</name>
- <visible>False</visible>
- <modal>True</modal>
- <copyright>Copyright (c) 1999 - 2002, Kern Sibbald and John Walker</copyright>
- <authors>Kern Sibbald and John Walker
-</authors>
- <comments>It comes by night and sucks the essence from your computers.</comments>
-</widget>
-
<widget>
<class>GnomeMessageBox</class>
<name>messagebox1</name>
</widget>
</widget>
+<widget>
+ <class>GtkDialog</class>
+ <name>about1</name>
+ <width>382</width>
+ <height>242</height>
+ <title>About Bacula Console</title>
+ <type>GTK_WINDOW_TOPLEVEL</type>
+ <position>GTK_WIN_POS_CENTER</position>
+ <modal>True</modal>
+ <allow_shrink>False</allow_shrink>
+ <allow_grow>False</allow_grow>
+ <auto_shrink>False</auto_shrink>
+
+ <widget>
+ <class>GtkVBox</class>
+ <child_name>Dialog:vbox</child_name>
+ <name>dialog-vbox5</name>
+ <homogeneous>False</homogeneous>
+ <spacing>0</spacing>
+
+ <widget>
+ <class>GtkHBox</class>
+ <child_name>Dialog:action_area</child_name>
+ <name>dialog-action_area5</name>
+ <border_width>10</border_width>
+ <homogeneous>True</homogeneous>
+ <spacing>5</spacing>
+ <child>
+ <padding>0</padding>
+ <expand>False</expand>
+ <fill>True</fill>
+ <pack>GTK_PACK_END</pack>
+ </child>
+
+ <widget>
+ <class>GtkHBox</class>
+ <name>hbox20</name>
+ <homogeneous>False</homogeneous>
+ <spacing>0</spacing>
+ <child>
+ <padding>0</padding>
+ <expand>True</expand>
+ <fill>True</fill>
+ </child>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>label44</name>
+ <label></label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0.5</xalign>
+ <yalign>0.5</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <child>
+ <padding>0</padding>
+ <expand>True</expand>
+ <fill>False</fill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkButton</class>
+ <name>about_button</name>
+ <border_width>1</border_width>
+ <width>80</width>
+ <can_default>True</can_default>
+ <can_focus>True</can_focus>
+ <signal>
+ <name>clicked</name>
+ <handler>on_about_button_clicked</handler>
+ <last_modification_time>Sun, 28 Apr 2002 15:55:15 GMT</last_modification_time>
+ </signal>
+ <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
+ <relief>GTK_RELIEF_NORMAL</relief>
+ <child>
+ <padding>0</padding>
+ <expand>False</expand>
+ <fill>False</fill>
+ </child>
+ </widget>
+ </widget>
+ </widget>
+
+ <widget>
+ <class>GtkVBox</class>
+ <name>vbox8</name>
+ <homogeneous>False</homogeneous>
+ <spacing>0</spacing>
+ <child>
+ <padding>0</padding>
+ <expand>True</expand>
+ <fill>True</fill>
+ </child>
+
+ <widget>
+ <class>GtkVBox</class>
+ <name>vbox9</name>
+ <homogeneous>False</homogeneous>
+ <spacing>0</spacing>
+ <child>
+ <padding>0</padding>
+ <expand>True</expand>
+ <fill>True</fill>
+ </child>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>about_head</name>
+ <height>102</height>
+ <label>Bacula Console 1.19 (28 April 2002)
+</label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0.5</xalign>
+ <yalign>0.5</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <child>
+ <padding>0</padding>
+ <expand>False</expand>
+ <fill>False</fill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkHSeparator</class>
+ <name>hseparator1</name>
+ <child>
+ <padding>0</padding>
+ <expand>False</expand>
+ <fill>False</fill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>copyright</name>
+ <label>Copyright (c) 1999 - 2002, Kern Sibbald and John Walker</label>
+ <justify>GTK_JUSTIFY_LEFT</justify>
+ <wrap>False</wrap>
+ <xalign>0.1</xalign>
+ <yalign>0.5</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <child>
+ <padding>0</padding>
+ <expand>True</expand>
+ <fill>False</fill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>authors</name>
+ <label>Authors: Kern Sibbald and John Walker</label>
+ <justify>GTK_JUSTIFY_LEFT</justify>
+ <wrap>False</wrap>
+ <xalign>0.0400001</xalign>
+ <yalign>0.5</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <child>
+ <padding>0</padding>
+ <expand>True</expand>
+ <fill>False</fill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>theme</name>
+ <label>It comes by night and sucks the essence from your computers</label>
+ <justify>GTK_JUSTIFY_LEFT</justify>
+ <wrap>False</wrap>
+ <xalign>0.15</xalign>
+ <yalign>0.5</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <child>
+ <padding>0</padding>
+ <expand>True</expand>
+ <fill>False</fill>
+ </child>
+ </widget>
+ </widget>
+ </widget>
+ </widget>
+</widget>
+
</GTK-Interface>
console: $(CONSOBJS) ../lib/libbac.a ../cats/libsql.a
$(CXX) $(LDFLAGS) $(CONS_LDFLAGS) -L../lib -L../cats -o $@ $(CONSOBJS) \
- $(LIBS) $(DLIB) $(CONS_LIBS) -lbac -lsql -lm -ltermcap
+ $(LIBS) $(DLIB) $(CONS_LIBS) -lbac -lsql -lm
Makefile: $(srcdir)/Makefile.in $(topdir)/config.status
cd $(topdir) \
/* Forward referenced functions */
static void terminate_console(int sig);
-int get_cmd(char *prompt, BSOCK *sock, int sec);
+int get_cmd(FILE *input, char *prompt, BSOCK *sock, int sec);
/* Static variables */
static char *configfile = NULL;
static BSOCK *UA_sock = NULL;
static DIRRES *dir;
+static FILE *output = stdout;
+
#define CONFIG_FILE "./console.conf" /* default configuration file */
exit(1);
}
+static void read_and_process_input(FILE *input, BSOCK *UA_sock)
+{
+ char *prompt = "*";
+ int at_prompt = FALSE;
+ int tty_input = isatty(fileno(input));
+ int stat;
+
+ for ( ;; ) {
+ if (at_prompt) { /* don't prompt multiple times */
+ prompt = "";
+ } else {
+ prompt = "*";
+ at_prompt = TRUE;
+ }
+ if (tty_input) {
+ stat = get_cmd(input, prompt, UA_sock, 30);
+ } else {
+ int len = sizeof_pool_memory(UA_sock->msg) - 1;
+ if (fgets(UA_sock->msg, len, input) == NULL) {
+ stat = -1;
+ } else {
+ strip_trailing_junk(UA_sock->msg);
+ UA_sock->msglen = strlen(UA_sock->msg);
+ stat = 1;
+ }
+ }
+ if (stat < 0) {
+ break; /* error */
+ } else if (stat == 0) { /* timeout */
+ bnet_fsend(UA_sock, ".messages");
+ } else {
+ at_prompt = FALSE;
+ if (!bnet_send(UA_sock)) { /* send command */
+ break; /* error */
+ }
+ }
+ if (strcmp(UA_sock->msg, "quit") == 0 || strcmp(UA_sock->msg, "exit") == 0) {
+ break;
+ }
+ while ((stat = bnet_recv(UA_sock)) > 0) {
+ if (at_prompt) {
+ fprintf(output, "\n");
+ at_prompt = FALSE;
+ }
+ printf("%s", UA_sock->msg);
+ }
+ fflush(output);
+ if (stat < 0) {
+ break; /* error */
+ } else if (stat == 0) {
+ if (UA_sock->msglen == BNET_PROMPT) {
+ at_prompt = TRUE;
+ }
+ Dmsg1(100, "Got poll %s\n", bnet_sig_to_ascii(UA_sock));
+ }
+ }
+}
+
/*********************************************************************
*
*/
int main(int argc, char *argv[])
{
- int ch, stat, i, ndir, item;
+ int ch, i, ndir, item;
int no_signals = FALSE;
int test_config = FALSE;
JCR jcr;
- char *prompt = "*";
- int at_prompt = FALSE;
init_stack_dump();
my_name_is(argc, argv, "console");
* Ensure that every message is always printed
*/
for (i=1; i<=M_MAX; i++) {
- add_msg_dest(MD_STDOUT, i, NULL, NULL);
+ add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL);
}
}
UnlockRes();
if (ndir == 0) {
- Emsg1(M_ABORT, 0, "No director resource defined in %s\n\
+ Emsg1(M_ABORT, 0, "No Director resource defined in %s\n\
Without that I don't how to speak to the Director :-(\n", configfile);
}
if (ndir > 1) {
UA_sock = init_bsock(0, "", "", 0);
try_again:
- printf("Available Directors:\n");
+ fprintf(output, "Available Directors:\n");
LockRes();
ndir = 0;
for (dir = NULL; (dir = (DIRRES *)GetNextRes(R_DIRECTOR, (RES *)dir)); ) {
- printf("%d %s at %s:%d\n", 1+ndir++, dir->hdr.name, dir->address,
+ fprintf(output, "%d %s at %s:%d\n", 1+ndir++, dir->hdr.name, dir->address,
dir->DIRport);
}
UnlockRes();
- if (get_cmd("Select Director: ", UA_sock, 600) < 0) {
+ if (get_cmd(stdin, "Select Director: ", UA_sock, 600) < 0) {
return 1;
}
item = atoi(UA_sock->msg);
if (item < 0 || item > ndir) {
- printf("You must enter a number between 1 and %d\n", ndir);
+ fprintf(output, "You must enter a number between 1 and %d\n", ndir);
goto try_again;
}
LockRes();
}
jcr.dir_bsock = UA_sock;
if (!authenticate_director(&jcr, dir)) {
- printf("ERR: %s", UA_sock->msg);
+ fprintf(stderr, "ERR: %s", UA_sock->msg);
terminate_console(0);
return 1;
}
Dmsg0(40, "Opened connection with Director daemon\n");
- for ( ;; ) {
- if (at_prompt) { /* don't prompt multiple times */
- prompt = "";
- } else {
- prompt = "*";
- at_prompt = TRUE;
- }
- stat = get_cmd(prompt, UA_sock, 30);
- if (stat < 0) {
- break; /* error */
- } else if (stat == 0) { /* timeout */
- bnet_fsend(UA_sock, ".messages");
- } else {
- at_prompt = FALSE;
- if (!bnet_send(UA_sock)) { /* send command */
- break; /* error */
- }
- }
- if (strcmp(UA_sock->msg, "quit") == 0 || strcmp(UA_sock->msg, "exit") == 0) {
- break;
- }
- while ((stat = bnet_recv(UA_sock)) > 0) {
- if (at_prompt) {
- printf("\n");
- at_prompt = FALSE;
- }
- printf("%s", UA_sock->msg);
- }
- fflush(stdout);
- if (stat < 0) {
- break; /* error */
- } else if (stat == 0) {
- if (UA_sock->msglen == BNET_PROMPT) {
- at_prompt = TRUE;
- }
- Dmsg1(100, "Got poll %s\n", bnet_sig_to_ascii(UA_sock));
- }
- }
+ read_and_process_input(stdin, UA_sock);
+
if (UA_sock) {
bnet_sig(UA_sock, BNET_TERMINATE); /* send EOF */
bnet_close(UA_sock);
#include "readline/readline.h"
#include "readline/history.h"
+
int
-get_cmd(char *prompt, BSOCK *sock, int sec)
+get_cmd(FILE *input, char *prompt, BSOCK *sock, int sec)
{
char *line;
* -1 if EOF or error
*/
int
-get_cmd(char *prompt, BSOCK *sock, int sec)
+get_cmd(FILE *input, char *prompt, BSOCK *sock, int sec)
{
- fprintf(stdout, prompt);
- fflush(stdout);
- switch (wait_for_data(fileno(stdin), sec)) {
+ int len;
+ fprintf(output, prompt);
+ fflush(output);
+ switch (wait_for_data(fileno(input), sec)) {
case 0:
return 0; /* timeout */
case -1:
return -1; /* error */
default:
- if (fgets(sock->msg, 200, stdin) == NULL) {
+ len = sizeof_pool_memory(sock->msg) - 1;
+ if (fgets(sock->msg, len, input) == NULL) {
return -1;
}
break;
* resource with the routine to process the record
* information.
*/
+
+/* Console "globals" */
+static struct res_items cons_items[] = {
+ {"name", store_name, ITEM(res_cons.hdr.name), 0, ITEM_REQUIRED, 0},
+ {"description", store_str, ITEM(res_cons.hdr.desc), 0, 0, 0},
+ {"rcfile", store_dir, ITEM(res_cons.rc_file), 0, 0, 0},
+ {"historyfile", store_dir, ITEM(res_cons.hist_file), 0, 0, 0},
+ {NULL, NULL, NULL, 0, 0, 0}
+};
+
+
+/* Director's that we can contact */
static struct res_items dir_items[] = {
{"name", store_name, ITEM(res_dir.hdr.name), 0, ITEM_REQUIRED, 0},
{"description", store_str, ITEM(res_dir.hdr.desc), 0, 0, 0},
* It must have one item for each of the resources.
*/
struct s_res resources[] = {
+ {"console", cons_items, R_CONSOLE, NULL},
{"director", dir_items, R_DIRECTOR, NULL},
{NULL, NULL, 0, NULL}
};
recurse = 0;
}
switch (type) {
+ case R_CONSOLE:
+ printf("Console: name=%s rcfile=%s histfile=%s\n", reshdr->name,
+ res->res_cons.rc_file, res->res_cons.hist_file);
+ break;
case R_DIRECTOR:
printf("Director: name=%s address=%s DIRport=%d\n", reshdr->name,
res->res_dir.address, res->res_dir.DIRport);
free(res->res_dir.hdr.desc);
switch (type) {
+ case R_CONSOLE:
+ if (res->res_cons.rc_file) {
+ free(res->res_cons.rc_file);
+ }
+ if (res->res_cons.hist_file) {
+ free(res->res_cons.hist_file);
+ }
case R_DIRECTOR:
if (res->res_dir.address)
free(res->res_dir.address);
if (pass == 2) {
switch (type) {
/* Resources not containing a resource */
+ case R_CONSOLE:
case R_DIRECTOR:
break;
}
switch (type) {
+ case R_CONSOLE:
+ size = sizeof(CONSRES);
+ break;
case R_DIRECTOR:
size = sizeof(DIRRES);
break;
/*
* Resource codes -- they must be sequential for indexing
*/
-#define R_FIRST 1001
+#define R_FIRST 1001
-#define R_DIRECTOR 1001
+#define R_CONSOLE 1001
+#define R_DIRECTOR 1002
-#define R_LAST R_DIRECTOR
+#define R_LAST R_DIRECTOR
/*
* 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
/* Definition of the contents of each Resource */
+
+/* Console "globals" */
+struct s_res_cons {
+ RES hdr;
+ char *rc_file; /* startup file */
+ char *hist_file; /* command history file */
+};
+typedef struct s_res_cons CONSRES;
+
+/* Director */
struct s_res_dir {
- RES hdr;
- int DIRport; /* UA server port */
- char *address; /* UA server address */
- char *password; /* UA server password */
+ RES hdr;
+ int DIRport; /* UA server port */
+ char *address; /* UA server address */
+ char *password; /* UA server password */
};
typedef struct s_res_dir DIRRES;
* resource structure definitions.
*/
union u_res {
- struct s_res_dir res_dir;
+ struct s_res_dir res_dir;
+ struct s_res_cons res_cons;
RES hdr;
};
dummy:
#
-SVRSRCS = dird.c authenticate.c backup.c catreq.c dird_conf.c \
+SVRSRCS = dird.c authenticate.c backup.c \
+ catreq.c dird_conf.c \
fd_cmds.c getmsg.c job.c \
- mountreq.c msgchan.c newvol.c run_conf.c restore.c \
+ mountreq.c msgchan.c newvol.c \
+ run_conf.c restore.c \
scheduler.c ua_cmds.c \
ua_dotcmds.c \
ua_db_query.c ua_retention.c \
- ua_input.c ua_output.c ua_run.c \
+ ua_input.c ua_output.c ua_prune.c \
+ ua_purge.c ua_run.c \
ua_select.c ua_server.c \
ua_status.c verify.c
-SVROBJS = dird.o authenticate.o backup.o catreq.o dird_conf.o \
+SVROBJS = dird.o authenticate.o backup.o \
+ catreq.o dird_conf.o \
fd_cmds.o getmsg.o job.o \
- mountreq.o msgchan.o newvol.o run_conf.o restore.o \
+ mountreq.o msgchan.o newvol.o \
+ run_conf.o restore.o \
scheduler.o ua_cmds.o \
ua_dotcmds.o \
ua_db_query.o ua_retention.o \
- ua_input.o ua_output.o ua_run.o \
+ ua_input.o ua_output.o ua_prune.o \
+ ua_purge.o ua_run.o \
ua_select.o ua_server.o \
ua_status.o verify.o
#include "bacula.h"
#include "dird.h"
+#include "ua.h"
/* Commands sent to File daemon */
static char backupcmd[] = "backup\n";
*/
memset(&cr, 0, sizeof(cr));
strcpy(cr.Name, jcr->client->hdr.name);
+ cr.AutoPrune = jcr->client->AutoPrune;
+ cr.FileRetention = jcr->client->FileRetention;
+ cr.JobRetention = jcr->client->JobRetention;
if (jcr->client_name) {
free(jcr->client_name);
}
jcr->client->hdr.name,
sdt,
edt,
- edit_uint_with_commas(jcr->jr.JobBytes, ec1),
- edit_uint_with_commas(jcr->jr.JobFiles, ec2),
+ edit_uint64_with_commas(jcr->jr.JobBytes, ec1),
+ edit_uint64_with_commas(jcr->jr.JobFiles, ec2),
jcr->VolumeName,
jcr->VolSessionId,
jcr->VolSessionTime,
- edit_uint_with_commas(mr.VolBytes, ec3),
+ edit_uint64_with_commas(mr.VolBytes, ec3),
term_msg);
Dmsg0(100, "Leave backup_cleanup()\n");
FDPort = @fd_port@
Catalog = MyCatalog
Password = "@fd_password@" # password for FileDaemon
+ File Retention = 180d # six months
+ Job Retention = 365d # one year
+ AutoPrune = yes # Prune expired Jobs/Files
}
# Definition of DLT tape storage device
Storage {
Name = DLTDrive
- Address = @hostname@
+ Address = @hostname@ # N.B. Use a fully qualified name here
SDPort = @sd_port@
Password = "@sd_password@" # password for Storage daemon
Device = "HP DLT 80" # must be same as Device in Storage daemon
# Definition of DDS tape storage device
Storage {
Name = SDT-10000
- Address = @hostname@
+ Address = @hostname@ # N.B. Use a fully qualified name here
SDPort = @sd_port@
Password = "@sd_password@" # password for Storage daemon
Device = SDT-10000 # must be same as Device in Storage daemon
# Definition of 8mm tape storage device
Storage {
Name = "8mmDrive"
- Address = @hostname@
+ Address = @hostname@ # N.B. Use a fully qualified name here
SDPort = @sd_port@
Password = "@sd_password@"
Device = "Exabyte 8mm"
# Definiton of file storage device
Storage {
Name = File
- Address = @hostname@
+ Address = @hostname@ # N.B. Use a fully qualified name here
SDPort = @sd_port@
Password = "@sd_password@"
Device = FileStorage
Pool {
Name = Default
Pool Type = Backup
+ Recycle = yes # Bacula can automatically recycle Volumes
+ AutoPrune = yes # Prune expired volumes
+ Volume Retention = 365d # one year
}
/* Requests from the Storage daemon */
static char Find_media[] = "CatReq Job=%127s FindMedia=%d\n";
-static char Find_Vol_Info[] = "CatReq Job=%127s GetVolInfo VolName=%127s\n";
+static char Get_Vol_Info[] = "CatReq Job=%127s GetVolInfo VolName=%127s\n";
static char Update_media[] = "CatReq Job=%127s UpdateMedia VolName=%s\
VolJobs=%d VolFiles=%d VolBlocks=%d VolBytes=%" lld " VolMounts=%d\
/* Responses sent to Storage daemon */
static char OK_media[] = "1000 OK VolName=%s VolJobs=%d VolFiles=%d\
VolBlocks=%d VolBytes=%" lld " VolMounts=%d VolErrors=%d VolWrites=%d\
- VolMaxBytes=%" lld " VolCapacityBytes=%" lld "\n";
+ VolMaxBytes=%" lld " VolCapacityBytes=%" lld " VolStatus=%s\n";
static char OK_update[] = "1000 OK UpdateMedia\n";
jcr->MediaId = mr.MediaId;
Dmsg1(20, "Find_next_vol MediaId=%d\n", jcr->MediaId);
strcpy(jcr->VolumeName, mr.VolumeName);
-
ok = TRUE;
} else {
- /* See if we can create a new Volume */
- ok = newVolume(jcr);
+ /* Well, try finding recycled tapes */
+ strcpy(mr.VolStatus, "Recycle");
+ if (db_find_next_volume(jcr->db, index, &mr)) {
+ jcr->MediaId = mr.MediaId;
+ Dmsg1(20, "Find_next_vol MediaId=%d\n", jcr->MediaId);
+ strcpy(jcr->VolumeName, mr.VolumeName);
+ ok = TRUE;
+ } else {
+ /* See if we can create a new Volume */
+ ok = newVolume(jcr);
+ }
}
/*
* Send Find Media response to Storage daemon
bash_spaces(mr.VolumeName);
bnet_fsend(bs, OK_media, mr.VolumeName, mr.VolJobs,
mr.VolFiles, mr.VolBlocks, mr.VolBytes, mr.VolMounts, mr.VolErrors,
- mr.VolWrites, mr.VolMaxBytes, mr.VolCapacityBytes);
+ mr.VolWrites, mr.VolMaxBytes, mr.VolCapacityBytes,
+ mr.VolStatus);
} else {
bnet_fsend(bs, "1999 No Media\n");
}
/*
* Request to find specific volume information
*/
- } else if (sscanf(bs->msg, Find_Vol_Info, &Job, &mr.VolumeName) == 2) {
+ } else if (sscanf(bs->msg, Get_Vol_Info, &Job, &mr.VolumeName) == 2) {
Dmsg1(120, "CatReq GetVolInfo Vol=%s\n", mr.VolumeName);
/*
* Find the Volume
Dmsg1(20, "VolumeInfo MediaId=%d\n", jcr->MediaId);
strcpy(jcr->VolumeName, mr.VolumeName);
/*
- * Make sure this volume is suitable for this job
+ * Make sure this volume is suitable for this job, i.e.
+ * it is either Append or Recycle and Media Type matches.
*/
if (mr.PoolId == jcr->PoolId &&
- strcmp(mr.VolStatus, "Append") == 0 &&
+ (strcmp(mr.VolStatus, "Append") == 0 ||
+ strcmp(mr.VolStatus, "Recycle") == 0) &&
strcmp(mr.MediaType, jcr->store->media_type) == 0) {
/*
* Send Find Media response to Storage daemon
bash_spaces(mr.VolumeName);
bnet_fsend(bs, OK_media, mr.VolumeName, mr.VolJobs,
mr.VolFiles, mr.VolBlocks, mr.VolBytes, mr.VolMounts, mr.VolErrors,
- mr.VolWrites, mr.VolMaxBytes, mr.VolCapacityBytes);
+ mr.VolWrites, mr.VolMaxBytes, mr.VolCapacityBytes,
+ mr.VolStatus);
} else {
Dmsg4(000, "get_media_record PoolId=%d wanted %d, Status=%s, \
MediaType=%s\n", mr.PoolId, jcr->PoolId, mr.VolStatus, mr.MediaType);
configfile = bstrdup(CONFIG_FILE);
}
- init_msg(NULL); /* initialize message handler */
+ init_msg(NULL, NULL); /* initialize message handler */
parse_config(configfile);
if (!check_resources()) {
Dmsg0(200, "Start UA server\n");
start_UA_server(director->DIRport);
- init_watchdog(); /* start network watchdog thread */
+ start_watchdog(); /* start network watchdog thread */
init_job_server(director->MaxConcurrentJobs);
exit(1);
}
already_here = TRUE;
- term_watchdog();
+ stop_watchdog();
signal(SIGCHLD, SIG_IGN); /* don't worry about children now */
term_scheduler();
if (runjob) {
* for the resource records.
*
* Kern Sibbald, January MM
+ *
+ * $Id:
*/
/*
Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
{"password", store_password, ITEM(res_dir.password), 0, ITEM_REQUIRED, 0},
{"fdconnecttimeout", store_time,ITEM(res_dir.FDConnectTimeout), 0, ITEM_DEFAULT, 60 * 30},
{"sdconnecttimeout", store_time,ITEM(res_dir.SDConnectTimeout), 0, ITEM_DEFAULT, 60 * 30},
-
{NULL, NULL, NULL, 0, 0, 0}
};
{"fdport", store_pint, ITEM(res_client.FDport), 0, ITEM_REQUIRED, 0},
{"password", store_password, ITEM(res_client.password), 0, ITEM_REQUIRED, 0},
{"catalog", store_res, ITEM(res_client.catalog), R_CATALOG, 0, 0},
- {"catalogretentionperiod", store_time,
- ITEM(res_client.cat_ret_period), 0, ITEM_DEFAULT, 60},
- {"mediaretentionperiod", store_time,
- ITEM(res_client.media_ret_period), 0, ITEM_DEFAULT, 60},
+ {"fileretention", store_time, ITEM(res_client.FileRetention), 0, ITEM_DEFAULT, 60*60*24*60},
+ {"jobretention", store_time, ITEM(res_client.JobRetention), 0, ITEM_DEFAULT, 60*60*24*180},
+ {"autoprune", store_yesno, ITEM(res_client.AutoPrune), 1, ITEM_DEFAULT, 1},
{NULL, NULL, NULL, 0, 0, 0}
};
*/
static struct res_items pool_items[] = {
{"name", store_name, ITEM(res_pool.hdr.name), 0, ITEM_REQUIRED, 0},
- {"description", store_str, ITEM(res_pool.hdr.desc), 0, 0, 0},
+ {"description", store_str, ITEM(res_pool.hdr.desc), 0, 0, 0},
{"pooltype", store_strname, ITEM(res_pool.pool_type), 0, ITEM_REQUIRED, 0},
- {"labelformat", store_strname, ITEM(res_pool.label_format), 0, 0, 0},
+ {"labelformat", store_strname, ITEM(res_pool.label_format), 0, 0, 0},
{"usecatalog", store_yesno, ITEM(res_pool.use_catalog), 1, ITEM_DEFAULT, 1},
- {"usevolumeonce", store_yesno, ITEM(res_pool.use_volume_once), 1, 0, 0},
+ {"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, 0, 0},
{"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},
+ {"recycle", store_yesno, ITEM(res_pool.Recycle), 1, ITEM_DEFAULT, 1},
{NULL, NULL, NULL, 0, 0, 0}
};
* level_name level level_class
*/
struct s_jl joblevels[] = {
- {"full", L_FULL, JT_BACKUP},
- {"incremental", L_INCREMENTAL, JT_BACKUP},
- {"differential", L_DIFFERENTIAL, JT_BACKUP},
- {"level", L_LEVEL, JT_BACKUP},
- {"since", L_SINCE, JT_BACKUP},
- {"catalog", L_VERIFY_CATALOG, JT_VERIFY},
- {"initcatalog", L_VERIFY_INIT, JT_VERIFY},
- {"volume", L_VERIFY_VOLUME, JT_VERIFY},
- {"data", L_VERIFY_DATA, JT_VERIFY},
+ {"Full", L_FULL, JT_BACKUP},
+ {"Incremental", L_INCREMENTAL, JT_BACKUP},
+ {"Differential", L_DIFFERENTIAL, JT_BACKUP},
+ {"Level", L_LEVEL, JT_BACKUP},
+ {"Since", L_SINCE, JT_BACKUP},
+ {"Catalog", L_VERIFY_CATALOG, JT_VERIFY},
+ {"Initcatalog", L_VERIFY_INIT, JT_VERIFY},
+ {"Volume", L_VERIFY_VOLUME, JT_VERIFY},
+ {"Data", L_VERIFY_DATA, JT_VERIFY},
{NULL, 0}
};
}
switch (type) {
case R_DIRECTOR:
- sendit(sock, "Director: name=%s maxjobs=%d FDtimeout=%d SDtimeout=%d\n",
+ char ed1[30], ed2[30];
+ sendit(sock, "Director: name=%s maxjobs=%d FDtimeout=%s SDtimeout=%s\n",
reshdr->name, res->res_dir.MaxConcurrentJobs,
- res->res_dir.FDConnectTimeout,
- res->res_dir.SDConnectTimeout);
+ edit_uint64(res->res_dir.FDConnectTimeout, ed1),
+ edit_uint64(res->res_dir.SDConnectTimeout, ed2));
if (res->res_dir.query_file) {
sendit(sock, " query_file=%s\n", res->res_dir.query_file);
}
case R_CLIENT:
sendit(sock, "Client: name=%s address=%s FDport=%d\n",
res->res_client.hdr.name, res->res_client.address, res->res_client.FDport);
- sendit(sock, "CatRetPeriod=%d MediaRetPeriod=%d\n",
- res->res_client.cat_ret_period, res->res_client.media_ret_period);
+ sendit(sock, "JobRetention=%" lld " FileRetention=%" lld " AutoPrune=%d\n",
+ res->res_client.JobRetention, res->res_client.FileRetention,
+ res->res_client.AutoPrune);
if (res->res_client.catalog) {
sendit(sock, " --> ");
dump_resource(-R_CATALOG, (RES *)res->res_client.catalog, sendit, sock);
case R_POOL:
sendit(sock, "Pool: name=%s PoolType=%s\n", res->res_pool.hdr.name,
res->res_pool.pool_type);
- sendit(sock, " use_cat=%d use_once=%d acpt_any=%d\n",
+ sendit(sock, " use_cat=%d use_once=%d acpt_any=%d cat_files=%d\n",
res->res_pool.use_catalog, res->res_pool.use_volume_once,
- res->res_pool.accept_any_volume);
- sendit(sock, " cat_files=%d max_vols=%d\n",
- res->res_pool.catalog_files, res->res_pool.max_volumes);
+ res->res_pool.accept_any_volume, res->res_pool.catalog_files);
+ sendit(sock, " max_vols=%d auto_prune=%d VolRetention=%" lld "\n",
+ res->res_pool.max_volumes, res->res_pool.AutoPrune,
+ res->res_pool.VolRetention);
+ sendit(sock, " recycle=%d\n", res->res_pool.Recycle);
+
+
sendit(sock, " LabelFormat=%s\n", res->res_pool.label_format?
res->res_pool.label_format:"NONE");
break;
free(res->res_msgs.mail_cmd);
if (res->res_msgs.operator_cmd)
free(res->res_msgs.operator_cmd);
-
break;
case R_GROUP:
break;
Dmsg1(190, "Got keyword: %s\n", lc->str);
found = FALSE;
for (i=0; BakVerFields[i].name; i++) {
- if (strcmp(lc->str, BakVerFields[i].name) == 0) {
+ if (strcasecmp(lc->str, BakVerFields[i].name) == 0) {
found = TRUE;
if (lex_get_token(lc) != T_EQUALS) {
scan_err1(lc, "Expected an equals, got: %s", lc->str);
lcase(lc->str);
for (i=0; joblevels[i].level_name; i++) {
if (joblevels[i].job_class == item->code &&
- strcmp(lc->str, joblevels[i].level_name) == 0) {
+ strcasecmp(lc->str, joblevels[i].level_name) == 0) {
((JOB *)(item->value))->level = joblevels[i].level;
i = 0;
break;
/*
* Resource codes -- they must be sequential for indexing
*/
-#define R_FIRST 1001
+#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_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_LAST R_MSGS
+#define R_LAST R_MSGS
/*
* 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;
- int level;
- int job_class;
+ int level;
+ int job_class;
};
/* 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 *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 *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;
- int MaxConcurrentJobs;
- int FDConnectTimeout; /* timeout for connect in seconds */
- int 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;
*
*/
struct s_res_client {
- RES hdr;
+ RES hdr;
- int FDport; /* Where File daemon listens */
- int32_t cat_ret_period; /* Catalog retention period */
- int32_t media_ret_period; /* Media retention period */
+ 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 */
*
*/
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;
*
*/
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;
*
*/
struct s_res_job {
- RES hdr;
+ 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 */
- int RestoreOptions; /* How (overwrite, ..) */
- int MaxRunTime; /* max run time in seconds */
- int MaxStartDelay; /* max start delay in seconds */
+ 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 */
+ int RestoreOptions; /* How (overwrite, ..) */
+ btime_t MaxRunTime; /* max run time in seconds */
+ btime_t MaxStartDelay; /* max start delay in seconds */
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 *fs; /* What to backup -- Fileset */
+ struct s_res_fs *fs; /* 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;
*
*/
struct s_res_fs {
- RES hdr;
+ RES hdr;
char **include_array;
int num_includes;
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 */
};
typedef struct s_res_fs FILESET;
*
*/
struct s_res_sch {
- RES hdr;
+ RES hdr;
struct s_run *run;
};
*
*/
struct s_res_group {
- RES hdr;
+ RES hdr;
};
typedef struct s_res_group GROUP;
*
*/
struct s_res_pool {
- RES hdr;
+ RES hdr;
char *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 */
+ 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;
* 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;
RES hdr;
};
/* Run structure contained in Schedule Resource */
struct s_run {
- struct s_run *next; /* points to next run record */
+ struct s_run *next; /* points to next run record */
int level;
int job_class;
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 */
Dmsg0(100, "=====Start Job=========\n");
jcr->start_time = now; /* set the real start time */
if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay <
- (jcr->start_time - jcr->sched_time)) {
+ (btime_t)(jcr->start_time - jcr->sched_time)) {
Jmsg(jcr, M_FATAL, 0, _("Job cancelled because max delay time exceeded.\n"));
free_jcr(jcr);
}
jcr->pool = job->pool;
jcr->catalog = job->client->catalog;
jcr->fileset = job->fs;
+ init_msg(jcr, job->messages);
/* If no default level given, set one */
if (jcr->level == 0) {
switch (jcr->JobType) {
* This routine runs as a thread and must be thread reentrant.
*
* Basic tasks done here:
- * If possible create a new Media entry
+ * If possible create a new Media entry
*
*/
/*
if (db_get_pool_record(jcr->db, &pr) && pr.LabelFormat[0] &&
pr.LabelFormat[0] != '*') {
if (pr.MaxVols == 0 || pr.NumVols < pr.MaxVols) {
- memset(&mr, 0, sizeof(mr));
- mr.PoolId = jcr->PoolId;
- strcpy(mr.MediaType, jcr->store->media_type);
- strcpy(name, pr.LabelFormat);
+ memset(&mr, 0, sizeof(mr));
+ mr.PoolId = jcr->PoolId;
+ strcpy(mr.MediaType, jcr->store->media_type);
+ strcpy(name, pr.LabelFormat);
strcat(name, "%04d");
- sprintf(mr.VolumeName, name, ++pr.NumVols);
+ sprintf(mr.VolumeName, name, ++pr.NumVols);
strcpy(mr.VolStatus, "Append");
- strcpy(mr.Recycle, "No");
- if (db_create_media_record(jcr->db, &mr) &&
- db_update_pool_record(jcr->db, &pr) == 1) {
+ mr.Recycle = pr.Recycle;
+ mr.VolRetention = pr.VolRetention;
+ if (db_create_media_record(jcr->db, &mr) &&
+ db_update_pool_record(jcr->db, &pr) == 1) {
Dmsg1(90, "Created new Volume=%s\n", mr.VolumeName);
- return 1;
- } else {
+ return 1;
+ } else {
Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
- }
+ }
}
}
return 0;
/*
* Director external function prototypes
+ *
+ * $Id:
*/
/*
Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
/* fd_cmds.c */
extern int connect_to_file_daemon(JCR *jcr, int retry_interval,
- int max_retry_time, int verbose);
+ int max_retry_time, int verbose);
extern int send_include_list(JCR *jcr);
extern int send_exclude_list(JCR *jcr);
extern int get_attributes_and_put_in_catalog(JCR *jcr);
extern int get_attributes_and_compare_to_catalog(JCR *jcr, int last_full_id);
extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname,
- char *link, char *attr, int stream);
+ char *link, char *attr, int stream);
/* job.c */
extern void free_jcr(JCR *jcr);
/* msgchan.c */
extern int connect_to_storage_daemon(JCR *jcr, int retry_interval,
- int max_retry_time, int verbose);
+ int max_retry_time, int verbose);
extern int start_storage_daemon_job(JCR *jcr);
extern int start_storage_daemon_message_thread(JCR *jcr);
extern int32_t bget_msg(BSOCK *bs, int type);
/* newvol.c */
extern int newVolume(JCR *jcr);
-/* ua_cmds.c */
+/* ua_cmd.c */
extern int create_pool(B_DB *db, POOL *pool);
*/
memset(&cr, 0, sizeof(cr));
strcpy(cr.Name, jcr->client->hdr.name);
+ cr.AutoPrune = jcr->client->AutoPrune;
+ cr.FileRetention = jcr->client->FileRetention;
+ cr.JobRetention = jcr->client->JobRetention;
if (jcr->client_name) {
free(jcr->client_name);
}
} else {
lcase(lc->str);
for (i=0; joblevels[i].level_name; i++) {
- if (strcmp(lc->str, joblevels[i].level_name) == 0) {
+ if (strcasecmp(lc->str, joblevels[i].level_name) == 0) {
lrun.level = joblevels[i].level;
lrun.job_class = joblevels[i].job_class;
i = 0;
* Includes specific to the Director User Agent Server
*
* Kern Sibbald, August MMI
+ *
+ * $Id:
*/
/*
Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
JCR *jcr;
B_DB *db;
CAT *catalog;
- char *cmd; /* return command/name buffer */
- char *args; /* command line arguments */
- char *argk[MAX_ARGS]; /* argument keywords */
- char *argv[MAX_ARGS]; /* argument values */
- int argc; /* number of arguments */
- char **prompt; /* list of prompts */
- int max_prompts; /* max size of list */
- int num_prompts; /* current number in list */
- int auto_display_messages; /* if set, display messages */
+ char *cmd; /* return command/name buffer */
+ char *args; /* command line arguments */
+ char *argk[MAX_ARGS]; /* argument keywords */
+ char *argv[MAX_ARGS]; /* argument values */
+ int argc; /* number of arguments */
+ char **prompt; /* list of prompts */
+ int max_prompts; /* max size of list */
+ int num_prompts; /* current number in list */
+ int auto_display_messages; /* if set, display messages */
int user_notified_msg_pending; /* set when user notified */
- int automount; /* if set, mount after label */
+ int automount; /* if set, mount after label */
+ int quit; /* if set, quit */
+ int verbose; /* set for normal UA verbosity */
} UAContext;
/* ua_cmds.c */
int select_pool_dbr(UAContext *ua, POOL_DBR *pr);
CLIENT *select_client_resource(UAContext *ua);
FILESET *select_fs_resource(UAContext *ua);
+int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
void start_prompt(UAContext *ua, char *msg);
void add_prompt(UAContext *ua, char *prompt);
int do_prompt(UAContext *ua, char *msg, char *prompt);
-CAT *get_catalog_resource(UAContext *ua);
+CAT *get_catalog_resource(UAContext *ua);
STORE *get_storage_resource(UAContext *ua, char *cmd);
int get_media_type(UAContext *ua, char *MediaType);
int get_pool_dbr(UAContext *ua, POOL_DBR *pr);
POOL *get_pool_resource(UAContext *ua);
CLIENT *get_client_resource(UAContext *ua);
+int get_job_dbr(UAContext *ua, JOB_DBR *jr);
int find_arg_keyword(UAContext *ua, char **list);
int do_keyword_prompt(UAContext *ua, char *msg, char **list);
+int confirm_retention(UAContext *ua, btime_t *ret, char *msg);
extern void run_job(JCR *jcr);
/* Imported variables */
-extern struct s_jl joblevels[];
extern int r_first;
extern int r_last;
extern struct s_res resources[];
extern int querycmd(UAContext *ua, char *cmd);
extern int runcmd(UAContext *ua, char *cmd);
extern int retentioncmd(UAContext *ua, char *cmd);
+extern int prunecmd(UAContext *ua, char *cmd);
+extern int purgecmd(UAContext *ua, char *cmd);
/* Forward referenced functions */
static int addcmd(UAContext *ua, char *cmd), createcmd(UAContext *ua, char *cmd), cancelcmd(UAContext *ua, char *cmd);
static int usecmd(UAContext *ua, char *cmd), unmountcmd(UAContext *ua, char *cmd);
static int labelcmd(UAContext *ua, char *cmd), mountcmd(UAContext *ua, char *cmd), updatecmd(UAContext *ua, char *cmd);
static int versioncmd(UAContext *ua, char *cmd), automountcmd(UAContext *ua, char *cmd);
-static int update_media(UAContext *ua);
+static int update_volume(UAContext *ua);
static int update_pool(UAContext *ua);
-static int delete_media(UAContext *ua);
+static int delete_volume(UAContext *ua);
static int delete_pool(UAContext *ua);
int quitcmd(UAContext *ua, char *cmd);
{ N_("list"), listcmd, _("list [pools | jobs | jobtotals | media <pool> | files job=<nn>]; from catalog")},
{ N_("messages"), messagescmd, _("messages")},
{ N_("mount"), mountcmd, _("mount <storage-name>")},
- { N_("retention"), retentioncmd, _("retention")},
+ { N_("prune"), prunecmd, _("prune expired records from catalog")},
+ { N_("purge"), purgecmd, _("purge records from catalog")},
{ N_("run"), runcmd, _("run <job-name>")},
{ N_("setdebug"), setdebugcmd, _("sets debug level")},
{ N_("show"), showcmd, _("show (resource records) [jobs | pools | ... | all]")},
mr.PoolId = pr.PoolId;
strcpy(mr.VolStatus, "Append");
- strcpy(mr.Recycle, "No");
+ mr.Recycle = pr.Recycle;
+ mr.VolRetention = pr.VolRetention;
for (i=startnum; i < num+startnum; i++) {
sprintf(mr.VolumeName, name, i);
Dmsg1(200, "Create Volume %s\n", mr.VolumeName);
pr.UseOnce = pool->use_volume_once;
pr.UseCatalog = pool->use_catalog;
pr.AcceptAnyVolume = pool->accept_any_volume;
+ pr.Recycle = pool->Recycle;
+ pr.VolRetention = pool->VolRetention;
+Dmsg1(000, "Retention=%d\n", (uint32_t)pr.VolRetention);
+ pr.AutoPrune = pool->AutoPrune;
if (pool->label_format) {
strcpy(pr.LabelFormat, pool->label_format);
} else {
switch (find_arg_keyword(ua, kw)) {
case 0:
case 1:
- update_media(ua);
+ update_volume(ua);
return 1;
case 2:
update_pool(ua);
start_prompt(ua, _("Update choice:\n"));
add_prompt(ua, _("pool"));
- add_prompt(ua, _("media"));
+ add_prompt(ua, _("volume"));
switch (do_prompt(ua, _("Choose catalog item to update"), NULL)) {
case 0:
update_pool(ua);
break;
case 1:
- update_media(ua);
+ update_volume(ua);
break;
default:
break;
* writing on the volume, set it to anything other
* than Append.
*/
-static int update_media(UAContext *ua)
+static int update_volume(UAContext *ua)
{
POOL_DBR pr;
MEDIA_DBR mr;
static char *kw[] = {
"volume",
NULL};
+ char *query;
+ char ed1[30];
memset(&pr, 0, sizeof(pr));
memset(&mr, 0, sizeof(mr));
if (!get_pool_dbr(ua, &pr)) {
- return 1;
+ return 0;
}
mr.PoolId = pr.PoolId;
mr.VolumeName[0] = 0;
if (mr.VolumeName[0] == 0) {
db_list_media_records(ua->db, &mr, prtit, ua);
if (!get_cmd(ua, _("Enter Volume name to update: "))) {
- return 1;
+ return 0;
}
strcpy(mr.VolumeName, ua->cmd);
}
mr.MediaId = 0;
if (!db_get_media_record(ua->db, &mr)) {
- bsendmsg(ua, _("Media record for %s not found.\n"), mr.VolumeName);
- return 1;
+ bsendmsg(ua, _("Volume record for %s not found.\n"), mr.VolumeName);
+ return 0;
}
- start_prompt(ua, _("Volume Status Values:\n"));
- add_prompt(ua, "Append");
- add_prompt(ua, "Archive");
- add_prompt(ua, "Disabled");
- add_prompt(ua, "Full");
- add_prompt(ua, "Recycle");
- add_prompt(ua, "Read-Only");
- if (do_prompt(ua, _("Choose new Volume Status"), ua->cmd) < 0) {
- return 1;
+
+ for (int done=0; !done; ) {
+ start_prompt(ua, _("Parameters to modify:\n"));
+ add_prompt(ua, _("Volume Status"));
+ add_prompt(ua, _("Volume Retention"));
+ add_prompt(ua, _("Done"));
+ switch (do_prompt(ua, _("Select paramter to modify"), NULL)) {
+ case 0: /* Volume Status */
+ /* Modify Volume */
+ bsendmsg(ua, _("Current value is: %s\n"), mr.VolStatus);
+ start_prompt(ua, _("Possible Values are:\n"));
+ add_prompt(ua, "Append");
+ add_prompt(ua, "Archive");
+ add_prompt(ua, "Disabled");
+ add_prompt(ua, "Full");
+ if (strcmp(mr.VolStatus, "Purged") == 0) {
+ add_prompt(ua, "Recycle");
+ }
+ add_prompt(ua, "Read-Only");
+ if (do_prompt(ua, _("Choose new Volume Status"), ua->cmd) < 0) {
+ return 1;
+ }
+ strcpy(mr.VolStatus, ua->cmd);
+ query = (char *)get_pool_memory(PM_MESSAGE);
+ Mmsg(&query, "UPDATE Media SET VolStatus=\"%s\" WHERE MediaId=%d",
+ mr.VolStatus, mr.MediaId);
+ if (!db_sql_query(ua->db, query, NULL, NULL)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ }
+ free_pool_memory(query);
+ break;
+ case 1: /* Retention */
+ bsendmsg(ua, _("Current value is: %s\n"),
+ edit_btime(mr.VolRetention, ed1));
+ if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
+ return 0;
+ }
+ if (!string_to_btime(ua->cmd, &mr.VolRetention)) {
+ bsendmsg(ua, _("Invalid retention period specified.\n"));
+ break;
+ }
+ query = (char *)get_pool_memory(PM_MESSAGE);
+ Mmsg(&query, "UPDATE Media SET VolRetention=%s WHERE MediaId=%d",
+ edit_uint64(mr.VolRetention, ed1), mr.MediaId);
+ if (!db_sql_query(ua->db, query, NULL, NULL)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ }
+ free_pool_memory(query);
+ break;
+ default: /* Done or error */
+ return 0;
+ }
}
- strcpy(mr.VolStatus, ua->cmd);
- db_update_media_record(ua->db, &mr);
return 1;
}
switch (find_arg_keyword(ua, keywords)) {
case 0:
- delete_media(ua);
+ delete_volume(ua);
return 1;
case 1:
delete_pool(ua);
}
switch (do_keyword_prompt(ua, _("Choose catalog item to delete"), keywords)) {
case 0:
- delete_media(ua);
+ delete_volume(ua);
break;
case 1:
delete_pool(ua);
/*
* Delete media records from database -- dangerous
*/
-static int delete_media(UAContext *ua)
+static int delete_volume(UAContext *ua)
{
POOL_DBR pr;
MEDIA_DBR mr;
- int found = FALSE;
- int i;
- memset(&pr, 0, sizeof(pr));
- memset(&mr, 0, sizeof(mr));
-
- /* Get the pool, possibly from pool=<pool-name> */
- if (!get_pool_dbr(ua, &pr)) {
+ if (!select_pool_and_media_dbr(ua, &pr, &mr)) {
return 1;
}
- mr.PoolId = pr.PoolId;
+ bsendmsg(ua, _("\nThis command will delete volume %s\n"
+ "and all Jobs saved on that volume from the Catalog\n"),
+ mr.VolumeName);
- /* See if a volume name is specified as an argument */
- for (i=1; i<ua->argc; i++) {
- if (strcasecmp(ua->argk[i], _("volume")) == 0 && ua->argv[i]) {
- found = TRUE;
- break;
- }
- }
- if (found) {
- strcpy(mr.VolumeName, ua->argv[i]);
- } else {
- db_list_media_records(ua->db, &mr, prtit, ua);
- if (!get_cmd(ua, _("Enter the Volume name to delete: "))) {
- return 1;
- }
- }
- mr.MediaId = 0;
- strcpy(mr.VolumeName, ua->cmd);
if (!get_cmd(ua, _("If you want to continue enter pretty please: "))) {
return 1;
}
return 1;
}
mr.PoolId = pr.PoolId;
- strcpy(mr.Recycle, "Yes");
strcpy(mr.VolStatus, "Append");
+ mr.Recycle = pr.Recycle;
+ mr.VolRetention = pr.VolRetention;
ua->jcr->store = store;
bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d ...\n"),
bnet_fsend(sd, _("label %s VolumeName=%s PoolName=%s MediaType=%s"),
dev_name, mr.VolumeName, pr.Name, mr.MediaType);
bsendmsg(ua, "Sending label command ...\n");
- while (bnet_recv(sd) > 0) {
+ while (bget_msg(sd, 0) > 0) {
bsendmsg(ua, "%s", sd->msg);
if (strncmp(sd->msg, "3000 OK label.", 14) == 0) {
ok = TRUE;
mr.VolumeName);
if (ua->automount) {
bsendmsg(ua, _("Requesting mount %s ...\n"), dev_name);
+ bash_spaces(dev_name);
bnet_fsend(sd, "mount %s", dev_name);
+ unbash_spaces(dev_name);
while (bnet_recv(sd) > 0) {
bsendmsg(ua, "%s", sd->msg);
/* Here we can get
int quitcmd(UAContext *ua, char *cmd)
{
- return 0;
+ ua->quit = TRUE;
+ return 1;
}
static int helpcmd(UAContext *ua, char *cmd)
close_db(ua);
return 0;
}
+ ua->jcr->db = ua->db;
Dmsg1(50, "DB %s opened\n", ua->catalog->db_name);
return 1;
}
db_close_database(ua->db);
}
ua->db = NULL;
+ ua->jcr->db = NULL;
}
#include "ua.h"
/* Imported variables */
-extern struct s_jl joblevels[];
extern int r_first;
extern int r_last;
extern struct s_res resources[];
BSOCK *sock = ua->UA_sock;
ua->cmd[0] = 0;
+ if (!sock) { /* No UA */
+ return 0;
+ }
bnet_fsend(sock, "%s", prompt);
bnet_sig(sock, BNET_PROMPT); /* request more input */
- if (bnet_recv(sock) < 0) {
- return 0;
+ for ( ;; ) {
+ if (bnet_recv(sock) < 0) {
+ return 0;
+ }
+ ua->cmd = (char *) check_pool_memory_size(ua->cmd, sock->msglen+1);
+ strcpy(ua->cmd, sock->msg);
+ ua->cmd[sock->msglen] = 0;
+ strip_trailing_junk(ua->cmd);
+ if (strcmp(ua->cmd, ".messages") == 0) {
+ qmessagescmd(ua, ua->cmd);
+ }
+ /* ****FIXME**** if .command, go off and do it. For now ignore it. */
+ if (ua->cmd[0] == '.' && ua->cmd[1] != 0) {
+ continue; /* dot command */
+ }
+ /* Lone dot => break or actual response */
+ break;
}
- ua->cmd = (char *) check_pool_memory_size(ua->cmd, sock->msglen+1);
- strcpy(ua->cmd, sock->msg);
- ua->cmd[sock->msglen] = 0;
- strip_trailing_junk(ua->cmd);
return 1;
}
extern void run_job(JCR *jcr);
/* Imported variables */
-extern struct s_jl joblevels[];
extern int r_first;
extern int r_last;
extern struct s_res resources[];
}
-/*
- * Callback routine for "printing" database file listing
- */
-void prtit(void *ctx, char *msg)
-{
- UAContext *ua = (UAContext *)ctx;
-
- bnet_fsend(ua->UA_sock, "%s", msg);
-}
-
-/* Format message and send to other end */
-void bsendmsg(void *ctx, char *fmt, ...)
-{
- va_list arg_ptr;
- UAContext *ua = (UAContext *)ctx;
- BSOCK *bs = ua->UA_sock;
- int maxlen;
-
-again:
- maxlen = sizeof_pool_memory(bs->msg) - 1;
- va_start(arg_ptr, fmt);
- bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
- va_end(arg_ptr);
- if (bs->msglen < 0 || bs->msglen >= maxlen) {
- bs->msg = (char *) realloc_pool_memory(bs->msg, maxlen + 200);
- goto again;
- }
- bnet_send(bs);
-}
/*
}
return 1;
}
+
+/*
+ * Callback routine for "printing" database file listing
+ */
+void prtit(void *ctx, char *msg)
+{
+ UAContext *ua = (UAContext *)ctx;
+
+ bnet_fsend(ua->UA_sock, "%s", msg);
+}
+
+/*
+ * Format message and send to other end.
+
+ * If the UA_sock is NULL, it means that there is no user
+ * agent, so we are being called from Bacula core. In
+ * that case direct the messages to the Job.
+ */
+void bsendmsg(void *ctx, char *fmt, ...)
+{
+ va_list arg_ptr;
+ UAContext *ua = (UAContext *)ctx;
+ BSOCK *bs = ua->UA_sock;
+ int maxlen, len;
+ char *msg;
+
+ if (bs) {
+ msg = bs->msg;
+ } else {
+ msg = (char *)get_pool_memory(PM_EMSG);
+ }
+
+again:
+ maxlen = sizeof_pool_memory(msg) - 1;
+ va_start(arg_ptr, fmt);
+ len = bvsnprintf(msg, maxlen, fmt, arg_ptr);
+ va_end(arg_ptr);
+ if (len < 0 || len >= maxlen) {
+ msg = (char *) realloc_pool_memory(msg, maxlen + 200);
+ goto again;
+ }
+
+ if (bs) {
+ bs->msglen = len;
+ bnet_send(bs);
+ } else { /* No UA, send to Job */
+ Jmsg(ua->jcr, M_INFO, 0, msg);
+ free_memory(msg);
+ }
+
+}
--- /dev/null
+/*
+ *
+ * Bacula Director -- User Agent Database prune Command
+ * Applies retention periods
+ *
+ * Kern Sibbald, February MMII
+ *
+ * $Id:
+ */
+
+/*
+ Copyright (C) 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 "dird.h"
+#include "ua.h"
+
+/* Forward referenced functions */
+int prune_files(UAContext *ua, CLIENT *client);
+int prune_jobs(UAContext *ua, CLIENT *client);
+int prune_volume(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
+static int mark_media_purged(UAContext *ua, MEDIA_DBR *mr);
+
+
+#define MAX_DEL_LIST_LEN 1000000
+
+/*
+ * Select JobIds for File deletion.
+ */
+static char *select_job =
+ "SELECT JobId from Job "
+ "WHERE JobTDate < %s "
+ "AND ClientId=%d "
+ "AND PurgedFiles=0";
+
+/*
+ * List of SQL commands terminated by NULL for deleting
+ * temporary tables and indicies
+ */
+static char *drop_deltabs[] = {
+ "DROP TABLE DelCandidates",
+ "DROP INDEX DelInx1",
+ NULL};
+
+/*
+ * List of SQL commands to create temp table and indicies
+ */
+static char *create_deltabs[] = {
+ "CREATE TABLE DelCandidates ("
+ "JobId INTEGER UNSIGNED NOT NULL, "
+ "PurgedFiles TINYINT, "
+ "FileSetId INTEGER UNSIGNED)",
+ "CREATE INDEX DelInx1 ON DelCandidates (JobId)",
+ NULL};
+
+
+/*
+ * Fill candidates table with all Files subject to being deleted
+ */
+static char *insert_delcand =
+ "INSERT INTO DelCandidates "
+ "SELECT JobId, PurgedFiles, FileSetId FROM Job "
+ "WHERE JobTDate < %s "
+ "AND ClientId=%d";
+
+/*
+ * Select files from the DelCandidates table that have a
+ * more recent backup -- i.e. are not the only backup.
+ * This is the list of files to delete.
+ */
+static char *select_del =
+ "SELECT DelCandidates.JobId "
+ "FROM Job,DelCandidates "
+ "WHERE Job.JobTDate >= %s "
+ "AND Job.ClientId=%d "
+ "AND Job.Level='F' "
+ "AND Job.JobStatus='T' "
+ "AND Job.FileSetId=DelCandidates.FileSetId";
+
+/* In memory list of JobIds */
+struct s_file_del_ctx {
+ JobId_t *JobId;
+ int num_ids; /* ids stored */
+ int max_ids; /* size of array */
+ int num_del; /* number deleted */
+ int tot_ids; /* total to process */
+};
+
+struct s_job_del_ctx {
+ JobId_t *JobId; /* array of JobIds */
+ char *PurgedFiles; /* Array of PurgedFile flags */
+ int num_ids; /* ids stored */
+ int max_ids; /* size of array */
+ int num_del; /* number deleted */
+ int tot_ids; /* total to process */
+};
+
+struct s_count_ctx {
+ int count;
+};
+
+
+/*
+ * Called here to count entries to be deleted
+ */
+static int count_handler(void *ctx, int num_fields, char **row)
+{
+ struct s_count_ctx *cnt = (struct s_count_ctx *)ctx;
+
+ if (row[0]) {
+ cnt->count = atoi(row[0]);
+ } else {
+ cnt->count = 0;
+ }
+ return 0;
+}
+
+
+/*
+ * Called here to count entries to be deleted
+ */
+static int file_count_handler(void *ctx, int num_fields, char **row)
+{
+ struct s_file_del_ctx *del = (struct s_file_del_ctx *)ctx;
+ del->tot_ids++;
+ return 0;
+}
+
+
+/*
+ * Called here to make in memory list of JobIds to be
+ * deleted and the associated PurgedFiles flag.
+ * The in memory list will then be transversed
+ * to issue the SQL DELETE commands. Note, the list
+ * is allowed to get to MAX_DEL_LIST_LEN to limit the
+ * maximum malloc'ed memory.
+ */
+static int job_delete_handler(void *ctx, int num_fields, char **row)
+{
+ struct s_job_del_ctx *del = (struct s_job_del_ctx *)ctx;
+
+ if (del->num_ids == MAX_DEL_LIST_LEN) {
+ return 1;
+ }
+ if (del->num_ids == del->max_ids) {
+ del->max_ids = (del->max_ids * 3) / 2;
+ del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) * del->max_ids);
+ del->PurgedFiles = (char *)brealloc(del->PurgedFiles, del->max_ids);
+ }
+ del->JobId[del->num_ids] = (JobId_t)strtod(row[0], NULL);
+ del->PurgedFiles[del->num_ids++] = (char)atoi(row[0]);
+ return 0;
+}
+
+static int file_delete_handler(void *ctx, int num_fields, char **row)
+{
+ struct s_file_del_ctx *del = (struct s_file_del_ctx *)ctx;
+
+ if (del->num_ids == MAX_DEL_LIST_LEN) {
+ return 1;
+ }
+ if (del->num_ids == del->max_ids) {
+ del->max_ids = (del->max_ids * 3) / 2;
+ del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) *
+ del->max_ids);
+ }
+ del->JobId[del->num_ids++] = (JobId_t)strtod(row[0], NULL);
+ return 0;
+}
+
+/*
+ * Prune records from database
+ *
+ * prune files (from) client=xxx
+ * prune jobs (from) client=xxx
+ * prune volume=xxx
+ */
+int prunecmd(UAContext *ua, char *cmd)
+{
+ CLIENT *client;
+ POOL_DBR pr;
+ MEDIA_DBR mr;
+
+ static char *keywords[] = {
+ N_("Files"),
+ N_("Jobs"),
+ N_("Volume"),
+ NULL};
+ if (!open_db(ua)) {
+ return 01;
+ }
+ switch (find_arg_keyword(ua, keywords)) {
+ case 0:
+ client = select_client_resource(ua);
+ if (!client || !confirm_retention(ua, &client->FileRetention, "File")) {
+ return 0;
+ }
+ prune_files(ua, client);
+ return 1;
+ case 1:
+ client = select_client_resource(ua);
+ if (!client || !confirm_retention(ua, &client->JobRetention, "Job")) {
+ return 0;
+ }
+ prune_jobs(ua, client);
+ return 1;
+ case 2:
+ if (!select_pool_and_media_dbr(ua, &pr, &mr)) {
+ return 0;
+ }
+ if (!confirm_retention(ua, &mr.VolRetention, "Volume")) {
+ return 0;
+ }
+ prune_volume(ua, &pr, &mr);
+ return 1;
+ default:
+ break;
+ }
+ switch (do_keyword_prompt(ua, _("Choose item to prune"), keywords)) {
+ case 0:
+ client = select_client_resource(ua);
+ if (!client || !confirm_retention(ua, &client->FileRetention, "File")) {
+ return 0;
+ }
+ prune_files(ua, client);
+ break;
+ case 1:
+ client = select_client_resource(ua);
+ if (!client || !confirm_retention(ua, &client->JobRetention, "Job")) {
+ return 0;
+ }
+ prune_jobs(ua, client);
+ break;
+ case 2:
+ if (!select_pool_and_media_dbr(ua, &pr, &mr)) {
+ return 0;
+ }
+ if (!confirm_retention(ua, &mr.VolRetention, "Volume")) {
+ return 0;
+ }
+ prune_volume(ua, &pr, &mr);
+ return 1;
+ }
+ return 1;
+}
+
+/*
+ * Prune File records from the database. For any Job which
+ * is older than the retention period, we unconditionally delete
+ * all File records for that Job. This is simple enough that no
+ * temporary tables are needed. We simply make an in memory list of
+ * the JobIds meeting the prune conditions, then delete all File records
+ * pointing to each of those JobIds.
+ */
+int prune_files(UAContext *ua, CLIENT *client)
+{
+ struct s_file_del_ctx del;
+ char *query = (char *)get_pool_memory(PM_MESSAGE);
+ int i;
+ btime_t now, period;
+ CLIENT_DBR cr;
+ char ed1[50];
+
+ memset(&cr, 0, sizeof(cr));
+ memset(&del, 0, sizeof(del));
+ strcpy(cr.Name, client->hdr.name);
+ if (!db_create_client_record(ua->db, &cr)) {
+ return 0;
+ }
+
+ period = client->FileRetention;
+ now = (btime_t)time(NULL);
+
+ Mmsg(&query, select_job, edit_uint64(now - period, ed1), cr.ClientId);
+
+ Dmsg1(050, "select sql=%s\n", query);
+
+ if (!db_sql_query(ua->db, query, file_count_handler, (void *)&del)) {
+ if (ua->verbose) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ }
+ Dmsg0(050, "Count failed\n");
+ goto bail_out;
+ }
+
+ if (del.tot_ids == 0) {
+ if (ua->verbose) {
+ bsendmsg(ua, _("No Files found for client %s to prune from %s catalog.\n"),
+ client->hdr.name, client->catalog->hdr.name);
+ }
+ goto bail_out;
+ }
+
+ if (del.tot_ids < MAX_DEL_LIST_LEN) {
+ del.max_ids = del.tot_ids + 1;
+ } else {
+ del.max_ids = MAX_DEL_LIST_LEN;
+ }
+ del.tot_ids = 0;
+
+ del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids);
+
+ db_sql_query(ua->db, query, file_delete_handler, (void *)&del);
+
+ for (i=0; i < del.num_ids; i++) {
+ Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]);
+ Mmsg(&query, "DELETE FROM File WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ /*
+ * Now mark Job as having files purged. This is necessary to
+ * avoid having too many Jobs to process in future prunings. If
+ * we don't do this, the number of JobId's in our in memory list
+ * will grow very large.
+ */
+ Mmsg(&query, "UPDATE Job Set PurgedFiles=1 WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ Dmsg1(050, "Del sql=%s\n", query);
+ }
+ bsendmsg(ua, _("Pruned %d Files for client %s from %s catalog.\n"), del.num_ids,
+ client->hdr.name, client->catalog->hdr.name);
+
+bail_out:
+ if (del.JobId) {
+ free(del.JobId);
+ }
+ free_pool_memory(query);
+ return 1;
+}
+
+
+static void drop_temp_tables(UAContext *ua)
+{
+ int i;
+ for (i=0; drop_deltabs[i]; i++) {
+ db_sql_query(ua->db, drop_deltabs[i], NULL, (void *)NULL);
+ }
+}
+
+static int create_temp_tables(UAContext *ua)
+{
+ int i;
+ /* Create temp tables and indicies */
+ for (i=0; create_deltabs[i]; i++) {
+ if (!db_sql_query(ua->db, create_deltabs[i], NULL, (void *)NULL)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ Dmsg0(050, "create DelTables table failed\n");
+ return 0;
+ }
+ }
+ return 1;
+}
+
+
+
+/*
+ * Purging Jobs is a bit more complicated than purging Files
+ * because we delete Job records only if there is a more current
+ * backup of the FileSet. Otherwise, we keep the Job record.
+ * In other words, we never delete the only Job record that
+ * contains a current backup of a FileSet. This prevents the
+ * Volume from being recycled and destroying a current backup.
+ */
+int prune_jobs(UAContext *ua, CLIENT *client)
+{
+ struct s_job_del_ctx del;
+ struct s_count_ctx cnt;
+ char *query = (char *)get_pool_memory(PM_MESSAGE);
+ int i;
+ btime_t now, period;
+ CLIENT_DBR cr;
+ char ed1[50];
+
+ memset(&cr, 0, sizeof(cr));
+ memset(&del, 0, sizeof(del));
+ strcpy(cr.Name, client->hdr.name);
+ if (!db_create_client_record(ua->db, &cr)) {
+ return 0;
+ }
+
+ period = client->JobRetention;
+ now = (btime_t)time(NULL);
+
+ /* Drop any previous temporary tables still there */
+ drop_temp_tables(ua);
+
+ /* Create temp tables and indicies */
+ if (!create_temp_tables(ua)) {
+ goto bail_out;
+ }
+
+ /*
+ * Select all files that are older than the JobRetention period
+ * and stuff them into the "DeletionCandidates" table.
+ */
+ edit_uint64(now - period, ed1);
+ Mmsg(&query, insert_delcand, ed1, cr.ClientId);
+
+ if (!db_sql_query(ua->db, query, NULL, (void *)NULL)) {
+ if (ua->verbose) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ }
+ Dmsg0(050, "insert delcand failed\n");
+ goto bail_out;
+ }
+
+ strcpy(query, "SELECT count(*) FROM DelCandidates");
+
+ Dmsg1(100, "select sql=%s\n", query);
+
+ if (!db_sql_query(ua->db, query, count_handler, (void *)&cnt)) {
+ if (ua->verbose) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ }
+ Dmsg0(050, "Count failed\n");
+ goto bail_out;
+ }
+
+ if (cnt.count == 0) {
+ if (ua->verbose) {
+ bsendmsg(ua, _("No Jobs for client %s found to prune from %s catalog.\n"),
+ client->hdr.name, client->catalog->hdr.name);
+ }
+ goto bail_out;
+ }
+
+ if (cnt.count < MAX_DEL_LIST_LEN) {
+ del.max_ids = cnt.count + 1;
+ } else {
+ del.max_ids = MAX_DEL_LIST_LEN;
+ }
+ del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids);
+ del.PurgedFiles = (char *)malloc(del.max_ids);
+
+ Mmsg(&query, select_del, ed1, cr.ClientId);
+ db_sql_query(ua->db, query, job_delete_handler, (void *)&del);
+
+ /*
+ * OK, now we have the list of JobId's to be pruned, first check
+ * if the Files have been purged, if not, purge (delete) them.
+ * Then delete the Job entry, and finally and JobMedia records.
+ */
+ for (i=0; i < del.num_ids; i++) {
+ Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]);
+ if (!del.PurgedFiles[i]) {
+ Mmsg(&query, "DELETE FROM File WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ Dmsg1(050, "Del sql=%s\n", query);
+ }
+
+ Mmsg(&query, "DELETE FROM Job WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ Dmsg1(050, "Del sql=%s\n", query);
+
+ Mmsg(&query, "DELETE FROM JobMedia WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ Dmsg1(050, "Del sql=%s\n", query);
+ }
+ bsendmsg(ua, _("Pruned %d Jobs for client %s from %s catalog.\n"), del.num_ids,
+ client->hdr.name, client->catalog->hdr.name);
+
+bail_out:
+ drop_temp_tables(ua);
+ if (del.JobId) {
+ free(del.JobId);
+ }
+ if (del.PurgedFiles) {
+ free(del.PurgedFiles);
+ }
+ free_pool_memory(query);
+ return 1;
+}
+
+/*
+ * Prune volumes
+ */
+int prune_volume(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr)
+{
+ char *query = (char *)get_pool_memory(PM_MESSAGE);
+ struct s_count_ctx cnt;
+ struct s_file_del_ctx del;
+ int i;
+ JOB_DBR jr;
+ btime_t now, period;
+
+ memset(&jr, 0, sizeof(jr));
+ memset(&del, 0, sizeof(del));
+ cnt.count = 0;
+ Mmsg(&query, "SELECT count(*) FROM JobMedia WHERE MediaId=%d", mr->MediaId);
+ if (!db_sql_query(ua->db, query, count_handler, (void *)&cnt)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ Dmsg0(050, "Count failed\n");
+ goto bail_out;
+ }
+
+ if (cnt.count == 0) {
+ if (ua->verbose) {
+ bsendmsg(ua, "There are no Jobs associated with Volume %s. It is purged.\n",
+ mr->VolumeName);
+ }
+ if (!mark_media_purged(ua, mr)) {
+ goto bail_out;
+ }
+ goto bail_out;
+ }
+
+ if (cnt.count < MAX_DEL_LIST_LEN) {
+ del.max_ids = cnt.count + 1;
+ } else {
+ del.max_ids = MAX_DEL_LIST_LEN;
+ }
+
+ del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids);
+
+ Mmsg(&query, "SELECT JobId FROM JobMedia WHERE MediaId=%d", mr->MediaId);
+ if (!db_sql_query(ua->db, query, file_delete_handler, (void *)&del)) {
+ if (ua->verbose) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ }
+ Dmsg0(050, "Count failed\n");
+ goto bail_out;
+ }
+
+ /* Use Volume Retention to purge Jobs and Files */
+ period = mr->VolRetention;
+ now = (btime_t)time(NULL);
+
+ for (i=0; i < del.num_ids; i++) {
+ jr.JobId = del.JobId[i];
+ if (!db_get_job_record(ua->db, &jr)) {
+ continue;
+ }
+ if (jr.JobTDate >= (now - period)) {
+ continue;
+ }
+ Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]);
+ Mmsg(&query, "DELETE FROM File WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ Mmsg(&query, "DELETE FROM Job WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ Mmsg(&query, "DELETE FROM JobMedia WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ Dmsg1(050, "Del sql=%s\n", query);
+ del.num_del++;
+ }
+ if (del.JobId) {
+ free(del.JobId);
+ }
+ bsendmsg(ua, _("Pruned %d Jobs on Volume %s from catalog.\n"), del.num_del,
+ mr->VolumeName);
+
+ /* If purged, mark it so */
+ if (del.num_ids == del.num_del) {
+ mark_media_purged(ua, mr);
+ }
+
+bail_out:
+ free_pool_memory(query);
+ return 1;
+}
+
+static int mark_media_purged(UAContext *ua, MEDIA_DBR *mr)
+{
+ if (strcmp(mr->VolStatus, "Append") == 0 ||
+ strcmp(mr->VolStatus, "Full") == 0) {
+ strcpy(mr->VolStatus, "Purged");
+ if (!db_update_media_record(ua->db, mr)) {
+ if (ua->verbose) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ }
+ return 0;
+ }
+ }
+ return 1;
+}
--- /dev/null
+/*
+ *
+ * Bacula Director -- User Agent Database Purge Command
+ *
+ * Purges Files from specific JobIds
+ * or
+ * Purges Jobs from Volumes
+ *
+ * Kern Sibbald, February MMII
+ *
+ * $Id:
+ */
+
+/*
+ Copyright (C) 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 "dird.h"
+#include "ua.h"
+
+/* Forward referenced functions */
+int purge_files_from_client(UAContext *ua, CLIENT *client);
+int purge_jobs_from_client(UAContext *ua, CLIENT *client);
+void purge_files_from_volume(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr );
+void purge_jobs_from_volume(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
+void purge_files_from_job(UAContext *ua, JOB_DBR *jr);
+static int mark_media_purged(UAContext *ua, MEDIA_DBR *mr);
+
+
+#define MAX_DEL_LIST_LEN 1000000
+
+
+static char *select_jobsfiles_from_client =
+ "SELECT JobId FROM Job "
+ "WHERE ClientId=%d "
+ "AND PurgedFiles=0";
+
+static char *select_jobs_from_client =
+ "SELECT JobId, PurgedFiles FROM Job "
+ "WHERE ClientId=%d";
+
+
+/* In memory list of JobIds */
+struct s_file_del_ctx {
+ JobId_t *JobId;
+ int num_ids; /* ids stored */
+ int max_ids; /* size of array */
+ int num_del; /* number deleted */
+ int tot_ids; /* total to process */
+};
+
+struct s_job_del_ctx {
+ JobId_t *JobId; /* array of JobIds */
+ char *PurgedFiles; /* Array of PurgedFile flags */
+ int num_ids; /* ids stored */
+ int max_ids; /* size of array */
+ int num_del; /* number deleted */
+ int tot_ids; /* total to process */
+};
+
+struct s_count_ctx {
+ int count;
+};
+
+/*
+ * Called here to count entries to be deleted
+ */
+static int count_handler(void *ctx, int num_fields, char **row)
+{
+ struct s_count_ctx *cnt = (struct s_count_ctx *)ctx;
+
+ if (row[0]) {
+ cnt->count = atoi(row[0]);
+ } else {
+ cnt->count = 0;
+ }
+ return 0;
+}
+
+/*
+ * Called here to count entries to be deleted
+ */
+static int file_count_handler(void *ctx, int num_fields, char **row)
+{
+ struct s_file_del_ctx *del = (struct s_file_del_ctx *)ctx;
+ del->tot_ids++;
+ return 0;
+}
+
+
+static int job_count_handler(void *ctx, int num_fields, char **row)
+{
+ struct s_job_del_ctx *del = (struct s_job_del_ctx *)ctx;
+ del->tot_ids++;
+ return 0;
+}
+
+
+/*
+ * Called here to make in memory list of JobIds to be
+ * deleted and the associated PurgedFiles flag.
+ * The in memory list will then be transversed
+ * to issue the SQL DELETE commands. Note, the list
+ * is allowed to get to MAX_DEL_LIST_LEN to limit the
+ * maximum malloc'ed memory.
+ */
+static int job_delete_handler(void *ctx, int num_fields, char **row)
+{
+ struct s_job_del_ctx *del = (struct s_job_del_ctx *)ctx;
+
+ if (del->num_ids == MAX_DEL_LIST_LEN) {
+ return 1;
+ }
+ if (del->num_ids == del->max_ids) {
+ del->max_ids = (del->max_ids * 3) / 2;
+ del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) * del->max_ids);
+ del->PurgedFiles = (char *)brealloc(del->PurgedFiles, del->max_ids);
+ }
+ del->JobId[del->num_ids] = (JobId_t)strtod(row[0], NULL);
+ del->PurgedFiles[del->num_ids++] = (char)atoi(row[0]);
+ return 0;
+}
+
+static int file_delete_handler(void *ctx, int num_fields, char **row)
+{
+ struct s_file_del_ctx *del = (struct s_file_del_ctx *)ctx;
+
+ if (del->num_ids == MAX_DEL_LIST_LEN) {
+ return 1;
+ }
+ if (del->num_ids == del->max_ids) {
+ del->max_ids = (del->max_ids * 3) / 2;
+ del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) *
+ del->max_ids);
+ }
+ del->JobId[del->num_ids++] = (JobId_t)strtod(row[0], NULL);
+ return 0;
+}
+
+/*
+ * Purge records from database
+ *
+ * Purge Files (from) [Job|JobId|Client|Volume]
+ * Purge Jobs (from) [Client|Volume]
+ *
+ * N.B. Not all above is implemented yet.
+ */
+int purgecmd(UAContext *ua, char *cmd)
+{
+ CLIENT *client;
+ MEDIA_DBR mr;
+ POOL_DBR pr;
+ JOB_DBR jr;
+ static char *keywords[] = {
+ N_("files"),
+ N_("jobs"),
+ NULL};
+
+ static char *files_keywords[] = {
+ N_("Job"),
+ N_("JobId"),
+ N_("Client"),
+ N_("Volume"),
+ NULL};
+
+ static char *jobs_keywords[] = {
+ N_("Client"),
+ N_("Volume"),
+ NULL};
+
+ bsendmsg(ua, _(
+ "This command is DANGEROUS!!!\n"
+ "It purges (deletes) all Files from a Job,\n"
+ "JobId, Client or Volume; or it purges (deletes)\n"
+ "all Jobs from a Client or Volume. Normally you\n"
+ "should use the PRUNE command instead.\n"));
+
+ if (!open_db(ua)) {
+ return 1;
+ }
+ switch (find_arg_keyword(ua, keywords)) {
+ /* Files */
+ case 0:
+ switch(find_arg_keyword(ua, files_keywords)) {
+ case 0: /* Job */
+ case 1:
+ if (get_job_dbr(ua, &jr)) {
+ purge_files_from_job(ua, &jr);
+ }
+ return 1;
+ case 2: /* client */
+ client = select_client_resource(ua);
+ purge_files_from_client(ua, client);
+ return 1;
+ case 3:
+ if (select_pool_and_media_dbr(ua, &pr, &mr)) {
+ purge_files_from_volume(ua, &pr, &mr);
+ }
+ return 1;
+ }
+ /* Jobs */
+ case 1:
+ switch(find_arg_keyword(ua, jobs_keywords)) {
+ case 0: /* client */
+ client = select_client_resource(ua);
+ purge_jobs_from_client(ua, client);
+ return 1;
+ case 1:
+ if (select_pool_and_media_dbr(ua, &pr, &mr)) {
+ purge_jobs_from_volume(ua, &pr, &mr);
+ }
+ return 1;
+ }
+ default:
+ break;
+ }
+ switch (do_keyword_prompt(ua, _("Choose item to purge"), keywords)) {
+ case 0:
+ client = select_client_resource(ua);
+ if (!client) {
+ return 1;
+ }
+ purge_files_from_client(ua, client);
+ break;
+ case 1:
+ client = select_client_resource(ua);
+ if (!client) {
+ return 1;
+ }
+ purge_jobs_from_client(ua, client);
+ break;
+ }
+ return 1;
+}
+
+/*
+ * Prune File records from the database. For any Job which
+ * is older than the retention period, we unconditionally delete
+ * all File records for that Job. This is simple enough that no
+ * temporary tables are needed. We simply make an in memory list of
+ * the JobIds meeting the prune conditions, then delete all File records
+ * pointing to each of those JobIds.
+ */
+int purge_files_from_client(UAContext *ua, CLIENT *client)
+{
+ struct s_file_del_ctx del;
+ char *query = (char *)get_pool_memory(PM_MESSAGE);
+ int i;
+ CLIENT_DBR cr;
+
+ memset(&cr, 0, sizeof(cr));
+ memset(&del, 0, sizeof(del));
+
+ strcpy(cr.Name, client->hdr.name);
+ if (!db_create_client_record(ua->db, &cr)) {
+ return 0;
+ }
+
+ Mmsg(&query, select_jobsfiles_from_client, cr.ClientId);
+
+ Dmsg1(050, "select sql=%s\n", query);
+
+ if (!db_sql_query(ua->db, query, file_count_handler, (void *)&del)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ Dmsg0(050, "Count failed\n");
+ goto bail_out;
+ }
+
+ if (del.tot_ids == 0) {
+ bsendmsg(ua, _("No Files found for client %s to purge from %s catalog.\n"),
+ client->hdr.name, client->catalog->hdr.name);
+ goto bail_out;
+ }
+
+ if (del.tot_ids < MAX_DEL_LIST_LEN) {
+ del.max_ids = del.tot_ids + 1;
+ } else {
+ del.max_ids = MAX_DEL_LIST_LEN;
+ }
+ del.tot_ids = 0;
+
+ del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids);
+
+ db_sql_query(ua->db, query, file_delete_handler, (void *)&del);
+
+ for (i=0; i < del.num_ids; i++) {
+ Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]);
+ Mmsg(&query, "DELETE FROM File WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ /*
+ * Now mark Job as having files purged. This is necessary to
+ * avoid having too many Jobs to process in future prunings. If
+ * we don't do this, the number of JobId's in our in memory list
+ * will grow very large.
+ */
+ Mmsg(&query, "UPDATE Job Set PurgedFiles=1 WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ Dmsg1(050, "Del sql=%s\n", query);
+ }
+ bsendmsg(ua, _("%d Files for client %s purged from %s catalog.\n"), del.num_ids,
+ client->hdr.name, client->catalog->hdr.name);
+
+bail_out:
+ if (del.JobId) {
+ free(del.JobId);
+ }
+ free_pool_memory(query);
+ return 1;
+}
+
+
+
+/*
+ * Purging Jobs is a bit more complicated than purging Files
+ * because we delete Job records only if there is a more current
+ * backup of the FileSet. Otherwise, we keep the Job record.
+ * In other words, we never delete the only Job record that
+ * contains a current backup of a FileSet. This prevents the
+ * Volume from being recycled and destroying a current backup.
+ */
+int purge_jobs_from_client(UAContext *ua, CLIENT *client)
+{
+ struct s_job_del_ctx del;
+ char *query = (char *)get_pool_memory(PM_MESSAGE);
+ int i;
+ CLIENT_DBR cr;
+
+ memset(&cr, 0, sizeof(cr));
+ memset(&del, 0, sizeof(del));
+
+ strcpy(cr.Name, client->hdr.name);
+ if (!db_create_client_record(ua->db, &cr)) {
+ return 0;
+ }
+
+ Mmsg(&query, select_jobs_from_client, cr.ClientId);
+
+ Dmsg1(050, "select sql=%s\n", query);
+
+ if (!db_sql_query(ua->db, query, job_count_handler, (void *)&del)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ Dmsg0(050, "Count failed\n");
+ goto bail_out;
+ }
+ if (del.tot_ids == 0) {
+ bsendmsg(ua, _("No Jobs found for client %s to purge from %s catalog.\n"),
+ client->hdr.name, client->catalog->hdr.name);
+ goto bail_out;
+ }
+
+ if (del.tot_ids < MAX_DEL_LIST_LEN) {
+ del.max_ids = del.tot_ids + 1;
+ } else {
+ del.max_ids = MAX_DEL_LIST_LEN;
+ }
+
+ del.tot_ids = 0;
+
+ del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids);
+ del.PurgedFiles = (char *)malloc(del.max_ids);
+
+ db_sql_query(ua->db, query, job_delete_handler, (void *)&del);
+
+ /*
+ * OK, now we have the list of JobId's to be purged, first check
+ * if the Files have been purged, if not, purge (delete) them.
+ * Then delete the Job entry, and finally and JobMedia records.
+ */
+ for (i=0; i < del.num_ids; i++) {
+ Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]);
+ if (!del.PurgedFiles[i]) {
+ Mmsg(&query, "DELETE FROM File WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ Dmsg1(050, "Del sql=%s\n", query);
+ }
+
+ Mmsg(&query, "DELETE FROM Job WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ Dmsg1(050, "Del sql=%s\n", query);
+
+ Mmsg(&query, "DELETE FROM JobMedia WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ Dmsg1(050, "Del sql=%s\n", query);
+ }
+ bsendmsg(ua, _("%d Jobs for client %s purged from %s catalog.\n"), del.num_ids,
+ client->hdr.name, client->catalog->hdr.name);
+
+bail_out:
+ if (del.JobId) {
+ free(del.JobId);
+ }
+ if (del.PurgedFiles) {
+ free(del.PurgedFiles);
+ }
+ free_pool_memory(query);
+ return 1;
+}
+
+void purge_files_from_job(UAContext *ua, JOB_DBR *jr)
+{
+ char *query = (char *)get_pool_memory(PM_MESSAGE);
+
+ Mmsg(&query, "DELETE FROM File WHERE JobId=%d", jr->JobId);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+
+ Mmsg(&query, "UPDATE Job Set PurgedFiles=1 WHERE JobId=%d", jr->JobId);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+
+ free_pool_memory(query);
+}
+
+void purge_files_from_volume(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr )
+{} /* ***FIXME*** implement */
+
+void purge_jobs_from_volume(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr)
+{
+ char *query = (char *)get_pool_memory(PM_MESSAGE);
+ struct s_count_ctx cnt;
+ struct s_file_del_ctx del;
+ int i;
+ JOB_DBR jr;
+
+ memset(&jr, 0, sizeof(jr));
+ memset(&del, 0, sizeof(del));
+ cnt.count = 0;
+ Mmsg(&query, "SELECT count(*) FROM JobMedia WHERE MediaId=%d", mr->MediaId);
+ if (!db_sql_query(ua->db, query, count_handler, (void *)&cnt)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ Dmsg0(050, "Count failed\n");
+ goto bail_out;
+ }
+
+ if (cnt.count == 0) {
+ bsendmsg(ua, "There are no Jobs associated with Volume %s. It is purged.\n",
+ mr->VolumeName);
+ if (!mark_media_purged(ua, mr)) {
+ goto bail_out;
+ }
+ goto bail_out;
+ }
+
+ if (cnt.count < MAX_DEL_LIST_LEN) {
+ del.max_ids = cnt.count + 1;
+ } else {
+ del.max_ids = MAX_DEL_LIST_LEN;
+ }
+
+ del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids);
+
+ Mmsg(&query, "SELECT JobId FROM JobMedia WHERE MediaId=%d", mr->MediaId);
+ if (!db_sql_query(ua->db, query, file_delete_handler, (void *)&del)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ Dmsg0(050, "Count failed\n");
+ goto bail_out;
+ }
+
+ for (i=0; i < del.num_ids; i++) {
+ Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]);
+ Mmsg(&query, "DELETE FROM File WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ Mmsg(&query, "DELETE FROM Job WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ Mmsg(&query, "DELETE FROM JobMedia WHERE JobId=%d", del.JobId[i]);
+ db_sql_query(ua->db, query, NULL, (void *)NULL);
+ Dmsg1(050, "Del sql=%s\n", query);
+ del.num_del++;
+ }
+ if (del.JobId) {
+ free(del.JobId);
+ }
+ bsendmsg(ua, _("%d Files for Volume %s purged from catalog.\n"), del.num_del,
+ mr->VolumeName);
+
+ /* If purged, mark it so */
+ if (del.num_ids == del.num_del) {
+ mark_media_purged(ua, mr);
+ }
+
+bail_out:
+ free_pool_memory(query);
+}
+
+static int mark_media_purged(UAContext *ua, MEDIA_DBR *mr)
+{
+ if (strcmp(mr->VolStatus, "Append") == 0 ||
+ strcmp(mr->VolStatus, "Full") == 0) {
+ strcpy(mr->VolStatus, "Purged");
+ if (!db_update_media_record(ua->db, mr)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ return 0;
+ }
+ }
+ return 1;
+}
goto try_again;
} else if (jcr->JobType == JT_VERIFY) {
start_prompt(ua, _("Levels:\n"));
- add_prompt(ua, _("Verify from Catalog"));
add_prompt(ua, _("Initialize Catalog"));
+ add_prompt(ua, _("Verify from Catalog"));
add_prompt(ua, _("Verify Volume"));
add_prompt(ua, _("Verify Volume Data"));
switch (do_prompt(ua, _("Select level"), NULL)) {
case 0:
- jcr->level = L_VERIFY_CATALOG;
+ jcr->level = L_VERIFY_INIT;
break;
case 1:
- jcr->level = L_VERIFY_INIT;
+ jcr->level = L_VERIFY_CATALOG;
break;
case 2:
jcr->level = L_VERIFY_VOLUME;
* Bacula Director -- User Agent Prompt and Selection code
*
* Kern Sibbald, October MMI
+ *
+ * $Id:
*/
/*
STORE *select_storage_resource(UAContext *ua);
JOB *select_job_resource(UAContext *ua);
+/*
+ * Confirm a retention period
+ */
+int confirm_retention(UAContext *ua, btime_t *ret, char *msg)
+{
+ char ed1[30];
+
+ for ( ;; ) {
+ bsendmsg(ua, _("The current %s retention period is: %s\n"),
+ msg, edit_btime(*ret, ed1));
+ if (!get_cmd(ua, _("Continue? (yes/mod/no): "))) {
+ return 0;
+ }
+ if (strcasecmp(ua->cmd, _("mod")) == 0) {
+ if (!get_cmd(ua, _("Enter new retention period: "))) {
+ return 0;
+ }
+ if (!string_to_btime(ua->cmd, ret)) {
+ bsendmsg(ua, _("Invalid period.\n"));
+ continue;
+ }
+ continue;
+ }
+ if (strcasecmp(ua->cmd, _("yes")) == 0) {
+ break;
+ }
+ }
+ return 1;
+}
+
/*
* Given a list of keywords, find the first one
* that is in the argument list.
return select_client_resource(ua);
}
-
-
-
/* Scan what the user has entered looking for:
*
* pool=<pool-name>
return 0;
}
if (num_pools <= 0) {
- bsendmsg(ua, _("No pools defined.\n"));
+ bsendmsg(ua, _("No pools defined. Use the \"create\" command to create one.\n"));
return 0;
}
return opr.PoolId;
}
+/*
+ * Select a Pool and a Media (Volume) record from the database
+ */
+int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr)
+{
+ int found = FALSE;
+ int i;
+
+ memset(pr, 0, sizeof(POOL_DBR));
+ memset(mr, 0, sizeof(MEDIA_DBR));
+
+ /* Get the pool, possibly from pool=<pool-name> */
+ if (!get_pool_dbr(ua, pr)) {
+ return 0;
+ }
+ mr->PoolId = pr->PoolId;
+
+ /* See if a volume name is specified as an argument */
+ for (i=1; i<ua->argc; i++) {
+ if (strcasecmp(ua->argk[i], _("volume")) == 0 && ua->argv[i]) {
+ found = TRUE;
+ break;
+ }
+ }
+ if (found) {
+ strcpy(mr->VolumeName, ua->argv[i]);
+ } else {
+ db_list_media_records(ua->db, mr, prtit, ua);
+ if (!get_cmd(ua, _("Enter the Volume name to delete: "))) {
+ return 01;
+ }
+ strcpy(mr->VolumeName, ua->cmd);
+ }
+ mr->MediaId = 0;
+ if (!db_get_media_record(ua->db, mr)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ return 0;
+ }
+ return 1;
+}
+
/*
* This routine is ONLY used in the create command.
return pool;
}
+/*
+ * List all jobs and ask user to select one
+ */
+int select_job_dbr(UAContext *ua, JOB_DBR *jr)
+{
+ db_list_job_records(ua->db, jr, prtit, ua);
+ if (!get_cmd(ua, _("Enter the JobId to select: "))) {
+ return 0;
+ }
+ jr->JobId = atoi(ua->cmd);
+ if (!db_get_job_record(ua->db, jr)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ return 0;
+ }
+ return jr->JobId;
+
+}
+
+
+/* Scan what the user has entered looking for:
+ *
+ * jobid=nn
+ *
+ * if error or not found, put up a list of Jobs
+ * to choose from.
+ *
+ * returns: 0 on error
+ * JobId on success and fills in JOB_DBR
+ */
+int get_job_dbr(UAContext *ua, JOB_DBR *jr)
+{
+ int i;
+
+ for (i=1; i<ua->argc; i++) {
+ if (strcasecmp(ua->argk[i], _("job")) == 0 && ua->argv[i]) {
+ jr->JobId = 0;
+ strcpy(jr->Job, ua->argv[i]);
+ } else if (strcasecmp(ua->argk[i], _("jobid")) == 0 && ua->argv[i]) {
+ jr->JobId = atoi(ua->argv[i]);
+ } else {
+ continue;
+ }
+ if (!db_get_job_record(ua->db, jr)) {
+ bsendmsg(ua, _("Could not find Job %s: ERR=%s"), ua->argv[i],
+ db_strerror(ua->db));
+ jr->JobId = 0;
+ break;
+ }
+ return jr->JobId;
+ }
+
+ if (!select_job_dbr(ua, jr)) { /* try once more */
+ return 0;
+ }
+ return jr->JobId;
+}
+
} else {
sprintf(pmsg, "%s (1-%d): ", msg, ua->num_prompts-1);
}
- if (!get_cmd(ua, pmsg) || *ua->cmd == '.') {
+ /* Either a . or an @ will get you out of the loop */
+ if (!get_cmd(ua, pmsg) || *ua->cmd == '.' || *ua->cmd == '@') {
item = -1; /* error */
break;
}
extern void run_job(JCR *jcr);
/* Imported variables */
-extern struct s_jl joblevels[];
extern int r_first;
extern int r_last;
extern struct s_res resources[];
*/
static void handle_UA_client_request(void *arg)
{
- int quit, stat;
+ int stat;
static char cmd[1000];
UAContext ua;
BSOCK *UA_sock = (BSOCK *) arg;
memset(&ua, 0, sizeof(ua));
ua.automount = TRUE;
+ ua.verbose = TRUE;
ua.jcr = new_jcr(sizeof(JCR), dird_free_jcr);
- close_msg(ua.jcr); /* we don't handle messages */
ua.jcr->sd_auth_key = bstrdup("dummy"); /* dummy Storage daemon key */
ua.UA_sock = UA_sock;
ua.cmd = (char *) get_pool_memory(PM_FNAME);
goto getout;
}
- quit = FALSE;
- while (!quit) {
+ while (!ua.quit) {
stat = bnet_recv(ua.UA_sock);
if (stat > 0) {
strncpy(cmd, ua.UA_sock->msg, sizeof(cmd));
cmd[sizeof(cmd)-1] = 0; /* ensure it is terminated/trucated */
parse_command_args(&ua);
if (ua.argc > 0 && ua.argk[0][0] == '.') {
- quit = !do_a_dot_command(&ua, cmd);
+ do_a_dot_command(&ua, cmd);
} else {
- quit = !do_a_command(&ua, cmd);
+ do_a_command(&ua, cmd);
}
- if (!quit) {
+ if (!ua.quit) {
if (ua.auto_display_messages) {
strcpy(cmd, "messages");
qmessagescmd(&ua, cmd);
}
} else if (stat == 0) {
if (ua.UA_sock->msglen == BNET_TERMINATE) {
+ ua.quit = TRUE;
break;
}
bnet_sig(ua.UA_sock, BNET_POLL);
ua.UA_sock = NULL;
}
+ close_db(&ua); /* do this before freeing JCR */
+
if (ua.jcr) {
free_jcr(ua.jcr);
ua.jcr = NULL;
}
- close_db(&ua);
if (ua.prompt) {
free(ua.prompt);
}
}
bsendmsg(ua, _(" Files=%s Bytes=%s Termination Status=%s\n"),
- edit_uint_with_commas(last_job.JobFiles, b1),
- edit_uint_with_commas(last_job.JobBytes, b2),
+ edit_uint64_with_commas(last_job.JobFiles, b1),
+ edit_uint64_with_commas(last_job.JobBytes, b2),
termstat);
}
lock_jcr_chain();
CLIENT_DBR cr;
memset(&cr, 0, sizeof(cr));
+ cr.AutoPrune = jcr->client->AutoPrune;
+ cr.FileRetention = jcr->client->FileRetention;
+ cr.JobRetention = jcr->client->JobRetention;
strcpy(cr.Name, jcr->client->hdr.name);
if (jcr->client_name) {
free(jcr->client_name);
return 0;
}
- jcr->fname = (char *) get_pool_memory(PM_FNAME);
+ if (!jcr->fname) {
+ jcr->fname = (char *) get_pool_memory(PM_FNAME);
+ }
jcr->jr.JobId = last_full_id; /* save last full id */
jcr->client->hdr.name,
sdt,
edt,
- edit_uint_with_commas(jcr->jr.JobFiles, ec1),
+ edit_uint64_with_commas(jcr->jr.JobFiles, ec1),
term_msg);
Dmsg0(100, "Leave verify_cleanup()\n");
-
+ if (jcr->fname) {
+ free_memory(jcr->fname);
+ jcr->fname = NULL;
+ }
}
/*
struct stat statc; /* catalog stat */
int stat = JS_Terminated;
char buf[MAXSTRING];
+ char *fname = (char *)get_pool_memory(PM_MESSAGE);
+ int do_MD5 = FALSE;
memset(&fdbr, 0, sizeof(FILE_DBR));
fd = jcr->file_bsock;
* Get Attributes and MD5 Signature from File daemon
*/
while ((n=bget_msg(fd, 0)) > 0) {
- long file_index, attr_file_index;
- int stream;
- char *attr, *p;
- char Opts[MAXSTRING]; /* Verify Opts or MD5 signature */
- int do_MD5;
-
- Dmsg1(50, "Atts+MD5=%s\n", fd->msg);
- if ((len = sscanf(fd->msg, "%ld %d %s %s", &file_index, &stream,
- Opts, jcr->fname)) != 4) {
- Jmsg3(jcr, M_FATAL, 0, _("bird<filed: bad attributes, expected 4 fields got %d\n\
-msglen=%d msg=%s\n"), len, fd->msglen, fd->msg);
- jcr->JobStatus = JS_ErrorTerminated;
- return 0;
- }
- /*
- * Got attributes stream, decode it
- */
- if (stream == STREAM_UNIX_ATTRIBUTES) {
- attr_file_index = file_index; /* remember attribute file_index */
- len = strlen(fd->msg);
- attr = &fd->msg[len+1];
- decode_stat(attr, &statf); /* decode file stat packet */
- do_MD5 = FALSE;
- jcr->fn_printed = FALSE;
-
- Dmsg2(11, "dird<filed: stream=%d %s\n", stream, jcr->fname);
- Dmsg1(20, "dird<filed: attr=%s\n", attr);
-
- /*
- * Find equivalent record in the database
- */
- fdbr.FileId = 0;
- db_get_file_attributes_record(jcr->db, jcr->fname, &fdbr);
-
- if (fdbr.FileId == 0) {
- Jmsg(jcr, M_INFO, 0, _("New file: %s\n"), jcr->fname);
- Dmsg1(20, _("File not in catalog: %s\n"), jcr->fname);
- stat = JS_Differences;
- continue;
- } else {
- /*
- * mark file record as visited by stuffing the
- * current JobId, which is unique, into the FileIndex
- */
- db_mark_file_record(jcr->db, fdbr.FileId, jcr->JobId);
- }
-
- Dmsg2(20, "Found %s in catalog. Opts=%s\n", jcr->fname, Opts);
- decode_stat(fdbr.LStat, &statc); /* decode catalog stat */
- strip_trailing_junk(jcr->fname);
- /*
- * Loop over options supplied by user and verify the
- * fields he requests.
- */
- for (p=Opts; *p; p++) {
- switch (*p) {
- case 'i': /* compare INODEs */
- if (statc.st_ino != statf.st_ino) {
- prt_fname(jcr);
- Jmsg(jcr, M_INFO, 0, _(" st_ino differ. Cat: %x File: %x\n"),
- statc.st_ino, statf.st_ino);
- stat = JS_Differences;
- }
- break;
- case 'p': /* permissions bits */
- if (statc.st_mode != statf.st_mode) {
- prt_fname(jcr);
- Jmsg(jcr, M_INFO, 0, _(" st_mode differ. Cat: %x File: %x\n"),
- statc.st_mode, statf.st_mode);
- stat = JS_Differences;
- }
- break;
- case 'n': /* number of links */
- if (statc.st_nlink != statf.st_nlink) {
- prt_fname(jcr);
- Jmsg(jcr, M_INFO, 0, _(" st_nlink differ. Cat: %d File: %d\n"),
- statc.st_nlink, statf.st_nlink);
- stat = JS_Differences;
- }
- break;
- case 'u': /* user id */
- if (statc.st_uid != statf.st_uid) {
- prt_fname(jcr);
- Jmsg(jcr, M_INFO, 0, _(" st_uid differ. Cat: %d File: %d\n"),
- statc.st_uid, statf.st_uid);
- stat = JS_Differences;
- }
- break;
- case 'g': /* group id */
- if (statc.st_gid != statf.st_gid) {
- prt_fname(jcr);
- Jmsg(jcr, M_INFO, 0, _(" st_gid differ. Cat: %d File: %d\n"),
- statc.st_gid, statf.st_gid);
- stat = JS_Differences;
- }
- break;
- case 's': /* size */
- if (statc.st_size != statf.st_size) {
- prt_fname(jcr);
- Jmsg(jcr, M_INFO, 0, _(" st_size differ. Cat: %d File: %d\n"),
- statc.st_size, statf.st_size);
- stat = JS_Differences;
- }
- break;
- case 'a': /* access time */
- if (statc.st_atime != statf.st_atime) {
- prt_fname(jcr);
- Jmsg(jcr, M_INFO, 0, _(" st_atime differs\n"));
- stat = JS_Differences;
- }
- break;
- case 'm':
- if (statc.st_mtime != statf.st_mtime) {
- prt_fname(jcr);
- Jmsg(jcr, M_INFO, 0, _(" st_mtime differs\n"));
- stat = JS_Differences;
- }
- break;
- case 'c': /* ctime */
- if (statc.st_ctime != statf.st_ctime) {
- prt_fname(jcr);
- Jmsg(jcr, M_INFO, 0, _(" st_ctime differs\n"));
- stat = JS_Differences;
- }
- break;
- case 'd': /* file size decrease */
- if (statc.st_size > statf.st_size) {
- prt_fname(jcr);
- Jmsg(jcr, M_INFO, 0, _(" st_size decrease. Cat: %d File: %d\n"),
- statc.st_size, statf.st_size);
- stat = JS_Differences;
- }
- break;
- case '5': /* compare MD5 */
- do_MD5 = TRUE;
- break;
- case ':':
- case 'V':
- default:
- break;
- }
- }
- /*
- * Got MD5 Signature from Storage daemon
- * It came across in the Opts field.
- */
- } else if (stream == STREAM_MD5_SIGNATURE) {
- if (attr_file_index != file_index) {
- Jmsg2(jcr, M_FATAL, 0, _("MD5 index %d not same as attributes %d\n"),
- file_index, attr_file_index);
- jcr->JobStatus = JS_ErrorTerminated;
- return 0;
- }
- if (do_MD5) {
- db_escape_string(buf, Opts, strlen(Opts));
- if (strcmp(buf, fdbr.MD5) != 0) {
- /***FIXME**** fname may not be valid */
- prt_fname(jcr);
- if (debug_level >= 10) {
- Jmsg(jcr, M_INFO, 0, _(" MD5 not same. File=%s Cat=%s\n"), buf, fdbr.MD5);
- } else {
- Jmsg(jcr, M_INFO, 0, _(" MD5 differs.\n"));
- }
- stat = JS_Differences;
- }
- }
- }
- jcr->jr.JobFiles = file_index;
-
+ long file_index, attr_file_index;
+ int stream;
+ char *attr, *p;
+ char Opts_MD5[MAXSTRING]; /* Verify Opts or MD5 signature */
+
+ fname = (char *)check_pool_memory_size(fname, fd->msglen);
+ jcr->fname = (char *)check_pool_memory_size(jcr->fname, fd->msglen);
+ Dmsg1(50, "Atts+MD5=%s\n", fd->msg);
+ if ((len = sscanf(fd->msg, "%ld %d %100s %s", &file_index, &stream,
+ Opts_MD5, fname)) != 4) {
+ Jmsg3(jcr, M_FATAL, 0, _("bird<filed: bad attributes, expected 4 fields got %d\n\
+ mslen=%d msg=%s\n"), len, fd->msglen, fd->msg);
+ jcr->JobStatus = JS_ErrorTerminated;
+ return 0;
+ }
+ /*
+ * Got attributes stream, decode it
+ */
+ if (stream == STREAM_UNIX_ATTRIBUTES) {
+ attr_file_index = file_index; /* remember attribute file_index */
+ len = strlen(fd->msg);
+ attr = &fd->msg[len+1];
+ decode_stat(attr, &statf); /* decode file stat packet */
+ do_MD5 = FALSE;
+ jcr->fn_printed = FALSE;
+ strip_trailing_junk(fname);
+ strcpy(jcr->fname, fname); /* move filename into JCR */
+
+ Dmsg2(040, "dird<filed: stream=%d %s\n", stream, jcr->fname);
+ Dmsg1(20, "dird<filed: attr=%s\n", attr);
+
+ /*
+ * Find equivalent record in the database
+ */
+ fdbr.FileId = 0;
+ if (!db_get_file_attributes_record(jcr->db, jcr->fname, &fdbr)) {
+ Jmsg(jcr, M_INFO, 0, _("New file: %s\n"), jcr->fname);
+ Dmsg1(020, _("File not in catalog: %s\n"), jcr->fname);
+ stat = JS_Differences;
+ continue;
+ } else {
+ /*
+ * mark file record as visited by stuffing the
+ * current JobId, which is unique, into the FileIndex
+ */
+ db_mark_file_record(jcr->db, fdbr.FileId, jcr->JobId);
+ }
+
+ Dmsg3(100, "Found %s in catalog. inx=%d Opts=%s\n", jcr->fname,
+ file_index, Opts_MD5);
+ decode_stat(fdbr.LStat, &statc); /* decode catalog stat */
+ /*
+ * Loop over options supplied by user and verify the
+ * fields he requests.
+ */
+ for (p=Opts_MD5; *p; p++) {
+ switch (*p) {
+ case 'i': /* compare INODEs */
+ if (statc.st_ino != statf.st_ino) {
+ prt_fname(jcr);
+ Jmsg(jcr, M_INFO, 0, _(" st_ino differ. Cat: %x File: %x\n"),
+ statc.st_ino, statf.st_ino);
+ stat = JS_Differences;
+ }
+ break;
+ case 'p': /* permissions bits */
+ if (statc.st_mode != statf.st_mode) {
+ prt_fname(jcr);
+ Jmsg(jcr, M_INFO, 0, _(" st_mode differ. Cat: %x File: %x\n"),
+ statc.st_mode, statf.st_mode);
+ stat = JS_Differences;
+ }
+ break;
+ case 'n': /* number of links */
+ if (statc.st_nlink != statf.st_nlink) {
+ prt_fname(jcr);
+ Jmsg(jcr, M_INFO, 0, _(" st_nlink differ. Cat: %d File: %d\n"),
+ statc.st_nlink, statf.st_nlink);
+ stat = JS_Differences;
+ }
+ break;
+ case 'u': /* user id */
+ if (statc.st_uid != statf.st_uid) {
+ prt_fname(jcr);
+ Jmsg(jcr, M_INFO, 0, _(" st_uid differ. Cat: %d File: %d\n"),
+ statc.st_uid, statf.st_uid);
+ stat = JS_Differences;
+ }
+ break;
+ case 'g': /* group id */
+ if (statc.st_gid != statf.st_gid) {
+ prt_fname(jcr);
+ Jmsg(jcr, M_INFO, 0, _(" st_gid differ. Cat: %d File: %d\n"),
+ statc.st_gid, statf.st_gid);
+ stat = JS_Differences;
+ }
+ break;
+ case 's': /* size */
+ if (statc.st_size != statf.st_size) {
+ prt_fname(jcr);
+ Jmsg(jcr, M_INFO, 0, _(" st_size differ. Cat: %d File: %d\n"),
+ statc.st_size, statf.st_size);
+ stat = JS_Differences;
+ }
+ break;
+ case 'a': /* access time */
+ if (statc.st_atime != statf.st_atime) {
+ prt_fname(jcr);
+ Jmsg(jcr, M_INFO, 0, _(" st_atime differs\n"));
+ stat = JS_Differences;
+ }
+ break;
+ case 'm':
+ if (statc.st_mtime != statf.st_mtime) {
+ prt_fname(jcr);
+ Jmsg(jcr, M_INFO, 0, _(" st_mtime differs\n"));
+ stat = JS_Differences;
+ }
+ break;
+ case 'c': /* ctime */
+ if (statc.st_ctime != statf.st_ctime) {
+ prt_fname(jcr);
+ Jmsg(jcr, M_INFO, 0, _(" st_ctime differs\n"));
+ stat = JS_Differences;
+ }
+ break;
+ case 'd': /* file size decrease */
+ if (statc.st_size > statf.st_size) {
+ prt_fname(jcr);
+ Jmsg(jcr, M_INFO, 0, _(" st_size decrease. Cat: %d File: %d\n"),
+ statc.st_size, statf.st_size);
+ stat = JS_Differences;
+ }
+ break;
+ case '5': /* compare MD5 */
+ Dmsg1(500, "set Do_MD5 for %s\n", jcr->fname);
+ do_MD5 = TRUE;
+ break;
+ case ':':
+ case 'V':
+ default:
+ break;
+ }
+ }
+ /*
+ * Got MD5 Signature from Storage daemon
+ * It came across in the Opts_MD5 field.
+ */
+ } else if (stream == STREAM_MD5_SIGNATURE) {
+ Dmsg2(100, "stream=MD5 inx=%d fname=%s\n", file_index, jcr->fname);
+ /*
+ * When ever we get an MD5 signature is MUST have been
+ * preceded by an attributes record, which sets attr_file_index
+ */
+ if (attr_file_index != file_index) {
+ Jmsg2(jcr, M_FATAL, 0, _("MD5 index %d not same as attributes %d\n"),
+ file_index, attr_file_index);
+ jcr->JobStatus = JS_ErrorTerminated;
+ return 0;
+ }
+ if (do_MD5) {
+ db_escape_string(buf, Opts_MD5, strlen(Opts_MD5));
+ if (strcmp(buf, fdbr.MD5) != 0) {
+ prt_fname(jcr);
+ if (debug_level >= 10) {
+ Jmsg(jcr, M_INFO, 0, _(" MD5 not same. File=%s Cat=%s\n"), buf, fdbr.MD5);
+ } else {
+ Jmsg(jcr, M_INFO, 0, _(" MD5 differs.\n"));
+ }
+ stat = JS_Differences;
+ }
+ do_MD5 = FALSE;
+ }
+ }
+ jcr->jr.JobFiles = file_index;
}
if (n < 0) {
Jmsg2(jcr, M_FATAL, 0, _("bdird<filed: bad attributes from filed n=%d : %s\n"),
jcr->JobStatus = JS_ErrorTerminated;
return 0;
}
+
/* Now find all the files that are missing -- i.e. all files in
* the database where the FileIndex != current JobId
*/
"AND File.FileIndex!=%d AND File.PathId=Path.PathId "
"AND File.FilenameId=Filename.FilenameId",
last_full_id, jcr->JobId);
+ /* missing_handler is called for each file found */
db_sql_query(jcr->db, buf, missing_handler, (void *)jcr);
if (jcr->fn_printed) {
stat = JS_Differences;
/* Terminate any MD5 signature and send it to Storage daemon and the Director */
if (gotMD5 && ff_pkt->flags & FO_MD5) {
-#ifdef really_needed
- char MD5buf[50]; /* 24 bytes should do */
-#endif
-
MD5Final(signature, &md5c);
-
- /* First do Storage daemon */
bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_MD5_SIGNATURE);
Dmsg1(10, "bfiled>stored:header %s\n", sd->msg);
memcpy(sd->msg, signature, 16);
sd->msglen = 16;
bnet_send(sd);
bnet_sig(sd, BNET_EOD); /* end of MD5 */
-
-#ifdef really_needed
- /* Now do Director (single record) */
- bin_to_base64(MD5buf, (char *)signature, 16); /* encode 16 bytes */
- bnet_fsend(dir, "%ld %d %s X", jcr->JobFiles, STREAM_MD5_SIGNATURE,
- MD5buf);
-#endif
gotMD5 = 0;
}
#ifdef really_needed
}
- init_msg(NULL);
+ init_msg(NULL, NULL);
parse_config(configfile);
LockRes();
me += 1000000;
#endif
- init_watchdog(); /* start watchdog thread */
+ start_watchdog(); /* start watchdog thread */
/* Become server, and handle requests */
Dmsg1(10, "filed: listening on port %d\n", me->FDport);
void terminate_filed(int sig)
{
- term_watchdog();
+ stop_watchdog();
if (configfile != NULL) {
free(configfile);
}
len = Mmsg(&msg, _(" Files=%s Bytes=%s Termination Status=%s\n"),
- edit_uint_with_commas(last_job.JobFiles, b1),
- edit_uint_with_commas(last_job.JobBytes, b2),
+ edit_uint64_with_commas(last_job.JobFiles, b1),
+ edit_uint64_with_commas(last_job.JobBytes, b2),
termstat);
sendit(msg, len, arg);
}
}
bps = njcr->JobBytes / sec;
len = Mmsg(&msg, _(" Files=%s Bytes=%s Bytes/sec=%s\n"),
- edit_uint_with_commas(njcr->JobFiles, b1),
- edit_uint_with_commas(njcr->JobBytes, b2),
- edit_uint_with_commas(bps, b3));
+ edit_uint64_with_commas(njcr->JobFiles, b1),
+ edit_uint64_with_commas(njcr->JobBytes, b2),
+ edit_uint64_with_commas(bps, b3));
sendit(msg, len, arg);
len = Mmsg(&msg, _(" Files Examined=%s\n"),
- edit_uint_with_commas(njcr->num_files_examined, b1));
+ edit_uint64_with_commas(njcr->num_files_examined, b1));
sendit(msg, len, arg);
if (njcr->JobFiles > 0) {
len = Mmsg(&msg, _(" Processing file: %s\n"), njcr->last_fname);
set_find_options(jcr->ff, jcr->incremental, jcr->mtime);
Dmsg0(10, "Start find files\n");
/* Subroutine verify_file() is called for each file */
- if (!find_files(jcr->ff, verify_file, (void *)jcr)) {
- /****FIXME**** error termination */
- Dmsg0(0, "========= Error return from find_files\n");
- }
+ find_files(jcr->ff, verify_file, (void *)jcr);
Dmsg0(10, "End find files\n");
- dir->msglen = 0;
- bnet_send(dir); /* signal end attributes to director */
+ bnet_sig(dir, BNET_EOD); /* signal end of data */
+
if (jcr->big_buf) {
free(jcr->big_buf);
jcr->big_buf = NULL;
{
char attribs[MAXSTRING];
int32_t n;
- int fid;
+ int fid, stat;
struct MD5Context md5c;
unsigned char signature[16];
BSOCK *sd, *dir;
return 1;
}
- if ((fid = open(ff_pkt->fname, O_RDONLY | O_BINARY)) < 0) {
- ff_pkt->ff_errno = errno;
- Jmsg(jcr, M_ERROR, -1, _(" Cannot open %s: ERR=%s.\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
- return 1;
+
+ 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) {
+ 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;
}
- Dmsg2(50, "opened %s fid=%d\n", ff_pkt->fname, fid);
- Dmsg1(10, "bfiled: sending %s to Director\n", ff_pkt->fname);
encode_stat(attribs, &ff_pkt->statp);
jcr->JobFiles++; /* increment number of files sent */
ff_pkt->VerifyOpts[0] = 'V';
ff_pkt->VerifyOpts[1] = 0;
}
+
+
+ /*
+ * Send file attributes to Director
+ * File_index
+ * Stream
+ * Verify Options
+ * Filename (full path)
+ * Encoded attributes
+ * Link name (if type==FT_LNK)
+ * For a directory, link is the same as fname, but with trailing
+ * slash. For a linked file, link is the link.
+ */
/* Send file attributes to Director (note different format than for Storage) */
+ Dmsg2(400, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, ff_pkt->fname);
if (ff_pkt->type == FT_LNK) {
- dir->msglen = sprintf(dir->msg,"%d %d %s %s%c%s%c%s%c", jcr->JobFiles,
+ stat = bnet_fsend(dir, "%d %d %s %s%c%s%c%s%c", jcr->JobFiles,
STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname,
0, attribs, 0, ff_pkt->link, 0);
} else {
- dir->msglen = sprintf(dir->msg,"%d %d %s %s%c%s%c%c", jcr->JobFiles,
+ stat = bnet_fsend(dir,"%d %d %s %s%c%s%c%c", jcr->JobFiles,
STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname,
0, attribs, 0, 0);
}
Dmsg2(20, "bfiled>bdird: attribs len=%d: msg=%s\n", dir->msglen, dir->msg);
- bnet_send(dir); /* send to Director */
-
+ if (!stat) {
+ Jmsg(jcr, M_ERROR, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir));
+ if (fid >= 0) {
+ close(fid);
+ }
+ return 0;
+ }
- /*
- * If MD5 is requested, read the file and compute the MD5
- *
- */
- if (ff_pkt->flags & FO_MD5) {
+ /* If file opened, compute MD5 */
+ if (fid >= 0 && ff_pkt->flags & FO_MD5) {
char MD5buf[50]; /* 24 should do */
MD5Init(&md5c);
- if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode) &&
- ff_pkt->statp.st_size > 0) {
- while ((n=read(fid, jcr->big_buf, jcr->buf_size)) > 0) {
- MD5Update(&md5c, ((unsigned char *) jcr->big_buf), n);
- jcr->JobBytes += n;
- }
- if (n < 0) {
- Jmsg(jcr, M_ERROR, -1, _(" Error reading %s: ERR=%s\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
- }
+ while ((n=read(fid, jcr->big_buf, jcr->buf_size)) > 0) {
+ MD5Update(&md5c, ((unsigned char *) jcr->big_buf), n);
+ jcr->JobBytes += n;
+ }
+ if (n < 0) {
+ Jmsg(jcr, M_WARNING, -1, _(" Error reading file %s: ERR=%s\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
}
MD5Final(signature, &md5c);
bin_to_base64(MD5buf, (char *)signature, 16); /* encode 16 bytes */
- dir->msglen = sprintf(dir->msg, "%d %d %s X", jcr->JobFiles,
- STREAM_MD5_SIGNATURE, MD5buf);
+ Dmsg2(400, "send inx=%d MD5=%s\n", jcr->JobFiles, MD5buf);
+ bnet_fsend(dir, "%d %d %s *MD5-%d*", jcr->JobFiles, STREAM_MD5_SIGNATURE, MD5buf,
+ jcr->JobFiles);
Dmsg2(20, "bfiled>bdird: MD5 len=%d: msg=%s\n", dir->msglen, dir->msg);
- bnet_send(dir); /* send MD5 signature to Director */
}
- close(fid);
+ if (fid >= 0) {
+ close(fid);
+ }
return 1;
}
char *VolumeName; /* Volume name desired -- pool_memory */
char *client_name; /* client name */
char *sd_auth_key; /* SD auth key */
+ MSGS *msgs; /* Message resource */
DEST *dest_chain; /* Job message destination chain */
char send_msg[nbytes_for_bits(M_MAX+1)]; /* message bit mask */
makepath.c \
md5.c message.c mem_pool.c parse_conf.c \
queue.c rwlock.c save-cwd.c serial.c \
- signal.c smartall.c util.c watchdog.c workq.c
-
+ signal.c smartall.c util.c watchdog.c workq.c
# immortal.c filesys.c
jcr->VolumeName[0] = 0;
jcr->errmsg = (char *) get_pool_memory(PM_MESSAGE);
jcr->errmsg[0] = 0;
- init_msg(jcr); /* init job message chain */
jobs = jcr;
V(mutex);
return jcr;
break;
}
pthread_mutex_destroy(&jcr->mutex);
+
close_msg(jcr); /* close messages for this job */
+
/* do this after closing messages */
if (jcr->client_name) {
free(jcr->client_name);
free_pool_memory(jcr->VolumeName);
jcr->VolumeName = NULL;
}
- close_msg(jcr); /* close messages for this job */
if (jcr->dir_bsock) {
bnet_close(jcr->dir_bsock);
/* Imported functions */
-/* This chain contains all the possible destinations */
-DEST *dest_chain = NULL;
-/*
- * send_msg has a bit set for each type that has a
- * message destination. The info in send_msg[] is
- * contained in the dest structures,
- * but we keep it here for speed so that we don't have to
- * search all the structures in all the cases.
- */
-char send_msg[nbytes_for_bits(M_MAX+1)];
+static MSGS daemon_msg; /* global messages */
/*
* Set daemon name. Also, find canonical execution
/* Initialize message handler */
void
-init_msg(void *vjcr)
+init_msg(void *vjcr, MSGS *msg)
{
DEST *d, *dnew, *temp_chain = NULL;
JCR *jcr = (JCR *)vjcr;
+ if (!msg) { /* If nothing specified, use */
+ msg = &daemon_msg; /* daemon global message resource */
+ }
if (!jcr) {
- memset(send_msg, 0, sizeof(send_msg)); /* init daemon stuff */
+ memset(msg, 0, sizeof(msg)); /* init daemon global message */
} else { /* init for job */
/* Walk down the global chain duplicating it
* for the current Job. No need to duplicate
* the attached strings.
*/
- for (d=dest_chain; d; d=d->next) {
+ for (d=daemon_msg.dest_chain; d; d=d->next) {
dnew = (DEST *) malloc(sizeof(DEST));
memcpy(dnew, d, sizeof(DEST));
dnew->next = temp_chain;
dnew->fd = NULL;
+ dnew->mail_filename = NULL;
temp_chain = dnew;
}
jcr->dest_chain = temp_chain;
- memcpy(jcr->send_msg, send_msg, sizeof(send_msg));
+ memcpy(jcr->send_msg, daemon_msg.send_msg, sizeof(daemon_msg.send_msg));
}
}
* but in the case of MAIL is a space separated list of
* email addresses, ...
*/
-void add_msg_dest(int dest_code, int msg_type, char *where, char *mail_cmd)
+void add_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where, char *mail_cmd)
{
DEST *d;
/* First search the existing chain and see if we
* can simply add this msg_type to an existing entry.
*/
- for (d=dest_chain; d; d=d->next) {
+ for (d=daemon_msg.dest_chain; d; d=d->next) {
if (dest_code == d->dest_code && ((where == NULL && d->where == NULL) ||
(strcmp(where, d->where) == 0))) {
Dmsg4(200, "Add to existing d=%x msgtype=%d destcode=%d where=%s\n",
d, msg_type, dest_code, where);
set_bit(msg_type, d->msg_types);
- set_bit(msg_type, send_msg); /* set msg_type bit in our local */
+ set_bit(msg_type, daemon_msg.send_msg); /* set msg_type bit in our local */
return;
}
}
/* Not found, create a new entry */
d = (DEST *) malloc(sizeof(DEST));
memset(d, 0, sizeof(DEST));
- d->next = dest_chain;
+ d->next = daemon_msg.dest_chain;
d->dest_code = dest_code;
set_bit(msg_type, d->msg_types); /* set type bit in structure */
- set_bit(msg_type, send_msg); /* set type bit in our local */
+ set_bit(msg_type, daemon_msg.send_msg); /* set type bit in our local */
if (where) {
d->where = bstrdup(where);
}
Dmsg5(200, "add new d=%x msgtype=%d destcode=%d where=%s mailcmd=%s\n",
d, msg_type, dest_code, where?where:"(null)",
d->mail_cmd?d->mail_cmd:"(null)");
- dest_chain = d;
+ daemon_msg.dest_chain = d;
}
/*
*
* Remove a message destination
*/
-void rem_msg_dest(int dest_code, int msg_type, char *where)
+void rem_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where)
{
DEST *d;
- for (d=dest_chain; d; d=d->next) {
+ for (d=daemon_msg.dest_chain; d; d=d->next) {
Dmsg2(200, "Remove_msg_dest d=%x where=%s\n", d, d->where);
if (bit_is_set(msg_type, d->msg_types) && (dest_code == d->dest_code) &&
((where == NULL && d->where == NULL) ||
rem_temp_file:
/* Remove temp file */
fclose(d->fd);
- make_unique_mail_filename(jcr, &cmd, d);
- Dmsg1(200, "unlink: %s\n", cmd);
- unlink(cmd);
+ unlink(d->mail_filename);
+ free_pool_memory(d->mail_filename);
+ d->mail_filename = NULL;
break;
default:
break;
}
- d->fd = 0;
+ d->fd = NULL;
}
old = d; /* save pointer to release */
d = d->next; /* point to next buffer */
{
DEST *d, *n;
- for (d=dest_chain; d; d=n) {
+ for (d=daemon_msg.dest_chain; d; d=n) {
if (d->fd) {
if (d->dest_code == MD_FILE || d->dest_code == MD_APPEND) {
fclose(d->fd); /* close open file descriptor */
+ d->fd = NULL;
} else if (d->dest_code == MD_MAIL || d->dest_code == MD_MAIL_ON_ERROR) {
- pclose(d->fd); /* close open pipe */
+ fclose(d->fd);
+ d->fd = NULL;
+ unlink(d->mail_filename);
+ free_pool_memory(d->mail_filename);
+ d->mail_filename = NULL;
}
}
n = d->next;
if (jcr) {
d = jcr->dest_chain; /* use job message chain */
} else {
- d = dest_chain; /* use global chain */
+ d = daemon_msg.dest_chain; /* use global chain */
}
for ( ; d; d=d->next) {
if (bit_is_set(type, d->msg_types)) {
fputs(buf, d->fd);
/* Messages to the operator go one at a time */
pclose(d->fd);
+ d->fd = NULL;
}
break;
case MD_MAIL:
case MD_MAIL_ON_ERROR:
Dmsg1(200, "MAIL for following err: %s\n", buf);
if (!d->fd) {
- char *name = (char *) get_pool_memory(PM_MESSAGE);
+ char *name = (char *)get_pool_memory(PM_MESSAGE);
make_unique_mail_filename(jcr, &name, d);
d->fd = fopen(name, "w+");
- Dmsg2(100, "Open mail file %d: %s\n", d->fd, name);
if (!d->fd) {
Emsg2(M_ERROR, 0, "fopen %s failed: ERR=%s\n", name, strerror(errno));
free_pool_memory(name);
break;
}
- free_pool_memory(name);
+ d->mail_filename = name;
}
len = strlen(buf);
if (len > d->max_len) {
* Check if we have a message destination defined.
* We always report M_ABORT
*/
- if (type != M_ABORT && !bit_is_set(type, send_msg))
+ if (type != M_ABORT && !bit_is_set(type, daemon_msg.send_msg))
return; /* no destination */
switch (type) {
case M_ABORT:
char msg_types[nbytes_for_bits(M_MAX+1)]; /* message type mask */
char *where; /* filename/program name */
char *mail_cmd; /* mail command */
+ char *mail_filename; /* unique mail filename */
} DEST;
/* Message Destination values for dest field of DEST */
static int res_locked = 0; /* set when resource chains locked */
/* Forward referenced subroutines */
-static void scan_types(LEX *lc, int dest, char *where, char *cmd);
+static void scan_types(LEX *lc, MSGS *msg, int dest, char *where, char *cmd);
/* Common Resource definitions */
/* Message resource directives
- * name handler store_addr code flags default_value
+ * name handler value code flags default_value
*/
struct res_items msgs_items[] = {
{"name", store_name, ITEM(res_msgs.hdr.name), 0, 0, 0},
{"description", store_str, ITEM(res_msgs.hdr.desc), 0, 0, 0},
{"mailcommand", store_str, ITEM(res_msgs.mail_cmd), 0, 0, 0},
{"operatorcommand", store_str, ITEM(res_msgs.operator_cmd), 0, 0, 0},
- {"syslog", store_msgs, NULL, MD_SYSLOG, 0, 0},
- {"mail", store_msgs, NULL, MD_MAIL, 0, 0},
- {"mailonerror", store_msgs, NULL, MD_MAIL_ON_ERROR, 0, 0},
- {"file", store_msgs, NULL, MD_FILE, 0, 0},
- {"append", store_msgs, NULL, MD_APPEND, 0, 0},
- {"stdout", store_msgs, NULL, MD_STDOUT, 0, 0},
- {"stderr", store_msgs, NULL, MD_STDERR, 0, 0},
- {"director", store_msgs, NULL, MD_DIRECTOR, 0, 0},
- {"console", store_msgs, NULL, MD_CONSOLE, 0, 0},
- {"operator", store_msgs, NULL, MD_OPERATOR, 0, 0},
+ {"syslog", store_msgs, ITEM(res_msgs), MD_SYSLOG, 0, 0},
+ {"mail", store_msgs, ITEM(res_msgs), MD_MAIL, 0, 0},
+ {"mailonerror", store_msgs, ITEM(res_msgs), MD_MAIL_ON_ERROR, 0, 0},
+ {"file", store_msgs, ITEM(res_msgs), MD_FILE, 0, 0},
+ {"append", store_msgs, ITEM(res_msgs), MD_APPEND, 0, 0},
+ {"stdout", store_msgs, ITEM(res_msgs), MD_STDOUT, 0, 0},
+ {"stderr", store_msgs, ITEM(res_msgs), MD_STDERR, 0, 0},
+ {"director", store_msgs, ITEM(res_msgs), MD_DIRECTOR, 0, 0},
+ {"console", store_msgs, ITEM(res_msgs), MD_CONSOLE, 0, 0},
+ {"operator", store_msgs, ITEM(res_msgs), MD_OPERATOR, 0, 0},
{NULL, NULL, NULL, 0}
};
if (items[i].handler == store_yesno) {
*(int *)(items[i].value) |= items[i].code;
} else if (items[i].handler == store_pint ||
- items[i].handler == store_int ||
- items[i].handler == store_time) {
+ items[i].handler == store_int) {
*(int *)(items[i].value) = items[i].default_value;
} else if (items[i].handler == store_int64) {
*(int64_t *)(items[i].value) = items[i].default_value;
- } else if (items[i].handler == store_size) {
+ } else if (items[i].handler == store_size ||
+ items[i].handler == store_time) {
*(uint64_t *)(items[i].value) = items[i].default_value;
}
}
case MD_STDERR:
case MD_SYSLOG: /* syslog */
case MD_CONSOLE:
- scan_types(lc, item->code, NULL, NULL);
+ scan_types(lc, (MSGS *)(item->value), item->code, NULL, NULL);
break;
case MD_OPERATOR: /* send to operator */
case MD_DIRECTOR: /* send to Director */
break;
}
Dmsg1(200, "mail_cmd=%s\n", cmd);
- scan_types(lc, item->code, dest, cmd);
+ scan_types(lc, (MSGS *)(item->value), item->code, dest, cmd);
free_pool_memory(dest);
Dmsg0(200, "done with dest codes\n");
break;
if (token != T_EQUALS) {
scan_err1(lc, "expected an =, got: %s", lc->str);
}
- scan_types(lc, item->code, dest, NULL);
+ scan_types(lc, (MSGS *)(item->value), item->code, dest, NULL);
free_pool_memory(dest);
Dmsg0(200, "done with dest codes\n");
break;
* (WARNING, ERROR, FATAL, INFO, ...) with an appropriate
* destination (MAIL, FILE, OPERATOR, ...)
*/
-static void scan_types(LEX *lc, int dest_code, char *where, char *cmd)
+static void scan_types(LEX *lc, MSGS *msg, int dest_code, char *where, char *cmd)
{
int token, i, found, quit, is_not;
int msg_type;
if (msg_type == M_MAX+1) { /* all? */
for (i=1; i<=M_MAX; i++) { /* yes set all types */
- add_msg_dest(dest_code, i, where, cmd);
+ add_msg_dest(msg, dest_code, i, where, cmd);
}
} else {
if (is_not) {
- rem_msg_dest(dest_code, msg_type, where);
+ rem_msg_dest(msg, dest_code, msg_type, where);
} else {
- add_msg_dest(dest_code, msg_type, where, cmd);
+ add_msg_dest(msg, dest_code, msg_type, where, cmd);
}
}
if (lc->ch != ',') {
int token;
token = lex_get_token(lc);
- if (token != T_NUMBER) {
+ if (token != T_NUMBER || !is_a_number(lc->str)) {
scan_err1(lc, "expected an integer number, got: %s", lc->str);
} else {
errno = 0;
- *(int *)(item->value) = strtol(lc->str, NULL, 0);
+ *(int *)(item->value) = (int)strtod(lc->str, NULL);
if (errno != 0) {
scan_err1(lc, "expected an integer number, got: %s", lc->str);
}
int token;
token = lex_get_token(lc);
- if (token != T_NUMBER) {
- scan_err1(lc, "expected an integer number, got: %s", lc->str);
+ if (token != T_NUMBER || !is_a_number(lc->str)) {
+ scan_err1(lc, "expected a positive integer number, got: %s", lc->str);
} else {
errno = 0;
- token = strtol(lc->str, NULL, 0);
+ token = (int)strtod(lc->str, NULL);
if (errno != 0 || token < 0) {
scan_err1(lc, "expected a postive integer number, got: %s", lc->str);
}
int token;
token = lex_get_token(lc);
- if (token != T_NUMBER) {
+ Dmsg2(400, "int64=:%s: %f\n", lc->str, strtod(lc->str, NULL));
+ if (token != T_NUMBER || !is_a_number(lc->str)) {
scan_err1(lc, "expected an integer number, got: %s", lc->str);
} else {
errno = 0;
{
int token, i, ch;
uint64_t value;
- int mod[] = {'k', 'm', 'g'};
- uint64_t mult[] = {1024, /* kilobyte */
+ int mod[] = {'*', 'k', 'm', 'g', 0}; /* first item * not used */
+ uint64_t mult[] = {1, /* byte */
+ 1024, /* kilobyte */
1048576, /* megabyte */
1073741824}; /* gigabyte */
#ifdef we_have_a_compiler_that_works
- int mod[] = {'k', 'm', 'g', 't'};
- uint64_t mult[] = {1024, /* kilobyte */
+ int mod[] = {'*', 'k', 'm', 'g', 't', 0};
+ uint64_t mult[] = {1, /* byte */
+ 1024, /* kilobyte */
1048576, /* megabyte */
1073741824, /* gigabyte */
1099511627776};/* terabyte */
errno = 0;
switch (token) {
case T_NUMBER:
+ Dmsg2(400, "size num=:%s: %f\n", lc->str, strtod(lc->str, NULL));
value = (uint64_t)strtod(lc->str, NULL);
if (errno != 0 || token < 0) {
- scan_err1(lc, "expected a size, got: %s", lc->str);
+ scan_err1(lc, "expected a size number, got: %s", lc->str);
}
*(uint64_t *)(item->value) = value;
break;
if (ISUPPER(ch)) {
ch = tolower(ch);
}
- while (i < (int)sizeof(mod)) {
+ while (mod[++i] != 0) {
if (ch == mod[i]) {
lc->str_len--;
lc->str[lc->str_len] = 0; /* strip modifier */
break;
}
- i++;
}
}
- if (i >= (int)sizeof(mod)) {
- scan_err1(lc, "expected a size, got: %s", lc->str);
+ if (mod[i] == 0 || !is_a_number(lc->str)) {
+ scan_err1(lc, "expected a size number, got: %s", lc->str);
}
+ Dmsg3(400, "size str=:%s: %f i=%d\n", lc->str, strtod(lc->str, NULL), i);
+
value = (uint64_t)strtod(lc->str, NULL);
Dmsg1(400, "Int value = %d\n", (int)value);
if (errno != 0 || value < 0) {
- scan_err1(lc, "expected a size, got: %s", lc->str);
+ scan_err1(lc, "expected a size number, got: %s", lc->str);
}
- *(uint64_t *)(item->value) = (uint64_t)(strtod(lc->str, NULL) * mult[i]);
- Dmsg1(400, "Full value = %f\n", strtod(lc->str, NULL) * mult[i]);
+ *(uint64_t *)(item->value) = value * mult[i];
+ Dmsg2(400, "Full value = %f %" lld "\n", strtod(lc->str, NULL) * mult[i],
+ value *mult[i]);
break;
default:
scan_err1(lc, "expected a size, got: %s", lc->str);
/* Store a time period in seconds */
void store_time(LEX *lc, struct res_items *item, int index, int pass)
{
- int token, i, ch, value;
- int mod[] = {'s', 'm', 'h', 'd', 'w', 'o', 'q', 'y'};
- int mult[] = {1, 60, 60*60, 60*60*24, 60*60*24*7, 60*60*24*30,
- 60*60*24*91, 60*60*24*365};
+ int token;
+ btime_t value;
token = lex_get_token(lc);
errno = 0;
switch (token) {
case T_NUMBER:
- token = strtol(lc->str, NULL, 0);
- if (errno != 0 || token < 0) {
+ value = (btime_t)strtod(lc->str, NULL);
+ if (errno != 0 || value < 0) {
scan_err1(lc, "expected a time period, got: %s", lc->str);
}
- *(int *)(item->value) = token;
+ *(btime_t *)(item->value) = value;
break;
case T_IDENTIFIER:
case T_STRING:
- /* Look for modifier */
- ch = lc->str[lc->str_len - 1];
- i = 0;
- if (ISALPHA(ch)) {
- if (ISUPPER(ch)) {
- ch = tolower(ch);
- }
- while (i < (int)sizeof(mod)) {
- if (ch == mod[i]) {
- break;
- }
- i++;
- }
- }
- if (i >= (int)sizeof(mod)) {
- scan_err1(lc, "expected a time period, got: %s", lc->str);
- }
- value = strtol(lc->str, NULL, 0);
- if (errno != 0 || value < 0) {
+ if (!string_to_btime(lc->str, &value)) {
scan_err1(lc, "expected a time period, got: %s", lc->str);
}
- *(int *)(item->value) = value * mult[i];
+ *(btime_t *)(item->value) = value;
break;
default:
scan_err1(lc, "expected a time period, got: %s", lc->str);
*/
/* base64.c */
-void base64_init __PROTO((void));
-int to_base64 __PROTO((intmax_t value, char *where));
-int from_base64 __PROTO((intmax_t *value, char *where));
-void encode_stat __PROTO((char *buf, struct stat *statp));
-void decode_stat __PROTO((char *buf, struct stat *statp));
-int bin_to_base64 __PROTO((char *buf, char *bin, int len));
+void base64_init __PROTO((void));
+int to_base64 __PROTO((intmax_t value, char *where));
+int from_base64 __PROTO((intmax_t *value, char *where));
+void encode_stat __PROTO((char *buf, struct stat *statp));
+void decode_stat __PROTO((char *buf, struct stat *statp));
+int bin_to_base64 __PROTO((char *buf, char *bin, int len));
/* bmisc.c */
-void *b_malloc (char *file, int line, size_t size);
+void *b_malloc (char *file, int line, size_t size);
#ifndef DEBUG
-void *bmalloc (size_t size);
+void *bmalloc (size_t size);
#endif
-void *brealloc (void *buf, size_t size);
-void *bcalloc (size_t size1, size_t size2);
-int bsnprintf (char *str, size_t size, const char *format, ...);
-int bvsnprintf (char *str, size_t size, const char *format, va_list ap);
-int pool_sprintf (char *pool_buf, char *fmt, ...);
-int create_pid_file (char *dir, char *progname, int port, char *errmsg);
-int delete_pid_file (char *dir, char *progname, int port);
+void *brealloc (void *buf, size_t size);
+void *bcalloc (size_t size1, size_t size2);
+int bsnprintf (char *str, size_t size, const char *format, ...);
+int bvsnprintf (char *str, size_t size, const char *format, va_list ap);
+int pool_sprintf (char *pool_buf, char *fmt, ...);
+int create_pid_file (char *dir, char *progname, int port, char *errmsg);
+int delete_pid_file (char *dir, char *progname, int port);
/* bnet.c */
-int32_t bnet_recv __PROTO((BSOCK *bsock));
-int bnet_send __PROTO((BSOCK *bsock));
-int bnet_fsend (BSOCK *bs, char *fmt, ...);
-int bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw);
-int bnet_sig (BSOCK *bs, int sig);
-BSOCK * bnet_connect (void *jcr, int retry_interval,
- int max_retry_time, char *name, char *host, char *service,
- int port, int verbose);
-int bnet_wait_data (BSOCK *bsock, int sec);
-void bnet_close __PROTO((BSOCK *bsock));
-BSOCK * init_bsock __PROTO((int sockfd, char *who, char *ip, int port));
-BSOCK * dup_bsock __PROTO((BSOCK *bsock));
-void term_bsock __PROTO((BSOCK *bsock));
-char * bnet_strerror __PROTO((BSOCK *bsock));
-char * bnet_sig_to_ascii __PROTO((BSOCK *bsock));
-int bnet_wait_data __PROTO((BSOCK *bsock, int sec));
+int32_t bnet_recv __PROTO((BSOCK *bsock));
+int bnet_send __PROTO((BSOCK *bsock));
+int bnet_fsend (BSOCK *bs, char *fmt, ...);
+int bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw);
+int bnet_sig (BSOCK *bs, int sig);
+BSOCK * bnet_connect (void *jcr, int retry_interval,
+ int max_retry_time, char *name, char *host, char *service,
+ int port, int verbose);
+int bnet_wait_data (BSOCK *bsock, int sec);
+void bnet_close __PROTO((BSOCK *bsock));
+BSOCK * init_bsock __PROTO((int sockfd, char *who, char *ip, int port));
+BSOCK * dup_bsock __PROTO((BSOCK *bsock));
+void term_bsock __PROTO((BSOCK *bsock));
+char * bnet_strerror __PROTO((BSOCK *bsock));
+char * bnet_sig_to_ascii __PROTO((BSOCK *bsock));
+int bnet_wait_data __PROTO((BSOCK *bsock, int sec));
/* cram-md5.c */
int cram_md5_get_auth(BSOCK *bs, char *password);
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);
+ 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 type, struct stat *statp, int *ofd);
int set_statp(void *jcr, char *fname, char *ofile, char *lname, int type,
- struct stat *statp);
+ struct stat *statp);
/* crc32.c */
uint32_t bcrc32(uint8_t *buf, int len);
/* daemon.c */
-void daemon_start __PROTO(());
+void daemon_start __PROTO(());
/* lex.c */
-LEX * lex_close_file __PROTO((LEX *lf));
-LEX * lex_open_file __PROTO((LEX *lf, char *fname));
-int lex_get_char __PROTO((LEX *lf));
-void lex_unget_char __PROTO((LEX *lf));
-char * lex_tok_to_str __PROTO((int token));
-int lex_get_token __PROTO((LEX *lf));
+LEX * lex_close_file __PROTO((LEX *lf));
+LEX * lex_open_file __PROTO((LEX *lf, char *fname));
+int lex_get_char __PROTO((LEX *lf));
+void lex_unget_char __PROTO((LEX *lf));
+char * lex_tok_to_str __PROTO((int token));
+int lex_get_token __PROTO((LEX *lf));
/* 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);
+ 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 __PROTO((int argc, char *argv[], char *name));
-void init_msg __PROTO((void *jcr));
-void term_msg __PROTO((void));
-void close_msg __PROTO((void *jcr));
-void add_msg_dest __PROTO((int dest, int type, char *where, char *dest_code));
-void rem_msg_dest __PROTO((int dest, int type, char *where));
-void Jmsg (void *jcr, int type, int level, char *fmt, ...);
-void dispatch_message __PROTO((void *jcr, int type, int level, char *buf));
-void init_console_msg __PROTO((char *wd));
+void my_name_is __PROTO((int argc, char *argv[], char *name));
+void init_msg __PROTO((void *jcr, MSGS *msg));
+void term_msg __PROTO((void));
+void close_msg __PROTO((void *jcr));
+void add_msg_dest __PROTO((MSGS *msg, int dest, int type, char *where, char *dest_code));
+void rem_msg_dest __PROTO((MSGS *msg, int dest, int type, char *where));
+void Jmsg (void *jcr, int type, int level, char *fmt, ...);
+void dispatch_message __PROTO((void *jcr, int type, int level, char *buf));
+void init_console_msg __PROTO((char *wd));
/* bnet_server.c */
-void bnet_thread_server(int port, int max_clients, workq_t *client_wq,
- void handle_client_request(void *bsock));
-void bnet_server __PROTO((int port, void handle_client_request(BSOCK *bsock)));
-int net_connect __PROTO((int port));
-BSOCK * bnet_bind __PROTO((int port));
-BSOCK * bnet_accept __PROTO((BSOCK *bsock, char *who));
+void bnet_thread_server(int port, int max_clients, workq_t *client_wq,
+ void handle_client_request(void *bsock));
+void bnet_server __PROTO((int port, void handle_client_request(BSOCK *bsock)));
+int net_connect __PROTO((int port));
+BSOCK * bnet_bind __PROTO((int port));
+BSOCK * bnet_accept __PROTO((BSOCK *bsock, char *who));
/* signal.c */
-void init_signals __PROTO((void terminate(int sig)));
-void init_stack_dump (void);
+void init_signals __PROTO((void terminate(int sig)));
+void init_stack_dump (void);
/* util.c */
-void lcase __PROTO((char *str));
-void bash_spaces __PROTO((char *str));
-void unbash_spaces __PROTO((char *str));
-void strip_trailing_junk __PROTO((char *str));
-void strip_trailing_slashes __PROTO((char *dir));
-int skip_spaces __PROTO((char **msg));
-int skip_nonspaces __PROTO((char **msg));
-int fstrsch __PROTO((char *a, char *b));
-char * encode_time __PROTO((time_t time, char *buf));
-char * encode_mode __PROTO((mode_t mode, char *buf));
-char * edit_uint_with_commas __PROTO((uint64_t val, char *buf));
-char * add_commas __PROTO((char *val, char *buf));
-int do_shell_expansion(char *name);
+void lcase __PROTO((char *str));
+void bash_spaces __PROTO((char *str));
+void unbash_spaces __PROTO((char *str));
+void strip_trailing_junk __PROTO((char *str));
+void strip_trailing_slashes __PROTO((char *dir));
+int skip_spaces __PROTO((char **msg));
+int skip_nonspaces __PROTO((char **msg));
+int fstrsch __PROTO((char *a, char *b));
+char * encode_time __PROTO((time_t time, char *buf));
+char * encode_mode __PROTO((mode_t mode, char *buf));
+char * edit_uint64_with_commas __PROTO((uint64_t val, char *buf));
+char * add_commas __PROTO((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 string_to_btime(char *str, btime_t *value);
+char *edit_btime(btime_t val, char *buf);
+
+
/*
- *void print_ls_output __PROTO((char *fname, char *lname, int type, struct stat *statp));
+ *void print_ls_output __PROTO((char *fname, char *lname, int type, struct stat *statp));
*/
/* watchdog.c */
-int init_watchdog(void);
-int term_watchdog(void);
+int start_watchdog(void);
+int stop_watchdog(void);
struct sigaction sigdefault;
if (already_dead) {
- abort();
+ _exit(1);
}
already_dead = TRUE;
if (sig == SIGTERM) {
Dmsg0(500, "Doing sleep\n");
sleep(30);
}
- abort(); /* produce dump */
}
#endif
*/
/*
- * Edit a number with commas, the supplied buffer
- * must be at least 27 bytes long.
+ * Convert a string to btime_t (64 bit seconds)
+ * Returns 0: if error
+ 1: if OK, and value stored in value
*/
-char *edit_uint_with_commas(uint64_t val, char *buf)
+int string_to_btime(char *str, btime_t *value)
+{
+ int i, ch, len;
+ btime_t val;
+ static int mod[] = {'*', 's', 'm', 'h', 'd', 'w', 'o', 'q', 'y', 0};
+ static int mult[] = {1, 1, 60, 60*60, 60*60*24, 60*60*24*7, 60*60*24*30,
+ 60*60*24*91, 60*60*24*365};
+
+ /* Look for modifier */
+ len = strlen(str);
+ ch = str[len - 1];
+ i = 0;
+ if (ISALPHA(ch)) {
+ if (ISUPPER(ch)) {
+ ch = tolower(ch);
+ }
+ while (mod[++i] != 0) {
+ if (ch == mod[i]) {
+ len--;
+ str[len] = 0; /* strip modifier */
+ break;
+ }
+ }
+ }
+ if (mod[i] == 0 || !is_a_number(str)) {
+ return 0;
+ }
+ val = (btime_t)strtod(str, NULL);
+ if (errno != 0 || val < 0) {
+ return 0;
+ }
+ *value = val * mult[i];
+ return 1;
+
+}
+
+char *edit_btime(btime_t val, char *buf)
+{
+ char mybuf[30];
+ static int mult[] = {60*60*24*365, 60*60*24*30, 60*60*24, 60*60, 60};
+ static char *mod[] = {"year", "month", "day", "hour", "min"};
+ int i;
+ uint32_t times;
+
+ *buf = 0;
+ for (i=0; i<5; i++) {
+ times = val / mult[i];
+ if (times > 0) {
+ val = val - (btime_t)times * mult[i];
+ sprintf(mybuf, "%d %s%s ", times, mod[i], times>1?"s":"");
+ strcat(buf, mybuf);
+ }
+ }
+ if (val == 0 && strlen(buf) == 0) {
+ strcat(buf, "0 secs");
+ } else if (val != 0) {
+ sprintf(mybuf, "%d sec%s", (uint32_t)val, val>1?"s":"");
+ strcat(buf, mybuf);
+ }
+ return buf;
+}
+
+/*
+ * Check if specified string is a number or not.
+ * Taken from SQLite, cool, thanks.
+ */
+int is_a_number(const char *n)
+{
+ int digit_seen = 0;
+
+ if( *n == '-' || *n == '+' ) {
+ n++;
+ }
+ while (ISDIGIT(*n)) {
+ digit_seen = 1;
+ n++;
+ }
+ if (digit_seen && *n == '.') {
+ n++;
+ while (ISDIGIT(*n)) { n++; }
+ }
+ if (digit_seen && (*n == 'e' || *n == 'E')
+ && (ISDIGIT(n[1]) || ((n[1]=='-' || n[1] == '+') && ISDIGIT(n[2])))) {
+ n += 2; /* skip e- or e+ or e digit */
+ while (ISDIGIT(*n)) { n++; }
+ }
+ return digit_seen && *n==0;
+}
+
+
+/*
+ * Edit an integer number with commas, the supplied buffer
+ * must be at least 27 bytes long. The incoming number
+ * is always widened to 64 bits.
+ */
+char *edit_uint64_with_commas(uint64_t val, char *buf)
{
sprintf(buf, "%" lld, val);
return add_commas(buf, buf);
}
+/*
+ * Edit an integer number, the supplied buffer
+ * must be at least 27 bytes long. The incoming number
+ * is always widened to 64 bits.
+ */
+char *edit_uint64(uint64_t val, char *buf)
+{
+ sprintf(buf, "%" lld, val);
+ return buf;
+}
+
+
+/*
+ * Add commas to a string, which is presumably
+ * a number.
+ */
char *add_commas(char *val, char *buf)
{
int len, nc;
/* Convert a string in place to lower case */
-void
-lcase(char *str)
+void lcase(char *str)
{
while (*str) {
if (ISUPPER(*str))
/*
- * Initialize watchdog thread
+ * Start watchdog thread
*
* Returns: 0 on success
* errno on failure
*/
-int init_watchdog(void)
+int start_watchdog(void)
{
int stat;
pthread_t wdid;
* Returns: 0 on success
* errno on failure
*/
-int term_watchdog(void)
+int stop_watchdog(void)
{
int stat;
/* Requests sent to the Director */
static char Find_media[] = "CatReq Job=%s FindMedia=%d\n";
-static char Find_Vol_Info[] = "CatReq Job=%s GetVolInfo VolName=%s\n";
+static char Get_Vol_Info[] = "CatReq Job=%s GetVolInfo VolName=%s\n";
static char Update_media[] = "CatReq Job=%s UpdateMedia VolName=%s\
VolJobs=%d VolFiles=%d VolBlocks=%d VolBytes=%" lld " VolMounts=%d\
/* Responses received from the Director */
static char OK_media[] = "1000 OK VolName=%127s VolJobs=%d VolFiles=%d\
VolBlocks=%d VolBytes=%" lld " VolMounts=%d VolErrors=%d VolWrites=%d\
- VolMaxBytes=%" lld " VolCapacityBytes=%" lld "\n";
+ VolMaxBytes=%" lld " VolCapacityBytes=%" lld " VolStatus=%20s\n";
static char OK_update[] = "1000 OK UpdateMedia\n";
&vol->VolCatBlocks, &vol->VolCatBytes,
&vol->VolCatMounts, &vol->VolCatErrors,
&vol->VolCatWrites, &vol->VolCatMaxBytes,
- &vol->VolCatCapacityBytes) != 10) {
+ &vol->VolCatCapacityBytes, vol->VolCatStatus) != 11) {
Dmsg1(30, "Bad response from Dir: %s\n", dir->msg);
return 0;
}
strcpy(jcr->VolumeName, vol->VolCatName); /* set desired VolumeName */
Dmsg1(200, "Got Volume=%s\n", vol->VolCatName);
- strcpy(vol->VolCatStatus, "Append");
return 1;
}
* Get Volume info for a specific volume from the Director's Database
*
* Returns: 1 on success (not Director guarantees that Pool and MediaType
- * are correct and VolStatus==Append)
+ * are correct and VolStatus==Append or
+ * VolStatus==Recycle)
* 0 on failure
*
* Volume information returned in jcr
strcpy(jcr->VolCatInfo.VolCatName, jcr->VolumeName);
Dmsg1(200, "dir_get_volume_info=%s\n", jcr->VolCatInfo.VolCatName);
bash_spaces(jcr->VolCatInfo.VolCatName);
- bnet_fsend(dir, Find_Vol_Info, jcr->Job, jcr->VolCatInfo.VolCatName);
+ bnet_fsend(dir, Get_Vol_Info, jcr->Job, jcr->VolCatInfo.VolCatName);
return do_request_volume_info(jcr);
}
* Ensure that every message is always printed
*/
for (i=1; i<=M_MAX; i++) {
- add_msg_dest(MD_STDOUT, i, NULL, NULL);
+ add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL);
}
jcr = new_jcr(sizeof(JCR), my_free_jcr);
* Ensure that every message is always printed
*/
for (i=1; i<=M_MAX; i++) {
- add_msg_dest(MD_STDOUT, i, NULL, NULL);
+ add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL);
}
/* Try default device */
* Ensure that every message is always printed
*/
for (i=1; i<=M_MAX; i++) {
- add_msg_dest(MD_STDOUT, i, NULL, NULL);
+ add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL);
}
jcr = new_jcr(sizeof(JCR), my_free_jcr);
* Ensure that every message is always printed
*/
for (i=1; i<=M_MAX; i++) {
- add_msg_dest(MD_STDOUT, i, NULL, NULL);
+ add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL);
}
uint32_t VolCatErrors; /* Number of errors this volume */
uint32_t VolCatWrites; /* Number of writes this volume */
uint32_t VolCatReads; /* Number of reads this volume */
+ uint32_t VolCatRecycles; /* Number of recycles this volume */
uint64_t VolCatMaxBytes; /* max bytes to write */
uint64_t VolCatCapacityBytes; /* capacity estimate */
char VolCatStatus[20]; /* Volume status */
static int ready_dev_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
{
int mounted = 0;
+ int recycle = 0;
Dmsg0(100, "Enter ready_dev_for_append\n");
case VOL_OK:
Dmsg1(200, "Vol OK name=%s\n", jcr->VolumeName);
memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(jcr->VolCatInfo));
+ if (strcmp(dev->VolCatInfo.VolCatStatus, "Recycle") == 0) {
+ recycle = 1;
+ }
break; /* got it */
case VOL_NAME_ERROR:
/* Check if we can accept this as an anonymous volume */
* be appended just after the block label. If we are writing
* an second volume, the calling routine will write the label
* before writing the overflow block.
+ *
+ * If the tape is marked as Recycle, we rewrite the label.
*/
- if (dev->VolHdr.LabelType == PRE_LABEL) { /* fresh tape */
+ if (dev->VolHdr.LabelType == PRE_LABEL || recycle) {
Dmsg1(90, "ready_for_append found freshly labeled volume. dev=%x\n", dev);
dev->VolHdr.LabelType = VOL_LABEL; /* set Volume label */
write_volume_label_to_block(jcr, dev, block);
write_volume_label_to_block(jcr, dev, block);
dev->VolCatInfo.VolCatJobs = 1;
dev->VolCatInfo.VolCatFiles = 1;
- dev->VolCatInfo.VolCatMounts = 1;
dev->VolCatInfo.VolCatErrors = 0;
- dev->VolCatInfo.VolCatWrites = 1;
dev->VolCatInfo.VolCatBlocks = 1;
+ if (recycle) {
+ dev->VolCatInfo.VolCatMounts++;
+ dev->VolCatInfo.VolCatRecycles++;
+ } else {
+ dev->VolCatInfo.VolCatMounts = 1;
+ dev->VolCatInfo.VolCatRecycles = 0;
+ dev->VolCatInfo.VolCatWrites = 1;
+ dev->VolCatInfo.VolCatReads = 1;
+ }
+ strcpy(dev->VolCatInfo.VolCatStatus, "Append");
dir_update_volume_info(jcr, &dev->VolCatInfo);
- Jmsg(jcr, M_INFO, 0, _("Wrote label to prelabeled Volume %s on device %s\n"),
- jcr->VolumeName, dev_name(dev));
+ if (recycle) {
+ Jmsg(jcr, M_INFO, 0, _("Recycled volume %s on device %s, all previous data lost.\n"),
+ jcr->VolumeName, dev_name(dev));
+ } else {
+ Jmsg(jcr, M_INFO, 0, _("Wrote label to prelabeled Volume %s on device %s\n"),
+ jcr->VolumeName, dev_name(dev));
+ }
} else {
/* OK, at this point, we have a valid Bacula label, but
/* Inform User about end of media */
Jmsg(jcr, M_INFO, 0, _("End of media on Volume %s Bytes=%s Blocks=%s.\n"),
- PrevVolName, edit_uint_with_commas(dev->VolCatInfo.VolCatBytes, b1),
- edit_uint_with_commas(dev->VolCatInfo.VolCatBlocks, b2));
+ PrevVolName, edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
+ edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2));
if (!dev_is_tape(dev)) { /* If file, */
close_dev(dev); /* yes, close it */
static int mount_cmd(JCR *jcr);
static int unmount_cmd(JCR *jcr);
static int status_cmd(JCR *sjcr);
-static void label_device_if_ok(JCR *jcr, DEVICE *dev, char *vname, char *poolname);
+static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *vname, char *poolname);
struct s_cmds {
char *cmd;
if (open_dev(dev, volname, READ_WRITE) < 0) {
bnet_fsend(dir, _("3994 Connot open device: %s\n"), strerror_dev(dev));
} else {
- label_device_if_ok(jcr, dev, volname, poolname);
+ label_volume_if_ok(jcr, dev, volname, poolname);
force_close_dev(dev);
}
} else if (dev->dev_blocked &&
dev->dev_blocked != BST_DOING_ACQUIRE) { /* device blocked? */
- label_device_if_ok(jcr, dev, volname, poolname);
+ label_volume_if_ok(jcr, dev, volname, poolname);
} else if (dev->state & ST_READ || dev->num_writers) {
if (dev->state & ST_READ) {
bnet_fsend(dir, _("3901 Device %s is busy with 1 reader.\n"),
dev_name(dev), dev->num_writers);
}
} else { /* device not being used */
- label_device_if_ok(jcr, dev, volname, poolname);
+ label_volume_if_ok(jcr, dev, volname, poolname);
}
V(dev->mutex);
} else {
*
* Enter with the mutex set
*/
-static void label_device_if_ok(JCR *jcr, DEVICE *dev, char *vname, char *poolname)
+static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *vname, char *poolname)
{
BSOCK *dir = jcr->dir_bsock;
DEV_BLOCK *block;
}
bnet_fsend(user, _(" Files=%s Bytes=%s Termination Status=%s\n"),
- edit_uint_with_commas(last_job.JobFiles, b1),
- edit_uint_with_commas(last_job.JobBytes, b2),
+ edit_uint64_with_commas(last_job.JobFiles, b1),
+ edit_uint64_with_commas(last_job.JobBytes, b2),
termstat);
}
}
bpb = dev->VolCatInfo.VolCatBytes / bpb;
bnet_fsend(user, _(" Total Bytes=%s Blocks=%s Bytes/block=%s\n"),
- edit_uint_with_commas(dev->VolCatInfo.VolCatBytes, b1),
- edit_uint_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
- edit_uint_with_commas(bpb, b3));
+ edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
+ edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
+ edit_uint64_with_commas(bpb, b3));
bnet_fsend(user, _(" Positioned at File=%s Block=%s\n"),
- edit_uint_with_commas(dev->file, b1),
- edit_uint_with_commas(dev->block_num, b2));
+ edit_uint64_with_commas(dev->file, b1),
+ edit_uint64_with_commas(dev->block_num, b2));
} else {
bnet_fsend(user, _("Device %s is not open.\n"), dev_name(dev));
}
bps = jcr->JobBytes / sec;
bnet_fsend(user, _(" Files=%s Bytes=%s Bytes/sec=%s\n"),
- edit_uint_with_commas(jcr->JobFiles, b1),
- edit_uint_with_commas(jcr->JobBytes, b2),
- edit_uint_with_commas(bps, b3));
+ edit_uint64_with_commas(jcr->JobFiles, b1),
+ edit_uint64_with_commas(jcr->JobBytes, b2),
+ edit_uint64_with_commas(bps, b3));
found = 1;
#ifdef DEBUG
if (jcr->file_bsock) {
EndFile : %s\n\
JobErrors : %s\n\
",
- edit_uint_with_commas(label.JobFiles, ec1),
- edit_uint_with_commas(label.JobBytes, ec2),
- edit_uint_with_commas(label.start_block, ec3),
- edit_uint_with_commas(label.end_block, ec4),
- edit_uint_with_commas(label.start_file, ec5),
- edit_uint_with_commas(label.end_file, ec6),
- edit_uint_with_commas(label.JobErrors, ec7));
+ edit_uint64_with_commas(label.JobFiles, ec1),
+ edit_uint64_with_commas(label.JobBytes, ec2),
+ edit_uint64_with_commas(label.start_block, ec3),
+ edit_uint64_with_commas(label.end_block, ec4),
+ edit_uint64_with_commas(label.start_file, ec5),
+ edit_uint64_with_commas(label.end_file, ec6),
+ edit_uint64_with_commas(label.JobErrors, ec7));
}
dt.julian_day_number = label.write_date;
dt.julian_day_fraction = label.write_time;
configfile = bstrdup(CONFIG_FILE);
}
- init_msg(NULL);
+ init_msg(NULL, NULL);
parse_config(configfile);
check_config();
UnlockRes();
device = NULL;
- init_watchdog(); /* start watchdog thread */
+ start_watchdog(); /* start watchdog thread */
/*
* Here we support either listening on one port or on two ports
}
in_here = TRUE;
- term_watchdog();
+ stop_watchdog();
Dmsg0(200, "In terminate_stored()\n");
/* */
-#define VERSION "1.18"
+#define VERSION "1.19"
#define VSTRING "1"
-#define DATE "22 April 2002"
-#define LSMDATE "22Apr02"
+#define DATE "10 May 2002"
+#define LSMDATE "10May02"
/* Debug flags */
#define DEBUG 1